diff --git a/contrib/other/sdlquake-1.0.9/3dfx.txt b/contrib/other/sdlquake-1.0.9/3dfx.txt new file mode 100644 index 000000000..404aa9a10 --- /dev/null +++ b/contrib/other/sdlquake-1.0.9/3dfx.txt @@ -0,0 +1,69 @@ +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/contrib/other/sdlquake-1.0.9/COPYING b/contrib/other/sdlquake-1.0.9/COPYING new file mode 100644 index 000000000..2f3289afb --- /dev/null +++ b/contrib/other/sdlquake-1.0.9/COPYING @@ -0,0 +1,87 @@ +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/contrib/other/sdlquake-1.0.9/Makefile.Solaris b/contrib/other/sdlquake-1.0.9/Makefile.Solaris new file mode 100644 index 000000000..8b91379d7 --- /dev/null +++ b/contrib/other/sdlquake-1.0.9/Makefile.Solaris @@ -0,0 +1,483 @@ +# +# Quake Makefile for Solaris +# +# Nov '97 by Zoid +# +# ELF only +# + +VERSION=1.09 + +ifneq (,$(findstring i86pc,$(shell uname -m))) +ARCH=i386 +else +ARCH=sparc +endif + +MOUNT_DIR=/grog/Projects/WinQuake + +BUILD_DEBUG_DIR=debug$(ARCH) +BUILD_RELEASE_DIR=release$(ARCH) + +CC=gcc +BASE_CFLAGS=-I/usr/openwin/include + +RELEASE_CFLAGS=$(BASE_CFLAGS) -O6 -ffast-math -funroll-loops -fomit-frame-pointer -fexpensive-optimizations +DEBUG_CFLAGS=$(BASE_CFLAGS) -g +LDFLAGS=-R /usr/openwin/lib -L /usr/openwin/lib -lm -lX11 -lXext -lsocket -lnsl -lthread -ldl +XIL_LDFLAGS=-L /opt/SUNWits/Graphics-sw/xil/lib -R /opt/SUNWits/Graphics-sw/xil/lib:/usr/openwin/lib -L /usr/openwin/lib -lm -lxil -lX11 -lXext -lsocket -lnsl -lthread -ldl + +DO_CC=$(CC) $(CFLAGS) -o $@ -c $< +DO_AS=$(CC) $(CFLAGS) -DELF -x assembler-with-cpp -o $@ -c $< + +############################################################################# +# SETUP AND BUILD +############################################################################# + +TARGETS=$(BUILDDIR)/quake.sw $(BUILDDIR)/quake.xil + +build_debug: + @-mkdir $(BUILD_DEBUG_DIR) + $(MAKE) targets BUILDDIR=$(BUILD_DEBUG_DIR) CFLAGS="$(DEBUG_CFLAGS)" + +build_release: + @-mkdir $(BUILD_RELEASE_DIR) + $(MAKE) targets BUILDDIR=$(BUILD_RELEASE_DIR) CFLAGS="$(RELEASE_CFLAGS)" + +all: build_debug build_release + +targets: $(TARGETS) + +############################################################################# +# CLIENT/SERVER +############################################################################# + +QUAKE_OBJS= \ + $(BUILDDIR)/chase.o \ + $(BUILDDIR)/cl_demo.o \ + $(BUILDDIR)/cl_input.o \ + $(BUILDDIR)/cl_main.o \ + $(BUILDDIR)/cl_parse.o \ + $(BUILDDIR)/cl_tent.o \ + $(BUILDDIR)/cmd.o \ + $(BUILDDIR)/common.o \ + $(BUILDDIR)/console.o \ + $(BUILDDIR)/crc.o \ + $(BUILDDIR)/cvar.o \ + $(BUILDDIR)/draw.o \ + $(BUILDDIR)/d_edge.o \ + $(BUILDDIR)/d_fill.o \ + $(BUILDDIR)/d_init.o \ + $(BUILDDIR)/d_modech.o \ + $(BUILDDIR)/d_part.o \ + $(BUILDDIR)/d_polyse.o \ + $(BUILDDIR)/d_scan.o \ + $(BUILDDIR)/d_sky.o \ + $(BUILDDIR)/d_sprite.o \ + $(BUILDDIR)/d_surf.o \ + $(BUILDDIR)/d_vars.o \ + $(BUILDDIR)/d_zpoint.o \ + $(BUILDDIR)/host.o \ + $(BUILDDIR)/host_cmd.o \ + $(BUILDDIR)/keys.o \ + $(BUILDDIR)/menu.o \ + $(BUILDDIR)/mathlib.o \ + $(BUILDDIR)/model.o \ + $(BUILDDIR)/nonintel.o \ + $(BUILDDIR)/pr_cmds.o \ + $(BUILDDIR)/pr_edict.o \ + $(BUILDDIR)/pr_exec.o \ + $(BUILDDIR)/r_aclip.o \ + $(BUILDDIR)/r_alias.o \ + $(BUILDDIR)/r_bsp.o \ + $(BUILDDIR)/r_light.o \ + $(BUILDDIR)/r_draw.o \ + $(BUILDDIR)/r_efrag.o \ + $(BUILDDIR)/r_edge.o \ + $(BUILDDIR)/r_misc.o \ + $(BUILDDIR)/r_main.o \ + $(BUILDDIR)/r_sky.o \ + $(BUILDDIR)/r_sprite.o \ + $(BUILDDIR)/r_surf.o \ + $(BUILDDIR)/r_part.o \ + $(BUILDDIR)/r_vars.o \ + $(BUILDDIR)/screen.o \ + $(BUILDDIR)/sbar.o \ + $(BUILDDIR)/sv_main.o \ + $(BUILDDIR)/sv_phys.o \ + $(BUILDDIR)/sv_move.o \ + $(BUILDDIR)/sv_user.o \ + $(BUILDDIR)/zone.o \ + $(BUILDDIR)/view.o \ + $(BUILDDIR)/wad.o \ + $(BUILDDIR)/world.o \ + $(BUILDDIR)/cd_null.o \ + $(BUILDDIR)/snd_dma.o \ + $(BUILDDIR)/snd_mix.o \ + $(BUILDDIR)/snd_mem.o \ + $(BUILDDIR)/net_dgrm.o \ + $(BUILDDIR)/net_loop.o \ + $(BUILDDIR)/net_main.o \ + $(BUILDDIR)/net_vcr.o \ + $(BUILDDIR)/net_udp.o \ + $(BUILDDIR)/net_bsd.o \ + $(BUILDDIR)/sys_sun.o \ + $(BUILDDIR)/snd_sun.o + +QUAKE_AS_OBJS= \ + $(BUILDDIR)/d_copy.o \ + $(BUILDDIR)/d_draw.o \ + $(BUILDDIR)/d_draw16.o \ + $(BUILDDIR)/d_parta.o \ + $(BUILDDIR)/d_polysa.o \ + $(BUILDDIR)/d_scana.o \ + $(BUILDDIR)/d_spr8.o \ + $(BUILDDIR)/d_varsa.o \ + $(BUILDDIR)/math.o \ + $(BUILDDIR)/r_aliasa.o \ + $(BUILDDIR)/r_drawa.o \ + $(BUILDDIR)/r_edgea.o \ + $(BUILDDIR)/r_varsa.o \ + $(BUILDDIR)/surf16.o \ + $(BUILDDIR)/surf8.o \ + $(BUILDDIR)/worlda.o \ + $(BUILDDIR)/r_aclipa.o \ + $(BUILDDIR)/snd_mixa.o \ + $(BUILDDIR)/sys_dosa.o + +QUAKE_X_OBJS = $(BUILDDIR)/vid_sunx.o + +QUAKE_XIL_OBJS = $(BUILDDIR)/vid_sunxil.o + +ifeq ($(ARCH),i386) +$(BUILDDIR)/quake.sw : $(QUAKE_OBJS) $(QUAKE_AS_OBJS) $(QUAKE_X_OBJS) + $(CC) -o $(@) $(QUAKE_OBJS) $(QUAKE_AS_OBJS) $(QUAKE_X_OBJS) $(LDFLAGS) + +$(BUILDDIR)/quake.xil: $(QUAKE_OBJS) $(QUAKE_AS_OBJS) $(QUAKE_XIL_OBJS) + $(CC) -o $(@) $(QUAKE_OBJS) $(QUAKE_AS_OBJS) $(QUAKE_XIL_OBJS) $(XIL_LDFLAGS) +else +$(BUILDDIR)/quake.sw : $(QUAKE_OBJS) $(QUAKE_X_OBJS) + $(CC) -o $(@) $(QUAKE_OBJS) $(QUAKE_X_OBJS) $(LDFLAGS) + +$(BUILDDIR)/quake.xil: $(QUAKE_OBJS) $(QUAKE_XIL_OBJS) + $(CC) -o $(@) $(QUAKE_OBJS) $(QUAKE_XIL_OBJS) $(XIL_LDFLAGS) +endif + +## + +$(BUILDDIR)/chase.o : $(MOUNT_DIR)/chase.c + $(DO_CC) + +$(BUILDDIR)/cl_demo.o : $(MOUNT_DIR)/cl_demo.c + $(DO_CC) + +$(BUILDDIR)/cl_input.o : $(MOUNT_DIR)/cl_input.c + $(DO_CC) + +$(BUILDDIR)/cl_main.o : $(MOUNT_DIR)/cl_main.c + $(DO_CC) + +$(BUILDDIR)/cl_parse.o : $(MOUNT_DIR)/cl_parse.c + $(DO_CC) + +$(BUILDDIR)/cl_tent.o : $(MOUNT_DIR)/cl_tent.c + $(DO_CC) + +$(BUILDDIR)/cmd.o : $(MOUNT_DIR)/cmd.c + $(DO_CC) + +$(BUILDDIR)/common.o : $(MOUNT_DIR)/common.c + $(DO_CC) + +$(BUILDDIR)/console.o : $(MOUNT_DIR)/console.c + $(DO_CC) + +$(BUILDDIR)/crc.o : $(MOUNT_DIR)/crc.c + $(DO_CC) + +$(BUILDDIR)/cvar.o : $(MOUNT_DIR)/cvar.c + $(DO_CC) + +$(BUILDDIR)/draw.o : $(MOUNT_DIR)/draw.c + $(DO_CC) + +$(BUILDDIR)/d_edge.o : $(MOUNT_DIR)/d_edge.c + $(DO_CC) + +$(BUILDDIR)/d_fill.o : $(MOUNT_DIR)/d_fill.c + $(DO_CC) + +$(BUILDDIR)/d_init.o : $(MOUNT_DIR)/d_init.c + $(DO_CC) + +$(BUILDDIR)/d_modech.o : $(MOUNT_DIR)/d_modech.c + $(DO_CC) + +$(BUILDDIR)/d_part.o : $(MOUNT_DIR)/d_part.c + $(DO_CC) + +$(BUILDDIR)/d_polyse.o : $(MOUNT_DIR)/d_polyse.c + $(DO_CC) + +$(BUILDDIR)/d_scan.o : $(MOUNT_DIR)/d_scan.c + $(DO_CC) + +$(BUILDDIR)/d_sky.o : $(MOUNT_DIR)/d_sky.c + $(DO_CC) + +$(BUILDDIR)/d_sprite.o : $(MOUNT_DIR)/d_sprite.c + $(DO_CC) + +$(BUILDDIR)/d_surf.o : $(MOUNT_DIR)/d_surf.c + $(DO_CC) + +$(BUILDDIR)/d_vars.o : $(MOUNT_DIR)/d_vars.c + $(DO_CC) + +$(BUILDDIR)/d_zpoint.o : $(MOUNT_DIR)/d_zpoint.c + $(DO_CC) + +$(BUILDDIR)/host.o : $(MOUNT_DIR)/host.c + $(DO_CC) + +$(BUILDDIR)/host_cmd.o : $(MOUNT_DIR)/host_cmd.c + $(DO_CC) + +$(BUILDDIR)/keys.o : $(MOUNT_DIR)/keys.c + $(DO_CC) + +$(BUILDDIR)/menu.o : $(MOUNT_DIR)/menu.c + $(DO_CC) + +$(BUILDDIR)/mathlib.o : $(MOUNT_DIR)/mathlib.c + $(DO_CC) + +$(BUILDDIR)/model.o : $(MOUNT_DIR)/model.c + $(DO_CC) + +$(BUILDDIR)/nonintel.o : $(MOUNT_DIR)/nonintel.c + $(DO_CC) + +$(BUILDDIR)/pr_cmds.o : $(MOUNT_DIR)/pr_cmds.c + $(DO_CC) + +$(BUILDDIR)/pr_edict.o : $(MOUNT_DIR)/pr_edict.c + $(DO_CC) + +$(BUILDDIR)/pr_exec.o : $(MOUNT_DIR)/pr_exec.c + $(DO_CC) + +$(BUILDDIR)/r_aclip.o : $(MOUNT_DIR)/r_aclip.c + $(DO_CC) + +$(BUILDDIR)/r_alias.o : $(MOUNT_DIR)/r_alias.c + $(DO_CC) + +$(BUILDDIR)/r_bsp.o : $(MOUNT_DIR)/r_bsp.c + $(DO_CC) + +$(BUILDDIR)/r_light.o : $(MOUNT_DIR)/r_light.c + $(DO_CC) + +$(BUILDDIR)/r_draw.o : $(MOUNT_DIR)/r_draw.c + $(DO_CC) + +$(BUILDDIR)/r_efrag.o : $(MOUNT_DIR)/r_efrag.c + $(DO_CC) + +$(BUILDDIR)/r_edge.o : $(MOUNT_DIR)/r_edge.c + $(DO_CC) + +$(BUILDDIR)/r_misc.o : $(MOUNT_DIR)/r_misc.c + $(DO_CC) + +$(BUILDDIR)/r_main.o : $(MOUNT_DIR)/r_main.c + $(DO_CC) + +$(BUILDDIR)/r_sky.o : $(MOUNT_DIR)/r_sky.c + $(DO_CC) + +$(BUILDDIR)/r_sprite.o : $(MOUNT_DIR)/r_sprite.c + $(DO_CC) + +$(BUILDDIR)/r_surf.o : $(MOUNT_DIR)/r_surf.c + $(DO_CC) + +$(BUILDDIR)/r_part.o : $(MOUNT_DIR)/r_part.c + $(DO_CC) + +$(BUILDDIR)/r_vars.o : $(MOUNT_DIR)/r_vars.c + $(DO_CC) + +$(BUILDDIR)/screen.o : $(MOUNT_DIR)/screen.c + $(DO_CC) + +$(BUILDDIR)/sbar.o : $(MOUNT_DIR)/sbar.c + $(DO_CC) + +$(BUILDDIR)/sv_main.o : $(MOUNT_DIR)/sv_main.c + $(DO_CC) + +$(BUILDDIR)/sv_phys.o : $(MOUNT_DIR)/sv_phys.c + $(DO_CC) + +$(BUILDDIR)/sv_move.o : $(MOUNT_DIR)/sv_move.c + $(DO_CC) + +$(BUILDDIR)/sv_user.o : $(MOUNT_DIR)/sv_user.c + $(DO_CC) + +$(BUILDDIR)/zone.o : $(MOUNT_DIR)/zone.c + $(DO_CC) + +$(BUILDDIR)/view.o : $(MOUNT_DIR)/view.c + $(DO_CC) + +$(BUILDDIR)/wad.o : $(MOUNT_DIR)/wad.c + $(DO_CC) + +$(BUILDDIR)/world.o : $(MOUNT_DIR)/world.c + $(DO_CC) + +$(BUILDDIR)/cd_null.o : $(MOUNT_DIR)/cd_null.c + $(DO_CC) + +$(BUILDDIR)/snd_dma.o : $(MOUNT_DIR)/snd_dma.c + $(DO_CC) + +$(BUILDDIR)/snd_mix.o : $(MOUNT_DIR)/snd_mix.c + $(DO_CC) + +$(BUILDDIR)/snd_mem.o : $(MOUNT_DIR)/snd_mem.c + $(DO_CC) + +$(BUILDDIR)/net_dgrm.o : $(MOUNT_DIR)/net_dgrm.c + $(DO_CC) + +$(BUILDDIR)/net_loop.o : $(MOUNT_DIR)/net_loop.c + $(DO_CC) + +$(BUILDDIR)/net_main.o : $(MOUNT_DIR)/net_main.c + $(DO_CC) + +$(BUILDDIR)/net_vcr.o : $(MOUNT_DIR)/net_vcr.c + $(DO_CC) + +$(BUILDDIR)/net_udp.o : $(MOUNT_DIR)/net_udp.c + $(DO_CC) + +$(BUILDDIR)/net_bsd.o : $(MOUNT_DIR)/net_bsd.c + $(DO_CC) + +$(BUILDDIR)/sys_sun.o : $(MOUNT_DIR)/sys_sun.c + $(DO_CC) + +$(BUILDDIR)/snd_sun.o : $(MOUNT_DIR)/snd_sun.c + $(DO_CC) + +$(BUILDDIR)/in_sun.o : $(MOUNT_DIR)/in_sun.c + $(DO_CC) + +$(BUILDDIR)/vid_sunx.o : $(MOUNT_DIR)/vid_sunx.c + $(DO_CC) + +$(BUILDDIR)/vid_sunxil.o : $(MOUNT_DIR)/vid_sunxil.c + $(DO_CC) + +##### + +$(BUILDDIR)/d_copy.o : $(MOUNT_DIR)/d_copy.s + $(DO_AS) + +$(BUILDDIR)/d_draw.o : $(MOUNT_DIR)/d_draw.s + $(DO_AS) + +$(BUILDDIR)/d_draw16.o : $(MOUNT_DIR)/d_draw16.s + $(DO_AS) + +$(BUILDDIR)/d_parta.o : $(MOUNT_DIR)/d_parta.s + $(DO_AS) + +$(BUILDDIR)/d_polysa.o : $(MOUNT_DIR)/d_polysa.s + $(DO_AS) + +$(BUILDDIR)/d_scana.o : $(MOUNT_DIR)/d_scana.s + $(DO_AS) + +$(BUILDDIR)/d_spr8.o : $(MOUNT_DIR)/d_spr8.s + $(DO_AS) + +$(BUILDDIR)/d_varsa.o : $(MOUNT_DIR)/d_varsa.s + $(DO_AS) + +$(BUILDDIR)/math.o : $(MOUNT_DIR)/math.s + $(DO_AS) + +$(BUILDDIR)/r_aliasa.o : $(MOUNT_DIR)/r_aliasa.s + $(DO_AS) + +$(BUILDDIR)/r_drawa.o : $(MOUNT_DIR)/r_drawa.s + $(DO_AS) + +$(BUILDDIR)/r_edgea.o : $(MOUNT_DIR)/r_edgea.s + $(DO_AS) + +$(BUILDDIR)/r_varsa.o : $(MOUNT_DIR)/r_varsa.s + $(DO_AS) + +$(BUILDDIR)/surf16.o : $(MOUNT_DIR)/surf16.s + $(DO_AS) + +$(BUILDDIR)/surf8.o : $(MOUNT_DIR)/surf8.s + $(DO_AS) + +$(BUILDDIR)/worlda.o : $(MOUNT_DIR)/worlda.s + $(DO_AS) + +$(BUILDDIR)/r_aclipa.o : $(MOUNT_DIR)/r_aclipa.s + $(DO_AS) + +$(BUILDDIR)/snd_mixa.o : $(MOUNT_DIR)/snd_mixa.s + $(DO_AS) + +$(BUILDDIR)/sys_dosa.o : $(MOUNT_DIR)/sys_dosa.s + $(DO_AS) + +############################################################################# +# TAR +############################################################################# + +# Make RPMs. You need to be root to make this work +RPMDIR = /var/tmp/quake-$(VERSION) + +tar: + if [ ! -d archives ];then mkdir archives;fi + $(MAKE) copyfiles COPYDIR=$(RPMDIR) + cd $(RPMDIR); tar cvf q2ded-$(VERSION)-$(ARCH)-sun-solaris2.5.1.tar * + cd $(RPMDIR); compress q2ded-$(VERSION)-$(ARCH)-sun-solaris2.5.1.tar + mv $(RPMDIR)/*.tar.Z archives/. + rm -rf $(RPMDIR) + +copyfiles: + -mkdirhier $(COPYDIR) + cp $(BUILD_RELEASE_DIR)/quake.sw $(COPYDIR) + cp $(BUILD_RELEASE_DIR)/quake.xil $(COPYDIR) + strip $(COPYDIR)/quake + strip $(COPYDIR)/quake.xil + cp $(MOUNT_DIR)/README.Solaris $(COPYDIR)/README.Solaris + +############################################################################# +# MISC +############################################################################# + +clean: clean-debug clean-release + +clean-debug: + $(MAKE) clean2 BUILDDIR=$(BUILD_DEBUG_DIR) CFLAGS="$(DEBUG_CFLAGS)" + +clean-release: + $(MAKE) clean2 BUILDDIR=$(BUILD_RELEASE_DIR) CFLAGS="$(DEBUG_CFLAGS)" + +clean2: + -rm -f $(QUAKE_OBJS) $(QUAKE_X_OBJS) $(QUAKE_XIL_OBJS) + diff --git a/contrib/other/sdlquake-1.0.9/Makefile.am b/contrib/other/sdlquake-1.0.9/Makefile.am new file mode 100644 index 000000000..0b8b256a8 --- /dev/null +++ b/contrib/other/sdlquake-1.0.9/Makefile.am @@ -0,0 +1,292 @@ + +bin_PROGRAMS = sdlquake + +sdlquake_LDADD = @MATHLIB@ @INETLIB@ + +sdlquake_SOURCES = \ + adivtab.h \ + anorm_dots.h \ + anorms.h \ + asm_draw.h \ + asm_i386.h \ + block16.h \ + block8.h \ + bspfile.h \ + cd_sdl.c \ + cdaudio.h \ + chase.c \ + cl_demo.c \ + cl_input.c \ + cl_main.c \ + cl_parse.c \ + cl_tent.c \ + clean.bat \ + client.h \ + cmd.c \ + cmd.h \ + common.c \ + common.h \ + conproc.h \ + console.c \ + console.h \ + crc.c \ + crc.h \ + cvar.c \ + cvar.h \ + d_copy.S \ + d_edge.c \ + d_fill.c \ + d_iface.h \ + d_ifacea.h \ + d_init.c \ + d_local.h \ + d_modech.c \ + d_part.c \ + d_polyse.c \ + d_scan.c \ + d_sky.c \ + d_sprite.c \ + d_surf.c \ + d_zpoint.c \ + dosasm.S \ + dosisms.h \ + draw.c \ + draw.h \ + host.c \ + host_cmd.c \ + input.h \ + keys.c \ + keys.h \ + mathlib.c \ + mathlib.h \ + menu.c \ + menu.h \ + model.c \ + model.h \ + modelgen.h \ + mpdosock.h \ + net.h \ + net_bsd.c \ + net_bw.h \ + net_dgrm.c \ + net_dgrm.h \ + net_loop.c \ + net_loop.h \ + net_main.c \ + net_udp.c \ + net_udp.h \ + net_vcr.c \ + net_vcr.h \ + net_wso.c \ + pr_cmds.c \ + pr_comp.h \ + pr_edict.c \ + pr_exec.c \ + progdefs.h \ + progs.h \ + protocol.h \ + quakeasm.h \ + quakedef.h \ + r_aclip.c \ + r_alias.c \ + r_bsp.c \ + r_draw.c \ + r_edge.c \ + r_efrag.c \ + r_light.c \ + r_local.h \ + r_main.c \ + r_misc.c \ + r_part.c \ + r_shared.h \ + r_sky.c \ + r_sprite.c \ + r_surf.c \ + r_vars.c \ + r_varsa.S \ + render.h \ + resource.h \ + sbar.c \ + sbar.h \ + scitech \ + screen.c \ + screen.h \ + server.h \ + snd_dma.c \ + snd_mem.c \ + snd_mix.c \ + snd_sdl.c \ + sound.h \ + spritegn.h \ + sv_main.c \ + sv_move.c \ + sv_phys.c \ + sv_user.c \ + sys.h \ + sys_sdl.c \ + vgamodes.h \ + vid.h \ + vid_sdl.c \ + view.c \ + view.h \ + wad.c \ + wad.h \ + winquake.h \ + world.c \ + world.h \ + zone.c \ + zone.h \ + $(X86_SRCS) $(NONX86_SRCS) + +X86_SRCS = \ + snd_mixa.S \ + sys_dosa.S \ + d_draw.S \ + d_draw16.S \ + d_parta.S \ + d_polysa.S \ + d_scana.S \ + d_spr8.S \ + d_varsa.S \ + math.S \ + r_aclipa.S \ + r_aliasa.S \ + r_drawa.S \ + r_edgea.S \ + surf16.S \ + surf8.S \ + worlda.S + +NONX86_SRCS = \ + d_vars.c \ + nonintel.c + + +NULL_SRCS = \ + cd_null.c \ + in_null.c \ + net_none.c \ + snd_null.c \ + sys_null.c \ + vid_null.c + +DOS_SRCS = \ + cd_audio.c \ + dos_v2.c \ + in_dos.c \ + mplib.c \ + mplpc.c \ + net_bw.c \ + net_comx.c \ + net_dos.c \ + net_ipx.c \ + net_ipx.h \ + net_ser.c \ + net_ser.h \ + snd_dos.c \ + snd_gus.c \ + sys_dos.c \ + vid_dos.c \ + vid_dos.h \ + vid_ext.c \ + vid_vga.c \ + vregset.c \ + vregset.h + +WIN_SRCS = \ + cd_win.c \ + conproc.c \ + in_win.c \ + net_mp.c \ + net_mp.h \ + net_win.c \ + net_wins.c \ + net_wins.h \ + net_wipx.c \ + net_wipx.h \ + snd_win.c \ + sys_win.c \ + sys_wina.S \ + sys_wind.c \ + vid_win.c + +LNX_SRCS = \ + cd_linux.c \ + snd_linux.c \ + sys_linux.c \ + vid_svgalib.c \ + vid_x.c + +SUN_SRCS = \ + snd_sun.c \ + in_sun.c \ + sys_sun.c \ + vid_sunx.c \ + vid_sunxil.c + +NEXT_SRCS = \ + snd_next.c + +GL_SRCS = \ + gl_draw.c \ + gl_mesh.c \ + gl_model.c \ + gl_model.h \ + gl_refrag.c \ + gl_rlight.c \ + gl_rmain.c \ + gl_rmisc.c \ + gl_rsurf.c \ + gl_screen.c \ + gl_test.c \ + gl_vidlinux.c \ + gl_vidlinuxglx.c \ + gl_vidnt.c \ + gl_warp.c \ + gl_warp_sin.h \ + glquake.h \ + glquake2.h + +EXTRA_DIST = \ + README.SDL \ + 3dfx.txt \ + Makefile.Solaris \ + Makefile.linuxi386 \ + README.Solaris \ + WinQuake.dsp \ + WinQuake.dsw \ + WinQuake.mdp \ + WinQuake.ncb \ + WinQuake.opt \ + WinQuake.plg \ + cwsdpmi.exe \ + glqnotes.txt \ + makezip.bat \ + progdefs.q1 \ + progdefs.q2 \ + q.bat \ + qa.bat \ + qb.bat \ + qe3.ico \ + qt.bat \ + quake-data.spec.sh \ + quake-hipnotic.spec.sh \ + quake-rogue.spec.sh \ + quake-shareware.spec.sh \ + quake.gif \ + quake.ico \ + quake.spec.sh \ + winquake.aps \ + winquake.rc \ + wq.bat \ + wqreadme.txt \ + $(NULL_SRCS) \ + $(DOS_SRCS) \ + $(WIN_SRCS) \ + $(LNX_SRCS) \ + $(SUN_SRCS) \ + $(NEXT_SRCS) \ + $(GL_SRCS) + +dist-hook: + cp -rp data docs dxsdk gas2masm kit scitech $(distdir)/ diff --git a/contrib/other/sdlquake-1.0.9/Makefile.in b/contrib/other/sdlquake-1.0.9/Makefile.in new file mode 100644 index 000000000..c9cd67ef4 --- /dev/null +++ b/contrib/other/sdlquake-1.0.9/Makefile.in @@ -0,0 +1,765 @@ +# Makefile.in generated automatically by automake 1.4 from Makefile.am + +# Copyright (C) 1994, 1995-8, 1999 Free Software Foundation, Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + + +SHELL = @SHELL@ + +srcdir = @srcdir@ +top_srcdir = @top_srcdir@ +VPATH = @srcdir@ +prefix = @prefix@ +exec_prefix = @exec_prefix@ + +bindir = @bindir@ +sbindir = @sbindir@ +libexecdir = @libexecdir@ +datadir = @datadir@ +sysconfdir = @sysconfdir@ +sharedstatedir = @sharedstatedir@ +localstatedir = @localstatedir@ +libdir = @libdir@ +infodir = @infodir@ +mandir = @mandir@ +includedir = @includedir@ +oldincludedir = /usr/include + +DESTDIR = + +pkgdatadir = $(datadir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ + +top_builddir = . + +ACLOCAL = @ACLOCAL@ +AUTOCONF = @AUTOCONF@ +AUTOMAKE = @AUTOMAKE@ +AUTOHEADER = @AUTOHEADER@ + +INSTALL = @INSTALL@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ $(AM_INSTALL_PROGRAM_FLAGS) +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +transform = @program_transform_name@ + +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +host_alias = @host_alias@ +host_triplet = @host@ +CC = @CC@ +ICONOBJ = @ICONOBJ@ +INETLIB = @INETLIB@ +MAKEINFO = @MAKEINFO@ +MATHLIB = @MATHLIB@ +PACKAGE = @PACKAGE@ +SDL_CFLAGS = @SDL_CFLAGS@ +SDL_CONFIG = @SDL_CONFIG@ +SDL_LIBS = @SDL_LIBS@ +VERSION = @VERSION@ + +bin_PROGRAMS = sdlquake + +sdlquake_LDADD = @MATHLIB@ @INETLIB@ + +sdlquake_SOURCES = adivtab.h anorm_dots.h anorms.h asm_draw.h asm_i386.h block16.h block8.h bspfile.h cd_sdl.c cdaudio.h chase.c cl_demo.c cl_input.c cl_main.c cl_parse.c cl_tent.c clean.bat client.h cmd.c cmd.h common.c common.h conproc.h console.c console.h crc.c crc.h cvar.c cvar.h d_copy.S d_edge.c d_fill.c d_iface.h d_ifacea.h d_init.c d_local.h d_modech.c d_part.c d_polyse.c d_scan.c d_sky.c d_sprite.c d_surf.c d_zpoint.c dosasm.S dosisms.h draw.c draw.h host.c host_cmd.c input.h keys.c keys.h mathlib.c mathlib.h menu.c menu.h model.c model.h modelgen.h mpdosock.h net.h net_bsd.c net_bw.h net_dgrm.c net_dgrm.h net_loop.c net_loop.h net_main.c net_udp.c net_udp.h net_vcr.c net_vcr.h net_wso.c pr_cmds.c pr_comp.h pr_edict.c pr_exec.c progdefs.h progs.h protocol.h quakeasm.h quakedef.h r_aclip.c r_alias.c r_bsp.c r_draw.c r_edge.c r_efrag.c r_light.c r_local.h r_main.c r_misc.c r_part.c r_shared.h r_sky.c r_sprite.c r_surf.c r_vars.c r_varsa.S render.h resource.h sbar.c sbar.h scitech screen.c screen.h server.h snd_dma.c snd_mem.c snd_mix.c snd_sdl.c sound.h spritegn.h sv_main.c sv_move.c sv_phys.c sv_user.c sys.h sys_sdl.c vgamodes.h vid.h vid_sdl.c view.c view.h wad.c wad.h winquake.h world.c world.h zone.c zone.h $(X86_SRCS) $(NONX86_SRCS) + + +X86_SRCS = snd_mixa.S sys_dosa.S d_draw.S d_draw16.S d_parta.S d_polysa.S d_scana.S d_spr8.S d_varsa.S math.S r_aclipa.S r_aliasa.S r_drawa.S r_edgea.S surf16.S surf8.S worlda.S + + +NONX86_SRCS = d_vars.c nonintel.c + + +NULL_SRCS = cd_null.c in_null.c net_none.c snd_null.c sys_null.c vid_null.c + + +DOS_SRCS = cd_audio.c dos_v2.c in_dos.c mplib.c mplpc.c net_bw.c net_comx.c net_dos.c net_ipx.c net_ipx.h net_ser.c net_ser.h snd_dos.c snd_gus.c sys_dos.c vid_dos.c vid_dos.h vid_ext.c vid_vga.c vregset.c vregset.h + + +WIN_SRCS = cd_win.c conproc.c in_win.c net_mp.c net_mp.h net_win.c net_wins.c net_wins.h net_wipx.c net_wipx.h snd_win.c sys_win.c sys_wina.S sys_wind.c vid_win.c + + +LNX_SRCS = cd_linux.c snd_linux.c sys_linux.c vid_svgalib.c vid_x.c + + +SUN_SRCS = snd_sun.c in_sun.c sys_sun.c vid_sunx.c vid_sunxil.c + + +NEXT_SRCS = snd_next.c + + +GL_SRCS = gl_draw.c gl_mesh.c gl_model.c gl_model.h gl_refrag.c gl_rlight.c gl_rmain.c gl_rmisc.c gl_rsurf.c gl_screen.c gl_test.c gl_vidlinux.c gl_vidlinuxglx.c gl_vidnt.c gl_warp.c gl_warp_sin.h glquake.h glquake2.h + + +EXTRA_DIST = README.SDL 3dfx.txt Makefile.Solaris Makefile.linuxi386 README.Solaris WinQuake.dsp WinQuake.dsw WinQuake.mdp WinQuake.ncb WinQuake.opt WinQuake.plg cwsdpmi.exe glqnotes.txt makezip.bat progdefs.q1 progdefs.q2 q.bat qa.bat qb.bat qe3.ico qt.bat quake-data.spec.sh quake-hipnotic.spec.sh quake-rogue.spec.sh quake-shareware.spec.sh quake.gif quake.ico quake.spec.sh winquake.aps winquake.rc wq.bat wqreadme.txt $(NULL_SRCS) $(DOS_SRCS) $(WIN_SRCS) $(LNX_SRCS) $(SUN_SRCS) $(NEXT_SRCS) $(GL_SRCS) + +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs +CONFIG_CLEAN_FILES = +PROGRAMS = $(bin_PROGRAMS) + + +DEFS = @DEFS@ -I. -I$(srcdir) +CPPFLAGS = @CPPFLAGS@ +LDFLAGS = @LDFLAGS@ +LIBS = @LIBS@ +sdlquake_OBJECTS = cd_sdl.o chase.o cl_demo.o cl_input.o cl_main.o \ +cl_parse.o cl_tent.o cmd.o common.o console.o crc.o cvar.o d_copy.o \ +d_edge.o d_fill.o d_init.o d_modech.o d_part.o d_polyse.o d_scan.o \ +d_sky.o d_sprite.o d_surf.o d_zpoint.o dosasm.o draw.o host.o \ +host_cmd.o keys.o mathlib.o menu.o model.o net_bsd.o net_dgrm.o \ +net_loop.o net_main.o net_udp.o net_vcr.o net_wso.o pr_cmds.o \ +pr_edict.o pr_exec.o r_aclip.o r_alias.o r_bsp.o r_draw.o r_edge.o \ +r_efrag.o r_light.o r_main.o r_misc.o r_part.o r_sky.o r_sprite.o \ +r_surf.o r_vars.o r_varsa.o sbar.o screen.o snd_dma.o snd_mem.o \ +snd_mix.o snd_sdl.o sv_main.o sv_move.o sv_phys.o sv_user.o sys_sdl.o \ +vid_sdl.o view.o wad.o world.o zone.o snd_mixa.o sys_dosa.o d_draw.o \ +d_draw16.o d_parta.o d_polysa.o d_scana.o d_spr8.o d_varsa.o math.o \ +r_aclipa.o r_aliasa.o r_drawa.o r_edgea.o surf16.o surf8.o worlda.o \ +d_vars.o nonintel.o +sdlquake_DEPENDENCIES = +sdlquake_LDFLAGS = +CFLAGS = @CFLAGS@ +COMPILE = $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +CCLD = $(CC) +LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(LDFLAGS) -o $@ +DIST_COMMON = COPYING Makefile.am Makefile.in acinclude.m4 aclocal.m4 \ +config.guess config.sub configure configure.in install-sh missing \ +mkinstalldirs + + +DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST) + +TAR = gtar +GZIP_ENV = --best +SOURCES = $(sdlquake_SOURCES) +OBJECTS = $(sdlquake_OBJECTS) + +all: all-redirect +.SUFFIXES: +.SUFFIXES: .S .c .o .s +$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4) + cd $(top_srcdir) && $(AUTOMAKE) --foreign --include-deps Makefile + +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + cd $(top_builddir) \ + && CONFIG_FILES=$@ CONFIG_HEADERS= $(SHELL) ./config.status + +$(ACLOCAL_M4): configure.in acinclude.m4 + cd $(srcdir) && $(ACLOCAL) + +config.status: $(srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + $(SHELL) ./config.status --recheck +$(srcdir)/configure: $(srcdir)/configure.in $(ACLOCAL_M4) $(CONFIGURE_DEPENDENCIES) + cd $(srcdir) && $(AUTOCONF) + +mostlyclean-binPROGRAMS: + +clean-binPROGRAMS: + -test -z "$(bin_PROGRAMS)" || rm -f $(bin_PROGRAMS) + +distclean-binPROGRAMS: + +maintainer-clean-binPROGRAMS: + +install-binPROGRAMS: $(bin_PROGRAMS) + @$(NORMAL_INSTALL) + $(mkinstalldirs) $(DESTDIR)$(bindir) + @list='$(bin_PROGRAMS)'; for p in $$list; do \ + if test -f $$p; then \ + echo " $(INSTALL_PROGRAM) $$p $(DESTDIR)$(bindir)/`echo $$p|sed 's/$(EXEEXT)$$//'|sed '$(transform)'|sed 's/$$/$(EXEEXT)/'`"; \ + $(INSTALL_PROGRAM) $$p $(DESTDIR)$(bindir)/`echo $$p|sed 's/$(EXEEXT)$$//'|sed '$(transform)'|sed 's/$$/$(EXEEXT)/'`; \ + else :; fi; \ + done + +uninstall-binPROGRAMS: + @$(NORMAL_UNINSTALL) + list='$(bin_PROGRAMS)'; for p in $$list; do \ + rm -f $(DESTDIR)$(bindir)/`echo $$p|sed 's/$(EXEEXT)$$//'|sed '$(transform)'|sed 's/$$/$(EXEEXT)/'`; \ + done + +.c.o: + $(COMPILE) -c $< + +.s.o: + $(COMPILE) -c $< + +.S.o: + $(COMPILE) -c $< + +mostlyclean-compile: + -rm -f *.o core *.core + +clean-compile: + +distclean-compile: + -rm -f *.tab.c + +maintainer-clean-compile: + +sdlquake: $(sdlquake_OBJECTS) $(sdlquake_DEPENDENCIES) + @rm -f sdlquake + $(LINK) $(sdlquake_LDFLAGS) $(sdlquake_OBJECTS) $(sdlquake_LDADD) $(LIBS) + +tags: TAGS + +ID: $(HEADERS) $(SOURCES) $(LISP) + list='$(SOURCES) $(HEADERS)'; \ + unique=`for i in $$list; do echo $$i; done | \ + awk ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + here=`pwd` && cd $(srcdir) \ + && mkid -f$$here/ID $$unique $(LISP) + +TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) $(LISP) + tags=; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS)'; \ + unique=`for i in $$list; do echo $$i; done | \ + awk ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + test -z "$(ETAGS_ARGS)$$unique$(LISP)$$tags" \ + || (cd $(srcdir) && etags $(ETAGS_ARGS) $$tags $$unique $(LISP) -o $$here/TAGS) + +mostlyclean-tags: + +clean-tags: + +distclean-tags: + -rm -f TAGS ID + +maintainer-clean-tags: + +distdir = $(PACKAGE)-$(VERSION) +top_distdir = $(distdir) + +# This target untars the dist file and tries a VPATH configuration. Then +# it guarantees that the distribution is self-contained by making another +# tarfile. +distcheck: dist + -rm -rf $(distdir) + GZIP=$(GZIP_ENV) $(TAR) zxf $(distdir).tar.gz + mkdir $(distdir)/=build + mkdir $(distdir)/=inst + dc_install_base=`cd $(distdir)/=inst && pwd`; \ + cd $(distdir)/=build \ + && ../configure --srcdir=.. --prefix=$$dc_install_base \ + && $(MAKE) $(AM_MAKEFLAGS) \ + && $(MAKE) $(AM_MAKEFLAGS) dvi \ + && $(MAKE) $(AM_MAKEFLAGS) check \ + && $(MAKE) $(AM_MAKEFLAGS) install \ + && $(MAKE) $(AM_MAKEFLAGS) installcheck \ + && $(MAKE) $(AM_MAKEFLAGS) dist + -rm -rf $(distdir) + @banner="$(distdir).tar.gz is ready for distribution"; \ + dashes=`echo "$$banner" | sed s/./=/g`; \ + echo "$$dashes"; \ + echo "$$banner"; \ + echo "$$dashes" +dist: distdir + -chmod -R a+r $(distdir) + GZIP=$(GZIP_ENV) $(TAR) chozf $(distdir).tar.gz $(distdir) + -rm -rf $(distdir) +dist-all: distdir + -chmod -R a+r $(distdir) + GZIP=$(GZIP_ENV) $(TAR) chozf $(distdir).tar.gz $(distdir) + -rm -rf $(distdir) +distdir: $(DISTFILES) + -rm -rf $(distdir) + mkdir $(distdir) + -chmod 777 $(distdir) + @for file in $(DISTFILES); do \ + d=$(srcdir); \ + if test -d $$d/$$file; then \ + cp -pr $$/$$file $(distdir)/$$file; \ + else \ + test -f $(distdir)/$$file \ + || ln $$d/$$file $(distdir)/$$file 2> /dev/null \ + || cp -p $$d/$$file $(distdir)/$$file || :; \ + fi; \ + done + $(MAKE) $(AM_MAKEFLAGS) top_distdir="$(top_distdir)" distdir="$(distdir)" dist-hook +cd_sdl.o: cd_sdl.c quakedef.h common.h bspfile.h vid.h sys.h zone.h \ + mathlib.h wad.h draw.h cvar.h screen.h net.h protocol.h cmd.h \ + sbar.h sound.h render.h client.h progs.h pr_comp.h progdefs.h \ + progdefs.q1 server.h model.h modelgen.h spritegn.h d_iface.h \ + input.h world.h keys.h console.h view.h menu.h crc.h cdaudio.h +chase.o: chase.c quakedef.h common.h bspfile.h vid.h sys.h zone.h \ + mathlib.h wad.h draw.h cvar.h screen.h net.h protocol.h cmd.h \ + sbar.h sound.h render.h client.h progs.h pr_comp.h progdefs.h \ + progdefs.q1 server.h model.h modelgen.h spritegn.h d_iface.h \ + input.h world.h keys.h console.h view.h menu.h crc.h cdaudio.h +cl_demo.o: cl_demo.c quakedef.h common.h bspfile.h vid.h sys.h zone.h \ + mathlib.h wad.h draw.h cvar.h screen.h net.h protocol.h cmd.h \ + sbar.h sound.h render.h client.h progs.h pr_comp.h progdefs.h \ + progdefs.q1 server.h model.h modelgen.h spritegn.h d_iface.h \ + input.h world.h keys.h console.h view.h menu.h crc.h cdaudio.h +cl_input.o: cl_input.c quakedef.h common.h bspfile.h vid.h sys.h zone.h \ + mathlib.h wad.h draw.h cvar.h screen.h net.h protocol.h cmd.h \ + sbar.h sound.h render.h client.h progs.h pr_comp.h progdefs.h \ + progdefs.q1 server.h model.h modelgen.h spritegn.h d_iface.h \ + input.h world.h keys.h console.h view.h menu.h crc.h cdaudio.h +cl_main.o: cl_main.c quakedef.h common.h bspfile.h vid.h sys.h zone.h \ + mathlib.h wad.h draw.h cvar.h screen.h net.h protocol.h cmd.h \ + sbar.h sound.h render.h client.h progs.h pr_comp.h progdefs.h \ + progdefs.q1 server.h model.h modelgen.h spritegn.h d_iface.h \ + input.h world.h keys.h console.h view.h menu.h crc.h cdaudio.h +cl_parse.o: cl_parse.c quakedef.h common.h bspfile.h vid.h sys.h zone.h \ + mathlib.h wad.h draw.h cvar.h screen.h net.h protocol.h cmd.h \ + sbar.h sound.h render.h client.h progs.h pr_comp.h progdefs.h \ + progdefs.q1 server.h model.h modelgen.h spritegn.h d_iface.h \ + input.h world.h keys.h console.h view.h menu.h crc.h cdaudio.h +cl_tent.o: cl_tent.c quakedef.h common.h bspfile.h vid.h sys.h zone.h \ + mathlib.h wad.h draw.h cvar.h screen.h net.h protocol.h cmd.h \ + sbar.h sound.h render.h client.h progs.h pr_comp.h progdefs.h \ + progdefs.q1 server.h model.h modelgen.h spritegn.h d_iface.h \ + input.h world.h keys.h console.h view.h menu.h crc.h cdaudio.h +cmd.o: cmd.c quakedef.h common.h bspfile.h vid.h sys.h zone.h mathlib.h \ + wad.h draw.h cvar.h screen.h net.h protocol.h cmd.h sbar.h \ + sound.h render.h client.h progs.h pr_comp.h progdefs.h \ + progdefs.q1 server.h model.h modelgen.h spritegn.h d_iface.h \ + input.h world.h keys.h console.h view.h menu.h crc.h cdaudio.h +common.o: common.c quakedef.h common.h bspfile.h vid.h sys.h zone.h \ + mathlib.h wad.h draw.h cvar.h screen.h net.h protocol.h cmd.h \ + sbar.h sound.h render.h client.h progs.h pr_comp.h progdefs.h \ + progdefs.q1 server.h model.h modelgen.h spritegn.h d_iface.h \ + input.h world.h keys.h console.h view.h menu.h crc.h cdaudio.h +console.o: console.c quakedef.h common.h bspfile.h vid.h sys.h zone.h \ + mathlib.h wad.h draw.h cvar.h screen.h net.h protocol.h cmd.h \ + sbar.h sound.h render.h client.h progs.h pr_comp.h progdefs.h \ + progdefs.q1 server.h model.h modelgen.h spritegn.h d_iface.h \ + input.h world.h keys.h console.h view.h menu.h crc.h cdaudio.h +crc.o: crc.c quakedef.h common.h bspfile.h vid.h sys.h zone.h mathlib.h \ + wad.h draw.h cvar.h screen.h net.h protocol.h cmd.h sbar.h \ + sound.h render.h client.h progs.h pr_comp.h progdefs.h \ + progdefs.q1 server.h model.h modelgen.h spritegn.h d_iface.h \ + input.h world.h keys.h console.h view.h menu.h crc.h cdaudio.h +cvar.o: cvar.c quakedef.h common.h bspfile.h vid.h sys.h zone.h \ + mathlib.h wad.h draw.h cvar.h screen.h net.h protocol.h cmd.h \ + sbar.h sound.h render.h client.h progs.h pr_comp.h progdefs.h \ + progdefs.q1 server.h model.h modelgen.h spritegn.h d_iface.h \ + input.h world.h keys.h console.h view.h menu.h crc.h cdaudio.h +d_edge.o: d_edge.c quakedef.h common.h bspfile.h vid.h sys.h zone.h \ + mathlib.h wad.h draw.h cvar.h screen.h net.h protocol.h cmd.h \ + sbar.h sound.h render.h client.h progs.h pr_comp.h progdefs.h \ + progdefs.q1 server.h model.h modelgen.h spritegn.h d_iface.h \ + input.h world.h keys.h console.h view.h menu.h crc.h cdaudio.h \ + d_local.h r_shared.h +d_fill.o: d_fill.c quakedef.h common.h bspfile.h vid.h sys.h zone.h \ + mathlib.h wad.h draw.h cvar.h screen.h net.h protocol.h cmd.h \ + sbar.h sound.h render.h client.h progs.h pr_comp.h progdefs.h \ + progdefs.q1 server.h model.h modelgen.h spritegn.h d_iface.h \ + input.h world.h keys.h console.h view.h menu.h crc.h cdaudio.h +d_init.o: d_init.c quakedef.h common.h bspfile.h vid.h sys.h zone.h \ + mathlib.h wad.h draw.h cvar.h screen.h net.h protocol.h cmd.h \ + sbar.h sound.h render.h client.h progs.h pr_comp.h progdefs.h \ + progdefs.q1 server.h model.h modelgen.h spritegn.h d_iface.h \ + input.h world.h keys.h console.h view.h menu.h crc.h cdaudio.h \ + d_local.h r_shared.h +d_modech.o: d_modech.c quakedef.h common.h bspfile.h vid.h sys.h zone.h \ + mathlib.h wad.h draw.h cvar.h screen.h net.h protocol.h cmd.h \ + sbar.h sound.h render.h client.h progs.h pr_comp.h progdefs.h \ + progdefs.q1 server.h model.h modelgen.h spritegn.h d_iface.h \ + input.h world.h keys.h console.h view.h menu.h crc.h cdaudio.h \ + d_local.h r_shared.h +d_part.o: d_part.c quakedef.h common.h bspfile.h vid.h sys.h zone.h \ + mathlib.h wad.h draw.h cvar.h screen.h net.h protocol.h cmd.h \ + sbar.h sound.h render.h client.h progs.h pr_comp.h progdefs.h \ + progdefs.q1 server.h model.h modelgen.h spritegn.h d_iface.h \ + input.h world.h keys.h console.h view.h menu.h crc.h cdaudio.h \ + d_local.h r_shared.h +d_polyse.o: d_polyse.c quakedef.h common.h bspfile.h vid.h sys.h zone.h \ + mathlib.h wad.h draw.h cvar.h screen.h net.h protocol.h cmd.h \ + sbar.h sound.h render.h client.h progs.h pr_comp.h progdefs.h \ + progdefs.q1 server.h model.h modelgen.h spritegn.h d_iface.h \ + input.h world.h keys.h console.h view.h menu.h crc.h cdaudio.h \ + r_local.h r_shared.h d_local.h adivtab.h +draw.o: draw.c quakedef.h common.h bspfile.h vid.h sys.h zone.h \ + mathlib.h wad.h draw.h cvar.h screen.h net.h protocol.h cmd.h \ + sbar.h sound.h render.h client.h progs.h pr_comp.h progdefs.h \ + progdefs.q1 server.h model.h modelgen.h spritegn.h d_iface.h \ + input.h world.h keys.h console.h view.h menu.h crc.h cdaudio.h +d_scan.o: d_scan.c quakedef.h common.h bspfile.h vid.h sys.h zone.h \ + mathlib.h wad.h draw.h cvar.h screen.h net.h protocol.h cmd.h \ + sbar.h sound.h render.h client.h progs.h pr_comp.h progdefs.h \ + progdefs.q1 server.h model.h modelgen.h spritegn.h d_iface.h \ + input.h world.h keys.h console.h view.h menu.h crc.h cdaudio.h \ + r_local.h r_shared.h d_local.h +d_sky.o: d_sky.c quakedef.h common.h bspfile.h vid.h sys.h zone.h \ + mathlib.h wad.h draw.h cvar.h screen.h net.h protocol.h cmd.h \ + sbar.h sound.h render.h client.h progs.h pr_comp.h progdefs.h \ + progdefs.q1 server.h model.h modelgen.h spritegn.h d_iface.h \ + input.h world.h keys.h console.h view.h menu.h crc.h cdaudio.h \ + r_local.h r_shared.h d_local.h +d_sprite.o: d_sprite.c quakedef.h common.h bspfile.h vid.h sys.h zone.h \ + mathlib.h wad.h draw.h cvar.h screen.h net.h protocol.h cmd.h \ + sbar.h sound.h render.h client.h progs.h pr_comp.h progdefs.h \ + progdefs.q1 server.h model.h modelgen.h spritegn.h d_iface.h \ + input.h world.h keys.h console.h view.h menu.h crc.h cdaudio.h \ + d_local.h r_shared.h +d_surf.o: d_surf.c quakedef.h common.h bspfile.h vid.h sys.h zone.h \ + mathlib.h wad.h draw.h cvar.h screen.h net.h protocol.h cmd.h \ + sbar.h sound.h render.h client.h progs.h pr_comp.h progdefs.h \ + progdefs.q1 server.h model.h modelgen.h spritegn.h d_iface.h \ + input.h world.h keys.h console.h view.h menu.h crc.h cdaudio.h \ + d_local.h r_shared.h r_local.h +d_vars.o: d_vars.c quakedef.h common.h bspfile.h vid.h sys.h zone.h \ + mathlib.h wad.h draw.h cvar.h screen.h net.h protocol.h cmd.h \ + sbar.h sound.h render.h client.h progs.h pr_comp.h progdefs.h \ + progdefs.q1 server.h model.h modelgen.h spritegn.h d_iface.h \ + input.h world.h keys.h console.h view.h menu.h crc.h cdaudio.h +d_zpoint.o: d_zpoint.c quakedef.h common.h bspfile.h vid.h sys.h zone.h \ + mathlib.h wad.h draw.h cvar.h screen.h net.h protocol.h cmd.h \ + sbar.h sound.h render.h client.h progs.h pr_comp.h progdefs.h \ + progdefs.q1 server.h model.h modelgen.h spritegn.h d_iface.h \ + input.h world.h keys.h console.h view.h menu.h crc.h cdaudio.h \ + d_local.h r_shared.h +host_cmd.o: host_cmd.c quakedef.h common.h bspfile.h vid.h sys.h zone.h \ + mathlib.h wad.h draw.h cvar.h screen.h net.h protocol.h cmd.h \ + sbar.h sound.h render.h client.h progs.h pr_comp.h progdefs.h \ + progdefs.q1 server.h model.h modelgen.h spritegn.h d_iface.h \ + input.h world.h keys.h console.h view.h menu.h crc.h cdaudio.h +host.o: host.c quakedef.h common.h bspfile.h vid.h sys.h zone.h \ + mathlib.h wad.h draw.h cvar.h screen.h net.h protocol.h cmd.h \ + sbar.h sound.h render.h client.h progs.h pr_comp.h progdefs.h \ + progdefs.q1 server.h model.h modelgen.h spritegn.h d_iface.h \ + input.h world.h keys.h console.h view.h menu.h crc.h cdaudio.h \ + r_local.h r_shared.h +keys.o: keys.c quakedef.h common.h bspfile.h vid.h sys.h zone.h \ + mathlib.h wad.h draw.h cvar.h screen.h net.h protocol.h cmd.h \ + sbar.h sound.h render.h client.h progs.h pr_comp.h progdefs.h \ + progdefs.q1 server.h model.h modelgen.h spritegn.h d_iface.h \ + input.h world.h keys.h console.h view.h menu.h crc.h cdaudio.h +mathlib.o: mathlib.c quakedef.h common.h bspfile.h vid.h sys.h zone.h \ + mathlib.h wad.h draw.h cvar.h screen.h net.h protocol.h cmd.h \ + sbar.h sound.h render.h client.h progs.h pr_comp.h progdefs.h \ + progdefs.q1 server.h model.h modelgen.h spritegn.h d_iface.h \ + input.h world.h keys.h console.h view.h menu.h crc.h cdaudio.h +menu.o: menu.c quakedef.h common.h bspfile.h vid.h sys.h zone.h \ + mathlib.h wad.h draw.h cvar.h screen.h net.h protocol.h cmd.h \ + sbar.h sound.h render.h client.h progs.h pr_comp.h progdefs.h \ + progdefs.q1 server.h model.h modelgen.h spritegn.h d_iface.h \ + input.h world.h keys.h console.h view.h menu.h crc.h cdaudio.h +model.o: model.c quakedef.h common.h bspfile.h vid.h sys.h zone.h \ + mathlib.h wad.h draw.h cvar.h screen.h net.h protocol.h cmd.h \ + sbar.h sound.h render.h client.h progs.h pr_comp.h progdefs.h \ + progdefs.q1 server.h model.h modelgen.h spritegn.h d_iface.h \ + input.h world.h keys.h console.h view.h menu.h crc.h cdaudio.h \ + r_local.h r_shared.h +net_bsd.o: net_bsd.c quakedef.h common.h bspfile.h vid.h sys.h zone.h \ + mathlib.h wad.h draw.h cvar.h screen.h net.h protocol.h cmd.h \ + sbar.h sound.h render.h client.h progs.h pr_comp.h progdefs.h \ + progdefs.q1 server.h model.h modelgen.h spritegn.h d_iface.h \ + input.h world.h keys.h console.h view.h menu.h crc.h cdaudio.h \ + net_loop.h net_dgrm.h net_udp.h +net_dgrm.o: net_dgrm.c quakedef.h common.h bspfile.h vid.h sys.h zone.h \ + mathlib.h wad.h draw.h cvar.h screen.h net.h protocol.h cmd.h \ + sbar.h sound.h render.h client.h progs.h pr_comp.h progdefs.h \ + progdefs.q1 server.h model.h modelgen.h spritegn.h d_iface.h \ + input.h world.h keys.h console.h view.h menu.h crc.h cdaudio.h \ + net_dgrm.h +net_loop.o: net_loop.c quakedef.h common.h bspfile.h vid.h sys.h zone.h \ + mathlib.h wad.h draw.h cvar.h screen.h net.h protocol.h cmd.h \ + sbar.h sound.h render.h client.h progs.h pr_comp.h progdefs.h \ + progdefs.q1 server.h model.h modelgen.h spritegn.h d_iface.h \ + input.h world.h keys.h console.h view.h menu.h crc.h cdaudio.h \ + net_loop.h +net_main.o: net_main.c quakedef.h common.h bspfile.h vid.h sys.h zone.h \ + mathlib.h wad.h draw.h cvar.h screen.h net.h protocol.h cmd.h \ + sbar.h sound.h render.h client.h progs.h pr_comp.h progdefs.h \ + progdefs.q1 server.h model.h modelgen.h spritegn.h d_iface.h \ + input.h world.h keys.h console.h view.h menu.h crc.h cdaudio.h \ + net_vcr.h +net_udp.o: net_udp.c quakedef.h common.h bspfile.h vid.h sys.h zone.h \ + mathlib.h wad.h draw.h cvar.h screen.h net.h protocol.h cmd.h \ + sbar.h sound.h render.h client.h progs.h pr_comp.h progdefs.h \ + progdefs.q1 server.h model.h modelgen.h spritegn.h d_iface.h \ + input.h world.h keys.h console.h view.h menu.h crc.h cdaudio.h \ + net_udp.h +net_vcr.o: net_vcr.c quakedef.h common.h bspfile.h vid.h sys.h zone.h \ + mathlib.h wad.h draw.h cvar.h screen.h net.h protocol.h cmd.h \ + sbar.h sound.h render.h client.h progs.h pr_comp.h progdefs.h \ + progdefs.q1 server.h model.h modelgen.h spritegn.h d_iface.h \ + input.h world.h keys.h console.h view.h menu.h crc.h cdaudio.h \ + net_vcr.h +net_wso.o: net_wso.c +nonintel.o: nonintel.c quakedef.h common.h bspfile.h vid.h sys.h zone.h \ + mathlib.h wad.h draw.h cvar.h screen.h net.h protocol.h cmd.h \ + sbar.h sound.h render.h client.h progs.h pr_comp.h progdefs.h \ + progdefs.q1 server.h model.h modelgen.h spritegn.h d_iface.h \ + input.h world.h keys.h console.h view.h menu.h crc.h cdaudio.h \ + r_local.h r_shared.h d_local.h +pr_cmds.o: pr_cmds.c quakedef.h common.h bspfile.h vid.h sys.h zone.h \ + mathlib.h wad.h draw.h cvar.h screen.h net.h protocol.h cmd.h \ + sbar.h sound.h render.h client.h progs.h pr_comp.h progdefs.h \ + progdefs.q1 server.h model.h modelgen.h spritegn.h d_iface.h \ + input.h world.h keys.h console.h view.h menu.h crc.h cdaudio.h +pr_edict.o: pr_edict.c quakedef.h common.h bspfile.h vid.h sys.h zone.h \ + mathlib.h wad.h draw.h cvar.h screen.h net.h protocol.h cmd.h \ + sbar.h sound.h render.h client.h progs.h pr_comp.h progdefs.h \ + progdefs.q1 server.h model.h modelgen.h spritegn.h d_iface.h \ + input.h world.h keys.h console.h view.h menu.h crc.h cdaudio.h +pr_exec.o: pr_exec.c quakedef.h common.h bspfile.h vid.h sys.h zone.h \ + mathlib.h wad.h draw.h cvar.h screen.h net.h protocol.h cmd.h \ + sbar.h sound.h render.h client.h progs.h pr_comp.h progdefs.h \ + progdefs.q1 server.h model.h modelgen.h spritegn.h d_iface.h \ + input.h world.h keys.h console.h view.h menu.h crc.h cdaudio.h +r_aclip.o: r_aclip.c quakedef.h common.h bspfile.h vid.h sys.h zone.h \ + mathlib.h wad.h draw.h cvar.h screen.h net.h protocol.h cmd.h \ + sbar.h sound.h render.h client.h progs.h pr_comp.h progdefs.h \ + progdefs.q1 server.h model.h modelgen.h spritegn.h d_iface.h \ + input.h world.h keys.h console.h view.h menu.h crc.h cdaudio.h \ + r_local.h r_shared.h d_local.h +r_alias.o: r_alias.c quakedef.h common.h bspfile.h vid.h sys.h zone.h \ + mathlib.h wad.h draw.h cvar.h screen.h net.h protocol.h cmd.h \ + sbar.h sound.h render.h client.h progs.h pr_comp.h progdefs.h \ + progdefs.q1 server.h model.h modelgen.h spritegn.h d_iface.h \ + input.h world.h keys.h console.h view.h menu.h crc.h cdaudio.h \ + r_local.h r_shared.h d_local.h anorms.h +r_bsp.o: r_bsp.c quakedef.h common.h bspfile.h vid.h sys.h zone.h \ + mathlib.h wad.h draw.h cvar.h screen.h net.h protocol.h cmd.h \ + sbar.h sound.h render.h client.h progs.h pr_comp.h progdefs.h \ + progdefs.q1 server.h model.h modelgen.h spritegn.h d_iface.h \ + input.h world.h keys.h console.h view.h menu.h crc.h cdaudio.h \ + r_local.h r_shared.h +r_draw.o: r_draw.c quakedef.h common.h bspfile.h vid.h sys.h zone.h \ + mathlib.h wad.h draw.h cvar.h screen.h net.h protocol.h cmd.h \ + sbar.h sound.h render.h client.h progs.h pr_comp.h progdefs.h \ + progdefs.q1 server.h model.h modelgen.h spritegn.h d_iface.h \ + input.h world.h keys.h console.h view.h menu.h crc.h cdaudio.h \ + r_local.h r_shared.h d_local.h +r_edge.o: r_edge.c quakedef.h common.h bspfile.h vid.h sys.h zone.h \ + mathlib.h wad.h draw.h cvar.h screen.h net.h protocol.h cmd.h \ + sbar.h sound.h render.h client.h progs.h pr_comp.h progdefs.h \ + progdefs.q1 server.h model.h modelgen.h spritegn.h d_iface.h \ + input.h world.h keys.h console.h view.h menu.h crc.h cdaudio.h \ + r_local.h r_shared.h +r_efrag.o: r_efrag.c quakedef.h common.h bspfile.h vid.h sys.h zone.h \ + mathlib.h wad.h draw.h cvar.h screen.h net.h protocol.h cmd.h \ + sbar.h sound.h render.h client.h progs.h pr_comp.h progdefs.h \ + progdefs.q1 server.h model.h modelgen.h spritegn.h d_iface.h \ + input.h world.h keys.h console.h view.h menu.h crc.h cdaudio.h \ + r_local.h r_shared.h +r_light.o: r_light.c quakedef.h common.h bspfile.h vid.h sys.h zone.h \ + mathlib.h wad.h draw.h cvar.h screen.h net.h protocol.h cmd.h \ + sbar.h sound.h render.h client.h progs.h pr_comp.h progdefs.h \ + progdefs.q1 server.h model.h modelgen.h spritegn.h d_iface.h \ + input.h world.h keys.h console.h view.h menu.h crc.h cdaudio.h \ + r_local.h r_shared.h +r_main.o: r_main.c quakedef.h common.h bspfile.h vid.h sys.h zone.h \ + mathlib.h wad.h draw.h cvar.h screen.h net.h protocol.h cmd.h \ + sbar.h sound.h render.h client.h progs.h pr_comp.h progdefs.h \ + progdefs.q1 server.h model.h modelgen.h spritegn.h d_iface.h \ + input.h world.h keys.h console.h view.h menu.h crc.h cdaudio.h \ + r_local.h r_shared.h +r_misc.o: r_misc.c quakedef.h common.h bspfile.h vid.h sys.h zone.h \ + mathlib.h wad.h draw.h cvar.h screen.h net.h protocol.h cmd.h \ + sbar.h sound.h render.h client.h progs.h pr_comp.h progdefs.h \ + progdefs.q1 server.h model.h modelgen.h spritegn.h d_iface.h \ + input.h world.h keys.h console.h view.h menu.h crc.h cdaudio.h \ + r_local.h r_shared.h +r_part.o: r_part.c quakedef.h common.h bspfile.h vid.h sys.h zone.h \ + mathlib.h wad.h draw.h cvar.h screen.h net.h protocol.h cmd.h \ + sbar.h sound.h render.h client.h progs.h pr_comp.h progdefs.h \ + progdefs.q1 server.h model.h modelgen.h spritegn.h d_iface.h \ + input.h world.h keys.h console.h view.h menu.h crc.h cdaudio.h \ + r_local.h r_shared.h +r_sky.o: r_sky.c quakedef.h common.h bspfile.h vid.h sys.h zone.h \ + mathlib.h wad.h draw.h cvar.h screen.h net.h protocol.h cmd.h \ + sbar.h sound.h render.h client.h progs.h pr_comp.h progdefs.h \ + progdefs.q1 server.h model.h modelgen.h spritegn.h d_iface.h \ + input.h world.h keys.h console.h view.h menu.h crc.h cdaudio.h \ + r_local.h r_shared.h d_local.h +r_sprite.o: r_sprite.c quakedef.h common.h bspfile.h vid.h sys.h zone.h \ + mathlib.h wad.h draw.h cvar.h screen.h net.h protocol.h cmd.h \ + sbar.h sound.h render.h client.h progs.h pr_comp.h progdefs.h \ + progdefs.q1 server.h model.h modelgen.h spritegn.h d_iface.h \ + input.h world.h keys.h console.h view.h menu.h crc.h cdaudio.h \ + r_local.h r_shared.h +r_surf.o: r_surf.c quakedef.h common.h bspfile.h vid.h sys.h zone.h \ + mathlib.h wad.h draw.h cvar.h screen.h net.h protocol.h cmd.h \ + sbar.h sound.h render.h client.h progs.h pr_comp.h progdefs.h \ + progdefs.q1 server.h model.h modelgen.h spritegn.h d_iface.h \ + input.h world.h keys.h console.h view.h menu.h crc.h cdaudio.h \ + r_local.h r_shared.h +r_vars.o: r_vars.c quakedef.h common.h bspfile.h vid.h sys.h zone.h \ + mathlib.h wad.h draw.h cvar.h screen.h net.h protocol.h cmd.h \ + sbar.h sound.h render.h client.h progs.h pr_comp.h progdefs.h \ + progdefs.q1 server.h model.h modelgen.h spritegn.h d_iface.h \ + input.h world.h keys.h console.h view.h menu.h crc.h cdaudio.h +sbar.o: sbar.c quakedef.h common.h bspfile.h vid.h sys.h zone.h \ + mathlib.h wad.h draw.h cvar.h screen.h net.h protocol.h cmd.h \ + sbar.h sound.h render.h client.h progs.h pr_comp.h progdefs.h \ + progdefs.q1 server.h model.h modelgen.h spritegn.h d_iface.h \ + input.h world.h keys.h console.h view.h menu.h crc.h cdaudio.h +screen.o: screen.c quakedef.h common.h bspfile.h vid.h sys.h zone.h \ + mathlib.h wad.h draw.h cvar.h screen.h net.h protocol.h cmd.h \ + sbar.h sound.h render.h client.h progs.h pr_comp.h progdefs.h \ + progdefs.q1 server.h model.h modelgen.h spritegn.h d_iface.h \ + input.h world.h keys.h console.h view.h menu.h crc.h cdaudio.h \ + r_local.h r_shared.h +snd_dma.o: snd_dma.c quakedef.h common.h bspfile.h vid.h sys.h zone.h \ + mathlib.h wad.h draw.h cvar.h screen.h net.h protocol.h cmd.h \ + sbar.h sound.h render.h client.h progs.h pr_comp.h progdefs.h \ + progdefs.q1 server.h model.h modelgen.h spritegn.h d_iface.h \ + input.h world.h keys.h console.h view.h menu.h crc.h cdaudio.h +snd_mem.o: snd_mem.c quakedef.h common.h bspfile.h vid.h sys.h zone.h \ + mathlib.h wad.h draw.h cvar.h screen.h net.h protocol.h cmd.h \ + sbar.h sound.h render.h client.h progs.h pr_comp.h progdefs.h \ + progdefs.q1 server.h model.h modelgen.h spritegn.h d_iface.h \ + input.h world.h keys.h console.h view.h menu.h crc.h cdaudio.h +snd_mix.o: snd_mix.c quakedef.h common.h bspfile.h vid.h sys.h zone.h \ + mathlib.h wad.h draw.h cvar.h screen.h net.h protocol.h cmd.h \ + sbar.h sound.h render.h client.h progs.h pr_comp.h progdefs.h \ + progdefs.q1 server.h model.h modelgen.h spritegn.h d_iface.h \ + input.h world.h keys.h console.h view.h menu.h crc.h cdaudio.h +snd_sdl.o: snd_sdl.c quakedef.h common.h bspfile.h vid.h sys.h zone.h \ + mathlib.h wad.h draw.h cvar.h screen.h net.h protocol.h cmd.h \ + sbar.h sound.h render.h client.h progs.h pr_comp.h progdefs.h \ + progdefs.q1 server.h model.h modelgen.h spritegn.h d_iface.h \ + input.h world.h keys.h console.h view.h menu.h crc.h cdaudio.h +sv_main.o: sv_main.c quakedef.h common.h bspfile.h vid.h sys.h zone.h \ + mathlib.h wad.h draw.h cvar.h screen.h net.h protocol.h cmd.h \ + sbar.h sound.h render.h client.h progs.h pr_comp.h progdefs.h \ + progdefs.q1 server.h model.h modelgen.h spritegn.h d_iface.h \ + input.h world.h keys.h console.h view.h menu.h crc.h cdaudio.h +sv_move.o: sv_move.c quakedef.h common.h bspfile.h vid.h sys.h zone.h \ + mathlib.h wad.h draw.h cvar.h screen.h net.h protocol.h cmd.h \ + sbar.h sound.h render.h client.h progs.h pr_comp.h progdefs.h \ + progdefs.q1 server.h model.h modelgen.h spritegn.h d_iface.h \ + input.h world.h keys.h console.h view.h menu.h crc.h cdaudio.h +sv_phys.o: sv_phys.c quakedef.h common.h bspfile.h vid.h sys.h zone.h \ + mathlib.h wad.h draw.h cvar.h screen.h net.h protocol.h cmd.h \ + sbar.h sound.h render.h client.h progs.h pr_comp.h progdefs.h \ + progdefs.q1 server.h model.h modelgen.h spritegn.h d_iface.h \ + input.h world.h keys.h console.h view.h menu.h crc.h cdaudio.h +sv_user.o: sv_user.c quakedef.h common.h bspfile.h vid.h sys.h zone.h \ + mathlib.h wad.h draw.h cvar.h screen.h net.h protocol.h cmd.h \ + sbar.h sound.h render.h client.h progs.h pr_comp.h progdefs.h \ + progdefs.q1 server.h model.h modelgen.h spritegn.h d_iface.h \ + input.h world.h keys.h console.h view.h menu.h crc.h cdaudio.h +sys_sdl.o: sys_sdl.c quakedef.h common.h bspfile.h vid.h sys.h zone.h \ + mathlib.h wad.h draw.h cvar.h screen.h net.h protocol.h cmd.h \ + sbar.h sound.h render.h client.h progs.h pr_comp.h progdefs.h \ + progdefs.q1 server.h model.h modelgen.h spritegn.h d_iface.h \ + input.h world.h keys.h console.h view.h menu.h crc.h cdaudio.h +vid_sdl.o: vid_sdl.c quakedef.h common.h bspfile.h vid.h sys.h zone.h \ + mathlib.h wad.h draw.h cvar.h screen.h net.h protocol.h cmd.h \ + sbar.h sound.h render.h client.h progs.h pr_comp.h progdefs.h \ + progdefs.q1 server.h model.h modelgen.h spritegn.h d_iface.h \ + input.h world.h keys.h console.h view.h menu.h crc.h cdaudio.h \ + d_local.h r_shared.h +view.o: view.c quakedef.h common.h bspfile.h vid.h sys.h zone.h \ + mathlib.h wad.h draw.h cvar.h screen.h net.h protocol.h cmd.h \ + sbar.h sound.h render.h client.h progs.h pr_comp.h progdefs.h \ + progdefs.q1 server.h model.h modelgen.h spritegn.h d_iface.h \ + input.h world.h keys.h console.h view.h menu.h crc.h cdaudio.h \ + r_local.h r_shared.h +wad.o: wad.c quakedef.h common.h bspfile.h vid.h sys.h zone.h mathlib.h \ + wad.h draw.h cvar.h screen.h net.h protocol.h cmd.h sbar.h \ + sound.h render.h client.h progs.h pr_comp.h progdefs.h \ + progdefs.q1 server.h model.h modelgen.h spritegn.h d_iface.h \ + input.h world.h keys.h console.h view.h menu.h crc.h cdaudio.h +world.o: world.c quakedef.h common.h bspfile.h vid.h sys.h zone.h \ + mathlib.h wad.h draw.h cvar.h screen.h net.h protocol.h cmd.h \ + sbar.h sound.h render.h client.h progs.h pr_comp.h progdefs.h \ + progdefs.q1 server.h model.h modelgen.h spritegn.h d_iface.h \ + input.h world.h keys.h console.h view.h menu.h crc.h cdaudio.h +zone.o: zone.c quakedef.h common.h bspfile.h vid.h sys.h zone.h \ + mathlib.h wad.h draw.h cvar.h screen.h net.h protocol.h cmd.h \ + sbar.h sound.h render.h client.h progs.h pr_comp.h progdefs.h \ + progdefs.q1 server.h model.h modelgen.h spritegn.h d_iface.h \ + input.h world.h keys.h console.h view.h menu.h crc.h cdaudio.h + +info-am: +info: info-am +dvi-am: +dvi: dvi-am +check-am: all-am +check: check-am +installcheck-am: +installcheck: installcheck-am +install-exec-am: install-binPROGRAMS +install-exec: install-exec-am + +install-data-am: +install-data: install-data-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am +install: install-am +uninstall-am: uninstall-binPROGRAMS +uninstall: uninstall-am +all-am: Makefile $(PROGRAMS) +all-redirect: all-am +install-strip: + $(MAKE) $(AM_MAKEFLAGS) AM_INSTALL_PROGRAM_FLAGS=-s install +installdirs: + $(mkinstalldirs) $(DESTDIR)$(bindir) + + +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -rm -f Makefile $(CONFIG_CLEAN_FILES) + -rm -f config.cache config.log stamp-h stamp-h[0-9]* + +maintainer-clean-generic: +mostlyclean-am: mostlyclean-binPROGRAMS mostlyclean-compile \ + mostlyclean-tags mostlyclean-generic + +mostlyclean: mostlyclean-am + +clean-am: clean-binPROGRAMS clean-compile clean-tags clean-generic \ + mostlyclean-am + +clean: clean-am + +distclean-am: distclean-binPROGRAMS distclean-compile distclean-tags \ + distclean-generic clean-am + +distclean: distclean-am + -rm -f config.status + +maintainer-clean-am: maintainer-clean-binPROGRAMS \ + maintainer-clean-compile maintainer-clean-tags \ + maintainer-clean-generic distclean-am + @echo "This command is intended for maintainers to use;" + @echo "it deletes files that may require special tools to rebuild." + +maintainer-clean: maintainer-clean-am + -rm -f config.status + +.PHONY: mostlyclean-binPROGRAMS distclean-binPROGRAMS clean-binPROGRAMS \ +maintainer-clean-binPROGRAMS uninstall-binPROGRAMS install-binPROGRAMS \ +mostlyclean-compile distclean-compile clean-compile \ +maintainer-clean-compile tags mostlyclean-tags distclean-tags \ +clean-tags maintainer-clean-tags distdir info-am info dvi-am dvi check \ +check-am installcheck-am installcheck install-exec-am install-exec \ +install-data-am install-data install-am install uninstall-am uninstall \ +all-redirect all-am all installdirs mostlyclean-generic \ +distclean-generic clean-generic maintainer-clean-generic clean \ +mostlyclean distclean maintainer-clean + + +dist-hook: + cp -rp data docs dxsdk gas2masm kit scitech $(distdir)/ + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/contrib/other/sdlquake-1.0.9/Makefile.linuxi386 b/contrib/other/sdlquake-1.0.9/Makefile.linuxi386 new file mode 100644 index 000000000..e0750d1e7 --- /dev/null +++ b/contrib/other/sdlquake-1.0.9/Makefile.linuxi386 @@ -0,0 +1,1242 @@ +# +# Quake Makefile for Linux 2.0 +# +# Aug '98 by Zoid +# +# ELF only +# + +BASEVERSION=1.09 +VERSION=$(BASEVERSION)$(GLIBC) + +# RPM release number +RPM_RELEASE=5 + +ifneq (,$(findstring libc6,$(shell if [ -e /lib/libc.so.6 ];then echo libc6;fi))) +GLIBC=-glibc +else +GLIBC= +endif + +ifneq (,$(findstring alpha,$(shell uname -m))) +ARCH=axp +else +ARCH=i386 +endif +NOARCH=noarch + +#MOUNT_DIR=/grog/Projects/WinQuake +MOUNT_DIR := $(shell pwd) +MASTER_DIR=/grog/Projects/QuakeMaster +MESA_DIR=/usr/local/src/Mesa-2.6 +TDFXGL_DIR = /home/zoid/3dfxgl + +BUILD_DEBUG_DIR=debug$(ARCH)$(GLIBC) +BUILD_RELEASE_DIR=release$(ARCH)$(GLIBC) + +#EGCS=/usr/local/egcs-1.1.2/bin/gcc +#CC=$(EGCS) + +BASE_CFLAGS=-Dstricmp=strcasecmp +RELEASE_CFLAGS=$(BASE_CFLAGS) -g -mpentiumpro -O6 -ffast-math -funroll-loops \ + -fomit-frame-pointer -fexpensive-optimizations +DEBUG_CFLAGS=$(BASE_CFLAGS) -g +LDFLAGS=-lm +SVGALDFLAGS=-lvga +XLDFLAGS=-L/usr/X11R6/lib -lX11 -lXext -lXxf86dga +XCFLAGS=-DX11 + +MESAGLLDFLAGS=-L/usr/X11/lib -L/usr/local/lib -L$(MESA_DIR)/lib -lMesaGL -lglide2x -lX11 -lXext -ldl +TDFXGLLDFLAGS=-L$(TDFXGL_DIR)/release$(ARCH)$(GLIBC) -l3dfxgl -lglide2x -ldl +GLLDFLAGS=-L/usr/X11/lib -L/usr/local/lib -lGL -lX11 -lXext -ldl -lXxf86dga -lXxf86vm -lm +GLCFLAGS=-DGLQUAKE -I$(MESA_DIR)/include -I/usr/include/glide + +DO_CC=$(CC) $(CFLAGS) -o $@ -c $< +DO_DEBUG_CC=$(CC) $(DEBUG_CFLAGS) -o $@ -c $< +DO_GL_CC=$(CC) $(CFLAGS) $(GLCFLAGS) -o $@ -c $< +DO_GL_DEBUG_CC=$(CC) $(DEBUG_CFLAGS) $(GLCFLAGS) -o $@ -c $< +DO_X11_CC=$(CC) $(CFLAGS) $(XCFLAGS) -o $@ -c $< +DO_X11_DEBUG_CC=$(CC) $(DEBUG_CFLAGS) $(XCFLAGS) -o $@ -c $< +DO_O_CC=$(CC) -O $(CFLAGS) -o $@ -c $< +#DO_AS=$(CC) $(CFLAGS) -DELF -x assembler-with-cpp -o $@ -c $< +DO_AS=$(CC) $(CFLAGS) -DELF -o $@ -c $< +DO_GL_AS=$(CC) $(CFLAGS) $(GLCFLAGS) -DELF -x assembler-with-cpp -o $@ -c $< + +############################################################################# +# SETUP AND BUILD +############################################################################# + +TARGETS=$(BUILDDIR)/bin/quake.x11\ + $(BUILDDIR)/bin/squake \ + $(BUILDDIR)/bin/glquake \ + $(BUILDDIR)/bin/glquake.glx \ + $(BUILDDIR)/bin/glquake.3dfxgl \ + # $(BUILDDIR)/bin/unixded + +build_debug: + @-mkdir $(BUILD_DEBUG_DIR) \ + $(BUILD_DEBUG_DIR)/bin \ + $(BUILD_DEBUG_DIR)/glquake \ + $(BUILD_DEBUG_DIR)/squake \ + $(BUILD_DEBUG_DIR)/unixded \ + $(BUILD_DEBUG_DIR)/x11 + $(MAKE) targets BUILDDIR=$(BUILD_DEBUG_DIR) CFLAGS="$(DEBUG_CFLAGS)" + +build_release: + @-mkdir $(BUILD_RELEASE_DIR) \ + $(BUILD_RELEASE_DIR)/bin \ + $(BUILD_RELEASE_DIR)/glquake \ + $(BUILD_RELEASE_DIR)/squake \ + $(BUILD_RELEASE_DIR)/unixded \ + $(BUILD_RELEASE_DIR)/x11 + $(MAKE) targets BUILDDIR=$(BUILD_RELEASE_DIR) CFLAGS="$(RELEASE_CFLAGS)" + +all: build_debug build_release + +targets: $(TARGETS) + +############################################################################# +# SVGALIB Quake +############################################################################# + +SQUAKE_OBJS = \ + $(BUILDDIR)/squake/cl_demo.o \ + $(BUILDDIR)/squake/cl_input.o \ + $(BUILDDIR)/squake/cl_main.o \ + $(BUILDDIR)/squake/cl_parse.o \ + $(BUILDDIR)/squake/cl_tent.o \ + $(BUILDDIR)/squake/chase.o \ + $(BUILDDIR)/squake/cmd.o \ + $(BUILDDIR)/squake/common.o \ + $(BUILDDIR)/squake/console.o \ + $(BUILDDIR)/squake/crc.o \ + $(BUILDDIR)/squake/cvar.o \ + $(BUILDDIR)/squake/draw.o \ + $(BUILDDIR)/squake/d_edge.o \ + $(BUILDDIR)/squake/d_fill.o \ + $(BUILDDIR)/squake/d_init.o \ + $(BUILDDIR)/squake/d_modech.o \ + $(BUILDDIR)/squake/d_part.o \ + $(BUILDDIR)/squake/d_polyse.o \ + $(BUILDDIR)/squake/d_scan.o \ + $(BUILDDIR)/squake/d_sky.o \ + $(BUILDDIR)/squake/d_sprite.o \ + $(BUILDDIR)/squake/d_surf.o \ + $(BUILDDIR)/squake/d_vars.o \ + $(BUILDDIR)/squake/d_zpoint.o \ + $(BUILDDIR)/squake/host.o \ + $(BUILDDIR)/squake/host_cmd.o \ + $(BUILDDIR)/squake/keys.o \ + $(BUILDDIR)/squake/menu.o \ + $(BUILDDIR)/squake/mathlib.o \ + $(BUILDDIR)/squake/model.o \ + $(BUILDDIR)/squake/net_dgrm.o \ + $(BUILDDIR)/squake/net_loop.o \ + $(BUILDDIR)/squake/net_main.o \ + $(BUILDDIR)/squake/net_vcr.o \ + $(BUILDDIR)/squake/net_udp.o \ + $(BUILDDIR)/squake/net_bsd.o \ + $(BUILDDIR)/squake/nonintel.o \ + $(BUILDDIR)/squake/pr_cmds.o \ + $(BUILDDIR)/squake/pr_edict.o \ + $(BUILDDIR)/squake/pr_exec.o \ + $(BUILDDIR)/squake/r_aclip.o \ + $(BUILDDIR)/squake/r_alias.o \ + $(BUILDDIR)/squake/r_bsp.o \ + $(BUILDDIR)/squake/r_light.o \ + $(BUILDDIR)/squake/r_draw.o \ + $(BUILDDIR)/squake/r_efrag.o \ + $(BUILDDIR)/squake/r_edge.o \ + $(BUILDDIR)/squake/r_misc.o \ + $(BUILDDIR)/squake/r_main.o \ + $(BUILDDIR)/squake/r_sky.o \ + $(BUILDDIR)/squake/r_sprite.o \ + $(BUILDDIR)/squake/r_surf.o \ + $(BUILDDIR)/squake/r_part.o \ + $(BUILDDIR)/squake/r_vars.o \ + $(BUILDDIR)/squake/screen.o \ + $(BUILDDIR)/squake/sbar.o \ + $(BUILDDIR)/squake/sv_main.o \ + $(BUILDDIR)/squake/sv_phys.o \ + $(BUILDDIR)/squake/sv_move.o \ + $(BUILDDIR)/squake/sv_user.o \ + $(BUILDDIR)/squake/zone.o \ + $(BUILDDIR)/squake/view.o \ + $(BUILDDIR)/squake/wad.o \ + $(BUILDDIR)/squake/world.o \ + $(BUILDDIR)/squake/cd_linux.o \ + $(BUILDDIR)/squake/sys_linux.o \ + $(BUILDDIR)/squake/vid_svgalib.o \ + $(BUILDDIR)/squake/snd_dma.o \ + $(BUILDDIR)/squake/snd_mem.o \ + $(BUILDDIR)/squake/snd_mix.o \ + $(BUILDDIR)/squake/snd_linux.o \ + \ + $(BUILDDIR)/squake/d_copy.o \ + $(BUILDDIR)/squake/d_draw.o \ + $(BUILDDIR)/squake/d_draw16.o \ + $(BUILDDIR)/squake/d_parta.o \ + $(BUILDDIR)/squake/d_polysa.o \ + $(BUILDDIR)/squake/d_scana.o \ + $(BUILDDIR)/squake/d_spr8.o \ + $(BUILDDIR)/squake/d_varsa.o \ + $(BUILDDIR)/squake/math.o \ + $(BUILDDIR)/squake/r_aliasa.o \ + $(BUILDDIR)/squake/r_drawa.o \ + $(BUILDDIR)/squake/r_edgea.o \ + $(BUILDDIR)/squake/r_varsa.o \ + $(BUILDDIR)/squake/surf16.o \ + $(BUILDDIR)/squake/surf8.o \ + $(BUILDDIR)/squake/worlda.o \ + $(BUILDDIR)/squake/r_aclipa.o \ + $(BUILDDIR)/squake/snd_mixa.o \ + $(BUILDDIR)/squake/sys_dosa.o + +$(BUILDDIR)/bin/squake : $(SQUAKE_OBJS) + $(CC) $(CFLAGS) -o $@ $(SQUAKE_OBJS) $(SVGALDFLAGS) $(LDFLAGS) + +#### + +$(BUILDDIR)/squake/cl_demo.o : $(MOUNT_DIR)/cl_demo.c + $(DO_CC) + +$(BUILDDIR)/squake/cl_input.o : $(MOUNT_DIR)/cl_input.c + $(DO_CC) + +$(BUILDDIR)/squake/cl_main.o : $(MOUNT_DIR)/cl_main.c + $(DO_CC) + +$(BUILDDIR)/squake/cl_parse.o : $(MOUNT_DIR)/cl_parse.c + $(DO_CC) + +$(BUILDDIR)/squake/cl_tent.o : $(MOUNT_DIR)/cl_tent.c + $(DO_CC) + +$(BUILDDIR)/squake/chase.o : $(MOUNT_DIR)/chase.c + $(DO_CC) + +$(BUILDDIR)/squake/cmd.o : $(MOUNT_DIR)/cmd.c + $(DO_CC) + +$(BUILDDIR)/squake/common.o : $(MOUNT_DIR)/common.c + $(DO_DEBUG_CC) + +$(BUILDDIR)/squake/console.o : $(MOUNT_DIR)/console.c + $(DO_CC) + +$(BUILDDIR)/squake/crc.o : $(MOUNT_DIR)/crc.c + $(DO_CC) + +$(BUILDDIR)/squake/cvar.o : $(MOUNT_DIR)/cvar.c + $(DO_CC) + +$(BUILDDIR)/squake/draw.o : $(MOUNT_DIR)/draw.c + $(DO_CC) + +$(BUILDDIR)/squake/d_edge.o : $(MOUNT_DIR)/d_edge.c + $(DO_CC) + +$(BUILDDIR)/squake/d_fill.o : $(MOUNT_DIR)/d_fill.c + $(DO_CC) + +$(BUILDDIR)/squake/d_init.o : $(MOUNT_DIR)/d_init.c + $(DO_CC) + +$(BUILDDIR)/squake/d_modech.o : $(MOUNT_DIR)/d_modech.c + $(DO_CC) + +$(BUILDDIR)/squake/d_part.o : $(MOUNT_DIR)/d_part.c + $(DO_CC) + +$(BUILDDIR)/squake/d_polyse.o : $(MOUNT_DIR)/d_polyse.c + $(DO_CC) + +$(BUILDDIR)/squake/d_scan.o : $(MOUNT_DIR)/d_scan.c + $(DO_CC) + +$(BUILDDIR)/squake/d_sky.o : $(MOUNT_DIR)/d_sky.c + $(DO_CC) + +$(BUILDDIR)/squake/d_sprite.o : $(MOUNT_DIR)/d_sprite.c + $(DO_CC) + +$(BUILDDIR)/squake/d_surf.o : $(MOUNT_DIR)/d_surf.c + $(DO_CC) + +$(BUILDDIR)/squake/d_vars.o : $(MOUNT_DIR)/d_vars.c + $(DO_CC) + +$(BUILDDIR)/squake/d_zpoint.o : $(MOUNT_DIR)/d_zpoint.c + $(DO_CC) + +$(BUILDDIR)/squake/host.o : $(MOUNT_DIR)/host.c + $(DO_CC) + +$(BUILDDIR)/squake/host_cmd.o : $(MOUNT_DIR)/host_cmd.c + $(DO_CC) + +$(BUILDDIR)/squake/keys.o : $(MOUNT_DIR)/keys.c + $(DO_CC) + +$(BUILDDIR)/squake/menu.o : $(MOUNT_DIR)/menu.c + $(DO_CC) + +$(BUILDDIR)/squake/mathlib.o : $(MOUNT_DIR)/mathlib.c + $(DO_CC) + +$(BUILDDIR)/squake/model.o : $(MOUNT_DIR)/model.c + $(DO_CC) + +$(BUILDDIR)/squake/net_dgrm.o : $(MOUNT_DIR)/net_dgrm.c + $(DO_CC) + +$(BUILDDIR)/squake/net_loop.o : $(MOUNT_DIR)/net_loop.c + $(DO_CC) + +$(BUILDDIR)/squake/net_main.o : $(MOUNT_DIR)/net_main.c + $(DO_CC) + +$(BUILDDIR)/squake/net_vcr.o : $(MOUNT_DIR)/net_vcr.c + $(DO_CC) + +$(BUILDDIR)/squake/net_udp.o : $(MOUNT_DIR)/net_udp.c + $(DO_CC) + +$(BUILDDIR)/squake/net_bsd.o : $(MOUNT_DIR)/net_bsd.c + $(DO_CC) + +$(BUILDDIR)/squake/nonintel.o : $(MOUNT_DIR)/nonintel.c + $(DO_CC) + +$(BUILDDIR)/squake/pr_cmds.o : $(MOUNT_DIR)/pr_cmds.c + $(DO_CC) + +$(BUILDDIR)/squake/pr_edict.o : $(MOUNT_DIR)/pr_edict.c + $(DO_CC) + +$(BUILDDIR)/squake/pr_exec.o : $(MOUNT_DIR)/pr_exec.c + $(DO_CC) + +$(BUILDDIR)/squake/r_aclip.o : $(MOUNT_DIR)/r_aclip.c + $(DO_CC) + +$(BUILDDIR)/squake/r_alias.o : $(MOUNT_DIR)/r_alias.c + $(DO_CC) + +$(BUILDDIR)/squake/r_bsp.o : $(MOUNT_DIR)/r_bsp.c + $(DO_CC) + +$(BUILDDIR)/squake/r_light.o : $(MOUNT_DIR)/r_light.c + $(DO_CC) + +$(BUILDDIR)/squake/r_draw.o : $(MOUNT_DIR)/r_draw.c + $(DO_CC) + +$(BUILDDIR)/squake/r_efrag.o : $(MOUNT_DIR)/r_efrag.c + $(DO_CC) + +$(BUILDDIR)/squake/r_edge.o : $(MOUNT_DIR)/r_edge.c + $(DO_CC) + +$(BUILDDIR)/squake/r_misc.o : $(MOUNT_DIR)/r_misc.c + $(DO_CC) + +$(BUILDDIR)/squake/r_main.o : $(MOUNT_DIR)/r_main.c + $(DO_CC) + +$(BUILDDIR)/squake/r_sky.o : $(MOUNT_DIR)/r_sky.c + $(DO_CC) + +$(BUILDDIR)/squake/r_sprite.o : $(MOUNT_DIR)/r_sprite.c + $(DO_CC) + +$(BUILDDIR)/squake/r_surf.o : $(MOUNT_DIR)/r_surf.c + $(DO_CC) + +$(BUILDDIR)/squake/r_part.o : $(MOUNT_DIR)/r_part.c + $(DO_CC) + +$(BUILDDIR)/squake/r_vars.o : $(MOUNT_DIR)/r_vars.c + $(DO_CC) + +$(BUILDDIR)/squake/screen.o : $(MOUNT_DIR)/screen.c + $(DO_CC) + +$(BUILDDIR)/squake/sbar.o : $(MOUNT_DIR)/sbar.c + $(DO_CC) + +$(BUILDDIR)/squake/sv_main.o : $(MOUNT_DIR)/sv_main.c + $(DO_CC) + +$(BUILDDIR)/squake/sv_phys.o : $(MOUNT_DIR)/sv_phys.c + $(DO_CC) + +$(BUILDDIR)/squake/sv_move.o : $(MOUNT_DIR)/sv_move.c + $(DO_CC) + +$(BUILDDIR)/squake/sv_user.o : $(MOUNT_DIR)/sv_user.c + $(DO_CC) + +$(BUILDDIR)/squake/zone.o : $(MOUNT_DIR)/zone.c + $(DO_CC) + +$(BUILDDIR)/squake/view.o : $(MOUNT_DIR)/view.c + $(DO_CC) + +$(BUILDDIR)/squake/wad.o : $(MOUNT_DIR)/wad.c + $(DO_CC) + +$(BUILDDIR)/squake/world.o : $(MOUNT_DIR)/world.c + $(DO_CC) + +$(BUILDDIR)/squake/cd_linux.o : $(MOUNT_DIR)/cd_linux.c + $(DO_CC) + +$(BUILDDIR)/squake/sys_linux.o :$(MOUNT_DIR)/sys_linux.c + $(DO_CC) + +$(BUILDDIR)/squake/vid_svgalib.o:$(MOUNT_DIR)/vid_svgalib.c + $(DO_O_CC) + +$(BUILDDIR)/squake/snd_dma.o : $(MOUNT_DIR)/snd_dma.c + $(DO_CC) + +$(BUILDDIR)/squake/snd_mem.o : $(MOUNT_DIR)/snd_mem.c + $(DO_CC) + +$(BUILDDIR)/squake/snd_mix.o : $(MOUNT_DIR)/snd_mix.c + $(DO_CC) + +$(BUILDDIR)/squake/snd_linux.o :$(MOUNT_DIR)/snd_linux.c + $(DO_CC) + +##### + +$(BUILDDIR)/squake/d_copy.o : $(MOUNT_DIR)/d_copy.S + $(DO_AS) + +$(BUILDDIR)/squake/d_draw.o : $(MOUNT_DIR)/d_draw.S + $(DO_AS) + +$(BUILDDIR)/squake/d_draw16.o : $(MOUNT_DIR)/d_draw16.S + $(DO_AS) + +$(BUILDDIR)/squake/d_parta.o : $(MOUNT_DIR)/d_parta.S + $(DO_AS) + +$(BUILDDIR)/squake/d_polysa.o : $(MOUNT_DIR)/d_polysa.S + $(DO_AS) + +$(BUILDDIR)/squake/d_scana.o : $(MOUNT_DIR)/d_scana.S + $(DO_AS) + +$(BUILDDIR)/squake/d_spr8.o : $(MOUNT_DIR)/d_spr8.S + $(DO_AS) + +$(BUILDDIR)/squake/d_varsa.o : $(MOUNT_DIR)/d_varsa.S + $(DO_AS) + +$(BUILDDIR)/squake/math.o : $(MOUNT_DIR)/math.S + $(DO_AS) + +$(BUILDDIR)/squake/r_aliasa.o : $(MOUNT_DIR)/r_aliasa.S + $(DO_AS) + +$(BUILDDIR)/squake/r_drawa.o : $(MOUNT_DIR)/r_drawa.S + $(DO_AS) + +$(BUILDDIR)/squake/r_edgea.o : $(MOUNT_DIR)/r_edgea.S + $(DO_AS) + +$(BUILDDIR)/squake/r_varsa.o : $(MOUNT_DIR)/r_varsa.S + $(DO_AS) + +$(BUILDDIR)/squake/surf16.o : $(MOUNT_DIR)/surf16.S + $(DO_AS) + +$(BUILDDIR)/squake/surf8.o : $(MOUNT_DIR)/surf8.S + $(DO_AS) + +$(BUILDDIR)/squake/worlda.o : $(MOUNT_DIR)/worlda.S + $(DO_AS) + +$(BUILDDIR)/squake/r_aclipa.o : $(MOUNT_DIR)/r_aclipa.S + $(DO_AS) + +$(BUILDDIR)/squake/snd_mixa.o : $(MOUNT_DIR)/snd_mixa.S + $(DO_AS) + +$(BUILDDIR)/squake/sys_dosa.o : $(MOUNT_DIR)/sys_dosa.S + $(DO_AS) + +############################################################################# +# X11 Quake +############################################################################# + +X11_OBJS = \ + $(BUILDDIR)/x11/cl_demo.o \ + $(BUILDDIR)/x11/cl_input.o \ + $(BUILDDIR)/x11/cl_main.o \ + $(BUILDDIR)/x11/cl_parse.o \ + $(BUILDDIR)/x11/cl_tent.o \ + $(BUILDDIR)/x11/chase.o \ + $(BUILDDIR)/x11/cmd.o \ + $(BUILDDIR)/x11/common.o \ + $(BUILDDIR)/x11/console.o \ + $(BUILDDIR)/x11/crc.o \ + $(BUILDDIR)/x11/cvar.o \ + $(BUILDDIR)/x11/draw.o \ + $(BUILDDIR)/x11/d_edge.o \ + $(BUILDDIR)/x11/d_fill.o \ + $(BUILDDIR)/x11/d_init.o \ + $(BUILDDIR)/x11/d_modech.o \ + $(BUILDDIR)/x11/d_part.o \ + $(BUILDDIR)/x11/d_polyse.o \ + $(BUILDDIR)/x11/d_scan.o \ + $(BUILDDIR)/x11/d_sky.o \ + $(BUILDDIR)/x11/d_sprite.o \ + $(BUILDDIR)/x11/d_surf.o \ + $(BUILDDIR)/x11/d_vars.o \ + $(BUILDDIR)/x11/d_zpoint.o \ + $(BUILDDIR)/x11/host.o \ + $(BUILDDIR)/x11/host_cmd.o \ + $(BUILDDIR)/x11/keys.o \ + $(BUILDDIR)/x11/menu.o \ + $(BUILDDIR)/x11/mathlib.o \ + $(BUILDDIR)/x11/model.o \ + $(BUILDDIR)/x11/net_dgrm.o \ + $(BUILDDIR)/x11/net_loop.o \ + $(BUILDDIR)/x11/net_main.o \ + $(BUILDDIR)/x11/net_vcr.o \ + $(BUILDDIR)/x11/net_udp.o \ + $(BUILDDIR)/x11/net_bsd.o \ + $(BUILDDIR)/x11/nonintel.o \ + $(BUILDDIR)/x11/pr_cmds.o \ + $(BUILDDIR)/x11/pr_edict.o \ + $(BUILDDIR)/x11/pr_exec.o \ + $(BUILDDIR)/x11/r_aclip.o \ + $(BUILDDIR)/x11/r_alias.o \ + $(BUILDDIR)/x11/r_bsp.o \ + $(BUILDDIR)/x11/r_light.o \ + $(BUILDDIR)/x11/r_draw.o \ + $(BUILDDIR)/x11/r_efrag.o \ + $(BUILDDIR)/x11/r_edge.o \ + $(BUILDDIR)/x11/r_misc.o \ + $(BUILDDIR)/x11/r_main.o \ + $(BUILDDIR)/x11/r_sky.o \ + $(BUILDDIR)/x11/r_sprite.o \ + $(BUILDDIR)/x11/r_surf.o \ + $(BUILDDIR)/x11/r_part.o \ + $(BUILDDIR)/x11/r_vars.o \ + $(BUILDDIR)/x11/screen.o \ + $(BUILDDIR)/x11/sbar.o \ + $(BUILDDIR)/x11/sv_main.o \ + $(BUILDDIR)/x11/sv_phys.o \ + $(BUILDDIR)/x11/sv_move.o \ + $(BUILDDIR)/x11/sv_user.o \ + $(BUILDDIR)/x11/zone.o \ + $(BUILDDIR)/x11/view.o \ + $(BUILDDIR)/x11/wad.o \ + $(BUILDDIR)/x11/world.o \ + $(BUILDDIR)/x11/cd_linux.o \ + $(BUILDDIR)/x11/sys_linux.o \ + $(BUILDDIR)/x11/vid_x.o \ + $(BUILDDIR)/x11/snd_dma.o \ + $(BUILDDIR)/x11/snd_mem.o \ + $(BUILDDIR)/x11/snd_mix.o \ + $(BUILDDIR)/x11/snd_linux.o \ + \ + $(BUILDDIR)/x11/d_draw.o \ + $(BUILDDIR)/x11/d_draw16.o \ + $(BUILDDIR)/x11/d_parta.o \ + $(BUILDDIR)/x11/d_polysa.o \ + $(BUILDDIR)/x11/d_scana.o \ + $(BUILDDIR)/x11/d_spr8.o \ + $(BUILDDIR)/x11/d_varsa.o \ + $(BUILDDIR)/x11/math.o \ + $(BUILDDIR)/x11/r_aliasa.o \ + $(BUILDDIR)/x11/r_drawa.o \ + $(BUILDDIR)/x11/r_edgea.o \ + $(BUILDDIR)/x11/r_varsa.o \ + $(BUILDDIR)/x11/surf16.o \ + $(BUILDDIR)/x11/surf8.o \ + $(BUILDDIR)/x11/worlda.o \ + $(BUILDDIR)/x11/r_aclipa.o \ + $(BUILDDIR)/x11/snd_mixa.o \ + $(BUILDDIR)/x11/sys_dosa.o + +$(BUILDDIR)/bin/quake.x11 : $(X11_OBJS) + $(CC) $(CFLAGS) -o $@ $(X11_OBJS) $(XLDFLAGS) $(LDFLAGS) + +#### + +$(BUILDDIR)/x11/cl_demo.o : $(MOUNT_DIR)/cl_demo.c + $(DO_X11_CC) + +$(BUILDDIR)/x11/cl_input.o : $(MOUNT_DIR)/cl_input.c + $(DO_X11_CC) + +$(BUILDDIR)/x11/cl_main.o : $(MOUNT_DIR)/cl_main.c + $(DO_X11_CC) + +$(BUILDDIR)/x11/cl_parse.o : $(MOUNT_DIR)/cl_parse.c + $(DO_X11_CC) + +$(BUILDDIR)/x11/cl_tent.o : $(MOUNT_DIR)/cl_tent.c + $(DO_X11_CC) + +$(BUILDDIR)/x11/chase.o : $(MOUNT_DIR)/chase.c + $(DO_X11_CC) + +$(BUILDDIR)/x11/cmd.o : $(MOUNT_DIR)/cmd.c + $(DO_X11_CC) + +$(BUILDDIR)/x11/common.o : $(MOUNT_DIR)/common.c + $(DO_X11_DEBUG_CC) + +$(BUILDDIR)/x11/console.o : $(MOUNT_DIR)/console.c + $(DO_X11_CC) + +$(BUILDDIR)/x11/crc.o : $(MOUNT_DIR)/crc.c + $(DO_X11_CC) + +$(BUILDDIR)/x11/cvar.o : $(MOUNT_DIR)/cvar.c + $(DO_X11_CC) + +$(BUILDDIR)/x11/draw.o : $(MOUNT_DIR)/draw.c + $(DO_X11_CC) + +$(BUILDDIR)/x11/d_edge.o : $(MOUNT_DIR)/d_edge.c + $(DO_X11_CC) + +$(BUILDDIR)/x11/d_fill.o : $(MOUNT_DIR)/d_fill.c + $(DO_X11_CC) + +$(BUILDDIR)/x11/d_init.o : $(MOUNT_DIR)/d_init.c + $(DO_X11_CC) + +$(BUILDDIR)/x11/d_modech.o : $(MOUNT_DIR)/d_modech.c + $(DO_X11_CC) + +$(BUILDDIR)/x11/d_part.o : $(MOUNT_DIR)/d_part.c + $(DO_X11_CC) + +$(BUILDDIR)/x11/d_polyse.o : $(MOUNT_DIR)/d_polyse.c + $(DO_X11_CC) + +$(BUILDDIR)/x11/d_scan.o : $(MOUNT_DIR)/d_scan.c + $(DO_X11_CC) + +$(BUILDDIR)/x11/d_sky.o : $(MOUNT_DIR)/d_sky.c + $(DO_X11_CC) + +$(BUILDDIR)/x11/d_sprite.o : $(MOUNT_DIR)/d_sprite.c + $(DO_X11_CC) + +$(BUILDDIR)/x11/d_surf.o : $(MOUNT_DIR)/d_surf.c + $(DO_X11_CC) + +$(BUILDDIR)/x11/d_vars.o : $(MOUNT_DIR)/d_vars.c + $(DO_X11_CC) + +$(BUILDDIR)/x11/d_zpoint.o : $(MOUNT_DIR)/d_zpoint.c + $(DO_X11_CC) + +$(BUILDDIR)/x11/host.o : $(MOUNT_DIR)/host.c + $(DO_X11_CC) + +$(BUILDDIR)/x11/host_cmd.o : $(MOUNT_DIR)/host_cmd.c + $(DO_X11_CC) + +$(BUILDDIR)/x11/keys.o : $(MOUNT_DIR)/keys.c + $(DO_X11_CC) + +$(BUILDDIR)/x11/menu.o : $(MOUNT_DIR)/menu.c + $(DO_X11_CC) + +$(BUILDDIR)/x11/mathlib.o : $(MOUNT_DIR)/mathlib.c + $(DO_X11_CC) + +$(BUILDDIR)/x11/model.o : $(MOUNT_DIR)/model.c + $(DO_X11_CC) + +$(BUILDDIR)/x11/net_dgrm.o : $(MOUNT_DIR)/net_dgrm.c + $(DO_X11_CC) + +$(BUILDDIR)/x11/net_loop.o : $(MOUNT_DIR)/net_loop.c + $(DO_X11_CC) + +$(BUILDDIR)/x11/net_main.o : $(MOUNT_DIR)/net_main.c + $(DO_X11_CC) + +$(BUILDDIR)/x11/net_vcr.o : $(MOUNT_DIR)/net_vcr.c + $(DO_X11_CC) + +$(BUILDDIR)/x11/net_udp.o : $(MOUNT_DIR)/net_udp.c + $(DO_X11_CC) + +$(BUILDDIR)/x11/net_bsd.o : $(MOUNT_DIR)/net_bsd.c + $(DO_X11_CC) + +$(BUILDDIR)/x11/nonintel.o : $(MOUNT_DIR)/nonintel.c + $(DO_X11_CC) + +$(BUILDDIR)/x11/pr_cmds.o : $(MOUNT_DIR)/pr_cmds.c + $(DO_X11_CC) + +$(BUILDDIR)/x11/pr_edict.o : $(MOUNT_DIR)/pr_edict.c + $(DO_X11_CC) + +$(BUILDDIR)/x11/pr_exec.o : $(MOUNT_DIR)/pr_exec.c + $(DO_X11_CC) + +$(BUILDDIR)/x11/r_aclip.o : $(MOUNT_DIR)/r_aclip.c + $(DO_X11_CC) + +$(BUILDDIR)/x11/r_alias.o : $(MOUNT_DIR)/r_alias.c + $(DO_X11_CC) + +$(BUILDDIR)/x11/r_bsp.o : $(MOUNT_DIR)/r_bsp.c + $(DO_X11_CC) + +$(BUILDDIR)/x11/r_light.o : $(MOUNT_DIR)/r_light.c + $(DO_X11_CC) + +$(BUILDDIR)/x11/r_draw.o : $(MOUNT_DIR)/r_draw.c + $(DO_X11_CC) + +$(BUILDDIR)/x11/r_efrag.o : $(MOUNT_DIR)/r_efrag.c + $(DO_X11_CC) + +$(BUILDDIR)/x11/r_edge.o : $(MOUNT_DIR)/r_edge.c + $(DO_X11_CC) + +$(BUILDDIR)/x11/r_misc.o : $(MOUNT_DIR)/r_misc.c + $(DO_X11_CC) + +$(BUILDDIR)/x11/r_main.o : $(MOUNT_DIR)/r_main.c + $(DO_X11_CC) + +$(BUILDDIR)/x11/r_sky.o : $(MOUNT_DIR)/r_sky.c + $(DO_X11_CC) + +$(BUILDDIR)/x11/r_sprite.o : $(MOUNT_DIR)/r_sprite.c + $(DO_X11_CC) + +$(BUILDDIR)/x11/r_surf.o : $(MOUNT_DIR)/r_surf.c + $(DO_X11_CC) + +$(BUILDDIR)/x11/r_part.o : $(MOUNT_DIR)/r_part.c + $(DO_X11_CC) + +$(BUILDDIR)/x11/r_vars.o : $(MOUNT_DIR)/r_vars.c + $(DO_X11_CC) + +$(BUILDDIR)/x11/screen.o : $(MOUNT_DIR)/screen.c + $(DO_X11_CC) + +$(BUILDDIR)/x11/sbar.o : $(MOUNT_DIR)/sbar.c + $(DO_X11_CC) + +$(BUILDDIR)/x11/sv_main.o : $(MOUNT_DIR)/sv_main.c + $(DO_X11_CC) + +$(BUILDDIR)/x11/sv_phys.o : $(MOUNT_DIR)/sv_phys.c + $(DO_X11_CC) + +$(BUILDDIR)/x11/sv_move.o : $(MOUNT_DIR)/sv_move.c + $(DO_X11_CC) + +$(BUILDDIR)/x11/sv_user.o : $(MOUNT_DIR)/sv_user.c + $(DO_X11_CC) + +$(BUILDDIR)/x11/zone.o : $(MOUNT_DIR)/zone.c + $(DO_X11_CC) + +$(BUILDDIR)/x11/view.o : $(MOUNT_DIR)/view.c + $(DO_X11_CC) + +$(BUILDDIR)/x11/wad.o : $(MOUNT_DIR)/wad.c + $(DO_X11_CC) + +$(BUILDDIR)/x11/world.o : $(MOUNT_DIR)/world.c + $(DO_X11_CC) + +$(BUILDDIR)/x11/cd_linux.o : $(MOUNT_DIR)/cd_linux.c + $(DO_X11_CC) + +$(BUILDDIR)/x11/sys_linux.o :$(MOUNT_DIR)/sys_linux.c + $(DO_X11_CC) + +$(BUILDDIR)/x11/vid_x.o: $(MOUNT_DIR)/vid_x.c + $(DO_O_CC) + +$(BUILDDIR)/x11/snd_dma.o : $(MOUNT_DIR)/snd_dma.c + $(DO_X11_CC) + +$(BUILDDIR)/x11/snd_mem.o : $(MOUNT_DIR)/snd_mem.c + $(DO_X11_CC) + +$(BUILDDIR)/x11/snd_mix.o : $(MOUNT_DIR)/snd_mix.c + $(DO_X11_CC) + +$(BUILDDIR)/x11/snd_linux.o :$(MOUNT_DIR)/snd_linux.c + $(DO_X11_CC) + +##### + +$(BUILDDIR)/x11/d_copy.o : $(MOUNT_DIR)/d_copy.S + $(DO_AS) + +$(BUILDDIR)/x11/d_draw.o : $(MOUNT_DIR)/d_draw.S + $(DO_AS) + +$(BUILDDIR)/x11/d_draw16.o : $(MOUNT_DIR)/d_draw16.S + $(DO_AS) + +$(BUILDDIR)/x11/d_parta.o : $(MOUNT_DIR)/d_parta.S + $(DO_AS) + +$(BUILDDIR)/x11/d_polysa.o : $(MOUNT_DIR)/d_polysa.S + $(DO_AS) + +$(BUILDDIR)/x11/d_scana.o : $(MOUNT_DIR)/d_scana.S + $(DO_AS) + +$(BUILDDIR)/x11/d_spr8.o : $(MOUNT_DIR)/d_spr8.S + $(DO_AS) + +$(BUILDDIR)/x11/d_varsa.o : $(MOUNT_DIR)/d_varsa.S + $(DO_AS) + +$(BUILDDIR)/x11/math.o : $(MOUNT_DIR)/math.S + $(DO_AS) + +$(BUILDDIR)/x11/r_aliasa.o : $(MOUNT_DIR)/r_aliasa.S + $(DO_AS) + +$(BUILDDIR)/x11/r_drawa.o : $(MOUNT_DIR)/r_drawa.S + $(DO_AS) + +$(BUILDDIR)/x11/r_edgea.o : $(MOUNT_DIR)/r_edgea.S + $(DO_AS) + +$(BUILDDIR)/x11/r_varsa.o : $(MOUNT_DIR)/r_varsa.S + $(DO_AS) + +$(BUILDDIR)/x11/surf16.o : $(MOUNT_DIR)/surf16.S + $(DO_AS) + +$(BUILDDIR)/x11/surf8.o : $(MOUNT_DIR)/surf8.S + $(DO_AS) + +$(BUILDDIR)/x11/worlda.o : $(MOUNT_DIR)/worlda.S + $(DO_AS) + +$(BUILDDIR)/x11/r_aclipa.o : $(MOUNT_DIR)/r_aclipa.S + $(DO_AS) + +$(BUILDDIR)/x11/snd_mixa.o : $(MOUNT_DIR)/snd_mixa.S + $(DO_AS) + +$(BUILDDIR)/x11/sys_dosa.o : $(MOUNT_DIR)/sys_dosa.S + $(DO_AS) + +############################################################################# +# GLQuake +############################################################################# + +GLQUAKE_OBJS= \ + $(BUILDDIR)/glquake/cl_demo.o \ + $(BUILDDIR)/glquake/cl_input.o \ + $(BUILDDIR)/glquake/cl_main.o \ + $(BUILDDIR)/glquake/cl_parse.o \ + $(BUILDDIR)/glquake/cl_tent.o \ + $(BUILDDIR)/glquake/chase.o \ + $(BUILDDIR)/glquake/cmd.o \ + $(BUILDDIR)/glquake/common.o \ + $(BUILDDIR)/glquake/console.o \ + $(BUILDDIR)/glquake/crc.o \ + $(BUILDDIR)/glquake/cvar.o \ + \ + $(BUILDDIR)/glquake/gl_draw.o \ + $(BUILDDIR)/glquake/gl_mesh.o \ + $(BUILDDIR)/glquake/gl_model.o \ + $(BUILDDIR)/glquake/gl_refrag.o \ + $(BUILDDIR)/glquake/gl_rlight.o \ + $(BUILDDIR)/glquake/gl_rmain.o \ + $(BUILDDIR)/glquake/gl_rmisc.o \ + $(BUILDDIR)/glquake/gl_rsurf.o \ + $(BUILDDIR)/glquake/gl_screen.o \ + $(BUILDDIR)/glquake/gl_test.o \ + $(BUILDDIR)/glquake/gl_warp.o \ + \ + $(BUILDDIR)/glquake/host.o \ + $(BUILDDIR)/glquake/host_cmd.o \ + $(BUILDDIR)/glquake/keys.o \ + $(BUILDDIR)/glquake/menu.o \ + $(BUILDDIR)/glquake/mathlib.o \ + $(BUILDDIR)/glquake/net_dgrm.o \ + $(BUILDDIR)/glquake/net_loop.o \ + $(BUILDDIR)/glquake/net_main.o \ + $(BUILDDIR)/glquake/net_vcr.o \ + $(BUILDDIR)/glquake/net_udp.o \ + $(BUILDDIR)/glquake/net_bsd.o \ + $(BUILDDIR)/glquake/pr_cmds.o \ + $(BUILDDIR)/glquake/pr_edict.o \ + $(BUILDDIR)/glquake/pr_exec.o \ + $(BUILDDIR)/glquake/r_part.o \ + $(BUILDDIR)/glquake/sbar.o \ + $(BUILDDIR)/glquake/sv_main.o \ + $(BUILDDIR)/glquake/sv_phys.o \ + $(BUILDDIR)/glquake/sv_move.o \ + $(BUILDDIR)/glquake/sv_user.o \ + $(BUILDDIR)/glquake/zone.o \ + $(BUILDDIR)/glquake/view.o \ + $(BUILDDIR)/glquake/wad.o \ + $(BUILDDIR)/glquake/world.o \ + $(BUILDDIR)/glquake/cd_linux.o \ + $(BUILDDIR)/glquake/sys_linux.o \ + $(BUILDDIR)/glquake/snd_dma.o \ + $(BUILDDIR)/glquake/snd_mem.o \ + $(BUILDDIR)/glquake/snd_mix.o \ + $(BUILDDIR)/glquake/snd_linux.o \ + \ + $(BUILDDIR)/glquake/math.o \ + $(BUILDDIR)/glquake/worlda.o \ + $(BUILDDIR)/glquake/snd_mixa.o \ + $(BUILDDIR)/glquake/sys_dosa.o + +GLSVGA_OBJS=$(BUILDDIR)/glquake/gl_vidlinux.o + +GLX_OBJS=$(BUILDDIR)/glquake/gl_vidlinuxglx.o + +$(BUILDDIR)/bin/glquake : $(GLQUAKE_OBJS) $(GLSVGA_OBJS) + $(CC) $(CFLAGS) -o $@ $(GLQUAKE_OBJS) $(GLSVGA_OBJS) $(MESAGLLDFLAGS) $(SVGALDFLAGS) $(LDFLAGS) + +$(BUILDDIR)/bin/glquake.glx : $(GLQUAKE_OBJS) $(GLX_OBJS) + $(CC) $(CFLAGS) -o $@ $(GLQUAKE_OBJS) $(GLX_OBJS) $(GLLDFLAGS) $(LDFLAGS) + +$(BUILDDIR)/bin/glquake.3dfxgl : $(GLQUAKE_OBJS) $(GLSVGA_OBJS) + $(CC) $(CFLAGS) -o $@ $(GLQUAKE_OBJS) $(GLSVGA_OBJS) $(TDFXGLLDFLAGS) $(SVGALDFLAGS) $(LDFLAGS) + +$(BUILDDIR)/glquake/cl_demo.o : $(MOUNT_DIR)/cl_demo.c + $(DO_GL_CC) + +$(BUILDDIR)/glquake/cl_input.o : $(MOUNT_DIR)/cl_input.c + $(DO_GL_CC) + +$(BUILDDIR)/glquake/cl_main.o : $(MOUNT_DIR)/cl_main.c + $(DO_GL_CC) + +$(BUILDDIR)/glquake/cl_parse.o : $(MOUNT_DIR)/cl_parse.c + $(DO_GL_CC) + +$(BUILDDIR)/glquake/cl_tent.o : $(MOUNT_DIR)/cl_tent.c + $(DO_GL_CC) + +$(BUILDDIR)/glquake/chase.o : $(MOUNT_DIR)/chase.c + $(DO_GL_CC) + +$(BUILDDIR)/glquake/cmd.o : $(MOUNT_DIR)/cmd.c + $(DO_GL_CC) + +$(BUILDDIR)/glquake/common.o : $(MOUNT_DIR)/common.c + $(DO_GL_DEBUG_CC) + +$(BUILDDIR)/glquake/console.o : $(MOUNT_DIR)/console.c + $(DO_GL_CC) + +$(BUILDDIR)/glquake/crc.o : $(MOUNT_DIR)/crc.c + $(DO_GL_CC) + +$(BUILDDIR)/glquake/cvar.o : $(MOUNT_DIR)/cvar.c + $(DO_GL_CC) + +$(BUILDDIR)/glquake/gl_draw.o : $(MOUNT_DIR)/gl_draw.c + $(DO_GL_CC) + +$(BUILDDIR)/glquake/gl_mesh.o : $(MOUNT_DIR)/gl_mesh.c + $(DO_GL_CC) + +$(BUILDDIR)/glquake/gl_model.o : $(MOUNT_DIR)/gl_model.c + $(DO_GL_CC) + +$(BUILDDIR)/glquake/gl_refrag.o : $(MOUNT_DIR)/gl_refrag.c + $(DO_GL_CC) + +$(BUILDDIR)/glquake/gl_rlight.o : $(MOUNT_DIR)/gl_rlight.c + $(DO_GL_CC) + +$(BUILDDIR)/glquake/gl_rmain.o : $(MOUNT_DIR)/gl_rmain.c + $(DO_GL_CC) + +$(BUILDDIR)/glquake/gl_rmisc.o : $(MOUNT_DIR)/gl_rmisc.c + $(DO_GL_CC) + +$(BUILDDIR)/glquake/gl_rsurf.o : $(MOUNT_DIR)/gl_rsurf.c + $(DO_GL_CC) + +$(BUILDDIR)/glquake/gl_screen.o : $(MOUNT_DIR)/gl_screen.c + $(DO_GL_CC) + +$(BUILDDIR)/glquake/gl_test.o : $(MOUNT_DIR)/gl_test.c + $(DO_GL_CC) + +$(BUILDDIR)/glquake/gl_vidlinux.o : $(MOUNT_DIR)/gl_vidlinux.c + $(DO_GL_CC) + +$(BUILDDIR)/glquake/gl_vidlinuxglx.o : $(MOUNT_DIR)/gl_vidlinuxglx.c + $(DO_GL_CC) + +$(BUILDDIR)/glquake/gl_warp.o : $(MOUNT_DIR)/gl_warp.c + $(DO_GL_CC) + +$(BUILDDIR)/glquake/host.o : $(MOUNT_DIR)/host.c + $(DO_GL_CC) + +$(BUILDDIR)/glquake/host_cmd.o : $(MOUNT_DIR)/host_cmd.c + $(DO_GL_CC) + +$(BUILDDIR)/glquake/keys.o : $(MOUNT_DIR)/keys.c + $(DO_GL_CC) + +$(BUILDDIR)/glquake/menu.o : $(MOUNT_DIR)/menu.c + $(DO_GL_CC) + +$(BUILDDIR)/glquake/mathlib.o : $(MOUNT_DIR)/mathlib.c + $(DO_GL_CC) + +$(BUILDDIR)/glquake/net_dgrm.o : $(MOUNT_DIR)/net_dgrm.c + $(DO_GL_CC) + +$(BUILDDIR)/glquake/net_loop.o : $(MOUNT_DIR)/net_loop.c + $(DO_GL_CC) + +$(BUILDDIR)/glquake/net_main.o : $(MOUNT_DIR)/net_main.c + $(DO_GL_CC) + +$(BUILDDIR)/glquake/net_vcr.o : $(MOUNT_DIR)/net_vcr.c + $(DO_GL_CC) + +$(BUILDDIR)/glquake/net_udp.o : $(MOUNT_DIR)/net_udp.c + $(DO_GL_CC) + +$(BUILDDIR)/glquake/net_bsd.o : $(MOUNT_DIR)/net_bsd.c + $(DO_GL_CC) + +$(BUILDDIR)/glquake/pr_cmds.o : $(MOUNT_DIR)/pr_cmds.c + $(DO_GL_CC) + +$(BUILDDIR)/glquake/pr_edict.o : $(MOUNT_DIR)/pr_edict.c + $(DO_GL_CC) + +$(BUILDDIR)/glquake/pr_exec.o : $(MOUNT_DIR)/pr_exec.c + $(DO_GL_CC) + +$(BUILDDIR)/glquake/r_part.o : $(MOUNT_DIR)/r_part.c + $(DO_GL_CC) + +$(BUILDDIR)/glquake/sbar.o : $(MOUNT_DIR)/sbar.c + $(DO_GL_CC) + +$(BUILDDIR)/glquake/sv_main.o : $(MOUNT_DIR)/sv_main.c + $(DO_GL_CC) + +$(BUILDDIR)/glquake/sv_phys.o : $(MOUNT_DIR)/sv_phys.c + $(DO_GL_CC) + +$(BUILDDIR)/glquake/sv_move.o : $(MOUNT_DIR)/sv_move.c + $(DO_GL_CC) + +$(BUILDDIR)/glquake/sv_user.o : $(MOUNT_DIR)/sv_user.c + $(DO_GL_CC) + +$(BUILDDIR)/glquake/zone.o : $(MOUNT_DIR)/zone.c + $(DO_GL_CC) + +$(BUILDDIR)/glquake/view.o : $(MOUNT_DIR)/view.c + $(DO_GL_CC) + +$(BUILDDIR)/glquake/wad.o : $(MOUNT_DIR)/wad.c + $(DO_GL_CC) + +$(BUILDDIR)/glquake/world.o : $(MOUNT_DIR)/world.c + $(DO_GL_CC) + +$(BUILDDIR)/glquake/cd_linux.o : $(MOUNT_DIR)/cd_linux.c + $(DO_GL_CC) + +$(BUILDDIR)/glquake/sys_linux.o : $(MOUNT_DIR)/sys_linux.c + $(DO_GL_CC) + +$(BUILDDIR)/glquake/snd_dma.o : $(MOUNT_DIR)/snd_dma.c + $(DO_GL_CC) + +$(BUILDDIR)/glquake/snd_mem.o : $(MOUNT_DIR)/snd_mem.c + $(DO_GL_CC) + +$(BUILDDIR)/glquake/snd_mix.o : $(MOUNT_DIR)/snd_mix.c + $(DO_GL_CC) + +$(BUILDDIR)/glquake/snd_linux.o : $(MOUNT_DIR)/snd_linux.c + $(DO_GL_CC) + +$(BUILDDIR)/glquake/math.o : $(MOUNT_DIR)/math.S + $(DO_GL_AS) + +$(BUILDDIR)/glquake/worlda.o : $(MOUNT_DIR)/worlda.S + $(DO_GL_AS) + +$(BUILDDIR)/glquake/snd_mixa.o : $(MOUNT_DIR)/snd_mixa.S + $(DO_GL_AS) + +$(BUILDDIR)/glquake/sys_dosa.o : $(MOUNT_DIR)/sys_dosa.S + $(DO_GL_AS) + +############################################################################# +# RPM +############################################################################# + +# Make RPMs. You need to be root to make this work +RPMROOT=/usr/src/redhat +RPM = rpm +RPMFLAGS = -bb +INSTALLDIR = /usr/local/games/quake +TMPDIR = /var/tmp +RPMDIR = $(TMPDIR)/quake-$(VERSION) +BASERPMDIR = $(TMPDIR)/quake-$(BASEVERSION) + +rpm: rpm-quake rpm-quake-data rpm-hipnotic rpm-rogue + +rpm-quake: quake.spec \ + $(BUILD_RELEASE_DIR)/bin/squake \ + $(BUILD_RELEASE_DIR)/bin/quake.x11 \ + $(BUILD_RELEASE_DIR)/bin/glquake \ + $(BUILD_RELEASE_DIR)/bin/glquake.glx \ + $(BUILD_RELEASE_DIR)/bin/glquake.3dfxgl + touch $(RPMROOT)/SOURCES/quake-$(VERSION).tar.gz + if [ ! -d RPMS ];then mkdir RPMS;fi + cp $(MOUNT_DIR)/quake.gif $(RPMROOT)/SOURCES/quake.gif + + # basic binaries rpm + -mkdirhier $(RPMDIR)/$(INSTALLDIR) + cp $(MOUNT_DIR)/docs/README $(RPMDIR)/$(INSTALLDIR)/. + cp $(BUILD_RELEASE_DIR)/bin/squake $(RPMDIR)/$(INSTALLDIR)/squake + strip $(RPMDIR)/$(INSTALLDIR)/squake + cp $(BUILD_RELEASE_DIR)/bin/quake.x11 $(RPMDIR)/$(INSTALLDIR)/quake.x11 + strip $(RPMDIR)/$(INSTALLDIR)/quake.x11 + cp $(BUILD_RELEASE_DIR)/bin/glquake $(RPMDIR)/$(INSTALLDIR)/glquake + strip $(RPMDIR)/$(INSTALLDIR)/glquake + cp $(BUILD_RELEASE_DIR)/bin/glquake.glx $(RPMDIR)/$(INSTALLDIR)/glquake.glx + strip $(RPMDIR)/$(INSTALLDIR)/glquake.glx + cp $(BUILD_RELEASE_DIR)/bin/glquake.3dfxgl $(RPMDIR)/$(INSTALLDIR)/glquake.3dfxgl + strip $(RPMDIR)/$(INSTALLDIR)/glquake.3dfxgl + -mkdirhier $(RPMDIR)/usr/lib + cp $(TDFXGL_DIR)/release$(ARCH)$(GLIBC)/lib3dfxgl.so $(RPMDIR)/usr/lib/lib3dfxgl.so + cp $(MESA_DIR)/lib/libMesaGL.so.2.6 $(RPMDIR)/usr/lib/libMesaGL.so.2.6 + + cp quake.spec $(RPMROOT)/SPECS/. + cd $(RPMROOT)/SPECS; $(RPM) $(RPMFLAGS) quake.spec + rm -rf $(RPMDIR) + rm -f $(RPMROOT)/SOURCES/quake-$(VERSION).tar.gz + + mv $(RPMROOT)/RPMS/$(ARCH)/quake-$(VERSION)-$(RPM_RELEASE).$(ARCH).rpm RPMS/. + +QUAKEDATADIR=$(TMPDIR)/quake-data-$(BASEVERSION) +rpm-quake-data: quake-data.spec + # data rpm + touch $(RPMROOT)/SOURCES/quake-$(BASEVERSION)-data.tar.gz + + -mkdirhier $(QUAKEDATADIR)/$(INSTALLDIR)/id1 + cp $(MASTER_DIR)/id1/pak0.pak $(QUAKEDATADIR)/$(INSTALLDIR)/id1/. + cp $(MASTER_DIR)/id1/pak1.pak $(QUAKEDATADIR)/$(INSTALLDIR)/id1/. + cp $(MOUNT_DIR)/docs/README $(QUAKEDATADIR)/$(INSTALLDIR)/. + cp $(MOUNT_DIR)/data/comexp.txt $(QUAKEDATADIR)/$(INSTALLDIR)/. + cp $(MOUNT_DIR)/data/help.txt $(QUAKEDATADIR)/$(INSTALLDIR)/. + cp $(MOUNT_DIR)/data/licinfo.txt $(QUAKEDATADIR)/$(INSTALLDIR)/. + cp $(MOUNT_DIR)/data/manual.txt $(QUAKEDATADIR)/$(INSTALLDIR)/. + cp $(MOUNT_DIR)/data/readme.txt $(QUAKEDATADIR)/$(INSTALLDIR)/. + cp $(MOUNT_DIR)/data/rlicnse.txt $(QUAKEDATADIR)/$(INSTALLDIR)/. + cp $(MOUNT_DIR)/data/slicnse.txt $(QUAKEDATADIR)/$(INSTALLDIR)/. + cp $(MOUNT_DIR)/data/techinfo.txt $(QUAKEDATADIR)/$(INSTALLDIR)/. + cp quake-data.spec $(RPMROOT)/SPECS/. + cd $(RPMROOT)/SPECS; $(RPM) $(RPMFLAGS) quake-data.spec + rm -rf $(QUAKEDATADIR) + rm -f $(RPMROOT)/SOURCES/quake-$(BASEVERSION)-data.tar.gz + + mv $(RPMROOT)/RPMS/$(NOARCH)/quake-data-$(BASEVERSION)-$(RPM_RELEASE).$(NOARCH).rpm RPMS/. + +RPMHIPNOTICDIR=$(TMPDIR)/quake-hipnotic-$(BASEVERSION) +rpm-hipnotic: quake-hipnotic.spec + touch $(RPMROOT)/SOURCES/quake-hipnotic-$(BASEVERSION).tar.gz + if [ ! -d RPMS ];then mkdir RPMS;fi + cp $(MOUNT_DIR)/quake.gif $(RPMROOT)/SOURCES/quake.gif + -mkdirhier $(RPMHIPNOTICDIR)/$(INSTALLDIR)/hipnotic/docs + cp $(MASTER_DIR)/hipnotic/pak0.pak $(RPMHIPNOTICDIR)/$(INSTALLDIR)/hipnotic/. + cp $(MASTER_DIR)/hipnotic/config.cfg $(RPMHIPNOTICDIR)/$(INSTALLDIR)/hipnotic/. + cp $(MASTER_DIR)/hipnotic/docs/manual.doc $(RPMHIPNOTICDIR)/$(INSTALLDIR)/hipnotic/docs/. + cp $(MASTER_DIR)/hipnotic/docs/manual.htm $(RPMHIPNOTICDIR)/$(INSTALLDIR)/hipnotic/docs/. + cp $(MASTER_DIR)/hipnotic/docs/manual.txt $(RPMHIPNOTICDIR)/$(INSTALLDIR)/hipnotic/docs/. + cp $(MASTER_DIR)/hipnotic/docs/readme.doc $(RPMHIPNOTICDIR)/$(INSTALLDIR)/hipnotic/docs/. + cp $(MASTER_DIR)/hipnotic/docs/readme.htm $(RPMHIPNOTICDIR)/$(INSTALLDIR)/hipnotic/docs/. + cp $(MASTER_DIR)/hipnotic/docs/readme.txt $(RPMHIPNOTICDIR)/$(INSTALLDIR)/hipnotic/docs/. + cp quake-hipnotic.spec $(RPMROOT)/SPECS/. + cd $(RPMROOT)/SPECS; $(RPM) $(RPMFLAGS) quake-hipnotic.spec + rm -rf $(RPMHIPNOTICDIR) + rm -f $(RPMROOT)/SOURCES/quake-hipnotic-$(BASEVERSION).tar.gz + + mv $(RPMROOT)/RPMS/$(NOARCH)/quake-hipnotic-$(BASEVERSION)-$(RPM_RELEASE).$(NOARCH).rpm RPMS/. + +RPMROGUEDIR=$(TMPDIR)/quake-rogue-$(BASEVERSION) +rpm-rogue: quake-rogue.spec + touch $(RPMROOT)/SOURCES/quake-rogue-$(BASEVERSION).tar.gz + if [ ! -d RPMS ];then mkdir RPMS;fi + cp $(MOUNT_DIR)/quake.gif $(RPMROOT)/SOURCES/quake.gif + -mkdirhier $(RPMROGUEDIR)/$(INSTALLDIR)/rogue/docs + cp $(MASTER_DIR)/rogue/pak0.pak $(RPMROGUEDIR)/$(INSTALLDIR)/rogue/. + cp $(MASTER_DIR)/rogue/docs/manual.doc $(RPMROGUEDIR)/$(INSTALLDIR)/rogue/docs/. + cp $(MASTER_DIR)/rogue/docs/manual.htm $(RPMROGUEDIR)/$(INSTALLDIR)/rogue/docs/. + cp $(MASTER_DIR)/rogue/docs/manual.txt $(RPMROGUEDIR)/$(INSTALLDIR)/rogue/docs/. + cp $(MASTER_DIR)/rogue/docs/readme.doc $(RPMROGUEDIR)/$(INSTALLDIR)/rogue/docs/. + cp $(MASTER_DIR)/rogue/docs/readme.htm $(RPMROGUEDIR)/$(INSTALLDIR)/rogue/docs/. + cp $(MASTER_DIR)/rogue/docs/readme.txt $(RPMROGUEDIR)/$(INSTALLDIR)/rogue/docs/. + cp $(MASTER_DIR)/rogue/docs/ctf.doc $(RPMROGUEDIR)/$(INSTALLDIR)/rogue/docs/. + cp $(MASTER_DIR)/rogue/docs/ctf.htm $(RPMROGUEDIR)/$(INSTALLDIR)/rogue/docs/. + cp $(MASTER_DIR)/rogue/docs/ctf.txt $(RPMROGUEDIR)/$(INSTALLDIR)/rogue/docs/. + cp quake-rogue.spec $(RPMROOT)/SPECS/. + cd $(RPMROOT)/SPECS; $(RPM) $(RPMFLAGS) quake-rogue.spec + rm -rf $(RPMROGUEDIR) + rm -f $(RPMROOT)/SOURCES/quake-rogue-$(BASEVERSION).tar.gz + + mv $(RPMROOT)/RPMS/$(NOARCH)/quake-rogue-$(BASEVERSION)-$(RPM_RELEASE).$(NOARCH).rpm RPMS/. + +quake.spec : $(MOUNT_DIR)/quake.spec.sh + sh $< $(VERSION) $(RPM_RELEASE) $(INSTALLDIR) > $@ + +quake-data.spec : $(MOUNT_DIR)/quake-data.spec.sh + sh $< $(BASEVERSION) $(RPM_RELEASE) $(INSTALLDIR) > $@ + +quake-hipnotic.spec : $(MOUNT_DIR)/quake-hipnotic.spec.sh + sh $< $(BASEVERSION) $(RPM_RELEASE) $(INSTALLDIR) > $@ + +quake-rogue.spec : $(MOUNT_DIR)/quake-rogue.spec.sh + sh $< $(BASEVERSION) $(RPM_RELEASE) $(INSTALLDIR) > $@ + +############################################################################# +# MISC +############################################################################# + +clean: clean-debug clean-release + rm -f squake.spec glquake.spec quake.x11.spec + +clean-debug: + $(MAKE) clean2 BUILDDIR=$(BUILD_DEBUG_DIR) CFLAGS="$(DEBUG_CFLAGS)" + +clean-release: + $(MAKE) clean2 BUILDDIR=$(BUILD_RELEASE_DIR) CFLAGS="$(DEBUG_CFLAGS)" + +clean2: + -rm -f $(SQUAKE_OBJS) $(X11_OBJS) $(GLQUAKE_OBJS) $(GLSVGA_OBJS) \ + $(GLX_OBJS) + diff --git a/contrib/other/sdlquake-1.0.9/README.SDL b/contrib/other/sdlquake-1.0.9/README.SDL new file mode 100644 index 000000000..87f7096c3 --- /dev/null +++ b/contrib/other/sdlquake-1.0.9/README.SDL @@ -0,0 +1,34 @@ + +This is a quick hack of Quake ported to the Simple DirectMedia Layer library. +http://www.devolution.com/~slouken/SDL/ + +To build under Linux, simply run ./configure; make + +This game requires the original Quake datafiles. You can get the shareware +data files from http://www.idsoftware.com/. + +Of interest in the original X sources is the following: + // Duff's Device + count = width; + n = (count + 7) / 8; + dest = ((PIXEL16 *)src) + x+width - 1; + src += x+width - 1; + + switch (count % 8) { + case 0: do { *dest-- = st2d_8to16table[*src--]; + case 7: *dest-- = st2d_8to16table[*src--]; + case 6: *dest-- = st2d_8to16table[*src--]; + case 5: *dest-- = st2d_8to16table[*src--]; + case 4: *dest-- = st2d_8to16table[*src--]; + case 3: *dest-- = st2d_8to16table[*src--]; + case 2: *dest-- = st2d_8to16table[*src--]; + case 1: *dest-- = st2d_8to16table[*src--]; + } while (--n > 0); + } +This idea may make it into the SDL blitters if it turns out to be faster +than my current code. :) + +Thanks to Zoid, Dave Taylor, John Carmack, and everyone else involved in the +open source release of id games. :) + +- Sam Lantinga (slouken@devolution.com) 12/25/1999 diff --git a/contrib/other/sdlquake-1.0.9/README.Solaris b/contrib/other/sdlquake-1.0.9/README.Solaris new file mode 100644 index 000000000..6d52ed01c --- /dev/null +++ b/contrib/other/sdlquake-1.0.9/README.Solaris @@ -0,0 +1,98 @@ +Solaris 2 Quake / QuakeWorld +---------------------------- + + This is an UNSUPPORTED version of Quake and QuakeWorld. Don't + bother id software about it. Bug reports will be ignored. + +PORT DETAILS +------------ + + There are a few major difference between this port and the + vanilla Quake/QuakeWorld available on the internet. For + optimum performance, you should copy everything to a directory + on your local system before starting play so that you are + not mounting files from a remote filesystem. + + In order to use this program, you need the files pak0.pak + and pak1.pak in the id1 directory found on a registered copy of + Quake. You can ftp them to your Solaris host from a Windows95 + machine for example. The files must be in an id1 subdirectory from + the directory you install Quake/QuakeWorld, and all file names must + be lowercase. Add on packages such as ThreeWave CTF work fine as + well, just place such addon packages in their own directory as you + would on a Windows95 installation. But again, make sure all files + are lowercase. + + COMMAND LINE FLAGS: + + +pixel_multiply + + You can magnify the screen by using this flag: + + Ex: % quake +pixel_multiply 2 + + You can also use this command (without the dash) + from the Quake console. pixel_multiply is a Quake + cvar and is saved from session to session in the + config.cfg file. + + -winsize + + Set the size of the window when you start + + -count_frames + + See how many frames per second you're getting + + GAME SETTINGS + + mouse binding + + You can bind and unbind the mouse to the Quake window + by using the Use Mouse selection in the Options menu, + or with the "_windowed_mouse" command in the console, + ex "_windowed_mouse 1" Now, moving the mouse will move + your player. Use "_windowed_mouse 0" to unbind. You + can bind or alias this to a key. + + Example command: + + % quake.xil +pixel_multiply 2 -winsize 400 300 + +WHAT IS "QUAKEWORLD" AND HOW DO I USE IT? +----------------------------------------- + + In a nutshell, QuakeWorld is an extension of Quake that is + much more user friendly. It allows the user to dynamically + download changes from the server, such as new maps and new + weapons while inside the Quake client. It is not directly + compatible with Quake (ie, you can't connect to a Quake server + from a QuakeWorld client) but in general it is superior to + Quake. QuakeWorld also offers much smoother play over the + Internet by using client prediction. For more information, + check out http://www.quakeworld.net/. + + In order to use it, you must make a copy of the "qw" + directory. Any new stuff that is downloaded from a QuakeWorld + server will be stored in this directory. All regular Quake + flags apply so you can use the same command line as before. + + Example command: + + % qwcl.xil +pixel_multiply 2 -winsize 400 300 + +WHERE CAN I FIND OUT ABOUT... +----------------------------- + + If you've got questions about Quake, rest assured that there + are answers out there. Try checking out these web sites: + + http://www.planetquake.com/ + http://www.stomped.com/ + http://www.quakeworld.net/ + + If all else fails use a search engine. + +Happy fragging, +the Quake/Solaris team + diff --git a/contrib/other/sdlquake-1.0.9/Tupfile.lua b/contrib/other/sdlquake-1.0.9/Tupfile.lua new file mode 100644 index 000000000..f51650abc --- /dev/null +++ b/contrib/other/sdlquake-1.0.9/Tupfile.lua @@ -0,0 +1,41 @@ +if tup.getconfig("NO_GCC") ~= "" then return end +if tup.getconfig("HELPERDIR") == "" +then + if tup.getconfig("NO_NASM") ~= "" then return end -- required for SDL compilation + HELPERDIR = "../../../programs" +end +tup.include(HELPERDIR .. "/use_gcc.lua") +tup.include(HELPERDIR .. "/use_menuetlibc.lua") +use_dynamic_stack() -- default 64K are not sufficient +tup.include(HELPERDIR .. "/use_sdl.lua") +CFLAGS = CFLAGS .. " -DSDL -UWIN32 -U_WIN32 -U__WIN32__ -D_KOLIBRI" +CFLAGS = CFLAGS .. " -DUSE_ASM" +-- CFLAGS = CFLAGS:gsub("-Os", "-O2") +compile_gcc{ + "chase.c", "cl_demo.c", "cl_input.c", "cl_main.c", "cl_parse.c", "cl_tent.c", + "cmd.c", "common.c", "console.c", "crc.c", "cvar.c", "d_edge.c", "d_init.c", + "d_modech.c", "d_part.c", "d_polyse.c", "d_scan.c", "d_sky.c", "d_sprite.c", + "d_surf.c", "draw.c", "host.c", "host_cmd.c", "keys.c", "mathlib.c", + "menu.c", "model.c", "net_loop.c", "net_main.c", "net_vcr.c", "pr_cmds.c", + "pr_edict.c", "pr_exec.c", "r_aclip.c", "r_alias.c", "r_bsp.c", "r_draw.c", + "r_edge.c", "r_efrag.c", "r_light.c", "r_main.c", "r_misc.c", "r_part.c", + "r_sky.c", "r_sprite.c", "r_surf.c", "sbar.c", "screen.c", "snd_dma.c", + "snd_mem.c", "snd_mix.c", "sv_main.c", "sv_move.c", "sv_phys.c", "sv_user.c", + "view.c", "wad.c", "world.c", "zone.c" +} +-- asm vs c +--[[compile_gcc{ + "d_vars.c", "r_vars.c", "nonintel.c" +}]] +compile_gcc{ + "d_draw.S", "d_draw16.S", "d_parta.S", "d_polysa.S", "d_scana.S", "d_spr8.S", + "d_varsa.S", "math.S", "r_aclipa.S", "r_aliasa.S", "r_drawa.S", "r_edgea.S", + "r_varsa.S", "snd_mixa.S", "surf8.S", "surf16.S", "sys_wina.S", "worlda.S" +} +-- select variants +compile_gcc{"sys_sdl.c"} -- SDL frontend +compile_gcc{"vid_sdl.c"} -- video and mouse from SDL +compile_gcc{"cd_null.c"} -- no CD audio +compile_gcc{"snd_sdl.c"} -- sound from SDL +compile_gcc{"net_none.c"} -- no network +link_gcc("sdlquake") diff --git a/contrib/other/sdlquake-1.0.9/WinQuake.dsp b/contrib/other/sdlquake-1.0.9/WinQuake.dsp new file mode 100644 index 000000000..4b0792ff1 --- /dev/null +++ b/contrib/other/sdlquake-1.0.9/WinQuake.dsp @@ -0,0 +1,2240 @@ +# Microsoft Developer Studio Project File - Name="winquake" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Application" 0x0101 + +CFG=winquake - Win32 Release +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "WinQuake.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "WinQuake.mak" CFG="winquake - Win32 Release" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "winquake - Win32 Release" (based on "Win32 (x86) Application") +!MESSAGE "winquake - Win32 Debug" (based on "Win32 (x86) Application") +!MESSAGE "winquake - Win32 GL Debug" (based on "Win32 (x86) Application") +!MESSAGE "winquake - Win32 GL Release" (based on "Win32 (x86) Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +MTL=midl.exe +RSC=rc.exe + +!IF "$(CFG)" == "winquake - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir ".\Release" +# PROP BASE Intermediate_Dir ".\Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir ".\Release" +# PROP Intermediate_Dir ".\Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /c +# ADD CPP /nologo /G5 /GX /Ox /Ot /Ow /I ".\scitech\include" /I ".\dxsdk\sdk\inc" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /FR /YX /FD /c +# SUBTRACT CPP /Oa /Og +# ADD BASE MTL /nologo /D "NDEBUG" /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386 +# ADD LINK32 .\dxsdk\sdk\lib\dxguid.lib .\scitech\lib\win32\vc\mgllt.lib winmm.lib wsock32.lib opengl32.lib glu32.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 /nologo /subsystem:windows /profile /machine:I386 +# SUBTRACT LINK32 /map /debug + +!ELSEIF "$(CFG)" == "winquake - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir ".\Debug" +# PROP BASE Intermediate_Dir ".\Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir ".\Debug" +# PROP Intermediate_Dir ".\Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /c +# ADD CPP /nologo /G5 /ML /GX /ZI /Od /I ".\scitech\include" /I ".\dxsdk\sdk\inc" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /FR /YX /FD /c +# ADD BASE MTL /nologo /D "_DEBUG" /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 +# ADD LINK32 .\dxsdk\sdk\lib\dxguid.lib .\scitech\lib\win32\vc\mgllt.lib winmm.lib wsock32.lib opengl32.lib glu32.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 /nologo /subsystem:windows /debug /machine:I386 +# SUBTRACT LINK32 /nodefaultlib + +!ELSEIF "$(CFG)" == "winquake - Win32 GL Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir ".\winquake" +# PROP BASE Intermediate_Dir ".\winquake" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir ".\debug_gl" +# PROP Intermediate_Dir ".\debug_gl" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /G5 /ML /GX /Zi /Od /I ".\scitech\include" /I ".\dxsdk\sdk\inc" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /c +# ADD CPP /nologo /G5 /ML /GX /ZI /Od /I ".\dxsdk\sdk\inc" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "GLQUAKE" /FR /YX /FD /c +# ADD BASE MTL /nologo /D "_DEBUG" /win32 +# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 winmm.lib wsock32.lib opengl32.lib glu32.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 .\scitech\lib\win32\vc\mgllt.lib /nologo /subsystem:windows /debug /machine:I386 +# SUBTRACT BASE LINK32 /nodefaultlib +# ADD LINK32 .\dxsdk\sdk\lib\dxguid.lib comctl32.lib winmm.lib wsock32.lib opengl32.lib glu32.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 /nologo /subsystem:windows /debug /machine:I386 /out:".\debug_gl\glquake.exe" +# SUBTRACT LINK32 /nodefaultlib + +!ELSEIF "$(CFG)" == "winquake - Win32 GL Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir ".\winquak0" +# PROP BASE Intermediate_Dir ".\winquak0" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir ".\release_gl" +# PROP Intermediate_Dir ".\release_gl" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /G5 /GX /Ox /Ot /Ow /I ".\scitech\include" /I ".\dxsdk\sdk\inc" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /c +# SUBTRACT BASE CPP /Oa /Og +# ADD CPP /nologo /G5 /GX /Ot /Ow /I ".\dxsdk\sdk\inc" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "GLQUAKE" /FR /YX /FD /c +# ADD BASE MTL /nologo /D "NDEBUG" /win32 +# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 winmm.lib wsock32.lib opengl32.lib glu32.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 .\scitech\lib\win32\vc\mgllt.lib /nologo /subsystem:windows /profile /machine:I386 +# SUBTRACT BASE LINK32 /map /debug +# ADD LINK32 .\dxsdk\sdk\lib\dxguid.lib comctl32.lib winmm.lib wsock32.lib opengl32.lib glu32.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 /nologo /subsystem:windows /profile /machine:I386 /out:".\release_gl\glquake.exe" +# SUBTRACT LINK32 /map /debug + +!ENDIF + +# Begin Target + +# Name "winquake - Win32 Release" +# Name "winquake - Win32 Debug" +# Name "winquake - Win32 GL Debug" +# Name "winquake - Win32 GL Release" +# Begin Group "Source Files" + +# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;hpj;bat;for;f90" +# Begin Source File + +SOURCE=.\cd_win.c +# End Source File +# Begin Source File + +SOURCE=.\chase.c +# End Source File +# Begin Source File + +SOURCE=.\cl_demo.c +# End Source File +# Begin Source File + +SOURCE=.\cl_input.c +# End Source File +# Begin Source File + +SOURCE=.\cl_main.c +# End Source File +# Begin Source File + +SOURCE=.\cl_parse.c +# End Source File +# Begin Source File + +SOURCE=.\cl_tent.c +# End Source File +# Begin Source File + +SOURCE=.\cmd.c +# End Source File +# Begin Source File + +SOURCE=.\common.c +# End Source File +# Begin Source File + +SOURCE=.\conproc.c +# End Source File +# Begin Source File + +SOURCE=.\console.c +# End Source File +# Begin Source File + +SOURCE=.\crc.c +# End Source File +# Begin Source File + +SOURCE=.\cvar.c +# End Source File +# Begin Source File + +SOURCE=.\d_draw.s + +!IF "$(CFG)" == "winquake - Win32 Release" + +# Begin Custom Build - mycoolbuild +OutDir=.\Release +InputPath=.\d_draw.s +InputName=d_draw + +"$(OUTDIR)\$(InputName).obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + cl /EP > $(OUTDIR)\$(InputName).spp $(InputPath) + gas2masm\debug\gas2masm < $(OUTDIR)\$(InputName).spp > $(OUTDIR)\$(InputName).asm + ml /c /Cp /coff /Fo$(OUTDIR)\$(InputName).obj /Zm /Zi $(OUTDIR)\$(InputName).asm + del $(OUTDIR)\$(InputName).spp + +# End Custom Build + +!ELSEIF "$(CFG)" == "winquake - Win32 Debug" + +# Begin Custom Build - mycoolbuild +OutDir=.\Debug +InputPath=.\d_draw.s +InputName=d_draw + +"$(OUTDIR)\$(InputName).obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + cl /EP > $(OUTDIR)\$(InputName).spp $(InputPath) + gas2masm\debug\gas2masm < $(OUTDIR)\$(InputName).spp > $(OUTDIR)\$(InputName).asm + ml /c /Cp /coff /Fo$(OUTDIR)\$(InputName).obj /Zm /Zi $(OUTDIR)\$(InputName).asm + del $(OUTDIR)\$(InputName).spp + +# End Custom Build + +!ELSEIF "$(CFG)" == "winquake - Win32 GL Debug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "winquake - Win32 GL Release" + +# PROP Exclude_From_Build 1 + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\d_draw16.s + +!IF "$(CFG)" == "winquake - Win32 Release" + +# Begin Custom Build - mycoolbuild +OutDir=.\Release +InputPath=.\d_draw16.s +InputName=d_draw16 + +"$(OUTDIR)\$(InputName).obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + cl /EP > $(OUTDIR)\$(InputName).spp $(InputPath) + gas2masm\debug\gas2masm < $(OUTDIR)\$(InputName).spp > $(OUTDIR)\$(InputName).asm + ml /c /Cp /coff /Fo$(OUTDIR)\$(InputName).obj /Zm /Zi $(OUTDIR)\$(InputName).asm + del $(OUTDIR)\$(InputName).spp + +# End Custom Build + +!ELSEIF "$(CFG)" == "winquake - Win32 Debug" + +# Begin Custom Build - mycoolbuild +OutDir=.\Debug +InputPath=.\d_draw16.s +InputName=d_draw16 + +"$(OUTDIR)\$(InputName).obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + cl /EP > $(OUTDIR)\$(InputName).spp $(InputPath) + gas2masm\debug\gas2masm < $(OUTDIR)\$(InputName).spp > $(OUTDIR)\$(InputName).asm + ml /c /Cp /coff /Fo$(OUTDIR)\$(InputName).obj /Zm /Zi $(OUTDIR)\$(InputName).asm + del $(OUTDIR)\$(InputName).spp + +# End Custom Build + +!ELSEIF "$(CFG)" == "winquake - Win32 GL Debug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "winquake - Win32 GL Release" + +# PROP Exclude_From_Build 1 + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\d_edge.c + +!IF "$(CFG)" == "winquake - Win32 Release" + +!ELSEIF "$(CFG)" == "winquake - Win32 Debug" + +!ELSEIF "$(CFG)" == "winquake - Win32 GL Debug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "winquake - Win32 GL Release" + +# PROP Exclude_From_Build 1 + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\d_fill.c + +!IF "$(CFG)" == "winquake - Win32 Release" + +!ELSEIF "$(CFG)" == "winquake - Win32 Debug" + +!ELSEIF "$(CFG)" == "winquake - Win32 GL Debug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "winquake - Win32 GL Release" + +# PROP Exclude_From_Build 1 + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\d_init.c + +!IF "$(CFG)" == "winquake - Win32 Release" + +!ELSEIF "$(CFG)" == "winquake - Win32 Debug" + +!ELSEIF "$(CFG)" == "winquake - Win32 GL Debug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "winquake - Win32 GL Release" + +# PROP Exclude_From_Build 1 + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\d_modech.c + +!IF "$(CFG)" == "winquake - Win32 Release" + +!ELSEIF "$(CFG)" == "winquake - Win32 Debug" + +!ELSEIF "$(CFG)" == "winquake - Win32 GL Debug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "winquake - Win32 GL Release" + +# PROP Exclude_From_Build 1 + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\d_part.c + +!IF "$(CFG)" == "winquake - Win32 Release" + +!ELSEIF "$(CFG)" == "winquake - Win32 Debug" + +!ELSEIF "$(CFG)" == "winquake - Win32 GL Debug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "winquake - Win32 GL Release" + +# PROP Exclude_From_Build 1 + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\d_parta.s + +!IF "$(CFG)" == "winquake - Win32 Release" + +# Begin Custom Build - mycoolbuild +OutDir=.\Release +InputPath=.\d_parta.s +InputName=d_parta + +"$(OUTDIR)\$(InputName).obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + cl /EP > $(OUTDIR)\$(InputName).spp $(InputPath) + gas2masm\debug\gas2masm < $(OUTDIR)\$(InputName).spp > $(OUTDIR)\$(InputName).asm + ml /c /Cp /coff /Fo$(OUTDIR)\$(InputName).obj /Zm /Zi $(OUTDIR)\$(InputName).asm + del $(OUTDIR)\$(InputName).spp + +# End Custom Build + +!ELSEIF "$(CFG)" == "winquake - Win32 Debug" + +# Begin Custom Build - mycoolbuild +OutDir=.\Debug +InputPath=.\d_parta.s +InputName=d_parta + +"$(OUTDIR)\$(InputName).obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + cl /EP > $(OUTDIR)\$(InputName).spp $(InputPath) + gas2masm\debug\gas2masm < $(OUTDIR)\$(InputName).spp > $(OUTDIR)\$(InputName).asm + ml /c /Cp /coff /Fo$(OUTDIR)\$(InputName).obj /Zm /Zi $(OUTDIR)\$(InputName).asm + del $(OUTDIR)\$(InputName).spp + +# End Custom Build + +!ELSEIF "$(CFG)" == "winquake - Win32 GL Debug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "winquake - Win32 GL Release" + +# PROP Exclude_From_Build 1 + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\d_polysa.s + +!IF "$(CFG)" == "winquake - Win32 Release" + +# Begin Custom Build - mycoolbuild +OutDir=.\Release +InputPath=.\d_polysa.s +InputName=d_polysa + +"$(OUTDIR)\$(InputName).obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + cl /EP > $(OUTDIR)\$(InputName).spp $(InputPath) + gas2masm\debug\gas2masm < $(OUTDIR)\$(InputName).spp > $(OUTDIR)\$(InputName).asm + ml /c /Cp /coff /Fo$(OUTDIR)\$(InputName).obj /Zm /Zi $(OUTDIR)\$(InputName).asm + del $(OUTDIR)\$(InputName).spp + +# End Custom Build + +!ELSEIF "$(CFG)" == "winquake - Win32 Debug" + +# Begin Custom Build - mycoolbuild +OutDir=.\Debug +InputPath=.\d_polysa.s +InputName=d_polysa + +"$(OUTDIR)\$(InputName).obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + cl /EP > $(OUTDIR)\$(InputName).spp $(InputPath) + gas2masm\debug\gas2masm < $(OUTDIR)\$(InputName).spp > $(OUTDIR)\$(InputName).asm + ml /c /Cp /coff /Fo$(OUTDIR)\$(InputName).obj /Zm /Zi $(OUTDIR)\$(InputName).asm + del $(OUTDIR)\$(InputName).spp + +# End Custom Build + +!ELSEIF "$(CFG)" == "winquake - Win32 GL Debug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "winquake - Win32 GL Release" + +# PROP Exclude_From_Build 1 + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\d_polyse.c + +!IF "$(CFG)" == "winquake - Win32 Release" + +!ELSEIF "$(CFG)" == "winquake - Win32 Debug" + +!ELSEIF "$(CFG)" == "winquake - Win32 GL Debug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "winquake - Win32 GL Release" + +# PROP Exclude_From_Build 1 + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\d_scan.c + +!IF "$(CFG)" == "winquake - Win32 Release" + +!ELSEIF "$(CFG)" == "winquake - Win32 Debug" + +!ELSEIF "$(CFG)" == "winquake - Win32 GL Debug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "winquake - Win32 GL Release" + +# PROP Exclude_From_Build 1 + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\d_scana.s + +!IF "$(CFG)" == "winquake - Win32 Release" + +# Begin Custom Build - mycoolbuild +OutDir=.\Release +InputPath=.\d_scana.s +InputName=d_scana + +"$(OUTDIR)\$(InputName).obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + cl /EP > $(OUTDIR)\$(InputName).spp $(InputPath) + gas2masm\debug\gas2masm < $(OUTDIR)\$(InputName).spp > $(OUTDIR)\$(InputName).asm + ml /c /Cp /coff /Fo$(OUTDIR)\$(InputName).obj /Zm /Zi $(OUTDIR)\$(InputName).asm + del $(OUTDIR)\$(InputName).spp + +# End Custom Build + +!ELSEIF "$(CFG)" == "winquake - Win32 Debug" + +# Begin Custom Build - mycoolbuild +OutDir=.\Debug +InputPath=.\d_scana.s +InputName=d_scana + +"$(OUTDIR)\$(InputName).obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + cl /EP > $(OUTDIR)\$(InputName).spp $(InputPath) + gas2masm\debug\gas2masm < $(OUTDIR)\$(InputName).spp > $(OUTDIR)\$(InputName).asm + ml /c /Cp /coff /Fo$(OUTDIR)\$(InputName).obj /Zm /Zi $(OUTDIR)\$(InputName).asm + del $(OUTDIR)\$(InputName).spp + +# End Custom Build + +!ELSEIF "$(CFG)" == "winquake - Win32 GL Debug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "winquake - Win32 GL Release" + +# PROP Exclude_From_Build 1 + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\d_sky.c + +!IF "$(CFG)" == "winquake - Win32 Release" + +!ELSEIF "$(CFG)" == "winquake - Win32 Debug" + +!ELSEIF "$(CFG)" == "winquake - Win32 GL Debug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "winquake - Win32 GL Release" + +# PROP Exclude_From_Build 1 + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\d_spr8.s + +!IF "$(CFG)" == "winquake - Win32 Release" + +# Begin Custom Build - mycoolbuild +OutDir=.\Release +InputPath=.\d_spr8.s +InputName=d_spr8 + +"$(OUTDIR)\$(InputName).obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + cl /EP > $(OUTDIR)\$(InputName).spp $(InputPath) + gas2masm\debug\gas2masm < $(OUTDIR)\$(InputName).spp > $(OUTDIR)\$(InputName).asm + ml /c /Cp /coff /Fo$(OUTDIR)\$(InputName).obj /Zm /Zi $(OUTDIR)\$(InputName).asm + del $(OUTDIR)\$(InputName).spp + +# End Custom Build + +!ELSEIF "$(CFG)" == "winquake - Win32 Debug" + +# Begin Custom Build - mycoolbuild +OutDir=.\Debug +InputPath=.\d_spr8.s +InputName=d_spr8 + +"$(OUTDIR)\$(InputName).obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + cl /EP > $(OUTDIR)\$(InputName).spp $(InputPath) + gas2masm\debug\gas2masm < $(OUTDIR)\$(InputName).spp > $(OUTDIR)\$(InputName).asm + ml /c /Cp /coff /Fo$(OUTDIR)\$(InputName).obj /Zm /Zi $(OUTDIR)\$(InputName).asm + del $(OUTDIR)\$(InputName).spp + +# End Custom Build + +!ELSEIF "$(CFG)" == "winquake - Win32 GL Debug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "winquake - Win32 GL Release" + +# PROP Exclude_From_Build 1 + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\d_sprite.c + +!IF "$(CFG)" == "winquake - Win32 Release" + +!ELSEIF "$(CFG)" == "winquake - Win32 Debug" + +!ELSEIF "$(CFG)" == "winquake - Win32 GL Debug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "winquake - Win32 GL Release" + +# PROP Exclude_From_Build 1 + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\d_surf.c + +!IF "$(CFG)" == "winquake - Win32 Release" + +!ELSEIF "$(CFG)" == "winquake - Win32 Debug" + +!ELSEIF "$(CFG)" == "winquake - Win32 GL Debug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "winquake - Win32 GL Release" + +# PROP Exclude_From_Build 1 + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\d_vars.c + +!IF "$(CFG)" == "winquake - Win32 Release" + +!ELSEIF "$(CFG)" == "winquake - Win32 Debug" + +!ELSEIF "$(CFG)" == "winquake - Win32 GL Debug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "winquake - Win32 GL Release" + +# PROP Exclude_From_Build 1 + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\d_varsa.s + +!IF "$(CFG)" == "winquake - Win32 Release" + +# Begin Custom Build - mycoolbuild +OutDir=.\Release +InputPath=.\d_varsa.s +InputName=d_varsa + +"$(OUTDIR)\$(InputName).obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + cl /EP > $(OUTDIR)\$(InputName).spp $(InputPath) + gas2masm\debug\gas2masm < $(OUTDIR)\$(InputName).spp > $(OUTDIR)\$(InputName).asm + ml /c /Cp /coff /Fo$(OUTDIR)\$(InputName).obj /Zm /Zi $(OUTDIR)\$(InputName).asm + del $(OUTDIR)\$(InputName).spp + +# End Custom Build + +!ELSEIF "$(CFG)" == "winquake - Win32 Debug" + +# Begin Custom Build - mycoolbuild +OutDir=.\Debug +InputPath=.\d_varsa.s +InputName=d_varsa + +"$(OUTDIR)\$(InputName).obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + cl /EP > $(OUTDIR)\$(InputName).spp $(InputPath) + gas2masm\debug\gas2masm < $(OUTDIR)\$(InputName).spp > $(OUTDIR)\$(InputName).asm + ml /c /Cp /coff /Fo$(OUTDIR)\$(InputName).obj /Zm /Zi $(OUTDIR)\$(InputName).asm + del $(OUTDIR)\$(InputName).spp + +# End Custom Build + +!ELSEIF "$(CFG)" == "winquake - Win32 GL Debug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "winquake - Win32 GL Release" + +# PROP Exclude_From_Build 1 + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\d_zpoint.c + +!IF "$(CFG)" == "winquake - Win32 Release" + +!ELSEIF "$(CFG)" == "winquake - Win32 Debug" + +!ELSEIF "$(CFG)" == "winquake - Win32 GL Debug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "winquake - Win32 GL Release" + +# PROP Exclude_From_Build 1 + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\draw.c + +!IF "$(CFG)" == "winquake - Win32 Release" + +!ELSEIF "$(CFG)" == "winquake - Win32 Debug" + +!ELSEIF "$(CFG)" == "winquake - Win32 GL Debug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "winquake - Win32 GL Release" + +# PROP Exclude_From_Build 1 + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\gl_draw.c + +!IF "$(CFG)" == "winquake - Win32 Release" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "winquake - Win32 Debug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "winquake - Win32 GL Debug" + +!ELSEIF "$(CFG)" == "winquake - Win32 GL Release" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\gl_mesh.c + +!IF "$(CFG)" == "winquake - Win32 Release" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "winquake - Win32 Debug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "winquake - Win32 GL Debug" + +!ELSEIF "$(CFG)" == "winquake - Win32 GL Release" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\gl_model.c + +!IF "$(CFG)" == "winquake - Win32 Release" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "winquake - Win32 Debug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "winquake - Win32 GL Debug" + +!ELSEIF "$(CFG)" == "winquake - Win32 GL Release" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\gl_refrag.c + +!IF "$(CFG)" == "winquake - Win32 Release" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "winquake - Win32 Debug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "winquake - Win32 GL Debug" + +!ELSEIF "$(CFG)" == "winquake - Win32 GL Release" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\gl_rlight.c + +!IF "$(CFG)" == "winquake - Win32 Release" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "winquake - Win32 Debug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "winquake - Win32 GL Debug" + +!ELSEIF "$(CFG)" == "winquake - Win32 GL Release" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\gl_rmain.c + +!IF "$(CFG)" == "winquake - Win32 Release" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "winquake - Win32 Debug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "winquake - Win32 GL Debug" + +!ELSEIF "$(CFG)" == "winquake - Win32 GL Release" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\gl_rmisc.c + +!IF "$(CFG)" == "winquake - Win32 Release" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "winquake - Win32 Debug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "winquake - Win32 GL Debug" + +!ELSEIF "$(CFG)" == "winquake - Win32 GL Release" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\gl_rsurf.c + +!IF "$(CFG)" == "winquake - Win32 Release" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "winquake - Win32 Debug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "winquake - Win32 GL Debug" + +!ELSEIF "$(CFG)" == "winquake - Win32 GL Release" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\gl_screen.c + +!IF "$(CFG)" == "winquake - Win32 Release" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "winquake - Win32 Debug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "winquake - Win32 GL Debug" + +!ELSEIF "$(CFG)" == "winquake - Win32 GL Release" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\gl_test.c + +!IF "$(CFG)" == "winquake - Win32 Release" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "winquake - Win32 Debug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "winquake - Win32 GL Debug" + +!ELSEIF "$(CFG)" == "winquake - Win32 GL Release" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\gl_vidnt.c + +!IF "$(CFG)" == "winquake - Win32 Release" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "winquake - Win32 Debug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "winquake - Win32 GL Debug" + +!ELSEIF "$(CFG)" == "winquake - Win32 GL Release" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\gl_warp.c + +!IF "$(CFG)" == "winquake - Win32 Release" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "winquake - Win32 Debug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "winquake - Win32 GL Debug" + +!ELSEIF "$(CFG)" == "winquake - Win32 GL Release" + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\host.c +# End Source File +# Begin Source File + +SOURCE=.\host_cmd.c +# End Source File +# Begin Source File + +SOURCE=.\in_win.c +# End Source File +# Begin Source File + +SOURCE=.\keys.c +# End Source File +# Begin Source File + +SOURCE=.\math.s + +!IF "$(CFG)" == "winquake - Win32 Release" + +# Begin Custom Build - mycoolbuild +OutDir=.\Release +InputPath=.\math.s +InputName=math + +"$(OUTDIR)\$(InputName).obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + cl /EP > $(OUTDIR)\$(InputName).spp $(InputPath) + gas2masm\debug\gas2masm < $(OUTDIR)\$(InputName).spp > $(OUTDIR)\$(InputName).asm + ml /c /Cp /coff /Fo$(OUTDIR)\$(InputName).obj /Zm /Zi $(OUTDIR)\$(InputName).asm + del $(OUTDIR)\$(InputName).spp + +# End Custom Build + +!ELSEIF "$(CFG)" == "winquake - Win32 Debug" + +# Begin Custom Build - mycoolbuild +OutDir=.\Debug +InputPath=.\math.s +InputName=math + +"$(OUTDIR)\$(InputName).obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + cl /EP > $(OUTDIR)\$(InputName).spp $(InputPath) + gas2masm\debug\gas2masm < $(OUTDIR)\$(InputName).spp > $(OUTDIR)\$(InputName).asm + ml /c /Cp /coff /Fo$(OUTDIR)\$(InputName).obj /Zm /Zi $(OUTDIR)\$(InputName).asm + del $(OUTDIR)\$(InputName).spp + +# End Custom Build + +!ELSEIF "$(CFG)" == "winquake - Win32 GL Debug" + +# Begin Custom Build - mycoolbuild +OutDir=.\debug_gl +InputPath=.\math.s +InputName=math + +"$(OUTDIR)\$(InputName).obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + cl /EP /DGLQUAKE > $(OUTDIR)\$(InputName).spp $(InputPath) + gas2masm\debug\gas2masm < $(OUTDIR)\$(InputName).spp > $(OUTDIR)\$(InputName).asm + ml /c /Cp /coff /Fo$(OUTDIR)\$(InputName).obj /Zm /Zi $(OUTDIR)\$(InputName).asm + del $(OUTDIR)\$(InputName).spp + +# End Custom Build + +!ELSEIF "$(CFG)" == "winquake - Win32 GL Release" + +# Begin Custom Build - mycoolbuild +OutDir=.\release_gl +InputPath=.\math.s +InputName=math + +"$(OUTDIR)\$(InputName).obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + cl /EP > $(OUTDIR)\$(InputName).spp $(InputPath) + gas2masm\debug\gas2masm < $(OUTDIR)\$(InputName).spp > $(OUTDIR)\$(InputName).asm + ml /c /Cp /coff /Fo$(OUTDIR)\$(InputName).obj /Zm /Zi $(OUTDIR)\$(InputName).asm + del $(OUTDIR)\$(InputName).spp + +# End Custom Build + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\mathlib.c +# End Source File +# Begin Source File + +SOURCE=.\menu.c +# End Source File +# Begin Source File + +SOURCE=.\model.c + +!IF "$(CFG)" == "winquake - Win32 Release" + +!ELSEIF "$(CFG)" == "winquake - Win32 Debug" + +!ELSEIF "$(CFG)" == "winquake - Win32 GL Debug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "winquake - Win32 GL Release" + +# PROP Exclude_From_Build 1 + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\net_dgrm.c +# End Source File +# Begin Source File + +SOURCE=.\net_loop.c +# End Source File +# Begin Source File + +SOURCE=.\net_main.c +# End Source File +# Begin Source File + +SOURCE=.\net_vcr.c +# End Source File +# Begin Source File + +SOURCE=.\net_win.c +# End Source File +# Begin Source File + +SOURCE=.\net_wins.c +# End Source File +# Begin Source File + +SOURCE=.\net_wipx.c +# End Source File +# Begin Source File + +SOURCE=.\pr_cmds.c +# End Source File +# Begin Source File + +SOURCE=.\pr_edict.c +# End Source File +# Begin Source File + +SOURCE=.\pr_exec.c +# End Source File +# Begin Source File + +SOURCE=.\r_aclip.c + +!IF "$(CFG)" == "winquake - Win32 Release" + +!ELSEIF "$(CFG)" == "winquake - Win32 Debug" + +!ELSEIF "$(CFG)" == "winquake - Win32 GL Debug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "winquake - Win32 GL Release" + +# PROP Exclude_From_Build 1 + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\r_aclipa.s + +!IF "$(CFG)" == "winquake - Win32 Release" + +# Begin Custom Build - mycoolbuild +OutDir=.\Release +InputPath=.\r_aclipa.s +InputName=r_aclipa + +"$(OUTDIR)\$(InputName).obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + cl /EP > $(OUTDIR)\$(InputName).spp $(InputPath) + gas2masm\debug\gas2masm < $(OUTDIR)\$(InputName).spp > $(OUTDIR)\$(InputName).asm + ml /c /Cp /coff /Fo$(OUTDIR)\$(InputName).obj /Zm /Zi $(OUTDIR)\$(InputName).asm + del $(OUTDIR)\$(InputName).spp + +# End Custom Build + +!ELSEIF "$(CFG)" == "winquake - Win32 Debug" + +# Begin Custom Build - mycoolbuild +OutDir=.\Debug +InputPath=.\r_aclipa.s +InputName=r_aclipa + +"$(OUTDIR)\$(InputName).obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + cl /EP > $(OUTDIR)\$(InputName).spp $(InputPath) + gas2masm\debug\gas2masm < $(OUTDIR)\$(InputName).spp > $(OUTDIR)\$(InputName).asm + ml /c /Cp /coff /Fo$(OUTDIR)\$(InputName).obj /Zm /Zi $(OUTDIR)\$(InputName).asm + del $(OUTDIR)\$(InputName).spp + +# End Custom Build + +!ELSEIF "$(CFG)" == "winquake - Win32 GL Debug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "winquake - Win32 GL Release" + +# PROP Exclude_From_Build 1 + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\r_alias.c + +!IF "$(CFG)" == "winquake - Win32 Release" + +!ELSEIF "$(CFG)" == "winquake - Win32 Debug" + +!ELSEIF "$(CFG)" == "winquake - Win32 GL Debug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "winquake - Win32 GL Release" + +# PROP Exclude_From_Build 1 + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\r_aliasa.s + +!IF "$(CFG)" == "winquake - Win32 Release" + +# Begin Custom Build - mycoolbuild +OutDir=.\Release +InputPath=.\r_aliasa.s +InputName=r_aliasa + +"$(OUTDIR)\$(InputName).obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + cl /EP > $(OUTDIR)\$(InputName).spp $(InputPath) + gas2masm\debug\gas2masm < $(OUTDIR)\$(InputName).spp > $(OUTDIR)\$(InputName).asm + ml /c /Cp /coff /Fo$(OUTDIR)\$(InputName).obj /Zm /Zi $(OUTDIR)\$(InputName).asm + del $(OUTDIR)\$(InputName).spp + +# End Custom Build + +!ELSEIF "$(CFG)" == "winquake - Win32 Debug" + +# Begin Custom Build - mycoolbuild +OutDir=.\Debug +InputPath=.\r_aliasa.s +InputName=r_aliasa + +"$(OUTDIR)\$(InputName).obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + cl /EP > $(OUTDIR)\$(InputName).spp $(InputPath) + gas2masm\debug\gas2masm < $(OUTDIR)\$(InputName).spp > $(OUTDIR)\$(InputName).asm + ml /c /Cp /coff /Fo$(OUTDIR)\$(InputName).obj /Zm /Zi $(OUTDIR)\$(InputName).asm + del $(OUTDIR)\$(InputName).spp + +# End Custom Build + +!ELSEIF "$(CFG)" == "winquake - Win32 GL Debug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "winquake - Win32 GL Release" + +# PROP Exclude_From_Build 1 + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\r_bsp.c + +!IF "$(CFG)" == "winquake - Win32 Release" + +!ELSEIF "$(CFG)" == "winquake - Win32 Debug" + +!ELSEIF "$(CFG)" == "winquake - Win32 GL Debug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "winquake - Win32 GL Release" + +# PROP Exclude_From_Build 1 + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\r_draw.c + +!IF "$(CFG)" == "winquake - Win32 Release" + +!ELSEIF "$(CFG)" == "winquake - Win32 Debug" + +!ELSEIF "$(CFG)" == "winquake - Win32 GL Debug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "winquake - Win32 GL Release" + +# PROP Exclude_From_Build 1 + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\r_drawa.s + +!IF "$(CFG)" == "winquake - Win32 Release" + +# Begin Custom Build - mycoolbuild +OutDir=.\Release +InputPath=.\r_drawa.s +InputName=r_drawa + +"$(OUTDIR)\$(InputName).obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + cl /EP > $(OUTDIR)\$(InputName).spp $(InputPath) + gas2masm\debug\gas2masm < $(OUTDIR)\$(InputName).spp > $(OUTDIR)\$(InputName).asm + ml /c /Cp /coff /Fo$(OUTDIR)\$(InputName).obj /Zm /Zi $(OUTDIR)\$(InputName).asm + del $(OUTDIR)\$(InputName).spp + +# End Custom Build + +!ELSEIF "$(CFG)" == "winquake - Win32 Debug" + +# Begin Custom Build - mycoolbuild +OutDir=.\Debug +InputPath=.\r_drawa.s +InputName=r_drawa + +"$(OUTDIR)\$(InputName).obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + cl /EP > $(OUTDIR)\$(InputName).spp $(InputPath) + gas2masm\debug\gas2masm < $(OUTDIR)\$(InputName).spp > $(OUTDIR)\$(InputName).asm + ml /c /Cp /coff /Fo$(OUTDIR)\$(InputName).obj /Zm /Zi $(OUTDIR)\$(InputName).asm + del $(OUTDIR)\$(InputName).spp + +# End Custom Build + +!ELSEIF "$(CFG)" == "winquake - Win32 GL Debug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "winquake - Win32 GL Release" + +# PROP Exclude_From_Build 1 + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\r_edge.c + +!IF "$(CFG)" == "winquake - Win32 Release" + +!ELSEIF "$(CFG)" == "winquake - Win32 Debug" + +!ELSEIF "$(CFG)" == "winquake - Win32 GL Debug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "winquake - Win32 GL Release" + +# PROP Exclude_From_Build 1 + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\r_edgea.s + +!IF "$(CFG)" == "winquake - Win32 Release" + +# Begin Custom Build - mycoolbuild +OutDir=.\Release +InputPath=.\r_edgea.s +InputName=r_edgea + +"$(OUTDIR)\$(InputName).obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + cl /EP > $(OUTDIR)\$(InputName).spp $(InputPath) + gas2masm\debug\gas2masm < $(OUTDIR)\$(InputName).spp > $(OUTDIR)\$(InputName).asm + ml /c /Cp /coff /Fo$(OUTDIR)\$(InputName).obj /Zm /Zi $(OUTDIR)\$(InputName).asm + del $(OUTDIR)\$(InputName).spp + +# End Custom Build + +!ELSEIF "$(CFG)" == "winquake - Win32 Debug" + +# Begin Custom Build - mycoolbuild +OutDir=.\Debug +InputPath=.\r_edgea.s +InputName=r_edgea + +"$(OUTDIR)\$(InputName).obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + cl /EP > $(OUTDIR)\$(InputName).spp $(InputPath) + gas2masm\debug\gas2masm < $(OUTDIR)\$(InputName).spp > $(OUTDIR)\$(InputName).asm + ml /c /Cp /coff /Fo$(OUTDIR)\$(InputName).obj /Zm /Zi $(OUTDIR)\$(InputName).asm + del $(OUTDIR)\$(InputName).spp + +# End Custom Build + +!ELSEIF "$(CFG)" == "winquake - Win32 GL Debug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "winquake - Win32 GL Release" + +# PROP Exclude_From_Build 1 + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\r_efrag.c + +!IF "$(CFG)" == "winquake - Win32 Release" + +!ELSEIF "$(CFG)" == "winquake - Win32 Debug" + +!ELSEIF "$(CFG)" == "winquake - Win32 GL Debug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "winquake - Win32 GL Release" + +# PROP Exclude_From_Build 1 + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\r_light.c + +!IF "$(CFG)" == "winquake - Win32 Release" + +!ELSEIF "$(CFG)" == "winquake - Win32 Debug" + +!ELSEIF "$(CFG)" == "winquake - Win32 GL Debug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "winquake - Win32 GL Release" + +# PROP Exclude_From_Build 1 + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\r_main.c + +!IF "$(CFG)" == "winquake - Win32 Release" + +!ELSEIF "$(CFG)" == "winquake - Win32 Debug" + +!ELSEIF "$(CFG)" == "winquake - Win32 GL Debug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "winquake - Win32 GL Release" + +# PROP Exclude_From_Build 1 + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\r_misc.c + +!IF "$(CFG)" == "winquake - Win32 Release" + +!ELSEIF "$(CFG)" == "winquake - Win32 Debug" + +!ELSEIF "$(CFG)" == "winquake - Win32 GL Debug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "winquake - Win32 GL Release" + +# PROP Exclude_From_Build 1 + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\r_part.c +# End Source File +# Begin Source File + +SOURCE=.\r_sky.c + +!IF "$(CFG)" == "winquake - Win32 Release" + +!ELSEIF "$(CFG)" == "winquake - Win32 Debug" + +!ELSEIF "$(CFG)" == "winquake - Win32 GL Debug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "winquake - Win32 GL Release" + +# PROP Exclude_From_Build 1 + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\r_sprite.c + +!IF "$(CFG)" == "winquake - Win32 Release" + +!ELSEIF "$(CFG)" == "winquake - Win32 Debug" + +!ELSEIF "$(CFG)" == "winquake - Win32 GL Debug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "winquake - Win32 GL Release" + +# PROP Exclude_From_Build 1 + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\r_surf.c + +!IF "$(CFG)" == "winquake - Win32 Release" + +!ELSEIF "$(CFG)" == "winquake - Win32 Debug" + +!ELSEIF "$(CFG)" == "winquake - Win32 GL Debug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "winquake - Win32 GL Release" + +# PROP Exclude_From_Build 1 + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\r_vars.c + +!IF "$(CFG)" == "winquake - Win32 Release" + +!ELSEIF "$(CFG)" == "winquake - Win32 Debug" + +!ELSEIF "$(CFG)" == "winquake - Win32 GL Debug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "winquake - Win32 GL Release" + +# PROP Exclude_From_Build 1 + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\r_varsa.s + +!IF "$(CFG)" == "winquake - Win32 Release" + +# Begin Custom Build - mycoolbuild +OutDir=.\Release +InputPath=.\r_varsa.s +InputName=r_varsa + +"$(OUTDIR)\$(InputName).obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + cl /EP > $(OUTDIR)\$(InputName).spp $(InputPath) + gas2masm\debug\gas2masm < $(OUTDIR)\$(InputName).spp > $(OUTDIR)\$(InputName).asm + ml /c /Cp /coff /Fo$(OUTDIR)\$(InputName).obj /Zm /Zi $(OUTDIR)\$(InputName).asm + del $(OUTDIR)\$(InputName).spp + +# End Custom Build + +!ELSEIF "$(CFG)" == "winquake - Win32 Debug" + +# Begin Custom Build - mycoolbuild +OutDir=.\Debug +InputPath=.\r_varsa.s +InputName=r_varsa + +"$(OUTDIR)\$(InputName).obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + cl /EP > $(OUTDIR)\$(InputName).spp $(InputPath) + gas2masm\debug\gas2masm < $(OUTDIR)\$(InputName).spp > $(OUTDIR)\$(InputName).asm + ml /c /Cp /coff /Fo$(OUTDIR)\$(InputName).obj /Zm /Zi $(OUTDIR)\$(InputName).asm + del $(OUTDIR)\$(InputName).spp + +# End Custom Build + +!ELSEIF "$(CFG)" == "winquake - Win32 GL Debug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "winquake - Win32 GL Release" + +# PROP Exclude_From_Build 1 + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\sbar.c +# End Source File +# Begin Source File + +SOURCE=.\screen.c + +!IF "$(CFG)" == "winquake - Win32 Release" + +!ELSEIF "$(CFG)" == "winquake - Win32 Debug" + +!ELSEIF "$(CFG)" == "winquake - Win32 GL Debug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "winquake - Win32 GL Release" + +# PROP Exclude_From_Build 1 + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\snd_dma.c +# End Source File +# Begin Source File + +SOURCE=.\snd_mem.c +# End Source File +# Begin Source File + +SOURCE=.\snd_mix.c +# End Source File +# Begin Source File + +SOURCE=.\snd_mixa.s + +!IF "$(CFG)" == "winquake - Win32 Release" + +# Begin Custom Build - mycoolbuild +OutDir=.\Release +InputPath=.\snd_mixa.s +InputName=snd_mixa + +"$(OUTDIR)\$(InputName).obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + cl /EP > $(OUTDIR)\$(InputName).spp $(InputPath) + gas2masm\debug\gas2masm < $(OUTDIR)\$(InputName).spp > $(OUTDIR)\$(InputName).asm + ml /c /Cp /coff /Fo$(OUTDIR)\$(InputName).obj /Zm /Zi $(OUTDIR)\$(InputName).asm + del $(OUTDIR)\$(InputName).spp + +# End Custom Build + +!ELSEIF "$(CFG)" == "winquake - Win32 Debug" + +# Begin Custom Build - mycoolbuild +OutDir=.\Debug +InputPath=.\snd_mixa.s +InputName=snd_mixa + +"$(OUTDIR)\$(InputName).obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + cl /EP > $(OUTDIR)\$(InputName).spp $(InputPath) + gas2masm\debug\gas2masm < $(OUTDIR)\$(InputName).spp > $(OUTDIR)\$(InputName).asm + ml /c /Cp /coff /Fo$(OUTDIR)\$(InputName).obj /Zm /Zi $(OUTDIR)\$(InputName).asm + del $(OUTDIR)\$(InputName).spp + +# End Custom Build + +!ELSEIF "$(CFG)" == "winquake - Win32 GL Debug" + +# Begin Custom Build - mycoolbuild +OutDir=.\debug_gl +InputPath=.\snd_mixa.s +InputName=snd_mixa + +"$(OUTDIR)\$(InputName).obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + cl /EP /DGLQUAKE > $(OUTDIR)\$(InputName).spp $(InputPath) + gas2masm\debug\gas2masm < $(OUTDIR)\$(InputName).spp > $(OUTDIR)\$(InputName).asm + ml /c /Cp /coff /Fo$(OUTDIR)\$(InputName).obj /Zm /Zi $(OUTDIR)\$(InputName).asm + del $(OUTDIR)\$(InputName).spp + +# End Custom Build + +!ELSEIF "$(CFG)" == "winquake - Win32 GL Release" + +# Begin Custom Build - mycoolbuild +OutDir=.\release_gl +InputPath=.\snd_mixa.s +InputName=snd_mixa + +"$(OUTDIR)\$(InputName).obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + cl /EP /DGLQUAKE > $(OUTDIR)\$(InputName).spp $(InputPath) + gas2masm\debug\gas2masm < $(OUTDIR)\$(InputName).spp > $(OUTDIR)\$(InputName).asm + ml /c /Cp /coff /Fo$(OUTDIR)\$(InputName).obj /Zm /Zi $(OUTDIR)\$(InputName).asm + del $(OUTDIR)\$(InputName).spp + +# End Custom Build + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\snd_win.c +# End Source File +# Begin Source File + +SOURCE=.\surf16.s + +!IF "$(CFG)" == "winquake - Win32 Release" + +# Begin Custom Build - mycoolbuild +OutDir=.\Release +InputPath=.\surf16.s +InputName=surf16 + +"$(OUTDIR)\$(InputName).obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + cl /EP > $(OUTDIR)\$(InputName).spp $(InputPath) + gas2masm\debug\gas2masm < $(OUTDIR)\$(InputName).spp > $(OUTDIR)\$(InputName).asm + ml /c /Cp /coff /Fo$(OUTDIR)\$(InputName).obj /Zm /Zi $(OUTDIR)\$(InputName).asm + del $(OUTDIR)\$(InputName).spp + +# End Custom Build + +!ELSEIF "$(CFG)" == "winquake - Win32 Debug" + +# Begin Custom Build - mycoolbuild +OutDir=.\Debug +InputPath=.\surf16.s +InputName=surf16 + +"$(OUTDIR)\$(InputName).obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + cl /EP > $(OUTDIR)\$(InputName).spp $(InputPath) + gas2masm\debug\gas2masm < $(OUTDIR)\$(InputName).spp > $(OUTDIR)\$(InputName).asm + ml /c /Cp /coff /Fo$(OUTDIR)\$(InputName).obj /Zm /Zi $(OUTDIR)\$(InputName).asm + del $(OUTDIR)\$(InputName).spp + +# End Custom Build + +!ELSEIF "$(CFG)" == "winquake - Win32 GL Debug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "winquake - Win32 GL Release" + +# PROP Exclude_From_Build 1 + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\surf8.s + +!IF "$(CFG)" == "winquake - Win32 Release" + +# Begin Custom Build - mycoolbuild +OutDir=.\Release +InputPath=.\surf8.s +InputName=surf8 + +"$(OUTDIR)\$(InputName).obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + cl /EP > $(OUTDIR)\$(InputName).spp $(InputPath) + gas2masm\debug\gas2masm < $(OUTDIR)\$(InputName).spp > $(OUTDIR)\$(InputName).asm + ml /c /Cp /coff /Fo$(OUTDIR)\$(InputName).obj /Zm /Zi $(OUTDIR)\$(InputName).asm + del $(OUTDIR)\$(InputName).spp + +# End Custom Build + +!ELSEIF "$(CFG)" == "winquake - Win32 Debug" + +# Begin Custom Build - mycoolbuild +OutDir=.\Debug +InputPath=.\surf8.s +InputName=surf8 + +"$(OUTDIR)\$(InputName).obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + cl /EP > $(OUTDIR)\$(InputName).spp $(InputPath) + gas2masm\debug\gas2masm < $(OUTDIR)\$(InputName).spp > $(OUTDIR)\$(InputName).asm + ml /c /Cp /coff /Fo$(OUTDIR)\$(InputName).obj /Zm /Zi $(OUTDIR)\$(InputName).asm + del $(OUTDIR)\$(InputName).spp + +# End Custom Build + +!ELSEIF "$(CFG)" == "winquake - Win32 GL Debug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "winquake - Win32 GL Release" + +# PROP Exclude_From_Build 1 + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\sv_main.c +# End Source File +# Begin Source File + +SOURCE=.\sv_move.c +# End Source File +# Begin Source File + +SOURCE=.\sv_phys.c +# End Source File +# Begin Source File + +SOURCE=.\sv_user.c +# End Source File +# Begin Source File + +SOURCE=.\sys_win.c +# End Source File +# Begin Source File + +SOURCE=.\sys_wina.s + +!IF "$(CFG)" == "winquake - Win32 Release" + +# Begin Custom Build - mycoolbuild +OutDir=.\Release +InputPath=.\sys_wina.s +InputName=sys_wina + +"$(OUTDIR)\$(InputName).obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + cl /EP > $(OUTDIR)\$(InputName).spp $(InputPath) + gas2masm\debug\gas2masm < $(OUTDIR)\$(InputName).spp > $(OUTDIR)\$(InputName).asm + ml /c /Cp /coff /Fo$(OUTDIR)\$(InputName).obj /Zm /Zi $(OUTDIR)\$(InputName).asm + del $(OUTDIR)\$(InputName).spp + +# End Custom Build + +!ELSEIF "$(CFG)" == "winquake - Win32 Debug" + +# Begin Custom Build - mycoolbuild +OutDir=.\Debug +InputPath=.\sys_wina.s +InputName=sys_wina + +"$(OUTDIR)\$(InputName).obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + cl /EP > $(OUTDIR)\$(InputName).spp $(InputPath) + gas2masm\debug\gas2masm < $(OUTDIR)\$(InputName).spp > $(OUTDIR)\$(InputName).asm + ml /c /Cp /coff /Fo$(OUTDIR)\$(InputName).obj /Zm /Zi $(OUTDIR)\$(InputName).asm + del $(OUTDIR)\$(InputName).spp + +# End Custom Build + +!ELSEIF "$(CFG)" == "winquake - Win32 GL Debug" + +# Begin Custom Build - mycoolbuild +OutDir=.\debug_gl +InputPath=.\sys_wina.s +InputName=sys_wina + +"$(OUTDIR)\$(InputName).obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + cl /EP /DGLQUAKE > $(OUTDIR)\$(InputName).spp $(InputPath) + gas2masm\debug\gas2masm < $(OUTDIR)\$(InputName).spp > $(OUTDIR)\$(InputName).asm + ml /c /Cp /coff /Fo$(OUTDIR)\$(InputName).obj /Zm /Zi $(OUTDIR)\$(InputName).asm + del $(OUTDIR)\$(InputName).spp + +# End Custom Build + +!ELSEIF "$(CFG)" == "winquake - Win32 GL Release" + +# Begin Custom Build - mycoolbuild +OutDir=.\release_gl +InputPath=.\sys_wina.s +InputName=sys_wina + +"$(OUTDIR)\$(InputName).obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + cl /EP /DGLQUAKE > $(OUTDIR)\$(InputName).spp $(InputPath) + gas2masm\debug\gas2masm < $(OUTDIR)\$(InputName).spp > $(OUTDIR)\$(InputName).asm + ml /c /Cp /coff /Fo$(OUTDIR)\$(InputName).obj /Zm /Zi $(OUTDIR)\$(InputName).asm + del $(OUTDIR)\$(InputName).spp + +# End Custom Build + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\vid_win.c + +!IF "$(CFG)" == "winquake - Win32 Release" + +!ELSEIF "$(CFG)" == "winquake - Win32 Debug" + +!ELSEIF "$(CFG)" == "winquake - Win32 GL Debug" + +# PROP Exclude_From_Build 1 + +!ELSEIF "$(CFG)" == "winquake - Win32 GL Release" + +# PROP Exclude_From_Build 1 + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\view.c +# End Source File +# Begin Source File + +SOURCE=.\wad.c +# End Source File +# Begin Source File + +SOURCE=.\winquake.rc +# End Source File +# Begin Source File + +SOURCE=.\world.c +# End Source File +# Begin Source File + +SOURCE=.\worlda.s + +!IF "$(CFG)" == "winquake - Win32 Release" + +# Begin Custom Build - mycoolbuild +OutDir=.\Release +InputPath=.\worlda.s +InputName=worlda + +"$(OUTDIR)\$(InputName).obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + cl /EP > $(OUTDIR)\$(InputName).spp $(InputPath) + gas2masm\debug\gas2masm < $(OUTDIR)\$(InputName).spp > $(OUTDIR)\$(InputName).asm + ml /c /Cp /coff /Fo$(OUTDIR)\$(InputName).obj /Zm /Zi $(OUTDIR)\$(InputName).asm + del $(OUTDIR)\$(InputName).spp + +# End Custom Build + +!ELSEIF "$(CFG)" == "winquake - Win32 Debug" + +# Begin Custom Build - mycoolbuild +OutDir=.\Debug +InputPath=.\worlda.s +InputName=worlda + +"$(OUTDIR)\$(InputName).obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + cl /EP > $(OUTDIR)\$(InputName).spp $(InputPath) + gas2masm\debug\gas2masm < $(OUTDIR)\$(InputName).spp > $(OUTDIR)\$(InputName).asm + ml /c /Cp /coff /Fo$(OUTDIR)\$(InputName).obj /Zm /Zi $(OUTDIR)\$(InputName).asm + del $(OUTDIR)\$(InputName).spp + +# End Custom Build + +!ELSEIF "$(CFG)" == "winquake - Win32 GL Debug" + +# Begin Custom Build - mycoolbuild +OutDir=.\debug_gl +InputPath=.\worlda.s +InputName=worlda + +"$(OUTDIR)\$(InputName).obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + cl /EP /DGLQUAKE > $(OUTDIR)\$(InputName).spp $(InputPath) + gas2masm\debug\gas2masm < $(OUTDIR)\$(InputName).spp > $(OUTDIR)\$(InputName).asm + ml /c /Cp /coff /Fo$(OUTDIR)\$(InputName).obj /Zm /Zi $(OUTDIR)\$(InputName).asm + del $(OUTDIR)\$(InputName).spp + +# End Custom Build + +!ELSEIF "$(CFG)" == "winquake - Win32 GL Release" + +# Begin Custom Build - mycoolbuild +OutDir=.\release_gl +InputPath=.\worlda.s +InputName=worlda + +"$(OUTDIR)\$(InputName).obj" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)" + cl /EP /DGLQUAKE > $(OUTDIR)\$(InputName).spp $(InputPath) + gas2masm\debug\gas2masm < $(OUTDIR)\$(InputName).spp > $(OUTDIR)\$(InputName).asm + ml /c /Cp /coff /Fo$(OUTDIR)\$(InputName).obj /Zm /Zi $(OUTDIR)\$(InputName).asm + del $(OUTDIR)\$(InputName).spp + +# End Custom Build + +!ENDIF + +# End Source File +# Begin Source File + +SOURCE=.\zone.c +# End Source File +# End Group +# Begin Group "Header Files" + +# PROP Default_Filter "h;hpp;hxx;hm;inl;fi;fd" +# Begin Source File + +SOURCE=.\anorm_dots.h +# End Source File +# Begin Source File + +SOURCE=.\anorms.h +# End Source File +# Begin Source File + +SOURCE=.\bspfile.h +# End Source File +# Begin Source File + +SOURCE=.\cdaudio.h +# End Source File +# Begin Source File + +SOURCE=.\client.h +# End Source File +# Begin Source File + +SOURCE=.\cmd.h +# End Source File +# Begin Source File + +SOURCE=.\common.h +# End Source File +# Begin Source File + +SOURCE=.\conproc.h +# End Source File +# Begin Source File + +SOURCE=.\console.h +# End Source File +# Begin Source File + +SOURCE=.\crc.h +# End Source File +# Begin Source File + +SOURCE=.\cvar.h +# End Source File +# Begin Source File + +SOURCE=.\d_iface.h +# End Source File +# Begin Source File + +SOURCE=.\dosisms.h +# End Source File +# Begin Source File + +SOURCE=.\draw.h +# End Source File +# Begin Source File + +SOURCE=.\gl_model.h +# End Source File +# Begin Source File + +SOURCE=.\gl_warp_sin.h +# End Source File +# Begin Source File + +SOURCE=.\glquake.h +# End Source File +# Begin Source File + +SOURCE=.\input.h +# End Source File +# Begin Source File + +SOURCE=.\keys.h +# End Source File +# Begin Source File + +SOURCE=.\mathlib.h +# End Source File +# Begin Source File + +SOURCE=.\menu.h +# End Source File +# Begin Source File + +SOURCE=.\model.h +# End Source File +# Begin Source File + +SOURCE=.\modelgen.h +# End Source File +# Begin Source File + +SOURCE=.\net.h +# End Source File +# Begin Source File + +SOURCE=.\net_dgrm.h +# End Source File +# Begin Source File + +SOURCE=.\net_loop.h +# End Source File +# Begin Source File + +SOURCE=.\net_ser.h +# End Source File +# Begin Source File + +SOURCE=.\net_vcr.h +# End Source File +# Begin Source File + +SOURCE=.\net_wins.h +# End Source File +# Begin Source File + +SOURCE=.\net_wipx.h +# End Source File +# Begin Source File + +SOURCE=.\pr_comp.h +# End Source File +# Begin Source File + +SOURCE=.\progdefs.h +# End Source File +# Begin Source File + +SOURCE=.\progs.h +# End Source File +# Begin Source File + +SOURCE=.\protocol.h +# End Source File +# Begin Source File + +SOURCE=.\quakedef.h +# End Source File +# Begin Source File + +SOURCE=.\r_local.h +# End Source File +# Begin Source File + +SOURCE=.\r_shared.h +# End Source File +# Begin Source File + +SOURCE=.\render.h +# End Source File +# Begin Source File + +SOURCE=.\sbar.h +# End Source File +# Begin Source File + +SOURCE=.\screen.h +# End Source File +# Begin Source File + +SOURCE=.\server.h +# End Source File +# Begin Source File + +SOURCE=.\sound.h +# End Source File +# Begin Source File + +SOURCE=.\spritegn.h +# End Source File +# Begin Source File + +SOURCE=.\sys.h +# End Source File +# Begin Source File + +SOURCE=.\vid.h +# End Source File +# Begin Source File + +SOURCE=.\view.h +# End Source File +# Begin Source File + +SOURCE=.\wad.h +# End Source File +# Begin Source File + +SOURCE=.\winquake.h +# End Source File +# Begin Source File + +SOURCE=.\world.h +# End Source File +# Begin Source File + +SOURCE=.\zone.h +# End Source File +# End Group +# Begin Group "Resource Files" + +# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;cnt;rtf;gif;jpg;jpeg;jpe" +# Begin Source File + +SOURCE=.\qe3.ico +# End Source File +# Begin Source File + +SOURCE=.\quake.ico +# End Source File +# End Group +# Begin Source File + +SOURCE=.\progdefs.q1 +# End Source File +# Begin Source File + +SOURCE=.\progdefs.q2 +# End Source File +# End Target +# End Project diff --git a/contrib/other/sdlquake-1.0.9/WinQuake.dsw b/contrib/other/sdlquake-1.0.9/WinQuake.dsw new file mode 100644 index 000000000..b95a3f3fe --- /dev/null +++ b/contrib/other/sdlquake-1.0.9/WinQuake.dsw @@ -0,0 +1,44 @@ +Microsoft Developer Studio Workspace File, Format Version 6.00 +# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! + +############################################################################### + +Project: "gas2masm"=.\gas2masm\gas2masm.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Project: "winquake"=.\WinQuake.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ + Begin Project Dependency + Project_Dep_Name gas2masm + End Project Dependency +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff --git a/contrib/other/sdlquake-1.0.9/acinclude.m4 b/contrib/other/sdlquake-1.0.9/acinclude.m4 new file mode 100644 index 000000000..26d01ce9b --- /dev/null +++ b/contrib/other/sdlquake-1.0.9/acinclude.m4 @@ -0,0 +1,165 @@ +# Configure paths for SDL +# Sam Lantinga 9/21/99 +# stolen from Manish Singh +# stolen back from Frank Belew +# stolen from Manish Singh +# Shamelessly stolen from Owen Taylor + +dnl AM_PATH_SDL([MINIMUM-VERSION, [ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND]]]) +dnl Test for SDL, and define SDL_CFLAGS and SDL_LIBS +dnl +AC_DEFUN(AM_PATH_SDL, +[dnl +dnl Get the cflags and libraries from the sdl-config script +dnl +AC_ARG_WITH(sdl-prefix,[ --with-sdl-prefix=PFX Prefix where SDL is installed (optional)], + sdl_prefix="$withval", sdl_prefix="") +AC_ARG_WITH(sdl-exec-prefix,[ --with-sdl-exec-prefix=PFX Exec prefix where SDL is installed (optional)], + sdl_exec_prefix="$withval", sdl_exec_prefix="") +AC_ARG_ENABLE(sdltest, [ --disable-sdltest Do not try to compile and run a test SDL program], + , enable_sdltest=yes) + + if test x$sdl_exec_prefix != x ; then + sdl_args="$sdl_args --exec-prefix=$sdl_exec_prefix" + if test x${SDL_CONFIG+set} != xset ; then + SDL_CONFIG=$sdl_exec_prefix/bin/sdl-config + fi + fi + if test x$sdl_prefix != x ; then + sdl_args="$sdl_args --prefix=$sdl_prefix" + if test x${SDL_CONFIG+set} != xset ; then + SDL_CONFIG=$sdl_prefix/bin/sdl-config + fi + fi + + AC_PATH_PROG(SDL_CONFIG, sdl-config, no) + min_sdl_version=ifelse([$1], ,0.11.0,$1) + AC_MSG_CHECKING(for SDL - version >= $min_sdl_version) + no_sdl="" + if test "$SDL_CONFIG" = "no" ; then + no_sdl=yes + else + SDL_CFLAGS=`$SDL_CONFIG $sdlconf_args --cflags` + SDL_LIBS=`$SDL_CONFIG $sdlconf_args --libs` + + sdl_major_version=`$SDL_CONFIG $sdl_args --version | \ + sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\1/'` + sdl_minor_version=`$SDL_CONFIG $sdl_args --version | \ + sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\2/'` + sdl_micro_version=`$SDL_CONFIG $sdl_config_args --version | \ + sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\3/'` + if test "x$enable_sdltest" = "xyes" ; then + ac_save_CFLAGS="$CFLAGS" + ac_save_LIBS="$LIBS" + CFLAGS="$CFLAGS $SDL_CFLAGS" + LIBS="$LIBS $SDL_LIBS" +dnl +dnl Now check if the installed SDL is sufficiently new. (Also sanity +dnl checks the results of sdl-config to some extent +dnl + rm -f conf.sdltest + AC_TRY_RUN([ +#include +#include +#include +#include "SDL.h" + +char* +my_strdup (char *str) +{ + char *new_str; + + if (str) + { + new_str = malloc ((strlen (str) + 1) * sizeof(char)); + strcpy (new_str, str); + } + else + new_str = NULL; + + return new_str; +} + +int main () +{ + int major, minor, micro; + char *tmp_version; + + system ("touch conf.sdltest"); + + /* HP/UX 9 (%@#!) writes to sscanf strings */ + tmp_version = my_strdup("$min_sdl_version"); + if (sscanf(tmp_version, "%d.%d.%d", &major, &minor, µ) != 3) { + printf("%s, bad version string\n", "$min_sdl_version"); + exit(1); + } + + if (($sdl_major_version > major) || + (($sdl_major_version == major) && ($sdl_minor_version > minor)) || + (($sdl_major_version == major) && ($sdl_minor_version == minor) && ($sdl_micro_version >= micro))) + { + return 0; + } + else + { + printf("\n*** 'sdl-config --version' returned %d.%d.%d, but the minimum version\n", $sdl_major_version, $sdl_minor_version, $sdl_micro_version); + printf("*** of SDL required is %d.%d.%d. If sdl-config is correct, then it is\n", major, minor, micro); + printf("*** best to upgrade to the required version.\n"); + printf("*** If sdl-config was wrong, set the environment variable SDL_CONFIG\n"); + printf("*** to point to the correct copy of sdl-config, and remove the file\n"); + printf("*** config.cache before re-running configure\n"); + return 1; + } +} + +],, no_sdl=yes,[echo $ac_n "cross compiling; assumed OK... $ac_c"]) + CFLAGS="$ac_save_CFLAGS" + LIBS="$ac_save_LIBS" + fi + fi + if test "x$no_sdl" = x ; then + AC_MSG_RESULT(yes) + ifelse([$2], , :, [$2]) + else + AC_MSG_RESULT(no) + if test "$SDL_CONFIG" = "no" ; then + echo "*** The sdl-config script installed by SDL could not be found" + echo "*** If SDL was installed in PREFIX, make sure PREFIX/bin is in" + echo "*** your path, or set the SDL_CONFIG environment variable to the" + echo "*** full path to sdl-config." + else + if test -f conf.sdltest ; then + : + else + echo "*** Could not run SDL test program, checking why..." + CFLAGS="$CFLAGS $SDL_CFLAGS" + LIBS="$LIBS $SDL_LIBS" + AC_TRY_LINK([ +#include +#include "SDL.h" +], [ return 0; ], + [ echo "*** The test program compiled, but did not run. This usually means" + echo "*** that the run-time linker is not finding SDL or finding the wrong" + echo "*** version of SDL. If it is not finding SDL, you'll need to set your" + echo "*** LD_LIBRARY_PATH environment variable, or edit /etc/ld.so.conf to point" + echo "*** to the installed location Also, make sure you have run ldconfig if that" + echo "*** is required on your system" + echo "***" + echo "*** If you have an old version installed, it is best to remove it, although" + echo "*** you may also be able to get things to work by modifying LD_LIBRARY_PATH"], + [ echo "*** The test program failed to compile or link. See the file config.log for the" + echo "*** exact error that occured. This usually means SDL was incorrectly installed" + echo "*** or that you have moved SDL since it was installed. In the latter case, you" + echo "*** may want to edit the sdl-config script: $SDL_CONFIG" ]) + CFLAGS="$ac_save_CFLAGS" + LIBS="$ac_save_LIBS" + fi + fi + SDL_CFLAGS="" + SDL_LIBS="" + ifelse([$3], , :, [$3]) + fi + AC_SUBST(SDL_CFLAGS) + AC_SUBST(SDL_LIBS) + rm -f conf.sdltest +]) diff --git a/contrib/other/sdlquake-1.0.9/aclocal.m4 b/contrib/other/sdlquake-1.0.9/aclocal.m4 new file mode 100644 index 000000000..41aebf0b2 --- /dev/null +++ b/contrib/other/sdlquake-1.0.9/aclocal.m4 @@ -0,0 +1,270 @@ +dnl aclocal.m4 generated automatically by aclocal 1.4 + +dnl Copyright (C) 1994, 1995-8, 1999 Free Software Foundation, Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. + +dnl This program is distributed in the hope that it will be useful, +dnl but WITHOUT ANY WARRANTY, to the extent permitted by law; without +dnl even the implied warranty of MERCHANTABILITY or FITNESS FOR A +dnl PARTICULAR PURPOSE. + +# Configure paths for SDL +# Sam Lantinga 9/21/99 +# stolen from Manish Singh +# stolen back from Frank Belew +# stolen from Manish Singh +# Shamelessly stolen from Owen Taylor + +dnl AM_PATH_SDL([MINIMUM-VERSION, [ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND]]]) +dnl Test for SDL, and define SDL_CFLAGS and SDL_LIBS +dnl +AC_DEFUN(AM_PATH_SDL, +[dnl +dnl Get the cflags and libraries from the sdl-config script +dnl +AC_ARG_WITH(sdl-prefix,[ --with-sdl-prefix=PFX Prefix where SDL is installed (optional)], + sdl_prefix="$withval", sdl_prefix="") +AC_ARG_WITH(sdl-exec-prefix,[ --with-sdl-exec-prefix=PFX Exec prefix where SDL is installed (optional)], + sdl_exec_prefix="$withval", sdl_exec_prefix="") +AC_ARG_ENABLE(sdltest, [ --disable-sdltest Do not try to compile and run a test SDL program], + , enable_sdltest=yes) + + if test x$sdl_exec_prefix != x ; then + sdl_args="$sdl_args --exec-prefix=$sdl_exec_prefix" + if test x${SDL_CONFIG+set} != xset ; then + SDL_CONFIG=$sdl_exec_prefix/bin/sdl-config + fi + fi + if test x$sdl_prefix != x ; then + sdl_args="$sdl_args --prefix=$sdl_prefix" + if test x${SDL_CONFIG+set} != xset ; then + SDL_CONFIG=$sdl_prefix/bin/sdl-config + fi + fi + + AC_PATH_PROG(SDL_CONFIG, sdl-config, no) + min_sdl_version=ifelse([$1], ,0.11.0,$1) + AC_MSG_CHECKING(for SDL - version >= $min_sdl_version) + no_sdl="" + if test "$SDL_CONFIG" = "no" ; then + no_sdl=yes + else + SDL_CFLAGS=`$SDL_CONFIG $sdlconf_args --cflags` + SDL_LIBS=`$SDL_CONFIG $sdlconf_args --libs` + + sdl_major_version=`$SDL_CONFIG $sdl_args --version | \ + sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\1/'` + sdl_minor_version=`$SDL_CONFIG $sdl_args --version | \ + sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\2/'` + sdl_micro_version=`$SDL_CONFIG $sdl_config_args --version | \ + sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\3/'` + if test "x$enable_sdltest" = "xyes" ; then + ac_save_CFLAGS="$CFLAGS" + ac_save_LIBS="$LIBS" + CFLAGS="$CFLAGS $SDL_CFLAGS" + LIBS="$LIBS $SDL_LIBS" +dnl +dnl Now check if the installed SDL is sufficiently new. (Also sanity +dnl checks the results of sdl-config to some extent +dnl + rm -f conf.sdltest + AC_TRY_RUN([ +#include +#include +#include +#include "SDL.h" + +char* +my_strdup (char *str) +{ + char *new_str; + + if (str) + { + new_str = malloc ((strlen (str) + 1) * sizeof(char)); + strcpy (new_str, str); + } + else + new_str = NULL; + + return new_str; +} + +int main () +{ + int major, minor, micro; + char *tmp_version; + + system ("touch conf.sdltest"); + + /* HP/UX 9 (%@#!) writes to sscanf strings */ + tmp_version = my_strdup("$min_sdl_version"); + if (sscanf(tmp_version, "%d.%d.%d", &major, &minor, µ) != 3) { + printf("%s, bad version string\n", "$min_sdl_version"); + exit(1); + } + + if (($sdl_major_version > major) || + (($sdl_major_version == major) && ($sdl_minor_version > minor)) || + (($sdl_major_version == major) && ($sdl_minor_version == minor) && ($sdl_micro_version >= micro))) + { + return 0; + } + else + { + printf("\n*** 'sdl-config --version' returned %d.%d.%d, but the minimum version\n", $sdl_major_version, $sdl_minor_version, $sdl_micro_version); + printf("*** of SDL required is %d.%d.%d. If sdl-config is correct, then it is\n", major, minor, micro); + printf("*** best to upgrade to the required version.\n"); + printf("*** If sdl-config was wrong, set the environment variable SDL_CONFIG\n"); + printf("*** to point to the correct copy of sdl-config, and remove the file\n"); + printf("*** config.cache before re-running configure\n"); + return 1; + } +} + +],, no_sdl=yes,[echo $ac_n "cross compiling; assumed OK... $ac_c"]) + CFLAGS="$ac_save_CFLAGS" + LIBS="$ac_save_LIBS" + fi + fi + if test "x$no_sdl" = x ; then + AC_MSG_RESULT(yes) + ifelse([$2], , :, [$2]) + else + AC_MSG_RESULT(no) + if test "$SDL_CONFIG" = "no" ; then + echo "*** The sdl-config script installed by SDL could not be found" + echo "*** If SDL was installed in PREFIX, make sure PREFIX/bin is in" + echo "*** your path, or set the SDL_CONFIG environment variable to the" + echo "*** full path to sdl-config." + else + if test -f conf.sdltest ; then + : + else + echo "*** Could not run SDL test program, checking why..." + CFLAGS="$CFLAGS $SDL_CFLAGS" + LIBS="$LIBS $SDL_LIBS" + AC_TRY_LINK([ +#include +#include "SDL.h" +], [ return 0; ], + [ echo "*** The test program compiled, but did not run. This usually means" + echo "*** that the run-time linker is not finding SDL or finding the wrong" + echo "*** version of SDL. If it is not finding SDL, you'll need to set your" + echo "*** LD_LIBRARY_PATH environment variable, or edit /etc/ld.so.conf to point" + echo "*** to the installed location Also, make sure you have run ldconfig if that" + echo "*** is required on your system" + echo "***" + echo "*** If you have an old version installed, it is best to remove it, although" + echo "*** you may also be able to get things to work by modifying LD_LIBRARY_PATH"], + [ echo "*** The test program failed to compile or link. See the file config.log for the" + echo "*** exact error that occured. This usually means SDL was incorrectly installed" + echo "*** or that you have moved SDL since it was installed. In the latter case, you" + echo "*** may want to edit the sdl-config script: $SDL_CONFIG" ]) + CFLAGS="$ac_save_CFLAGS" + LIBS="$ac_save_LIBS" + fi + fi + SDL_CFLAGS="" + SDL_LIBS="" + ifelse([$3], , :, [$3]) + fi + AC_SUBST(SDL_CFLAGS) + AC_SUBST(SDL_LIBS) + rm -f conf.sdltest +]) + +# Do all the work for Automake. This macro actually does too much -- +# some checks are only needed if your package does certain things. +# But this isn't really a big deal. + +# serial 1 + +dnl Usage: +dnl AM_INIT_AUTOMAKE(package,version, [no-define]) + +AC_DEFUN(AM_INIT_AUTOMAKE, +[AC_REQUIRE([AC_PROG_INSTALL]) +PACKAGE=[$1] +AC_SUBST(PACKAGE) +VERSION=[$2] +AC_SUBST(VERSION) +dnl test to see if srcdir already configured +if test "`cd $srcdir && pwd`" != "`pwd`" && test -f $srcdir/config.status; then + AC_MSG_ERROR([source directory already configured; run "make distclean" there first]) +fi +ifelse([$3],, +AC_DEFINE_UNQUOTED(PACKAGE, "$PACKAGE", [Name of package]) +AC_DEFINE_UNQUOTED(VERSION, "$VERSION", [Version number of package])) +AC_REQUIRE([AM_SANITY_CHECK]) +AC_REQUIRE([AC_ARG_PROGRAM]) +dnl FIXME This is truly gross. +missing_dir=`cd $ac_aux_dir && pwd` +AM_MISSING_PROG(ACLOCAL, aclocal, $missing_dir) +AM_MISSING_PROG(AUTOCONF, autoconf, $missing_dir) +AM_MISSING_PROG(AUTOMAKE, automake, $missing_dir) +AM_MISSING_PROG(AUTOHEADER, autoheader, $missing_dir) +AM_MISSING_PROG(MAKEINFO, makeinfo, $missing_dir) +AC_REQUIRE([AC_PROG_MAKE_SET])]) + +# +# Check to make sure that the build environment is sane. +# + +AC_DEFUN(AM_SANITY_CHECK, +[AC_MSG_CHECKING([whether build environment is sane]) +# Just in case +sleep 1 +echo timestamp > conftestfile +# Do `set' in a subshell so we don't clobber the current shell's +# arguments. Must try -L first in case configure is actually a +# symlink; some systems play weird games with the mod time of symlinks +# (eg FreeBSD returns the mod time of the symlink's containing +# directory). +if ( + set X `ls -Lt $srcdir/configure conftestfile 2> /dev/null` + if test "[$]*" = "X"; then + # -L didn't work. + set X `ls -t $srcdir/configure conftestfile` + fi + if test "[$]*" != "X $srcdir/configure conftestfile" \ + && test "[$]*" != "X conftestfile $srcdir/configure"; then + + # If neither matched, then we have a broken ls. This can happen + # if, for instance, CONFIG_SHELL is bash and it inherits a + # broken ls alias from the environment. This has actually + # happened. Such a system could not be considered "sane". + AC_MSG_ERROR([ls -t appears to fail. Make sure there is not a broken +alias in your environment]) + fi + + test "[$]2" = conftestfile + ) +then + # Ok. + : +else + AC_MSG_ERROR([newly created file is older than distributed files! +Check your system clock]) +fi +rm -f conftest* +AC_MSG_RESULT(yes)]) + +dnl AM_MISSING_PROG(NAME, PROGRAM, DIRECTORY) +dnl The program must properly implement --version. +AC_DEFUN(AM_MISSING_PROG, +[AC_MSG_CHECKING(for working $2) +# Run test in a subshell; some versions of sh will print an error if +# an executable is not found, even if stderr is redirected. +# Redirect stdin to placate older versions of autoconf. Sigh. +if ($2 --version) < /dev/null > /dev/null 2>&1; then + $1=$2 + AC_MSG_RESULT(found) +else + $1="$3/missing $2" + AC_MSG_RESULT(missing) +fi +AC_SUBST($1)]) + diff --git a/contrib/other/sdlquake-1.0.9/adivtab.h b/contrib/other/sdlquake-1.0.9/adivtab.h new file mode 100644 index 000000000..238df5c05 --- /dev/null +++ b/contrib/other/sdlquake-1.0.9/adivtab.h @@ -0,0 +1,1077 @@ +/* +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. + +*/ +// table of quotients and remainders for [-15...16] / [-15...16] + +// numerator = -15 +{1, 0}, +{1, -1}, +{1, -2}, +{1, -3}, +{1, -4}, +{1, -5}, +{1, -6}, +{1, -7}, +{2, -1}, +{2, -3}, +{3, 0}, +{3, -3}, +{5, 0}, +{7, -1}, +{15, 0}, +{0, 0}, +{-15, 0}, +{-8, 1}, +{-5, 0}, +{-4, 1}, +{-3, 0}, +{-3, 3}, +{-3, 6}, +{-2, 1}, +{-2, 3}, +{-2, 5}, +{-2, 7}, +{-2, 9}, +{-2, 11}, +{-2, 13}, +{-1, 0}, +{-1, 1}, +// numerator = -14 +{0, -14}, +{1, 0}, +{1, -1}, +{1, -2}, +{1, -3}, +{1, -4}, +{1, -5}, +{1, -6}, +{2, 0}, +{2, -2}, +{2, -4}, +{3, -2}, +{4, -2}, +{7, 0}, +{14, 0}, +{0, 0}, +{-14, 0}, +{-7, 0}, +{-5, 1}, +{-4, 2}, +{-3, 1}, +{-3, 4}, +{-2, 0}, +{-2, 2}, +{-2, 4}, +{-2, 6}, +{-2, 8}, +{-2, 10}, +{-2, 12}, +{-1, 0}, +{-1, 1}, +{-1, 2}, +// numerator = -13 +{0, -13}, +{0, -13}, +{1, 0}, +{1, -1}, +{1, -2}, +{1, -3}, +{1, -4}, +{1, -5}, +{1, -6}, +{2, -1}, +{2, -3}, +{3, -1}, +{4, -1}, +{6, -1}, +{13, 0}, +{0, 0}, +{-13, 0}, +{-7, 1}, +{-5, 2}, +{-4, 3}, +{-3, 2}, +{-3, 5}, +{-2, 1}, +{-2, 3}, +{-2, 5}, +{-2, 7}, +{-2, 9}, +{-2, 11}, +{-1, 0}, +{-1, 1}, +{-1, 2}, +{-1, 3}, +// numerator = -12 +{0, -12}, +{0, -12}, +{0, -12}, +{1, 0}, +{1, -1}, +{1, -2}, +{1, -3}, +{1, -4}, +{1, -5}, +{2, 0}, +{2, -2}, +{3, 0}, +{4, 0}, +{6, 0}, +{12, 0}, +{0, 0}, +{-12, 0}, +{-6, 0}, +{-4, 0}, +{-3, 0}, +{-3, 3}, +{-2, 0}, +{-2, 2}, +{-2, 4}, +{-2, 6}, +{-2, 8}, +{-2, 10}, +{-1, 0}, +{-1, 1}, +{-1, 2}, +{-1, 3}, +{-1, 4}, +// numerator = -11 +{0, -11}, +{0, -11}, +{0, -11}, +{0, -11}, +{1, 0}, +{1, -1}, +{1, -2}, +{1, -3}, +{1, -4}, +{1, -5}, +{2, -1}, +{2, -3}, +{3, -2}, +{5, -1}, +{11, 0}, +{0, 0}, +{-11, 0}, +{-6, 1}, +{-4, 1}, +{-3, 1}, +{-3, 4}, +{-2, 1}, +{-2, 3}, +{-2, 5}, +{-2, 7}, +{-2, 9}, +{-1, 0}, +{-1, 1}, +{-1, 2}, +{-1, 3}, +{-1, 4}, +{-1, 5}, +// numerator = -10 +{0, -10}, +{0, -10}, +{0, -10}, +{0, -10}, +{0, -10}, +{1, 0}, +{1, -1}, +{1, -2}, +{1, -3}, +{1, -4}, +{2, 0}, +{2, -2}, +{3, -1}, +{5, 0}, +{10, 0}, +{0, 0}, +{-10, 0}, +{-5, 0}, +{-4, 2}, +{-3, 2}, +{-2, 0}, +{-2, 2}, +{-2, 4}, +{-2, 6}, +{-2, 8}, +{-1, 0}, +{-1, 1}, +{-1, 2}, +{-1, 3}, +{-1, 4}, +{-1, 5}, +{-1, 6}, +// numerator = -9 +{0, -9}, +{0, -9}, +{0, -9}, +{0, -9}, +{0, -9}, +{0, -9}, +{1, 0}, +{1, -1}, +{1, -2}, +{1, -3}, +{1, -4}, +{2, -1}, +{3, 0}, +{4, -1}, +{9, 0}, +{0, 0}, +{-9, 0}, +{-5, 1}, +{-3, 0}, +{-3, 3}, +{-2, 1}, +{-2, 3}, +{-2, 5}, +{-2, 7}, +{-1, 0}, +{-1, 1}, +{-1, 2}, +{-1, 3}, +{-1, 4}, +{-1, 5}, +{-1, 6}, +{-1, 7}, +// numerator = -8 +{0, -8}, +{0, -8}, +{0, -8}, +{0, -8}, +{0, -8}, +{0, -8}, +{0, -8}, +{1, 0}, +{1, -1}, +{1, -2}, +{1, -3}, +{2, 0}, +{2, -2}, +{4, 0}, +{8, 0}, +{0, 0}, +{-8, 0}, +{-4, 0}, +{-3, 1}, +{-2, 0}, +{-2, 2}, +{-2, 4}, +{-2, 6}, +{-1, 0}, +{-1, 1}, +{-1, 2}, +{-1, 3}, +{-1, 4}, +{-1, 5}, +{-1, 6}, +{-1, 7}, +{-1, 8}, +// numerator = -7 +{0, -7}, +{0, -7}, +{0, -7}, +{0, -7}, +{0, -7}, +{0, -7}, +{0, -7}, +{0, -7}, +{1, 0}, +{1, -1}, +{1, -2}, +{1, -3}, +{2, -1}, +{3, -1}, +{7, 0}, +{0, 0}, +{-7, 0}, +{-4, 1}, +{-3, 2}, +{-2, 1}, +{-2, 3}, +{-2, 5}, +{-1, 0}, +{-1, 1}, +{-1, 2}, +{-1, 3}, +{-1, 4}, +{-1, 5}, +{-1, 6}, +{-1, 7}, +{-1, 8}, +{-1, 9}, +// numerator = -6 +{0, -6}, +{0, -6}, +{0, -6}, +{0, -6}, +{0, -6}, +{0, -6}, +{0, -6}, +{0, -6}, +{0, -6}, +{1, 0}, +{1, -1}, +{1, -2}, +{2, 0}, +{3, 0}, +{6, 0}, +{0, 0}, +{-6, 0}, +{-3, 0}, +{-2, 0}, +{-2, 2}, +{-2, 4}, +{-1, 0}, +{-1, 1}, +{-1, 2}, +{-1, 3}, +{-1, 4}, +{-1, 5}, +{-1, 6}, +{-1, 7}, +{-1, 8}, +{-1, 9}, +{-1, 10}, +// numerator = -5 +{0, -5}, +{0, -5}, +{0, -5}, +{0, -5}, +{0, -5}, +{0, -5}, +{0, -5}, +{0, -5}, +{0, -5}, +{0, -5}, +{1, 0}, +{1, -1}, +{1, -2}, +{2, -1}, +{5, 0}, +{0, 0}, +{-5, 0}, +{-3, 1}, +{-2, 1}, +{-2, 3}, +{-1, 0}, +{-1, 1}, +{-1, 2}, +{-1, 3}, +{-1, 4}, +{-1, 5}, +{-1, 6}, +{-1, 7}, +{-1, 8}, +{-1, 9}, +{-1, 10}, +{-1, 11}, +// numerator = -4 +{0, -4}, +{0, -4}, +{0, -4}, +{0, -4}, +{0, -4}, +{0, -4}, +{0, -4}, +{0, -4}, +{0, -4}, +{0, -4}, +{0, -4}, +{1, 0}, +{1, -1}, +{2, 0}, +{4, 0}, +{0, 0}, +{-4, 0}, +{-2, 0}, +{-2, 2}, +{-1, 0}, +{-1, 1}, +{-1, 2}, +{-1, 3}, +{-1, 4}, +{-1, 5}, +{-1, 6}, +{-1, 7}, +{-1, 8}, +{-1, 9}, +{-1, 10}, +{-1, 11}, +{-1, 12}, +// numerator = -3 +{0, -3}, +{0, -3}, +{0, -3}, +{0, -3}, +{0, -3}, +{0, -3}, +{0, -3}, +{0, -3}, +{0, -3}, +{0, -3}, +{0, -3}, +{0, -3}, +{1, 0}, +{1, -1}, +{3, 0}, +{0, 0}, +{-3, 0}, +{-2, 1}, +{-1, 0}, +{-1, 1}, +{-1, 2}, +{-1, 3}, +{-1, 4}, +{-1, 5}, +{-1, 6}, +{-1, 7}, +{-1, 8}, +{-1, 9}, +{-1, 10}, +{-1, 11}, +{-1, 12}, +{-1, 13}, +// numerator = -2 +{0, -2}, +{0, -2}, +{0, -2}, +{0, -2}, +{0, -2}, +{0, -2}, +{0, -2}, +{0, -2}, +{0, -2}, +{0, -2}, +{0, -2}, +{0, -2}, +{0, -2}, +{1, 0}, +{2, 0}, +{0, 0}, +{-2, 0}, +{-1, 0}, +{-1, 1}, +{-1, 2}, +{-1, 3}, +{-1, 4}, +{-1, 5}, +{-1, 6}, +{-1, 7}, +{-1, 8}, +{-1, 9}, +{-1, 10}, +{-1, 11}, +{-1, 12}, +{-1, 13}, +{-1, 14}, +// numerator = -1 +{0, -1}, +{0, -1}, +{0, -1}, +{0, -1}, +{0, -1}, +{0, -1}, +{0, -1}, +{0, -1}, +{0, -1}, +{0, -1}, +{0, -1}, +{0, -1}, +{0, -1}, +{0, -1}, +{1, 0}, +{0, 0}, +{-1, 0}, +{-1, 1}, +{-1, 2}, +{-1, 3}, +{-1, 4}, +{-1, 5}, +{-1, 6}, +{-1, 7}, +{-1, 8}, +{-1, 9}, +{-1, 10}, +{-1, 11}, +{-1, 12}, +{-1, 13}, +{-1, 14}, +{-1, 15}, +// numerator = 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}, +{0, 0}, +{0, 0}, +{0, 0}, +{0, 0}, +{0, 0}, +{0, 0}, +{0, 0}, +{0, 0}, +{0, 0}, +{0, 0}, +// numerator = 1 +{-1, -14}, +{-1, -13}, +{-1, -12}, +{-1, -11}, +{-1, -10}, +{-1, -9}, +{-1, -8}, +{-1, -7}, +{-1, -6}, +{-1, -5}, +{-1, -4}, +{-1, -3}, +{-1, -2}, +{-1, -1}, +{-1, 0}, +{0, 0}, +{1, 0}, +{0, 1}, +{0, 1}, +{0, 1}, +{0, 1}, +{0, 1}, +{0, 1}, +{0, 1}, +{0, 1}, +{0, 1}, +{0, 1}, +{0, 1}, +{0, 1}, +{0, 1}, +{0, 1}, +{0, 1}, +// numerator = 2 +{-1, -13}, +{-1, -12}, +{-1, -11}, +{-1, -10}, +{-1, -9}, +{-1, -8}, +{-1, -7}, +{-1, -6}, +{-1, -5}, +{-1, -4}, +{-1, -3}, +{-1, -2}, +{-1, -1}, +{-1, 0}, +{-2, 0}, +{0, 0}, +{2, 0}, +{1, 0}, +{0, 2}, +{0, 2}, +{0, 2}, +{0, 2}, +{0, 2}, +{0, 2}, +{0, 2}, +{0, 2}, +{0, 2}, +{0, 2}, +{0, 2}, +{0, 2}, +{0, 2}, +{0, 2}, +// numerator = 3 +{-1, -12}, +{-1, -11}, +{-1, -10}, +{-1, -9}, +{-1, -8}, +{-1, -7}, +{-1, -6}, +{-1, -5}, +{-1, -4}, +{-1, -3}, +{-1, -2}, +{-1, -1}, +{-1, 0}, +{-2, -1}, +{-3, 0}, +{0, 0}, +{3, 0}, +{1, 1}, +{1, 0}, +{0, 3}, +{0, 3}, +{0, 3}, +{0, 3}, +{0, 3}, +{0, 3}, +{0, 3}, +{0, 3}, +{0, 3}, +{0, 3}, +{0, 3}, +{0, 3}, +{0, 3}, +// numerator = 4 +{-1, -11}, +{-1, -10}, +{-1, -9}, +{-1, -8}, +{-1, -7}, +{-1, -6}, +{-1, -5}, +{-1, -4}, +{-1, -3}, +{-1, -2}, +{-1, -1}, +{-1, 0}, +{-2, -2}, +{-2, 0}, +{-4, 0}, +{0, 0}, +{4, 0}, +{2, 0}, +{1, 1}, +{1, 0}, +{0, 4}, +{0, 4}, +{0, 4}, +{0, 4}, +{0, 4}, +{0, 4}, +{0, 4}, +{0, 4}, +{0, 4}, +{0, 4}, +{0, 4}, +{0, 4}, +// numerator = 5 +{-1, -10}, +{-1, -9}, +{-1, -8}, +{-1, -7}, +{-1, -6}, +{-1, -5}, +{-1, -4}, +{-1, -3}, +{-1, -2}, +{-1, -1}, +{-1, 0}, +{-2, -3}, +{-2, -1}, +{-3, -1}, +{-5, 0}, +{0, 0}, +{5, 0}, +{2, 1}, +{1, 2}, +{1, 1}, +{1, 0}, +{0, 5}, +{0, 5}, +{0, 5}, +{0, 5}, +{0, 5}, +{0, 5}, +{0, 5}, +{0, 5}, +{0, 5}, +{0, 5}, +{0, 5}, +// numerator = 6 +{-1, -9}, +{-1, -8}, +{-1, -7}, +{-1, -6}, +{-1, -5}, +{-1, -4}, +{-1, -3}, +{-1, -2}, +{-1, -1}, +{-1, 0}, +{-2, -4}, +{-2, -2}, +{-2, 0}, +{-3, 0}, +{-6, 0}, +{0, 0}, +{6, 0}, +{3, 0}, +{2, 0}, +{1, 2}, +{1, 1}, +{1, 0}, +{0, 6}, +{0, 6}, +{0, 6}, +{0, 6}, +{0, 6}, +{0, 6}, +{0, 6}, +{0, 6}, +{0, 6}, +{0, 6}, +// numerator = 7 +{-1, -8}, +{-1, -7}, +{-1, -6}, +{-1, -5}, +{-1, -4}, +{-1, -3}, +{-1, -2}, +{-1, -1}, +{-1, 0}, +{-2, -5}, +{-2, -3}, +{-2, -1}, +{-3, -2}, +{-4, -1}, +{-7, 0}, +{0, 0}, +{7, 0}, +{3, 1}, +{2, 1}, +{1, 3}, +{1, 2}, +{1, 1}, +{1, 0}, +{0, 7}, +{0, 7}, +{0, 7}, +{0, 7}, +{0, 7}, +{0, 7}, +{0, 7}, +{0, 7}, +{0, 7}, +// numerator = 8 +{-1, -7}, +{-1, -6}, +{-1, -5}, +{-1, -4}, +{-1, -3}, +{-1, -2}, +{-1, -1}, +{-1, 0}, +{-2, -6}, +{-2, -4}, +{-2, -2}, +{-2, 0}, +{-3, -1}, +{-4, 0}, +{-8, 0}, +{0, 0}, +{8, 0}, +{4, 0}, +{2, 2}, +{2, 0}, +{1, 3}, +{1, 2}, +{1, 1}, +{1, 0}, +{0, 8}, +{0, 8}, +{0, 8}, +{0, 8}, +{0, 8}, +{0, 8}, +{0, 8}, +{0, 8}, +// numerator = 9 +{-1, -6}, +{-1, -5}, +{-1, -4}, +{-1, -3}, +{-1, -2}, +{-1, -1}, +{-1, 0}, +{-2, -7}, +{-2, -5}, +{-2, -3}, +{-2, -1}, +{-3, -3}, +{-3, 0}, +{-5, -1}, +{-9, 0}, +{0, 0}, +{9, 0}, +{4, 1}, +{3, 0}, +{2, 1}, +{1, 4}, +{1, 3}, +{1, 2}, +{1, 1}, +{1, 0}, +{0, 9}, +{0, 9}, +{0, 9}, +{0, 9}, +{0, 9}, +{0, 9}, +{0, 9}, +// numerator = 10 +{-1, -5}, +{-1, -4}, +{-1, -3}, +{-1, -2}, +{-1, -1}, +{-1, 0}, +{-2, -8}, +{-2, -6}, +{-2, -4}, +{-2, -2}, +{-2, 0}, +{-3, -2}, +{-4, -2}, +{-5, 0}, +{-10, 0}, +{0, 0}, +{10, 0}, +{5, 0}, +{3, 1}, +{2, 2}, +{2, 0}, +{1, 4}, +{1, 3}, +{1, 2}, +{1, 1}, +{1, 0}, +{0, 10}, +{0, 10}, +{0, 10}, +{0, 10}, +{0, 10}, +{0, 10}, +// numerator = 11 +{-1, -4}, +{-1, -3}, +{-1, -2}, +{-1, -1}, +{-1, 0}, +{-2, -9}, +{-2, -7}, +{-2, -5}, +{-2, -3}, +{-2, -1}, +{-3, -4}, +{-3, -1}, +{-4, -1}, +{-6, -1}, +{-11, 0}, +{0, 0}, +{11, 0}, +{5, 1}, +{3, 2}, +{2, 3}, +{2, 1}, +{1, 5}, +{1, 4}, +{1, 3}, +{1, 2}, +{1, 1}, +{1, 0}, +{0, 11}, +{0, 11}, +{0, 11}, +{0, 11}, +{0, 11}, +// numerator = 12 +{-1, -3}, +{-1, -2}, +{-1, -1}, +{-1, 0}, +{-2, -10}, +{-2, -8}, +{-2, -6}, +{-2, -4}, +{-2, -2}, +{-2, 0}, +{-3, -3}, +{-3, 0}, +{-4, 0}, +{-6, 0}, +{-12, 0}, +{0, 0}, +{12, 0}, +{6, 0}, +{4, 0}, +{3, 0}, +{2, 2}, +{2, 0}, +{1, 5}, +{1, 4}, +{1, 3}, +{1, 2}, +{1, 1}, +{1, 0}, +{0, 12}, +{0, 12}, +{0, 12}, +{0, 12}, +// numerator = 13 +{-1, -2}, +{-1, -1}, +{-1, 0}, +{-2, -11}, +{-2, -9}, +{-2, -7}, +{-2, -5}, +{-2, -3}, +{-2, -1}, +{-3, -5}, +{-3, -2}, +{-4, -3}, +{-5, -2}, +{-7, -1}, +{-13, 0}, +{0, 0}, +{13, 0}, +{6, 1}, +{4, 1}, +{3, 1}, +{2, 3}, +{2, 1}, +{1, 6}, +{1, 5}, +{1, 4}, +{1, 3}, +{1, 2}, +{1, 1}, +{1, 0}, +{0, 13}, +{0, 13}, +{0, 13}, +// numerator = 14 +{-1, -1}, +{-1, 0}, +{-2, -12}, +{-2, -10}, +{-2, -8}, +{-2, -6}, +{-2, -4}, +{-2, -2}, +{-2, 0}, +{-3, -4}, +{-3, -1}, +{-4, -2}, +{-5, -1}, +{-7, 0}, +{-14, 0}, +{0, 0}, +{14, 0}, +{7, 0}, +{4, 2}, +{3, 2}, +{2, 4}, +{2, 2}, +{2, 0}, +{1, 6}, +{1, 5}, +{1, 4}, +{1, 3}, +{1, 2}, +{1, 1}, +{1, 0}, +{0, 14}, +{0, 14}, +// numerator = 15 +{-1, 0}, +{-2, -13}, +{-2, -11}, +{-2, -9}, +{-2, -7}, +{-2, -5}, +{-2, -3}, +{-2, -1}, +{-3, -6}, +{-3, -3}, +{-3, 0}, +{-4, -1}, +{-5, 0}, +{-8, -1}, +{-15, 0}, +{0, 0}, +{15, 0}, +{7, 1}, +{5, 0}, +{3, 3}, +{3, 0}, +{2, 3}, +{2, 1}, +{1, 7}, +{1, 6}, +{1, 5}, +{1, 4}, +{1, 3}, +{1, 2}, +{1, 1}, +{1, 0}, +{0, 15}, +// numerator = 16 +{-2, -14}, +{-2, -12}, +{-2, -10}, +{-2, -8}, +{-2, -6}, +{-2, -4}, +{-2, -2}, +{-2, 0}, +{-3, -5}, +{-3, -2}, +{-4, -4}, +{-4, 0}, +{-6, -2}, +{-8, 0}, +{-16, 0}, +{0, 0}, +{16, 0}, +{8, 0}, +{5, 1}, +{4, 0}, +{3, 1}, +{2, 4}, +{2, 2}, +{2, 0}, +{1, 7}, +{1, 6}, +{1, 5}, +{1, 4}, +{1, 3}, +{1, 2}, +{1, 1}, +{1, 0}, diff --git a/contrib/other/sdlquake-1.0.9/anorm_dots.h b/contrib/other/sdlquake-1.0.9/anorm_dots.h new file mode 100644 index 000000000..2845fa20e --- /dev/null +++ b/contrib/other/sdlquake-1.0.9/anorm_dots.h @@ -0,0 +1,37 @@ +/* +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/contrib/other/sdlquake-1.0.9/anorms.h b/contrib/other/sdlquake-1.0.9/anorms.h new file mode 100644 index 000000000..11a9007e8 --- /dev/null +++ b/contrib/other/sdlquake-1.0.9/anorms.h @@ -0,0 +1,181 @@ +/* +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/contrib/other/sdlquake-1.0.9/asm_draw.h b/contrib/other/sdlquake-1.0.9/asm_draw.h new file mode 100644 index 000000000..5534ab63c --- /dev/null +++ b/contrib/other/sdlquake-1.0.9/asm_draw.h @@ -0,0 +1,151 @@ +/* +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. + +*/ +// +// asm_draw.h +// +// Include file for asm drawing routines. +// + +// +// !!! note that this file must match the corresponding C structures at all +// times !!! +// + +// !!! if this is changed, it must be changed in r_local.h too !!! +#define NEAR_CLIP 0.01 + +// !!! if this is changed, it must be changed in r_local.h too !!! +#define CYCLE 128 + +// espan_t structure +// !!! if this is changed, it must be changed in r_shared.h too !!! +#define espan_t_u 0 +#define espan_t_v 4 +#define espan_t_count 8 +#define espan_t_pnext 12 +#define espan_t_size 16 + +// sspan_t structure +// !!! if this is changed, it must be changed in d_local.h too !!! +#define sspan_t_u 0 +#define sspan_t_v 4 +#define sspan_t_count 8 +#define sspan_t_size 12 + +// spanpackage_t structure +// !!! if this is changed, it must be changed in d_polyset.c too !!! +#define spanpackage_t_pdest 0 +#define spanpackage_t_pz 4 +#define spanpackage_t_count 8 +#define spanpackage_t_ptex 12 +#define spanpackage_t_sfrac 16 +#define spanpackage_t_tfrac 20 +#define spanpackage_t_light 24 +#define spanpackage_t_zi 28 +#define spanpackage_t_size 32 + +// edge_t structure +// !!! if this is changed, it must be changed in r_shared.h too !!! +#define et_u 0 +#define et_u_step 4 +#define et_prev 8 +#define et_next 12 +#define et_surfs 16 +#define et_nextremove 20 +#define et_nearzi 24 +#define et_owner 28 +#define et_size 32 + +// surf_t structure +// !!! if this is changed, it must be changed in r_shared.h too !!! +#define SURF_T_SHIFT 6 +#define st_next 0 +#define st_prev 4 +#define st_spans 8 +#define st_key 12 +#define st_last_u 16 +#define st_spanstate 20 +#define st_flags 24 +#define st_data 28 +#define st_entity 32 +#define st_nearzi 36 +#define st_insubmodel 40 +#define st_d_ziorigin 44 +#define st_d_zistepu 48 +#define st_d_zistepv 52 +#define st_pad 56 +#define st_size 64 + +// clipplane_t structure +// !!! if this is changed, it must be changed in r_local.h too !!! +#define cp_normal 0 +#define cp_dist 12 +#define cp_next 16 +#define cp_leftedge 20 +#define cp_rightedge 21 +#define cp_reserved 22 +#define cp_size 24 + +// medge_t structure +// !!! if this is changed, it must be changed in model.h too !!! +#define me_v 0 +#define me_cachededgeoffset 4 +#define me_size 8 + +// mvertex_t structure +// !!! if this is changed, it must be changed in model.h too !!! +#define mv_position 0 +#define mv_size 12 + +// refdef_t structure +// !!! if this is changed, it must be changed in render.h too !!! +#define rd_vrect 0 +#define rd_aliasvrect 20 +#define rd_vrectright 40 +#define rd_vrectbottom 44 +#define rd_aliasvrectright 48 +#define rd_aliasvrectbottom 52 +#define rd_vrectrightedge 56 +#define rd_fvrectx 60 +#define rd_fvrecty 64 +#define rd_fvrectx_adj 68 +#define rd_fvrecty_adj 72 +#define rd_vrect_x_adj_shift20 76 +#define rd_vrectright_adj_shift20 80 +#define rd_fvrectright_adj 84 +#define rd_fvrectbottom_adj 88 +#define rd_fvrectright 92 +#define rd_fvrectbottom 96 +#define rd_horizontalFieldOfView 100 +#define rd_xOrigin 104 +#define rd_yOrigin 108 +#define rd_vieworg 112 +#define rd_viewangles 124 +#define rd_ambientlight 136 +#define rd_size 140 + +// mtriangle_t structure +// !!! if this is changed, it must be changed in model.h too !!! +#define mtri_facesfront 0 +#define mtri_vertindex 4 +#define mtri_size 16 // !!! if this changes, array indexing in !!! + // !!! d_polysa.s must be changed to match !!! +#define mtri_shift 4 + diff --git a/contrib/other/sdlquake-1.0.9/asm_i386.h b/contrib/other/sdlquake-1.0.9/asm_i386.h new file mode 100644 index 000000000..03dc2aae8 --- /dev/null +++ b/contrib/other/sdlquake-1.0.9/asm_i386.h @@ -0,0 +1,97 @@ +/* +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. + +*/ + +#ifndef __ASM_I386__ +#define __ASM_I386__ + +#ifdef ELF +#define C(label) label +#else +#define C(label) _##label +#endif + +// +// !!! note that this file must match the corresponding C structures at all +// times !!! +// + +// plane_t structure +// !!! if this is changed, it must be changed in model.h too !!! +// !!! if the size of this is changed, the array lookup in SV_HullPointContents +// must be changed too !!! +#define pl_normal 0 +#define pl_dist 12 +#define pl_type 16 +#define pl_signbits 17 +#define pl_pad 18 +#define pl_size 20 + +// hull_t structure +// !!! if this is changed, it must be changed in model.h too !!! +#define hu_clipnodes 0 +#define hu_planes 4 +#define hu_firstclipnode 8 +#define hu_lastclipnode 12 +#define hu_clip_mins 16 +#define hu_clip_maxs 28 +#define hu_size 40 + +// dnode_t structure +// !!! if this is changed, it must be changed in bspfile.h too !!! +#define nd_planenum 0 +#define nd_children 4 +#define nd_mins 8 +#define nd_maxs 20 +#define nd_firstface 32 +#define nd_numfaces 36 +#define nd_size 40 + +// sfxcache_t structure +// !!! if this is changed, it much be changed in sound.h too !!! +#define sfxc_length 0 +#define sfxc_loopstart 4 +#define sfxc_speed 8 +#define sfxc_width 12 +#define sfxc_stereo 16 +#define sfxc_data 20 + +// channel_t structure +// !!! if this is changed, it much be changed in sound.h too !!! +#define ch_sfx 0 +#define ch_leftvol 4 +#define ch_rightvol 8 +#define ch_end 12 +#define ch_pos 16 +#define ch_looping 20 +#define ch_entnum 24 +#define ch_entchannel 28 +#define ch_origin 32 +#define ch_dist_mult 44 +#define ch_master_vol 48 +#define ch_size 52 + +// portable_samplepair_t structure +// !!! if this is changed, it much be changed in sound.h too !!! +#define psp_left 0 +#define psp_right 4 +#define psp_size 8 + +#endif + diff --git a/contrib/other/sdlquake-1.0.9/block16.h b/contrib/other/sdlquake-1.0.9/block16.h new file mode 100644 index 000000000..96f222e18 --- /dev/null +++ b/contrib/other/sdlquake-1.0.9/block16.h @@ -0,0 +1,142 @@ +/* +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. + +*/ +LEnter16_16: + movb (%esi),%al + movb (%esi,%ebx,),%cl + movb %dh,%ah + addl %ebp,%edx + movb %dh,%ch + leal (%esi,%ebx,2),%esi + movw 0x12345678(,%eax,2),%ax +LBPatch0: + addl %ebp,%edx + movw %ax,(%edi) + movw 0x12345678(,%ecx,2),%cx +LBPatch1: + movw %cx,2(%edi) + addl $0x4,%edi + + movb (%esi),%al + movb (%esi,%ebx,),%cl + movb %dh,%ah + addl %ebp,%edx + movb %dh,%ch + leal (%esi,%ebx,2),%esi + movw 0x12345678(,%eax,2),%ax +LBPatch2: + addl %ebp,%edx + movw %ax,(%edi) + movw 0x12345678(,%ecx,2),%cx +LBPatch3: + movw %cx,2(%edi) + addl $0x4,%edi + + movb (%esi),%al + movb (%esi,%ebx,),%cl + movb %dh,%ah + addl %ebp,%edx + movb %dh,%ch + leal (%esi,%ebx,2),%esi + movw 0x12345678(,%eax,2),%ax +LBPatch4: + addl %ebp,%edx + movw %ax,(%edi) + movw 0x12345678(,%ecx,2),%cx +LBPatch5: + movw %cx,2(%edi) + addl $0x4,%edi + + movb (%esi),%al + movb (%esi,%ebx,),%cl + movb %dh,%ah + addl %ebp,%edx + movb %dh,%ch + leal (%esi,%ebx,2),%esi + movw 0x12345678(,%eax,2),%ax +LBPatch6: + addl %ebp,%edx + movw %ax,(%edi) + movw 0x12345678(,%ecx,2),%cx +LBPatch7: + movw %cx,2(%edi) + addl $0x4,%edi + +LEnter8_16: + movb (%esi),%al + movb (%esi,%ebx,),%cl + movb %dh,%ah + addl %ebp,%edx + movb %dh,%ch + leal (%esi,%ebx,2),%esi + movw 0x12345678(,%eax,2),%ax +LBPatch8: + addl %ebp,%edx + movw %ax,(%edi) + movw 0x12345678(,%ecx,2),%cx +LBPatch9: + movw %cx,2(%edi) + addl $0x4,%edi + + movb (%esi),%al + movb (%esi,%ebx,),%cl + movb %dh,%ah + addl %ebp,%edx + movb %dh,%ch + leal (%esi,%ebx,2),%esi + movw 0x12345678(,%eax,2),%ax +LBPatch10: + addl %ebp,%edx + movw %ax,(%edi) + movw 0x12345678(,%ecx,2),%cx +LBPatch11: + movw %cx,2(%edi) + addl $0x4,%edi + +LEnter4_16: + movb (%esi),%al + movb (%esi,%ebx,),%cl + movb %dh,%ah + addl %ebp,%edx + movb %dh,%ch + leal (%esi,%ebx,2),%esi + movw 0x12345678(,%eax,2),%ax +LBPatch12: + addl %ebp,%edx + movw %ax,(%edi) + movw 0x12345678(,%ecx,2),%cx +LBPatch13: + movw %cx,2(%edi) + addl $0x4,%edi + +LEnter2_16: + movb (%esi),%al + movb (%esi,%ebx,),%cl + movb %dh,%ah + addl %ebp,%edx + movb %dh,%ch + leal (%esi,%ebx,2),%esi + movw 0x12345678(,%eax,2),%ax +LBPatch14: + addl %ebp,%edx + movw %ax,(%edi) + movw 0x12345678(,%ecx,2),%cx +LBPatch15: + movw %cx,2(%edi) + addl $0x4,%edi diff --git a/contrib/other/sdlquake-1.0.9/block8.h b/contrib/other/sdlquake-1.0.9/block8.h new file mode 100644 index 000000000..eb9b03c3a --- /dev/null +++ b/contrib/other/sdlquake-1.0.9/block8.h @@ -0,0 +1,143 @@ +/* +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. + +*/ +LEnter16_8: + movb (%esi),%al + movb (%esi,%ebx,),%cl + movb %dh,%ah + addl %ebp,%edx + movb %dh,%ch + leal (%esi,%ebx,2),%esi + movb 0x12345678(%eax),%al +LBPatch0: + addl %ebp,%edx + movb %al,(%edi) + movb 0x12345678(%ecx),%cl +LBPatch1: + movb %cl,1(%edi) + addl $0x2,%edi + + movb (%esi),%al + movb (%esi,%ebx,),%cl + movb %dh,%ah + addl %ebp,%edx + movb %dh,%ch + leal (%esi,%ebx,2),%esi + movb 0x12345678(%eax),%al +LBPatch2: + addl %ebp,%edx + movb %al,(%edi) + movb 0x12345678(%ecx),%cl +LBPatch3: + movb %cl,1(%edi) + addl $0x2,%edi + + movb (%esi),%al + movb (%esi,%ebx,),%cl + movb %dh,%ah + addl %ebp,%edx + movb %dh,%ch + leal (%esi,%ebx,2),%esi + movb 0x12345678(%eax),%al +LBPatch4: + addl %ebp,%edx + movb %al,(%edi) + movb 0x12345678(%ecx),%cl +LBPatch5: + movb %cl,1(%edi) + addl $0x2,%edi + + movb (%esi),%al + movb (%esi,%ebx,),%cl + movb %dh,%ah + addl %ebp,%edx + movb %dh,%ch + leal (%esi,%ebx,2),%esi + movb 0x12345678(%eax),%al +LBPatch6: + addl %ebp,%edx + movb %al,(%edi) + movb 0x12345678(%ecx),%cl +LBPatch7: + movb %cl,1(%edi) + addl $0x2,%edi + +LEnter8_8: + movb (%esi),%al + movb (%esi,%ebx,),%cl + movb %dh,%ah + addl %ebp,%edx + movb %dh,%ch + leal (%esi,%ebx,2),%esi + movb 0x12345678(%eax),%al +LBPatch8: + addl %ebp,%edx + movb %al,(%edi) + movb 0x12345678(%ecx),%cl +LBPatch9: + movb %cl,1(%edi) + addl $0x2,%edi + + movb (%esi),%al + movb (%esi,%ebx,),%cl + movb %dh,%ah + addl %ebp,%edx + movb %dh,%ch + leal (%esi,%ebx,2),%esi + movb 0x12345678(%eax),%al +LBPatch10: + addl %ebp,%edx + movb %al,(%edi) + movb 0x12345678(%ecx),%cl +LBPatch11: + movb %cl,1(%edi) + addl $0x2,%edi + +LEnter4_8: + movb (%esi),%al + movb (%esi,%ebx,),%cl + movb %dh,%ah + addl %ebp,%edx + movb %dh,%ch + leal (%esi,%ebx,2),%esi + movb 0x12345678(%eax),%al +LBPatch12: + addl %ebp,%edx + movb %al,(%edi) + movb 0x12345678(%ecx),%cl +LBPatch13: + movb %cl,1(%edi) + addl $0x2,%edi + +LEnter2_8: + movb (%esi),%al + movb (%esi,%ebx,),%cl + movb %dh,%ah + addl %ebp,%edx + movb %dh,%ch + leal (%esi,%ebx,2),%esi + movb 0x12345678(%eax),%al +LBPatch14: + addl %ebp,%edx + movb %al,(%edi) + movb 0x12345678(%ecx),%cl +LBPatch15: + movb %cl,1(%edi) + addl $0x2,%edi + diff --git a/contrib/other/sdlquake-1.0.9/bspfile.h b/contrib/other/sdlquake-1.0.9/bspfile.h new file mode 100644 index 000000000..308902632 --- /dev/null +++ b/contrib/other/sdlquake-1.0.9/bspfile.h @@ -0,0 +1,324 @@ +/* +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. + +*/ + + +// upper design bounds + +#define MAX_MAP_HULLS 4 + +#define MAX_MAP_MODELS 256 +#define MAX_MAP_BRUSHES 4096 +#define MAX_MAP_ENTITIES 1024 +#define MAX_MAP_ENTSTRING 65536 + +#define MAX_MAP_PLANES 32767 +#define MAX_MAP_NODES 32767 // because negative shorts are contents +#define MAX_MAP_CLIPNODES 32767 // +#define MAX_MAP_LEAFS 8192 +#define MAX_MAP_VERTS 65535 +#define MAX_MAP_FACES 65535 +#define MAX_MAP_MARKSURFACES 65535 +#define MAX_MAP_TEXINFO 4096 +#define MAX_MAP_EDGES 256000 +#define MAX_MAP_SURFEDGES 512000 +#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 + +// key / value pair sizes + +#define MAX_KEY 32 +#define MAX_VALUE 1024 + +//============================================================================= + + +#define BSPVERSION 29 +#define TOOLVERSION 2 + +typedef struct +{ + int fileofs, filelen; +} lump_t; + +#define LUMP_ENTITIES 0 +#define LUMP_PLANES 1 +#define LUMP_TEXTURES 2 +#define LUMP_VERTEXES 3 +#define LUMP_VISIBILITY 4 +#define LUMP_NODES 5 +#define LUMP_TEXINFO 6 +#define LUMP_FACES 7 +#define LUMP_LIGHTING 8 +#define LUMP_CLIPNODES 9 +#define LUMP_LEAFS 10 +#define LUMP_MARKSURFACES 11 +#define LUMP_EDGES 12 +#define LUMP_SURFEDGES 13 +#define LUMP_MODELS 14 + +#define HEADER_LUMPS 15 + +typedef struct +{ + float mins[3], maxs[3]; + float origin[3]; + int headnode[MAX_MAP_HULLS]; + int visleafs; // not including the solid leaf 0 + int firstface, numfaces; +} dmodel_t; + +typedef struct +{ + int version; + lump_t lumps[HEADER_LUMPS]; +} dheader_t; + +typedef struct +{ + int nummiptex; + int dataofs[4]; // [nummiptex] +} dmiptexlump_t; + +#define MIPLEVELS 4 +typedef struct miptex_s +{ + char name[16]; + unsigned width, height; + unsigned offsets[MIPLEVELS]; // four mip maps stored +} miptex_t; + + +typedef struct +{ + float point[3]; +} dvertex_t; + + +// 0-2 are axial planes +#define PLANE_X 0 +#define PLANE_Y 1 +#define PLANE_Z 2 + +// 3-5 are non-axial planes snapped to the nearest +#define PLANE_ANYX 3 +#define PLANE_ANYY 4 +#define PLANE_ANYZ 5 + +typedef struct +{ + float normal[3]; + float dist; + int type; // PLANE_X - PLANE_ANYZ ?remove? trivial to regenerate +} dplane_t; + + + +#define CONTENTS_EMPTY -1 +#define CONTENTS_SOLID -2 +#define CONTENTS_WATER -3 +#define CONTENTS_SLIME -4 +#define CONTENTS_LAVA -5 +#define CONTENTS_SKY -6 +#define CONTENTS_ORIGIN -7 // removed at csg time +#define CONTENTS_CLIP -8 // changed to contents_solid + +#define CONTENTS_CURRENT_0 -9 +#define CONTENTS_CURRENT_90 -10 +#define CONTENTS_CURRENT_180 -11 +#define CONTENTS_CURRENT_270 -12 +#define CONTENTS_CURRENT_UP -13 +#define CONTENTS_CURRENT_DOWN -14 + + +// !!! if this is changed, it must be changed in asm_i386.h too !!! +typedef struct +{ + int planenum; + short children[2]; // negative numbers are -(leafs+1), not nodes + short mins[3]; // for sphere culling + short maxs[3]; + unsigned short firstface; + unsigned short numfaces; // counting both sides +} dnode_t; + +typedef struct +{ + int planenum; + short children[2]; // negative numbers are contents +} dclipnode_t; + + +typedef struct texinfo_s +{ + float vecs[2][4]; // [s/t][xyz offset] + int miptex; + int flags; +} texinfo_t; +#define TEX_SPECIAL 1 // sky or slime, no lightmap or 256 subdivision + +// 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; + +#define MAXLIGHTMAPS 4 +typedef struct +{ + short planenum; + short side; + + int firstedge; // we must support > 64k edges + short numedges; + short texinfo; + +// lighting info + byte styles[MAXLIGHTMAPS]; + int lightofs; // start of [numstyles*surfsize] samples +} dface_t; + + + +#define AMBIENT_WATER 0 +#define AMBIENT_SKY 1 +#define AMBIENT_SLIME 2 +#define AMBIENT_LAVA 3 + +#define NUM_AMBIENTS 4 // automatic ambient sounds + +// leaf 0 is the generic CONTENTS_SOLID leaf, used for all solid areas +// all other leafs need visibility info +typedef struct +{ + int contents; + int visofs; // -1 = no visibility info + + short mins[3]; // for frustum culling + short maxs[3]; + + unsigned short firstmarksurface; + unsigned short nummarksurfaces; + + byte ambient_level[NUM_AMBIENTS]; +} dleaf_t; + + +//============================================================================ + +#ifndef QUAKE_GAME + +#define ANGLE_UP -1 +#define ANGLE_DOWN -2 + + +// the utilities get to be lazy and just use large static arrays + +extern int nummodels; +extern dmodel_t dmodels[MAX_MAP_MODELS]; + +extern int visdatasize; +extern byte dvisdata[MAX_MAP_VISIBILITY]; + +extern int lightdatasize; +extern byte dlightdata[MAX_MAP_LIGHTING]; + +extern int texdatasize; +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 numplanes; +extern dplane_t dplanes[MAX_MAP_PLANES]; + +extern int numvertexes; +extern dvertex_t dvertexes[MAX_MAP_VERTS]; + +extern int numnodes; +extern dnode_t dnodes[MAX_MAP_NODES]; + +extern int numtexinfo; +extern texinfo_t texinfo[MAX_MAP_TEXINFO]; + +extern int numfaces; +extern dface_t dfaces[MAX_MAP_FACES]; + +extern int numclipnodes; +extern dclipnode_t dclipnodes[MAX_MAP_CLIPNODES]; + +extern int numedges; +extern dedge_t dedges[MAX_MAP_EDGES]; + +extern int nummarksurfaces; +extern unsigned short dmarksurfaces[MAX_MAP_MARKSURFACES]; + +extern int numsurfedges; +extern int dsurfedges[MAX_MAP_SURFEDGES]; + + +void DecompressVis (byte *in, byte *decompressed); +int CompressVis (byte *vis, byte *dest); + +void LoadBSPFile (char *filename); +void WriteBSPFile (char *filename); +void PrintBSPFileSizes (void); + +//=============== + + +typedef struct epair_s +{ + struct epair_s *next; + char *key; + char *value; +} epair_t; + +typedef struct +{ + vec3_t origin; + int firstbrush; + int numbrushes; + epair_t *epairs; +} entity_t; + +extern int num_entities; +extern entity_t entities[MAX_MAP_ENTITIES]; + +void ParseEntities (void); +void UnparseEntities (void); + +void SetKeyValue (entity_t *ent, char *key, char *value); +char *ValueForKey (entity_t *ent, char *key); +// will return "" if not present + +vec_t FloatForKey (entity_t *ent, char *key); +void GetVectorForKey (entity_t *ent, char *key, vec3_t vec); + +epair_t *ParseEpair (void); + +#endif diff --git a/contrib/other/sdlquake-1.0.9/cd_audio.c b/contrib/other/sdlquake-1.0.9/cd_audio.c new file mode 100644 index 000000000..03934220c --- /dev/null +++ b/contrib/other/sdlquake-1.0.9/cd_audio.c @@ -0,0 +1,886 @@ +/* +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. + +#include +#include "quakedef.h" +#include "dosisms.h" + +extern cvar_t bgmvolume; + +#define ADDRESS_MODE_HSG 0 +#define ADDRESS_MODE_RED_BOOK 1 + +#define STATUS_ERROR_BIT 0x8000 +#define STATUS_BUSY_BIT 0x0200 +#define STATUS_DONE_BIT 0x0100 +#define STATUS_ERROR_MASK 0x00ff + +#define ERROR_WRITE_PROTECT 0 +#define ERROR_UNKNOWN_UNIT 1 +#define ERROR_DRIVE_NOT_READY 2 +#define ERROR_UNKNOWN_COMMAND 3 +#define ERROR_CRC_ERROR 4 +#define ERROR_BAD_REQUEST_LEN 5 +#define ERROR_SEEK_ERROR 6 +#define ERROR_UNKNOWN_MEDIA 7 +#define ERROR_SECTOR_NOT_FOUND 8 +#define ERROR_OUT_OF_PAPER 9 +#define ERROR_WRITE_FAULT 10 +#define ERROR_READ_FAULT 11 +#define ERROR_GENERAL_FAILURE 12 +#define ERROR_RESERVED_13 13 +#define ERROR_RESERVED_14 14 +#define ERROR_BAD_DISK_CHANGE 15 + +#define COMMAND_READ 3 +#define COMMAND_WRITE 12 +#define COMMAND_PLAY_AUDIO 132 +#define COMMAND_STOP_AUDIO 133 +#define COMMAND_RESUME_AUDIO 136 + +#define READ_REQUEST_AUDIO_CHANNEL_INFO 4 +#define READ_REQUEST_DEVICE_STATUS 6 +#define READ_REQUEST_MEDIA_CHANGE 9 +#define READ_REQUEST_AUDIO_DISK_INFO 10 +#define READ_REQUEST_AUDIO_TRACK_INFO 11 +#define READ_REQUEST_AUDIO_STATUS 15 + +#define WRITE_REQUEST_EJECT 0 +#define WRITE_REQUEST_RESET 2 +#define WRITE_REQUEST_AUDIO_CHANNEL_INFO 3 + +#define STATUS_DOOR_OPEN 0x00000001 +#define STATUS_DOOR_UNLOCKED 0x00000002 +#define STATUS_RAW_SUPPORT 0x00000004 +#define STATUS_READ_WRITE 0x00000008 +#define STATUS_AUDIO_SUPPORT 0x00000010 +#define STATUS_INTERLEAVE_SUPPORT 0x00000020 +#define STATUS_BIT_6_RESERVED 0x00000040 +#define STATUS_PREFETCH_SUPPORT 0x00000080 +#define STATUS_AUDIO_MANIPLUATION_SUPPORT 0x00000100 +#define STATUS_RED_BOOK_ADDRESS_SUPPORT 0x00000200 + +#define MEDIA_NOT_CHANGED 1 +#define MEDIA_STATUS_UNKNOWN 0 +#define MEDIA_CHANGED -1 + +#define AUDIO_CONTROL_MASK 0xd0 +#define AUDIO_CONTROL_DATA_TRACK 0x40 +#define AUDIO_CONTROL_AUDIO_2_TRACK 0x00 +#define AUDIO_CONTROL_AUDIO_2P_TRACK 0x10 +#define AUDIO_CONTROL_AUDIO_4_TRACK 0x80 +#define AUDIO_CONTROL_AUDIO_4P_TRACK 0x90 + +#define AUDIO_STATUS_PAUSED 0x0001 + +#pragma pack(1) + +struct playAudioRequest +{ + char addressingMode; + int startLocation; + int sectors; +}; + +struct readRequest +{ + char mediaDescriptor; + short bufferOffset; + short bufferSegment; + short length; + short startSector; + int volumeID; +}; + +struct writeRequest +{ + char mediaDescriptor; + short bufferOffset; + short bufferSegment; + short length; + short startSector; + int volumeID; +}; + +struct cd_request +{ + char headerLength; + char unit; + char command; + short status; + char reserved[8]; + union + { + struct playAudioRequest playAudio; + struct readRequest read; + struct writeRequest write; + } x; +}; + + +struct audioChannelInfo_s +{ + char code; + char channel0input; + char channel0volume; + char channel1input; + char channel1volume; + char channel2input; + char channel2volume; + char channel3input; + char channel3volume; +}; + +struct deviceStatus_s +{ + char code; + int status; +}; + +struct mediaChange_s +{ + char code; + char status; +}; + +struct audioDiskInfo_s +{ + char code; + char lowTrack; + char highTrack; + int leadOutStart; +}; + +struct audioTrackInfo_s +{ + char code; + char track; + int start; + char control; +}; + +struct audioStatus_s +{ + char code; + short status; + int PRstartLocation; + int PRendLocation; +}; + +struct reset_s +{ + char code; +}; + +union readInfo_u +{ + struct audioChannelInfo_s audioChannelInfo; + struct deviceStatus_s deviceStatus; + struct mediaChange_s mediaChange; + struct audioDiskInfo_s audioDiskInfo; + struct audioTrackInfo_s audioTrackInfo; + struct audioStatus_s audioStatus; + struct reset_s reset; +}; + +#pragma pack() + +#define MAXIMUM_TRACKS 100 + +typedef struct +{ + int start; + int length; + qboolean isData; +} track_info; + +typedef struct +{ + qboolean valid; + int leadOutAddress; + track_info track[MAXIMUM_TRACKS]; + byte lowTrack; + byte highTrack; +} cd_info; + +static struct cd_request *cdRequest; +static union readInfo_u *readInfo; +static cd_info cd; + +static qboolean playing = false; +static qboolean wasPlaying = false; +static qboolean mediaCheck = false; +static qboolean initialized = false; +static qboolean enabled = true; +static qboolean playLooping = false; +static short cdRequestSegment; +static short cdRequestOffset; +static short readInfoSegment; +static short readInfoOffset; +static byte remap[256]; +static byte cdrom; +static byte playTrack; +static byte cdvolume; + + +static int RedBookToSector(int rb) +{ + byte minute; + byte second; + byte frame; + + minute = (rb >> 16) & 0xff; + second = (rb >> 8) & 0xff; + frame = rb & 0xff; + return minute * 60 * 75 + second * 75 + frame; +} + + +static void CDAudio_Reset(void) +{ + cdRequest->headerLength = 13; + cdRequest->unit = 0; + cdRequest->command = COMMAND_WRITE; + cdRequest->status = 0; + + cdRequest->x.write.mediaDescriptor = 0; + cdRequest->x.write.bufferOffset = readInfoOffset; + cdRequest->x.write.bufferSegment = readInfoSegment; + cdRequest->x.write.length = sizeof(struct reset_s); + cdRequest->x.write.startSector = 0; + cdRequest->x.write.volumeID = 0; + + readInfo->reset.code = WRITE_REQUEST_RESET; + + regs.x.ax = 0x1510; + regs.x.cx = cdrom; + regs.x.es = cdRequestSegment; + regs.x.bx = cdRequestOffset; + dos_int86 (0x2f); +} + + +static void CDAudio_Eject(void) +{ + cdRequest->headerLength = 13; + cdRequest->unit = 0; + cdRequest->command = COMMAND_WRITE; + cdRequest->status = 0; + + cdRequest->x.write.mediaDescriptor = 0; + cdRequest->x.write.bufferOffset = readInfoOffset; + cdRequest->x.write.bufferSegment = readInfoSegment; + cdRequest->x.write.length = sizeof(struct reset_s); + cdRequest->x.write.startSector = 0; + cdRequest->x.write.volumeID = 0; + + readInfo->reset.code = WRITE_REQUEST_EJECT; + + regs.x.ax = 0x1510; + regs.x.cx = cdrom; + regs.x.es = cdRequestSegment; + regs.x.bx = cdRequestOffset; + dos_int86 (0x2f); +} + + +static int CDAudio_GetAudioTrackInfo(byte track, int *start) +{ + byte control; + + cdRequest->headerLength = 13; + cdRequest->unit = 0; + cdRequest->command = COMMAND_READ; + cdRequest->status = 0; + + cdRequest->x.read.mediaDescriptor = 0; + cdRequest->x.read.bufferOffset = readInfoOffset; + cdRequest->x.read.bufferSegment = readInfoSegment; + cdRequest->x.read.length = sizeof(struct audioTrackInfo_s); + cdRequest->x.read.startSector = 0; + cdRequest->x.read.volumeID = 0; + + readInfo->audioTrackInfo.code = READ_REQUEST_AUDIO_TRACK_INFO; + readInfo->audioTrackInfo.track = track; + + regs.x.ax = 0x1510; + regs.x.cx = cdrom; + regs.x.es = cdRequestSegment; + regs.x.bx = cdRequestOffset; + dos_int86 (0x2f); + + if (cdRequest->status & STATUS_ERROR_BIT) + { + Con_DPrintf("CDAudio_GetAudioTrackInfo %04x\n", cdRequest->status & 0xffff); + return -1; + } + + *start = readInfo->audioTrackInfo.start; + control = readInfo->audioTrackInfo.control & AUDIO_CONTROL_MASK; + return (control & AUDIO_CONTROL_DATA_TRACK); +} + + +static int CDAudio_GetAudioDiskInfo(void) +{ + int n; + + cdRequest->headerLength = 13; + cdRequest->unit = 0; + cdRequest->command = COMMAND_READ; + cdRequest->status = 0; + + cdRequest->x.read.mediaDescriptor = 0; + cdRequest->x.read.bufferOffset = readInfoOffset; + cdRequest->x.read.bufferSegment = readInfoSegment; + cdRequest->x.read.length = sizeof(struct audioDiskInfo_s); + cdRequest->x.read.startSector = 0; + cdRequest->x.read.volumeID = 0; + + readInfo->audioDiskInfo.code = READ_REQUEST_AUDIO_DISK_INFO; + + regs.x.ax = 0x1510; + regs.x.cx = cdrom; + regs.x.es = cdRequestSegment; + regs.x.bx = cdRequestOffset; + dos_int86 (0x2f); + + if (cdRequest->status & STATUS_ERROR_BIT) + { + Con_DPrintf("CDAudio_GetAudioDiskInfo %04x\n", cdRequest->status & 0xffff); + return -1; + } + + cd.valid = true; + cd.lowTrack = readInfo->audioDiskInfo.lowTrack; + cd.highTrack = readInfo->audioDiskInfo.highTrack; + cd.leadOutAddress = readInfo->audioDiskInfo.leadOutStart; + + for (n = cd.lowTrack; n <= cd.highTrack; n++) + { + cd.track[n].isData = CDAudio_GetAudioTrackInfo (n, &cd.track[n].start); + if (n > cd.lowTrack) + { + cd.track[n-1].length = RedBookToSector(cd.track[n].start) - RedBookToSector(cd.track[n-1].start); + if (n == cd.highTrack) + cd.track[n].length = RedBookToSector(cd.leadOutAddress) - RedBookToSector(cd.track[n].start); + } + } + + return 0; +} + + +static int CDAudio_GetAudioStatus(void) +{ + cdRequest->headerLength = 13; + cdRequest->unit = 0; + cdRequest->command = COMMAND_READ; + cdRequest->status = 0; + + cdRequest->x.read.mediaDescriptor = 0; + cdRequest->x.read.bufferOffset = readInfoOffset; + cdRequest->x.read.bufferSegment = readInfoSegment; + cdRequest->x.read.length = sizeof(struct audioStatus_s); + cdRequest->x.read.startSector = 0; + cdRequest->x.read.volumeID = 0; + + readInfo->audioDiskInfo.code = READ_REQUEST_AUDIO_STATUS; + + regs.x.ax = 0x1510; + regs.x.cx = cdrom; + regs.x.es = cdRequestSegment; + regs.x.bx = cdRequestOffset; + dos_int86 (0x2f); + + if (cdRequest->status & STATUS_ERROR_BIT) + return -1; + return 0; +} + + +static int CDAudio_MediaChange(void) +{ + cdRequest->headerLength = 13; + cdRequest->unit = 0; + cdRequest->command = COMMAND_READ; + cdRequest->status = 0; + + cdRequest->x.read.mediaDescriptor = 0; + cdRequest->x.read.bufferOffset = readInfoOffset; + cdRequest->x.read.bufferSegment = readInfoSegment; + cdRequest->x.read.length = sizeof(struct mediaChange_s); + cdRequest->x.read.startSector = 0; + cdRequest->x.read.volumeID = 0; + + readInfo->mediaChange.code = READ_REQUEST_MEDIA_CHANGE; + + regs.x.ax = 0x1510; + regs.x.cx = cdrom; + regs.x.es = cdRequestSegment; + regs.x.bx = cdRequestOffset; + dos_int86 (0x2f); + + return readInfo->mediaChange.status; +} + + +// we set the volume to 0 first and then to the desired volume +// some cd-rom drivers seem to need it done this way +void CDAudio_SetVolume (byte volume) +{ + if (!initialized || !enabled) + return; + + cdRequest->headerLength = 13; + cdRequest->unit = 0; + cdRequest->command = COMMAND_WRITE; + cdRequest->status = 0; + + cdRequest->x.read.mediaDescriptor = 0; + cdRequest->x.read.bufferOffset = readInfoOffset; + cdRequest->x.read.bufferSegment = readInfoSegment; + cdRequest->x.read.length = sizeof(struct audioChannelInfo_s); + cdRequest->x.read.startSector = 0; + cdRequest->x.read.volumeID = 0; + + readInfo->audioChannelInfo.code = WRITE_REQUEST_AUDIO_CHANNEL_INFO; + readInfo->audioChannelInfo.channel0input = 0; + readInfo->audioChannelInfo.channel0volume = 0; + readInfo->audioChannelInfo.channel1input = 1; + readInfo->audioChannelInfo.channel1volume = 0; + readInfo->audioChannelInfo.channel2input = 2; + readInfo->audioChannelInfo.channel2volume = 0; + readInfo->audioChannelInfo.channel3input = 3; + readInfo->audioChannelInfo.channel3volume = 0; + + regs.x.ax = 0x1510; + regs.x.cx = cdrom; + regs.x.es = cdRequestSegment; + regs.x.bx = cdRequestOffset; + dos_int86 (0x2f); + + readInfo->audioChannelInfo.channel0volume = volume; + readInfo->audioChannelInfo.channel1volume = volume; + + regs.x.ax = 0x1510; + regs.x.cx = cdrom; + regs.x.es = cdRequestSegment; + regs.x.bx = cdRequestOffset; + dos_int86 (0x2f); + + cdvolume = volume; +} + + +void CDAudio_Play(byte track, qboolean looping) +{ + int volume; + + if (!initialized || !enabled) + return; + + if (!cd.valid) + return; + + track = remap[track]; + + if (playing) + { + if (playTrack == track) + return; + CDAudio_Stop(); + } + + playLooping = looping; + + if (track < cd.lowTrack || track > cd.highTrack) + { + Con_DPrintf("CDAudio_Play: Bad track number %u.\n", track); + return; + } + + playTrack = track; + + if (cd.track[track].isData) + { + Con_DPrintf("CDAudio_Play: Can not play data.\n"); + return; + } + + volume = (int)(bgmvolume.value * 255.0); + if (volume < 0) + { + Cvar_SetValue ("bgmvolume", 0.0); + volume = 0; + } + else if (volume > 255) + { + Cvar_SetValue ("bgmvolume", 1.0); + volume = 255; + } + CDAudio_SetVolume (volume); + + cdRequest->headerLength = 13; + cdRequest->unit = 0; + cdRequest->command = COMMAND_PLAY_AUDIO; + cdRequest->status = 0; + + cdRequest->x.playAudio.addressingMode = ADDRESS_MODE_RED_BOOK; + cdRequest->x.playAudio.startLocation = cd.track[track].start; + cdRequest->x.playAudio.sectors = cd.track[track].length; + + regs.x.ax = 0x1510; + regs.x.cx = cdrom; + regs.x.es = cdRequestSegment; + regs.x.bx = cdRequestOffset; + dos_int86 (0x2f); + + if (cdRequest->status & STATUS_ERROR_BIT) + { + Con_DPrintf("CDAudio_Play: track %u failed\n", track); + cd.valid = false; + playing = false; + return; + } + + playing = true; +} + + +void CDAudio_Stop(void) +{ + if (!initialized || !enabled) + return; + + cdRequest->headerLength = 13; + cdRequest->unit = 0; + cdRequest->command = COMMAND_STOP_AUDIO; + cdRequest->status = 0; + + regs.x.ax = 0x1510; + regs.x.cx = cdrom; + regs.x.es = cdRequestSegment; + regs.x.bx = cdRequestOffset; + dos_int86 (0x2f); + + wasPlaying = playing; + playing = false; +} + + +void CDAudio_Pause(void) +{ + CDAudio_Stop(); +} + + +void CDAudio_Resume(void) +{ + if (!initialized || !enabled) + return; + + if (!cd.valid) + return; + + if (!wasPlaying) + return; + + cdRequest->headerLength = 13; + cdRequest->unit = 0; + cdRequest->command = COMMAND_RESUME_AUDIO; + cdRequest->status = 0; + + regs.x.ax = 0x1510; + regs.x.cx = cdrom; + regs.x.es = cdRequestSegment; + regs.x.bx = cdRequestOffset; + dos_int86 (0x2f); + + 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 < 256; n++) + remap[n] = n; + CDAudio_Reset(); + CDAudio_GetAudioDiskInfo(); + return; + } + + if (Q_strcasecmp(command, "remap") == 0) + { + ret = Cmd_Argc() - 2; + if (ret <= 0) + { + for (n = 1; n < 256; 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 (!cd.valid) + { + Con_Printf("No CD in player.\n"); + return; + } + + if (Q_strcasecmp(command, "play") == 0) + { + CDAudio_Play(Q_atoi(Cmd_Argv (2)), false); + return; + } + + if (Q_strcasecmp(command, "loop") == 0) + { + CDAudio_Play(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(); + cd.valid = false; + return; + } + + if (Q_strcasecmp(command, "info") == 0) + { + Con_Printf("%u tracks\n", cd.highTrack - cd.lowTrack + 1); + for (n = cd.lowTrack; n <= cd.highTrack; n++) + { + ret = CDAudio_GetAudioTrackInfo (n, &startAddress); + Con_Printf("Track %2u: %s at %2u:%02u\n", n, ret ? "data " : "music", (startAddress >> 16) & 0xff, (startAddress >> 8) & 0xff); + } + if (playing) + Con_Printf("Currently %s track %u\n", playLooping ? "looping" : "playing", playTrack); + Con_Printf("Volume is %u\n", cdvolume); + CDAudio_MediaChange(); + Con_Printf("Status %04x\n", cdRequest->status & 0xffff); + return; + } +} + + +void CDAudio_Update(void) +{ + int ret; + int newVolume; + static double lastUpdate; + + if (!initialized || !enabled) + return; + + if ((realtime - lastUpdate) < 0.25) + return; + lastUpdate = realtime; + + if (mediaCheck) + { + static double lastCheck; + + if ((realtime - lastCheck) < 5.0) + return; + lastCheck = realtime; + + ret = CDAudio_MediaChange(); + if (ret == MEDIA_CHANGED) + { + Con_DPrintf("CDAudio: media changed\n"); + playing = false; + wasPlaying = false; + cd.valid = false; + CDAudio_GetAudioDiskInfo(); + return; + } + } + + newVolume = (int)(bgmvolume.value * 255.0); + if (newVolume != cdvolume) + { + if (newVolume < 0) + { + Cvar_SetValue ("bgmvolume", 0.0); + newVolume = 0; + } + else if (newVolume > 255) + { + Cvar_SetValue ("bgmvolume", 1.0); + newVolume = 255; + } + CDAudio_SetVolume (newVolume); + } + + if (playing) + { + CDAudio_GetAudioStatus(); + if ((cdRequest->status & STATUS_BUSY_BIT) == 0) + { + playing = false; + if (playLooping) + CDAudio_Play(playTrack, true); + } + } +} + + +int CDAudio_Init(void) +{ + char *memory; + int n; + + if (cls.state == ca_dedicated) + return -1; + + if (COM_CheckParm("-nocdaudio")) + return -1; + + if (COM_CheckParm("-cdmediacheck")) + mediaCheck = true; + + regs.x.ax = 0x1500; + regs.x.bx = 0; + dos_int86 (0x2f); + if (regs.x.bx == 0) + { + Con_NotifyBox ( + "MSCDEX not loaded, music is\n" + "disabled. Use \"-nocdaudio\" if you\n" + "wish to avoid this message in the\n" + "future. See README.TXT for help.\n" + ); + return -1; + } + if (regs.x.bx > 1) + Con_DPrintf("CDAudio_Init: First CD-ROM drive will be used\n"); + cdrom = regs.x.cx; + + regs.x.ax = 0x150c; + regs.x.bx = 0; + dos_int86 (0x2f); + if (regs.x.bx == 0) + { + Con_NotifyBox ( + "MSCDEX version 2.00 or later\n" + "required for music. See README.TXT\n" + "for help.\n" + ); + Con_DPrintf("CDAudio_Init: MSCDEX version 2.00 or later required.\n"); + return -1; + } + + memory = dos_getmemory(sizeof(struct cd_request +) + sizeof(union readInfo_u)); + if (memory == NULL) + { + Con_DPrintf("CDAudio_Init: Unable to allocate low memory.\n"); + return -1; + } + + cdRequest = (struct cd_request *)memory; + cdRequestSegment = ptr2real(cdRequest) >> 4; + cdRequestOffset = ptr2real(cdRequest) & 0xf; + + readInfo = (union readInfo_u *)(memory + sizeof(struct cd_request)); + readInfoSegment = ptr2real(readInfo) >> 4; + readInfoOffset = ptr2real(readInfo) & 0xf; + + for (n = 0; n < 256; n++) + remap[n] = n; + initialized = true; + + CDAudio_SetVolume (255); + if (CDAudio_GetAudioDiskInfo()) + { + Con_Printf("CDAudio_Init: No CD in player.\n"); + enabled = false; + } + + Cmd_AddCommand ("cd", CD_f); + + Con_Printf("CD Audio Initialized\n"); + + return 0; +} + + +void CDAudio_Shutdown(void) +{ + if (!initialized) + return; + CDAudio_Stop(); +} diff --git a/contrib/other/sdlquake-1.0.9/cd_linux.c b/contrib/other/sdlquake-1.0.9/cd_linux.c new file mode 100644 index 000000000..0e23d9603 --- /dev/null +++ b/contrib/other/sdlquake-1.0.9/cd_linux.c @@ -0,0 +1,416 @@ +/* +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. + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "quakedef.h" + +static qboolean cdValid = false; +static qboolean playing = false; +static qboolean wasPlaying = false; +static qboolean initialized = false; +static qboolean enabled = true; +static qboolean playLooping = false; +static float cdvolume; +static byte remap[100]; +static byte playTrack; +static byte maxTrack; + +static int cdfile = -1; +static char cd_dev[64] = "/dev/cdrom"; + +static void CDAudio_Eject(void) +{ + if (cdfile == -1 || !enabled) + return; // no cd init'd + + if ( ioctl(cdfile, CDROMEJECT) == -1 ) + Con_DPrintf("ioctl cdromeject failed\n"); +} + + +static void CDAudio_CloseDoor(void) +{ + if (cdfile == -1 || !enabled) + return; // no cd init'd + + if ( ioctl(cdfile, CDROMCLOSETRAY) == -1 ) + Con_DPrintf("ioctl cdromclosetray failed\n"); +} + +static int CDAudio_GetAudioDiskInfo(void) +{ + struct cdrom_tochdr tochdr; + + cdValid = false; + + if ( ioctl(cdfile, CDROMREADTOCHDR, &tochdr) == -1 ) + { + Con_DPrintf("ioctl cdromreadtochdr failed\n"); + return -1; + } + + if (tochdr.cdth_trk0 < 1) + { + Con_DPrintf("CDAudio: no music tracks\n"); + return -1; + } + + cdValid = true; + maxTrack = tochdr.cdth_trk1; + + return 0; +} + + +void CDAudio_Play(byte track, qboolean looping) +{ + struct cdrom_tocentry entry; + struct cdrom_ti ti; + + if (cdfile == -1 || !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 + entry.cdte_track = track; + entry.cdte_format = CDROM_MSF; + if ( ioctl(cdfile, CDROMREADTOCENTRY, &entry) == -1 ) + { + Con_DPrintf("ioctl cdromreadtocentry failed\n"); + return; + } + if (entry.cdte_ctrl == CDROM_DATA_TRACK) + { + Con_Printf("CDAudio: track %i is not audio\n", track); + return; + } + + if (playing) + { + if (playTrack == track) + return; + CDAudio_Stop(); + } + + ti.cdti_trk0 = track; + ti.cdti_trk1 = track; + ti.cdti_ind0 = 1; + ti.cdti_ind1 = 99; + + if ( ioctl(cdfile, CDROMPLAYTRKIND, &ti) == -1 ) + { + Con_DPrintf("ioctl cdromplaytrkind failed\n"); + return; + } + + if ( ioctl(cdfile, CDROMRESUME) == -1 ) + Con_DPrintf("ioctl cdromresume failed\n"); + + playLooping = looping; + playTrack = track; + playing = true; + + if (cdvolume == 0.0) + CDAudio_Pause (); +} + + +void CDAudio_Stop(void) +{ + if (cdfile == -1 || !enabled) + return; + + if (!playing) + return; + + if ( ioctl(cdfile, CDROMSTOP) == -1 ) + Con_DPrintf("ioctl cdromstop failed (%d)\n", errno); + + wasPlaying = false; + playing = false; +} + +void CDAudio_Pause(void) +{ + if (cdfile == -1 || !enabled) + return; + + if (!playing) + return; + + if ( ioctl(cdfile, CDROMPAUSE) == -1 ) + Con_DPrintf("ioctl cdrompause failed\n"); + + wasPlaying = playing; + playing = false; +} + + +void CDAudio_Resume(void) +{ + if (cdfile == -1 || !enabled) + return; + + if (!cdValid) + return; + + if (!wasPlaying) + return; + + if ( ioctl(cdfile, CDROMRESUME) == -1 ) + Con_DPrintf("ioctl cdromresume failed\n"); + playing = true; +} + +static void CD_f (void) +{ + char *command; + int ret; + int n; + + 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; + } +} + +void CDAudio_Update(void) +{ + struct cdrom_subchnl subchnl; + static time_t lastchk; + + if (!enabled) + return; + + if (bgmvolume.value != cdvolume) + { + if (cdvolume) + { + Cvar_SetValue ("bgmvolume", 0.0); + cdvolume = bgmvolume.value; + CDAudio_Pause (); + } + else + { + Cvar_SetValue ("bgmvolume", 1.0); + cdvolume = bgmvolume.value; + CDAudio_Resume (); + } + } + + if (playing && lastchk < time(NULL)) { + lastchk = time(NULL) + 2; //two seconds between chks + subchnl.cdsc_format = CDROM_MSF; + if (ioctl(cdfile, CDROMSUBCHNL, &subchnl) == -1 ) { + Con_DPrintf("ioctl cdromsubchnl failed\n"); + playing = false; + return; + } + if (subchnl.cdsc_audiostatus != CDROM_AUDIO_PLAY && + subchnl.cdsc_audiostatus != CDROM_AUDIO_PAUSED) { + playing = false; + if (playLooping) + CDAudio_Play(playTrack, true); + } + } +} + +int CDAudio_Init(void) +{ + int i; + + if (cls.state == ca_dedicated) + return -1; + + if (COM_CheckParm("-nocdaudio")) + return -1; + + if ((i = COM_CheckParm("-cddev")) != 0 && i < com_argc - 1) { + strncpy(cd_dev, com_argv[i + 1], sizeof(cd_dev)); + cd_dev[sizeof(cd_dev) - 1] = 0; + } + + if ((cdfile = open(cd_dev, O_RDONLY)) == -1) { + Con_Printf("CDAudio_Init: open of \"%s\" failed (%i)\n", cd_dev, errno); + cdfile = -1; + return -1; + } + + for (i = 0; i < 100; i++) + remap[i] = i; + initialized = true; + enabled = true; + + if (CDAudio_GetAudioDiskInfo()) + { + Con_Printf("CDAudio_Init: No CD in player.\n"); + cdValid = false; + } + + Cmd_AddCommand ("cd", CD_f); + + Con_Printf("CD Audio Initialized\n"); + + return 0; +} + + +void CDAudio_Shutdown(void) +{ + if (!initialized) + return; + CDAudio_Stop(); + close(cdfile); + cdfile = -1; +} diff --git a/contrib/other/sdlquake-1.0.9/cd_null.c b/contrib/other/sdlquake-1.0.9/cd_null.c new file mode 100644 index 000000000..d5eeec8ad --- /dev/null +++ b/contrib/other/sdlquake-1.0.9/cd_null.c @@ -0,0 +1,55 @@ +/* +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" + +void CDAudio_Play(byte track, qboolean looping) +{ +} + + +void CDAudio_Stop(void) +{ +} + + +void CDAudio_Pause(void) +{ +} + + +void CDAudio_Resume(void) +{ +} + + +void CDAudio_Update(void) +{ +} + + +int CDAudio_Init(void) +{ + return 0; +} + + +void CDAudio_Shutdown(void) +{ +} \ No newline at end of file diff --git a/contrib/other/sdlquake-1.0.9/cd_sdl.c b/contrib/other/sdlquake-1.0.9/cd_sdl.c new file mode 100644 index 000000000..46b2aa283 --- /dev/null +++ b/contrib/other/sdlquake-1.0.9/cd_sdl.c @@ -0,0 +1,223 @@ +/* + Some of this may not work. I'm not overly familiar with SDL, I just sort + of podged this together from the SDL headers, and the other cd-rom code. + + Mark Baker +*/ + +#include + +#include "quakedef.h" + +static qboolean cdValid = false; +static qboolean initialized = false; +static qboolean enabled = true; +static qboolean playLooping = false; +static SDL_CD *cd_id; +static float cdvolume = 1.0; + +static void CD_f(); + +static void CDAudio_Eject() +{ + if(!cd_id || !enabled) return; + + if(SDL_CDEject(cd_id)) + Con_DPrintf("Unable to eject CD-ROM tray.\n"); +} + +void CDAudio_Play(byte track, qboolean looping) +{ + CDstatus cd_stat; + if(!cd_id || !enabled) return; + + if(!cdValid) + { + if(!CD_INDRIVE(cd_stat=SDL_CDStatus(cd_id)) ||(!cd_id->numtracks)) return; + cdValid = true; + } + + if((track < 1) || (track >= cd_id->numtracks)) + { + Con_DPrintf("CDAudio: Bad track number: %d\n",track); + return; + } + track--; /* Convert track from person to SDL value */ + if(cd_stat == CD_PLAYING) + { + if(cd_id->cur_track == track) return; + CDAudio_Stop(); + } + + if(SDL_CDPlay(cd_id,cd_id->track[track].offset, + cd_id->track[track].length)) + { + Con_DPrintf("CDAudio_Play: Unable to play track: %d\n",track+1); + return; + } + playLooping = looping; +} + + +void CDAudio_Stop() +{ + int cdstate; + if(!cd_id || !enabled) return; + cdstate = SDL_CDStatus(cd_id); + if((cdstate != CD_PLAYING) && (cdstate != CD_PAUSED)) return; + + if(SDL_CDStop(cd_id)) + Con_DPrintf("CDAudio_Stop: Failed to stop track.\n"); +} + +void CDAudio_Pause() +{ + if(!cd_id || !enabled) return; + if(SDL_CDStatus(cd_id) != CD_PLAYING) return; + + if(SDL_CDPause(cd_id)) + Con_DPrintf("CDAudio_Pause: Failed to pause track.\n"); +} + + +void CDAudio_Resume() +{ + if(!cd_id || !enabled) return; + if(SDL_CDStatus(cd_id) != CD_PAUSED) return; + + if(SDL_CDResume(cd_id)) + Con_DPrintf("CDAudio_Resume: Failed tp resume track.\n"); +} + +void CDAudio_Update() +{ + if(!cd_id || !enabled) return; + if(bgmvolume.value != cdvolume) + { + if(cdvolume) + { + Cvar_SetValue("bgmvolume",0.0); + CDAudio_Pause(); + } + else + { + Cvar_SetValue("bgmvolume",1.0); + CDAudio_Resume(); + } + cdvolume = bgmvolume.value; + return; + } + if(playLooping && (SDL_CDStatus(cd_id) != CD_PLAYING) + && (SDL_CDStatus(cd_id) != CD_PAUSED)) + CDAudio_Play(cd_id->cur_track+1,true); +} + +int CDAudio_Init() +{ + if((cls.state == ca_dedicated) || COM_CheckParm("-nocdaudio")) + return -1; + + cd_id = SDL_CDOpen(0); + if(!cd_id) + { + Con_Printf("CDAudio_Init: Unable to open default CD-ROM drive: %s\n", + SDL_GetError()); + return -1; + } + + initialized = true; + enabled = true; + cdValid = true; + + if(!CD_INDRIVE(SDL_CDStatus(cd_id))) + { + Con_Printf("CDAudio_Init: No CD in drive.\n"); + cdValid = false; + } + if(!cd_id->numtracks) + { + Con_Printf("CDAudio_Init: CD contains no audio tracks.\n"); + cdValid = false; + } + Cmd_AddCommand("cd",CD_f); + Con_Printf("CD Audio Initialized.\n"); + return 0; +} + + +void CDAudio_Shutdown() +{ + if(!cd_id) return; + CDAudio_Stop(); + SDL_CDClose(cd_id); + cd_id = NULL; +} + +static void CD_f() +{ + char *command; + int cdstate; + if(Cmd_Argc() < 2) return; + + command = Cmd_Argv(1); + if(!Q_strcasecmp(command,"on")) + { + enabled = true; + } + if(!Q_strcasecmp(command,"off")) + { + if(!cd_id) return; + cdstate = SDL_CDStatus(cd_id); + if((cdstate == CD_PLAYING) || (cdstate == CD_PAUSED)) + CDAudio_Stop(); + enabled = false; + return; + } + if(!Q_strcasecmp(command,"play")) + { + CDAudio_Play(Q_atoi(Cmd_Argv(2)),false); + return; + } + if(!Q_strcasecmp(command,"loop")) + { + CDAudio_Play(Q_atoi(Cmd_Argv(2)),true); + return; + } + if(!Q_strcasecmp(command,"stop")) + { + CDAudio_Stop(); + return; + } + if(!Q_strcasecmp(command,"pause")) + { + CDAudio_Pause(); + return; + } + if(!Q_strcasecmp(command,"resume")) + { + CDAudio_Resume(); + return; + } + if(!Q_strcasecmp(command,"eject")) + { + CDAudio_Eject(); + return; + } + if(!Q_strcasecmp(command,"info")) + { + if(!cd_id) return; + cdstate = SDL_CDStatus(cd_id); + Con_Printf("%d tracks\n",cd_id->numtracks); + if(cdstate == CD_PLAYING) + Con_Printf("Currently %s track %d\n", + playLooping ? "looping" : "playing", + cd_id->cur_track+1); + else + if(cdstate == CD_PAUSED) + Con_Printf("Paused %s track %d\n", + playLooping ? "looping" : "playing", + cd_id->cur_track+1); + return; + } +} + diff --git a/contrib/other/sdlquake-1.0.9/cd_win.c b/contrib/other/sdlquake-1.0.9/cd_win.c new file mode 100644 index 000000000..867255603 --- /dev/null +++ b/contrib/other/sdlquake-1.0.9/cd_win.c @@ -0,0 +1,477 @@ +/* +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. + +#include +#include "quakedef.h" + +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; + +UINT wDeviceID; + + +static void CDAudio_Eject(void) +{ + DWORD dwReturn; + + if (dwReturn = mciSendCommand(wDeviceID, MCI_SET, MCI_SET_DOOR_OPEN, (DWORD)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)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) (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) (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) (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) (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; + mciPlayParms.dwCallback = (DWORD)mainwindow; + dwReturn = mciSendCommand(wDeviceID, MCI_PLAY, MCI_NOTIFY | MCI_FROM | MCI_TO, (DWORD)(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)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)mainwindow; + if (dwReturn = mciSendCommand(wDeviceID, MCI_PAUSE, 0, (DWORD)(LPVOID) &mciGenericParms)) + Con_DPrintf("MCI_PAUSE failed (%i)", dwReturn); + + wasPlaying = playing; + playing = false; +} + + +void CDAudio_Resume(void) +{ + DWORD dwReturn; + MCI_PLAY_PARMS mciPlayParms; + + if (!enabled) + return; + + if (!cdValid) + return; + + if (!wasPlaying) + return; + + 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); + 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; +} + + +void CDAudio_Update(void) +{ + if (!enabled) + return; + + if (bgmvolume.value != cdvolume) + { + if (cdvolume) + { + Cvar_SetValue ("bgmvolume", 0.0); + cdvolume = bgmvolume.value; + CDAudio_Pause (); + } + else + { + Cvar_SetValue ("bgmvolume", 1.0); + cdvolume = bgmvolume.value; + CDAudio_Resume (); + } + } +} + + +int CDAudio_Init(void) +{ + DWORD dwReturn; + MCI_OPEN_PARMS mciOpenParms; + MCI_SET_PARMS mciSetParms; + int n; + + if (cls.state == ca_dedicated) + return -1; + + if (COM_CheckParm("-nocdaudio")) + return -1; + + mciOpenParms.lpstrDeviceType = "cdaudio"; + if (dwReturn = mciSendCommand(0, MCI_OPEN, MCI_OPEN_TYPE | MCI_OPEN_SHAREABLE, (DWORD) (LPVOID) &mciOpenParms)) + { + Con_Printf("CDAudio_Init: MCI_OPEN failed (%i)\n", dwReturn); + return -1; + } + wDeviceID = mciOpenParms.wDeviceID; + + // Set the time format to track/minute/second/frame (TMSF). + mciSetParms.dwTimeFormat = MCI_FORMAT_TMSF; + if (dwReturn = mciSendCommand(wDeviceID, MCI_SET, MCI_SET_TIME_FORMAT, (DWORD)(LPVOID) &mciSetParms)) + { + Con_Printf("MCI_SET_TIME_FORMAT failed (%i)\n", dwReturn); + mciSendCommand(wDeviceID, MCI_CLOSE, 0, (DWORD)NULL); + return -1; + } + + for (n = 0; n < 100; n++) + remap[n] = n; + initialized = true; + enabled = true; + + if (CDAudio_GetAudioDiskInfo()) + { + Con_Printf("CDAudio_Init: No CD in player.\n"); + cdValid = false; + } + + Cmd_AddCommand ("cd", CD_f); + + Con_Printf("CD Audio Initialized\n"); + + return 0; +} + + +void CDAudio_Shutdown(void) +{ + if (!initialized) + return; + CDAudio_Stop(); + if (mciSendCommand(wDeviceID, MCI_CLOSE, MCI_WAIT, (DWORD)NULL)) + Con_DPrintf("CDAudio_Shutdown: MCI_CLOSE failed\n"); +} diff --git a/contrib/other/sdlquake-1.0.9/cdaudio.h b/contrib/other/sdlquake-1.0.9/cdaudio.h new file mode 100644 index 000000000..80e975be2 --- /dev/null +++ b/contrib/other/sdlquake-1.0.9/cdaudio.h @@ -0,0 +1,27 @@ +/* +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. + +*/ + +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); diff --git a/contrib/other/sdlquake-1.0.9/chase.c b/contrib/other/sdlquake-1.0.9/chase.c new file mode 100644 index 000000000..23061e341 --- /dev/null +++ b/contrib/other/sdlquake-1.0.9/chase.c @@ -0,0 +1,92 @@ +/* +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. + +*/ +// chase.c -- chase camera code + +#include "quakedef.h" + +cvar_t chase_back = {"chase_back", "100"}; +cvar_t chase_up = {"chase_up", "16"}; +cvar_t chase_right = {"chase_right", "0"}; +cvar_t chase_active = {"chase_active", "0"}; + +vec3_t chase_pos; +vec3_t chase_angles; + +vec3_t chase_dest; +vec3_t chase_dest_angles; + + +void Chase_Init (void) +{ + Cvar_RegisterVariable (&chase_back); + Cvar_RegisterVariable (&chase_up); + Cvar_RegisterVariable (&chase_right); + Cvar_RegisterVariable (&chase_active); +} + +void Chase_Reset (void) +{ + // for respawning and teleporting +// start position 12 units behind head +} + +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); +} + +void Chase_Update (void) +{ + int i; + float dist; + vec3_t forward, up, right; + vec3_t dest, stop; + + + // if can't see player, reset + AngleVectors (cl.viewangles, forward, right, up); + + // calc exact destination + for (i=0 ; i<3 ; i++) + chase_dest[i] = r_refdef.vieworg[i] + - forward[i]*chase_back.value + - right[i]*chase_right.value; + chase_dest[2] = r_refdef.vieworg[2] + chase_up.value; + + // find the spot the player is looking at + VectorMA (r_refdef.vieworg, 4096, forward, dest); + TraceLine (r_refdef.vieworg, dest, stop); + + // calculate pitch to look at the same spot from camera + VectorSubtract (stop, r_refdef.vieworg, stop); + dist = DotProduct (stop, forward); + if (dist < 1) + dist = 1; + r_refdef.viewangles[PITCH] = -atan(stop[2] / dist) / M_PI * 180; + + // move towards destination + VectorCopy (chase_dest, r_refdef.vieworg); +} + diff --git a/contrib/other/sdlquake-1.0.9/cl_demo.c b/contrib/other/sdlquake-1.0.9/cl_demo.c new file mode 100644 index 000000000..550368e07 --- /dev/null +++ b/contrib/other/sdlquake-1.0.9/cl_demo.c @@ -0,0 +1,367 @@ +/* +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" + +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. +============================================================================== +*/ + +/* +============== +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.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 +==================== +*/ +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); +} + +/* +==================== +CL_GetMessage + +Handles recording and playback of demos, on top of NET_ code +==================== +*/ +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) // allways grab until fully connected + { + 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); + 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; +} + + +/* +==================== +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] +==================== +*/ +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); +} + +/* +==================== +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; + cls.td_lastframe = -1; // get a new message this frame +} + diff --git a/contrib/other/sdlquake-1.0.9/cl_input.c b/contrib/other/sdlquake-1.0.9/cl_input.c new file mode 100644 index 000000000..5327b7363 --- /dev/null +++ b/contrib/other/sdlquake-1.0.9/cl_input.c @@ -0,0 +1,448 @@ +/* +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. + +*/ +// cl.input.c -- builds an intended movement command to send to the server + +// Quake is a trademark of Id Software, Inc., (c) 1996 Id Software, Inc. All +// rights reserved. + +#include "quakedef.h" + +/* +=============================================================================== + +KEY BUTTONS + +Continuous button event tracking is complicated by the fact that two different +input sources (say, mouse button 1 and the control key) can both press the +same button, but the button should only be released when both of the +pressing key have been released. + +When a key event issues a button command (+forward, +attack, etc), it appends +its key number as a parameter to the command so it can be matched up with +the release. + +state bit 0 is the current state of the key +state bit 1 is edge triggered on the up to down transition +state bit 2 is edge triggered on the down to up transition + +=============================================================================== +*/ + + +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; +kbutton_t in_up, in_down; + +int in_impulse; + + +void KeyDown (kbutton_t *b) +{ + int k; + char *c; + + c = Cmd_Argv(1); + if (c[0]) + k = atoi(c); + else + k = -1; // typed manually at the console for continuous down + + 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]) + b->down[1] = k; + else + { + Con_Printf ("Three keys down for a button!\n"); + return; + } + + if (b->state & 1) + return; // still down + b->state |= 1 + 2; // down + impulse down +} + +void KeyUp (kbutton_t *b) +{ + int k; + char *c; + + c = Cmd_Argv(1); + if (c[0]) + k = atoi(c); + else + { // typed manually at the console, assume for unsticking, so clear all + b->down[0] = b->down[1] = 0; + b->state = 4; // impulse up + return; + } + + if (b->down[0] == k) + b->down[0] = 0; + else if (b->down[1] == k) + b->down[1] = 0; + else + return; // key up without coresponding down (menu pass through) + if (b->down[0] || b->down[1]) + return; // some other key is still holding it down + + if (!(b->state & 1)) + return; // still up (this should not happen) + b->state &= ~1; // now up + b->state |= 4; // impulse up +} + +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(); +} +void IN_UpDown(void) {KeyDown(&in_up);} +void IN_UpUp(void) {KeyUp(&in_up);} +void IN_DownDown(void) {KeyDown(&in_down);} +void IN_DownUp(void) {KeyUp(&in_down);} +void IN_LeftDown(void) {KeyDown(&in_left);} +void IN_LeftUp(void) {KeyUp(&in_left);} +void IN_RightDown(void) {KeyDown(&in_right);} +void IN_RightUp(void) {KeyUp(&in_right);} +void IN_ForwardDown(void) {KeyDown(&in_forward);} +void IN_ForwardUp(void) {KeyUp(&in_forward);} +void IN_BackDown(void) {KeyDown(&in_back);} +void IN_BackUp(void) {KeyUp(&in_back);} +void IN_LookupDown(void) {KeyDown(&in_lookup);} +void IN_LookupUp(void) {KeyUp(&in_lookup);} +void IN_LookdownDown(void) {KeyDown(&in_lookdown);} +void IN_LookdownUp(void) {KeyUp(&in_lookdown);} +void IN_MoveleftDown(void) {KeyDown(&in_moveleft);} +void IN_MoveleftUp(void) {KeyUp(&in_moveleft);} +void IN_MoverightDown(void) {KeyDown(&in_moveright);} +void IN_MoverightUp(void) {KeyUp(&in_moveright);} + +void IN_SpeedDown(void) {KeyDown(&in_speed);} +void IN_SpeedUp(void) {KeyUp(&in_speed);} +void IN_StrafeDown(void) {KeyDown(&in_strafe);} +void IN_StrafeUp(void) {KeyUp(&in_strafe);} + +void IN_AttackDown(void) {KeyDown(&in_attack);} +void IN_AttackUp(void) {KeyUp(&in_attack);} + +void IN_UseDown (void) {KeyDown(&in_use);} +void IN_UseUp (void) {KeyUp(&in_use);} +void IN_JumpDown (void) {KeyDown(&in_jump);} +void IN_JumpUp (void) {KeyUp(&in_jump);} + +void IN_Impulse (void) {in_impulse=Q_atoi(Cmd_Argv(1));} + +/* +=============== +CL_KeyState + +Returns 0.25 if a key was pressed and released during the frame, +0.5 if it was pressed and held +0 if held then released, and +1.0 if held for the entire time +=============== +*/ +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}; +cvar_t cl_sidespeed = {"cl_sidespeed","350"}; + +cvar_t cl_movespeedkey = {"cl_movespeedkey","2.0"}; + +cvar_t cl_yawspeed = {"cl_yawspeed","140"}; +cvar_t cl_pitchspeed = {"cl_pitchspeed","150"}; + +cvar_t cl_anglespeedkey = {"cl_anglespeedkey","1.5"}; + + +/* +================ +CL_AdjustAngles + +Moves the local angle positions +================ +*/ +void CL_AdjustAngles (void) +{ + float speed; + float up, down; + + if (in_speed.state & 1) + speed = host_frametime * cl_anglespeedkey.value; + else + speed = host_frametime; + + if (!(in_strafe.state & 1)) + { + cl.viewangles[YAW] -= speed*cl_yawspeed.value*CL_KeyState (&in_right); + cl.viewangles[YAW] += speed*cl_yawspeed.value*CL_KeyState (&in_left); + cl.viewangles[YAW] = anglemod(cl.viewangles[YAW]); + } + 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); + } + + 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; + + if (cl.viewangles[ROLL] > 50) + cl.viewangles[ROLL] = 50; + if (cl.viewangles[ROLL] < -50) + cl.viewangles[ROLL] = -50; + +} + +/* +================ +CL_BaseMove + +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); + cmd->sidemove -= cl_sidespeed.value * CL_KeyState (&in_left); + } + + cmd->sidemove += cl_sidespeed.value * CL_KeyState (&in_moveright); + cmd->sidemove -= cl_sidespeed.value * CL_KeyState (&in_moveleft); + + cmd->upmove += cl_upspeed.value * CL_KeyState (&in_up); + cmd->upmove -= cl_upspeed.value * CL_KeyState (&in_down); + + if (! (in_klook.state & 1) ) + { + cmd->forwardmove += cl_forwardspeed.value * CL_KeyState (&in_forward); + cmd->forwardmove -= cl_backspeed.value * CL_KeyState (&in_back); + } + +// +// adjust for speed key +// + if (in_speed.state & 1) + { + cmd->forwardmove *= cl_movespeedkey.value; + cmd->sidemove *= cl_movespeedkey.value; + cmd->upmove *= cl_movespeedkey.value; + } + +#ifdef QUAKE2 + cmd->lightlevel = cl.light_level; +#endif +} + + + +/* +============== +CL_SendMove +============== +*/ +void CL_SendMove (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_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); + +// +// 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; + +#ifdef QUAKE2 +// +// light level +// + MSG_WriteByte (&buf, cmd->lightlevel); +#endif + +// +// deliver the message +// + if (cls.demoplayback) + return; + +// +// allways dump the first two message, because it may contain leftover inputs +// from the last level +// + if (++cl.movemessages <= 2) + return; + + if (NET_SendUnreliableMessage (cls.netcon, &buf) == -1) + { + Con_Printf ("CL_SendMove: lost server connection\n"); + CL_Disconnect (); + } +} + +/* +============ +CL_InitInput +============ +*/ +void CL_InitInput (void) +{ + Cmd_AddCommand ("+moveup",IN_UpDown); + Cmd_AddCommand ("-moveup",IN_UpUp); + Cmd_AddCommand ("+movedown",IN_DownDown); + Cmd_AddCommand ("-movedown",IN_DownUp); + Cmd_AddCommand ("+left",IN_LeftDown); + Cmd_AddCommand ("-left",IN_LeftUp); + Cmd_AddCommand ("+right",IN_RightDown); + Cmd_AddCommand ("-right",IN_RightUp); + Cmd_AddCommand ("+forward",IN_ForwardDown); + Cmd_AddCommand ("-forward",IN_ForwardUp); + Cmd_AddCommand ("+back",IN_BackDown); + Cmd_AddCommand ("-back",IN_BackUp); + Cmd_AddCommand ("+lookup", IN_LookupDown); + Cmd_AddCommand ("-lookup", IN_LookupUp); + Cmd_AddCommand ("+lookdown", IN_LookdownDown); + Cmd_AddCommand ("-lookdown", IN_LookdownUp); + Cmd_AddCommand ("+strafe", IN_StrafeDown); + Cmd_AddCommand ("-strafe", IN_StrafeUp); + Cmd_AddCommand ("+moveleft", IN_MoveleftDown); + Cmd_AddCommand ("-moveleft", IN_MoveleftUp); + Cmd_AddCommand ("+moveright", IN_MoverightDown); + Cmd_AddCommand ("-moveright", IN_MoverightUp); + Cmd_AddCommand ("+speed", IN_SpeedDown); + Cmd_AddCommand ("-speed", IN_SpeedUp); + Cmd_AddCommand ("+attack", IN_AttackDown); + Cmd_AddCommand ("-attack", IN_AttackUp); + Cmd_AddCommand ("+use", IN_UseDown); + Cmd_AddCommand ("-use", IN_UseUp); + Cmd_AddCommand ("+jump", IN_JumpDown); + Cmd_AddCommand ("-jump", IN_JumpUp); + Cmd_AddCommand ("impulse", IN_Impulse); + Cmd_AddCommand ("+klook", IN_KLookDown); + Cmd_AddCommand ("-klook", IN_KLookUp); + Cmd_AddCommand ("+mlook", IN_MLookDown); + Cmd_AddCommand ("-mlook", IN_MLookUp); + +} + diff --git a/contrib/other/sdlquake-1.0.9/cl_main.c b/contrib/other/sdlquake-1.0.9/cl_main.c new file mode 100644 index 000000000..58121434b --- /dev/null +++ b/contrib/other/sdlquake-1.0.9/cl_main.c @@ -0,0 +1,757 @@ +/* +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. + +*/ +// cl_main.c -- client main loop + +#include "quakedef.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_shownet = {"cl_shownet","0"}; // can be 0, 1, or 2 +cvar_t cl_nolerp = {"cl_nolerp","0"}; + +cvar_t lookspring = {"lookspring","0", true}; +cvar_t lookstrafe = {"lookstrafe","0", true}; +cvar_t sensitivity = {"sensitivity","3", true}; + +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}; + + +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]; + +int cl_numvisedicts; +entity_t *cl_visedicts[MAX_VISEDICTS]; + +/* +===================== +CL_ClearState + +===================== +*/ +void CL_ClearState (void) +{ + int i; + + if (!sv.active) + Host_ClearMemory (); + +// wipe the entire cl structure + memset (&cl, 0, sizeof(cl)); + + SZ_Clear (&cls.message); + +// clear other arrays + memset (cl_efrags, 0, sizeof(cl_efrags)); + memset (cl_entities, 0, sizeof(cl_entities)); + 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: + 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; + } +} + +/* +===================== +CL_NextDemo + +Called to play the next demo in the demo loop +===================== +*/ +void CL_NextDemo (void) +{ + char str[1024]; + + if (cls.demonum == -1) + return; // don't play demos + + SCR_BeginLoadingPlaque (); + + if (!cls.demos[cls.demonum][0] || cls.demonum == MAX_DEMOS) + { + cls.demonum = 0; + if (!cls.demos[cls.demonum][0]) + { + Con_Printf ("No demos listed with startdemos\n"); + cls.demonum = -1; + return; + } + } + + sprintf (str,"playdemo %s\n", cls.demos[cls.demonum]); + Cbuf_InsertText (str); + cls.demonum++; +} + +/* +============== +CL_PrintEntities_f +============== +*/ +void CL_PrintEntities_f (void) +{ + entity_t *ent; + int i; + + for (i=0,ent=cl_entities ; imodel) + { + Con_Printf ("EMPTY\n"); + continue; + } + Con_Printf ("%s:%2i (%5.1f,%5.1f,%5.1f) [%5.1f %5.1f %5.1f]\n" + ,ent->model->name,ent->frame, ent->origin[0], ent->origin[1], ent->origin[2], ent->angles[0], ent->angles[1], ent->angles[2]); + } +} + + +/* +=============== +SetPal + +Debugging tool, just flashes the screen +=============== +*/ +void SetPal (int i) +{ +#if 0 + static int old; + byte pal[768]; + int c; + + if (i == old) + return; + old = i; + + if (i==0) + VID_SetPalette (host_basepal); + else if (i==1) + { + for (c=0 ; c<768 ; c+=3) + { + pal[c] = 0; + pal[c+1] = 255; + pal[c+2] = 0; + } + VID_SetPalette (pal); + } + else + { + for (c=0 ; c<768 ; c+=3) + { + pal[c] = 0; + pal[c+1] = 0; + pal[c+2] = 255; + } + VID_SetPalette (pal); + } +#endif +} + +/* +=============== +CL_AllocDlight + +=============== +*/ +dlight_t *CL_AllocDlight (int key) +{ + int i; + dlight_t *dl; + +// first look for an exact key match + if (key) + { + dl = cl_dlights; + for (i=0 ; ikey == key) + { + memset (dl, 0, sizeof(*dl)); + dl->key = key; + return dl; + } + } + } + +// then look for anything else + dl = cl_dlights; + for (i=0 ; idie < cl.time) + { + memset (dl, 0, sizeof(*dl)); + dl->key = key; + return dl; + } + } + + dl = &cl_dlights[0]; + memset (dl, 0, sizeof(*dl)); + dl->key = key; + return dl; +} + + +/* +=============== +CL_DecayLights + +=============== +*/ +void CL_DecayLights (void) +{ + int i; + dlight_t *dl; + float time; + + time = cl.time - cl.oldtime; + + dl = cl_dlights; + for (i=0 ; idie < cl.time || !dl->radius) + continue; + + dl->radius -= time*dl->decay; + if (dl->radius < 0) + dl->radius = 0; + } +} + + +/* +=============== +CL_LerpPoint + +Determines the fraction between the last two messages that the objects +should be put at. +=============== +*/ +float CL_LerpPoint (void) +{ + float f, frac; + + f = cl.mtime[0] - cl.mtime[1]; + + if (!f || cl_nolerp.value || cls.timedemo || sv.active) + { + cl.time = cl.mtime[0]; + return 1; + } + + 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); + + return frac; +} + + +/* +=============== +CL_RelinkEntities +=============== +*/ +void CL_RelinkEntities (void) +{ + entity_t *ent; + int i, j; + float frac, f, d; + vec3_t delta; + float bobjrotate; + vec3_t oldorg; + dlight_t *dl; + +// determine partial update time + frac = CL_LerpPoint (); + + cl_numvisedicts = 0; + +// +// interpolate player info +// + for (i=0 ; i<3 ; i++) + cl.velocity[i] = cl.mvelocity[1][i] + + frac * (cl.mvelocity[0][i] - cl.mvelocity[1][i]); + + if (cls.demoplayback) + { + // interpolate the angles + for (j=0 ; j<3 ; j++) + { + d = cl.mviewangles[0][j] - cl.mviewangles[1][j]; + if (d > 180) + d -= 360; + else if (d < -180) + d += 360; + 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 + continue; + } + +// if the object wasn't included in the last packet, remove it + if (ent->msgtime != cl.mtime[0]) + { + ent->model = NULL; + continue; + } + + VectorCopy (ent->origin, oldorg); + + if (ent->forcelink) + { // the entity was not updated in the last message + // so move to the final spot + VectorCopy (ent->msg_origins[0], ent->origin); + VectorCopy (ent->msg_angles[0], ent->angles); + } + else + { // if the delta is large, assume a teleport and don't lerp + f = frac; + for (j=0 ; j<3 ; j++) + { + 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 + } + + // interpolate the origin and angles + for (j=0 ; j<3 ; j++) + { + ent->origin[j] = ent->msg_origins[1][j] + f*delta[j]; + + d = ent->msg_angles[0][j] - ent->msg_angles[1][j]; + if (d > 180) + d -= 360; + else if (d < -180) + d += 360; + ent->angles[j] = ent->msg_angles[1][j] + f*d; + } + + } + +// rotate binary objects locally + if (ent->model->flags & EF_ROTATE) + ent->angles[1] = bobjrotate; + + 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; + + dl = CL_AllocDlight (i); + 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; + } + if (ent->effects & EF_BRIGHTLIGHT) + { + dl = CL_AllocDlight (i); + VectorCopy (ent->origin, dl->origin); + dl->origin[2] += 16; + dl->radius = 400 + (rand()&31); + 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); + else if (ent->model->flags & EF_ZOMGIB) + R_RocketTrail (oldorg, ent->origin, 4); + else if (ent->model->flags & EF_TRACER) + R_RocketTrail (oldorg, ent->origin, 3); + else if (ent->model->flags & EF_TRACER2) + R_RocketTrail (oldorg, ent->origin, 5); + else if (ent->model->flags & EF_ROCKET) + { + R_RocketTrail (oldorg, ent->origin, 0); + dl = CL_AllocDlight (i); + VectorCopy (ent->origin, dl->origin); + dl->radius = 200; + dl->die = cl.time + 0.01; + } + else if (ent->model->flags & EF_GRENADE) + R_RocketTrail (oldorg, ent->origin, 1); + else if (ent->model->flags & EF_TRACER3) + R_RocketTrail (oldorg, ent->origin, 6); + + ent->forcelink = false; + + if (i == cl.viewentity && !chase_active.value) + continue; + +#ifdef QUAKE2 + if ( ent->effects & EF_NODRAW ) + continue; +#endif + if (cl_numvisedicts < MAX_VISEDICTS) + { + cl_visedicts[cl_numvisedicts] = ent; + cl_numvisedicts++; + } + } + +} + + +/* +=============== +CL_ReadFromServer + +Read all incoming data from the server +=============== +*/ +int CL_ReadFromServer (void) +{ + int ret; + + cl.oldtime = cl.time; + cl.time += host_frametime; + + do + { + ret = CL_GetMessage (); + if (ret == -1) + 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 (); + +// +// bring the links up to date +// + return 0; +} + +/* +================= +CL_SendCmd +================= +*/ +void CL_SendCmd (void) +{ + usercmd_t cmd; + + if (cls.state != ca_connected) + return; + + if (cls.signon == SIGNONS) + { + // 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) + { + 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"); + return; + } + + if (NET_SendMessage (cls.netcon, &cls.message) == -1) + Host_Error ("CL_WriteToServer: lost server connection"); + + SZ_Clear (&cls.message); +} + +/* +================= +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); + Cvar_RegisterVariable (&cl_forwardspeed); + Cvar_RegisterVariable (&cl_backspeed); + Cvar_RegisterVariable (&cl_sidespeed); + Cvar_RegisterVariable (&cl_movespeedkey); + Cvar_RegisterVariable (&cl_yawspeed); + Cvar_RegisterVariable (&cl_pitchspeed); + Cvar_RegisterVariable (&cl_anglespeedkey); + Cvar_RegisterVariable (&cl_shownet); + Cvar_RegisterVariable (&cl_nolerp); + Cvar_RegisterVariable (&lookspring); + Cvar_RegisterVariable (&lookstrafe); + Cvar_RegisterVariable (&sensitivity); + + Cvar_RegisterVariable (&m_pitch); + Cvar_RegisterVariable (&m_yaw); + Cvar_RegisterVariable (&m_forward); + Cvar_RegisterVariable (&m_side); + +// Cvar_RegisterVariable (&cl_autofire); + + 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); +} + diff --git a/contrib/other/sdlquake-1.0.9/cl_parse.c b/contrib/other/sdlquake-1.0.9/cl_parse.c new file mode 100644 index 000000000..c79ca4754 --- /dev/null +++ b/contrib/other/sdlquake-1.0.9/cl_parse.c @@ -0,0 +1,963 @@ +/* +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. + +*/ +// cl_parse.c -- parse a message received from the server + +#include "quakedef.h" + +char *svc_strings[] = +{ + "svc_bad", + "svc_nop", + "svc_disconnect", + "svc_updatestat", + "svc_version", // [long] server version + "svc_setview", // [short] entity number + "svc_sound", // + "svc_time", // [float] server time + "svc_print", // [string] null terminated string + "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 + // [string]..[0]item cache + "svc_lightstyle", // [byte] [string] + "svc_updatename", // [byte] [string] + "svc_updatefrags", // [byte] [short] + "svc_clientdata", // + "svc_stopsound", // + "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", + "svc_centerprint", + "svc_killedmonster", + "svc_foundsecret", + "svc_spawnstaticsound", + "svc_intermission", + "svc_finale", // [string] music [string] text + "svc_cdtrack", // [byte] track [byte] looptrack + "svc_sellscreen", + "svc_cutscene" +}; + +//============================================================================= + +/* +=============== +CL_EntityNum + +This error checks and tracks the total number of entities +=============== +*/ +entity_t *CL_EntityNum (int num) +{ + if (num >= cl.num_entities) + { + if (num >= 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.num_entities++; + } + } + + return &cl_entities[num]; +} + + +/* +================== +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) + volume = MSG_ReadByte (); + else + volume = DEFAULT_SOUND_PACKET_VOLUME; + + 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; + + if (ent > 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); +} + +/* +================== +CL_KeepaliveMessage + +When the client is taking a long time to load stuff, send keepalive messages +so the server doesn't disconnect. +================== +*/ +void CL_KeepaliveMessage (void) +{ + float time; + static float lastmsg; + int ret; + sizebuf_t old; + byte olddata[8192]; + + if (sv.active) + return; // no need if server is local + if (cls.demoplayback) + return; + +// read messages from server, should just be nops + 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"); + case 0: + break; // nothing waiting + case 1: + Host_Error ("CL_KeepaliveMessage: received a message"); + break; + case 2: + if (MSG_ReadByte() != svc_nop) + Host_Error ("CL_KeepaliveMessage: datagram wasn't a nop"); + break; + } + } while (ret); + + net_message = old; + memcpy (net_message.data, olddata, net_message.cursize); + +// check time + time = Sys_FloatTime (); + if (time - lastmsg < 5) + return; + lastmsg = time; + +// write out a nop + Con_Printf ("--> client to server keepalive\n"); + + MSG_WriteByte (&cls.message, clc_nop); + NET_SendMessage (cls.netcon, &cls.message); + SZ_Clear (&cls.message); +} + +/* +================== +CL_ParseServerInfo +================== +*/ +void CL_ParseServerInfo (void) +{ + 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"); +// +// wipe the client_state_t struct +// + CL_ClearState (); + +// parse protocol version number + i = MSG_ReadLong (); + if (i != PROTOCOL_VERSION) + { + Con_Printf ("Server returned version %i, not %i", i, PROTOCOL_VERSION); + return; + } + +// 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; + } + cl.scores = 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); + +// 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 ("%c%s\n", 2, str); + +// +// 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++) + { + str = MSG_ReadString (); + if (!str[0]) + break; + if (nummodels==MAX_MODELS) + { + Con_Printf ("Server sent too many model precaches\n"); + return; + } + strcpy (model_precache[nummodels], str); + Mod_TouchModel (str); + } + +// precache sounds + memset (cl.sound_precache, 0, sizeof(cl.sound_precache)); + 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; + } + strcpy (sound_precache[numsounds], str); + S_TouchSound (str); + } + +// +// 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; + + ent->msgtime = cl.mtime[0]; + + if (bits & U_MODEL) + { + modnum = MSG_ReadByte (); + if (modnum >= MAX_MODELS) + Host_Error ("CL_ParseModel: bad modnum"); + } + else + modnum = ent->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 + ent->frame = ent->baseline.frame; + + if (bits & U_COLORMAP) + i = MSG_ReadByte(); + else + i = ent->baseline.colormap; + if (!i) + ent->colormap = vid.colormap; + else + { + if (i > cl.maxclients) + Sys_Error ("i >= 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) { + ent->skinnum = skin; + if (num > 0 && num <= cl.maxclients) + R_TranslatePlayerSkin (num - 1); + } + +#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 + ent->effects = ent->baseline.effects; + +// shift the known values for interpolation + VectorCopy (ent->msg_origins[0], ent->msg_origins[1]); + VectorCopy (ent->msg_angles[0], ent->msg_angles[1]); + + if (bits & U_ORIGIN1) + ent->msg_origins[0][0] = MSG_ReadCoord (); + else + ent->msg_origins[0][0] = ent->baseline.origin[0]; + if (bits & U_ANGLE1) + ent->msg_angles[0][0] = MSG_ReadAngle(); + else + ent->msg_angles[0][0] = ent->baseline.angles[0]; + + if (bits & U_ORIGIN2) + ent->msg_origins[0][1] = MSG_ReadCoord (); + else + ent->msg_origins[0][1] = ent->baseline.origin[1]; + if (bits & U_ANGLE2) + ent->msg_angles[0][1] = MSG_ReadAngle(); + else + ent->msg_angles[0][1] = ent->baseline.angles[1]; + + if (bits & U_ORIGIN3) + ent->msg_origins[0][2] = MSG_ReadCoord (); + else + ent->msg_origins[0][2] = ent->baseline.origin[2]; + if (bits & U_ANGLE3) + ent->msg_angles[0][2] = MSG_ReadAngle(); + else + ent->msg_angles[0][2] = ent->baseline.angles[2]; + + if ( bits & U_NOLERP ) + ent->forcelink = true; + + if ( forcelink ) + { // didn't have an update last message + VectorCopy (ent->msg_origins[0], ent->msg_origins[1]); + VectorCopy (ent->msg_origins[0], ent->origin); + VectorCopy (ent->msg_angles[0], ent->msg_angles[1]); + VectorCopy (ent->msg_angles[0], ent->angles); + ent->forcelink = true; + } +} + +/* +================== +CL_ParseBaseline +================== +*/ +void CL_ParseBaseline (entity_t *ent) +{ + int i; + + ent->baseline.modelindex = MSG_ReadByte (); + ent->baseline.frame = MSG_ReadByte (); + ent->baseline.colormap = MSG_ReadByte(); + ent->baseline.skin = MSG_ReadByte(); + for (i=0 ; i<3 ; i++) + { + ent->baseline.origin[i] = MSG_ReadCoord (); + ent->baseline.angles[i] = MSG_ReadAngle (); + } +} + + +/* +================== +CL_ParseClientdata + +Server information pertaining to this client only +================== +*/ +void CL_ParseClientdata (int bits) +{ + int i, j; + + if (bits & SU_VIEWHEIGHT) + cl.viewheight = MSG_ReadChar (); + else + cl.viewheight = DEFAULT_VIEWHEIGHT; + + if (bits & SU_IDEALPITCH) + cl.idealpitch = MSG_ReadChar (); + else + cl.idealpitch = 0; + + VectorCopy (cl.mvelocity[0], cl.mvelocity[1]); + for (i=0 ; i<3 ; i++) + { + if (bits & (SU_PUNCH1< cl.maxclients) + Sys_Error ("CL_NewTranslation: slot > cl.maxclients"); + dest = cl.scores[slot].translations; + source = vid.colormap; + 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); + +// copy it to the current state + ent->model = cl.model_precache[ent->baseline.modelindex]; + ent->frame = ent->baseline.frame; + ent->colormap = vid.colormap; + ent->skinnum = ent->baseline.skin; + ent->effects = ent->baseline.effects; + + VectorCopy (ent->baseline.origin, ent->origin); + VectorCopy (ent->baseline.angles, ent->angles); + R_AddEfrags (ent); +} + +/* +=================== +CL_ParseStaticSound +=================== +*/ +void CL_ParseStaticSound (void) +{ + vec3_t org; + int sound_num, vol, atten; + int i; + + for (i=0 ; i<3 ; i++) + org[i] = MSG_ReadCoord (); + sound_num = MSG_ReadByte (); + 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 +===================== +*/ +void CL_ParseServerMessage (void) +{ + int cmd; + int i; + +// +// if recording demos, copy the message out +// + if (cl_shownet.value == 1) + Con_Printf ("%i ",net_message.cursize); + else if (cl_shownet.value == 2) + Con_Printf ("------------------\n"); + + cl.onground = false; // unless the server says otherwise +// +// parse the message +// + MSG_BeginReading (); + + while (1) + { + if (msg_badread) + Host_Error ("CL_ParseServerMessage: Bad server message"); + + cmd = MSG_ReadByte (); + + if (cmd == -1) + { + SHOWNET("END OF MESSAGE"); + return; // end of message + } + + // if the high bit of the command byte is set, it is a fast update + if (cmd & 128) + { + SHOWNET("fast update"); + CL_ParseUpdate (cmd&127); + continue; + } + + SHOWNET(svc_strings[cmd]); + + // other commands + switch (cmd) + { + default: + Host_Error ("CL_ParseServerMessage: Illegible server message\n"); + break; + + case svc_nop: +// Con_Printf ("svc_nop\n"); + break; + + case svc_time: + cl.mtime[1] = cl.mtime[0]; + cl.mtime[0] = MSG_ReadFloat (); + break; + + case svc_clientdata: + i = MSG_ReadShort (); + CL_ParseClientdata (i); + 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); + 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 ()); + break; + + 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 (); + 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()); + cl_lightstyle[i].length = Q_strlen(cl_lightstyle[i].map); + break; + + case svc_sound: + CL_ParseStartSoundPacket(); + break; + + case svc_stopsound: + i = MSG_ReadShort(); + S_StopSound(i>>3, i&7); + break; + + case svc_updatename: + Sbar_Changed (); + i = MSG_ReadByte (); + if (i >= cl.maxclients) + Host_Error ("CL_ParseServerMessage: svc_updatename > MAX_SCOREBOARD"); + strcpy (cl.scores[i].name, MSG_ReadString ()); + break; + + case svc_updatefrags: + Sbar_Changed (); + i = MSG_ReadByte (); + if (i >= cl.maxclients) + Host_Error ("CL_ParseServerMessage: svc_updatefrags > MAX_SCOREBOARD"); + cl.scores[i].frags = MSG_ReadShort (); + break; + + case svc_updatecolors: + 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; + + case svc_spawnbaseline: + i = MSG_ReadShort (); + // must use CL_EntityNum() to force cl.num_entities up + CL_ParseBaseline (CL_EntityNum(i)); + break; + case svc_spawnstatic: + CL_ParseStatic (); + break; + case svc_temp_entity: + CL_ParseTEnt (); + break; + + case svc_setpause: + { + cl.paused = MSG_ReadByte (); + + if (cl.paused) + { + CDAudio_Pause (); +#ifdef _WIN32 + VID_HandlePause (true); +#endif + } + else + { + CDAudio_Resume (); +#ifdef _WIN32 + VID_HandlePause (false); +#endif + } + } + 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; + CL_SignonReply (); + break; + + case svc_killedmonster: + cl.stats[STAT_MONSTERS]++; + break; + + case svc_foundsecret: + cl.stats[STAT_SECRETS]++; + break; + + case svc_updatestat: + i = MSG_ReadByte (); + if (i < 0 || i >= MAX_CL_STATS) + Sys_Error ("svc_updatestat: %i is invalid", i); + cl.stats[i] = MSG_ReadLong ();; + break; + + case svc_spawnstaticsound: + CL_ParseStaticSound (); + break; + + case svc_cdtrack: + cl.cdtrack = MSG_ReadByte (); + cl.looptrack = MSG_ReadByte (); + if ( (cls.demoplayback || cls.demorecording) && (cls.forcetrack != -1) ) + CDAudio_Play ((byte)cls.forcetrack, true); + else + CDAudio_Play ((byte)cl.cdtrack, true); + break; + + case svc_intermission: + cl.intermission = 1; + cl.completed_time = cl.time; + vid.recalc_refdef = true; // go to full screen + break; + + case svc_finale: + cl.intermission = 2; + cl.completed_time = cl.time; + vid.recalc_refdef = true; // go to full screen + SCR_CenterPrint (MSG_ReadString ()); + break; + + case svc_cutscene: + cl.intermission = 3; + cl.completed_time = cl.time; + vid.recalc_refdef = true; // go to full screen + SCR_CenterPrint (MSG_ReadString ()); + break; + + case svc_sellscreen: + Cmd_ExecuteString ("help", src_command); + break; + } + } +} + diff --git a/contrib/other/sdlquake-1.0.9/cl_tent.c b/contrib/other/sdlquake-1.0.9/cl_tent.c new file mode 100644 index 000000000..546e832f8 --- /dev/null +++ b/contrib/other/sdlquake-1.0.9/cl_tent.c @@ -0,0 +1,394 @@ +/* +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. + +*/ +// cl_tent.c -- client side temporary entities + +#include "quakedef.h" + +int num_temp_entities; +entity_t cl_temp_entities[MAX_TEMP_ENTITIES]; +beam_t cl_beams[MAX_BEAMS]; + +sfx_t *cl_sfx_wizhit; +sfx_t *cl_sfx_knighthit; +sfx_t *cl_sfx_tink1; +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 + +/* +================= +CL_ParseTEnt +================= +*/ +void CL_InitTEnts (void) +{ + cl_sfx_wizhit = S_PrecacheSound ("wizard/hit.wav"); + cl_sfx_knighthit = S_PrecacheSound ("hknight/hit.wav"); + cl_sfx_tink1 = S_PrecacheSound ("weapons/tink1.wav"); + cl_sfx_ric1 = S_PrecacheSound ("weapons/ric1.wav"); + 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 +} + +/* +================= +CL_ParseBeam +================= +*/ +void CL_ParseBeam (model_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 (); + +// override any beam with the same entity + for (i=0, b=cl_beams ; i< MAX_BEAMS ; i++, b++) + if (b->entity == ent) + { + b->entity = ent; + b->model = m; + b->endtime = cl.time + 0.2; + VectorCopy (start, b->start); + VectorCopy (end, b->end); + return; + } + +// find a free beam + for (i=0, b=cl_beams ; i< MAX_BEAMS ; i++, b++) + { + if (!b->model || b->endtime < cl.time) + { + b->entity = ent; + b->model = m; + b->endtime = cl.time + 0.2; + VectorCopy (start, b->start); + VectorCopy (end, b->end); + return; + } + } + Con_Printf ("beam list overflow!\n"); +} + +/* +================= +CL_ParseTEnt +================= +*/ +void CL_ParseTEnt (void) +{ + int type; + vec3_t pos; +#ifdef QUAKE2 + vec3_t endpos; +#endif + dlight_t *dl; + int rnd; + int colorStart, colorLength; + + type = MSG_ReadByte (); + switch (type) + { + case TE_WIZSPIKE: // spike hitting wall + pos[0] = MSG_ReadCoord (); + pos[1] = MSG_ReadCoord (); + pos[2] = MSG_ReadCoord (); + 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 (); + 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 + R_RunParticleEffect (pos, vec3_origin, 0, 10); +#endif + if ( rand() % 5 ) + S_StartSound (-1, 0, cl_sfx_tink1, pos, 1, 1); + else + { + rnd = rand() & 3; + if (rnd == 1) + S_StartSound (-1, 0, cl_sfx_ric1, pos, 1, 1); + else if (rnd == 2) + S_StartSound (-1, 0, cl_sfx_ric2, pos, 1, 1); + else + S_StartSound (-1, 0, cl_sfx_ric3, pos, 1, 1); + } + break; + case TE_SUPERSPIKE: // super spike hitting wall + pos[0] = MSG_ReadCoord (); + pos[1] = MSG_ReadCoord (); + pos[2] = MSG_ReadCoord (); + R_RunParticleEffect (pos, vec3_origin, 0, 20); + + if ( rand() % 5 ) + S_StartSound (-1, 0, cl_sfx_tink1, pos, 1, 1); + else + { + rnd = rand() & 3; + if (rnd == 1) + S_StartSound (-1, 0, cl_sfx_ric1, pos, 1, 1); + else if (rnd == 2) + S_StartSound (-1, 0, cl_sfx_ric2, pos, 1, 1); + else + 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 (); + 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 (); + R_ParticleExplosion (pos); + dl = CL_AllocDlight (0); + VectorCopy (pos, dl->origin); + dl->radius = 350; + dl->die = cl.time + 0.5; + 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 (); + R_BlobExplosion (pos); + + S_StartSound (-1, 0, cl_sfx_r_exp3, pos, 1, 1); + break; + + 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 + 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 (); + R_LavaSplash (pos); + break; + + case TE_TELEPORT: + pos[0] = MSG_ReadCoord (); + pos[1] = MSG_ReadCoord (); + pos[2] = MSG_ReadCoord (); + R_TeleportSplash (pos); + break; + + case TE_EXPLOSION2: // color mapped explosion + pos[0] = MSG_ReadCoord (); + pos[1] = MSG_ReadCoord (); + pos[2] = MSG_ReadCoord (); + colorStart = MSG_ReadByte (); + colorLength = MSG_ReadByte (); + R_ParticleExplosion2 (pos, colorStart, colorLength); + dl = CL_AllocDlight (0); + VectorCopy (pos, dl->origin); + dl->radius = 350; + dl->die = cl.time + 0.5; + 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"); + } +} + + +/* +================= +CL_NewTempEntity +================= +*/ +entity_t *CL_NewTempEntity (void) +{ + entity_t *ent; + + if (cl_numvisedicts == MAX_VISEDICTS) + return NULL; + if (num_temp_entities == MAX_TEMP_ENTITIES) + return NULL; + ent = &cl_temp_entities[num_temp_entities]; + memset (ent, 0, sizeof(*ent)); + num_temp_entities++; + cl_visedicts[cl_numvisedicts] = ent; + cl_numvisedicts++; + + ent->colormap = vid.colormap; + return ent; +} + + +/* +================= +CL_UpdateTEnts +================= +*/ +void CL_UpdateTEnts (void) +{ + int i; + beam_t *b; + vec3_t dist, org; + float d; + entity_t *ent; + float yaw, pitch; + float forward; + + num_temp_entities = 0; + +// update lightning + for (i=0, b=cl_beams ; i< MAX_BEAMS ; i++, b++) + { + if (!b->model || b->endtime < cl.time) + continue; + + // if coming from the player, update the start position + if (b->entity == cl.viewentity) + { + VectorCopy (cl_entities[cl.viewentity].origin, b->start); + } + + // calculate pitch and yaw + VectorSubtract (b->end, b->start, dist); + + if (dist[1] == 0 && dist[0] == 0) + { + yaw = 0; + if (dist[2] > 0) + pitch = 90; + else + pitch = 270; + } + else + { + 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) + pitch += 360; + } + + // add new entities for the lightning + VectorCopy (b->start, org); + d = VectorNormalize(dist); + while (d > 0) + { + ent = CL_NewTempEntity (); + if (!ent) + return; + VectorCopy (org, ent->origin); + ent->model = b->model; + ent->angles[0] = pitch; + ent->angles[1] = yaw; + ent->angles[2] = rand()%360; + + for (i=0 ; i<3 ; i++) + org[i] += dist[i]*30; + d -= 30; + } + } + +} + + diff --git a/contrib/other/sdlquake-1.0.9/clean.bat b/contrib/other/sdlquake-1.0.9/clean.bat new file mode 100644 index 000000000..8a5aad486 --- /dev/null +++ b/contrib/other/sdlquake-1.0.9/clean.bat @@ -0,0 +1,18 @@ +rmdir /s /q debug +rmdir /s /q release +rmdir /s /q debug_gl +rmdir /s /q release_gl + +rmdir /s /q gas2masm\debug +rmdir /s /q gas2masm\release + +del gas2masm\gas2masm.opt +del gas2masm\gas2masm.plg +del gas2masm\gas2masm.ncb +del gas2masm\gas2masm.stt + +del WinQuake.opt +del WinQuake.plg +del WinQuake.ncb +del WinQuake.stt + diff --git a/contrib/other/sdlquake-1.0.9/client.h b/contrib/other/sdlquake-1.0.9/client.h new file mode 100644 index 000000000..7c59ee92a --- /dev/null +++ b/contrib/other/sdlquake-1.0.9/client.h @@ -0,0 +1,375 @@ +/* +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. + +*/ +// client.h + +typedef struct +{ + vec3_t viewangles; + +// intended velocities + float forwardmove; + float sidemove; + float upmove; +#ifdef QUAKE2 + byte lightlevel; +#endif +} usercmd_t; + +typedef struct +{ + int length; + char map[MAX_STYLESTRING]; +} lightstyle_t; + +typedef struct +{ + char name[MAX_SCOREBOARDNAME]; + float entertime; + int frags; + int colors; // two 4 bit fields + byte translations[VID_GRADES*256]; +} scoreboard_t; + +typedef struct +{ + int destcolor[3]; + int percent; // 0-256 +} cshift_t; + +#define CSHIFT_CONTENTS 0 +#define CSHIFT_DAMAGE 1 +#define CSHIFT_BONUS 2 +#define CSHIFT_POWERUP 3 +#define NUM_CSHIFTS 4 + +#define NAME_LENGTH 64 + + +// +// client_state_t should hold all pieces of the client state +// + +#define SIGNONS 4 // signon messages to receive before connected + +#define MAX_DLIGHTS 32 +typedef struct +{ + vec3_t origin; + float radius; + float die; // stop lighting after this time + 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 +} dlight_t; + + +#define MAX_BEAMS 24 +typedef struct +{ + int entity; + struct model_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 + +typedef enum { +ca_dedicated, // a dedicated server with no ability to start a client +ca_disconnected, // full screen console with no connection +ca_connected // valid netcon, talking to a server +} cactive_t; + +// +// the client_static_t structure is persistant through an arbitrary number +// of server connections +// +typedef struct +{ + cactive_t state; + +// personalization data sent to server + char mapstring[MAX_QPATH]; + 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 + +// 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; + 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 + struct qsocket_s *netcon; + sizebuf_t message; // writing buffer to send to server + +} client_static_t; + +extern client_static_t cls; + +// +// the client_state_t structure is wiped completely at every +// server signon +// +typedef struct +{ + int movemessages; // since connecting to this server + // throw out the first couple, so the player + // doesn't accidentally do something the + // first frame + usercmd_t cmd; // last command sent to the server + +// information for local display + int stats[MAX_CL_STATS]; // health, etc + int items; // inventory bit flags + float item_gettime[32]; // cl.time of aquiring item, for blinking + float faceanimtime; // use anim frame if cl.time < this + + cshift_t cshifts[NUM_CSHIFTS]; // color shifts for damage, powerups + cshift_t prev_cshifts[NUM_CSHIFTS]; // and content types + +// the client maintains its own idea of view angles, which are +// sent to the server each frame. The server sets punchangle when +// the view is temporarliy offset, and an angle reset commands at the start +// of each level and after teleporting. + 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; + qboolean nodrift; + float driftmove; + double laststop; + + float viewheight; + float crouch; // local amount for smoothing stepups + + qboolean paused; // send over by server + 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 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 sfx_s *sound_precache[MAX_SOUNDS]; + + char levelname[40]; // for display on solo scoreboard + int viewentity; // cl_entitites[cl.viewentity] = player + int maxclients; + int gametype; + +// refresh related state + struct model_s *worldmodel; // cl_entitites[0].model + struct efrag_s *free_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 + +// 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 +} client_state_t; + + +// +// cvars +// +extern cvar_t cl_name; +extern cvar_t cl_color; + +extern cvar_t cl_upspeed; +extern cvar_t cl_forwardspeed; +extern cvar_t cl_backspeed; +extern cvar_t cl_sidespeed; + +extern cvar_t cl_movespeedkey; + +extern cvar_t cl_yawspeed; +extern cvar_t cl_pitchspeed; + +extern cvar_t cl_anglespeedkey; + +extern cvar_t cl_autofire; + +extern cvar_t cl_shownet; +extern cvar_t cl_nolerp; + +extern cvar_t cl_pitchdriftspeed; +extern cvar_t lookspring; +extern cvar_t lookstrafe; +extern cvar_t sensitivity; + +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 + +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]; + +//============================================================================= + +// +// cl_main +// +dlight_t *CL_AllocDlight (int key); +void CL_DecayLights (void); + +void CL_Init (void); + +void CL_EstablishConnection (char *host); +void CL_Signon1 (void); +void CL_Signon2 (void); +void CL_Signon3 (void); +void CL_Signon4 (void); + +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 +// +typedef struct +{ + int down[2]; // key nums holding it down + int state; // low bit is down state +} kbutton_t; + +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_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 +// +void CL_StopPlayback (void); +int CL_GetMessage (void); + +void CL_Stop_f (void); +void CL_Record_f (void); +void CL_PlayDemo_f (void); +void CL_TimeDemo_f (void); + +// +// cl_parse.c +// +void CL_ParseServerMessage (void); +void CL_NewTranslation (int slot); + +// +// view +// +void V_StartPitchDrift (void); +void V_StopPitchDrift (void); + +void V_RenderView (void); +void V_UpdatePalette (void); +void V_Register (void); +void V_ParseDamage (void); +void V_SetContentsColor (int contents); + + +// +// cl_tent +// +void CL_InitTEnts (void); +void CL_SignonReply (void); diff --git a/contrib/other/sdlquake-1.0.9/cmd.c b/contrib/other/sdlquake-1.0.9/cmd.c new file mode 100644 index 000000000..0778c5eca --- /dev/null +++ b/contrib/other/sdlquake-1.0.9/cmd.c @@ -0,0 +1,705 @@ +/* +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. + +*/ +// cmd.c -- Quake script command processing module + +#include "quakedef.h" + +void Cmd_ForwardToServer (void); + +#define MAX_ALIAS_NAME 32 + +typedef struct cmdalias_s +{ + struct cmdalias_s *next; + char name[MAX_ALIAS_NAME]; + char *value; +} cmdalias_t; + +cmdalias_t *cmd_alias; + +int trashtest; +int *trashspot; + +qboolean cmd_wait; + +//============================================================================= + +/* +============ +Cmd_Wait_f + +Causes execution of the remainder of the command buffer to be delayed until +next frame. This allows commands like: +bind g "impulse 5 ; +attack ; wait ; -attack ; impulse 2" +============ +*/ +void Cmd_Wait_f (void) +{ + cmd_wait = true; +} + +/* +============================================================================= + + COMMAND BUFFER + +============================================================================= +*/ + +sizebuf_t cmd_text; + +/* +============ +Cbuf_Init +============ +*/ +void Cbuf_Init (void) +{ + SZ_Alloc (&cmd_text, 8192); // space for commands and script files +} + + +/* +============ +Cbuf_AddText + +Adds command text at the end of the buffer +============ +*/ +void Cbuf_AddText (char *text) +{ + int l; + + l = Q_strlen (text); + + if (cmd_text.cursize + l >= cmd_text.maxsize) + { + Con_Printf ("Cbuf_AddText: overflow\n"); + return; + } + + SZ_Write (&cmd_text, text, Q_strlen (text)); +} + + +/* +============ +Cbuf_InsertText + +Adds command text immediately after the current command +Adds a \n to the text +FIXME: actually change the command buffer to do less copying +============ +*/ +void Cbuf_InsertText (char *text) +{ + char *temp; + int templen; + +// copy off any commands still remaining in the exec buffer + templen = cmd_text.cursize; + if (templen) + { + temp = 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); + +// add the copied off data + if (templen) + { + SZ_Write (&cmd_text, temp, templen); + Z_Free (temp); + } +} + +/* +============ +Cbuf_Execute +============ +*/ +void Cbuf_Execute (void) +{ + int i; + char *text; + char line[1024]; + int quotes; + + while (cmd_text.cursize) + { +// find a \n or ; line break + text = (char *)cmd_text.data; + + quotes = 0; + for (i=0 ; i< cmd_text.cursize ; i++) + { + if (text[i] == '"') + quotes++; + if ( !(quotes&1) && text[i] == ';') + break; // don't break if inside a quoted string + if (text[i] == '\n') + break; + } + + + 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 + + if (i == cmd_text.cursize) + cmd_text.cursize = 0; + else + { + i++; + cmd_text.cursize -= i; + Q_memcpy (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 + cmd_wait = false; + break; + } + } +} + +/* +============================================================================== + + SCRIPT COMMANDS + +============================================================================== +*/ + +/* +=============== +Cmd_StuffCmds_f + +Adds command line parameters as script statements +Commands lead with a +, and continue until a - or another + +quake +prog jctest.qp +cmd amlev1 +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; + } + +// build the combined string to parse from + s = 0; + for (i=1 ; i : execute a script file\n"); + return; + } + + mark = Hunk_LowMark (); + f = (char *)COM_LoadHunkFile (Cmd_Argv(1)); + 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); +} + + +/* +=============== +Cmd_Echo_f + +Just prints the rest of the line to the console +=============== +*/ +void Cmd_Echo_f (void) +{ + int i; + + for (i=1 ; inext) + Con_Printf ("%s : %s\n", a->name, a->value); + 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 (!a) + { + a = 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++) + { + strcat (cmd, Cmd_Argv(i)); + if (i != c) + strcat (cmd, " "); + } + strcat (cmd, "\n"); + + a->value = CopyString (cmd); +} + +/* +============================================================================= + + COMMAND EXECUTION + +============================================================================= +*/ + +typedef struct cmd_function_s +{ + struct cmd_function_s *next; + char *name; + xcommand_t function; +} cmd_function_t; + + +#define MAX_ARGS 80 + +static int cmd_argc; +static char *cmd_argv[MAX_ARGS]; +static char *cmd_null_string = ""; +static char *cmd_args = NULL; + +cmd_source_t cmd_source; + + +static cmd_function_t *cmd_functions; // possible commands to execute + +/* +============ +Cmd_Init +============ +*/ +void Cmd_Init (void) +{ +// +// register our commands +// + 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_Argc +============ +*/ +int Cmd_Argc (void) +{ + return cmd_argc; +} + +/* +============ +Cmd_Argv +============ +*/ +char *Cmd_Argv (int arg) +{ + if ( (unsigned)arg >= cmd_argc ) + return cmd_null_string; + return cmd_argv[arg]; +} + +/* +============ +Cmd_Args +============ +*/ +char *Cmd_Args (void) +{ + return cmd_args; +} + + +/* +============ +Cmd_TokenizeString + +Parses the given string into command line tokens. +============ +*/ +void Cmd_TokenizeString (char *text) +{ + int i; + +// clear the args from the last string + for (i=0 ; inext) + { + if (!Q_strcmp (cmd_name, cmd->name)) + { + Con_Printf ("Cmd_AddCommand: %s already defined\n", cmd_name); + return; + } + } + + cmd = Hunk_Alloc (sizeof(cmd_function_t)); + cmd->name = cmd_name; + cmd->function = function; + cmd->next = cmd_functions; + cmd_functions = cmd; +} + +/* +============ +Cmd_Exists +============ +*/ +qboolean Cmd_Exists (char *cmd_name) +{ + cmd_function_t *cmd; + + for (cmd=cmd_functions ; cmd ; cmd=cmd->next) + { + if (!Q_strcmp (cmd_name,cmd->name)) + return true; + } + + return false; +} + + + +/* +============ +Cmd_CompleteCommand +============ +*/ +char *Cmd_CompleteCommand (char *partial) +{ + cmd_function_t *cmd; + 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)) + return cmd->name; + + return NULL; +} + +/* +============ +Cmd_ExecuteString + +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) +{ + cmd_function_t *cmd; + cmdalias_t *a; + + cmd_source = src; + Cmd_TokenizeString (text); + +// execute the command line + if (!Cmd_Argc()) + return; // no tokens + +// check functions + for (cmd=cmd_functions ; cmd ; cmd=cmd->next) + { + if (!Q_strcasecmp (cmd_argv[0],cmd->name)) + { + cmd->function (); + return; + } + } + +// check alias + for (a=cmd_alias ; a ; a=a->next) + { + 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)); + +} + + +/* +=================== +Cmd_ForwardToServer + +Sends the entire command line over to the server +=================== +*/ +void Cmd_ForwardToServer (void) +{ + if (cls.state != ca_connected) + { + 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) + { + SZ_Print (&cls.message, Cmd_Argv(0)); + SZ_Print (&cls.message, " "); + } + if (Cmd_Argc() > 1) + SZ_Print (&cls.message, Cmd_Args()); + else + SZ_Print (&cls.message, "\n"); +} + + +/* +================ +Cmd_CheckParm + +Returns the position (1 to argc-1) in the command's argument list +where the given parameter apears, or 0 if not present +================ +*/ + +int Cmd_CheckParm (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))) + return i; + + return 0; +} diff --git a/contrib/other/sdlquake-1.0.9/cmd.h b/contrib/other/sdlquake-1.0.9/cmd.h new file mode 100644 index 000000000..f9eab24ec --- /dev/null +++ b/contrib/other/sdlquake-1.0.9/cmd.h @@ -0,0 +1,121 @@ +/* +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. + +*/ + +// cmd.h -- Command buffer and command execution + +//=========================================================================== + +/* + +Any number of commands can be added in a frame, from several different sources. +Most commands come from either keybindings or console line input, but remote +servers can also send across commands and entire text files can be execed. + +The + command line options are also added to the command buffer. + +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); +// 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); +// when a command wants to issue other commands immediately, the text is +// inserted at the beginning of the buffer, before any remaining unexecuted +// commands. + +void Cbuf_Execute (void); +// Pulls off \n terminated lines of text from the command buffer and sends +// them through Cmd_ExecuteString. Stops when the buffer is empty. +// Normally called once per frame, but may be explicitly invoked. +// Do not call inside a command function! + +//=========================================================================== + +/* + +Command execution takes a null terminated string, breaks it into tokens, +then searches for a command or variable that matches the first token. + +Commands can come from three sources, but the handler functions may choose +to dissallow the action or forward it to a remote server if the source is +not apropriate. + +*/ + +typedef void (*xcommand_t) (void); + +typedef enum +{ + src_client, // came in over a net connection as a clc_stringcmd + // host_client will be valid during this state. + src_command // from the command buffer +} cmd_source_t; + +extern cmd_source_t cmd_source; + +void Cmd_Init (void); + +void Cmd_AddCommand (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); +// used by the cvar code to check for cvar / command name overlap + +char *Cmd_CompleteCommand (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); +// 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); +// 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); +// 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); +// 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. + +void Cmd_ForwardToServer (void); +// adds the current command line as a clc_stringcmd to the client message. +// 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); +// used by command functions to send output to either the graphics console or +// passed as a print message to the client + diff --git a/contrib/other/sdlquake-1.0.9/common.c b/contrib/other/sdlquake-1.0.9/common.c new file mode 100644 index 000000000..5b41b5017 --- /dev/null +++ b/contrib/other/sdlquake-1.0.9/common.c @@ -0,0 +1,1840 @@ +/* +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" + +#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; +} + +/* +============================================================================ + + LIBRARY REPLACEMENT FUNCTIONS + +============================================================================ +*/ + +void Q_memset (void *dest, int fill, int count) +{ + int i; + + if ( (((long)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 + +============================================================================ +*/ + +#ifdef SDL +#include "SDL_byteorder.h" +#endif + +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) +{ + MSG_WriteShort (sb, (int)(f*8)); +} + +void MSG_WriteAngle (sizebuf_t *sb, float f) +{ + 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--; + + for (s2 = s ; *s2 && *s2 != '/' ; 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); +} + +/* +=========== +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"); + +// +// 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); + if (handle) + { + *handle = pak->handle; + Sys_FileSeek (pak->handle, pak->files[i].filepos); + } + else + { // open a new file on the pakfile + *file = fopen (pak->filename, "rb"); + if (*file) + fseek (*file, pak->files[i].filepos, SEEK_SET); + } + com_filesize = pak->files[i].filelen; + 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); +} + + +/* +============ +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) + { +// Con_Printf ("Couldn't open %s\n", packfile); + 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 (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 ; ifilename, packfile); + pack->handle = packhandle; + pack->numfiles = numpackfiles; + pack->files = newfiles; + + Con_Printf ("Added packfile %s (%i files)\n", packfile, numpackfiles); + return pack; +} + + +/* +================ +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) +{ + int i; + searchpath_t *search; + pack_t *pak; + char pakfile[MAX_OSPATH]; + + 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, ... +// + 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; + } + +// +// 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) +// +#ifdef _KOLIBRI + COM_AddGameDirectory (basedir); +#else + COM_AddGameDirectory (va("%s/"GAMENAME, basedir) ); +#endif + + if (COM_CheckParm ("-rogue")) + COM_AddGameDirectory (va("%s/rogue", basedir) ); + if (COM_CheckParm ("-hipnotic")) + COM_AddGameDirectory (va("%s/hipnotic", basedir) ); + +// +// -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 + strcpy (search->filename, com_argv[i]); + search->next = com_searchpaths; + com_searchpaths = search; + } + } + + if (COM_CheckParm ("-proghack")) + proghack = true; +} + + diff --git a/contrib/other/sdlquake-1.0.9/common.h b/contrib/other/sdlquake-1.0.9/common.h new file mode 100644 index 000000000..87d4a55ea --- /dev/null +++ b/contrib/other/sdlquake-1.0.9/common.h @@ -0,0 +1,183 @@ +/* +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 - (int)&(((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); + +//============================================================================ + +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); + +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/contrib/other/sdlquake-1.0.9/config.guess b/contrib/other/sdlquake-1.0.9/config.guess new file mode 100644 index 000000000..1d27287d5 --- /dev/null +++ b/contrib/other/sdlquake-1.0.9/config.guess @@ -0,0 +1,997 @@ +#! /bin/sh +# Attempt to guess a canonical system name. +# Copyright (C) 1992, 93, 94, 95, 96, 97, 1998 Free Software Foundation, Inc. +# +# This file is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public 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. +# +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +# Written by Per Bothner . +# The master version of this file is at the FSF in /home/gd/gnu/lib. +# Please send patches to the Autoconf mailing list . +# +# This script attempts to guess a canonical system name similar to +# config.sub. If it succeeds, it prints the system name on stdout, and +# exits with 0. Otherwise, it exits with 1. +# +# The plan is that this can be called by configure scripts if you +# don't specify an explicit system type (host/target name). +# +# Only a few systems have been added to this list; please add others +# (but try to keep the structure clean). +# + +# This is needed to find uname on a Pyramid OSx when run in the BSD universe. +# (ghazi@noc.rutgers.edu 8/24/94.) +if (test -f /.attbin/uname) >/dev/null 2>&1 ; then + PATH=$PATH:/.attbin ; export PATH +fi + +UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown +UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown +UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown +UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown + +dummy=dummy-$$ +trap 'rm -f $dummy.c $dummy.o $dummy; exit 1' 1 2 15 + +# Note: order is significant - the case branches are not exclusive. + +case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in + alpha:OSF1:*:*) + if test $UNAME_RELEASE = "V4.0"; then + UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'` + fi + # A Vn.n version is a released version. + # A Tn.n version is a released field test version. + # A Xn.n version is an unreleased experimental baselevel. + # 1.2 uses "1.2" for uname -r. + cat <$dummy.s + .globl main + .ent main +main: + .frame \$30,0,\$26,0 + .prologue 0 + .long 0x47e03d80 # implver $0 + lda \$2,259 + .long 0x47e20c21 # amask $2,$1 + srl \$1,8,\$2 + sll \$2,2,\$2 + sll \$0,3,\$0 + addl \$1,\$0,\$0 + addl \$2,\$0,\$0 + ret \$31,(\$26),1 + .end main +EOF + ${CC-cc} $dummy.s -o $dummy 2>/dev/null + if test "$?" = 0 ; then + ./$dummy + case "$?" in + 7) + UNAME_MACHINE="alpha" + ;; + 15) + UNAME_MACHINE="alphaev5" + ;; + 14) + UNAME_MACHINE="alphaev56" + ;; + 10) + UNAME_MACHINE="alphapca56" + ;; + 16) + UNAME_MACHINE="alphaev6" + ;; + esac + fi + rm -f $dummy.s $dummy + echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[VTX]//' | tr [[A-Z]] [[a-z]]` + exit 0 ;; + 21064:Windows_NT:50:3) + echo alpha-dec-winnt3.5 + exit 0 ;; + Amiga*:UNIX_System_V:4.0:*) + echo m68k-cbm-sysv4 + exit 0;; + amiga:NetBSD:*:*) + echo m68k-cbm-netbsd${UNAME_RELEASE} + exit 0 ;; + amiga:OpenBSD:*:*) + echo m68k-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + *:[Aa]miga[Oo][Ss]:*:*) + echo ${UNAME_MACHINE}-unknown-amigaos + exit 0 ;; + arc64:OpenBSD:*:*) + echo mips64el-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + arc:OpenBSD:*:*) + echo mipsel-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + hkmips:OpenBSD:*:*) + echo mips-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + pmax:OpenBSD:*:*) + echo mipsel-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + sgi:OpenBSD:*:*) + echo mips-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + wgrisc:OpenBSD:*:*) + echo mipsel-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*) + echo arm-acorn-riscix${UNAME_RELEASE} + exit 0;; + arm32:NetBSD:*:*) + echo arm-unknown-netbsd`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'` + exit 0 ;; + SR2?01:HI-UX/MPP:*:*) + echo hppa1.1-hitachi-hiuxmpp + exit 0;; + Pyramid*:OSx*:*:*|MIS*:OSx*:*:*|MIS*:SMP_DC-OSx*:*:*) + # akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE. + if test "`(/bin/universe) 2>/dev/null`" = att ; then + echo pyramid-pyramid-sysv3 + else + echo pyramid-pyramid-bsd + fi + exit 0 ;; + NILE*:*:*:dcosx) + echo pyramid-pyramid-svr4 + exit 0 ;; + sun4H:SunOS:5.*:*) + echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit 0 ;; + sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*) + echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit 0 ;; + i86pc:SunOS:5.*:*) + echo i386-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit 0 ;; + sun4*:SunOS:6*:*) + # According to config.sub, this is the proper way to canonicalize + # SunOS6. Hard to guess exactly what SunOS6 will be like, but + # it's likely to be more like Solaris than SunOS4. + echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit 0 ;; + sun4*:SunOS:*:*) + case "`/usr/bin/arch -k`" in + Series*|S4*) + UNAME_RELEASE=`uname -v` + ;; + esac + # Japanese Language versions have a version number like `4.1.3-JL'. + echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'` + exit 0 ;; + sun3*:SunOS:*:*) + echo m68k-sun-sunos${UNAME_RELEASE} + exit 0 ;; + sun*:*:4.2BSD:*) + UNAME_RELEASE=`(head -1 /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null` + test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3 + case "`/bin/arch`" in + sun3) + echo m68k-sun-sunos${UNAME_RELEASE} + ;; + sun4) + echo sparc-sun-sunos${UNAME_RELEASE} + ;; + esac + exit 0 ;; + aushp:SunOS:*:*) + echo sparc-auspex-sunos${UNAME_RELEASE} + exit 0 ;; + atari*:NetBSD:*:*) + echo m68k-atari-netbsd${UNAME_RELEASE} + exit 0 ;; + atari*:OpenBSD:*:*) + echo m68k-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + sun3*:NetBSD:*:*) + echo m68k-sun-netbsd${UNAME_RELEASE} + exit 0 ;; + sun3*:OpenBSD:*:*) + echo m68k-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + mac68k:NetBSD:*:*) + echo m68k-apple-netbsd${UNAME_RELEASE} + exit 0 ;; + mac68k:OpenBSD:*:*) + echo m68k-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + mvme68k:OpenBSD:*:*) + echo m68k-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + mvme88k:OpenBSD:*:*) + echo m88k-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + powerpc:machten:*:*) + echo powerpc-apple-machten${UNAME_RELEASE} + exit 0 ;; + macppc:NetBSD:*:*) + echo powerpc-apple-netbsd${UNAME_RELEASE} + exit 0 ;; + RISC*:Mach:*:*) + echo mips-dec-mach_bsd4.3 + exit 0 ;; + RISC*:ULTRIX:*:*) + echo mips-dec-ultrix${UNAME_RELEASE} + exit 0 ;; + VAX*:ULTRIX*:*:*) + echo vax-dec-ultrix${UNAME_RELEASE} + exit 0 ;; + 2020:CLIX:*:*) + echo clipper-intergraph-clix${UNAME_RELEASE} + exit 0 ;; + mips:*:*:UMIPS | mips:*:*:RISCos) + sed 's/^ //' << EOF >$dummy.c +#ifdef __cplusplus + int main (int argc, char *argv[]) { +#else + int main (argc, argv) int argc; char *argv[]; { +#endif + #if defined (host_mips) && defined (MIPSEB) + #if defined (SYSTYPE_SYSV) + printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0); + #endif + #if defined (SYSTYPE_SVR4) + printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0); + #endif + #if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD) + printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0); + #endif + #endif + exit (-1); + } +EOF + ${CC-cc} $dummy.c -o $dummy \ + && ./$dummy `echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` \ + && rm $dummy.c $dummy && exit 0 + rm -f $dummy.c $dummy + echo mips-mips-riscos${UNAME_RELEASE} + exit 0 ;; + Night_Hawk:Power_UNIX:*:*) + echo powerpc-harris-powerunix + exit 0 ;; + m88k:CX/UX:7*:*) + echo m88k-harris-cxux7 + exit 0 ;; + m88k:*:4*:R4*) + echo m88k-motorola-sysv4 + exit 0 ;; + m88k:*:3*:R3*) + echo m88k-motorola-sysv3 + exit 0 ;; + AViiON:dgux:*:*) + # DG/UX returns AViiON for all architectures + UNAME_PROCESSOR=`/usr/bin/uname -p` + if [ $UNAME_PROCESSOR = mc88100 -o $UNAME_PROCESSOR = mc88110 ] ; then + if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx \ + -o ${TARGET_BINARY_INTERFACE}x = x ] ; then + echo m88k-dg-dgux${UNAME_RELEASE} + else + echo m88k-dg-dguxbcs${UNAME_RELEASE} + fi + else echo i586-dg-dgux${UNAME_RELEASE} + fi + exit 0 ;; + M88*:DolphinOS:*:*) # DolphinOS (SVR3) + echo m88k-dolphin-sysv3 + exit 0 ;; + M88*:*:R3*:*) + # Delta 88k system running SVR3 + echo m88k-motorola-sysv3 + exit 0 ;; + XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3) + echo m88k-tektronix-sysv3 + exit 0 ;; + Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD) + echo m68k-tektronix-bsd + exit 0 ;; + *:IRIX*:*:*) + echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'` + exit 0 ;; + ????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX. + echo romp-ibm-aix # uname -m gives an 8 hex-code CPU id + exit 0 ;; # Note that: echo "'`uname -s`'" gives 'AIX ' + i?86:AIX:*:*) + echo i386-ibm-aix + exit 0 ;; + *:AIX:2:3) + if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then + sed 's/^ //' << EOF >$dummy.c + #include + + main() + { + if (!__power_pc()) + exit(1); + puts("powerpc-ibm-aix3.2.5"); + exit(0); + } +EOF + ${CC-cc} $dummy.c -o $dummy && ./$dummy && rm $dummy.c $dummy && exit 0 + rm -f $dummy.c $dummy + echo rs6000-ibm-aix3.2.5 + elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then + echo rs6000-ibm-aix3.2.4 + else + echo rs6000-ibm-aix3.2 + fi + exit 0 ;; + *:AIX:*:4) + IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | head -1 | awk '{ print $1 }'` + if /usr/sbin/lsattr -EHl ${IBM_CPU_ID} | grep POWER >/dev/null 2>&1; then + IBM_ARCH=rs6000 + else + IBM_ARCH=powerpc + fi + if [ -x /usr/bin/oslevel ] ; then + IBM_REV=`/usr/bin/oslevel` + else + IBM_REV=4.${UNAME_RELEASE} + fi + echo ${IBM_ARCH}-ibm-aix${IBM_REV} + exit 0 ;; + *:AIX:*:*) + echo rs6000-ibm-aix + exit 0 ;; + ibmrt:4.4BSD:*|romp-ibm:BSD:*) + echo romp-ibm-bsd4.4 + exit 0 ;; + ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC NetBSD and + echo romp-ibm-bsd${UNAME_RELEASE} # 4.3 with uname added to + exit 0 ;; # report: romp-ibm BSD 4.3 + *:BOSX:*:*) + echo rs6000-bull-bosx + exit 0 ;; + DPX/2?00:B.O.S.:*:*) + echo m68k-bull-sysv3 + exit 0 ;; + 9000/[34]??:4.3bsd:1.*:*) + echo m68k-hp-bsd + exit 0 ;; + hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*) + echo m68k-hp-bsd4.4 + exit 0 ;; + 9000/[34678]??:HP-UX:*:*) + case "${UNAME_MACHINE}" in + 9000/31? ) HP_ARCH=m68000 ;; + 9000/[34]?? ) HP_ARCH=m68k ;; + 9000/6?? | 9000/7?? | 9000/80[024] | 9000/8?[136790] | 9000/892 ) + sed 's/^ //' << EOF >$dummy.c + #include + #include + + int main () + { + #if defined(_SC_KERNEL_BITS) + long bits = sysconf(_SC_KERNEL_BITS); + #endif + long cpu = sysconf (_SC_CPU_VERSION); + + switch (cpu) + { + case CPU_PA_RISC1_0: puts ("hppa1.0"); break; + case CPU_PA_RISC1_1: puts ("hppa1.1"); break; + case CPU_PA_RISC2_0: + #if defined(_SC_KERNEL_BITS) + switch (bits) + { + case 64: puts ("hppa2.0w"); break; + case 32: puts ("hppa2.0n"); break; + default: puts ("hppa2.0"); break; + } break; + #else /* !defined(_SC_KERNEL_BITS) */ + puts ("hppa2.0"); break; + #endif + default: puts ("hppa1.0"); break; + } + exit (0); + } +EOF + (${CC-cc} $dummy.c -o $dummy 2>/dev/null ) && HP_ARCH=`./$dummy` + rm -f $dummy.c $dummy + esac + HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` + echo ${HP_ARCH}-hp-hpux${HPUX_REV} + exit 0 ;; + 3050*:HI-UX:*:*) + sed 's/^ //' << EOF >$dummy.c + #include + int + main () + { + long cpu = sysconf (_SC_CPU_VERSION); + /* The order matters, because CPU_IS_HP_MC68K erroneously returns + true for CPU_PA_RISC1_0. CPU_IS_PA_RISC returns correct + results, however. */ + if (CPU_IS_PA_RISC (cpu)) + { + switch (cpu) + { + case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break; + case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break; + case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break; + default: puts ("hppa-hitachi-hiuxwe2"); break; + } + } + else if (CPU_IS_HP_MC68K (cpu)) + puts ("m68k-hitachi-hiuxwe2"); + else puts ("unknown-hitachi-hiuxwe2"); + exit (0); + } +EOF + ${CC-cc} $dummy.c -o $dummy && ./$dummy && rm $dummy.c $dummy && exit 0 + rm -f $dummy.c $dummy + echo unknown-hitachi-hiuxwe2 + exit 0 ;; + 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* ) + echo hppa1.1-hp-bsd + exit 0 ;; + 9000/8??:4.3bsd:*:*) + echo hppa1.0-hp-bsd + exit 0 ;; + *9??*:MPE*:*:*) + echo hppa1.0-hp-mpeix + exit 0 ;; + *9??*:MPE*:*:*) + echo hppa1.0-hp-mpeix + exit 0 ;; + hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* ) + echo hppa1.1-hp-osf + exit 0 ;; + hp8??:OSF1:*:*) + echo hppa1.0-hp-osf + exit 0 ;; + i?86:OSF1:*:*) + if [ -x /usr/sbin/sysversion ] ; then + echo ${UNAME_MACHINE}-unknown-osf1mk + else + echo ${UNAME_MACHINE}-unknown-osf1 + fi + exit 0 ;; + parisc*:Lites*:*:*) + echo hppa1.1-hp-lites + exit 0 ;; + C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*) + echo c1-convex-bsd + exit 0 ;; + C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*) + if getsysinfo -f scalar_acc + then echo c32-convex-bsd + else echo c2-convex-bsd + fi + exit 0 ;; + C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*) + echo c34-convex-bsd + exit 0 ;; + C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*) + echo c38-convex-bsd + exit 0 ;; + C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*) + echo c4-convex-bsd + exit 0 ;; + CRAY*X-MP:*:*:*) + echo xmp-cray-unicos + exit 0 ;; + CRAY*Y-MP:*:*:*) + echo ymp-cray-unicos${UNAME_RELEASE} + exit 0 ;; + CRAY*[A-Z]90:*:*:*) + echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \ + | sed -e 's/CRAY.*\([A-Z]90\)/\1/' \ + -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ + exit 0 ;; + CRAY*TS:*:*:*) + echo t90-cray-unicos${UNAME_RELEASE} + exit 0 ;; + CRAY*T3E:*:*:*) + echo t3e-cray-unicosmk${UNAME_RELEASE} + exit 0 ;; + CRAY-2:*:*:*) + echo cray2-cray-unicos + exit 0 ;; + F300:UNIX_System_V:*:*) + FUJITSU_SYS=`uname -p | tr [A-Z] [a-z] | sed -e 's/\///'` + FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'` + echo "f300-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" + exit 0 ;; + F301:UNIX_System_V:*:*) + echo f301-fujitsu-uxpv`echo $UNAME_RELEASE | sed 's/ .*//'` + exit 0 ;; + hp3[0-9][05]:NetBSD:*:*) + echo m68k-hp-netbsd${UNAME_RELEASE} + exit 0 ;; + hp300:OpenBSD:*:*) + echo m68k-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + sparc*:BSD/OS:*:*) + echo sparc-unknown-bsdi${UNAME_RELEASE} + exit 0 ;; + i?86:BSD/386:*:* | i?86:BSD/OS:*:*) + echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE} + exit 0 ;; + *:BSD/OS:*:*) + echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE} + exit 0 ;; + *:FreeBSD:*:*) + if test -x /usr/bin/objformat; then + if test "elf" = "`/usr/bin/objformat`"; then + echo ${UNAME_MACHINE}-unknown-freebsdelf`echo ${UNAME_RELEASE}|sed -e 's/[-_].*//'` + exit 0 + fi + fi + echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` + exit 0 ;; + *:NetBSD:*:*) + echo ${UNAME_MACHINE}-unknown-netbsd`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'` + exit 0 ;; + *:OpenBSD:*:*) + echo ${UNAME_MACHINE}-unknown-openbsd`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'` + exit 0 ;; + i*:CYGWIN*:*) + echo ${UNAME_MACHINE}-pc-cygwin + exit 0 ;; + i*:MINGW*:*) + echo ${UNAME_MACHINE}-pc-mingw32 + exit 0 ;; + p*:CYGWIN*:*) + echo powerpcle-unknown-cygwin + exit 0 ;; + prep*:SunOS:5.*:*) + echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit 0 ;; + *:GNU:*:*) + echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'` + exit 0 ;; + *:Linux:*:*) +# # uname on the ARM produces all sorts of strangeness, and we need to +# # filter it out. +# case "$UNAME_MACHINE" in +# armv*) UNAME_MACHINE=$UNAME_MACHINE ;; +# arm* | sa110*) UNAME_MACHINE="arm" ;; +# esac + + # The BFD linker knows what the default object file format is, so + # first see if it will tell us. + ld_help_string=`ld --help 2>&1` + ld_supported_emulations=`echo $ld_help_string \ + | sed -ne '/supported emulations:/!d + s/[ ][ ]*/ /g + s/.*supported emulations: *// + s/ .*// + p'` + case "$ld_supported_emulations" in + i?86linux) echo "${UNAME_MACHINE}-pc-linux-gnuaout" ; exit 0 ;; + i?86coff) echo "${UNAME_MACHINE}-pc-linux-gnucoff" ; exit 0 ;; + sparclinux) echo "${UNAME_MACHINE}-unknown-linux-gnuaout" ; exit 0 ;; + armlinux) echo "${UNAME_MACHINE}-unknown-linux-gnuaout" ; exit 0 ;; + m68klinux) echo "${UNAME_MACHINE}-unknown-linux-gnuaout" ; exit 0 ;; + elf32arm) echo "${UNAME_MACHINE}-unknown-linux-gnu" ; exit 0 ;; + elf32ppc) echo "powerpc-unknown-linux-gnu" ; exit 0 ;; + esac + + if test "${UNAME_MACHINE}" = "alpha" ; then + sed 's/^ //' <$dummy.s + .globl main + .ent main + main: + .frame \$30,0,\$26,0 + .prologue 0 + .long 0x47e03d80 # implver $0 + lda \$2,259 + .long 0x47e20c21 # amask $2,$1 + srl \$1,8,\$2 + sll \$2,2,\$2 + sll \$0,3,\$0 + addl \$1,\$0,\$0 + addl \$2,\$0,\$0 + ret \$31,(\$26),1 + .end main +EOF + LIBC="" + ${CC-cc} $dummy.s -o $dummy 2>/dev/null + if test "$?" = 0 ; then + ./$dummy + case "$?" in + 7) + UNAME_MACHINE="alpha" + ;; + 15) + UNAME_MACHINE="alphaev5" + ;; + 14) + UNAME_MACHINE="alphaev56" + ;; + 10) + UNAME_MACHINE="alphapca56" + ;; + 16) + UNAME_MACHINE="alphaev6" + ;; + esac + + objdump --private-headers $dummy | \ + grep ld.so.1 > /dev/null + if test "$?" = 0 ; then + LIBC="libc1" + fi + fi + rm -f $dummy.s $dummy + echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC} ; exit 0 + elif test "${UNAME_MACHINE}" = "mips" ; then + cat >$dummy.c </dev/null && ./$dummy "${UNAME_MACHINE}" && rm $dummy.c $dummy && exit 0 + rm -f $dummy.c $dummy + else + # Either a pre-BFD a.out linker (linux-gnuoldld) + # or one that does not give us useful --help. + # GCC wants to distinguish between linux-gnuoldld and linux-gnuaout. + # If ld does not provide *any* "supported emulations:" + # that means it is gnuoldld. + echo "$ld_help_string" | grep >/dev/null 2>&1 "supported emulations:" + test $? != 0 && echo "${UNAME_MACHINE}-pc-linux-gnuoldld" && exit 0 + + case "${UNAME_MACHINE}" in + i?86) + VENDOR=pc; + ;; + *) + VENDOR=unknown; + ;; + esac + # Determine whether the default compiler is a.out or elf + cat >$dummy.c < +#ifdef __cplusplus + int main (int argc, char *argv[]) { +#else + int main (argc, argv) int argc; char *argv[]; { +#endif +#ifdef __ELF__ +# ifdef __GLIBC__ +# if __GLIBC__ >= 2 + printf ("%s-${VENDOR}-linux-gnu\n", argv[1]); +# else + printf ("%s-${VENDOR}-linux-gnulibc1\n", argv[1]); +# endif +# else + printf ("%s-${VENDOR}-linux-gnulibc1\n", argv[1]); +# endif +#else + printf ("%s-${VENDOR}-linux-gnuaout\n", argv[1]); +#endif + return 0; +} +EOF + ${CC-cc} $dummy.c -o $dummy 2>/dev/null && ./$dummy "${UNAME_MACHINE}" && rm $dummy.c $dummy && exit 0 + rm -f $dummy.c $dummy + fi ;; +# ptx 4.0 does uname -s correctly, with DYNIX/ptx in there. earlier versions +# are messed up and put the nodename in both sysname and nodename. + i?86:DYNIX/ptx:4*:*) + echo i386-sequent-sysv4 + exit 0 ;; + i?86:UNIX_SV:4.2MP:2.*) + # Unixware is an offshoot of SVR4, but it has its own version + # number series starting with 2... + # I am not positive that other SVR4 systems won't match this, + # I just have to hope. -- rms. + # Use sysv4.2uw... so that sysv4* matches it. + echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION} + exit 0 ;; + i?86:*:4.*:* | i?86:SYSTEM_V:4.*:*) + if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then + echo ${UNAME_MACHINE}-univel-sysv${UNAME_RELEASE} + else + echo ${UNAME_MACHINE}-pc-sysv${UNAME_RELEASE} + fi + exit 0 ;; + i?86:*:3.2:*) + if test -f /usr/options/cb.name; then + UNAME_REL=`sed -n 's/.*Version //p' /dev/null >/dev/null ; then + UNAME_REL=`(/bin/uname -X|egrep Release|sed -e 's/.*= //')` + (/bin/uname -X|egrep i80486 >/dev/null) && UNAME_MACHINE=i486 + (/bin/uname -X|egrep '^Machine.*Pentium' >/dev/null) \ + && UNAME_MACHINE=i586 + echo ${UNAME_MACHINE}-pc-sco$UNAME_REL + else + echo ${UNAME_MACHINE}-pc-sysv32 + fi + exit 0 ;; + i?86:UnixWare:*:*) + if /bin/uname -X 2>/dev/null >/dev/null ; then + (/bin/uname -X|egrep '^Machine.*Pentium' >/dev/null) \ + && UNAME_MACHINE=i586 + fi + echo ${UNAME_MACHINE}-unixware-${UNAME_RELEASE}-${UNAME_VERSION} + exit 0 ;; + pc:*:*:*) + # uname -m prints for DJGPP always 'pc', but it prints nothing about + # the processor, so we play safe by assuming i386. + echo i386-pc-msdosdjgpp + exit 0 ;; + Intel:Mach:3*:*) + echo i386-pc-mach3 + exit 0 ;; + paragon:*:*:*) + echo i860-intel-osf1 + exit 0 ;; + i860:*:4.*:*) # i860-SVR4 + if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then + echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4 + else # Add other i860-SVR4 vendors below as they are discovered. + echo i860-unknown-sysv${UNAME_RELEASE} # Unknown i860-SVR4 + fi + exit 0 ;; + mini*:CTIX:SYS*5:*) + # "miniframe" + echo m68010-convergent-sysv + exit 0 ;; + M68*:*:R3V[567]*:*) + test -r /sysV68 && echo 'm68k-motorola-sysv' && exit 0 ;; + 3[34]??:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 4850:*:4.0:3.0) + OS_REL='' + test -r /etc/.relid \ + && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` + /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ + && echo i486-ncr-sysv4.3${OS_REL} && exit 0 + /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ + && echo i586-ncr-sysv4.3${OS_REL} && exit 0 ;; + 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*) + /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ + && echo i486-ncr-sysv4 && exit 0 ;; + m68*:LynxOS:2.*:*) + echo m68k-unknown-lynxos${UNAME_RELEASE} + exit 0 ;; + mc68030:UNIX_System_V:4.*:*) + echo m68k-atari-sysv4 + exit 0 ;; + i?86:LynxOS:2.*:* | i?86:LynxOS:3.[01]*:*) + echo i386-unknown-lynxos${UNAME_RELEASE} + exit 0 ;; + TSUNAMI:LynxOS:2.*:*) + echo sparc-unknown-lynxos${UNAME_RELEASE} + exit 0 ;; + rs6000:LynxOS:2.*:* | PowerPC:LynxOS:2.*:*) + echo rs6000-unknown-lynxos${UNAME_RELEASE} + exit 0 ;; + SM[BE]S:UNIX_SV:*:*) + echo mips-dde-sysv${UNAME_RELEASE} + exit 0 ;; + RM*:ReliantUNIX-*:*:*) + echo mips-sni-sysv4 + exit 0 ;; + RM*:SINIX-*:*:*) + echo mips-sni-sysv4 + exit 0 ;; + *:SINIX-*:*:*) + if uname -p 2>/dev/null >/dev/null ; then + UNAME_MACHINE=`(uname -p) 2>/dev/null` + echo ${UNAME_MACHINE}-sni-sysv4 + else + echo ns32k-sni-sysv + fi + exit 0 ;; + PENTIUM:CPunix:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort + # says + echo i586-unisys-sysv4 + exit 0 ;; + *:UNIX_System_V:4*:FTX*) + # From Gerald Hewes . + # How about differentiating between stratus architectures? -djm + echo hppa1.1-stratus-sysv4 + exit 0 ;; + *:*:*:FTX*) + # From seanf@swdc.stratus.com. + echo i860-stratus-sysv4 + exit 0 ;; + mc68*:A/UX:*:*) + echo m68k-apple-aux${UNAME_RELEASE} + exit 0 ;; + news*:NEWS-OS:*:6*) + echo mips-sony-newsos6 + exit 0 ;; + R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R4000:UNIX_SV:*:*) + if [ -d /usr/nec ]; then + echo mips-nec-sysv${UNAME_RELEASE} + else + echo mips-unknown-sysv${UNAME_RELEASE} + fi + exit 0 ;; + BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only. + echo powerpc-be-beos + exit 0 ;; + BeMac:BeOS:*:*) # BeOS running on Mac or Mac clone, PPC only. + echo powerpc-apple-beos + exit 0 ;; + BePC:BeOS:*:*) # BeOS running on Intel PC compatible. + echo i586-pc-beos + exit 0 ;; + SX-4:SUPER-UX:*:*) + echo sx4-nec-superux${UNAME_RELEASE} + exit 0 ;; + SX-5:SUPER-UX:*:*) + echo sx5-nec-superux${UNAME_RELEASE} + exit 0 ;; + Power*:Rhapsody:*:*) + echo powerpc-apple-rhapsody${UNAME_RELEASE} + exit 0 ;; + *:Rhapsody:*:*) + echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE} + exit 0 ;; +esac + +#echo '(No uname command or uname output not recognized.)' 1>&2 +#echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2 + +cat >$dummy.c < +# include +#endif +main () +{ +#if defined (sony) +#if defined (MIPSEB) + /* BFD wants "bsd" instead of "newsos". Perhaps BFD should be changed, + I don't know.... */ + printf ("mips-sony-bsd\n"); exit (0); +#else +#include + printf ("m68k-sony-newsos%s\n", +#ifdef NEWSOS4 + "4" +#else + "" +#endif + ); exit (0); +#endif +#endif + +#if defined (__arm) && defined (__acorn) && defined (__unix) + printf ("arm-acorn-riscix"); exit (0); +#endif + +#if defined (hp300) && !defined (hpux) + printf ("m68k-hp-bsd\n"); exit (0); +#endif + +#if defined (NeXT) +#if !defined (__ARCHITECTURE__) +#define __ARCHITECTURE__ "m68k" +#endif + int version; + version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`; + if (version < 4) + printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version); + else + printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version); + exit (0); +#endif + +#if defined (MULTIMAX) || defined (n16) +#if defined (UMAXV) + printf ("ns32k-encore-sysv\n"); exit (0); +#else +#if defined (CMU) + printf ("ns32k-encore-mach\n"); exit (0); +#else + printf ("ns32k-encore-bsd\n"); exit (0); +#endif +#endif +#endif + +#if defined (__386BSD__) + printf ("i386-pc-bsd\n"); exit (0); +#endif + +#if defined (sequent) +#if defined (i386) + printf ("i386-sequent-dynix\n"); exit (0); +#endif +#if defined (ns32000) + printf ("ns32k-sequent-dynix\n"); exit (0); +#endif +#endif + +#if defined (_SEQUENT_) + struct utsname un; + + uname(&un); + + if (strncmp(un.version, "V2", 2) == 0) { + printf ("i386-sequent-ptx2\n"); exit (0); + } + if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */ + printf ("i386-sequent-ptx1\n"); exit (0); + } + printf ("i386-sequent-ptx\n"); exit (0); + +#endif + +#if defined (vax) +#if !defined (ultrix) + printf ("vax-dec-bsd\n"); exit (0); +#else + printf ("vax-dec-ultrix\n"); exit (0); +#endif +#endif + +#if defined (alliant) && defined (i860) + printf ("i860-alliant-bsd\n"); exit (0); +#endif + + exit (1); +} +EOF + +${CC-cc} $dummy.c -o $dummy 2>/dev/null && ./$dummy && rm $dummy.c $dummy && exit 0 +rm -f $dummy.c $dummy + +# Apollos put the system type in the environment. + +test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit 0; } + +# Convex versions that predate uname can use getsysinfo(1) + +if [ -x /usr/convex/getsysinfo ] +then + case `getsysinfo -f cpu_type` in + c1*) + echo c1-convex-bsd + exit 0 ;; + c2*) + if getsysinfo -f scalar_acc + then echo c32-convex-bsd + else echo c2-convex-bsd + fi + exit 0 ;; + c34*) + echo c34-convex-bsd + exit 0 ;; + c38*) + echo c38-convex-bsd + exit 0 ;; + c4*) + echo c4-convex-bsd + exit 0 ;; + esac +fi + +#echo '(Unable to guess system type)' 1>&2 + +exit 1 diff --git a/contrib/other/sdlquake-1.0.9/config.sub b/contrib/other/sdlquake-1.0.9/config.sub new file mode 100644 index 000000000..ecf770cea --- /dev/null +++ b/contrib/other/sdlquake-1.0.9/config.sub @@ -0,0 +1,979 @@ +#! /bin/sh +# Configuration validation subroutine script, version 1.1. +# Copyright (C) 1991, 92-97, 1998 Free Software Foundation, Inc. +# This file is (in principle) common to ALL GNU software. +# The presence of a machine in this file suggests that SOME GNU software +# can handle that machine. It does not imply ALL GNU software can. +# +# This file is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public 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. + +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +# Configuration subroutine to validate and canonicalize a configuration type. +# Supply the specified configuration type as an argument. +# If it is invalid, we print an error message on stderr and exit with code 1. +# Otherwise, we print the canonical config type on stdout and succeed. + +# This file is supposed to be the same for all GNU packages +# and recognize all the CPU types, system types and aliases +# that are meaningful with *any* GNU software. +# Each package is responsible for reporting which valid configurations +# it does not support. The user should be able to distinguish +# a failure to support a valid configuration from a meaningless +# configuration. + +# The goal of this file is to map all the various variations of a given +# machine specification into a single specification in the form: +# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM +# or in some cases, the newer four-part form: +# CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM +# It is wrong to echo any other type of specification. + +if [ x$1 = x ] +then + echo Configuration name missing. 1>&2 + echo "Usage: $0 CPU-MFR-OPSYS" 1>&2 + echo "or $0 ALIAS" 1>&2 + echo where ALIAS is a recognized configuration type. 1>&2 + exit 1 +fi + +# First pass through any local machine types. +case $1 in + *local*) + echo $1 + exit 0 + ;; + *) + ;; +esac + +# Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any). +# Here we must recognize all the valid KERNEL-OS combinations. +maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'` +case $maybe_os in + linux-gnu*) + os=-$maybe_os + basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'` + ;; + *) + basic_machine=`echo $1 | sed 's/-[^-]*$//'` + if [ $basic_machine != $1 ] + then os=`echo $1 | sed 's/.*-/-/'` + else os=; fi + ;; +esac + +### Let's recognize common machines as not being operating systems so +### that things like config.sub decstation-3100 work. We also +### recognize some manufacturers as not being operating systems, so we +### can provide default operating systems below. +case $os in + -sun*os*) + # Prevent following clause from handling this invalid input. + ;; + -dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \ + -att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \ + -unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \ + -convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\ + -c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \ + -harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \ + -apple) + os= + basic_machine=$1 + ;; + -hiux*) + os=-hiuxwe2 + ;; + -sco5) + os=sco3.2v5 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco4) + os=-sco3.2v4 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco3.2.[4-9]*) + os=`echo $os | sed -e 's/sco3.2./sco3.2v/'` + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco3.2v[4-9]*) + # Don't forget version if it is 3.2v4 or newer. + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco*) + os=-sco3.2v2 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -isc) + os=-isc2.2 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -clix*) + basic_machine=clipper-intergraph + ;; + -isc*) + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -lynx*) + os=-lynxos + ;; + -ptx*) + basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'` + ;; + -windowsnt*) + os=`echo $os | sed -e 's/windowsnt/winnt/'` + ;; + -psos*) + os=-psos + ;; +esac + +# Decode aliases for certain CPU-COMPANY combinations. +case $basic_machine in + # Recognize the basic CPU types without company name. + # Some are omitted here because they have special meanings below. + tahoe | i860 | m32r | m68k | m68000 | m88k | ns32k | arc | arm \ + | arme[lb] | pyramid | mn10200 | mn10300 | tron | a29k \ + | 580 | i960 | h8300 | hppa | hppa1.0 | hppa1.1 | hppa2.0 \ + | hppa2.0w \ + | alpha | alphaev5 | alphaev56 | we32k | ns16k | clipper \ + | i370 | sh | powerpc | powerpcle | 1750a | dsp16xx | pdp11 \ + | mips64 | mipsel | mips64el | mips64orion | mips64orionel \ + | mipstx39 | mipstx39el | armv[34][lb] \ + | sparc | sparclet | sparclite | sparc64 | v850) + basic_machine=$basic_machine-unknown + ;; + # We use `pc' rather than `unknown' + # because (1) that's what they normally are, and + # (2) the word "unknown" tends to confuse beginning users. + i[34567]86) + basic_machine=$basic_machine-pc + ;; + # Object if more than one company name word. + *-*-*) + echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 + exit 1 + ;; + # Recognize the basic CPU types with company name. + vax-* | tahoe-* | i[34567]86-* | i860-* | m32r-* | m68k-* | m68000-* \ + | m88k-* | sparc-* | ns32k-* | fx80-* | arc-* | arm-* | c[123]* \ + | mips-* | pyramid-* | tron-* | a29k-* | romp-* | rs6000-* \ + | power-* | none-* | 580-* | cray2-* | h8300-* | i960-* \ + | xmp-* | ymp-* | hppa-* | hppa1.0-* | hppa1.1-* | hppa2.0-* \ + | hppa2.0w-* \ + | alpha-* | alphaev5-* | alphaev56-* | we32k-* | cydra-* \ + | ns16k-* | pn-* | np1-* | xps100-* | clipper-* | orion-* \ + | sparclite-* | pdp11-* | sh-* | powerpc-* | powerpcle-* \ + | sparc64-* | mips64-* | mipsel-* | armv[34][lb]-*\ + | mips64el-* | mips64orion-* | mips64orionel-* \ + | mipstx39-* | mipstx39el-* \ + | f301-* | armv*-*) + ;; + # Recognize the various machine names and aliases which stand + # for a CPU type and a company and sometimes even an OS. + 3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc) + basic_machine=m68000-att + ;; + 3b*) + basic_machine=we32k-att + ;; + alliant | fx80) + basic_machine=fx80-alliant + ;; + altos | altos3068) + basic_machine=m68k-altos + ;; + am29k) + basic_machine=a29k-none + os=-bsd + ;; + amdahl) + basic_machine=580-amdahl + os=-sysv + ;; + amiga | amiga-*) + basic_machine=m68k-cbm + ;; + amigaos | amigados) + basic_machine=m68k-cbm + os=-amigaos + ;; + amigaunix | amix) + basic_machine=m68k-cbm + os=-sysv4 + ;; + apollo68) + basic_machine=m68k-apollo + os=-sysv + ;; + aux) + basic_machine=m68k-apple + os=-aux + ;; + balance) + basic_machine=ns32k-sequent + os=-dynix + ;; + convex-c1) + basic_machine=c1-convex + os=-bsd + ;; + convex-c2) + basic_machine=c2-convex + os=-bsd + ;; + convex-c32) + basic_machine=c32-convex + os=-bsd + ;; + convex-c34) + basic_machine=c34-convex + os=-bsd + ;; + convex-c38) + basic_machine=c38-convex + os=-bsd + ;; + cray | ymp) + basic_machine=ymp-cray + os=-unicos + ;; + cray2) + basic_machine=cray2-cray + os=-unicos + ;; + [ctj]90-cray) + basic_machine=c90-cray + os=-unicos + ;; + crds | unos) + basic_machine=m68k-crds + ;; + da30 | da30-*) + basic_machine=m68k-da30 + ;; + decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn) + basic_machine=mips-dec + ;; + delta | 3300 | motorola-3300 | motorola-delta \ + | 3300-motorola | delta-motorola) + basic_machine=m68k-motorola + ;; + delta88) + basic_machine=m88k-motorola + os=-sysv3 + ;; + dpx20 | dpx20-*) + basic_machine=rs6000-bull + os=-bosx + ;; + dpx2* | dpx2*-bull) + basic_machine=m68k-bull + os=-sysv3 + ;; + ebmon29k) + basic_machine=a29k-amd + os=-ebmon + ;; + elxsi) + basic_machine=elxsi-elxsi + os=-bsd + ;; + encore | umax | mmax) + basic_machine=ns32k-encore + ;; + fx2800) + basic_machine=i860-alliant + ;; + genix) + basic_machine=ns32k-ns + ;; + gmicro) + basic_machine=tron-gmicro + os=-sysv + ;; + h3050r* | hiux*) + basic_machine=hppa1.1-hitachi + os=-hiuxwe2 + ;; + h8300hms) + basic_machine=h8300-hitachi + os=-hms + ;; + harris) + basic_machine=m88k-harris + os=-sysv3 + ;; + hp300-*) + basic_machine=m68k-hp + ;; + hp300bsd) + basic_machine=m68k-hp + os=-bsd + ;; + hp300hpux) + basic_machine=m68k-hp + os=-hpux + ;; + hp9k2[0-9][0-9] | hp9k31[0-9]) + basic_machine=m68000-hp + ;; + hp9k3[2-9][0-9]) + basic_machine=m68k-hp + ;; + hp9k7[0-9][0-9] | hp7[0-9][0-9] | hp9k8[0-9]7 | hp8[0-9]7) + basic_machine=hppa1.1-hp + ;; + hp9k8[0-9][0-9] | hp8[0-9][0-9]) + basic_machine=hppa1.0-hp + ;; + hppa-next) + os=-nextstep3 + ;; + hp3k9[0-9][0-9] | hp9[0-9][0-9]) + basic_machine=hppa1.0-hp + os=-mpeix + ;; + hp3k9[0-9][0-9] | hp9[0-9][0-9]) + basic_machine=hppa1.0-hp + os=-mpeix + ;; + i370-ibm* | ibm*) + basic_machine=i370-ibm + os=-mvs + ;; +# I'm not sure what "Sysv32" means. Should this be sysv3.2? + i[34567]86v32) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-sysv32 + ;; + i[34567]86v4*) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-sysv4 + ;; + i[34567]86v) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-sysv + ;; + i[34567]86sol2) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-solaris2 + ;; + iris | iris4d) + basic_machine=mips-sgi + case $os in + -irix*) + ;; + *) + os=-irix4 + ;; + esac + ;; + isi68 | isi) + basic_machine=m68k-isi + os=-sysv + ;; + m88k-omron*) + basic_machine=m88k-omron + ;; + magnum | m3230) + basic_machine=mips-mips + os=-sysv + ;; + merlin) + basic_machine=ns32k-utek + os=-sysv + ;; + miniframe) + basic_machine=m68000-convergent + ;; + mipsel*-linux*) + basic_machine=mipsel-unknown + os=-linux-gnu + ;; + mips*-linux*) + basic_machine=mips-unknown + os=-linux-gnu + ;; + mips3*-*) + basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'` + ;; + mips3*) + basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown + ;; + ncr3000) + basic_machine=i486-ncr + os=-sysv4 + ;; + netwinder) + basic_machine=armv4l-corel + os=-linux + ;; + news | news700 | news800 | news900) + basic_machine=m68k-sony + os=-newsos + ;; + news1000) + basic_machine=m68030-sony + os=-newsos + ;; + news-3600 | risc-news) + basic_machine=mips-sony + os=-newsos + ;; + next | m*-next ) + basic_machine=m68k-next + case $os in + -nextstep* ) + ;; + -ns2*) + os=-nextstep2 + ;; + *) + os=-nextstep3 + ;; + esac + ;; + nh3000) + basic_machine=m68k-harris + os=-cxux + ;; + nh[45]000) + basic_machine=m88k-harris + os=-cxux + ;; + nindy960) + basic_machine=i960-intel + os=-nindy + ;; + np1) + basic_machine=np1-gould + ;; + pa-hitachi) + basic_machine=hppa1.1-hitachi + os=-hiuxwe2 + ;; + paragon) + basic_machine=i860-intel + os=-osf + ;; + pbd) + basic_machine=sparc-tti + ;; + pbb) + basic_machine=m68k-tti + ;; + pc532 | pc532-*) + basic_machine=ns32k-pc532 + ;; + pentium | p5 | k5 | nexen) + basic_machine=i586-pc + ;; + pentiumpro | p6 | k6 | 6x86) + basic_machine=i686-pc + ;; + pentiumii | pentium2) + basic_machine=i786-pc + ;; + pentium-* | p5-* | k5-* | nexen-*) + basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentiumpro-* | p6-* | k6-* | 6x86-*) + basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentiumii-* | pentium2-*) + basic_machine=i786-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pn) + basic_machine=pn-gould + ;; + power) basic_machine=rs6000-ibm + ;; + ppc) basic_machine=powerpc-unknown + ;; + ppc-*) basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ppcle | powerpclittle | ppc-le | powerpc-little) + basic_machine=powerpcle-unknown + ;; + ppcle-* | powerpclittle-*) + basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ps2) + basic_machine=i386-ibm + ;; + rm[46]00) + basic_machine=mips-siemens + ;; + rtpc | rtpc-*) + basic_machine=romp-ibm + ;; + sequent) + basic_machine=i386-sequent + ;; + sh) + basic_machine=sh-hitachi + os=-hms + ;; + sps7) + basic_machine=m68k-bull + os=-sysv2 + ;; + spur) + basic_machine=spur-unknown + ;; + sun2) + basic_machine=m68000-sun + ;; + sun2os3) + basic_machine=m68000-sun + os=-sunos3 + ;; + sun2os4) + basic_machine=m68000-sun + os=-sunos4 + ;; + sun3os3) + basic_machine=m68k-sun + os=-sunos3 + ;; + sun3os4) + basic_machine=m68k-sun + os=-sunos4 + ;; + sun4os3) + basic_machine=sparc-sun + os=-sunos3 + ;; + sun4os4) + basic_machine=sparc-sun + os=-sunos4 + ;; + sun4sol2) + basic_machine=sparc-sun + os=-solaris2 + ;; + sun3 | sun3-*) + basic_machine=m68k-sun + ;; + sun4) + basic_machine=sparc-sun + ;; + sun386 | sun386i | roadrunner) + basic_machine=i386-sun + ;; + symmetry) + basic_machine=i386-sequent + os=-dynix + ;; + tx39) + basic_machine=mipstx39-unknown + ;; + tx39el) + basic_machine=mipstx39el-unknown + ;; + tower | tower-32) + basic_machine=m68k-ncr + ;; + udi29k) + basic_machine=a29k-amd + os=-udi + ;; + ultra3) + basic_machine=a29k-nyu + os=-sym1 + ;; + vaxv) + basic_machine=vax-dec + os=-sysv + ;; + vms) + basic_machine=vax-dec + os=-vms + ;; + vpp*|vx|vx-*) + basic_machine=f301-fujitsu + ;; + vxworks960) + basic_machine=i960-wrs + os=-vxworks + ;; + vxworks68) + basic_machine=m68k-wrs + os=-vxworks + ;; + vxworks29k) + basic_machine=a29k-wrs + os=-vxworks + ;; + xmp) + basic_machine=xmp-cray + os=-unicos + ;; + xps | xps100) + basic_machine=xps100-honeywell + ;; + none) + basic_machine=none-none + os=-none + ;; + +# Here we handle the default manufacturer of certain CPU types. It is in +# some cases the only manufacturer, in others, it is the most popular. + mips) + if [ x$os = x-linux-gnu ]; then + basic_machine=mips-unknown + else + basic_machine=mips-mips + fi + ;; + romp) + basic_machine=romp-ibm + ;; + rs6000) + basic_machine=rs6000-ibm + ;; + vax) + basic_machine=vax-dec + ;; + pdp11) + basic_machine=pdp11-dec + ;; + we32k) + basic_machine=we32k-att + ;; + sparc) + basic_machine=sparc-sun + ;; + cydra) + basic_machine=cydra-cydrome + ;; + orion) + basic_machine=orion-highlevel + ;; + orion105) + basic_machine=clipper-highlevel + ;; + *) + echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 + exit 1 + ;; +esac + +# Here we canonicalize certain aliases for manufacturers. +case $basic_machine in + *-digital*) + basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'` + ;; + *-commodore*) + basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'` + ;; + *) + ;; +esac + +# Decode manufacturer-specific aliases for certain operating systems. + +if [ x"$os" != x"" ] +then +case $os in + # First match some system type aliases + # that might get confused with valid system types. + # -solaris* is a basic system type, with this one exception. + -solaris1 | -solaris1.*) + os=`echo $os | sed -e 's|solaris1|sunos4|'` + ;; + -solaris) + os=-solaris2 + ;; + -svr4*) + os=-sysv4 + ;; + -unixware*) + os=-sysv4.2uw + ;; + -gnu/linux*) + os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'` + ;; + # First accept the basic system types. + # The portable systems comes first. + # Each alternative MUST END IN A *, to match a version number. + # -sysv* is not here because it comes later, after sysvr4. + -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \ + | -*vms* | -sco* | -esix* | -isc* | -aix* | -sunos | -sunos[34]*\ + | -hpux* | -unos* | -osf* | -luna* | -dgux* | -solaris* | -sym* \ + | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \ + | -aos* \ + | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \ + | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \ + | -hiux* | -386bsd* | -netbsd* | -openbsd* | -freebsd* | -riscix* \ + | -lynxos* | -bosx* | -nextstep* | -cxux* | -aout* | -elf* \ + | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \ + | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \ + | -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \ + | -mingw32* | -linux-gnu* | -uxpv* | -beos* | -rhapsody* \ + | -openstep* | -mpeix* | -oskit*) + # Remember, each alternative MUST END IN *, to match a version number. + ;; + -linux*) + os=`echo $os | sed -e 's|linux|linux-gnu|'` + ;; + -sunos5*) + os=`echo $os | sed -e 's|sunos5|solaris2|'` + ;; + -sunos6*) + os=`echo $os | sed -e 's|sunos6|solaris3|'` + ;; + -osfrose*) + os=-osfrose + ;; + -osf*) + os=-osf + ;; + -utek*) + os=-bsd + ;; + -dynix*) + os=-bsd + ;; + -acis*) + os=-aos + ;; + -ctix* | -uts*) + os=-sysv + ;; + -ns2 ) + os=-nextstep2 + ;; + # Preserve the version number of sinix5. + -sinix5.*) + os=`echo $os | sed -e 's|sinix|sysv|'` + ;; + -sinix*) + os=-sysv4 + ;; + -triton*) + os=-sysv3 + ;; + -oss*) + os=-sysv3 + ;; + -svr4) + os=-sysv4 + ;; + -svr3) + os=-sysv3 + ;; + -sysvr4) + os=-sysv4 + ;; + # This must come after -sysvr4. + -sysv*) + ;; + -xenix) + os=-xenix + ;; + -none) + ;; + *) + # Get rid of the `-' at the beginning of $os. + os=`echo $os | sed 's/[^-]*-//'` + echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2 + exit 1 + ;; +esac +else + +# Here we handle the default operating systems that come with various machines. +# The value should be what the vendor currently ships out the door with their +# machine or put another way, the most popular os provided with the machine. + +# Note that if you're going to try to match "-MANUFACTURER" here (say, +# "-sun"), then you have to tell the case statement up towards the top +# that MANUFACTURER isn't an operating system. Otherwise, code above +# will signal an error saying that MANUFACTURER isn't an operating +# system, and we'll never get to this point. + +case $basic_machine in + *-acorn) + os=-riscix1.2 + ;; + arm*-corel) + os=-linux + ;; + arm*-semi) + os=-aout + ;; + pdp11-*) + os=-none + ;; + *-dec | vax-*) + os=-ultrix4.2 + ;; + m68*-apollo) + os=-domain + ;; + i386-sun) + os=-sunos4.0.2 + ;; + m68000-sun) + os=-sunos3 + # This also exists in the configure program, but was not the + # default. + # os=-sunos4 + ;; + *-tti) # must be before sparc entry or we get the wrong os. + os=-sysv3 + ;; + sparc-* | *-sun) + os=-sunos4.1.1 + ;; + *-be) + os=-beos + ;; + *-ibm) + os=-aix + ;; + *-hp) + os=-hpux + ;; + *-hitachi) + os=-hiux + ;; + i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent) + os=-sysv + ;; + *-cbm) + os=-amigaos + ;; + *-dg) + os=-dgux + ;; + *-dolphin) + os=-sysv3 + ;; + m68k-ccur) + os=-rtu + ;; + m88k-omron*) + os=-luna + ;; + *-next ) + os=-nextstep + ;; + *-sequent) + os=-ptx + ;; + *-crds) + os=-unos + ;; + *-ns) + os=-genix + ;; + i370-*) + os=-mvs + ;; + *-next) + os=-nextstep3 + ;; + *-gould) + os=-sysv + ;; + *-highlevel) + os=-bsd + ;; + *-encore) + os=-bsd + ;; + *-sgi) + os=-irix + ;; + *-siemens) + os=-sysv4 + ;; + *-masscomp) + os=-rtu + ;; + f301-fujitsu) + os=-uxpv + ;; + *) + os=-none + ;; +esac +fi + +# Here we handle the case where we know the os, and the CPU type, but not the +# manufacturer. We pick the logical manufacturer. +vendor=unknown +case $basic_machine in + *-unknown) + case $os in + -riscix*) + vendor=acorn + ;; + -sunos*) + vendor=sun + ;; + -aix*) + vendor=ibm + ;; + -hpux*) + vendor=hp + ;; + -mpeix*) + vendor=hp + ;; + -mpeix*) + vendor=hp + ;; + -hiux*) + vendor=hitachi + ;; + -unos*) + vendor=crds + ;; + -dgux*) + vendor=dg + ;; + -luna*) + vendor=omron + ;; + -genix*) + vendor=ns + ;; + -mvs*) + vendor=ibm + ;; + -ptx*) + vendor=sequent + ;; + -vxsim* | -vxworks*) + vendor=wrs + ;; + -aux*) + vendor=apple + ;; + esac + basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"` + ;; +esac + +echo $basic_machine$os diff --git a/contrib/other/sdlquake-1.0.9/configure b/contrib/other/sdlquake-1.0.9/configure new file mode 100644 index 000000000..e9c6b92fe --- /dev/null +++ b/contrib/other/sdlquake-1.0.9/configure @@ -0,0 +1,1745 @@ +#! /bin/sh + +# Guess values for system-dependent variables and create Makefiles. +# Generated automatically using autoconf version 2.13 +# Copyright (C) 1992, 93, 94, 95, 96 Free Software Foundation, Inc. +# +# This configure script is free software; the Free Software Foundation +# gives unlimited permission to copy, distribute and modify it. + +# Defaults: +ac_help= +ac_default_prefix=/usr/local +# Any additions from configure.in: +ac_help="$ac_help + --with-sdl-prefix=PFX Prefix where SDL is installed (optional)" +ac_help="$ac_help + --with-sdl-exec-prefix=PFX Exec prefix where SDL is installed (optional)" +ac_help="$ac_help + --disable-sdltest Do not try to compile and run a test SDL program" +ac_help="$ac_help + --enable-asm enable i686 assembly routines [default=no]" + +# Initialize some variables set by options. +# The variables have the same names as the options, with +# dashes changed to underlines. +build=NONE +cache_file=./config.cache +exec_prefix=NONE +host=NONE +no_create= +nonopt=NONE +no_recursion= +prefix=NONE +program_prefix=NONE +program_suffix=NONE +program_transform_name=s,x,x, +silent= +site= +srcdir= +target=NONE +verbose= +x_includes=NONE +x_libraries=NONE +bindir='${exec_prefix}/bin' +sbindir='${exec_prefix}/sbin' +libexecdir='${exec_prefix}/libexec' +datadir='${prefix}/share' +sysconfdir='${prefix}/etc' +sharedstatedir='${prefix}/com' +localstatedir='${prefix}/var' +libdir='${exec_prefix}/lib' +includedir='${prefix}/include' +oldincludedir='/usr/include' +infodir='${prefix}/info' +mandir='${prefix}/man' + +# Initialize some other variables. +subdirs= +MFLAGS= MAKEFLAGS= +SHELL=${CONFIG_SHELL-/bin/sh} +# Maximum number of lines to put in a shell here document. +ac_max_here_lines=12 + +ac_prev= +for ac_option +do + + # If the previous option needs an argument, assign it. + if test -n "$ac_prev"; then + eval "$ac_prev=\$ac_option" + ac_prev= + continue + fi + + case "$ac_option" in + -*=*) ac_optarg=`echo "$ac_option" | sed 's/[-_a-zA-Z0-9]*=//'` ;; + *) ac_optarg= ;; + esac + + # Accept the important Cygnus configure options, so we can diagnose typos. + + case "$ac_option" in + + -bindir | --bindir | --bindi | --bind | --bin | --bi) + ac_prev=bindir ;; + -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) + bindir="$ac_optarg" ;; + + -build | --build | --buil | --bui | --bu) + ac_prev=build ;; + -build=* | --build=* | --buil=* | --bui=* | --bu=*) + build="$ac_optarg" ;; + + -cache-file | --cache-file | --cache-fil | --cache-fi \ + | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) + ac_prev=cache_file ;; + -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ + | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) + cache_file="$ac_optarg" ;; + + -datadir | --datadir | --datadi | --datad | --data | --dat | --da) + ac_prev=datadir ;; + -datadir=* | --datadir=* | --datadi=* | --datad=* | --data=* | --dat=* \ + | --da=*) + datadir="$ac_optarg" ;; + + -disable-* | --disable-*) + ac_feature=`echo $ac_option|sed -e 's/-*disable-//'` + # Reject names that are not valid shell variable names. + if test -n "`echo $ac_feature| sed 's/[-a-zA-Z0-9_]//g'`"; then + { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; } + fi + ac_feature=`echo $ac_feature| sed 's/-/_/g'` + eval "enable_${ac_feature}=no" ;; + + -enable-* | --enable-*) + ac_feature=`echo $ac_option|sed -e 's/-*enable-//' -e 's/=.*//'` + # Reject names that are not valid shell variable names. + if test -n "`echo $ac_feature| sed 's/[-_a-zA-Z0-9]//g'`"; then + { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; } + fi + ac_feature=`echo $ac_feature| sed 's/-/_/g'` + case "$ac_option" in + *=*) ;; + *) ac_optarg=yes ;; + esac + eval "enable_${ac_feature}='$ac_optarg'" ;; + + -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ + | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ + | --exec | --exe | --ex) + ac_prev=exec_prefix ;; + -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ + | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ + | --exec=* | --exe=* | --ex=*) + exec_prefix="$ac_optarg" ;; + + -gas | --gas | --ga | --g) + # Obsolete; use --with-gas. + with_gas=yes ;; + + -help | --help | --hel | --he) + # Omit some internal or obsolete options to make the list less imposing. + # This message is too long to be a string in the A/UX 3.1 sh. + cat << EOF +Usage: configure [options] [host] +Options: [defaults in brackets after descriptions] +Configuration: + --cache-file=FILE cache test results in FILE + --help print this message + --no-create do not create output files + --quiet, --silent do not print \`checking...' messages + --version print the version of autoconf that created configure +Directory and file names: + --prefix=PREFIX install architecture-independent files in PREFIX + [$ac_default_prefix] + --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX + [same as prefix] + --bindir=DIR user executables in DIR [EPREFIX/bin] + --sbindir=DIR system admin executables in DIR [EPREFIX/sbin] + --libexecdir=DIR program executables in DIR [EPREFIX/libexec] + --datadir=DIR read-only architecture-independent data in DIR + [PREFIX/share] + --sysconfdir=DIR read-only single-machine data in DIR [PREFIX/etc] + --sharedstatedir=DIR modifiable architecture-independent data in DIR + [PREFIX/com] + --localstatedir=DIR modifiable single-machine data in DIR [PREFIX/var] + --libdir=DIR object code libraries in DIR [EPREFIX/lib] + --includedir=DIR C header files in DIR [PREFIX/include] + --oldincludedir=DIR C header files for non-gcc in DIR [/usr/include] + --infodir=DIR info documentation in DIR [PREFIX/info] + --mandir=DIR man documentation in DIR [PREFIX/man] + --srcdir=DIR find the sources in DIR [configure dir or ..] + --program-prefix=PREFIX prepend PREFIX to installed program names + --program-suffix=SUFFIX append SUFFIX to installed program names + --program-transform-name=PROGRAM + run sed PROGRAM on installed program names +EOF + cat << EOF +Host type: + --build=BUILD configure for building on BUILD [BUILD=HOST] + --host=HOST configure for HOST [guessed] + --target=TARGET configure for TARGET [TARGET=HOST] +Features and packages: + --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) + --enable-FEATURE[=ARG] include FEATURE [ARG=yes] + --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] + --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) + --x-includes=DIR X include files are in DIR + --x-libraries=DIR X library files are in DIR +EOF + if test -n "$ac_help"; then + echo "--enable and --with options recognized:$ac_help" + fi + exit 0 ;; + + -host | --host | --hos | --ho) + ac_prev=host ;; + -host=* | --host=* | --hos=* | --ho=*) + host="$ac_optarg" ;; + + -includedir | --includedir | --includedi | --included | --include \ + | --includ | --inclu | --incl | --inc) + ac_prev=includedir ;; + -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ + | --includ=* | --inclu=* | --incl=* | --inc=*) + includedir="$ac_optarg" ;; + + -infodir | --infodir | --infodi | --infod | --info | --inf) + ac_prev=infodir ;; + -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) + infodir="$ac_optarg" ;; + + -libdir | --libdir | --libdi | --libd) + ac_prev=libdir ;; + -libdir=* | --libdir=* | --libdi=* | --libd=*) + libdir="$ac_optarg" ;; + + -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ + | --libexe | --libex | --libe) + ac_prev=libexecdir ;; + -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ + | --libexe=* | --libex=* | --libe=*) + libexecdir="$ac_optarg" ;; + + -localstatedir | --localstatedir | --localstatedi | --localstated \ + | --localstate | --localstat | --localsta | --localst \ + | --locals | --local | --loca | --loc | --lo) + ac_prev=localstatedir ;; + -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ + | --localstate=* | --localstat=* | --localsta=* | --localst=* \ + | --locals=* | --local=* | --loca=* | --loc=* | --lo=*) + localstatedir="$ac_optarg" ;; + + -mandir | --mandir | --mandi | --mand | --man | --ma | --m) + ac_prev=mandir ;; + -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) + mandir="$ac_optarg" ;; + + -nfp | --nfp | --nf) + # Obsolete; use --without-fp. + with_fp=no ;; + + -no-create | --no-create | --no-creat | --no-crea | --no-cre \ + | --no-cr | --no-c) + no_create=yes ;; + + -no-recursion | --no-recursion | --no-recursio | --no-recursi \ + | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) + no_recursion=yes ;; + + -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \ + | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \ + | --oldin | --oldi | --old | --ol | --o) + ac_prev=oldincludedir ;; + -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ + | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ + | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) + oldincludedir="$ac_optarg" ;; + + -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) + ac_prev=prefix ;; + -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) + prefix="$ac_optarg" ;; + + -program-prefix | --program-prefix | --program-prefi | --program-pref \ + | --program-pre | --program-pr | --program-p) + ac_prev=program_prefix ;; + -program-prefix=* | --program-prefix=* | --program-prefi=* \ + | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) + program_prefix="$ac_optarg" ;; + + -program-suffix | --program-suffix | --program-suffi | --program-suff \ + | --program-suf | --program-su | --program-s) + ac_prev=program_suffix ;; + -program-suffix=* | --program-suffix=* | --program-suffi=* \ + | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) + program_suffix="$ac_optarg" ;; + + -program-transform-name | --program-transform-name \ + | --program-transform-nam | --program-transform-na \ + | --program-transform-n | --program-transform- \ + | --program-transform | --program-transfor \ + | --program-transfo | --program-transf \ + | --program-trans | --program-tran \ + | --progr-tra | --program-tr | --program-t) + ac_prev=program_transform_name ;; + -program-transform-name=* | --program-transform-name=* \ + | --program-transform-nam=* | --program-transform-na=* \ + | --program-transform-n=* | --program-transform-=* \ + | --program-transform=* | --program-transfor=* \ + | --program-transfo=* | --program-transf=* \ + | --program-trans=* | --program-tran=* \ + | --progr-tra=* | --program-tr=* | --program-t=*) + program_transform_name="$ac_optarg" ;; + + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil) + silent=yes ;; + + -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) + ac_prev=sbindir ;; + -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ + | --sbi=* | --sb=*) + sbindir="$ac_optarg" ;; + + -sharedstatedir | --sharedstatedir | --sharedstatedi \ + | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ + | --sharedst | --shareds | --shared | --share | --shar \ + | --sha | --sh) + ac_prev=sharedstatedir ;; + -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ + | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ + | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ + | --sha=* | --sh=*) + sharedstatedir="$ac_optarg" ;; + + -site | --site | --sit) + ac_prev=site ;; + -site=* | --site=* | --sit=*) + site="$ac_optarg" ;; + + -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) + ac_prev=srcdir ;; + -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) + srcdir="$ac_optarg" ;; + + -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ + | --syscon | --sysco | --sysc | --sys | --sy) + ac_prev=sysconfdir ;; + -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ + | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) + sysconfdir="$ac_optarg" ;; + + -target | --target | --targe | --targ | --tar | --ta | --t) + ac_prev=target ;; + -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) + target="$ac_optarg" ;; + + -v | -verbose | --verbose | --verbos | --verbo | --verb) + verbose=yes ;; + + -version | --version | --versio | --versi | --vers) + echo "configure generated by autoconf version 2.13" + exit 0 ;; + + -with-* | --with-*) + ac_package=`echo $ac_option|sed -e 's/-*with-//' -e 's/=.*//'` + # Reject names that are not valid shell variable names. + if test -n "`echo $ac_package| sed 's/[-_a-zA-Z0-9]//g'`"; then + { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; } + fi + ac_package=`echo $ac_package| sed 's/-/_/g'` + case "$ac_option" in + *=*) ;; + *) ac_optarg=yes ;; + esac + eval "with_${ac_package}='$ac_optarg'" ;; + + -without-* | --without-*) + ac_package=`echo $ac_option|sed -e 's/-*without-//'` + # Reject names that are not valid shell variable names. + if test -n "`echo $ac_package| sed 's/[-a-zA-Z0-9_]//g'`"; then + { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; } + fi + ac_package=`echo $ac_package| sed 's/-/_/g'` + eval "with_${ac_package}=no" ;; + + --x) + # Obsolete; use --with-x. + with_x=yes ;; + + -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ + | --x-incl | --x-inc | --x-in | --x-i) + ac_prev=x_includes ;; + -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ + | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) + x_includes="$ac_optarg" ;; + + -x-libraries | --x-libraries | --x-librarie | --x-librari \ + | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) + ac_prev=x_libraries ;; + -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ + | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) + x_libraries="$ac_optarg" ;; + + -*) { echo "configure: error: $ac_option: invalid option; use --help to show usage" 1>&2; exit 1; } + ;; + + *) + if test -n "`echo $ac_option| sed 's/[-a-z0-9.]//g'`"; then + echo "configure: warning: $ac_option: invalid host type" 1>&2 + fi + if test "x$nonopt" != xNONE; then + { echo "configure: error: can only configure for one host and one target at a time" 1>&2; exit 1; } + fi + nonopt="$ac_option" + ;; + + esac +done + +if test -n "$ac_prev"; then + { echo "configure: error: missing argument to --`echo $ac_prev | sed 's/_/-/g'`" 1>&2; exit 1; } +fi + +trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15 + +# File descriptor usage: +# 0 standard input +# 1 file creation +# 2 errors and warnings +# 3 some systems may open it to /dev/tty +# 4 used on the Kubota Titan +# 6 checking for... messages and results +# 5 compiler messages saved in config.log +if test "$silent" = yes; then + exec 6>/dev/null +else + exec 6>&1 +fi +exec 5>./config.log + +echo "\ +This file contains any messages produced by compilers while +running configure, to aid debugging if configure makes a mistake. +" 1>&5 + +# Strip out --no-create and --no-recursion so they do not pile up. +# Also quote any args containing shell metacharacters. +ac_configure_args= +for ac_arg +do + case "$ac_arg" in + -no-create | --no-create | --no-creat | --no-crea | --no-cre \ + | --no-cr | --no-c) ;; + -no-recursion | --no-recursion | --no-recursio | --no-recursi \ + | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) ;; + *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?]*) + ac_configure_args="$ac_configure_args '$ac_arg'" ;; + *) ac_configure_args="$ac_configure_args $ac_arg" ;; + esac +done + +# NLS nuisances. +# Only set these to C if already set. These must not be set unconditionally +# because not all systems understand e.g. LANG=C (notably SCO). +# Fixing LC_MESSAGES prevents Solaris sh from translating var values in `set'! +# Non-C LC_CTYPE values break the ctype check. +if test "${LANG+set}" = set; then LANG=C; export LANG; fi +if test "${LC_ALL+set}" = set; then LC_ALL=C; export LC_ALL; fi +if test "${LC_MESSAGES+set}" = set; then LC_MESSAGES=C; export LC_MESSAGES; fi +if test "${LC_CTYPE+set}" = set; then LC_CTYPE=C; export LC_CTYPE; fi + +# confdefs.h avoids OS command line length limits that DEFS can exceed. +rm -rf conftest* confdefs.h +# AIX cpp loses on an empty file, so make sure it contains at least a newline. +echo > confdefs.h + +# A filename unique to this package, relative to the directory that +# configure is in, which we can look for to find out if srcdir is correct. +ac_unique_file=README.SDL + +# Find the source files, if location was not specified. +if test -z "$srcdir"; then + ac_srcdir_defaulted=yes + # Try the directory containing this script, then its parent. + ac_prog=$0 + ac_confdir=`echo $ac_prog|sed 's%/[^/][^/]*$%%'` + test "x$ac_confdir" = "x$ac_prog" && ac_confdir=. + srcdir=$ac_confdir + if test ! -r $srcdir/$ac_unique_file; then + srcdir=.. + fi +else + ac_srcdir_defaulted=no +fi +if test ! -r $srcdir/$ac_unique_file; then + if test "$ac_srcdir_defaulted" = yes; then + { echo "configure: error: can not find sources in $ac_confdir or .." 1>&2; exit 1; } + else + { echo "configure: error: can not find sources in $srcdir" 1>&2; exit 1; } + fi +fi +srcdir=`echo "${srcdir}" | sed 's%\([^/]\)/*$%\1%'` + +# Prefer explicitly selected file to automatically selected ones. +if test -z "$CONFIG_SITE"; then + if test "x$prefix" != xNONE; then + CONFIG_SITE="$prefix/share/config.site $prefix/etc/config.site" + else + CONFIG_SITE="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site" + fi +fi +for ac_site_file in $CONFIG_SITE; do + if test -r "$ac_site_file"; then + echo "loading site script $ac_site_file" + . "$ac_site_file" + fi +done + +if test -r "$cache_file"; then + echo "loading cache $cache_file" + . $cache_file +else + echo "creating cache $cache_file" + > $cache_file +fi + +ac_ext=c +# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. +ac_cpp='$CPP $CPPFLAGS' +ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5' +ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5' +cross_compiling=$ac_cv_prog_cc_cross + +ac_exeext= +ac_objext=o +if (echo "testing\c"; echo 1,2,3) | grep c >/dev/null; then + # Stardent Vistra SVR4 grep lacks -e, says ghazi@caip.rutgers.edu. + if (echo -n testing; echo 1,2,3) | sed s/-n/xn/ | grep xn >/dev/null; then + ac_n= ac_c=' +' ac_t=' ' + else + ac_n=-n ac_c= ac_t= + fi +else + ac_n= ac_c='\c' ac_t= +fi + + + +ac_aux_dir= +for ac_dir in $srcdir $srcdir/.. $srcdir/../..; do + if test -f $ac_dir/install-sh; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/install-sh -c" + break + elif test -f $ac_dir/install.sh; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/install.sh -c" + break + fi +done +if test -z "$ac_aux_dir"; then + { echo "configure: error: can not find install-sh or install.sh in $srcdir $srcdir/.. $srcdir/../.." 1>&2; exit 1; } +fi +ac_config_guess=$ac_aux_dir/config.guess +ac_config_sub=$ac_aux_dir/config.sub +ac_configure=$ac_aux_dir/configure # This should be Cygnus configure. + +# Find a good install program. We prefer a C program (faster), +# so one script is as good as another. But avoid the broken or +# incompatible versions: +# SysV /etc/install, /usr/sbin/install +# SunOS /usr/etc/install +# IRIX /sbin/install +# AIX /bin/install +# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag +# AFS /usr/afsws/bin/install, which mishandles nonexistent args +# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" +# ./install, which can be erroneously created by make from ./install.sh. +echo $ac_n "checking for a BSD compatible install""... $ac_c" 1>&6 +echo "configure:565: checking for a BSD compatible install" >&5 +if test -z "$INSTALL"; then +if eval "test \"`echo '$''{'ac_cv_path_install'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + IFS="${IFS= }"; ac_save_IFS="$IFS"; IFS=":" + for ac_dir in $PATH; do + # Account for people who put trailing slashes in PATH elements. + case "$ac_dir/" in + /|./|.//|/etc/*|/usr/sbin/*|/usr/etc/*|/sbin/*|/usr/afsws/bin/*|/usr/ucb/*) ;; + *) + # OSF1 and SCO ODT 3.0 have their own names for install. + # Don't use installbsd from OSF since it installs stuff as root + # by default. + for ac_prog in ginstall scoinst install; do + if test -f $ac_dir/$ac_prog; then + if test $ac_prog = install && + grep dspmsg $ac_dir/$ac_prog >/dev/null 2>&1; then + # AIX install. It has an incompatible calling convention. + : + else + ac_cv_path_install="$ac_dir/$ac_prog -c" + break 2 + fi + fi + done + ;; + esac + done + IFS="$ac_save_IFS" + +fi + if test "${ac_cv_path_install+set}" = set; then + INSTALL="$ac_cv_path_install" + else + # As a last resort, use the slow shell script. We don't cache a + # path for INSTALL within a source directory, because that will + # break other packages using the cache if that directory is + # removed, or if the path is relative. + INSTALL="$ac_install_sh" + fi +fi +echo "$ac_t""$INSTALL" 1>&6 + +# Use test -z because SunOS4 sh mishandles braces in ${var-val}. +# It thinks the first close brace ends the variable substitution. +test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}' + +test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL_PROGRAM}' + +test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' + +echo $ac_n "checking whether build environment is sane""... $ac_c" 1>&6 +echo "configure:618: checking whether build environment is sane" >&5 +# Just in case +sleep 1 +echo timestamp > conftestfile +# Do `set' in a subshell so we don't clobber the current shell's +# arguments. Must try -L first in case configure is actually a +# symlink; some systems play weird games with the mod time of symlinks +# (eg FreeBSD returns the mod time of the symlink's containing +# directory). +if ( + set X `ls -Lt $srcdir/configure conftestfile 2> /dev/null` + if test "$*" = "X"; then + # -L didn't work. + set X `ls -t $srcdir/configure conftestfile` + fi + if test "$*" != "X $srcdir/configure conftestfile" \ + && test "$*" != "X conftestfile $srcdir/configure"; then + + # If neither matched, then we have a broken ls. This can happen + # if, for instance, CONFIG_SHELL is bash and it inherits a + # broken ls alias from the environment. This has actually + # happened. Such a system could not be considered "sane". + { echo "configure: error: ls -t appears to fail. Make sure there is not a broken +alias in your environment" 1>&2; exit 1; } + fi + + test "$2" = conftestfile + ) +then + # Ok. + : +else + { echo "configure: error: newly created file is older than distributed files! +Check your system clock" 1>&2; exit 1; } +fi +rm -f conftest* +echo "$ac_t""yes" 1>&6 +if test "$program_transform_name" = s,x,x,; then + program_transform_name= +else + # Double any \ or $. echo might interpret backslashes. + cat <<\EOF_SED > conftestsed +s,\\,\\\\,g; s,\$,$$,g +EOF_SED + program_transform_name="`echo $program_transform_name|sed -f conftestsed`" + rm -f conftestsed +fi +test "$program_prefix" != NONE && + program_transform_name="s,^,${program_prefix},; $program_transform_name" +# Use a double $ so make ignores it. +test "$program_suffix" != NONE && + program_transform_name="s,\$\$,${program_suffix},; $program_transform_name" + +# sed with no file args requires a program. +test "$program_transform_name" = "" && program_transform_name="s,x,x," + +echo $ac_n "checking whether ${MAKE-make} sets \${MAKE}""... $ac_c" 1>&6 +echo "configure:675: checking whether ${MAKE-make} sets \${MAKE}" >&5 +set dummy ${MAKE-make}; ac_make=`echo "$2" | sed 'y%./+-%__p_%'` +if eval "test \"`echo '$''{'ac_cv_prog_make_${ac_make}_set'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftestmake <<\EOF +all: + @echo 'ac_maketemp="${MAKE}"' +EOF +# GNU make sometimes prints "make[1]: Entering...", which would confuse us. +eval `${MAKE-make} -f conftestmake 2>/dev/null | grep temp=` +if test -n "$ac_maketemp"; then + eval ac_cv_prog_make_${ac_make}_set=yes +else + eval ac_cv_prog_make_${ac_make}_set=no +fi +rm -f conftestmake +fi +if eval "test \"`echo '$ac_cv_prog_make_'${ac_make}_set`\" = yes"; then + echo "$ac_t""yes" 1>&6 + SET_MAKE= +else + echo "$ac_t""no" 1>&6 + SET_MAKE="MAKE=${MAKE-make}" +fi + + +PACKAGE=sdlquake + +VERSION=1.0.9 + +if test "`cd $srcdir && pwd`" != "`pwd`" && test -f $srcdir/config.status; then + { echo "configure: error: source directory already configured; run "make distclean" there first" 1>&2; exit 1; } +fi +cat >> confdefs.h <> confdefs.h <&6 +echo "configure:721: checking for working aclocal" >&5 +# Run test in a subshell; some versions of sh will print an error if +# an executable is not found, even if stderr is redirected. +# Redirect stdin to placate older versions of autoconf. Sigh. +if (aclocal --version) < /dev/null > /dev/null 2>&1; then + ACLOCAL=aclocal + echo "$ac_t""found" 1>&6 +else + ACLOCAL="$missing_dir/missing aclocal" + echo "$ac_t""missing" 1>&6 +fi + +echo $ac_n "checking for working autoconf""... $ac_c" 1>&6 +echo "configure:734: checking for working autoconf" >&5 +# Run test in a subshell; some versions of sh will print an error if +# an executable is not found, even if stderr is redirected. +# Redirect stdin to placate older versions of autoconf. Sigh. +if (autoconf --version) < /dev/null > /dev/null 2>&1; then + AUTOCONF=autoconf + echo "$ac_t""found" 1>&6 +else + AUTOCONF="$missing_dir/missing autoconf" + echo "$ac_t""missing" 1>&6 +fi + +echo $ac_n "checking for working automake""... $ac_c" 1>&6 +echo "configure:747: checking for working automake" >&5 +# Run test in a subshell; some versions of sh will print an error if +# an executable is not found, even if stderr is redirected. +# Redirect stdin to placate older versions of autoconf. Sigh. +if (automake --version) < /dev/null > /dev/null 2>&1; then + AUTOMAKE=automake + echo "$ac_t""found" 1>&6 +else + AUTOMAKE="$missing_dir/missing automake" + echo "$ac_t""missing" 1>&6 +fi + +echo $ac_n "checking for working autoheader""... $ac_c" 1>&6 +echo "configure:760: checking for working autoheader" >&5 +# Run test in a subshell; some versions of sh will print an error if +# an executable is not found, even if stderr is redirected. +# Redirect stdin to placate older versions of autoconf. Sigh. +if (autoheader --version) < /dev/null > /dev/null 2>&1; then + AUTOHEADER=autoheader + echo "$ac_t""found" 1>&6 +else + AUTOHEADER="$missing_dir/missing autoheader" + echo "$ac_t""missing" 1>&6 +fi + +echo $ac_n "checking for working makeinfo""... $ac_c" 1>&6 +echo "configure:773: checking for working makeinfo" >&5 +# Run test in a subshell; some versions of sh will print an error if +# an executable is not found, even if stderr is redirected. +# Redirect stdin to placate older versions of autoconf. Sigh. +if (makeinfo --version) < /dev/null > /dev/null 2>&1; then + MAKEINFO=makeinfo + echo "$ac_t""found" 1>&6 +else + MAKEINFO="$missing_dir/missing makeinfo" + echo "$ac_t""missing" 1>&6 +fi + + + + +# Make sure we can run config.sub. +if ${CONFIG_SHELL-/bin/sh} $ac_config_sub sun4 >/dev/null 2>&1; then : +else { echo "configure: error: can not run $ac_config_sub" 1>&2; exit 1; } +fi + +echo $ac_n "checking host system type""... $ac_c" 1>&6 +echo "configure:794: checking host system type" >&5 + +host_alias=$host +case "$host_alias" in +NONE) + case $nonopt in + NONE) + if host_alias=`${CONFIG_SHELL-/bin/sh} $ac_config_guess`; then : + else { echo "configure: error: can not guess host type; you must specify one" 1>&2; exit 1; } + fi ;; + *) host_alias=$nonopt ;; + esac ;; +esac + +host=`${CONFIG_SHELL-/bin/sh} $ac_config_sub $host_alias` +host_cpu=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'` +host_vendor=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'` +host_os=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'` +echo "$ac_t""$host" 1>&6 + +echo $ac_n "checking target system type""... $ac_c" 1>&6 +echo "configure:815: checking target system type" >&5 + +target_alias=$target +case "$target_alias" in +NONE) + case $nonopt in + NONE) target_alias=$host_alias ;; + *) target_alias=$nonopt ;; + esac ;; +esac + +target=`${CONFIG_SHELL-/bin/sh} $ac_config_sub $target_alias` +target_cpu=`echo $target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'` +target_vendor=`echo $target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'` +target_os=`echo $target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'` +echo "$ac_t""$target" 1>&6 + + + +echo $ac_n "checking whether ${MAKE-make} sets \${MAKE}""... $ac_c" 1>&6 +echo "configure:835: checking whether ${MAKE-make} sets \${MAKE}" >&5 +set dummy ${MAKE-make}; ac_make=`echo "$2" | sed 'y%./+-%__p_%'` +if eval "test \"`echo '$''{'ac_cv_prog_make_${ac_make}_set'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftestmake <<\EOF +all: + @echo 'ac_maketemp="${MAKE}"' +EOF +# GNU make sometimes prints "make[1]: Entering...", which would confuse us. +eval `${MAKE-make} -f conftestmake 2>/dev/null | grep temp=` +if test -n "$ac_maketemp"; then + eval ac_cv_prog_make_${ac_make}_set=yes +else + eval ac_cv_prog_make_${ac_make}_set=no +fi +rm -f conftestmake +fi +if eval "test \"`echo '$ac_cv_prog_make_'${ac_make}_set`\" = yes"; then + echo "$ac_t""yes" 1>&6 + SET_MAKE= +else + echo "$ac_t""no" 1>&6 + SET_MAKE="MAKE=${MAKE-make}" +fi + +# Extract the first word of "gcc", so it can be a program name with args. +set dummy gcc; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:864: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_prog_CC="gcc" + break + fi + done + IFS="$ac_save_ifs" +fi +fi +CC="$ac_cv_prog_CC" +if test -n "$CC"; then + echo "$ac_t""$CC" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + +if test -z "$CC"; then + # Extract the first word of "cc", so it can be a program name with args. +set dummy cc; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:894: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_prog_rejected=no + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + if test "$ac_dir/$ac_word" = "/usr/ucb/cc"; then + ac_prog_rejected=yes + continue + fi + ac_cv_prog_CC="cc" + break + fi + done + IFS="$ac_save_ifs" +if test $ac_prog_rejected = yes; then + # We found a bogon in the path, so make sure we never use it. + set dummy $ac_cv_prog_CC + shift + if test $# -gt 0; then + # We chose a different compiler from the bogus one. + # However, it has the same basename, so the bogon will be chosen + # first if we set CC to just the basename; use the full file name. + shift + set dummy "$ac_dir/$ac_word" "$@" + shift + ac_cv_prog_CC="$@" + fi +fi +fi +fi +CC="$ac_cv_prog_CC" +if test -n "$CC"; then + echo "$ac_t""$CC" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + + if test -z "$CC"; then + case "`uname -s`" in + *win32* | *WIN32*) + # Extract the first word of "cl", so it can be a program name with args. +set dummy cl; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:945: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_prog_CC="cl" + break + fi + done + IFS="$ac_save_ifs" +fi +fi +CC="$ac_cv_prog_CC" +if test -n "$CC"; then + echo "$ac_t""$CC" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + ;; + esac + fi + test -z "$CC" && { echo "configure: error: no acceptable cc found in \$PATH" 1>&2; exit 1; } +fi + +echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works""... $ac_c" 1>&6 +echo "configure:977: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works" >&5 + +ac_ext=c +# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. +ac_cpp='$CPP $CPPFLAGS' +ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5' +ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5' +cross_compiling=$ac_cv_prog_cc_cross + +cat > conftest.$ac_ext << EOF + +#line 988 "configure" +#include "confdefs.h" + +main(){return(0);} +EOF +if { (eval echo configure:993: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + ac_cv_prog_cc_works=yes + # If we can't run a trivial program, we are probably using a cross compiler. + if (./conftest; exit) 2>/dev/null; then + ac_cv_prog_cc_cross=no + else + ac_cv_prog_cc_cross=yes + fi +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + ac_cv_prog_cc_works=no +fi +rm -fr conftest* +ac_ext=c +# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. +ac_cpp='$CPP $CPPFLAGS' +ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5' +ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5' +cross_compiling=$ac_cv_prog_cc_cross + +echo "$ac_t""$ac_cv_prog_cc_works" 1>&6 +if test $ac_cv_prog_cc_works = no; then + { echo "configure: error: installation or configuration problem: C compiler cannot create executables." 1>&2; exit 1; } +fi +echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler""... $ac_c" 1>&6 +echo "configure:1019: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler" >&5 +echo "$ac_t""$ac_cv_prog_cc_cross" 1>&6 +cross_compiling=$ac_cv_prog_cc_cross + +echo $ac_n "checking whether we are using GNU C""... $ac_c" 1>&6 +echo "configure:1024: checking whether we are using GNU C" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_gcc'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.c <&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then + ac_cv_prog_gcc=yes +else + ac_cv_prog_gcc=no +fi +fi + +echo "$ac_t""$ac_cv_prog_gcc" 1>&6 + +if test $ac_cv_prog_gcc = yes; then + GCC=yes +else + GCC= +fi + +ac_test_CFLAGS="${CFLAGS+set}" +ac_save_CFLAGS="$CFLAGS" +CFLAGS= +echo $ac_n "checking whether ${CC-cc} accepts -g""... $ac_c" 1>&6 +echo "configure:1052: checking whether ${CC-cc} accepts -g" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_cc_g'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + echo 'void f(){}' > conftest.c +if test -z "`${CC-cc} -g -c conftest.c 2>&1`"; then + ac_cv_prog_cc_g=yes +else + ac_cv_prog_cc_g=no +fi +rm -f conftest* + +fi + +echo "$ac_t""$ac_cv_prog_cc_g" 1>&6 +if test "$ac_test_CFLAGS" = set; then + CFLAGS="$ac_save_CFLAGS" +elif test $ac_cv_prog_cc_g = yes; then + if test "$GCC" = yes; then + CFLAGS="-g -O2" + else + CFLAGS="-g" + fi +else + if test "$GCC" = yes; then + CFLAGS="-O2" + else + CFLAGS= + fi +fi + +# Find a good install program. We prefer a C program (faster), +# so one script is as good as another. But avoid the broken or +# incompatible versions: +# SysV /etc/install, /usr/sbin/install +# SunOS /usr/etc/install +# IRIX /sbin/install +# AIX /bin/install +# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag +# AFS /usr/afsws/bin/install, which mishandles nonexistent args +# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" +# ./install, which can be erroneously created by make from ./install.sh. +echo $ac_n "checking for a BSD compatible install""... $ac_c" 1>&6 +echo "configure:1095: checking for a BSD compatible install" >&5 +if test -z "$INSTALL"; then +if eval "test \"`echo '$''{'ac_cv_path_install'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + IFS="${IFS= }"; ac_save_IFS="$IFS"; IFS=":" + for ac_dir in $PATH; do + # Account for people who put trailing slashes in PATH elements. + case "$ac_dir/" in + /|./|.//|/etc/*|/usr/sbin/*|/usr/etc/*|/sbin/*|/usr/afsws/bin/*|/usr/ucb/*) ;; + *) + # OSF1 and SCO ODT 3.0 have their own names for install. + # Don't use installbsd from OSF since it installs stuff as root + # by default. + for ac_prog in ginstall scoinst install; do + if test -f $ac_dir/$ac_prog; then + if test $ac_prog = install && + grep dspmsg $ac_dir/$ac_prog >/dev/null 2>&1; then + # AIX install. It has an incompatible calling convention. + : + else + ac_cv_path_install="$ac_dir/$ac_prog -c" + break 2 + fi + fi + done + ;; + esac + done + IFS="$ac_save_IFS" + +fi + if test "${ac_cv_path_install+set}" = set; then + INSTALL="$ac_cv_path_install" + else + # As a last resort, use the slow shell script. We don't cache a + # path for INSTALL within a source directory, because that will + # break other packages using the cache if that directory is + # removed, or if the path is relative. + INSTALL="$ac_install_sh" + fi +fi +echo "$ac_t""$INSTALL" 1>&6 + +# Use test -z because SunOS4 sh mishandles braces in ${var-val}. +# It thinks the first close brace ends the variable substitution. +test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}' + +test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL_PROGRAM}' + +test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' + + +echo $ac_n "checking target system type""... $ac_c" 1>&6 +echo "configure:1149: checking target system type" >&5 + +target_alias=$target +case "$target_alias" in +NONE) + case $nonopt in + NONE) target_alias=$host_alias ;; + *) target_alias=$nonopt ;; + esac ;; +esac + +target=`${CONFIG_SHELL-/bin/sh} $ac_config_sub $target_alias` +target_cpu=`echo $target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'` +target_vendor=`echo $target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'` +target_os=`echo $target | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'` +echo "$ac_t""$target" 1>&6 + +case "$target" in + i686-*-linux*) + CFLAGS="-g -mpentiumpro -O6 -ffast-math -funroll-loops -fomit-frame-pointer -fexpensive-optimizations" + #CFLAGS="-g -mpentiumpro -O6 -ffast-math -funroll-loops -fexpensive-optimizations" + ;; + alpha*-*-linux*) + CFLAGS="$CFLAGS -mcpu=ev4 -Wa,-mall" + ;; +esac + +case "$target" in + *-*-mingw32*) + MATHLIB="" + INETLIB="-lwsock32" + ;; + *-*-beos*) + MATHLIB="" + INETLIB="" + ;; + *) + MATHLIB="-lm" + INETLIB="" + ;; +esac + + + +SDL_VERSION=1.0.1 +# Check whether --with-sdl-prefix or --without-sdl-prefix was given. +if test "${with_sdl_prefix+set}" = set; then + withval="$with_sdl_prefix" + sdl_prefix="$withval" +else + sdl_prefix="" +fi + +# Check whether --with-sdl-exec-prefix or --without-sdl-exec-prefix was given. +if test "${with_sdl_exec_prefix+set}" = set; then + withval="$with_sdl_exec_prefix" + sdl_exec_prefix="$withval" +else + sdl_exec_prefix="" +fi + +# Check whether --enable-sdltest or --disable-sdltest was given. +if test "${enable_sdltest+set}" = set; then + enableval="$enable_sdltest" + : +else + enable_sdltest=yes +fi + + + if test x$sdl_exec_prefix != x ; then + sdl_args="$sdl_args --exec-prefix=$sdl_exec_prefix" + if test x${SDL_CONFIG+set} != xset ; then + SDL_CONFIG=$sdl_exec_prefix/bin/sdl-config + fi + fi + if test x$sdl_prefix != x ; then + sdl_args="$sdl_args --prefix=$sdl_prefix" + if test x${SDL_CONFIG+set} != xset ; then + SDL_CONFIG=$sdl_prefix/bin/sdl-config + fi + fi + + # Extract the first word of "sdl-config", so it can be a program name with args. +set dummy sdl-config; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:1235: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_path_SDL_CONFIG'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + case "$SDL_CONFIG" in + /*) + ac_cv_path_SDL_CONFIG="$SDL_CONFIG" # Let the user override the test with a path. + ;; + ?:/*) + ac_cv_path_SDL_CONFIG="$SDL_CONFIG" # Let the user override the test with a dos path. + ;; + *) + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_path_SDL_CONFIG="$ac_dir/$ac_word" + break + fi + done + IFS="$ac_save_ifs" + test -z "$ac_cv_path_SDL_CONFIG" && ac_cv_path_SDL_CONFIG="no" + ;; +esac +fi +SDL_CONFIG="$ac_cv_path_SDL_CONFIG" +if test -n "$SDL_CONFIG"; then + echo "$ac_t""$SDL_CONFIG" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + + min_sdl_version=$SDL_VERSION + echo $ac_n "checking for SDL - version >= $min_sdl_version""... $ac_c" 1>&6 +echo "configure:1270: checking for SDL - version >= $min_sdl_version" >&5 + no_sdl="" + if test "$SDL_CONFIG" = "no" ; then + no_sdl=yes + else + SDL_CFLAGS=`$SDL_CONFIG $sdlconf_args --cflags` + SDL_LIBS=`$SDL_CONFIG $sdlconf_args --libs` + + sdl_major_version=`$SDL_CONFIG $sdl_args --version | \ + sed 's/\([0-9]*\).\([0-9]*\).\([0-9]*\)/\1/'` + sdl_minor_version=`$SDL_CONFIG $sdl_args --version | \ + sed 's/\([0-9]*\).\([0-9]*\).\([0-9]*\)/\2/'` + sdl_micro_version=`$SDL_CONFIG $sdl_config_args --version | \ + sed 's/\([0-9]*\).\([0-9]*\).\([0-9]*\)/\3/'` + if test "x$enable_sdltest" = "xyes" ; then + ac_save_CFLAGS="$CFLAGS" + ac_save_LIBS="$LIBS" + CFLAGS="$CFLAGS $SDL_CFLAGS" + LIBS="$LIBS $SDL_LIBS" + rm -f conf.sdltest + if test "$cross_compiling" = yes; then + echo $ac_n "cross compiling; assumed OK... $ac_c" +else + cat > conftest.$ac_ext < +#include +#include +#include "SDL.h" + +char* +my_strdup (char *str) +{ + char *new_str; + + if (str) + { + new_str = malloc ((strlen (str) + 1) * sizeof(char)); + strcpy (new_str, str); + } + else + new_str = NULL; + + return new_str; +} + +int main () +{ + int major, minor, micro; + char *tmp_version; + + system ("touch conf.sdltest"); + + /* HP/UX 9 (%@#!) writes to sscanf strings */ + tmp_version = my_strdup("$min_sdl_version"); + if (sscanf(tmp_version, "%d.%d.%d", &major, &minor, µ) != 3) { + printf("%s, bad version string\n", "$min_sdl_version"); + exit(1); + } + + if (($sdl_major_version > major) || + (($sdl_major_version == major) && ($sdl_minor_version > minor)) || + (($sdl_major_version == major) && ($sdl_minor_version == minor) && ($sdl_micro_version >= micro))) + { + return 0; + } + else + { + printf("\n*** 'sdl-config --version' returned %d.%d.%d, but the minimum version\n", $sdl_major_version, $sdl_minor_version, $sdl_micro_version); + printf("*** of SDL required is %d.%d.%d. If sdl-config is correct, then it is\n", major, minor, micro); + printf("*** best to upgrade to the required version.\n"); + printf("*** If sdl-config was wrong, set the environment variable SDL_CONFIG\n"); + printf("*** to point to the correct copy of sdl-config, and remove the file\n"); + printf("*** config.cache before re-running configure\n"); + return 1; + } +} + + +EOF +if { (eval echo configure:1352: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +then + : +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -fr conftest* + no_sdl=yes +fi +rm -fr conftest* +fi + + CFLAGS="$ac_save_CFLAGS" + LIBS="$ac_save_LIBS" + fi + fi + if test "x$no_sdl" = x ; then + echo "$ac_t""yes" 1>&6 + : + else + echo "$ac_t""no" 1>&6 + if test "$SDL_CONFIG" = "no" ; then + echo "*** The sdl-config script installed by SDL could not be found" + echo "*** If SDL was installed in PREFIX, make sure PREFIX/bin is in" + echo "*** your path, or set the SDL_CONFIG environment variable to the" + echo "*** full path to sdl-config." + else + if test -f conf.sdltest ; then + : + else + echo "*** Could not run SDL test program, checking why..." + CFLAGS="$CFLAGS $SDL_CFLAGS" + LIBS="$LIBS $SDL_LIBS" + cat > conftest.$ac_ext < +#include "SDL.h" + +int main() { + return 0; +; return 0; } +EOF +if { (eval echo configure:1396: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + echo "*** The test program compiled, but did not run. This usually means" + echo "*** that the run-time linker is not finding SDL or finding the wrong" + echo "*** version of SDL. If it is not finding SDL, you'll need to set your" + echo "*** LD_LIBRARY_PATH environment variable, or edit /etc/ld.so.conf to point" + echo "*** to the installed location Also, make sure you have run ldconfig if that" + echo "*** is required on your system" + echo "***" + echo "*** If you have an old version installed, it is best to remove it, although" + echo "*** you may also be able to get things to work by modifying LD_LIBRARY_PATH" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + echo "*** The test program failed to compile or link. See the file config.log for the" + echo "*** exact error that occured. This usually means SDL was incorrectly installed" + echo "*** or that you have moved SDL since it was installed. In the latter case, you" + echo "*** may want to edit the sdl-config script: $SDL_CONFIG" +fi +rm -f conftest* + CFLAGS="$ac_save_CFLAGS" + LIBS="$ac_save_LIBS" + fi + fi + SDL_CFLAGS="" + SDL_LIBS="" + { echo "configure: error: *** SDL version $SDL_VERSION not found!" 1>&2; exit 1; } + + fi + + + rm -f conf.sdltest + +CFLAGS="$CFLAGS $SDL_CFLAGS -DSDL" +LIBS="$LIBS $SDL_LIBS" + +case "$target" in + *-*-mingw32*) + cp ico_o ico.o + ICONOBJ="ico.o" + ;; + *) + ICONOBJ="" + ;; +esac + + +# Check whether --enable-asm or --disable-asm was given. +if test "${enable_asm+set}" = set; then + enableval="$enable_asm" + : +else + enable_asm=no +fi + +if test x$enable_asm = xyes; then + CFLAGS="$CFLAGS -DUSE_ASM" +fi + +CFLAGS="$CFLAGS -DELF" + +# Finally create all the generated files +trap '' 1 2 15 +cat > confcache <<\EOF +# This file is a shell script that caches the results of configure +# tests run on this system so they can be shared between configure +# scripts and configure runs. It is not useful on other systems. +# If it contains results you don't want to keep, you may remove or edit it. +# +# By default, configure uses ./config.cache as the cache file, +# creating it if it does not exist already. You can give configure +# the --cache-file=FILE option to use a different cache file; that is +# what configure does when it calls configure scripts in +# subdirectories, so they share the cache. +# Giving --cache-file=/dev/null disables caching, for debugging configure. +# config.status only pays attention to the cache file if you give it the +# --recheck option to rerun configure. +# +EOF +# The following way of writing the cache mishandles newlines in values, +# but we know of no workaround that is simple, portable, and efficient. +# So, don't put newlines in cache variables' values. +# Ultrix sh set writes to stderr and can't be redirected directly, +# and sets the high bit in the cache file unless we assign to the vars. +(set) 2>&1 | + case `(ac_space=' '; set | grep ac_space) 2>&1` in + *ac_space=\ *) + # `set' does not quote correctly, so add quotes (double-quote substitution + # turns \\\\ into \\, and sed turns \\ into \). + sed -n \ + -e "s/'/'\\\\''/g" \ + -e "s/^\\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\\)=\\(.*\\)/\\1=\${\\1='\\2'}/p" + ;; + *) + # `set' quotes correctly as required by POSIX, so do not add quotes. + sed -n -e 's/^\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\)=\(.*\)/\1=${\1=\2}/p' + ;; + esac >> confcache +if cmp -s $cache_file confcache; then + : +else + if test -w $cache_file; then + echo "updating cache $cache_file" + cat confcache > $cache_file + else + echo "not updating unwritable cache $cache_file" + fi +fi +rm -f confcache + +trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15 + +test "x$prefix" = xNONE && prefix=$ac_default_prefix +# Let make expand exec_prefix. +test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' + +# Any assignment to VPATH causes Sun make to only execute +# the first set of double-colon rules, so remove it if not needed. +# If there is a colon in the path, we need to keep it. +if test "x$srcdir" = x.; then + ac_vpsub='/^[ ]*VPATH[ ]*=[^:]*$/d' +fi + +trap 'rm -f $CONFIG_STATUS conftest*; exit 1' 1 2 15 + +# Transform confdefs.h into DEFS. +# Protect against shell expansion while executing Makefile rules. +# Protect against Makefile macro expansion. +cat > conftest.defs <<\EOF +s%#define \([A-Za-z_][A-Za-z0-9_]*\) *\(.*\)%-D\1=\2%g +s%[ `~#$^&*(){}\\|;'"<>?]%\\&%g +s%\[%\\&%g +s%\]%\\&%g +s%\$%$$%g +EOF +DEFS=`sed -f conftest.defs confdefs.h | tr '\012' ' '` +rm -f conftest.defs + + +# Without the "./", some shells look in PATH for config.status. +: ${CONFIG_STATUS=./config.status} + +echo creating $CONFIG_STATUS +rm -f $CONFIG_STATUS +cat > $CONFIG_STATUS </dev/null | sed 1q`: +# +# $0 $ac_configure_args +# +# Compiler output produced by configure, useful for debugging +# configure, is in ./config.log if it exists. + +ac_cs_usage="Usage: $CONFIG_STATUS [--recheck] [--version] [--help]" +for ac_option +do + case "\$ac_option" in + -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) + echo "running \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion" + exec \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion ;; + -version | --version | --versio | --versi | --vers | --ver | --ve | --v) + echo "$CONFIG_STATUS generated by autoconf version 2.13" + exit 0 ;; + -help | --help | --hel | --he | --h) + echo "\$ac_cs_usage"; exit 0 ;; + *) echo "\$ac_cs_usage"; exit 1 ;; + esac +done + +ac_given_srcdir=$srcdir +ac_given_INSTALL="$INSTALL" + +trap 'rm -fr `echo " +Makefile +" | sed "s/:[^ ]*//g"` conftest*; exit 1' 1 2 15 +EOF +cat >> $CONFIG_STATUS < conftest.subs <<\\CEOF +$ac_vpsub +$extrasub +s%@SHELL@%$SHELL%g +s%@CFLAGS@%$CFLAGS%g +s%@CPPFLAGS@%$CPPFLAGS%g +s%@CXXFLAGS@%$CXXFLAGS%g +s%@FFLAGS@%$FFLAGS%g +s%@DEFS@%$DEFS%g +s%@LDFLAGS@%$LDFLAGS%g +s%@LIBS@%$LIBS%g +s%@exec_prefix@%$exec_prefix%g +s%@prefix@%$prefix%g +s%@program_transform_name@%$program_transform_name%g +s%@bindir@%$bindir%g +s%@sbindir@%$sbindir%g +s%@libexecdir@%$libexecdir%g +s%@datadir@%$datadir%g +s%@sysconfdir@%$sysconfdir%g +s%@sharedstatedir@%$sharedstatedir%g +s%@localstatedir@%$localstatedir%g +s%@libdir@%$libdir%g +s%@includedir@%$includedir%g +s%@oldincludedir@%$oldincludedir%g +s%@infodir@%$infodir%g +s%@mandir@%$mandir%g +s%@INSTALL_PROGRAM@%$INSTALL_PROGRAM%g +s%@INSTALL_SCRIPT@%$INSTALL_SCRIPT%g +s%@INSTALL_DATA@%$INSTALL_DATA%g +s%@PACKAGE@%$PACKAGE%g +s%@VERSION@%$VERSION%g +s%@ACLOCAL@%$ACLOCAL%g +s%@AUTOCONF@%$AUTOCONF%g +s%@AUTOMAKE@%$AUTOMAKE%g +s%@AUTOHEADER@%$AUTOHEADER%g +s%@MAKEINFO@%$MAKEINFO%g +s%@SET_MAKE@%$SET_MAKE%g +s%@host@%$host%g +s%@host_alias@%$host_alias%g +s%@host_cpu@%$host_cpu%g +s%@host_vendor@%$host_vendor%g +s%@host_os@%$host_os%g +s%@target@%$target%g +s%@target_alias@%$target_alias%g +s%@target_cpu@%$target_cpu%g +s%@target_vendor@%$target_vendor%g +s%@target_os@%$target_os%g +s%@CC@%$CC%g +s%@MATHLIB@%$MATHLIB%g +s%@INETLIB@%$INETLIB%g +s%@SDL_CONFIG@%$SDL_CONFIG%g +s%@SDL_CFLAGS@%$SDL_CFLAGS%g +s%@SDL_LIBS@%$SDL_LIBS%g +s%@ICONOBJ@%$ICONOBJ%g + +CEOF +EOF + +cat >> $CONFIG_STATUS <<\EOF + +# Split the substitutions into bite-sized pieces for seds with +# small command number limits, like on Digital OSF/1 and HP-UX. +ac_max_sed_cmds=90 # Maximum number of lines to put in a sed script. +ac_file=1 # Number of current file. +ac_beg=1 # First line for current file. +ac_end=$ac_max_sed_cmds # Line after last line for current file. +ac_more_lines=: +ac_sed_cmds="" +while $ac_more_lines; do + if test $ac_beg -gt 1; then + sed "1,${ac_beg}d; ${ac_end}q" conftest.subs > conftest.s$ac_file + else + sed "${ac_end}q" conftest.subs > conftest.s$ac_file + fi + if test ! -s conftest.s$ac_file; then + ac_more_lines=false + rm -f conftest.s$ac_file + else + if test -z "$ac_sed_cmds"; then + ac_sed_cmds="sed -f conftest.s$ac_file" + else + ac_sed_cmds="$ac_sed_cmds | sed -f conftest.s$ac_file" + fi + ac_file=`expr $ac_file + 1` + ac_beg=$ac_end + ac_end=`expr $ac_end + $ac_max_sed_cmds` + fi +done +if test -z "$ac_sed_cmds"; then + ac_sed_cmds=cat +fi +EOF + +cat >> $CONFIG_STATUS <> $CONFIG_STATUS <<\EOF +for ac_file in .. $CONFIG_FILES; do if test "x$ac_file" != x..; then + # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in". + case "$ac_file" in + *:*) ac_file_in=`echo "$ac_file"|sed 's%[^:]*:%%'` + ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;; + *) ac_file_in="${ac_file}.in" ;; + esac + + # Adjust a relative srcdir, top_srcdir, and INSTALL for subdirectories. + + # Remove last slash and all that follows it. Not all systems have dirname. + ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'` + if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then + # The file is in a subdirectory. + test ! -d "$ac_dir" && mkdir "$ac_dir" + ac_dir_suffix="/`echo $ac_dir|sed 's%^\./%%'`" + # A "../" for each directory in $ac_dir_suffix. + ac_dots=`echo $ac_dir_suffix|sed 's%/[^/]*%../%g'` + else + ac_dir_suffix= ac_dots= + fi + + case "$ac_given_srcdir" in + .) srcdir=. + if test -z "$ac_dots"; then top_srcdir=. + else top_srcdir=`echo $ac_dots|sed 's%/$%%'`; fi ;; + /*) srcdir="$ac_given_srcdir$ac_dir_suffix"; top_srcdir="$ac_given_srcdir" ;; + *) # Relative path. + srcdir="$ac_dots$ac_given_srcdir$ac_dir_suffix" + top_srcdir="$ac_dots$ac_given_srcdir" ;; + esac + + case "$ac_given_INSTALL" in + [/$]*) INSTALL="$ac_given_INSTALL" ;; + *) INSTALL="$ac_dots$ac_given_INSTALL" ;; + esac + + echo creating "$ac_file" + rm -f "$ac_file" + configure_input="Generated automatically from `echo $ac_file_in|sed 's%.*/%%'` by configure." + case "$ac_file" in + *Makefile*) ac_comsub="1i\\ +# $configure_input" ;; + *) ac_comsub= ;; + esac + + ac_file_inputs=`echo $ac_file_in|sed -e "s%^%$ac_given_srcdir/%" -e "s%:% $ac_given_srcdir/%g"` + sed -e "$ac_comsub +s%@configure_input@%$configure_input%g +s%@srcdir@%$srcdir%g +s%@top_srcdir@%$top_srcdir%g +s%@INSTALL@%$INSTALL%g +" $ac_file_inputs | (eval "$ac_sed_cmds") > $ac_file +fi; done +rm -f conftest.s* + +EOF +cat >> $CONFIG_STATUS <> $CONFIG_STATUS <<\EOF + +exit 0 +EOF +chmod +x $CONFIG_STATUS +rm -fr confdefs* $ac_clean_files +test "$no_create" = yes || ${CONFIG_SHELL-/bin/sh} $CONFIG_STATUS || exit 1 + diff --git a/contrib/other/sdlquake-1.0.9/configure.in b/contrib/other/sdlquake-1.0.9/configure.in new file mode 100644 index 000000000..0dc7d7e1e --- /dev/null +++ b/contrib/other/sdlquake-1.0.9/configure.in @@ -0,0 +1,81 @@ +dnl Process this file with autoconf to produce a configure script. +AC_INIT(README.SDL) + +dnl Setup for automake +AM_INIT_AUTOMAKE(sdlquake, 1.0.9) + +dnl Detect the canonical target build environment +AC_CANONICAL_HOST +AC_CANONICAL_TARGET + +dnl Check for tools + +AC_PROG_MAKE_SET +AC_PROG_CC +AC_PROG_INSTALL + +dnl The alpha architecture needs special flags for binary portability +AC_CANONICAL_TARGET +case "$target" in + i686-*-linux*) + CFLAGS="-g -mpentiumpro -O6 -ffast-math -funroll-loops -fomit-frame-pointer -fexpensive-optimizations" + #CFLAGS="-g -mpentiumpro -O6 -ffast-math -funroll-loops -fexpensive-optimizations" + ;; + alpha*-*-linux*) + CFLAGS="$CFLAGS -mcpu=ev4 -Wa,-mall" + ;; +esac + +dnl Figure out which math and networking libraries to use +case "$target" in + *-*-mingw32*) + MATHLIB="" + INETLIB="-lwsock32" + ;; + *-*-beos*) + MATHLIB="" + INETLIB="" + ;; + *) + MATHLIB="-lm" + INETLIB="" + ;; +esac +AC_SUBST(MATHLIB) +AC_SUBST(INETLIB) + +dnl Check for SDL +SDL_VERSION=1.0.1 +AM_PATH_SDL($SDL_VERSION, + :, + AC_MSG_ERROR([*** SDL version $SDL_VERSION not found!]) +) +CFLAGS="$CFLAGS $SDL_CFLAGS -DSDL" +LIBS="$LIBS $SDL_LIBS" + +dnl Set up the icon object file, for Mingw32 +case "$target" in + *-*-mingw32*) + cp ico_o ico.o + ICONOBJ="ico.o" + ;; + *) + ICONOBJ="" + ;; +esac +AC_SUBST(ICONOBJ) + +dnl Enable/disable the i686 asm +AC_ARG_ENABLE(asm, +[ --enable-asm enable i686 assembly routines [default=no]], + , enable_asm=no) +if test x$enable_asm = xyes; then + CFLAGS="$CFLAGS -DUSE_ASM" +fi + +CFLAGS="$CFLAGS -DELF" + +# Finally create all the generated files +AC_OUTPUT([ +Makefile +]) diff --git a/contrib/other/sdlquake-1.0.9/conproc.c b/contrib/other/sdlquake-1.0.9/conproc.c new file mode 100644 index 000000000..43c20ca45 --- /dev/null +++ b/contrib/other/sdlquake-1.0.9/conproc.c @@ -0,0 +1,365 @@ +/* +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/contrib/other/sdlquake-1.0.9/conproc.h b/contrib/other/sdlquake-1.0.9/conproc.h new file mode 100644 index 000000000..743526f87 --- /dev/null +++ b/contrib/other/sdlquake-1.0.9/conproc.h @@ -0,0 +1,37 @@ +/* +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/contrib/other/sdlquake-1.0.9/console.c b/contrib/other/sdlquake-1.0.9/console.c new file mode 100644 index 000000000..17ff6eea2 --- /dev/null +++ b/contrib/other/sdlquake-1.0.9/console.c @@ -0,0 +1,651 @@ +/* +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" + +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> 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> 8) ^ data]; +} + +unsigned short CRC_Value(unsigned short crcvalue) +{ + return crcvalue ^ CRC_XOR_VALUE; +} \ No newline at end of file diff --git a/contrib/other/sdlquake-1.0.9/crc.h b/contrib/other/sdlquake-1.0.9/crc.h new file mode 100644 index 000000000..cad97725b --- /dev/null +++ b/contrib/other/sdlquake-1.0.9/crc.h @@ -0,0 +1,24 @@ +/* +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. + +*/ +/* crc.h */ + +void CRC_Init(unsigned short *crcvalue); +void CRC_ProcessByte(unsigned short *crcvalue, byte data); +unsigned short CRC_Value(unsigned short crcvalue); diff --git a/contrib/other/sdlquake-1.0.9/cvar.c b/contrib/other/sdlquake-1.0.9/cvar.c new file mode 100644 index 000000000..07a761a33 --- /dev/null +++ b/contrib/other/sdlquake-1.0.9/cvar.c @@ -0,0 +1,224 @@ +/* +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.c -- dynamic variable tracking + +#include "quakedef.h" + +cvar_t *cvar_vars; +char *cvar_null_string = ""; + +/* +============ +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); + } +} + +/* +============ +Cvar_SetValue +============ +*/ +void Cvar_SetValue (char *var_name, float value) +{ + char val[32]; + + sprintf (val, "%f",value); + 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/contrib/other/sdlquake-1.0.9/cvar.h b/contrib/other/sdlquake-1.0.9/cvar.h new file mode 100644 index 000000000..009b74783 --- /dev/null +++ b/contrib/other/sdlquake-1.0.9/cvar.h @@ -0,0 +1,97 @@ +/* +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); + +extern cvar_t *cvar_vars; diff --git a/contrib/other/sdlquake-1.0.9/d_copy.S b/contrib/other/sdlquake-1.0.9/d_copy.S new file mode 100644 index 000000000..92e414a1b --- /dev/null +++ b/contrib/other/sdlquake-1.0.9/d_copy.S @@ -0,0 +1,149 @@ +// +// d_copy.s +// x86 assembly-language screen copying code. +// + +#include "asm_i386.h" +#include "quakeasm.h" +#include "asm_draw.h" + + .data + +LCopyWidth: .long 0 +LBlockSrcStep: .long 0 +LBlockDestStep: .long 0 +LSrcDelta: .long 0 +LDestDelta: .long 0 + +#define bufptr 4+16 + +// copies 16 rows per plane at a pop; idea is that 16*512 = 8k, and since +// no Mode X mode is wider than 360, all the data should fit in the cache for +// the passes for the next 3 planes + + .text + +.globl C(VGA_UpdatePlanarScreen) +C(VGA_UpdatePlanarScreen): + pushl %ebp // preserve caller's stack frame + pushl %edi + pushl %esi // preserve register variables + pushl %ebx + + movl C(VGA_bufferrowbytes),%eax + shll $1,%eax + movl %eax,LBlockSrcStep + movl C(VGA_rowbytes),%eax + shll $1,%eax + movl %eax,LBlockDestStep + + movl $0x3C4,%edx + movb $2,%al + outb %al,%dx // point the SC to the Map Mask + incl %edx + + movl bufptr(%esp),%esi + movl C(VGA_pagebase),%edi + movl C(VGA_height),%ebp + shrl $1,%ebp + + movl C(VGA_width),%ecx + movl C(VGA_bufferrowbytes),%eax + subl %ecx,%eax + movl %eax,LSrcDelta + movl C(VGA_rowbytes),%eax + shll $2,%eax + subl %ecx,%eax + movl %eax,LDestDelta + shrl $4,%ecx + movl %ecx,LCopyWidth + +LRowLoop: + movb $1,%al + +LPlaneLoop: + outb %al,%dx + movb $2,%ah + + pushl %esi + pushl %edi +LRowSetLoop: + movl LCopyWidth,%ecx +LColumnLoop: + movb 12(%esi),%bh + movb 8(%esi),%bl + shll $16,%ebx + movb 4(%esi),%bh + movb (%esi),%bl + movl %ebx,(%edi) + addl $16,%esi + addl $4,%edi + decl %ecx + jnz LColumnLoop + + addl LDestDelta,%edi + addl LSrcDelta,%esi + decb %ah + jnz LRowSetLoop + + popl %edi + popl %esi + incl %esi + + shlb $1,%al + cmpb $16,%al + jnz LPlaneLoop + + subl $4,%esi + addl LBlockSrcStep,%esi + addl LBlockDestStep,%edi + decl %ebp + jnz LRowLoop + + popl %ebx // restore register variables + popl %esi + popl %edi + popl %ebp // restore the caller's stack frame + + ret + + +#define srcptr 4+16 +#define destptr 8+16 +#define width 12+16 +#define height 16+16 +#define srcrowbytes 20+16 +#define destrowbytes 24+16 + +.globl C(VGA_UpdateLinearScreen) +C(VGA_UpdateLinearScreen): + pushl %ebp // preserve caller's stack frame + pushl %edi + pushl %esi // preserve register variables + pushl %ebx + + cld + movl srcptr(%esp),%esi + movl destptr(%esp),%edi + movl width(%esp),%ebx + movl srcrowbytes(%esp),%eax + subl %ebx,%eax + movl destrowbytes(%esp),%edx + subl %ebx,%edx + shrl $2,%ebx + movl height(%esp),%ebp +LLRowLoop: + movl %ebx,%ecx + rep/movsl (%esi),(%edi) + addl %eax,%esi + addl %edx,%edi + decl %ebp + jnz LLRowLoop + + popl %ebx // restore register variables + popl %esi + popl %edi + popl %ebp // restore the caller's stack frame + + ret + diff --git a/contrib/other/sdlquake-1.0.9/d_draw.S b/contrib/other/sdlquake-1.0.9/d_draw.S new file mode 100644 index 000000000..f0a6e2aaf --- /dev/null +++ b/contrib/other/sdlquake-1.0.9/d_draw.S @@ -0,0 +1,1037 @@ +/* +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. + +*/ +// +// d_draw.s +// x86 assembly-language horizontal 8-bpp span-drawing code. +// + +#include "asm_i386.h" +#include "quakeasm.h" +#include "asm_draw.h" +#include "d_ifacea.h" + +#if id386 + +//---------------------------------------------------------------------- +// 8-bpp horizontal span drawing code for polygons, with no transparency. +// +// Assumes there is at least one span in pspans, and that every span +// contains at least one pixel +//---------------------------------------------------------------------- + + .text + +// out-of-line, rarely-needed clamping code + +LClampHigh0: + movl C(bbextents),%esi + jmp LClampReentry0 +LClampHighOrLow0: + jg LClampHigh0 + xorl %esi,%esi + jmp LClampReentry0 + +LClampHigh1: + movl C(bbextentt),%edx + jmp LClampReentry1 +LClampHighOrLow1: + jg LClampHigh1 + xorl %edx,%edx + jmp LClampReentry1 + +LClampLow2: + movl $2048,%ebp + jmp LClampReentry2 +LClampHigh2: + movl C(bbextents),%ebp + jmp LClampReentry2 + +LClampLow3: + movl $2048,%ecx + jmp LClampReentry3 +LClampHigh3: + movl C(bbextentt),%ecx + jmp LClampReentry3 + +LClampLow4: + movl $2048,%eax + jmp LClampReentry4 +LClampHigh4: + movl C(bbextents),%eax + jmp LClampReentry4 + +LClampLow5: + movl $2048,%ebx + jmp LClampReentry5 +LClampHigh5: + movl C(bbextentt),%ebx + jmp LClampReentry5 + + +#define pspans 4+16 + + .align 4 +.globl C(D_DrawSpans8) +C(D_DrawSpans8): + pushl %ebp // preserve caller's stack frame + pushl %edi + pushl %esi // preserve register variables + pushl %ebx + +// +// set up scaled-by-8 steps, for 8-long segments; also set up cacheblock +// and span list pointers +// +// TODO: any overlap from rearranging? + flds C(d_sdivzstepu) + fmuls fp_8 + movl C(cacheblock),%edx + flds C(d_tdivzstepu) + fmuls fp_8 + movl pspans(%esp),%ebx // point to the first span descriptor + flds C(d_zistepu) + fmuls fp_8 + movl %edx,pbase // pbase = cacheblock + fstps zi8stepu + fstps tdivz8stepu + fstps sdivz8stepu + +LSpanLoop: +// +// set up the initial s/z, t/z, and 1/z on the FP stack, and generate the +// initial s and t values +// +// FIXME: pipeline FILD? + fildl espan_t_v(%ebx) + fildl espan_t_u(%ebx) + + fld %st(1) // dv | du | dv + fmuls C(d_sdivzstepv) // dv*d_sdivzstepv | du | dv + fld %st(1) // du | dv*d_sdivzstepv | du | dv + fmuls C(d_sdivzstepu) // du*d_sdivzstepu | dv*d_sdivzstepv | du | dv + fld %st(2) // du | du*d_sdivzstepu | dv*d_sdivzstepv | du | dv + fmuls C(d_tdivzstepu) // du*d_tdivzstepu | du*d_sdivzstepu | + // dv*d_sdivzstepv | du | dv + fxch %st(1) // du*d_sdivzstepu | du*d_tdivzstepu | + // dv*d_sdivzstepv | du | dv + faddp %st(0),%st(2) // du*d_tdivzstepu | + // du*d_sdivzstepu + dv*d_sdivzstepv | du | dv + fxch %st(1) // du*d_sdivzstepu + dv*d_sdivzstepv | + // du*d_tdivzstepu | du | dv + fld %st(3) // dv | du*d_sdivzstepu + dv*d_sdivzstepv | + // du*d_tdivzstepu | du | dv + fmuls C(d_tdivzstepv) // dv*d_tdivzstepv | + // du*d_sdivzstepu + dv*d_sdivzstepv | + // du*d_tdivzstepu | du | dv + fxch %st(1) // du*d_sdivzstepu + dv*d_sdivzstepv | + // dv*d_tdivzstepv | du*d_tdivzstepu | du | dv + fadds C(d_sdivzorigin) // sdivz = d_sdivzorigin + dv*d_sdivzstepv + + // du*d_sdivzstepu; stays in %st(2) at end + fxch %st(4) // dv | dv*d_tdivzstepv | du*d_tdivzstepu | du | + // s/z + fmuls C(d_zistepv) // dv*d_zistepv | dv*d_tdivzstepv | + // du*d_tdivzstepu | du | s/z + fxch %st(1) // dv*d_tdivzstepv | dv*d_zistepv | + // du*d_tdivzstepu | du | s/z + faddp %st(0),%st(2) // dv*d_zistepv | + // dv*d_tdivzstepv + du*d_tdivzstepu | du | s/z + fxch %st(2) // du | dv*d_tdivzstepv + du*d_tdivzstepu | + // dv*d_zistepv | s/z + fmuls C(d_zistepu) // du*d_zistepu | + // dv*d_tdivzstepv + du*d_tdivzstepu | + // dv*d_zistepv | s/z + fxch %st(1) // dv*d_tdivzstepv + du*d_tdivzstepu | + // du*d_zistepu | dv*d_zistepv | s/z + fadds C(d_tdivzorigin) // tdivz = d_tdivzorigin + dv*d_tdivzstepv + + // du*d_tdivzstepu; stays in %st(1) at end + fxch %st(2) // dv*d_zistepv | du*d_zistepu | t/z | s/z + faddp %st(0),%st(1) // dv*d_zistepv + du*d_zistepu | t/z | s/z + + flds fp_64k // fp_64k | dv*d_zistepv + du*d_zistepu | t/z | s/z + fxch %st(1) // dv*d_zistepv + du*d_zistepu | fp_64k | t/z | s/z + fadds C(d_ziorigin) // zi = d_ziorigin + dv*d_zistepv + + // du*d_zistepu; stays in %st(0) at end + // 1/z | fp_64k | t/z | s/z +// +// calculate and clamp s & t +// + fdivr %st(0),%st(1) // 1/z | z*64k | t/z | s/z + +// +// point %edi to the first pixel in the span +// + movl C(d_viewbuffer),%ecx + movl espan_t_v(%ebx),%eax + movl %ebx,pspantemp // preserve spans pointer + + movl C(tadjust),%edx + movl C(sadjust),%esi + movl C(d_scantable)(,%eax,4),%edi // v * screenwidth + addl %ecx,%edi + movl espan_t_u(%ebx),%ecx + addl %ecx,%edi // pdest = &pdestspan[scans->u]; + movl espan_t_count(%ebx),%ecx + +// +// now start the FDIV for the end of the span +// + cmpl $8,%ecx + ja LSetupNotLast1 + + decl %ecx + jz LCleanup1 // if only one pixel, no need to start an FDIV + movl %ecx,spancountminus1 + +// finish up the s and t calcs + fxch %st(1) // z*64k | 1/z | t/z | s/z + + fld %st(0) // z*64k | z*64k | 1/z | t/z | s/z + fmul %st(4),%st(0) // s | z*64k | 1/z | t/z | s/z + fxch %st(1) // z*64k | s | 1/z | t/z | s/z + fmul %st(3),%st(0) // t | s | 1/z | t/z | s/z + fxch %st(1) // s | t | 1/z | t/z | s/z + fistpl s // 1/z | t | t/z | s/z + fistpl t // 1/z | t/z | s/z + + fildl spancountminus1 + + flds C(d_tdivzstepu) // C(d_tdivzstepu) | spancountminus1 + flds C(d_zistepu) // C(d_zistepu) | C(d_tdivzstepu) | spancountminus1 + fmul %st(2),%st(0) // C(d_zistepu)*scm1 | C(d_tdivzstepu) | scm1 + fxch %st(1) // C(d_tdivzstepu) | C(d_zistepu)*scm1 | scm1 + fmul %st(2),%st(0) // C(d_tdivzstepu)*scm1 | C(d_zistepu)*scm1 | scm1 + fxch %st(2) // scm1 | C(d_zistepu)*scm1 | C(d_tdivzstepu)*scm1 + fmuls C(d_sdivzstepu) // C(d_sdivzstepu)*scm1 | C(d_zistepu)*scm1 | + // C(d_tdivzstepu)*scm1 + fxch %st(1) // C(d_zistepu)*scm1 | C(d_sdivzstepu)*scm1 | + // C(d_tdivzstepu)*scm1 + faddp %st(0),%st(3) // C(d_sdivzstepu)*scm1 | C(d_tdivzstepu)*scm1 + fxch %st(1) // C(d_tdivzstepu)*scm1 | C(d_sdivzstepu)*scm1 + faddp %st(0),%st(3) // C(d_sdivzstepu)*scm1 + faddp %st(0),%st(3) + + flds fp_64k + fdiv %st(1),%st(0) // this is what we've gone to all this trouble to + // overlap + jmp LFDIVInFlight1 + +LCleanup1: +// finish up the s and t calcs + fxch %st(1) // z*64k | 1/z | t/z | s/z + + fld %st(0) // z*64k | z*64k | 1/z | t/z | s/z + fmul %st(4),%st(0) // s | z*64k | 1/z | t/z | s/z + fxch %st(1) // z*64k | s | 1/z | t/z | s/z + fmul %st(3),%st(0) // t | s | 1/z | t/z | s/z + fxch %st(1) // s | t | 1/z | t/z | s/z + fistpl s // 1/z | t | t/z | s/z + fistpl t // 1/z | t/z | s/z + jmp LFDIVInFlight1 + + .align 4 +LSetupNotLast1: +// finish up the s and t calcs + fxch %st(1) // z*64k | 1/z | t/z | s/z + + fld %st(0) // z*64k | z*64k | 1/z | t/z | s/z + fmul %st(4),%st(0) // s | z*64k | 1/z | t/z | s/z + fxch %st(1) // z*64k | s | 1/z | t/z | s/z + fmul %st(3),%st(0) // t | s | 1/z | t/z | s/z + fxch %st(1) // s | t | 1/z | t/z | s/z + fistpl s // 1/z | t | t/z | s/z + fistpl t // 1/z | t/z | s/z + + fadds zi8stepu + fxch %st(2) + fadds sdivz8stepu + fxch %st(2) + flds tdivz8stepu + faddp %st(0),%st(2) + flds fp_64k + fdiv %st(1),%st(0) // z = 1/1/z + // this is what we've gone to all this trouble to + // overlap +LFDIVInFlight1: + + addl s,%esi + addl t,%edx + movl C(bbextents),%ebx + movl C(bbextentt),%ebp + cmpl %ebx,%esi + ja LClampHighOrLow0 +LClampReentry0: + movl %esi,s + movl pbase,%ebx + shll $16,%esi + cmpl %ebp,%edx + movl %esi,sfracf + ja LClampHighOrLow1 +LClampReentry1: + movl %edx,t + movl s,%esi // sfrac = scans->sfrac; + shll $16,%edx + movl t,%eax // tfrac = scans->tfrac; + sarl $16,%esi + movl %edx,tfracf + +// +// calculate the texture starting address +// + sarl $16,%eax + movl C(cachewidth),%edx + imull %edx,%eax // (tfrac >> 16) * cachewidth + addl %ebx,%esi + addl %eax,%esi // psource = pbase + (sfrac >> 16) + + // ((tfrac >> 16) * cachewidth); + +// +// determine whether last span or not +// + cmpl $8,%ecx + jna LLastSegment + +// +// not the last segment; do full 8-wide segment +// +LNotLastSegment: + +// +// advance s/z, t/z, and 1/z, and calculate s & t at end of span and steps to +// get there +// + +// pick up after the FDIV that was left in flight previously + + fld %st(0) // duplicate it + fmul %st(4),%st(0) // s = s/z * z + fxch %st(1) + fmul %st(3),%st(0) // t = t/z * z + fxch %st(1) + fistpl snext + fistpl tnext + movl snext,%eax + movl tnext,%edx + + movb (%esi),%bl // get first source texel + subl $8,%ecx // count off this segments' pixels + movl C(sadjust),%ebp + movl %ecx,counttemp // remember count of remaining pixels + + movl C(tadjust),%ecx + movb %bl,(%edi) // store first dest pixel + + addl %eax,%ebp + addl %edx,%ecx + + movl C(bbextents),%eax + movl C(bbextentt),%edx + + cmpl $2048,%ebp + jl LClampLow2 + cmpl %eax,%ebp + ja LClampHigh2 +LClampReentry2: + + cmpl $2048,%ecx + jl LClampLow3 + cmpl %edx,%ecx + ja LClampHigh3 +LClampReentry3: + + movl %ebp,snext + movl %ecx,tnext + + subl s,%ebp + subl t,%ecx + +// +// set up advancetable +// + movl %ecx,%eax + movl %ebp,%edx + sarl $19,%eax // tstep >>= 16; + jz LZero + sarl $19,%edx // sstep >>= 16; + movl C(cachewidth),%ebx + imull %ebx,%eax + jmp LSetUp1 + +LZero: + sarl $19,%edx // sstep >>= 16; + movl C(cachewidth),%ebx + +LSetUp1: + + addl %edx,%eax // add in sstep + // (tstep >> 16) * cachewidth + (sstep >> 16); + movl tfracf,%edx + movl %eax,advancetable+4 // advance base in t + addl %ebx,%eax // ((tstep >> 16) + 1) * cachewidth + + // (sstep >> 16); + shll $13,%ebp // left-justify sstep fractional part + movl sfracf,%ebx + shll $13,%ecx // left-justify tstep fractional part + movl %eax,advancetable // advance extra in t + + movl %ecx,tstep + addl %ecx,%edx // advance tfrac fractional part by tstep frac + + sbbl %ecx,%ecx // turn tstep carry into -1 (0 if none) + addl %ebp,%ebx // advance sfrac fractional part by sstep frac + adcl advancetable+4(,%ecx,4),%esi // point to next source texel + + addl tstep,%edx + sbbl %ecx,%ecx + movb (%esi),%al + addl %ebp,%ebx + movb %al,1(%edi) + adcl advancetable+4(,%ecx,4),%esi + + addl tstep,%edx + sbbl %ecx,%ecx + addl %ebp,%ebx + movb (%esi),%al + adcl advancetable+4(,%ecx,4),%esi + + addl tstep,%edx + sbbl %ecx,%ecx + movb %al,2(%edi) + addl %ebp,%ebx + movb (%esi),%al + adcl advancetable+4(,%ecx,4),%esi + + addl tstep,%edx + sbbl %ecx,%ecx + movb %al,3(%edi) + addl %ebp,%ebx + movb (%esi),%al + adcl advancetable+4(,%ecx,4),%esi + + +// +// start FDIV for end of next segment in flight, so it can overlap +// + movl counttemp,%ecx + cmpl $8,%ecx // more than one segment after this? + ja LSetupNotLast2 // yes + + decl %ecx + jz LFDIVInFlight2 // if only one pixel, no need to start an FDIV + movl %ecx,spancountminus1 + fildl spancountminus1 + + flds C(d_zistepu) // C(d_zistepu) | spancountminus1 + fmul %st(1),%st(0) // C(d_zistepu)*scm1 | scm1 + flds C(d_tdivzstepu) // C(d_tdivzstepu) | C(d_zistepu)*scm1 | scm1 + fmul %st(2),%st(0) // C(d_tdivzstepu)*scm1 | C(d_zistepu)*scm1 | scm1 + fxch %st(1) // C(d_zistepu)*scm1 | C(d_tdivzstepu)*scm1 | scm1 + faddp %st(0),%st(3) // C(d_tdivzstepu)*scm1 | scm1 + fxch %st(1) // scm1 | C(d_tdivzstepu)*scm1 + fmuls C(d_sdivzstepu) // C(d_sdivzstepu)*scm1 | C(d_tdivzstepu)*scm1 + fxch %st(1) // C(d_tdivzstepu)*scm1 | C(d_sdivzstepu)*scm1 + faddp %st(0),%st(3) // C(d_sdivzstepu)*scm1 + flds fp_64k // 64k | C(d_sdivzstepu)*scm1 + fxch %st(1) // C(d_sdivzstepu)*scm1 | 64k + faddp %st(0),%st(4) // 64k + + fdiv %st(1),%st(0) // this is what we've gone to all this trouble to + // overlap + jmp LFDIVInFlight2 + + .align 4 +LSetupNotLast2: + fadds zi8stepu + fxch %st(2) + fadds sdivz8stepu + fxch %st(2) + flds tdivz8stepu + faddp %st(0),%st(2) + flds fp_64k + fdiv %st(1),%st(0) // z = 1/1/z + // this is what we've gone to all this trouble to + // overlap +LFDIVInFlight2: + movl %ecx,counttemp + + addl tstep,%edx + sbbl %ecx,%ecx + movb %al,4(%edi) + addl %ebp,%ebx + movb (%esi),%al + adcl advancetable+4(,%ecx,4),%esi + + addl tstep,%edx + sbbl %ecx,%ecx + movb %al,5(%edi) + addl %ebp,%ebx + movb (%esi),%al + adcl advancetable+4(,%ecx,4),%esi + + addl tstep,%edx + sbbl %ecx,%ecx + movb %al,6(%edi) + addl %ebp,%ebx + movb (%esi),%al + adcl advancetable+4(,%ecx,4),%esi + + addl $8,%edi + movl %edx,tfracf + movl snext,%edx + movl %ebx,sfracf + movl tnext,%ebx + movl %edx,s + movl %ebx,t + + movl counttemp,%ecx // retrieve count + +// +// determine whether last span or not +// + cmpl $8,%ecx // are there multiple segments remaining? + movb %al,-1(%edi) + ja LNotLastSegment // yes + +// +// last segment of scan +// +LLastSegment: + +// +// advance s/z, t/z, and 1/z, and calculate s & t at end of span and steps to +// get there. The number of pixels left is variable, and we want to land on the +// last pixel, not step one past it, so we can't run into arithmetic problems +// + testl %ecx,%ecx + jz LNoSteps // just draw the last pixel and we're done + +// pick up after the FDIV that was left in flight previously + + + fld %st(0) // duplicate it + fmul %st(4),%st(0) // s = s/z * z + fxch %st(1) + fmul %st(3),%st(0) // t = t/z * z + fxch %st(1) + fistpl snext + fistpl tnext + + movb (%esi),%al // load first texel in segment + movl C(tadjust),%ebx + movb %al,(%edi) // store first pixel in segment + movl C(sadjust),%eax + + addl snext,%eax + addl tnext,%ebx + + movl C(bbextents),%ebp + movl C(bbextentt),%edx + + cmpl $2048,%eax + jl LClampLow4 + cmpl %ebp,%eax + ja LClampHigh4 +LClampReentry4: + movl %eax,snext + + cmpl $2048,%ebx + jl LClampLow5 + cmpl %edx,%ebx + ja LClampHigh5 +LClampReentry5: + + cmpl $1,%ecx // don't bother + je LOnlyOneStep // if two pixels in segment, there's only one step, + // of the segment length + subl s,%eax + subl t,%ebx + + addl %eax,%eax // convert to 15.17 format so multiply by 1.31 + addl %ebx,%ebx // reciprocal yields 16.48 + + imull reciprocal_table-8(,%ecx,4) // sstep = (snext - s) / (spancount-1) + movl %edx,%ebp + + movl %ebx,%eax + imull reciprocal_table-8(,%ecx,4) // tstep = (tnext - t) / (spancount-1) + +LSetEntryvec: +// +// set up advancetable +// + movl entryvec_table(,%ecx,4),%ebx + movl %edx,%eax + movl %ebx,jumptemp // entry point into code for RET later + movl %ebp,%ecx + sarl $16,%edx // tstep >>= 16; + movl C(cachewidth),%ebx + sarl $16,%ecx // sstep >>= 16; + imull %ebx,%edx + + addl %ecx,%edx // add in sstep + // (tstep >> 16) * cachewidth + (sstep >> 16); + movl tfracf,%ecx + movl %edx,advancetable+4 // advance base in t + addl %ebx,%edx // ((tstep >> 16) + 1) * cachewidth + + // (sstep >> 16); + shll $16,%ebp // left-justify sstep fractional part + movl sfracf,%ebx + shll $16,%eax // left-justify tstep fractional part + movl %edx,advancetable // advance extra in t + + movl %eax,tstep + movl %ecx,%edx + addl %eax,%edx + sbbl %ecx,%ecx + addl %ebp,%ebx + adcl advancetable+4(,%ecx,4),%esi + + jmp *jumptemp // jump to the number-of-pixels handler + +//---------------------------------------- + +LNoSteps: + movb (%esi),%al // load first texel in segment + subl $7,%edi // adjust for hardwired offset + jmp LEndSpan + + +LOnlyOneStep: + subl s,%eax + subl t,%ebx + movl %eax,%ebp + movl %ebx,%edx + jmp LSetEntryvec + +//---------------------------------------- + +.globl Entry2_8 +Entry2_8: + subl $6,%edi // adjust for hardwired offsets + movb (%esi),%al + jmp LLEntry2_8 + +//---------------------------------------- + +.globl Entry3_8 +Entry3_8: + subl $5,%edi // adjust for hardwired offsets + addl %eax,%edx + movb (%esi),%al + sbbl %ecx,%ecx + addl %ebp,%ebx + adcl advancetable+4(,%ecx,4),%esi + jmp LLEntry3_8 + +//---------------------------------------- + +.globl Entry4_8 +Entry4_8: + subl $4,%edi // adjust for hardwired offsets + addl %eax,%edx + movb (%esi),%al + sbbl %ecx,%ecx + addl %ebp,%ebx + adcl advancetable+4(,%ecx,4),%esi + addl tstep,%edx + jmp LLEntry4_8 + +//---------------------------------------- + +.globl Entry5_8 +Entry5_8: + subl $3,%edi // adjust for hardwired offsets + addl %eax,%edx + movb (%esi),%al + sbbl %ecx,%ecx + addl %ebp,%ebx + adcl advancetable+4(,%ecx,4),%esi + addl tstep,%edx + jmp LLEntry5_8 + +//---------------------------------------- + +.globl Entry6_8 +Entry6_8: + subl $2,%edi // adjust for hardwired offsets + addl %eax,%edx + movb (%esi),%al + sbbl %ecx,%ecx + addl %ebp,%ebx + adcl advancetable+4(,%ecx,4),%esi + addl tstep,%edx + jmp LLEntry6_8 + +//---------------------------------------- + +.globl Entry7_8 +Entry7_8: + decl %edi // adjust for hardwired offsets + addl %eax,%edx + movb (%esi),%al + sbbl %ecx,%ecx + addl %ebp,%ebx + adcl advancetable+4(,%ecx,4),%esi + addl tstep,%edx + jmp LLEntry7_8 + +//---------------------------------------- + +.globl Entry8_8 +Entry8_8: + addl %eax,%edx + movb (%esi),%al + sbbl %ecx,%ecx + addl %ebp,%ebx + adcl advancetable+4(,%ecx,4),%esi + + addl tstep,%edx + sbbl %ecx,%ecx + movb %al,1(%edi) + addl %ebp,%ebx + movb (%esi),%al + adcl advancetable+4(,%ecx,4),%esi + addl tstep,%edx +LLEntry7_8: + sbbl %ecx,%ecx + movb %al,2(%edi) + addl %ebp,%ebx + movb (%esi),%al + adcl advancetable+4(,%ecx,4),%esi + addl tstep,%edx +LLEntry6_8: + sbbl %ecx,%ecx + movb %al,3(%edi) + addl %ebp,%ebx + movb (%esi),%al + adcl advancetable+4(,%ecx,4),%esi + addl tstep,%edx +LLEntry5_8: + sbbl %ecx,%ecx + movb %al,4(%edi) + addl %ebp,%ebx + movb (%esi),%al + adcl advancetable+4(,%ecx,4),%esi + addl tstep,%edx +LLEntry4_8: + sbbl %ecx,%ecx + movb %al,5(%edi) + addl %ebp,%ebx + movb (%esi),%al + adcl advancetable+4(,%ecx,4),%esi +LLEntry3_8: + movb %al,6(%edi) + movb (%esi),%al +LLEntry2_8: + +LEndSpan: + +// +// clear s/z, t/z, 1/z from FP stack +// + fstp %st(0) + fstp %st(0) + fstp %st(0) + + movl pspantemp,%ebx // restore spans pointer + movl espan_t_pnext(%ebx),%ebx // point to next span + testl %ebx,%ebx // any more spans? + movb %al,7(%edi) + jnz LSpanLoop // more spans + + popl %ebx // restore register variables + popl %esi + popl %edi + popl %ebp // restore the caller's stack frame + ret + +//---------------------------------------------------------------------- +// 8-bpp horizontal span z drawing codefor polygons, with no transparency. +// +// Assumes there is at least one span in pzspans, and that every span +// contains at least one pixel +//---------------------------------------------------------------------- + + .text + +// z-clamp on a non-negative gradient span +LClamp: + movl $0x40000000,%edx + xorl %ebx,%ebx + fstp %st(0) + jmp LZDraw + +// z-clamp on a negative gradient span +LClampNeg: + movl $0x40000000,%edx + xorl %ebx,%ebx + fstp %st(0) + jmp LZDrawNeg + + +#define pzspans 4+16 + +.globl C(D_DrawZSpans) +C(D_DrawZSpans): + pushl %ebp // preserve caller's stack frame + pushl %edi + pushl %esi // preserve register variables + pushl %ebx + + flds C(d_zistepu) + movl C(d_zistepu),%eax + movl pzspans(%esp),%esi + testl %eax,%eax + jz LFNegSpan + + fmuls Float2ToThe31nd + fistpl izistep // note: we are relying on FP exceptions being turned + // off here to avoid range problems + movl izistep,%ebx // remains loaded for all spans + +LFSpanLoop: +// set up the initial 1/z value + fildl espan_t_v(%esi) + fildl espan_t_u(%esi) + movl espan_t_v(%esi),%ecx + movl C(d_pzbuffer),%edi + fmuls C(d_zistepu) + fxch %st(1) + fmuls C(d_zistepv) + fxch %st(1) + fadds C(d_ziorigin) + imull C(d_zrowbytes),%ecx + faddp %st(0),%st(1) + +// clamp if z is nearer than 2 (1/z > 0.5) + fcoms float_point5 + addl %ecx,%edi + movl espan_t_u(%esi),%edx + addl %edx,%edx // word count + movl espan_t_count(%esi),%ecx + addl %edx,%edi // pdest = &pdestspan[scans->u]; + pushl %esi // preserve spans pointer + fnstsw %ax + testb $0x45,%ah + jz LClamp + + fmuls Float2ToThe31nd + fistpl izi // note: we are relying on FP exceptions being turned + // off here to avoid problems when the span is closer + // than 1/(2**31) + movl izi,%edx + +// at this point: +// %ebx = izistep +// %ecx = count +// %edx = izi +// %edi = pdest + +LZDraw: + +// do a single pixel up front, if necessary to dword align the destination + testl $2,%edi + jz LFMiddle + movl %edx,%eax + addl %ebx,%edx + shrl $16,%eax + decl %ecx + movw %ax,(%edi) + addl $2,%edi + +// do middle a pair of aligned dwords at a time +LFMiddle: + pushl %ecx + shrl $1,%ecx // count / 2 + jz LFLast // no aligned dwords to do + shrl $1,%ecx // (count / 2) / 2 + jnc LFMiddleLoop // even number of aligned dwords to do + + movl %edx,%eax + addl %ebx,%edx + shrl $16,%eax + movl %edx,%esi + addl %ebx,%edx + andl $0xFFFF0000,%esi + orl %esi,%eax + movl %eax,(%edi) + addl $4,%edi + andl %ecx,%ecx + jz LFLast + +LFMiddleLoop: + movl %edx,%eax + addl %ebx,%edx + shrl $16,%eax + movl %edx,%esi + addl %ebx,%edx + andl $0xFFFF0000,%esi + orl %esi,%eax + movl %edx,%ebp + movl %eax,(%edi) + addl %ebx,%edx + shrl $16,%ebp + movl %edx,%esi + addl %ebx,%edx + andl $0xFFFF0000,%esi + orl %esi,%ebp + movl %ebp,4(%edi) // FIXME: eliminate register contention + addl $8,%edi + + decl %ecx + jnz LFMiddleLoop + +LFLast: + popl %ecx // retrieve count + popl %esi // retrieve span pointer + +// do the last, unaligned pixel, if there is one + andl $1,%ecx // is there an odd pixel left to do? + jz LFSpanDone // no + shrl $16,%edx + movw %dx,(%edi) // do the final pixel's z + +LFSpanDone: + movl espan_t_pnext(%esi),%esi + testl %esi,%esi + jnz LFSpanLoop + + jmp LFDone + +LFNegSpan: + fmuls FloatMinus2ToThe31nd + fistpl izistep // note: we are relying on FP exceptions being turned + // off here to avoid range problems + movl izistep,%ebx // remains loaded for all spans + +LFNegSpanLoop: +// set up the initial 1/z value + fildl espan_t_v(%esi) + fildl espan_t_u(%esi) + movl espan_t_v(%esi),%ecx + movl C(d_pzbuffer),%edi + fmuls C(d_zistepu) + fxch %st(1) + fmuls C(d_zistepv) + fxch %st(1) + fadds C(d_ziorigin) + imull C(d_zrowbytes),%ecx + faddp %st(0),%st(1) + +// clamp if z is nearer than 2 (1/z > 0.5) + fcoms float_point5 + addl %ecx,%edi + movl espan_t_u(%esi),%edx + addl %edx,%edx // word count + movl espan_t_count(%esi),%ecx + addl %edx,%edi // pdest = &pdestspan[scans->u]; + pushl %esi // preserve spans pointer + fnstsw %ax + testb $0x45,%ah + jz LClampNeg + + fmuls Float2ToThe31nd + fistpl izi // note: we are relying on FP exceptions being turned + // off here to avoid problems when the span is closer + // than 1/(2**31) + movl izi,%edx + +// at this point: +// %ebx = izistep +// %ecx = count +// %edx = izi +// %edi = pdest + +LZDrawNeg: + +// do a single pixel up front, if necessary to dword align the destination + testl $2,%edi + jz LFNegMiddle + movl %edx,%eax + subl %ebx,%edx + shrl $16,%eax + decl %ecx + movw %ax,(%edi) + addl $2,%edi + +// do middle a pair of aligned dwords at a time +LFNegMiddle: + pushl %ecx + shrl $1,%ecx // count / 2 + jz LFNegLast // no aligned dwords to do + shrl $1,%ecx // (count / 2) / 2 + jnc LFNegMiddleLoop // even number of aligned dwords to do + + movl %edx,%eax + subl %ebx,%edx + shrl $16,%eax + movl %edx,%esi + subl %ebx,%edx + andl $0xFFFF0000,%esi + orl %esi,%eax + movl %eax,(%edi) + addl $4,%edi + andl %ecx,%ecx + jz LFNegLast + +LFNegMiddleLoop: + movl %edx,%eax + subl %ebx,%edx + shrl $16,%eax + movl %edx,%esi + subl %ebx,%edx + andl $0xFFFF0000,%esi + orl %esi,%eax + movl %edx,%ebp + movl %eax,(%edi) + subl %ebx,%edx + shrl $16,%ebp + movl %edx,%esi + subl %ebx,%edx + andl $0xFFFF0000,%esi + orl %esi,%ebp + movl %ebp,4(%edi) // FIXME: eliminate register contention + addl $8,%edi + + decl %ecx + jnz LFNegMiddleLoop + +LFNegLast: + popl %ecx // retrieve count + popl %esi // retrieve span pointer + +// do the last, unaligned pixel, if there is one + andl $1,%ecx // is there an odd pixel left to do? + jz LFNegSpanDone // no + shrl $16,%edx + movw %dx,(%edi) // do the final pixel's z + +LFNegSpanDone: + movl espan_t_pnext(%esi),%esi + testl %esi,%esi + jnz LFNegSpanLoop + +LFDone: + popl %ebx // restore register variables + popl %esi + popl %edi + popl %ebp // restore the caller's stack frame + ret + +#endif // id386 diff --git a/contrib/other/sdlquake-1.0.9/d_draw16.S b/contrib/other/sdlquake-1.0.9/d_draw16.S new file mode 100644 index 000000000..cccfdbfe4 --- /dev/null +++ b/contrib/other/sdlquake-1.0.9/d_draw16.S @@ -0,0 +1,974 @@ +/* +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. + +*/ +// +// d_draw16.s +// x86 assembly-language horizontal 8-bpp span-drawing code, with 16-pixel +// subdivision. +// + +#include "asm_i386.h" +#include "quakeasm.h" +#include "asm_draw.h" +#include "d_ifacea.h" + +#if id386 + +//---------------------------------------------------------------------- +// 8-bpp horizontal span drawing code for polygons, with no transparency and +// 16-pixel subdivision. +// +// Assumes there is at least one span in pspans, and that every span +// contains at least one pixel +//---------------------------------------------------------------------- + + .data + + .text + +// out-of-line, rarely-needed clamping code + +LClampHigh0: + movl C(bbextents),%esi + jmp LClampReentry0 +LClampHighOrLow0: + jg LClampHigh0 + xorl %esi,%esi + jmp LClampReentry0 + +LClampHigh1: + movl C(bbextentt),%edx + jmp LClampReentry1 +LClampHighOrLow1: + jg LClampHigh1 + xorl %edx,%edx + jmp LClampReentry1 + +LClampLow2: + movl $4096,%ebp + jmp LClampReentry2 +LClampHigh2: + movl C(bbextents),%ebp + jmp LClampReentry2 + +LClampLow3: + movl $4096,%ecx + jmp LClampReentry3 +LClampHigh3: + movl C(bbextentt),%ecx + jmp LClampReentry3 + +LClampLow4: + movl $4096,%eax + jmp LClampReentry4 +LClampHigh4: + movl C(bbextents),%eax + jmp LClampReentry4 + +LClampLow5: + movl $4096,%ebx + jmp LClampReentry5 +LClampHigh5: + movl C(bbextentt),%ebx + jmp LClampReentry5 + + +#define pspans 4+16 + + .align 4 +.globl C(D_DrawSpans16) +C(D_DrawSpans16): + pushl %ebp // preserve caller's stack frame + pushl %edi + pushl %esi // preserve register variables + pushl %ebx + +// +// set up scaled-by-16 steps, for 16-long segments; also set up cacheblock +// and span list pointers +// +// TODO: any overlap from rearranging? + flds C(d_sdivzstepu) + fmuls fp_16 + movl C(cacheblock),%edx + flds C(d_tdivzstepu) + fmuls fp_16 + movl pspans(%esp),%ebx // point to the first span descriptor + flds C(d_zistepu) + fmuls fp_16 + movl %edx,pbase // pbase = cacheblock + fstps zi16stepu + fstps tdivz16stepu + fstps sdivz16stepu + +LSpanLoop: +// +// set up the initial s/z, t/z, and 1/z on the FP stack, and generate the +// initial s and t values +// +// FIXME: pipeline FILD? + fildl espan_t_v(%ebx) + fildl espan_t_u(%ebx) + + fld %st(1) // dv | du | dv + fmuls C(d_sdivzstepv) // dv*d_sdivzstepv | du | dv + fld %st(1) // du | dv*d_sdivzstepv | du | dv + fmuls C(d_sdivzstepu) // du*d_sdivzstepu | dv*d_sdivzstepv | du | dv + fld %st(2) // du | du*d_sdivzstepu | dv*d_sdivzstepv | du | dv + fmuls C(d_tdivzstepu) // du*d_tdivzstepu | du*d_sdivzstepu | + // dv*d_sdivzstepv | du | dv + fxch %st(1) // du*d_sdivzstepu | du*d_tdivzstepu | + // dv*d_sdivzstepv | du | dv + faddp %st(0),%st(2) // du*d_tdivzstepu | + // du*d_sdivzstepu + dv*d_sdivzstepv | du | dv + fxch %st(1) // du*d_sdivzstepu + dv*d_sdivzstepv | + // du*d_tdivzstepu | du | dv + fld %st(3) // dv | du*d_sdivzstepu + dv*d_sdivzstepv | + // du*d_tdivzstepu | du | dv + fmuls C(d_tdivzstepv) // dv*d_tdivzstepv | + // du*d_sdivzstepu + dv*d_sdivzstepv | + // du*d_tdivzstepu | du | dv + fxch %st(1) // du*d_sdivzstepu + dv*d_sdivzstepv | + // dv*d_tdivzstepv | du*d_tdivzstepu | du | dv + fadds C(d_sdivzorigin) // sdivz = d_sdivzorigin + dv*d_sdivzstepv + + // du*d_sdivzstepu; stays in %st(2) at end + fxch %st(4) // dv | dv*d_tdivzstepv | du*d_tdivzstepu | du | + // s/z + fmuls C(d_zistepv) // dv*d_zistepv | dv*d_tdivzstepv | + // du*d_tdivzstepu | du | s/z + fxch %st(1) // dv*d_tdivzstepv | dv*d_zistepv | + // du*d_tdivzstepu | du | s/z + faddp %st(0),%st(2) // dv*d_zistepv | + // dv*d_tdivzstepv + du*d_tdivzstepu | du | s/z + fxch %st(2) // du | dv*d_tdivzstepv + du*d_tdivzstepu | + // dv*d_zistepv | s/z + fmuls C(d_zistepu) // du*d_zistepu | + // dv*d_tdivzstepv + du*d_tdivzstepu | + // dv*d_zistepv | s/z + fxch %st(1) // dv*d_tdivzstepv + du*d_tdivzstepu | + // du*d_zistepu | dv*d_zistepv | s/z + fadds C(d_tdivzorigin) // tdivz = d_tdivzorigin + dv*d_tdivzstepv + + // du*d_tdivzstepu; stays in %st(1) at end + fxch %st(2) // dv*d_zistepv | du*d_zistepu | t/z | s/z + faddp %st(0),%st(1) // dv*d_zistepv + du*d_zistepu | t/z | s/z + + flds fp_64k // fp_64k | dv*d_zistepv + du*d_zistepu | t/z | s/z + fxch %st(1) // dv*d_zistepv + du*d_zistepu | fp_64k | t/z | s/z + fadds C(d_ziorigin) // zi = d_ziorigin + dv*d_zistepv + + // du*d_zistepu; stays in %st(0) at end + // 1/z | fp_64k | t/z | s/z +// +// calculate and clamp s & t +// + fdivr %st(0),%st(1) // 1/z | z*64k | t/z | s/z + +// +// point %edi to the first pixel in the span +// + movl C(d_viewbuffer),%ecx + movl espan_t_v(%ebx),%eax + movl %ebx,pspantemp // preserve spans pointer + + movl C(tadjust),%edx + movl C(sadjust),%esi + movl C(d_scantable)(,%eax,4),%edi // v * screenwidth + addl %ecx,%edi + movl espan_t_u(%ebx),%ecx + addl %ecx,%edi // pdest = &pdestspan[scans->u]; + movl espan_t_count(%ebx),%ecx + +// +// now start the FDIV for the end of the span +// + cmpl $16,%ecx + ja LSetupNotLast1 + + decl %ecx + jz LCleanup1 // if only one pixel, no need to start an FDIV + movl %ecx,spancountminus1 + +// finish up the s and t calcs + fxch %st(1) // z*64k | 1/z | t/z | s/z + + fld %st(0) // z*64k | z*64k | 1/z | t/z | s/z + fmul %st(4),%st(0) // s | z*64k | 1/z | t/z | s/z + fxch %st(1) // z*64k | s | 1/z | t/z | s/z + fmul %st(3),%st(0) // t | s | 1/z | t/z | s/z + fxch %st(1) // s | t | 1/z | t/z | s/z + fistpl s // 1/z | t | t/z | s/z + fistpl t // 1/z | t/z | s/z + + fildl spancountminus1 + + flds C(d_tdivzstepu) // C(d_tdivzstepu) | spancountminus1 + flds C(d_zistepu) // C(d_zistepu) | C(d_tdivzstepu) | spancountminus1 + fmul %st(2),%st(0) // C(d_zistepu)*scm1 | C(d_tdivzstepu) | scm1 + fxch %st(1) // C(d_tdivzstepu) | C(d_zistepu)*scm1 | scm1 + fmul %st(2),%st(0) // C(d_tdivzstepu)*scm1 | C(d_zistepu)*scm1 | scm1 + fxch %st(2) // scm1 | C(d_zistepu)*scm1 | C(d_tdivzstepu)*scm1 + fmuls C(d_sdivzstepu) // C(d_sdivzstepu)*scm1 | C(d_zistepu)*scm1 | + // C(d_tdivzstepu)*scm1 + fxch %st(1) // C(d_zistepu)*scm1 | C(d_sdivzstepu)*scm1 | + // C(d_tdivzstepu)*scm1 + faddp %st(0),%st(3) // C(d_sdivzstepu)*scm1 | C(d_tdivzstepu)*scm1 + fxch %st(1) // C(d_tdivzstepu)*scm1 | C(d_sdivzstepu)*scm1 + faddp %st(0),%st(3) // C(d_sdivzstepu)*scm1 + faddp %st(0),%st(3) + + flds fp_64k + fdiv %st(1),%st(0) // this is what we've gone to all this trouble to + // overlap + jmp LFDIVInFlight1 + +LCleanup1: +// finish up the s and t calcs + fxch %st(1) // z*64k | 1/z | t/z | s/z + + fld %st(0) // z*64k | z*64k | 1/z | t/z | s/z + fmul %st(4),%st(0) // s | z*64k | 1/z | t/z | s/z + fxch %st(1) // z*64k | s | 1/z | t/z | s/z + fmul %st(3),%st(0) // t | s | 1/z | t/z | s/z + fxch %st(1) // s | t | 1/z | t/z | s/z + fistpl s // 1/z | t | t/z | s/z + fistpl t // 1/z | t/z | s/z + jmp LFDIVInFlight1 + + .align 4 +LSetupNotLast1: +// finish up the s and t calcs + fxch %st(1) // z*64k | 1/z | t/z | s/z + + fld %st(0) // z*64k | z*64k | 1/z | t/z | s/z + fmul %st(4),%st(0) // s | z*64k | 1/z | t/z | s/z + fxch %st(1) // z*64k | s | 1/z | t/z | s/z + fmul %st(3),%st(0) // t | s | 1/z | t/z | s/z + fxch %st(1) // s | t | 1/z | t/z | s/z + fistpl s // 1/z | t | t/z | s/z + fistpl t // 1/z | t/z | s/z + + fadds zi16stepu + fxch %st(2) + fadds sdivz16stepu + fxch %st(2) + flds tdivz16stepu + faddp %st(0),%st(2) + flds fp_64k + fdiv %st(1),%st(0) // z = 1/1/z + // this is what we've gone to all this trouble to + // overlap +LFDIVInFlight1: + + addl s,%esi + addl t,%edx + movl C(bbextents),%ebx + movl C(bbextentt),%ebp + cmpl %ebx,%esi + ja LClampHighOrLow0 +LClampReentry0: + movl %esi,s + movl pbase,%ebx + shll $16,%esi + cmpl %ebp,%edx + movl %esi,sfracf + ja LClampHighOrLow1 +LClampReentry1: + movl %edx,t + movl s,%esi // sfrac = scans->sfrac; + shll $16,%edx + movl t,%eax // tfrac = scans->tfrac; + sarl $16,%esi + movl %edx,tfracf + +// +// calculate the texture starting address +// + sarl $16,%eax + movl C(cachewidth),%edx + imull %edx,%eax // (tfrac >> 16) * cachewidth + addl %ebx,%esi + addl %eax,%esi // psource = pbase + (sfrac >> 16) + + // ((tfrac >> 16) * cachewidth); +// +// determine whether last span or not +// + cmpl $16,%ecx + jna LLastSegment + +// +// not the last segment; do full 16-wide segment +// +LNotLastSegment: + +// +// advance s/z, t/z, and 1/z, and calculate s & t at end of span and steps to +// get there +// + +// pick up after the FDIV that was left in flight previously + + fld %st(0) // duplicate it + fmul %st(4),%st(0) // s = s/z * z + fxch %st(1) + fmul %st(3),%st(0) // t = t/z * z + fxch %st(1) + fistpl snext + fistpl tnext + movl snext,%eax + movl tnext,%edx + + movb (%esi),%bl // get first source texel + subl $16,%ecx // count off this segments' pixels + movl C(sadjust),%ebp + movl %ecx,counttemp // remember count of remaining pixels + + movl C(tadjust),%ecx + movb %bl,(%edi) // store first dest pixel + + addl %eax,%ebp + addl %edx,%ecx + + movl C(bbextents),%eax + movl C(bbextentt),%edx + + cmpl $4096,%ebp + jl LClampLow2 + cmpl %eax,%ebp + ja LClampHigh2 +LClampReentry2: + + cmpl $4096,%ecx + jl LClampLow3 + cmpl %edx,%ecx + ja LClampHigh3 +LClampReentry3: + + movl %ebp,snext + movl %ecx,tnext + + subl s,%ebp + subl t,%ecx + +// +// set up advancetable +// + movl %ecx,%eax + movl %ebp,%edx + sarl $20,%eax // tstep >>= 16; + jz LZero + sarl $20,%edx // sstep >>= 16; + movl C(cachewidth),%ebx + imull %ebx,%eax + jmp LSetUp1 + +LZero: + sarl $20,%edx // sstep >>= 16; + movl C(cachewidth),%ebx + +LSetUp1: + + addl %edx,%eax // add in sstep + // (tstep >> 16) * cachewidth + (sstep >> 16); + movl tfracf,%edx + movl %eax,advancetable+4 // advance base in t + addl %ebx,%eax // ((tstep >> 16) + 1) * cachewidth + + // (sstep >> 16); + shll $12,%ebp // left-justify sstep fractional part + movl sfracf,%ebx + shll $12,%ecx // left-justify tstep fractional part + movl %eax,advancetable // advance extra in t + + movl %ecx,tstep + addl %ecx,%edx // advance tfrac fractional part by tstep frac + + sbbl %ecx,%ecx // turn tstep carry into -1 (0 if none) + addl %ebp,%ebx // advance sfrac fractional part by sstep frac + adcl advancetable+4(,%ecx,4),%esi // point to next source texel + + addl tstep,%edx + sbbl %ecx,%ecx + movb (%esi),%al + addl %ebp,%ebx + movb %al,1(%edi) + adcl advancetable+4(,%ecx,4),%esi + + addl tstep,%edx + sbbl %ecx,%ecx + addl %ebp,%ebx + movb (%esi),%al + adcl advancetable+4(,%ecx,4),%esi + + addl tstep,%edx + sbbl %ecx,%ecx + movb %al,2(%edi) + addl %ebp,%ebx + movb (%esi),%al + adcl advancetable+4(,%ecx,4),%esi + + addl tstep,%edx + sbbl %ecx,%ecx + movb %al,3(%edi) + addl %ebp,%ebx + movb (%esi),%al + adcl advancetable+4(,%ecx,4),%esi + + addl tstep,%edx + sbbl %ecx,%ecx + movb %al,4(%edi) + addl %ebp,%ebx + movb (%esi),%al + adcl advancetable+4(,%ecx,4),%esi + + addl tstep,%edx + sbbl %ecx,%ecx + movb %al,5(%edi) + addl %ebp,%ebx + movb (%esi),%al + adcl advancetable+4(,%ecx,4),%esi + + addl tstep,%edx + sbbl %ecx,%ecx + movb %al,6(%edi) + addl %ebp,%ebx + movb (%esi),%al + adcl advancetable+4(,%ecx,4),%esi + + addl tstep,%edx + sbbl %ecx,%ecx + movb %al,7(%edi) + addl %ebp,%ebx + movb (%esi),%al + adcl advancetable+4(,%ecx,4),%esi + + +// +// start FDIV for end of next segment in flight, so it can overlap +// + movl counttemp,%ecx + cmpl $16,%ecx // more than one segment after this? + ja LSetupNotLast2 // yes + + decl %ecx + jz LFDIVInFlight2 // if only one pixel, no need to start an FDIV + movl %ecx,spancountminus1 + fildl spancountminus1 + + flds C(d_zistepu) // C(d_zistepu) | spancountminus1 + fmul %st(1),%st(0) // C(d_zistepu)*scm1 | scm1 + flds C(d_tdivzstepu) // C(d_tdivzstepu) | C(d_zistepu)*scm1 | scm1 + fmul %st(2),%st(0) // C(d_tdivzstepu)*scm1 | C(d_zistepu)*scm1 | scm1 + fxch %st(1) // C(d_zistepu)*scm1 | C(d_tdivzstepu)*scm1 | scm1 + faddp %st(0),%st(3) // C(d_tdivzstepu)*scm1 | scm1 + fxch %st(1) // scm1 | C(d_tdivzstepu)*scm1 + fmuls C(d_sdivzstepu) // C(d_sdivzstepu)*scm1 | C(d_tdivzstepu)*scm1 + fxch %st(1) // C(d_tdivzstepu)*scm1 | C(d_sdivzstepu)*scm1 + faddp %st(0),%st(3) // C(d_sdivzstepu)*scm1 + flds fp_64k // 64k | C(d_sdivzstepu)*scm1 + fxch %st(1) // C(d_sdivzstepu)*scm1 | 64k + faddp %st(0),%st(4) // 64k + + fdiv %st(1),%st(0) // this is what we've gone to all this trouble to + // overlap + jmp LFDIVInFlight2 + + .align 4 +LSetupNotLast2: + fadds zi16stepu + fxch %st(2) + fadds sdivz16stepu + fxch %st(2) + flds tdivz16stepu + faddp %st(0),%st(2) + flds fp_64k + fdiv %st(1),%st(0) // z = 1/1/z + // this is what we've gone to all this trouble to + // overlap +LFDIVInFlight2: + movl %ecx,counttemp + + addl tstep,%edx + sbbl %ecx,%ecx + movb %al,8(%edi) + addl %ebp,%ebx + movb (%esi),%al + adcl advancetable+4(,%ecx,4),%esi + + addl tstep,%edx + sbbl %ecx,%ecx + movb %al,9(%edi) + addl %ebp,%ebx + movb (%esi),%al + adcl advancetable+4(,%ecx,4),%esi + + addl tstep,%edx + sbbl %ecx,%ecx + movb %al,10(%edi) + addl %ebp,%ebx + movb (%esi),%al + adcl advancetable+4(,%ecx,4),%esi + + addl tstep,%edx + sbbl %ecx,%ecx + movb %al,11(%edi) + addl %ebp,%ebx + movb (%esi),%al + adcl advancetable+4(,%ecx,4),%esi + + addl tstep,%edx + sbbl %ecx,%ecx + movb %al,12(%edi) + addl %ebp,%ebx + movb (%esi),%al + adcl advancetable+4(,%ecx,4),%esi + + addl tstep,%edx + sbbl %ecx,%ecx + movb %al,13(%edi) + addl %ebp,%ebx + movb (%esi),%al + adcl advancetable+4(,%ecx,4),%esi + + addl tstep,%edx + sbbl %ecx,%ecx + movb %al,14(%edi) + addl %ebp,%ebx + movb (%esi),%al + adcl advancetable+4(,%ecx,4),%esi + + addl $16,%edi + movl %edx,tfracf + movl snext,%edx + movl %ebx,sfracf + movl tnext,%ebx + movl %edx,s + movl %ebx,t + + movl counttemp,%ecx // retrieve count + +// +// determine whether last span or not +// + cmpl $16,%ecx // are there multiple segments remaining? + movb %al,-1(%edi) + ja LNotLastSegment // yes + +// +// last segment of scan +// +LLastSegment: + +// +// advance s/z, t/z, and 1/z, and calculate s & t at end of span and steps to +// get there. The number of pixels left is variable, and we want to land on the +// last pixel, not step one past it, so we can't run into arithmetic problems +// + testl %ecx,%ecx + jz LNoSteps // just draw the last pixel and we're done + +// pick up after the FDIV that was left in flight previously + + + fld %st(0) // duplicate it + fmul %st(4),%st(0) // s = s/z * z + fxch %st(1) + fmul %st(3),%st(0) // t = t/z * z + fxch %st(1) + fistpl snext + fistpl tnext + + movb (%esi),%al // load first texel in segment + movl C(tadjust),%ebx + movb %al,(%edi) // store first pixel in segment + movl C(sadjust),%eax + + addl snext,%eax + addl tnext,%ebx + + movl C(bbextents),%ebp + movl C(bbextentt),%edx + + cmpl $4096,%eax + jl LClampLow4 + cmpl %ebp,%eax + ja LClampHigh4 +LClampReentry4: + movl %eax,snext + + cmpl $4096,%ebx + jl LClampLow5 + cmpl %edx,%ebx + ja LClampHigh5 +LClampReentry5: + + cmpl $1,%ecx // don't bother + je LOnlyOneStep // if two pixels in segment, there's only one step, + // of the segment length + subl s,%eax + subl t,%ebx + + addl %eax,%eax // convert to 15.17 format so multiply by 1.31 + addl %ebx,%ebx // reciprocal yields 16.48 + + imull reciprocal_table_16-8(,%ecx,4) // sstep = (snext - s) / + // (spancount-1) + movl %edx,%ebp + + movl %ebx,%eax + imull reciprocal_table_16-8(,%ecx,4) // tstep = (tnext - t) / + // (spancount-1) +LSetEntryvec: +// +// set up advancetable +// + movl entryvec_table_16(,%ecx,4),%ebx + movl %edx,%eax + movl %ebx,jumptemp // entry point into code for RET later + movl %ebp,%ecx + sarl $16,%edx // tstep >>= 16; + movl C(cachewidth),%ebx + sarl $16,%ecx // sstep >>= 16; + imull %ebx,%edx + + addl %ecx,%edx // add in sstep + // (tstep >> 16) * cachewidth + (sstep >> 16); + movl tfracf,%ecx + movl %edx,advancetable+4 // advance base in t + addl %ebx,%edx // ((tstep >> 16) + 1) * cachewidth + + // (sstep >> 16); + shll $16,%ebp // left-justify sstep fractional part + movl sfracf,%ebx + shll $16,%eax // left-justify tstep fractional part + movl %edx,advancetable // advance extra in t + + movl %eax,tstep + movl %ecx,%edx + addl %eax,%edx + sbbl %ecx,%ecx + addl %ebp,%ebx + adcl advancetable+4(,%ecx,4),%esi + + jmp *jumptemp // jump to the number-of-pixels handler + +//---------------------------------------- + +LNoSteps: + movb (%esi),%al // load first texel in segment + subl $15,%edi // adjust for hardwired offset + jmp LEndSpan + + +LOnlyOneStep: + subl s,%eax + subl t,%ebx + movl %eax,%ebp + movl %ebx,%edx + jmp LSetEntryvec + +//---------------------------------------- + +.globl Entry2_16, Entry3_16, Entry4_16, Entry5_16 +.globl Entry6_16, Entry7_16, Entry8_16, Entry9_16 +.globl Entry10_16, Entry11_16, Entry12_16, Entry13_16 +.globl Entry14_16, Entry15_16, Entry16_16 + +Entry2_16: + subl $14,%edi // adjust for hardwired offsets + movb (%esi),%al + jmp LEntry2_16 + +//---------------------------------------- + +Entry3_16: + subl $13,%edi // adjust for hardwired offsets + addl %eax,%edx + movb (%esi),%al + sbbl %ecx,%ecx + addl %ebp,%ebx + adcl advancetable+4(,%ecx,4),%esi + jmp LEntry3_16 + +//---------------------------------------- + +Entry4_16: + subl $12,%edi // adjust for hardwired offsets + addl %eax,%edx + movb (%esi),%al + sbbl %ecx,%ecx + addl %ebp,%ebx + adcl advancetable+4(,%ecx,4),%esi + addl tstep,%edx + jmp LEntry4_16 + +//---------------------------------------- + +Entry5_16: + subl $11,%edi // adjust for hardwired offsets + addl %eax,%edx + movb (%esi),%al + sbbl %ecx,%ecx + addl %ebp,%ebx + adcl advancetable+4(,%ecx,4),%esi + addl tstep,%edx + jmp LEntry5_16 + +//---------------------------------------- + +Entry6_16: + subl $10,%edi // adjust for hardwired offsets + addl %eax,%edx + movb (%esi),%al + sbbl %ecx,%ecx + addl %ebp,%ebx + adcl advancetable+4(,%ecx,4),%esi + addl tstep,%edx + jmp LEntry6_16 + +//---------------------------------------- + +Entry7_16: + subl $9,%edi // adjust for hardwired offsets + addl %eax,%edx + movb (%esi),%al + sbbl %ecx,%ecx + addl %ebp,%ebx + adcl advancetable+4(,%ecx,4),%esi + addl tstep,%edx + jmp LEntry7_16 + +//---------------------------------------- + +Entry8_16: + subl $8,%edi // adjust for hardwired offsets + addl %eax,%edx + movb (%esi),%al + sbbl %ecx,%ecx + addl %ebp,%ebx + adcl advancetable+4(,%ecx,4),%esi + addl tstep,%edx + jmp LEntry8_16 + +//---------------------------------------- + +Entry9_16: + subl $7,%edi // adjust for hardwired offsets + addl %eax,%edx + movb (%esi),%al + sbbl %ecx,%ecx + addl %ebp,%ebx + adcl advancetable+4(,%ecx,4),%esi + addl tstep,%edx + jmp LEntry9_16 + +//---------------------------------------- + +Entry10_16: + subl $6,%edi // adjust for hardwired offsets + addl %eax,%edx + movb (%esi),%al + sbbl %ecx,%ecx + addl %ebp,%ebx + adcl advancetable+4(,%ecx,4),%esi + addl tstep,%edx + jmp LEntry10_16 + +//---------------------------------------- + +Entry11_16: + subl $5,%edi // adjust for hardwired offsets + addl %eax,%edx + movb (%esi),%al + sbbl %ecx,%ecx + addl %ebp,%ebx + adcl advancetable+4(,%ecx,4),%esi + addl tstep,%edx + jmp LEntry11_16 + +//---------------------------------------- + +Entry12_16: + subl $4,%edi // adjust for hardwired offsets + addl %eax,%edx + movb (%esi),%al + sbbl %ecx,%ecx + addl %ebp,%ebx + adcl advancetable+4(,%ecx,4),%esi + addl tstep,%edx + jmp LEntry12_16 + +//---------------------------------------- + +Entry13_16: + subl $3,%edi // adjust for hardwired offsets + addl %eax,%edx + movb (%esi),%al + sbbl %ecx,%ecx + addl %ebp,%ebx + adcl advancetable+4(,%ecx,4),%esi + addl tstep,%edx + jmp LEntry13_16 + +//---------------------------------------- + +Entry14_16: + subl $2,%edi // adjust for hardwired offsets + addl %eax,%edx + movb (%esi),%al + sbbl %ecx,%ecx + addl %ebp,%ebx + adcl advancetable+4(,%ecx,4),%esi + addl tstep,%edx + jmp LEntry14_16 + +//---------------------------------------- + +Entry15_16: + decl %edi // adjust for hardwired offsets + addl %eax,%edx + movb (%esi),%al + sbbl %ecx,%ecx + addl %ebp,%ebx + adcl advancetable+4(,%ecx,4),%esi + addl tstep,%edx + jmp LEntry15_16 + +//---------------------------------------- + +Entry16_16: + addl %eax,%edx + movb (%esi),%al + sbbl %ecx,%ecx + addl %ebp,%ebx + adcl advancetable+4(,%ecx,4),%esi + + addl tstep,%edx + sbbl %ecx,%ecx + movb %al,1(%edi) + addl %ebp,%ebx + movb (%esi),%al + adcl advancetable+4(,%ecx,4),%esi + addl tstep,%edx +LEntry15_16: + sbbl %ecx,%ecx + movb %al,2(%edi) + addl %ebp,%ebx + movb (%esi),%al + adcl advancetable+4(,%ecx,4),%esi + addl tstep,%edx +LEntry14_16: + sbbl %ecx,%ecx + movb %al,3(%edi) + addl %ebp,%ebx + movb (%esi),%al + adcl advancetable+4(,%ecx,4),%esi + addl tstep,%edx +LEntry13_16: + sbbl %ecx,%ecx + movb %al,4(%edi) + addl %ebp,%ebx + movb (%esi),%al + adcl advancetable+4(,%ecx,4),%esi + addl tstep,%edx +LEntry12_16: + sbbl %ecx,%ecx + movb %al,5(%edi) + addl %ebp,%ebx + movb (%esi),%al + adcl advancetable+4(,%ecx,4),%esi + addl tstep,%edx +LEntry11_16: + sbbl %ecx,%ecx + movb %al,6(%edi) + addl %ebp,%ebx + movb (%esi),%al + adcl advancetable+4(,%ecx,4),%esi + addl tstep,%edx +LEntry10_16: + sbbl %ecx,%ecx + movb %al,7(%edi) + addl %ebp,%ebx + movb (%esi),%al + adcl advancetable+4(,%ecx,4),%esi + addl tstep,%edx +LEntry9_16: + sbbl %ecx,%ecx + movb %al,8(%edi) + addl %ebp,%ebx + movb (%esi),%al + adcl advancetable+4(,%ecx,4),%esi + addl tstep,%edx +LEntry8_16: + sbbl %ecx,%ecx + movb %al,9(%edi) + addl %ebp,%ebx + movb (%esi),%al + adcl advancetable+4(,%ecx,4),%esi + addl tstep,%edx +LEntry7_16: + sbbl %ecx,%ecx + movb %al,10(%edi) + addl %ebp,%ebx + movb (%esi),%al + adcl advancetable+4(,%ecx,4),%esi + addl tstep,%edx +LEntry6_16: + sbbl %ecx,%ecx + movb %al,11(%edi) + addl %ebp,%ebx + movb (%esi),%al + adcl advancetable+4(,%ecx,4),%esi + addl tstep,%edx +LEntry5_16: + sbbl %ecx,%ecx + movb %al,12(%edi) + addl %ebp,%ebx + movb (%esi),%al + adcl advancetable+4(,%ecx,4),%esi + addl tstep,%edx +LEntry4_16: + sbbl %ecx,%ecx + movb %al,13(%edi) + addl %ebp,%ebx + movb (%esi),%al + adcl advancetable+4(,%ecx,4),%esi +LEntry3_16: + movb %al,14(%edi) + movb (%esi),%al +LEntry2_16: + +LEndSpan: + +// +// clear s/z, t/z, 1/z from FP stack +// + fstp %st(0) + fstp %st(0) + fstp %st(0) + + movl pspantemp,%ebx // restore spans pointer + movl espan_t_pnext(%ebx),%ebx // point to next span + testl %ebx,%ebx // any more spans? + movb %al,15(%edi) + jnz LSpanLoop // more spans + + popl %ebx // restore register variables + popl %esi + popl %edi + popl %ebp // restore the caller's stack frame + ret + +#endif // id386 diff --git a/contrib/other/sdlquake-1.0.9/d_edge.c b/contrib/other/sdlquake-1.0.9/d_edge.c new file mode 100644 index 000000000..52cc8eb27 --- /dev/null +++ b/contrib/other/sdlquake-1.0.9/d_edge.c @@ -0,0 +1,331 @@ +/* +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. + +*/ +// d_edge.c + +#include "quakedef.h" +#include "d_local.h" + +static int miplevel; + +float scale_for_mip; +int screenwidth; +int ubasestep, errorterm, erroradjustup, erroradjustdown; +int vstartscan; + +// FIXME: should go away +extern void R_RotateBmodel (void); +extern void R_TransformFrustum (void); + +vec3_t transformed_modelorg; + +/* +============== +D_DrawPoly + +============== +*/ +void D_DrawPoly (void) +{ +// this driver takes spans, not polygons +} + + +/* +============= +D_MipLevelForScale +============= +*/ +int D_MipLevelForScale (float scale) +{ + int lmiplevel; + + if (scale >= d_scalemip[0] ) + lmiplevel = 0; + else if (scale >= d_scalemip[1] ) + lmiplevel = 1; + else if (scale >= d_scalemip[2] ) + lmiplevel = 2; + else + lmiplevel = 3; + + if (lmiplevel < d_minmip) + lmiplevel = d_minmip; + + return lmiplevel; +} + + +/* +============== +D_DrawSolidSurface +============== +*/ + +// FIXME: clean this up + +void D_DrawSolidSurface (surf_t *surf, int color) +{ + espan_t *span; + byte *pdest; + int u, u2, pix; + + pix = (color<<24) | (color<<16) | (color<<8) | color; + for (span=surf->spans ; span ; span=span->pnext) + { + pdest = (byte *)d_viewbuffer + screenwidth*span->v; + u = span->u; + u2 = span->u + span->count - 1; + ((byte *)pdest)[u] = pix; + + if (u2 - u < 8) + { + for (u++ ; u <= u2 ; u++) + ((byte *)pdest)[u] = pix; + } + else + { + for (u++ ; u & 3 ; u++) + ((byte *)pdest)[u] = pix; + + u2 -= 4; + for ( ; u <= u2 ; u+=4) + *(int *)((byte *)pdest + u) = pix; + u2 += 4; + for ( ; u <= u2 ; u++) + ((byte *)pdest)[u] = pix; + } + } +} + + +/* +============== +D_CalcGradients +============== +*/ +void D_CalcGradients (msurface_t *pface) +{ + mplane_t *pplane; + float mipscale; + vec3_t p_temp1; + vec3_t p_saxis, p_taxis; + float t; + + pplane = pface->plane; + + mipscale = 1.0 / (float)(1 << miplevel); + + TransformVector (pface->texinfo->vecs[0], p_saxis); + TransformVector (pface->texinfo->vecs[1], p_taxis); + + t = xscaleinv * mipscale; + d_sdivzstepu = p_saxis[0] * t; + d_tdivzstepu = p_taxis[0] * t; + + t = yscaleinv * mipscale; + d_sdivzstepv = -p_saxis[1] * t; + d_tdivzstepv = -p_taxis[1] * t; + + d_sdivzorigin = p_saxis[2] * mipscale - xcenter * d_sdivzstepu - + ycenter * d_sdivzstepv; + d_tdivzorigin = p_taxis[2] * mipscale - xcenter * d_tdivzstepu - + ycenter * d_tdivzstepv; + + VectorScale (transformed_modelorg, mipscale, p_temp1); + + t = 0x10000*mipscale; + sadjust = ((fixed16_t)(DotProduct (p_temp1, p_saxis) * 0x10000 + 0.5)) - + ((pface->texturemins[0] << 16) >> miplevel) + + pface->texinfo->vecs[0][3]*t; + tadjust = ((fixed16_t)(DotProduct (p_temp1, p_taxis) * 0x10000 + 0.5)) - + ((pface->texturemins[1] << 16) >> miplevel) + + pface->texinfo->vecs[1][3]*t; + +// +// -1 (-epsilon) so we never wander off the edge of the texture +// + bbextents = ((pface->extents[0] << 16) >> miplevel) - 1; + bbextentt = ((pface->extents[1] << 16) >> miplevel) - 1; +} + + +/* +============== +D_DrawSurfaces +============== +*/ +void D_DrawSurfaces (void) +{ + surf_t *s; + msurface_t *pface; + surfcache_t *pcurrentcache; + vec3_t world_transformed_modelorg; + vec3_t local_modelorg; + + currententity = &cl_entities[0]; + TransformVector (modelorg, transformed_modelorg); + VectorCopy (transformed_modelorg, world_transformed_modelorg); + +// TODO: could preset a lot of this at mode set time + if (r_drawflat.value) + { + for (s = &surfaces[1] ; sspans) + continue; + + d_zistepu = s->d_zistepu; + d_zistepv = s->d_zistepv; + d_ziorigin = s->d_ziorigin; + + D_DrawSolidSurface (s, (int)s->data & 0xFF); + D_DrawZSpans (s->spans); + } + } + else + { + for (s = &surfaces[1] ; sspans) + continue; + + r_drawnpolycount++; + + d_zistepu = s->d_zistepu; + d_zistepv = s->d_zistepv; + d_ziorigin = s->d_ziorigin; + + if (s->flags & SURF_DRAWSKY) + { + if (!r_skymade) + { + R_MakeSky (); + } + + D_DrawSkyScans8 (s->spans); + D_DrawZSpans (s->spans); + } + else if (s->flags & SURF_DRAWBACKGROUND) + { + // set up a gradient for the background surface that places it + // effectively at infinity distance from the viewpoint + d_zistepu = 0; + d_zistepv = 0; + d_ziorigin = -0.9; + + D_DrawSolidSurface (s, (int)r_clearcolor.value & 0xFF); + D_DrawZSpans (s->spans); + } + else if (s->flags & SURF_DRAWTURB) + { + pface = s->data; + miplevel = 0; + cacheblock = (pixel_t *) + ((byte *)pface->texinfo->texture + + pface->texinfo->texture->offsets[0]); + cachewidth = 64; + + if (s->insubmodel) + { + // FIXME: we don't want to do all this for every polygon! + // TODO: store once at start of frame + currententity = s->entity; //FIXME: make this passed in to + // R_RotateBmodel () + VectorSubtract (r_origin, currententity->origin, + local_modelorg); + TransformVector (local_modelorg, transformed_modelorg); + + R_RotateBmodel (); // FIXME: don't mess with the frustum, + // make entity passed in + } + + D_CalcGradients (pface); + Turbulent8 (s->spans); + D_DrawZSpans (s->spans); + + if (s->insubmodel) + { + // + // restore the old drawing state + // FIXME: we don't want to do this every time! + // TODO: speed up + // + currententity = &cl_entities[0]; + VectorCopy (world_transformed_modelorg, + transformed_modelorg); + VectorCopy (base_vpn, vpn); + VectorCopy (base_vup, vup); + VectorCopy (base_vright, vright); + VectorCopy (base_modelorg, modelorg); + R_TransformFrustum (); + } + } + else + { + if (s->insubmodel) + { + // FIXME: we don't want to do all this for every polygon! + // TODO: store once at start of frame + currententity = s->entity; //FIXME: make this passed in to + // R_RotateBmodel () + VectorSubtract (r_origin, currententity->origin, local_modelorg); + TransformVector (local_modelorg, transformed_modelorg); + + R_RotateBmodel (); // FIXME: don't mess with the frustum, + // make entity passed in + } + + pface = s->data; + miplevel = D_MipLevelForScale (s->nearzi * scale_for_mip + * pface->texinfo->mipadjust); + + // FIXME: make this passed in to D_CacheSurface + pcurrentcache = D_CacheSurface (pface, miplevel); + + cacheblock = (pixel_t *)pcurrentcache->data; + cachewidth = pcurrentcache->width; + + D_CalcGradients (pface); + + (*d_drawspans) (s->spans); + + D_DrawZSpans (s->spans); + + if (s->insubmodel) + { + // + // restore the old drawing state + // FIXME: we don't want to do this every time! + // TODO: speed up + // + currententity = &cl_entities[0]; + VectorCopy (world_transformed_modelorg, + transformed_modelorg); + VectorCopy (base_vpn, vpn); + VectorCopy (base_vup, vup); + VectorCopy (base_vright, vright); + VectorCopy (base_modelorg, modelorg); + R_TransformFrustum (); + } + } + } + } +} + diff --git a/contrib/other/sdlquake-1.0.9/d_fill.c b/contrib/other/sdlquake-1.0.9/d_fill.c new file mode 100644 index 000000000..e6c14733b --- /dev/null +++ b/contrib/other/sdlquake-1.0.9/d_fill.c @@ -0,0 +1,88 @@ +/* +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. + +*/ +// d_clear: clears a specified rectangle to the specified color + +#include "quakedef.h" + + +/* +================ +D_FillRect +================ +*/ +void D_FillRect (vrect_t *rect, int color) +{ + int rx, ry, rwidth, rheight; + unsigned char *dest; + unsigned *ldest; + + rx = rect->x; + ry = rect->y; + rwidth = rect->width; + rheight = rect->height; + + if (rx < 0) + { + rwidth += rx; + rx = 0; + } + if (ry < 0) + { + rheight += ry; + ry = 0; + } + if (rx+rwidth > vid.width) + rwidth = vid.width - rx; + if (ry+rheight > vid.height) + rheight = vid.height - rx; + + if (rwidth < 1 || rheight < 1) + return; + + dest = ((byte *)vid.buffer + ry*vid.rowbytes + rx); + + if (((rwidth & 0x03) == 0) && (((long)dest & 0x03) == 0)) + { + // faster aligned dword clear + ldest = (unsigned *)dest; + color += color << 16; + + rwidth >>= 2; + color += color << 8; + + for (ry=0 ; ry 3) + d_minmip = 3; + else if (d_minmip < 0) + d_minmip = 0; + + for (i=0 ; i<(NUM_MIPS-1) ; i++) + d_scalemip[i] = basemip[i] * d_mipscale.value; + +#if id386 + if (d_subdiv16.value) + d_drawspans = D_DrawSpans16; + else + d_drawspans = D_DrawSpans8; +#else + d_drawspans = D_DrawSpans8; +#endif + + d_aflatcolor = 0; +} + + +/* +=============== +D_UpdateRects +=============== +*/ +void D_UpdateRects (vrect_t *prect) +{ + +// the software driver draws these directly to the vid buffer + + UNUSED(prect); +} + diff --git a/contrib/other/sdlquake-1.0.9/d_local.h b/contrib/other/sdlquake-1.0.9/d_local.h new file mode 100644 index 000000000..af924899e --- /dev/null +++ b/contrib/other/sdlquake-1.0.9/d_local.h @@ -0,0 +1,111 @@ +/* +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. + +*/ +// d_local.h: private rasterization driver defs + +#include "r_shared.h" + +// +// TODO: fine-tune this; it's based on providing some overage even if there +// is a 2k-wide scan, with subdivision every 8, for 256 spans of 12 bytes each +// +#define SCANBUFFERPAD 0x1000 + +#define R_SKY_SMASK 0x007F0000 +#define R_SKY_TMASK 0x007F0000 + +#define DS_SPAN_LIST_END -128 + +#define SURFCACHE_SIZE_AT_320X200 600*1024 + +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; + +// !!! if this is changed, it must be changed in asm_draw.h too !!! +typedef struct sspan_s +{ + int u, v, count; +} sspan_t; + +extern cvar_t d_subdiv16; + +extern float scale_for_mip; + +extern qboolean d_roverwrapped; +extern surfcache_t *sc_rover; +extern surfcache_t *d_initial_rover; + +extern float d_sdivzstepu, d_tdivzstepu, d_zistepu; +extern float d_sdivzstepv, d_tdivzstepv, d_zistepv; +extern float d_sdivzorigin, d_tdivzorigin, d_ziorigin; + +fixed16_t sadjust, tadjust; +fixed16_t bbextents, bbextentt; + + +void D_DrawSpans8 (espan_t *pspans); +void D_DrawSpans16 (espan_t *pspans); +void D_DrawZSpans (espan_t *pspans); +void Turbulent8 (espan_t *pspan); +void D_SpriteDrawSpans (sspan_t *pspan); + +void D_DrawSkyScans8 (espan_t *pspan); +void D_DrawSkyScans16 (espan_t *pspan); + +void R_ShowSubDiv (void); +void (*prealspandrawer)(void); +surfcache_t *D_CacheSurface (msurface_t *surface, int miplevel); + +extern int D_MipLevelForScale (float scale); + +#if id386 +extern void D_PolysetAff8Start (void); +extern void D_PolysetAff8End (void); +#endif + +extern short *d_pzbuffer; +extern unsigned int d_zrowbytes, d_zwidth; + +extern int *d_pscantable; +extern int d_scantable[MAXHEIGHT]; + +extern int d_vrectx, d_vrecty, d_vrectright_particle, d_vrectbottom_particle; + +extern int d_y_aspect_shift, d_pix_min, d_pix_max, d_pix_shift; + +extern pixel_t *d_viewbuffer; + +extern short *zspantable[MAXHEIGHT]; + +extern int d_minmip; +extern float d_scalemip[3]; + +extern void (*d_drawspans) (espan_t *pspan); + diff --git a/contrib/other/sdlquake-1.0.9/d_modech.c b/contrib/other/sdlquake-1.0.9/d_modech.c new file mode 100644 index 000000000..75c188e36 --- /dev/null +++ b/contrib/other/sdlquake-1.0.9/d_modech.c @@ -0,0 +1,107 @@ +/* +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. + +*/ +// d_modech.c: called when mode has just changed + +#include "quakedef.h" +#include "d_local.h" + +int d_vrectx, d_vrecty, d_vrectright_particle, d_vrectbottom_particle; + +int d_y_aspect_shift, d_pix_min, d_pix_max, d_pix_shift; + +int d_scantable[MAXHEIGHT]; +short *zspantable[MAXHEIGHT]; + +/* +================ +D_Patch +================ +*/ +void D_Patch (void) +{ +#if id386 + + static qboolean protectset8 = false; + + if (!protectset8) + { + Sys_MakeCodeWriteable ((int)D_PolysetAff8Start, + (int)D_PolysetAff8End - (int)D_PolysetAff8Start); + protectset8 = true; + } + +#endif // id386 +} + + +/* +================ +D_ViewChanged +================ +*/ +void D_ViewChanged (void) +{ + int rowbytes; + + if (r_dowarp) + rowbytes = WARP_WIDTH; + else + rowbytes = vid.rowbytes; + + scale_for_mip = xscale; + if (yscale > xscale) + scale_for_mip = yscale; + + d_zrowbytes = vid.width * 2; + d_zwidth = vid.width; + + d_pix_min = r_refdef.vrect.width / 320; + if (d_pix_min < 1) + d_pix_min = 1; + + d_pix_max = (int)((float)r_refdef.vrect.width / (320.0 / 4.0) + 0.5); + d_pix_shift = 8 - (int)((float)r_refdef.vrect.width / 320.0 + 0.5); + if (d_pix_max < 1) + d_pix_max = 1; + + if (pixelAspect > 1.4) + d_y_aspect_shift = 1; + else + d_y_aspect_shift = 0; + + d_vrectx = r_refdef.vrect.x; + d_vrecty = r_refdef.vrect.y; + d_vrectright_particle = r_refdef.vrectright - d_pix_max; + d_vrectbottom_particle = + r_refdef.vrectbottom - (d_pix_max << d_y_aspect_shift); + + { + int i; + + for (i=0 ; iorg, r_origin, local); + + transformed[0] = DotProduct(local, r_pright); + transformed[1] = DotProduct(local, r_pup); + transformed[2] = DotProduct(local, r_ppn); + + if (transformed[2] < PARTICLE_Z_CLIP) + return; + +// project the point +// FIXME: preadjust xcenter and ycenter + zi = 1.0 / transformed[2]; + u = (int)(xcenter + zi * transformed[0] + 0.5); + v = (int)(ycenter - zi * transformed[1] + 0.5); + + if ((v > d_vrectbottom_particle) || + (u > d_vrectright_particle) || + (v < d_vrecty) || + (u < d_vrectx)) + { + return; + } + + pz = d_pzbuffer + (d_zwidth * v) + u; + pdest = d_viewbuffer + d_scantable[v] + u; + izi = (int)(zi * 0x8000); + + pix = izi >> d_pix_shift; + + if (pix < d_pix_min) + pix = d_pix_min; + else if (pix > d_pix_max) + pix = d_pix_max; + + switch (pix) + { + case 1: + count = 1 << d_y_aspect_shift; + + for ( ; count ; count--, pz += d_zwidth, pdest += screenwidth) + { + if (pz[0] <= izi) + { + pz[0] = izi; + pdest[0] = pparticle->color; + } + } + break; + + case 2: + count = 2 << d_y_aspect_shift; + + for ( ; count ; count--, pz += d_zwidth, pdest += screenwidth) + { + if (pz[0] <= izi) + { + pz[0] = izi; + pdest[0] = pparticle->color; + } + + if (pz[1] <= izi) + { + pz[1] = izi; + pdest[1] = pparticle->color; + } + } + break; + + case 3: + count = 3 << d_y_aspect_shift; + + for ( ; count ; count--, pz += d_zwidth, pdest += screenwidth) + { + if (pz[0] <= izi) + { + pz[0] = izi; + pdest[0] = pparticle->color; + } + + if (pz[1] <= izi) + { + pz[1] = izi; + pdest[1] = pparticle->color; + } + + if (pz[2] <= izi) + { + pz[2] = izi; + pdest[2] = pparticle->color; + } + } + break; + + case 4: + count = 4 << d_y_aspect_shift; + + for ( ; count ; count--, pz += d_zwidth, pdest += screenwidth) + { + if (pz[0] <= izi) + { + pz[0] = izi; + pdest[0] = pparticle->color; + } + + if (pz[1] <= izi) + { + pz[1] = izi; + pdest[1] = pparticle->color; + } + + if (pz[2] <= izi) + { + pz[2] = izi; + pdest[2] = pparticle->color; + } + + if (pz[3] <= izi) + { + pz[3] = izi; + pdest[3] = pparticle->color; + } + } + break; + + default: + count = pix << d_y_aspect_shift; + + for ( ; count ; count--, pz += d_zwidth, pdest += screenwidth) + { + for (i=0 ; icolor; + } + } + } + break; + } +} + +#endif // !id386 + diff --git a/contrib/other/sdlquake-1.0.9/d_parta.S b/contrib/other/sdlquake-1.0.9/d_parta.S new file mode 100644 index 000000000..b32f1bcb6 --- /dev/null +++ b/contrib/other/sdlquake-1.0.9/d_parta.S @@ -0,0 +1,477 @@ +/* +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. + +*/ +// +// d_parta.s +// x86 assembly-language 8-bpp particle-drawing code. +// + +#include "asm_i386.h" +#include "quakeasm.h" +#include "d_ifacea.h" +#include "asm_draw.h" + +#if id386 + +//---------------------------------------------------------------------- +// 8-bpp particle drawing code. +//---------------------------------------------------------------------- + +//FIXME: comments, full optimization + +//---------------------------------------------------------------------- +// 8-bpp particle queueing code. +//---------------------------------------------------------------------- + + .text + +#define P 12+4 + + .align 4 +.globl C(D_DrawParticle) +C(D_DrawParticle): + pushl %ebp // preserve caller's stack frame + pushl %edi // preserve register variables + pushl %ebx + + movl P(%esp),%edi + +// FIXME: better FP overlap in general here + +// transform point +// VectorSubtract (p->org, r_origin, local); + flds C(r_origin) + fsubrs pt_org(%edi) + flds pt_org+4(%edi) + fsubs C(r_origin)+4 + flds pt_org+8(%edi) + fsubs C(r_origin)+8 + fxch %st(2) // local[0] | local[1] | local[2] + +// transformed[2] = DotProduct(local, r_ppn); + flds C(r_ppn) // r_ppn[0] | local[0] | local[1] | local[2] + fmul %st(1),%st(0) // dot0 | local[0] | local[1] | local[2] + flds C(r_ppn)+4 // r_ppn[1] | dot0 | local[0] | local[1] | local[2] + fmul %st(3),%st(0) // dot1 | dot0 | local[0] | local[1] | local[2] + flds C(r_ppn)+8 // r_ppn[2] | dot1 | dot0 | local[0] | + // local[1] | local[2] + fmul %st(5),%st(0) // dot2 | dot1 | dot0 | local[0] | local[1] | local[2] + fxch %st(2) // dot0 | dot1 | dot2 | local[0] | local[1] | local[2] + faddp %st(0),%st(1) // dot0 + dot1 | dot2 | local[0] | local[1] | + // local[2] + faddp %st(0),%st(1) // z | local[0] | local[1] | local[2] + fld %st(0) // z | z | local[0] | local[1] | + // local[2] + fdivrs float_1 // 1/z | z | local[0] | local[1] | local[2] + fxch %st(1) // z | 1/z | local[0] | local[1] | local[2] + +// if (transformed[2] < PARTICLE_Z_CLIP) +// return; + fcomps float_particle_z_clip // 1/z | local[0] | local[1] | local[2] + fxch %st(3) // local[2] | local[0] | local[1] | 1/z + + flds C(r_pup) // r_pup[0] | local[2] | local[0] | local[1] | 1/z + fmul %st(2),%st(0) // dot0 | local[2] | local[0] | local[1] | 1/z + flds C(r_pup)+4 // r_pup[1] | dot0 | local[2] | local[0] | + // local[1] | 1/z + + fnstsw %ax + testb $1,%ah + jnz LPop6AndDone + +// transformed[1] = DotProduct(local, r_pup); + fmul %st(4),%st(0) // dot1 | dot0 | local[2] | local[0] | local[1] | 1/z + flds C(r_pup)+8 // r_pup[2] | dot1 | dot0 | local[2] | + // local[0] | local[1] | 1/z + fmul %st(3),%st(0) // dot2 | dot1 | dot0 | local[2] | local[0] | + // local[1] | 1/z + fxch %st(2) // dot0 | dot1 | dot2 | local[2] | local[0] | + // local[1] | 1/z + faddp %st(0),%st(1) // dot0 + dot1 | dot2 | local[2] | local[0] | + // local[1] | 1/z + faddp %st(0),%st(1) // y | local[2] | local[0] | local[1] | 1/z + fxch %st(3) // local[1] | local[2] | local[0] | y | 1/z + +// transformed[0] = DotProduct(local, r_pright); + fmuls C(r_pright)+4 // dot1 | local[2] | local[0] | y | 1/z + fxch %st(2) // local[0] | local[2] | dot1 | y | 1/z + fmuls C(r_pright) // dot0 | local[2] | dot1 | y | 1/z + fxch %st(1) // local[2] | dot0 | dot1 | y | 1/z + fmuls C(r_pright)+8 // dot2 | dot0 | dot1 | y | 1/z + fxch %st(2) // dot1 | dot0 | dot2 | y | 1/z + faddp %st(0),%st(1) // dot1 + dot0 | dot2 | y | 1/z + + faddp %st(0),%st(1) // x | y | 1/z + fxch %st(1) // y | x | 1/z + +// project the point + fmul %st(2),%st(0) // y/z | x | 1/z + fxch %st(1) // x | y/z | 1/z + fmul %st(2),%st(0) // x/z | y/z | 1/z + fxch %st(1) // y/z | x/z | 1/z + fsubrs C(ycenter) // v | x/z | 1/z + fxch %st(1) // x/z | v | 1/z + fadds C(xcenter) // u | v | 1/z +// FIXME: preadjust xcenter and ycenter + fxch %st(1) // v | u | 1/z + fadds float_point5 // v | u | 1/z + fxch %st(1) // u | v | 1/z + fadds float_point5 // u | v | 1/z + fxch %st(2) // 1/z | v | u + fmuls DP_32768 // 1/z * 0x8000 | v | u + fxch %st(2) // u | v | 1/z * 0x8000 + +// FIXME: use Terje's fp->int trick here? +// FIXME: check we're getting proper rounding here + fistpl DP_u // v | 1/z * 0x8000 + fistpl DP_v // 1/z * 0x8000 + + movl DP_u,%eax + movl DP_v,%edx + +// if ((v > d_vrectbottom_particle) || +// (u > d_vrectright_particle) || +// (v < d_vrecty) || +// (u < d_vrectx)) +// { +// continue; +// } + + movl C(d_vrectbottom_particle),%ebx + movl C(d_vrectright_particle),%ecx + cmpl %ebx,%edx + jg LPop1AndDone + cmpl %ecx,%eax + jg LPop1AndDone + movl C(d_vrecty),%ebx + movl C(d_vrectx),%ecx + cmpl %ebx,%edx + jl LPop1AndDone + + cmpl %ecx,%eax + jl LPop1AndDone + + flds pt_color(%edi) // color | 1/z * 0x8000 +// FIXME: use Terje's fast fp->int trick? + fistpl DP_Color // 1/z * 0x8000 + + movl C(d_viewbuffer),%ebx + + addl %eax,%ebx + movl C(d_scantable)(,%edx,4),%edi // point to the pixel + + imull C(d_zrowbytes),%edx // point to the z pixel + + leal (%edx,%eax,2),%edx + movl C(d_pzbuffer),%eax + + fistpl izi + + addl %ebx,%edi + addl %eax,%edx + +// pix = izi >> d_pix_shift; + + movl izi,%eax + movl C(d_pix_shift),%ecx + shrl %cl,%eax + movl izi,%ebp + +// if (pix < d_pix_min) +// pix = d_pix_min; +// else if (pix > d_pix_max) +// pix = d_pix_max; + + movl C(d_pix_min),%ebx + movl C(d_pix_max),%ecx + cmpl %ebx,%eax + jnl LTestPixMax + movl %ebx,%eax + jmp LTestDone + +LTestPixMax: + cmpl %ecx,%eax + jng LTestDone + movl %ecx,%eax +LTestDone: + + movb DP_Color,%ch + + movl C(d_y_aspect_shift),%ebx + testl %ebx,%ebx + jnz LDefault + + cmpl $4,%eax + ja LDefault + + jmp DP_EntryTable-4(,%eax,4) + +// 1x1 +.globl DP_1x1 +DP_1x1: + cmpw %bp,(%edx) // just one pixel to do + jg LDone + movw %bp,(%edx) + movb %ch,(%edi) + jmp LDone + +// 2x2 +.globl DP_2x2 +DP_2x2: + pushl %esi + movl C(screenwidth),%ebx + movl C(d_zrowbytes),%esi + + cmpw %bp,(%edx) + jg L2x2_1 + movw %bp,(%edx) + movb %ch,(%edi) +L2x2_1: + cmpw %bp,2(%edx) + jg L2x2_2 + movw %bp,2(%edx) + movb %ch,1(%edi) +L2x2_2: + cmpw %bp,(%edx,%esi,1) + jg L2x2_3 + movw %bp,(%edx,%esi,1) + movb %ch,(%edi,%ebx,1) +L2x2_3: + cmpw %bp,2(%edx,%esi,1) + jg L2x2_4 + movw %bp,2(%edx,%esi,1) + movb %ch,1(%edi,%ebx,1) +L2x2_4: + + popl %esi + jmp LDone + +// 3x3 +.globl DP_3x3 +DP_3x3: + pushl %esi + movl C(screenwidth),%ebx + movl C(d_zrowbytes),%esi + + cmpw %bp,(%edx) + jg L3x3_1 + movw %bp,(%edx) + movb %ch,(%edi) +L3x3_1: + cmpw %bp,2(%edx) + jg L3x3_2 + movw %bp,2(%edx) + movb %ch,1(%edi) +L3x3_2: + cmpw %bp,4(%edx) + jg L3x3_3 + movw %bp,4(%edx) + movb %ch,2(%edi) +L3x3_3: + + cmpw %bp,(%edx,%esi,1) + jg L3x3_4 + movw %bp,(%edx,%esi,1) + movb %ch,(%edi,%ebx,1) +L3x3_4: + cmpw %bp,2(%edx,%esi,1) + jg L3x3_5 + movw %bp,2(%edx,%esi,1) + movb %ch,1(%edi,%ebx,1) +L3x3_5: + cmpw %bp,4(%edx,%esi,1) + jg L3x3_6 + movw %bp,4(%edx,%esi,1) + movb %ch,2(%edi,%ebx,1) +L3x3_6: + + cmpw %bp,(%edx,%esi,2) + jg L3x3_7 + movw %bp,(%edx,%esi,2) + movb %ch,(%edi,%ebx,2) +L3x3_7: + cmpw %bp,2(%edx,%esi,2) + jg L3x3_8 + movw %bp,2(%edx,%esi,2) + movb %ch,1(%edi,%ebx,2) +L3x3_8: + cmpw %bp,4(%edx,%esi,2) + jg L3x3_9 + movw %bp,4(%edx,%esi,2) + movb %ch,2(%edi,%ebx,2) +L3x3_9: + + popl %esi + jmp LDone + + +// 4x4 +.globl DP_4x4 +DP_4x4: + pushl %esi + movl C(screenwidth),%ebx + movl C(d_zrowbytes),%esi + + cmpw %bp,(%edx) + jg L4x4_1 + movw %bp,(%edx) + movb %ch,(%edi) +L4x4_1: + cmpw %bp,2(%edx) + jg L4x4_2 + movw %bp,2(%edx) + movb %ch,1(%edi) +L4x4_2: + cmpw %bp,4(%edx) + jg L4x4_3 + movw %bp,4(%edx) + movb %ch,2(%edi) +L4x4_3: + cmpw %bp,6(%edx) + jg L4x4_4 + movw %bp,6(%edx) + movb %ch,3(%edi) +L4x4_4: + + cmpw %bp,(%edx,%esi,1) + jg L4x4_5 + movw %bp,(%edx,%esi,1) + movb %ch,(%edi,%ebx,1) +L4x4_5: + cmpw %bp,2(%edx,%esi,1) + jg L4x4_6 + movw %bp,2(%edx,%esi,1) + movb %ch,1(%edi,%ebx,1) +L4x4_6: + cmpw %bp,4(%edx,%esi,1) + jg L4x4_7 + movw %bp,4(%edx,%esi,1) + movb %ch,2(%edi,%ebx,1) +L4x4_7: + cmpw %bp,6(%edx,%esi,1) + jg L4x4_8 + movw %bp,6(%edx,%esi,1) + movb %ch,3(%edi,%ebx,1) +L4x4_8: + + leal (%edx,%esi,2),%edx + leal (%edi,%ebx,2),%edi + + cmpw %bp,(%edx) + jg L4x4_9 + movw %bp,(%edx) + movb %ch,(%edi) +L4x4_9: + cmpw %bp,2(%edx) + jg L4x4_10 + movw %bp,2(%edx) + movb %ch,1(%edi) +L4x4_10: + cmpw %bp,4(%edx) + jg L4x4_11 + movw %bp,4(%edx) + movb %ch,2(%edi) +L4x4_11: + cmpw %bp,6(%edx) + jg L4x4_12 + movw %bp,6(%edx) + movb %ch,3(%edi) +L4x4_12: + + cmpw %bp,(%edx,%esi,1) + jg L4x4_13 + movw %bp,(%edx,%esi,1) + movb %ch,(%edi,%ebx,1) +L4x4_13: + cmpw %bp,2(%edx,%esi,1) + jg L4x4_14 + movw %bp,2(%edx,%esi,1) + movb %ch,1(%edi,%ebx,1) +L4x4_14: + cmpw %bp,4(%edx,%esi,1) + jg L4x4_15 + movw %bp,4(%edx,%esi,1) + movb %ch,2(%edi,%ebx,1) +L4x4_15: + cmpw %bp,6(%edx,%esi,1) + jg L4x4_16 + movw %bp,6(%edx,%esi,1) + movb %ch,3(%edi,%ebx,1) +L4x4_16: + + popl %esi + jmp LDone + +// default case, handling any size particle +LDefault: + +// count = pix << d_y_aspect_shift; + + movl %eax,%ebx + movl %eax,DP_Pix + movb C(d_y_aspect_shift),%cl + shll %cl,%ebx + +// for ( ; count ; count--, pz += d_zwidth, pdest += screenwidth) +// { +// for (i=0 ; i> 16) + +// (r_sstepx >> 16); + + movl C(r_sstepx),%eax + movl C(r_tstepx),%edx + shll $16,%eax + shll $16,%edx + movl %eax,C(a_sstepxfrac) + movl %edx,C(a_tstepxfrac) + + movl C(r_sstepx),%ecx + movl C(r_tstepx),%eax + sarl $16,%ecx + sarl $16,%eax + imull skinwidth(%esp) + addl %ecx,%eax + movl %eax,C(a_ststepxwhole) + + ret + + +//---------------------------------------------------------------------- +// recursive subdivision affine triangle drawing code +// +// not C-callable because of stdcall return +//---------------------------------------------------------------------- + +#define lp1 4+16 +#define lp2 8+16 +#define lp3 12+16 + +.globl C(D_PolysetRecursiveTriangle) +C(D_PolysetRecursiveTriangle): + pushl %ebp // preserve caller stack frame pointer + pushl %esi // preserve register variables + pushl %edi + pushl %ebx + +// int *temp; +// int d; +// int new[6]; +// int i; +// int z; +// short *zbuf; + movl lp2(%esp),%esi + movl lp1(%esp),%ebx + movl lp3(%esp),%edi + +// d = lp2[0] - lp1[0]; +// if (d < -1 || d > 1) +// goto split; + movl 0(%esi),%eax + + movl 0(%ebx),%edx + movl 4(%esi),%ebp + + subl %edx,%eax + movl 4(%ebx),%ecx + + subl %ecx,%ebp + incl %eax + + cmpl $2,%eax + ja LSplit + +// d = lp2[1] - lp1[1]; +// if (d < -1 || d > 1) +// goto split; + movl 0(%edi),%eax + incl %ebp + + cmpl $2,%ebp + ja LSplit + +// d = lp3[0] - lp2[0]; +// if (d < -1 || d > 1) +// goto split2; + movl 0(%esi),%edx + movl 4(%edi),%ebp + + subl %edx,%eax + movl 4(%esi),%ecx + + subl %ecx,%ebp + incl %eax + + cmpl $2,%eax + ja LSplit2 + +// d = lp3[1] - lp2[1]; +// if (d < -1 || d > 1) +// goto split2; + movl 0(%ebx),%eax + incl %ebp + + cmpl $2,%ebp + ja LSplit2 + +// d = lp1[0] - lp3[0]; +// if (d < -1 || d > 1) +// goto split3; + movl 0(%edi),%edx + movl 4(%ebx),%ebp + + subl %edx,%eax + movl 4(%edi),%ecx + + subl %ecx,%ebp + incl %eax + + incl %ebp + movl %ebx,%edx + + cmpl $2,%eax + ja LSplit3 + +// d = lp1[1] - lp3[1]; +// if (d < -1 || d > 1) +// { +//split3: +// temp = lp1; +// lp3 = lp2; +// lp1 = lp3; +// lp2 = temp; +// goto split; +// } +// +// return; // entire tri is filled +// + cmpl $2,%ebp + jna LDone + +LSplit3: + movl %edi,%ebx + movl %esi,%edi + movl %edx,%esi + jmp LSplit + +//split2: +LSplit2: + +// temp = lp1; +// lp1 = lp2; +// lp2 = lp3; +// lp3 = temp; + movl %ebx,%eax + movl %esi,%ebx + movl %edi,%esi + movl %eax,%edi + +//split: +LSplit: + + subl $24,%esp // allocate space for a new vertex + +//// split this edge +// new[0] = (lp1[0] + lp2[0]) >> 1; +// new[1] = (lp1[1] + lp2[1]) >> 1; +// new[2] = (lp1[2] + lp2[2]) >> 1; +// new[3] = (lp1[3] + lp2[3]) >> 1; +// new[5] = (lp1[5] + lp2[5]) >> 1; + movl 8(%ebx),%eax + + movl 8(%esi),%edx + movl 12(%ebx),%ecx + + addl %edx,%eax + movl 12(%esi),%edx + + sarl $1,%eax + addl %edx,%ecx + + movl %eax,8(%esp) + movl 20(%ebx),%eax + + sarl $1,%ecx + movl 20(%esi),%edx + + movl %ecx,12(%esp) + addl %edx,%eax + + movl 0(%ebx),%ecx + movl 0(%esi),%edx + + sarl $1,%eax + addl %ecx,%edx + + movl %eax,20(%esp) + movl 4(%ebx),%eax + + sarl $1,%edx + movl 4(%esi),%ebp + + movl %edx,0(%esp) + addl %eax,%ebp + + sarl $1,%ebp + movl %ebp,4(%esp) + +//// draw the point if splitting a leading edge +// if (lp2[1] > lp1[1]) +// goto nodraw; + cmpl %eax,4(%esi) + jg LNoDraw + +// if ((lp2[1] == lp1[1]) && (lp2[0] < lp1[0])) +// goto nodraw; + movl 0(%esi),%edx + jnz LDraw + + cmpl %ecx,%edx + jl LNoDraw + +LDraw: + +// z = new[5] >> 16; + movl 20(%esp),%edx + movl 4(%esp),%ecx + + sarl $16,%edx + movl 0(%esp),%ebp + +// zbuf = zspantable[new[1]] + new[0]; + movl C(zspantable)(,%ecx,4),%eax + +// if (z >= *zbuf) +// { + cmpw (%eax,%ebp,2),%dx + jnge LNoDraw + +// int pix; +// +// *zbuf = z; + movw %dx,(%eax,%ebp,2) + +// pix = d_pcolormap[skintable[new[3]>>16][new[2]>>16]]; + movl 12(%esp),%eax + + sarl $16,%eax + movl 8(%esp),%edx + + sarl $16,%edx + subl %ecx,%ecx + + movl C(skintable)(,%eax,4),%eax + movl 4(%esp),%ebp + + movb (%eax,%edx,),%cl + movl C(d_pcolormap),%edx + + movb (%edx,%ecx,),%dl + movl 0(%esp),%ecx + +// d_viewbuffer[d_scantable[new[1]] + new[0]] = pix; + movl C(d_scantable)(,%ebp,4),%eax + addl %eax,%ecx + movl C(d_viewbuffer),%eax + movb %dl,(%eax,%ecx,1) + +// } +// +//nodraw: +LNoDraw: + +//// recursively continue +// D_PolysetRecursiveTriangle (lp3, lp1, new); + pushl %esp + pushl %ebx + pushl %edi + call C(D_PolysetRecursiveTriangle) + +// D_PolysetRecursiveTriangle (lp3, new, lp2); + movl %esp,%ebx + pushl %esi + pushl %ebx + pushl %edi + call C(D_PolysetRecursiveTriangle) + addl $24,%esp + +LDone: + popl %ebx // restore register variables + popl %edi + popl %esi + popl %ebp // restore caller stack frame pointer + ret $12 + + +//---------------------------------------------------------------------- +// 8-bpp horizontal span drawing code for affine polygons, with smooth +// shading and no transparency +//---------------------------------------------------------------------- + +#define pspans 4+8 + +.globl C(D_PolysetAff8Start) +C(D_PolysetAff8Start): + +.globl C(D_PolysetDrawSpans8) +C(D_PolysetDrawSpans8): + pushl %esi // preserve register variables + pushl %ebx + + movl pspans(%esp),%esi // point to the first span descriptor + movl C(r_zistepx),%ecx + + pushl %ebp // preserve caller's stack frame + pushl %edi + + rorl $16,%ecx // put high 16 bits of 1/z step in low word + movl spanpackage_t_count(%esi),%edx + + movl %ecx,lzistepx + +LSpanLoop: + +// lcount = d_aspancount - pspanpackage->count; +// +// errorterm += erroradjustup; +// if (errorterm >= 0) +// { +// d_aspancount += d_countextrastep; +// errorterm -= erroradjustdown; +// } +// else +// { +// d_aspancount += ubasestep; +// } + movl C(d_aspancount),%eax + subl %edx,%eax + + movl C(erroradjustup),%edx + movl C(errorterm),%ebx + addl %edx,%ebx + js LNoTurnover + + movl C(erroradjustdown),%edx + movl C(d_countextrastep),%edi + subl %edx,%ebx + movl C(d_aspancount),%ebp + movl %ebx,C(errorterm) + addl %edi,%ebp + movl %ebp,C(d_aspancount) + jmp LRightEdgeStepped + +LNoTurnover: + movl C(d_aspancount),%edi + movl C(ubasestep),%edx + movl %ebx,C(errorterm) + addl %edx,%edi + movl %edi,C(d_aspancount) + +LRightEdgeStepped: + cmpl $1,%eax + + jl LNextSpan + jz LExactlyOneLong + +// +// set up advancetable +// + movl C(a_ststepxwhole),%ecx + movl C(r_affinetridesc)+atd_skinwidth,%edx + + movl %ecx,advancetable+4 // advance base in t + addl %edx,%ecx + + movl %ecx,advancetable // advance extra in t + movl C(a_tstepxfrac),%ecx + + movw C(r_lstepx),%cx + movl %eax,%edx // count + + movl %ecx,tstep + addl $7,%edx + + shrl $3,%edx // count of full and partial loops + movl spanpackage_t_sfrac(%esi),%ebx + + movw %dx,%bx + movl spanpackage_t_pz(%esi),%ecx + + negl %eax + + movl spanpackage_t_pdest(%esi),%edi + andl $7,%eax // 0->0, 1->7, 2->6, ... , 7->1 + + subl %eax,%edi // compensate for hardwired offsets + subl %eax,%ecx + + subl %eax,%ecx + movl spanpackage_t_tfrac(%esi),%edx + + movw spanpackage_t_light(%esi),%dx + movl spanpackage_t_zi(%esi),%ebp + + rorl $16,%ebp // put high 16 bits of 1/z in low word + pushl %esi + + movl spanpackage_t_ptex(%esi),%esi + jmp aff8entryvec_table(,%eax,4) + +// %bx = count of full and partial loops +// %ebx high word = sfrac +// %ecx = pz +// %dx = light +// %edx high word = tfrac +// %esi = ptex +// %edi = pdest +// %ebp = 1/z +// tstep low word = C(r_lstepx) +// tstep high word = C(a_tstepxfrac) +// C(a_sstepxfrac) low word = 0 +// C(a_sstepxfrac) high word = C(a_sstepxfrac) + +LDrawLoop: + +// FIXME: do we need to clamp light? We may need at least a buffer bit to +// keep it from poking into tfrac and causing problems + +LDraw8: + cmpw (%ecx),%bp + jl Lp1 + xorl %eax,%eax + movb %dh,%ah + movb (%esi),%al + movw %bp,(%ecx) + movb 0x12345678(%eax),%al +LPatch8: + movb %al,(%edi) +Lp1: + addl tstep,%edx + sbbl %eax,%eax + addl lzistepx,%ebp + adcl $0,%ebp + addl C(a_sstepxfrac),%ebx + adcl advancetable+4(,%eax,4),%esi + +LDraw7: + cmpw 2(%ecx),%bp + jl Lp2 + xorl %eax,%eax + movb %dh,%ah + movb (%esi),%al + movw %bp,2(%ecx) + movb 0x12345678(%eax),%al +LPatch7: + movb %al,1(%edi) +Lp2: + addl tstep,%edx + sbbl %eax,%eax + addl lzistepx,%ebp + adcl $0,%ebp + addl C(a_sstepxfrac),%ebx + adcl advancetable+4(,%eax,4),%esi + +LDraw6: + cmpw 4(%ecx),%bp + jl Lp3 + xorl %eax,%eax + movb %dh,%ah + movb (%esi),%al + movw %bp,4(%ecx) + movb 0x12345678(%eax),%al +LPatch6: + movb %al,2(%edi) +Lp3: + addl tstep,%edx + sbbl %eax,%eax + addl lzistepx,%ebp + adcl $0,%ebp + addl C(a_sstepxfrac),%ebx + adcl advancetable+4(,%eax,4),%esi + +LDraw5: + cmpw 6(%ecx),%bp + jl Lp4 + xorl %eax,%eax + movb %dh,%ah + movb (%esi),%al + movw %bp,6(%ecx) + movb 0x12345678(%eax),%al +LPatch5: + movb %al,3(%edi) +Lp4: + addl tstep,%edx + sbbl %eax,%eax + addl lzistepx,%ebp + adcl $0,%ebp + addl C(a_sstepxfrac),%ebx + adcl advancetable+4(,%eax,4),%esi + +LDraw4: + cmpw 8(%ecx),%bp + jl Lp5 + xorl %eax,%eax + movb %dh,%ah + movb (%esi),%al + movw %bp,8(%ecx) + movb 0x12345678(%eax),%al +LPatch4: + movb %al,4(%edi) +Lp5: + addl tstep,%edx + sbbl %eax,%eax + addl lzistepx,%ebp + adcl $0,%ebp + addl C(a_sstepxfrac),%ebx + adcl advancetable+4(,%eax,4),%esi + +LDraw3: + cmpw 10(%ecx),%bp + jl Lp6 + xorl %eax,%eax + movb %dh,%ah + movb (%esi),%al + movw %bp,10(%ecx) + movb 0x12345678(%eax),%al +LPatch3: + movb %al,5(%edi) +Lp6: + addl tstep,%edx + sbbl %eax,%eax + addl lzistepx,%ebp + adcl $0,%ebp + addl C(a_sstepxfrac),%ebx + adcl advancetable+4(,%eax,4),%esi + +LDraw2: + cmpw 12(%ecx),%bp + jl Lp7 + xorl %eax,%eax + movb %dh,%ah + movb (%esi),%al + movw %bp,12(%ecx) + movb 0x12345678(%eax),%al +LPatch2: + movb %al,6(%edi) +Lp7: + addl tstep,%edx + sbbl %eax,%eax + addl lzistepx,%ebp + adcl $0,%ebp + addl C(a_sstepxfrac),%ebx + adcl advancetable+4(,%eax,4),%esi + +LDraw1: + cmpw 14(%ecx),%bp + jl Lp8 + xorl %eax,%eax + movb %dh,%ah + movb (%esi),%al + movw %bp,14(%ecx) + movb 0x12345678(%eax),%al +LPatch1: + movb %al,7(%edi) +Lp8: + addl tstep,%edx + sbbl %eax,%eax + addl lzistepx,%ebp + adcl $0,%ebp + addl C(a_sstepxfrac),%ebx + adcl advancetable+4(,%eax,4),%esi + + addl $8,%edi + addl $16,%ecx + + decw %bx + jnz LDrawLoop + + popl %esi // restore spans pointer +LNextSpan: + addl $(spanpackage_t_size),%esi // point to next span +LNextSpanESISet: + movl spanpackage_t_count(%esi),%edx + cmpl $-999999,%edx // any more spans? + jnz LSpanLoop // yes + + popl %edi + popl %ebp // restore the caller's stack frame + popl %ebx // restore register variables + popl %esi + ret + + +// draw a one-long span + +LExactlyOneLong: + + movl spanpackage_t_pz(%esi),%ecx + movl spanpackage_t_zi(%esi),%ebp + + rorl $16,%ebp // put high 16 bits of 1/z in low word + movl spanpackage_t_ptex(%esi),%ebx + + cmpw (%ecx),%bp + jl LNextSpan + xorl %eax,%eax + movl spanpackage_t_pdest(%esi),%edi + movb spanpackage_t_light+1(%esi),%ah + addl $(spanpackage_t_size),%esi // point to next span + movb (%ebx),%al + movw %bp,(%ecx) + movb 0x12345678(%eax),%al +LPatch9: + movb %al,(%edi) + + jmp LNextSpanESISet + +.globl C(D_PolysetAff8End) +C(D_PolysetAff8End): + + +#define pcolormap 4 + +.globl C(D_Aff8Patch) +C(D_Aff8Patch): + movl pcolormap(%esp),%eax + movl %eax,LPatch1-4 + movl %eax,LPatch2-4 + movl %eax,LPatch3-4 + movl %eax,LPatch4-4 + movl %eax,LPatch5-4 + movl %eax,LPatch6-4 + movl %eax,LPatch7-4 + movl %eax,LPatch8-4 + movl %eax,LPatch9-4 + + ret + + +//---------------------------------------------------------------------- +// Alias model polygon dispatching code, combined with subdivided affine +// triangle drawing code +//---------------------------------------------------------------------- + +.globl C(D_PolysetDraw) +C(D_PolysetDraw): + +// spanpackage_t spans[DPS_MAXSPANS + 1 + +// ((CACHE_SIZE - 1) / sizeof(spanpackage_t)) + 1]; +// // one extra because of cache line pretouching +// +// a_spans = (spanpackage_t *) +// (((long)&spans[0] + CACHE_SIZE - 1) & ~(CACHE_SIZE - 1)); + subl $(SPAN_SIZE),%esp + movl %esp,%eax + addl $(CACHE_SIZE - 1),%eax + andl $(~(CACHE_SIZE - 1)),%eax + movl %eax,C(a_spans) + +// if (r_affinetridesc.drawtype) +// D_DrawSubdiv (); +// else +// D_DrawNonSubdiv (); + movl C(r_affinetridesc)+atd_drawtype,%eax + testl %eax,%eax + jz C(D_DrawNonSubdiv) + + pushl %ebp // preserve caller stack frame pointer + +// lnumtriangles = r_affinetridesc.numtriangles; + movl C(r_affinetridesc)+atd_numtriangles,%ebp + + pushl %esi // preserve register variables + shll $4,%ebp + + pushl %ebx +// ptri = r_affinetridesc.ptriangles; + movl C(r_affinetridesc)+atd_ptriangles,%ebx + + pushl %edi + +// mtriangle_t *ptri; +// finalvert_t *pfv, *index0, *index1, *index2; +// int i; +// int lnumtriangles; +// int s0, s1, s2; + +// pfv = r_affinetridesc.pfinalverts; + movl C(r_affinetridesc)+atd_pfinalverts,%edi + +// for (i=0 ; iv[1]-index1->v[1]) * +// (index0->v[0]-index2->v[0]) - +// (index0->v[0]-index1->v[0])*(index0->v[1]-index2->v[1])) >= 0) +// { +// continue; +// } +// +// d_pcolormap = &((byte *)acolormap)[index0->v[4] & 0xFF00]; + fildl fv_v+4(%ecx) // i0v1 + fildl fv_v+4(%esi) // i1v1 | i0v1 + fildl fv_v+0(%ecx) // i0v0 | i1v1 | i0v1 + fildl fv_v+0(%edx) // i2v0 | i0v0 | i1v1 | i0v1 + fxch %st(2) // i1v1 | i0v0 | i2v0 | i0v1 + fsubr %st(3),%st(0) // i0v1-i1v1 | i0v0 | i2v0 | i0v1 + fildl fv_v+0(%esi) // i1v0 | i0v1-i1v1 | i0v0 | i2v0 | i0v1 + fxch %st(2) // i0v0 | i0v1-i1v1 | i1v0 | i2v0 | i0v1 + fsub %st(0),%st(3) // i0v0 | i0v1-i1v1 | i1v0 | i0v0-i2v0 | i0v1 + fildl fv_v+4(%edx) // i2v1 | i0v0 | i0v1-i1v1 | i1v0 | i0v0-i2v0| i0v1 + fxch %st(1) // i0v0 | i2v1 | i0v1-i1v1 | i1v0 | i0v0-i2v0| i0v1 + fsubp %st(0),%st(3) // i2v1 | i0v1-i1v1 | i0v0-i1v0 | i0v0-i2v0 | i0v1 + fxch %st(1) // i0v1-i1v1 | i2v1 | i0v0-i1v0 | i0v0-i2v0 | i0v1 + fmulp %st(0),%st(3) // i2v1 | i0v0-i1v0 | i0v1-i1v1*i0v0-i2v0 | i0v1 + fsubrp %st(0),%st(3) // i0v0-i1v0 | i0v1-i1v1*i0v0-i2v0 | i0v1-i2v1 + movl fv_v+16(%ecx),%eax + andl $0xFF00,%eax + fmulp %st(0),%st(2) // i0v1-i1v1*i0v0-i2v0 | i0v0-i1v0*i0v1-i2v1 + addl C(acolormap),%eax + fsubp %st(0),%st(1) // (i0v1-i1v1)*(i0v0-i2v0)-(i0v0-i1v0)*(i0v1-i2v1) + movl %eax,C(d_pcolormap) + fstps Ltemp + movl Ltemp,%eax + subl $0x80000001,%eax + jc Lskip + +// if (ptri[i].facesfront) +// { +// D_PolysetRecursiveTriangle(index0->v, index1->v, index2->v); + movl mtri_facesfront-16(%ebx,%ebp,),%eax + testl %eax,%eax + jz Lfacesback + + pushl %edx + pushl %esi + pushl %ecx + call C(D_PolysetRecursiveTriangle) + + subl $16,%ebp + jnz Llooptop + jmp Ldone2 + +// } +// else +// { +Lfacesback: + +// s0 = index0->v[2]; +// s1 = index1->v[2]; +// s2 = index2->v[2]; + movl fv_v+8(%ecx),%eax + pushl %eax + movl fv_v+8(%esi),%eax + pushl %eax + movl fv_v+8(%edx),%eax + pushl %eax + pushl %ecx + pushl %edx + +// if (index0->flags & ALIAS_ONSEAM) +// index0->v[2] += r_affinetridesc.seamfixupX16; + movl C(r_affinetridesc)+atd_seamfixupX16,%eax + testl $(ALIAS_ONSEAM),fv_flags(%ecx) + jz Lp11 + addl %eax,fv_v+8(%ecx) +Lp11: + +// if (index1->flags & ALIAS_ONSEAM) +// index1->v[2] += r_affinetridesc.seamfixupX16; + testl $(ALIAS_ONSEAM),fv_flags(%esi) + jz Lp12 + addl %eax,fv_v+8(%esi) +Lp12: + +// if (index2->flags & ALIAS_ONSEAM) +// index2->v[2] += r_affinetridesc.seamfixupX16; + testl $(ALIAS_ONSEAM),fv_flags(%edx) + jz Lp13 + addl %eax,fv_v+8(%edx) +Lp13: + +// D_PolysetRecursiveTriangle(index0->v, index1->v, index2->v); + pushl %edx + pushl %esi + pushl %ecx + call C(D_PolysetRecursiveTriangle) + +// index0->v[2] = s0; +// index1->v[2] = s1; +// index2->v[2] = s2; + popl %edx + popl %ecx + popl %eax + movl %eax,fv_v+8(%edx) + popl %eax + movl %eax,fv_v+8(%esi) + popl %eax + movl %eax,fv_v+8(%ecx) + +// } +// } +Lskip: + subl $16,%ebp + jnz Llooptop + +Ldone2: + popl %edi // restore the caller's stack frame + popl %ebx + popl %esi // restore register variables + popl %ebp + + addl $(SPAN_SIZE),%esp + + ret + + +//---------------------------------------------------------------------- +// Alias model triangle left-edge scanning code +//---------------------------------------------------------------------- + +#define height 4+16 + +.globl C(D_PolysetScanLeftEdge) +C(D_PolysetScanLeftEdge): + pushl %ebp // preserve caller stack frame pointer + pushl %esi // preserve register variables + pushl %edi + pushl %ebx + + movl height(%esp),%eax + movl C(d_sfrac),%ecx + andl $0xFFFF,%eax + movl C(d_ptex),%ebx + orl %eax,%ecx + movl C(d_pedgespanpackage),%esi + movl C(d_tfrac),%edx + movl C(d_light),%edi + movl C(d_zi),%ebp + +// %eax: scratch +// %ebx: d_ptex +// %ecx: d_sfrac in high word, count in low word +// %edx: d_tfrac +// %esi: d_pedgespanpackage, errorterm, scratch alternately +// %edi: d_light +// %ebp: d_zi + +// do +// { + +LScanLoop: + +// d_pedgespanpackage->ptex = ptex; +// d_pedgespanpackage->pdest = d_pdest; +// d_pedgespanpackage->pz = d_pz; +// d_pedgespanpackage->count = d_aspancount; +// d_pedgespanpackage->light = d_light; +// d_pedgespanpackage->zi = d_zi; +// d_pedgespanpackage->sfrac = d_sfrac << 16; +// d_pedgespanpackage->tfrac = d_tfrac << 16; + movl %ebx,spanpackage_t_ptex(%esi) + movl C(d_pdest),%eax + movl %eax,spanpackage_t_pdest(%esi) + movl C(d_pz),%eax + movl %eax,spanpackage_t_pz(%esi) + movl C(d_aspancount),%eax + movl %eax,spanpackage_t_count(%esi) + movl %edi,spanpackage_t_light(%esi) + movl %ebp,spanpackage_t_zi(%esi) + movl %ecx,spanpackage_t_sfrac(%esi) + movl %edx,spanpackage_t_tfrac(%esi) + +// pretouch the next cache line + movb spanpackage_t_size(%esi),%al + +// d_pedgespanpackage++; + addl $(spanpackage_t_size),%esi + movl C(erroradjustup),%eax + movl %esi,C(d_pedgespanpackage) + +// errorterm += erroradjustup; + movl C(errorterm),%esi + addl %eax,%esi + movl C(d_pdest),%eax + +// if (errorterm >= 0) +// { + js LNoLeftEdgeTurnover + +// errorterm -= erroradjustdown; +// d_pdest += d_pdestextrastep; + subl C(erroradjustdown),%esi + addl C(d_pdestextrastep),%eax + movl %esi,C(errorterm) + movl %eax,C(d_pdest) + +// d_pz += d_pzextrastep; +// d_aspancount += d_countextrastep; +// d_ptex += d_ptexextrastep; +// d_sfrac += d_sfracextrastep; +// d_ptex += d_sfrac >> 16; +// d_sfrac &= 0xFFFF; +// d_tfrac += d_tfracextrastep; + movl C(d_pz),%eax + movl C(d_aspancount),%esi + addl C(d_pzextrastep),%eax + addl C(d_sfracextrastep),%ecx + adcl C(d_ptexextrastep),%ebx + addl C(d_countextrastep),%esi + movl %eax,C(d_pz) + movl C(d_tfracextrastep),%eax + movl %esi,C(d_aspancount) + addl %eax,%edx + +// if (d_tfrac & 0x10000) +// { + jnc LSkip1 + +// d_ptex += r_affinetridesc.skinwidth; +// d_tfrac &= 0xFFFF; + addl C(r_affinetridesc)+atd_skinwidth,%ebx + +// } + +LSkip1: + +// d_light += d_lightextrastep; +// d_zi += d_ziextrastep; + addl C(d_lightextrastep),%edi + addl C(d_ziextrastep),%ebp + +// } + movl C(d_pedgespanpackage),%esi + decl %ecx + testl $0xFFFF,%ecx + jnz LScanLoop + + popl %ebx + popl %edi + popl %esi + popl %ebp + ret + +// else +// { + +LNoLeftEdgeTurnover: + movl %esi,C(errorterm) + +// d_pdest += d_pdestbasestep; + addl C(d_pdestbasestep),%eax + movl %eax,C(d_pdest) + +// d_pz += d_pzbasestep; +// d_aspancount += ubasestep; +// d_ptex += d_ptexbasestep; +// d_sfrac += d_sfracbasestep; +// d_ptex += d_sfrac >> 16; +// d_sfrac &= 0xFFFF; + movl C(d_pz),%eax + movl C(d_aspancount),%esi + addl C(d_pzbasestep),%eax + addl C(d_sfracbasestep),%ecx + adcl C(d_ptexbasestep),%ebx + addl C(ubasestep),%esi + movl %eax,C(d_pz) + movl %esi,C(d_aspancount) + +// d_tfrac += d_tfracbasestep; + movl C(d_tfracbasestep),%esi + addl %esi,%edx + +// if (d_tfrac & 0x10000) +// { + jnc LSkip2 + +// d_ptex += r_affinetridesc.skinwidth; +// d_tfrac &= 0xFFFF; + addl C(r_affinetridesc)+atd_skinwidth,%ebx + +// } + +LSkip2: + +// d_light += d_lightbasestep; +// d_zi += d_zibasestep; + addl C(d_lightbasestep),%edi + addl C(d_zibasestep),%ebp + +// } +// } while (--height); + movl C(d_pedgespanpackage),%esi + decl %ecx + testl $0xFFFF,%ecx + jnz LScanLoop + + popl %ebx + popl %edi + popl %esi + popl %ebp + ret + + +//---------------------------------------------------------------------- +// Alias model vertex drawing code +//---------------------------------------------------------------------- + +#define fv 4+8 +#define numverts 8+8 + +.globl C(D_PolysetDrawFinalVerts) +C(D_PolysetDrawFinalVerts): + pushl %ebp // preserve caller stack frame pointer + pushl %ebx + +// int i, z; +// short *zbuf; + + movl numverts(%esp),%ecx + movl fv(%esp),%ebx + + pushl %esi // preserve register variables + pushl %edi + +LFVLoop: + +// for (i=0 ; iv[0] < r_refdef.vrectright) && +// (fv->v[1] < r_refdef.vrectbottom)) +// { + movl fv_v+0(%ebx),%eax + movl C(r_refdef)+rd_vrectright,%edx + cmpl %edx,%eax + jge LNextVert + movl fv_v+4(%ebx),%esi + movl C(r_refdef)+rd_vrectbottom,%edx + cmpl %edx,%esi + jge LNextVert + +// zbuf = zspantable[fv->v[1]] + fv->v[0]; + movl C(zspantable)(,%esi,4),%edi + +// z = fv->v[5]>>16; + movl fv_v+20(%ebx),%edx + shrl $16,%edx + +// if (z >= *zbuf) +// { +// int pix; + cmpw (%edi,%eax,2),%dx + jl LNextVert + +// *zbuf = z; + movw %dx,(%edi,%eax,2) + +// pix = skintable[fv->v[3]>>16][fv->v[2]>>16]; + movl fv_v+12(%ebx),%edi + shrl $16,%edi + movl C(skintable)(,%edi,4),%edi + movl fv_v+8(%ebx),%edx + shrl $16,%edx + movb (%edi,%edx),%dl + +// pix = ((byte *)acolormap)[pix + (fv->v[4] & 0xFF00)]; + movl fv_v+16(%ebx),%edi + andl $0xFF00,%edi + andl $0x00FF,%edx + addl %edx,%edi + movl C(acolormap),%edx + movb (%edx,%edi,1),%dl + +// d_viewbuffer[d_scantable[fv->v[1]] + fv->v[0]] = pix; + movl C(d_scantable)(,%esi,4),%edi + movl C(d_viewbuffer),%esi + addl %eax,%edi + movb %dl,(%esi,%edi) + +// } +// } +// } +LNextVert: + addl $(fv_size),%ebx + decl %ecx + jnz LFVLoop + + popl %edi + popl %esi + popl %ebx + popl %ebp + ret + + +//---------------------------------------------------------------------- +// Alias model non-subdivided polygon dispatching code +// +// not C-callable because of stack buffer cleanup +//---------------------------------------------------------------------- + +.globl C(D_DrawNonSubdiv) +C(D_DrawNonSubdiv): + pushl %ebp // preserve caller stack frame pointer + movl C(r_affinetridesc)+atd_numtriangles,%ebp + pushl %ebx + shll $(mtri_shift),%ebp + pushl %esi // preserve register variables + movl C(r_affinetridesc)+atd_ptriangles,%esi + pushl %edi + +// mtriangle_t *ptri; +// finalvert_t *pfv, *index0, *index1, *index2; +// int i; +// int lnumtriangles; + +// pfv = r_affinetridesc.pfinalverts; +// ptri = r_affinetridesc.ptriangles; +// lnumtriangles = r_affinetridesc.numtriangles; + +LNDLoop: + +// for (i=0 ; ivertindex[0]; +// index1 = pfv + ptri->vertindex[1]; +// index2 = pfv + ptri->vertindex[2]; + movl C(r_affinetridesc)+atd_pfinalverts,%edi + movl mtri_vertindex+0-mtri_size(%esi,%ebp,1),%ecx + shll $(fv_shift),%ecx + movl mtri_vertindex+4-mtri_size(%esi,%ebp,1),%edx + shll $(fv_shift),%edx + movl mtri_vertindex+8-mtri_size(%esi,%ebp,1),%ebx + shll $(fv_shift),%ebx + addl %edi,%ecx + addl %edi,%edx + addl %edi,%ebx + +// d_xdenom = (index0->v[1]-index1->v[1]) * +// (index0->v[0]-index2->v[0]) - +// (index0->v[0]-index1->v[0])*(index0->v[1]-index2->v[1]); + movl fv_v+4(%ecx),%eax + movl fv_v+0(%ecx),%esi + subl fv_v+4(%edx),%eax + subl fv_v+0(%ebx),%esi + imull %esi,%eax + movl fv_v+0(%ecx),%esi + movl fv_v+4(%ecx),%edi + subl fv_v+0(%edx),%esi + subl fv_v+4(%ebx),%edi + imull %esi,%edi + subl %edi,%eax + +// if (d_xdenom >= 0) +// { +// continue; + jns LNextTri + +// } + + movl %eax,C(d_xdenom) + fildl C(d_xdenom) + +// r_p0[0] = index0->v[0]; // u +// r_p0[1] = index0->v[1]; // v +// r_p0[2] = index0->v[2]; // s +// r_p0[3] = index0->v[3]; // t +// r_p0[4] = index0->v[4]; // light +// r_p0[5] = index0->v[5]; // iz + movl fv_v+0(%ecx),%eax + movl fv_v+4(%ecx),%esi + movl %eax,C(r_p0)+0 + movl %esi,C(r_p0)+4 + movl fv_v+8(%ecx),%eax + movl fv_v+12(%ecx),%esi + movl %eax,C(r_p0)+8 + movl %esi,C(r_p0)+12 + movl fv_v+16(%ecx),%eax + movl fv_v+20(%ecx),%esi + movl %eax,C(r_p0)+16 + movl %esi,C(r_p0)+20 + + fdivrs float_1 + +// r_p1[0] = index1->v[0]; +// r_p1[1] = index1->v[1]; +// r_p1[2] = index1->v[2]; +// r_p1[3] = index1->v[3]; +// r_p1[4] = index1->v[4]; +// r_p1[5] = index1->v[5]; + movl fv_v+0(%edx),%eax + movl fv_v+4(%edx),%esi + movl %eax,C(r_p1)+0 + movl %esi,C(r_p1)+4 + movl fv_v+8(%edx),%eax + movl fv_v+12(%edx),%esi + movl %eax,C(r_p1)+8 + movl %esi,C(r_p1)+12 + movl fv_v+16(%edx),%eax + movl fv_v+20(%edx),%esi + movl %eax,C(r_p1)+16 + movl %esi,C(r_p1)+20 + +// r_p2[0] = index2->v[0]; +// r_p2[1] = index2->v[1]; +// r_p2[2] = index2->v[2]; +// r_p2[3] = index2->v[3]; +// r_p2[4] = index2->v[4]; +// r_p2[5] = index2->v[5]; + movl fv_v+0(%ebx),%eax + movl fv_v+4(%ebx),%esi + movl %eax,C(r_p2)+0 + movl %esi,C(r_p2)+4 + movl fv_v+8(%ebx),%eax + movl fv_v+12(%ebx),%esi + movl %eax,C(r_p2)+8 + movl %esi,C(r_p2)+12 + movl fv_v+16(%ebx),%eax + movl fv_v+20(%ebx),%esi + movl %eax,C(r_p2)+16 + movl C(r_affinetridesc)+atd_ptriangles,%edi + movl %esi,C(r_p2)+20 + movl mtri_facesfront-mtri_size(%edi,%ebp,1),%eax + +// if (!ptri->facesfront) +// { + testl %eax,%eax + jnz LFacesFront + +// if (index0->flags & ALIAS_ONSEAM) +// r_p0[2] += r_affinetridesc.seamfixupX16; + movl fv_flags(%ecx),%eax + movl fv_flags(%edx),%esi + movl fv_flags(%ebx),%edi + testl $(ALIAS_ONSEAM),%eax + movl C(r_affinetridesc)+atd_seamfixupX16,%eax + jz LOnseamDone0 + addl %eax,C(r_p0)+8 +LOnseamDone0: + +// if (index1->flags & ALIAS_ONSEAM) +// r_p1[2] += r_affinetridesc.seamfixupX16; + testl $(ALIAS_ONSEAM),%esi + jz LOnseamDone1 + addl %eax,C(r_p1)+8 +LOnseamDone1: + +// if (index2->flags & ALIAS_ONSEAM) +// r_p2[2] += r_affinetridesc.seamfixupX16; + testl $(ALIAS_ONSEAM),%edi + jz LOnseamDone2 + addl %eax,C(r_p2)+8 +LOnseamDone2: + +// } + +LFacesFront: + + fstps C(d_xdenom) + +// D_PolysetSetEdgeTable (); +// D_RasterizeAliasPolySmooth (); + call C(D_PolysetSetEdgeTable) + call C(D_RasterizeAliasPolySmooth) + +LNextTri: + movl C(r_affinetridesc)+atd_ptriangles,%esi + subl $16,%ebp + jnz LNDLoop +// } + + popl %edi + popl %esi + popl %ebx + popl %ebp + + addl $(SPAN_SIZE),%esp + + ret + + +#endif // id386 + diff --git a/contrib/other/sdlquake-1.0.9/d_polyse.c b/contrib/other/sdlquake-1.0.9/d_polyse.c new file mode 100644 index 000000000..9acd34b10 --- /dev/null +++ b/contrib/other/sdlquake-1.0.9/d_polyse.c @@ -0,0 +1,1111 @@ +/* +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. + +*/ +// d_polyset.c: routines for drawing sets of polygons sharing the same +// texture (used for Alias models) + +#include "quakedef.h" +#include "r_local.h" +#include "d_local.h" + +// TODO: put in span spilling to shrink list size +// !!! if this is changed, it must be changed in d_polysa.s too !!! +#define DPS_MAXSPANS MAXHEIGHT+1 + // 1 extra for spanpackage that marks end + +// !!! if this is changed, it must be changed in asm_draw.h too !!! +typedef struct { + void *pdest; + short *pz; + int count; + byte *ptex; + int sfrac, tfrac, light, zi; +} spanpackage_t; + +typedef struct { + int isflattop; + int numleftedges; + int *pleftedgevert0; + int *pleftedgevert1; + int *pleftedgevert2; + int numrightedges; + int *prightedgevert0; + int *prightedgevert1; + int *prightedgevert2; +} edgetable; + +int r_p0[6], r_p1[6], r_p2[6]; + +byte *d_pcolormap; + +int d_aflatcolor; +int d_xdenom; + +edgetable *pedgetable; + +edgetable edgetables[12] = { + {0, 1, r_p0, r_p2, NULL, 2, r_p0, r_p1, r_p2 }, + {0, 2, r_p1, r_p0, r_p2, 1, r_p1, r_p2, NULL}, + {1, 1, r_p0, r_p2, NULL, 1, r_p1, r_p2, NULL}, + {0, 1, r_p1, r_p0, NULL, 2, r_p1, r_p2, r_p0 }, + {0, 2, r_p0, r_p2, r_p1, 1, r_p0, r_p1, NULL}, + {0, 1, r_p2, r_p1, NULL, 1, r_p2, r_p0, NULL}, + {0, 1, r_p2, r_p1, NULL, 2, r_p2, r_p0, r_p1 }, + {0, 2, r_p2, r_p1, r_p0, 1, r_p2, r_p0, NULL}, + {0, 1, r_p1, r_p0, NULL, 1, r_p1, r_p2, NULL}, + {1, 1, r_p2, r_p1, NULL, 1, r_p0, r_p1, NULL}, + {1, 1, r_p1, r_p0, NULL, 1, r_p2, r_p0, NULL}, + {0, 1, r_p0, r_p2, NULL, 1, r_p0, r_p1, NULL}, +}; + +// FIXME: some of these can become statics +int a_sstepxfrac, a_tstepxfrac, r_lstepx, a_ststepxwhole; +int r_sstepx, r_tstepx, r_lstepy, r_sstepy, r_tstepy; +int r_zistepx, r_zistepy; +int d_aspancount, d_countextrastep; + +spanpackage_t *a_spans; +spanpackage_t *d_pedgespanpackage; +static int ystart; +byte *d_pdest, *d_ptex; +short *d_pz; +int d_sfrac, d_tfrac, d_light, d_zi; +int d_ptexextrastep, d_sfracextrastep; +int d_tfracextrastep, d_lightextrastep, d_pdestextrastep; +int d_lightbasestep, d_pdestbasestep, d_ptexbasestep; +int d_sfracbasestep, d_tfracbasestep; +int d_ziextrastep, d_zibasestep; +int d_pzextrastep, d_pzbasestep; + +typedef struct { + int quotient; + int remainder; +} adivtab_t; + +static adivtab_t adivtab[32*32] = { +#include "adivtab.h" +}; + +byte *skintable[MAX_LBM_HEIGHT]; +int skinwidth; +byte *skinstart; + +void D_PolysetDrawSpans8 (spanpackage_t *pspanpackage); +void D_PolysetCalcGradients (int skinwidth); +void D_DrawSubdiv (void); +void D_DrawNonSubdiv (void); +void D_PolysetRecursiveTriangle (int *p1, int *p2, int *p3); +void D_PolysetSetEdgeTable (void); +void D_RasterizeAliasPolySmooth (void); +void D_PolysetScanLeftEdge (int height); + +#if !id386 + +/* +================ +D_PolysetDraw +================ +*/ +void D_PolysetDraw (void) +{ + spanpackage_t spans[DPS_MAXSPANS + 1 + + ((CACHE_SIZE - 1) / sizeof(spanpackage_t)) + 1]; + // one extra because of cache line pretouching + + a_spans = (spanpackage_t *) + (((long)&spans[0] + CACHE_SIZE - 1) & ~(CACHE_SIZE - 1)); + + if (r_affinetridesc.drawtype) + { + D_DrawSubdiv (); + } + else + { + D_DrawNonSubdiv (); + } +} + + +/* +================ +D_PolysetDrawFinalVerts +================ +*/ +void D_PolysetDrawFinalVerts (finalvert_t *fv, int numverts) +{ + int i, z; + short *zbuf; + + for (i=0 ; iv[0] < r_refdef.vrectright) && + (fv->v[1] < r_refdef.vrectbottom)) + { + z = fv->v[5]>>16; + zbuf = zspantable[fv->v[1]] + fv->v[0]; + if (z >= *zbuf) + { + int pix; + + *zbuf = z; + pix = skintable[fv->v[3]>>16][fv->v[2]>>16]; + pix = ((byte *)acolormap)[pix + (fv->v[4] & 0xFF00) ]; + d_viewbuffer[d_scantable[fv->v[1]] + fv->v[0]] = pix; + } + } + } +} + + +/* +================ +D_DrawSubdiv +================ +*/ +void D_DrawSubdiv (void) +{ + mtriangle_t *ptri; + finalvert_t *pfv, *index0, *index1, *index2; + int i; + int lnumtriangles; + + pfv = r_affinetridesc.pfinalverts; + ptri = r_affinetridesc.ptriangles; + lnumtriangles = r_affinetridesc.numtriangles; + + for (i=0 ; iv[1]-index1->v[1]) * + (index0->v[0]-index2->v[0]) - + (index0->v[0]-index1->v[0]) * + (index0->v[1]-index2->v[1])) >= 0) + { + continue; + } + + d_pcolormap = &((byte *)acolormap)[index0->v[4] & 0xFF00]; + + if (ptri[i].facesfront) + { + D_PolysetRecursiveTriangle(index0->v, index1->v, index2->v); + } + else + { + int s0, s1, s2; + + s0 = index0->v[2]; + s1 = index1->v[2]; + s2 = index2->v[2]; + + if (index0->flags & ALIAS_ONSEAM) + index0->v[2] += r_affinetridesc.seamfixupX16; + if (index1->flags & ALIAS_ONSEAM) + index1->v[2] += r_affinetridesc.seamfixupX16; + if (index2->flags & ALIAS_ONSEAM) + index2->v[2] += r_affinetridesc.seamfixupX16; + + D_PolysetRecursiveTriangle(index0->v, index1->v, index2->v); + + index0->v[2] = s0; + index1->v[2] = s1; + index2->v[2] = s2; + } + } +} + + +/* +================ +D_DrawNonSubdiv +================ +*/ +void D_DrawNonSubdiv (void) +{ + mtriangle_t *ptri; + finalvert_t *pfv, *index0, *index1, *index2; + int i; + int lnumtriangles; + + pfv = r_affinetridesc.pfinalverts; + ptri = r_affinetridesc.ptriangles; + lnumtriangles = r_affinetridesc.numtriangles; + + for (i=0 ; ivertindex[0]; + index1 = pfv + ptri->vertindex[1]; + index2 = pfv + ptri->vertindex[2]; + + d_xdenom = (index0->v[1]-index1->v[1]) * + (index0->v[0]-index2->v[0]) - + (index0->v[0]-index1->v[0])*(index0->v[1]-index2->v[1]); + + if (d_xdenom >= 0) + { + continue; + } + + r_p0[0] = index0->v[0]; // u + r_p0[1] = index0->v[1]; // v + r_p0[2] = index0->v[2]; // s + r_p0[3] = index0->v[3]; // t + r_p0[4] = index0->v[4]; // light + r_p0[5] = index0->v[5]; // iz + + r_p1[0] = index1->v[0]; + r_p1[1] = index1->v[1]; + r_p1[2] = index1->v[2]; + r_p1[3] = index1->v[3]; + r_p1[4] = index1->v[4]; + r_p1[5] = index1->v[5]; + + r_p2[0] = index2->v[0]; + r_p2[1] = index2->v[1]; + r_p2[2] = index2->v[2]; + r_p2[3] = index2->v[3]; + r_p2[4] = index2->v[4]; + r_p2[5] = index2->v[5]; + + if (!ptri->facesfront) + { + if (index0->flags & ALIAS_ONSEAM) + r_p0[2] += r_affinetridesc.seamfixupX16; + if (index1->flags & ALIAS_ONSEAM) + r_p1[2] += r_affinetridesc.seamfixupX16; + if (index2->flags & ALIAS_ONSEAM) + r_p2[2] += r_affinetridesc.seamfixupX16; + } + + D_PolysetSetEdgeTable (); + D_RasterizeAliasPolySmooth (); + } +} + + +/* +================ +D_PolysetRecursiveTriangle +================ +*/ +void D_PolysetRecursiveTriangle (int *lp1, int *lp2, int *lp3) +{ + int *temp; + int d; + int new[6]; + int z; + short *zbuf; + + d = lp2[0] - lp1[0]; + if (d < -1 || d > 1) + goto split; + d = lp2[1] - lp1[1]; + if (d < -1 || d > 1) + goto split; + + d = lp3[0] - lp2[0]; + if (d < -1 || d > 1) + goto split2; + d = lp3[1] - lp2[1]; + if (d < -1 || d > 1) + goto split2; + + d = lp1[0] - lp3[0]; + if (d < -1 || d > 1) + goto split3; + d = lp1[1] - lp3[1]; + if (d < -1 || d > 1) + { +split3: + temp = lp1; + lp1 = lp3; + lp3 = lp2; + lp2 = temp; + + goto split; + } + + return; // entire tri is filled + +split2: + temp = lp1; + lp1 = lp2; + lp2 = lp3; + lp3 = temp; + +split: +// split this edge + new[0] = (lp1[0] + lp2[0]) >> 1; + new[1] = (lp1[1] + lp2[1]) >> 1; + new[2] = (lp1[2] + lp2[2]) >> 1; + new[3] = (lp1[3] + lp2[3]) >> 1; + new[5] = (lp1[5] + lp2[5]) >> 1; + +// draw the point if splitting a leading edge + if (lp2[1] > lp1[1]) + goto nodraw; + if ((lp2[1] == lp1[1]) && (lp2[0] < lp1[0])) + goto nodraw; + + + z = new[5]>>16; + zbuf = zspantable[new[1]] + new[0]; + if (z >= *zbuf) + { + int pix; + + *zbuf = z; + pix = d_pcolormap[skintable[new[3]>>16][new[2]>>16]]; + d_viewbuffer[d_scantable[new[1]] + new[0]] = pix; + } + +nodraw: +// recursively continue + D_PolysetRecursiveTriangle (lp3, lp1, new); + D_PolysetRecursiveTriangle (lp3, new, lp2); +} + +#endif // !id386 + + +/* +================ +D_PolysetUpdateTables +================ +*/ +void D_PolysetUpdateTables (void) +{ + int i; + byte *s; + + if (r_affinetridesc.skinwidth != skinwidth || + r_affinetridesc.pskin != skinstart) + { + skinwidth = r_affinetridesc.skinwidth; + skinstart = r_affinetridesc.pskin; + s = skinstart; + for (i=0 ; ipdest = d_pdest; + d_pedgespanpackage->pz = d_pz; + d_pedgespanpackage->count = d_aspancount; + d_pedgespanpackage->ptex = d_ptex; + + d_pedgespanpackage->sfrac = d_sfrac; + d_pedgespanpackage->tfrac = d_tfrac; + + // FIXME: need to clamp l, s, t, at both ends? + d_pedgespanpackage->light = d_light; + d_pedgespanpackage->zi = d_zi; + + d_pedgespanpackage++; + + errorterm += erroradjustup; + if (errorterm >= 0) + { + d_pdest += d_pdestextrastep; + d_pz += d_pzextrastep; + d_aspancount += d_countextrastep; + d_ptex += d_ptexextrastep; + d_sfrac += d_sfracextrastep; + d_ptex += d_sfrac >> 16; + + d_sfrac &= 0xFFFF; + d_tfrac += d_tfracextrastep; + if (d_tfrac & 0x10000) + { + d_ptex += r_affinetridesc.skinwidth; + d_tfrac &= 0xFFFF; + } + d_light += d_lightextrastep; + d_zi += d_ziextrastep; + errorterm -= erroradjustdown; + } + else + { + d_pdest += d_pdestbasestep; + d_pz += d_pzbasestep; + d_aspancount += ubasestep; + d_ptex += d_ptexbasestep; + d_sfrac += d_sfracbasestep; + d_ptex += d_sfrac >> 16; + d_sfrac &= 0xFFFF; + d_tfrac += d_tfracbasestep; + if (d_tfrac & 0x10000) + { + d_ptex += r_affinetridesc.skinwidth; + d_tfrac &= 0xFFFF; + } + d_light += d_lightbasestep; + d_zi += d_zibasestep; + } + } while (--height); +} + +#endif // !id386 + + +/* +=================== +D_PolysetSetUpForLineScan +==================== +*/ +void D_PolysetSetUpForLineScan(fixed8_t startvertu, fixed8_t startvertv, + fixed8_t endvertu, fixed8_t endvertv) +{ + double dm, dn; + int tm, tn; + adivtab_t *ptemp; + +// TODO: implement x86 version + + errorterm = -1; + + tm = endvertu - startvertu; + tn = endvertv - startvertv; + + if (((tm <= 16) && (tm >= -15)) && + ((tn <= 16) && (tn >= -15))) + { + ptemp = &adivtab[((tm+15) << 5) + (tn+15)]; + ubasestep = ptemp->quotient; + erroradjustup = ptemp->remainder; + erroradjustdown = tn; + } + else + { + dm = (double)tm; + dn = (double)tn; + + FloorDivMod (dm, dn, &ubasestep, &erroradjustup); + + erroradjustdown = dn; + } +} + + +#if !id386 + +/* +================ +D_PolysetCalcGradients +================ +*/ +void D_PolysetCalcGradients (int skinwidth) +{ + float xstepdenominv, ystepdenominv, t0, t1; + float p01_minus_p21, p11_minus_p21, p00_minus_p20, p10_minus_p20; + + p00_minus_p20 = r_p0[0] - r_p2[0]; + p01_minus_p21 = r_p0[1] - r_p2[1]; + p10_minus_p20 = r_p1[0] - r_p2[0]; + p11_minus_p21 = r_p1[1] - r_p2[1]; + + xstepdenominv = 1.0 / (float)d_xdenom; + + ystepdenominv = -xstepdenominv; + +// ceil () for light so positive steps are exaggerated, negative steps +// diminished, pushing us away from underflow toward overflow. Underflow is +// very visible, overflow is very unlikely, because of ambient lighting + t0 = r_p0[4] - r_p2[4]; + t1 = r_p1[4] - r_p2[4]; + r_lstepx = (int) + ceil((t1 * p01_minus_p21 - t0 * p11_minus_p21) * xstepdenominv); + r_lstepy = (int) + ceil((t1 * p00_minus_p20 - t0 * p10_minus_p20) * ystepdenominv); + + t0 = r_p0[2] - r_p2[2]; + t1 = r_p1[2] - r_p2[2]; + r_sstepx = (int)((t1 * p01_minus_p21 - t0 * p11_minus_p21) * + xstepdenominv); + r_sstepy = (int)((t1 * p00_minus_p20 - t0* p10_minus_p20) * + ystepdenominv); + + t0 = r_p0[3] - r_p2[3]; + t1 = r_p1[3] - r_p2[3]; + r_tstepx = (int)((t1 * p01_minus_p21 - t0 * p11_minus_p21) * + xstepdenominv); + r_tstepy = (int)((t1 * p00_minus_p20 - t0 * p10_minus_p20) * + ystepdenominv); + + t0 = r_p0[5] - r_p2[5]; + t1 = r_p1[5] - r_p2[5]; + r_zistepx = (int)((t1 * p01_minus_p21 - t0 * p11_minus_p21) * + xstepdenominv); + r_zistepy = (int)((t1 * p00_minus_p20 - t0 * p10_minus_p20) * + ystepdenominv); + +#if id386 + a_sstepxfrac = r_sstepx << 16; + a_tstepxfrac = r_tstepx << 16; +#else + a_sstepxfrac = r_sstepx & 0xFFFF; + a_tstepxfrac = r_tstepx & 0xFFFF; +#endif + + a_ststepxwhole = skinwidth * (r_tstepx >> 16) + (r_sstepx >> 16); +} + +#endif // !id386 + + +#if 0 +byte gelmap[256]; +void InitGel (byte *palette) +{ + int i; + int r; + + for (i=0 ; i<256 ; i++) + { +// r = (palette[i*3]>>4); + r = (palette[i*3] + palette[i*3+1] + palette[i*3+2])/(16*3); + gelmap[i] = /* 64 */ 0 + r; + } +} +#endif + + +#if !id386 + +/* +================ +D_PolysetDrawSpans8 +================ +*/ +void D_PolysetDrawSpans8 (spanpackage_t *pspanpackage) +{ + int lcount; + byte *lpdest; + byte *lptex; + int lsfrac, ltfrac; + int llight; + int lzi; + short *lpz; + + do + { + lcount = d_aspancount - pspanpackage->count; + + errorterm += erroradjustup; + if (errorterm >= 0) + { + d_aspancount += d_countextrastep; + errorterm -= erroradjustdown; + } + else + { + d_aspancount += ubasestep; + } + + if (lcount) + { + lpdest = pspanpackage->pdest; + lptex = pspanpackage->ptex; + lpz = pspanpackage->pz; + lsfrac = pspanpackage->sfrac; + ltfrac = pspanpackage->tfrac; + llight = pspanpackage->light; + lzi = pspanpackage->zi; + + do + { + if ((lzi >> 16) >= *lpz) + { + *lpdest = ((byte *)acolormap)[*lptex + (llight & 0xFF00)]; +// gel mapping *lpdest = gelmap[*lpdest]; + *lpz = lzi >> 16; + } + lpdest++; + lzi += r_zistepx; + lpz++; + llight += r_lstepx; + lptex += a_ststepxwhole; + lsfrac += a_sstepxfrac; + lptex += lsfrac >> 16; + lsfrac &= 0xFFFF; + ltfrac += a_tstepxfrac; + if (ltfrac & 0x10000) + { + lptex += r_affinetridesc.skinwidth; + ltfrac &= 0xFFFF; + } + } while (--lcount); + } + + pspanpackage++; + } while (pspanpackage->count != -999999); +} +#endif // !id386 + + +/* +================ +D_PolysetFillSpans8 +================ +*/ +void D_PolysetFillSpans8 (spanpackage_t *pspanpackage) +{ + int color; + +// FIXME: do z buffering + + color = d_aflatcolor++; + + while (1) + { + int lcount; + byte *lpdest; + + lcount = pspanpackage->count; + + if (lcount == -1) + return; + + if (lcount) + { + lpdest = pspanpackage->pdest; + + do + { + *lpdest++ = color; + } while (--lcount); + } + + pspanpackage++; + } +} + +/* +================ +D_RasterizeAliasPolySmooth +================ +*/ +void D_RasterizeAliasPolySmooth (void) +{ + int initialleftheight, initialrightheight; + int *plefttop, *prighttop, *pleftbottom, *prightbottom; + int working_lstepx, originalcount; + + plefttop = pedgetable->pleftedgevert0; + prighttop = pedgetable->prightedgevert0; + + pleftbottom = pedgetable->pleftedgevert1; + prightbottom = pedgetable->prightedgevert1; + + initialleftheight = pleftbottom[1] - plefttop[1]; + initialrightheight = prightbottom[1] - prighttop[1]; + +// +// set the s, t, and light gradients, which are consistent across the triangle +// because being a triangle, things are affine +// + D_PolysetCalcGradients (r_affinetridesc.skinwidth); + +// +// rasterize the polygon +// + +// +// scan out the top (and possibly only) part of the left edge +// + d_pedgespanpackage = a_spans; + + ystart = plefttop[1]; + d_aspancount = plefttop[0] - prighttop[0]; + + d_ptex = (byte *)r_affinetridesc.pskin + (plefttop[2] >> 16) + + (plefttop[3] >> 16) * r_affinetridesc.skinwidth; +#if id386 + d_sfrac = (plefttop[2] & 0xFFFF) << 16; + d_tfrac = (plefttop[3] & 0xFFFF) << 16; +#else + d_sfrac = plefttop[2] & 0xFFFF; + d_tfrac = plefttop[3] & 0xFFFF; +#endif + d_light = plefttop[4]; + d_zi = plefttop[5]; + + d_pdest = (byte *)d_viewbuffer + + ystart * screenwidth + plefttop[0]; + d_pz = d_pzbuffer + ystart * d_zwidth + plefttop[0]; + + if (initialleftheight == 1) + { + d_pedgespanpackage->pdest = d_pdest; + d_pedgespanpackage->pz = d_pz; + d_pedgespanpackage->count = d_aspancount; + d_pedgespanpackage->ptex = d_ptex; + + d_pedgespanpackage->sfrac = d_sfrac; + d_pedgespanpackage->tfrac = d_tfrac; + + // FIXME: need to clamp l, s, t, at both ends? + d_pedgespanpackage->light = d_light; + d_pedgespanpackage->zi = d_zi; + + d_pedgespanpackage++; + } + else + { + D_PolysetSetUpForLineScan(plefttop[0], plefttop[1], + pleftbottom[0], pleftbottom[1]); + + #if id386 + d_pzbasestep = (d_zwidth + ubasestep) << 1; + d_pzextrastep = d_pzbasestep + 2; + #else + d_pzbasestep = d_zwidth + ubasestep; + d_pzextrastep = d_pzbasestep + 1; + #endif + + d_pdestbasestep = screenwidth + ubasestep; + d_pdestextrastep = d_pdestbasestep + 1; + + // TODO: can reuse partial expressions here + + // for negative steps in x along left edge, bias toward overflow rather than + // underflow (sort of turning the floor () we did in the gradient calcs into + // ceil (), but plus a little bit) + if (ubasestep < 0) + working_lstepx = r_lstepx - 1; + else + working_lstepx = r_lstepx; + + d_countextrastep = ubasestep + 1; + d_ptexbasestep = ((r_sstepy + r_sstepx * ubasestep) >> 16) + + ((r_tstepy + r_tstepx * ubasestep) >> 16) * + r_affinetridesc.skinwidth; + #if id386 + d_sfracbasestep = (r_sstepy + r_sstepx * ubasestep) << 16; + d_tfracbasestep = (r_tstepy + r_tstepx * ubasestep) << 16; + #else + d_sfracbasestep = (r_sstepy + r_sstepx * ubasestep) & 0xFFFF; + d_tfracbasestep = (r_tstepy + r_tstepx * ubasestep) & 0xFFFF; + #endif + d_lightbasestep = r_lstepy + working_lstepx * ubasestep; + d_zibasestep = r_zistepy + r_zistepx * ubasestep; + + d_ptexextrastep = ((r_sstepy + r_sstepx * d_countextrastep) >> 16) + + ((r_tstepy + r_tstepx * d_countextrastep) >> 16) * + r_affinetridesc.skinwidth; + #if id386 + d_sfracextrastep = (r_sstepy + r_sstepx*d_countextrastep) << 16; + d_tfracextrastep = (r_tstepy + r_tstepx*d_countextrastep) << 16; + #else + d_sfracextrastep = (r_sstepy + r_sstepx*d_countextrastep) & 0xFFFF; + d_tfracextrastep = (r_tstepy + r_tstepx*d_countextrastep) & 0xFFFF; + #endif + d_lightextrastep = d_lightbasestep + working_lstepx; + d_ziextrastep = d_zibasestep + r_zistepx; + + D_PolysetScanLeftEdge (initialleftheight); + } + +// +// scan out the bottom part of the left edge, if it exists +// + if (pedgetable->numleftedges == 2) + { + int height; + + plefttop = pleftbottom; + pleftbottom = pedgetable->pleftedgevert2; + + height = pleftbottom[1] - plefttop[1]; + +// TODO: make this a function; modularize this function in general + + ystart = plefttop[1]; + d_aspancount = plefttop[0] - prighttop[0]; + d_ptex = (byte *)r_affinetridesc.pskin + (plefttop[2] >> 16) + + (plefttop[3] >> 16) * r_affinetridesc.skinwidth; + d_sfrac = 0; + d_tfrac = 0; + d_light = plefttop[4]; + d_zi = plefttop[5]; + + d_pdest = (byte *)d_viewbuffer + ystart * screenwidth + plefttop[0]; + d_pz = d_pzbuffer + ystart * d_zwidth + plefttop[0]; + + if (height == 1) + { + d_pedgespanpackage->pdest = d_pdest; + d_pedgespanpackage->pz = d_pz; + d_pedgespanpackage->count = d_aspancount; + d_pedgespanpackage->ptex = d_ptex; + + d_pedgespanpackage->sfrac = d_sfrac; + d_pedgespanpackage->tfrac = d_tfrac; + + // FIXME: need to clamp l, s, t, at both ends? + d_pedgespanpackage->light = d_light; + d_pedgespanpackage->zi = d_zi; + + d_pedgespanpackage++; + } + else + { + D_PolysetSetUpForLineScan(plefttop[0], plefttop[1], + pleftbottom[0], pleftbottom[1]); + + d_pdestbasestep = screenwidth + ubasestep; + d_pdestextrastep = d_pdestbasestep + 1; + + #if id386 + d_pzbasestep = (d_zwidth + ubasestep) << 1; + d_pzextrastep = d_pzbasestep + 2; + #else + d_pzbasestep = d_zwidth + ubasestep; + d_pzextrastep = d_pzbasestep + 1; + #endif + + if (ubasestep < 0) + working_lstepx = r_lstepx - 1; + else + working_lstepx = r_lstepx; + + d_countextrastep = ubasestep + 1; + d_ptexbasestep = ((r_sstepy + r_sstepx * ubasestep) >> 16) + + ((r_tstepy + r_tstepx * ubasestep) >> 16) * + r_affinetridesc.skinwidth; + #if id386 + d_sfracbasestep = (r_sstepy + r_sstepx * ubasestep) << 16; + d_tfracbasestep = (r_tstepy + r_tstepx * ubasestep) << 16; + #else + d_sfracbasestep = (r_sstepy + r_sstepx * ubasestep) & 0xFFFF; + d_tfracbasestep = (r_tstepy + r_tstepx * ubasestep) & 0xFFFF; + #endif + d_lightbasestep = r_lstepy + working_lstepx * ubasestep; + d_zibasestep = r_zistepy + r_zistepx * ubasestep; + + d_ptexextrastep = ((r_sstepy + r_sstepx * d_countextrastep) >> 16) + + ((r_tstepy + r_tstepx * d_countextrastep) >> 16) * + r_affinetridesc.skinwidth; + #if id386 + d_sfracextrastep = ((r_sstepy+r_sstepx*d_countextrastep) & 0xFFFF)<<16; + d_tfracextrastep = ((r_tstepy+r_tstepx*d_countextrastep) & 0xFFFF)<<16; + #else + d_sfracextrastep = (r_sstepy+r_sstepx*d_countextrastep) & 0xFFFF; + d_tfracextrastep = (r_tstepy+r_tstepx*d_countextrastep) & 0xFFFF; + #endif + d_lightextrastep = d_lightbasestep + working_lstepx; + d_ziextrastep = d_zibasestep + r_zistepx; + + D_PolysetScanLeftEdge (height); + } + } + +// scan out the top (and possibly only) part of the right edge, updating the +// count field + d_pedgespanpackage = a_spans; + + D_PolysetSetUpForLineScan(prighttop[0], prighttop[1], + prightbottom[0], prightbottom[1]); + d_aspancount = 0; + d_countextrastep = ubasestep + 1; + originalcount = a_spans[initialrightheight].count; + a_spans[initialrightheight].count = -999999; // mark end of the spanpackages + D_PolysetDrawSpans8 (a_spans); + +// scan out the bottom part of the right edge, if it exists + if (pedgetable->numrightedges == 2) + { + int height; + spanpackage_t *pstart; + + pstart = a_spans + initialrightheight; + pstart->count = originalcount; + + d_aspancount = prightbottom[0] - prighttop[0]; + + prighttop = prightbottom; + prightbottom = pedgetable->prightedgevert2; + + height = prightbottom[1] - prighttop[1]; + + D_PolysetSetUpForLineScan(prighttop[0], prighttop[1], + prightbottom[0], prightbottom[1]); + + d_countextrastep = ubasestep + 1; + a_spans[initialrightheight + height].count = -999999; + // mark end of the spanpackages + D_PolysetDrawSpans8 (pstart); + } +} + + +/* +================ +D_PolysetSetEdgeTable +================ +*/ +void D_PolysetSetEdgeTable (void) +{ + int edgetableindex; + + edgetableindex = 0; // assume the vertices are already in + // top to bottom order + +// +// determine which edges are right & left, and the order in which +// to rasterize them +// + if (r_p0[1] >= r_p1[1]) + { + if (r_p0[1] == r_p1[1]) + { + if (r_p0[1] < r_p2[1]) + pedgetable = &edgetables[2]; + else + pedgetable = &edgetables[5]; + + return; + } + else + { + edgetableindex = 1; + } + } + + if (r_p0[1] == r_p2[1]) + { + if (edgetableindex) + pedgetable = &edgetables[8]; + else + pedgetable = &edgetables[9]; + + return; + } + else if (r_p1[1] == r_p2[1]) + { + if (edgetableindex) + pedgetable = &edgetables[10]; + else + pedgetable = &edgetables[11]; + + return; + } + + if (r_p0[1] > r_p2[1]) + edgetableindex += 2; + + if (r_p1[1] > r_p2[1]) + edgetableindex += 4; + + pedgetable = &edgetables[edgetableindex]; +} + + +#if 0 + +void D_PolysetRecursiveDrawLine (int *lp1, int *lp2) +{ + int d; + int new[6]; + int ofs; + + d = lp2[0] - lp1[0]; + if (d < -1 || d > 1) + goto split; + d = lp2[1] - lp1[1]; + if (d < -1 || d > 1) + goto split; + + return; // line is completed + +split: +// split this edge + new[0] = (lp1[0] + lp2[0]) >> 1; + new[1] = (lp1[1] + lp2[1]) >> 1; + new[5] = (lp1[5] + lp2[5]) >> 1; + new[2] = (lp1[2] + lp2[2]) >> 1; + new[3] = (lp1[3] + lp2[3]) >> 1; + new[4] = (lp1[4] + lp2[4]) >> 1; + +// draw the point + ofs = d_scantable[new[1]] + new[0]; + if (new[5] > d_pzbuffer[ofs]) + { + int pix; + + d_pzbuffer[ofs] = new[5]; + pix = skintable[new[3]>>16][new[2]>>16]; +// pix = ((byte *)acolormap)[pix + (new[4] & 0xFF00)]; + d_viewbuffer[ofs] = pix; + } + +// recursively continue + D_PolysetRecursiveDrawLine (lp1, new); + D_PolysetRecursiveDrawLine (new, lp2); +} + +void D_PolysetRecursiveTriangle2 (int *lp1, int *lp2, int *lp3) +{ + int d; + int new[4]; + + d = lp2[0] - lp1[0]; + if (d < -1 || d > 1) + goto split; + d = lp2[1] - lp1[1]; + if (d < -1 || d > 1) + goto split; + return; + +split: +// split this edge + new[0] = (lp1[0] + lp2[0]) >> 1; + new[1] = (lp1[1] + lp2[1]) >> 1; + new[5] = (lp1[5] + lp2[5]) >> 1; + new[2] = (lp1[2] + lp2[2]) >> 1; + new[3] = (lp1[3] + lp2[3]) >> 1; + new[4] = (lp1[4] + lp2[4]) >> 1; + + D_PolysetRecursiveDrawLine (new, lp3); + +// recursively continue + D_PolysetRecursiveTriangle (lp1, new, lp3); + D_PolysetRecursiveTriangle (new, lp2, lp3); +} + +#endif + diff --git a/contrib/other/sdlquake-1.0.9/d_scan.c b/contrib/other/sdlquake-1.0.9/d_scan.c new file mode 100644 index 000000000..008c783be --- /dev/null +++ b/contrib/other/sdlquake-1.0.9/d_scan.c @@ -0,0 +1,449 @@ +/* +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. + +*/ +// d_scan.c +// +// Portable C scan-level rasterization code, all pixel depths. + +#include "quakedef.h" +#include "r_local.h" +#include "d_local.h" + +unsigned char *r_turb_pbase, *r_turb_pdest; +fixed16_t r_turb_s, r_turb_t, r_turb_sstep, r_turb_tstep; +int *r_turb_turb; +int r_turb_spancount; + +void D_DrawTurbulent8Span (void); + + +/* +============= +D_WarpScreen + +// this performs a slight compression of the screen at the same time as +// the sine warp, to keep the edges from wrapping +============= +*/ +void D_WarpScreen (void) +{ + int w, h; + int u,v; + byte *dest; + int *turb; + int *col; + byte **row; + byte *rowptr[MAXHEIGHT+(AMP2*2)]; + int column[MAXWIDTH+(AMP2*2)]; + float wratio, hratio; + + w = r_refdef.vrect.width; + h = r_refdef.vrect.height; + + wratio = w / (float)scr_vrect.width; + hratio = h / (float)scr_vrect.height; + + for (v=0 ; v>16)&(CYCLE-1)])>>16)&63; + tturb = ((r_turb_t + r_turb_turb[(r_turb_s>>16)&(CYCLE-1)])>>16)&63; + *r_turb_pdest++ = *(r_turb_pbase + (tturb<<6) + sturb); + r_turb_s += r_turb_sstep; + r_turb_t += r_turb_tstep; + } while (--r_turb_spancount > 0); +} + +#endif // !id386 + + +/* +============= +Turbulent8 +============= +*/ +void Turbulent8 (espan_t *pspan) +{ + int count; + fixed16_t snext, tnext; + float sdivz, tdivz, zi, z, du, dv, spancountminus1; + float sdivz16stepu, tdivz16stepu, zi16stepu; + + r_turb_turb = sintable + ((int)(cl.time*SPEED)&(CYCLE-1)); + + r_turb_sstep = 0; // keep compiler happy + r_turb_tstep = 0; // ditto + + r_turb_pbase = (unsigned char *)cacheblock; + + sdivz16stepu = d_sdivzstepu * 16; + tdivz16stepu = d_tdivzstepu * 16; + zi16stepu = d_zistepu * 16; + + do + { + r_turb_pdest = (unsigned char *)((byte *)d_viewbuffer + + (screenwidth * pspan->v) + pspan->u); + + count = pspan->count; + + // calculate the initial s/z, t/z, 1/z, s, and t and clamp + du = (float)pspan->u; + dv = (float)pspan->v; + + sdivz = d_sdivzorigin + dv*d_sdivzstepv + du*d_sdivzstepu; + tdivz = d_tdivzorigin + dv*d_tdivzstepv + du*d_tdivzstepu; + zi = d_ziorigin + dv*d_zistepv + du*d_zistepu; + z = (float)0x10000 / zi; // prescale to 16.16 fixed-point + + r_turb_s = (int)(sdivz * z) + sadjust; + if (r_turb_s > bbextents) + r_turb_s = bbextents; + else if (r_turb_s < 0) + r_turb_s = 0; + + r_turb_t = (int)(tdivz * z) + tadjust; + if (r_turb_t > bbextentt) + r_turb_t = bbextentt; + else if (r_turb_t < 0) + r_turb_t = 0; + + do + { + // calculate s and t at the far end of the span + if (count >= 16) + r_turb_spancount = 16; + else + r_turb_spancount = count; + + count -= r_turb_spancount; + + if (count) + { + // calculate s/z, t/z, zi->fixed s and t at far end of span, + // calculate s and t steps across span by shifting + sdivz += sdivz16stepu; + tdivz += tdivz16stepu; + zi += zi16stepu; + z = (float)0x10000 / zi; // prescale to 16.16 fixed-point + + snext = (int)(sdivz * z) + sadjust; + if (snext > bbextents) + snext = bbextents; + else if (snext < 16) + snext = 16; // prevent round-off error on <0 steps from + // from causing overstepping & running off the + // edge of the texture + + tnext = (int)(tdivz * z) + tadjust; + if (tnext > bbextentt) + tnext = bbextentt; + else if (tnext < 16) + tnext = 16; // guard against round-off error on <0 steps + + r_turb_sstep = (snext - r_turb_s) >> 4; + r_turb_tstep = (tnext - r_turb_t) >> 4; + } + else + { + // calculate s/z, t/z, zi->fixed s and t at last pixel in span (so + // can't step off polygon), clamp, calculate s and t steps across + // span by division, biasing steps low so we don't run off the + // texture + spancountminus1 = (float)(r_turb_spancount - 1); + sdivz += d_sdivzstepu * spancountminus1; + tdivz += d_tdivzstepu * spancountminus1; + zi += d_zistepu * spancountminus1; + z = (float)0x10000 / zi; // prescale to 16.16 fixed-point + snext = (int)(sdivz * z) + sadjust; + if (snext > bbextents) + snext = bbextents; + else if (snext < 16) + snext = 16; // prevent round-off error on <0 steps from + // from causing overstepping & running off the + // edge of the texture + + tnext = (int)(tdivz * z) + tadjust; + if (tnext > bbextentt) + tnext = bbextentt; + else if (tnext < 16) + tnext = 16; // guard against round-off error on <0 steps + + if (r_turb_spancount > 1) + { + r_turb_sstep = (snext - r_turb_s) / (r_turb_spancount - 1); + r_turb_tstep = (tnext - r_turb_t) / (r_turb_spancount - 1); + } + } + + r_turb_s = r_turb_s & ((CYCLE<<16)-1); + r_turb_t = r_turb_t & ((CYCLE<<16)-1); + + D_DrawTurbulent8Span (); + + r_turb_s = snext; + r_turb_t = tnext; + + } while (count > 0); + + } while ((pspan = pspan->pnext) != NULL); +} + + +#if !id386 + +/* +============= +D_DrawSpans8 +============= +*/ +void D_DrawSpans8 (espan_t *pspan) +{ + int count, spancount; + unsigned char *pbase, *pdest; + fixed16_t s, t, snext, tnext, sstep, tstep; + float sdivz, tdivz, zi, z, du, dv, spancountminus1; + float sdivz8stepu, tdivz8stepu, zi8stepu; + + sstep = 0; // keep compiler happy + tstep = 0; // ditto + + pbase = (unsigned char *)cacheblock; + + sdivz8stepu = d_sdivzstepu * 8; + tdivz8stepu = d_tdivzstepu * 8; + zi8stepu = d_zistepu * 8; + + do + { + pdest = (unsigned char *)((byte *)d_viewbuffer + + (screenwidth * pspan->v) + pspan->u); + + count = pspan->count; + + // calculate the initial s/z, t/z, 1/z, s, and t and clamp + du = (float)pspan->u; + dv = (float)pspan->v; + + sdivz = d_sdivzorigin + dv*d_sdivzstepv + du*d_sdivzstepu; + tdivz = d_tdivzorigin + dv*d_tdivzstepv + du*d_tdivzstepu; + zi = d_ziorigin + dv*d_zistepv + du*d_zistepu; + z = (float)0x10000 / zi; // prescale to 16.16 fixed-point + + s = (int)(sdivz * z) + sadjust; + if (s > bbextents) + s = bbextents; + else if (s < 0) + s = 0; + + t = (int)(tdivz * z) + tadjust; + if (t > bbextentt) + t = bbextentt; + else if (t < 0) + t = 0; + + do + { + // calculate s and t at the far end of the span + if (count >= 8) + spancount = 8; + else + spancount = count; + + count -= spancount; + + if (count) + { + // calculate s/z, t/z, zi->fixed s and t at far end of span, + // calculate s and t steps across span by shifting + sdivz += sdivz8stepu; + tdivz += tdivz8stepu; + zi += zi8stepu; + z = (float)0x10000 / zi; // prescale to 16.16 fixed-point + + snext = (int)(sdivz * z) + sadjust; + if (snext > bbextents) + snext = bbextents; + else if (snext < 8) + snext = 8; // prevent round-off error on <0 steps from + // from causing overstepping & running off the + // edge of the texture + + tnext = (int)(tdivz * z) + tadjust; + if (tnext > bbextentt) + tnext = bbextentt; + else if (tnext < 8) + tnext = 8; // guard against round-off error on <0 steps + + sstep = (snext - s) >> 3; + tstep = (tnext - t) >> 3; + } + else + { + // calculate s/z, t/z, zi->fixed s and t at last pixel in span (so + // can't step off polygon), clamp, calculate s and t steps across + // span by division, biasing steps low so we don't run off the + // texture + spancountminus1 = (float)(spancount - 1); + sdivz += d_sdivzstepu * spancountminus1; + tdivz += d_tdivzstepu * spancountminus1; + zi += d_zistepu * spancountminus1; + z = (float)0x10000 / zi; // prescale to 16.16 fixed-point + snext = (int)(sdivz * z) + sadjust; + if (snext > bbextents) + snext = bbextents; + else if (snext < 8) + snext = 8; // prevent round-off error on <0 steps from + // from causing overstepping & running off the + // edge of the texture + + tnext = (int)(tdivz * z) + tadjust; + if (tnext > bbextentt) + tnext = bbextentt; + else if (tnext < 8) + tnext = 8; // guard against round-off error on <0 steps + + if (spancount > 1) + { + sstep = (snext - s) / (spancount - 1); + tstep = (tnext - t) / (spancount - 1); + } + } + + do + { + *pdest++ = *(pbase + (s >> 16) + (t >> 16) * cachewidth); + s += sstep; + t += tstep; + } while (--spancount > 0); + + s = snext; + t = tnext; + + } while (count > 0); + + } while ((pspan = pspan->pnext) != NULL); +} + +#endif + + +#if !id386 + +/* +============= +D_DrawZSpans +============= +*/ +void D_DrawZSpans (espan_t *pspan) +{ + int count, doublecount, izistep; + int izi; + short *pdest; + unsigned ltemp; + double zi; + float du, dv; + +// FIXME: check for clamping/range problems +// we count on FP exceptions being turned off to avoid range problems + izistep = (int)(d_zistepu * 0x8000 * 0x10000); + + do + { + pdest = d_pzbuffer + (d_zwidth * pspan->v) + pspan->u; + + count = pspan->count; + + // calculate the initial 1/z + du = (float)pspan->u; + dv = (float)pspan->v; + + zi = d_ziorigin + dv*d_zistepv + du*d_zistepu; + // we count on FP exceptions being turned off to avoid range problems + izi = (int)(zi * 0x8000 * 0x10000); + + if ((long)pdest & 0x02) + { + *pdest++ = (short)(izi >> 16); + izi += izistep; + count--; + } + + if ((doublecount = count >> 1) > 0) + { + do + { + ltemp = izi >> 16; + izi += izistep; + ltemp |= izi & 0xFFFF0000; + izi += izistep; + *(int *)pdest = ltemp; + pdest += 2; + } while (--doublecount > 0); + } + + if (count & 1) + *pdest = (short)(izi >> 16); + + } while ((pspan = pspan->pnext) != NULL); +} + +#endif + diff --git a/contrib/other/sdlquake-1.0.9/d_scana.S b/contrib/other/sdlquake-1.0.9/d_scana.S new file mode 100644 index 000000000..bd4fd7447 --- /dev/null +++ b/contrib/other/sdlquake-1.0.9/d_scana.S @@ -0,0 +1,89 @@ +/* +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. + +*/ +// +// d_scana.s +// x86 assembly-language turbulent texture mapping code +// + +#include "asm_i386.h" +#include "quakeasm.h" +#include "asm_draw.h" +#include "d_ifacea.h" + +#if id386 + + .data + + .text + +//---------------------------------------------------------------------- +// turbulent texture mapping code +//---------------------------------------------------------------------- + + .align 4 +.globl C(D_DrawTurbulent8Span) +C(D_DrawTurbulent8Span): + pushl %ebp // preserve caller's stack frame pointer + pushl %esi // preserve register variables + pushl %edi + pushl %ebx + + movl C(r_turb_s),%esi + movl C(r_turb_t),%ecx + movl C(r_turb_pdest),%edi + movl C(r_turb_spancount),%ebx + +Llp: + movl %ecx,%eax + movl %esi,%edx + sarl $16,%eax + movl C(r_turb_turb),%ebp + sarl $16,%edx + andl $(CYCLE-1),%eax + andl $(CYCLE-1),%edx + movl (%ebp,%eax,4),%eax + movl (%ebp,%edx,4),%edx + addl %esi,%eax + sarl $16,%eax + addl %ecx,%edx + sarl $16,%edx + andl $(TURB_TEX_SIZE-1),%eax + andl $(TURB_TEX_SIZE-1),%edx + shll $6,%edx + movl C(r_turb_pbase),%ebp + addl %eax,%edx + incl %edi + addl C(r_turb_sstep),%esi + addl C(r_turb_tstep),%ecx + movb (%ebp,%edx,1),%dl + decl %ebx + movb %dl,-1(%edi) + jnz Llp + + movl %edi,C(r_turb_pdest) + + popl %ebx // restore register variables + popl %edi + popl %esi + popl %ebp // restore caller's stack frame pointer + ret + +#endif // id386 + diff --git a/contrib/other/sdlquake-1.0.9/d_sky.c b/contrib/other/sdlquake-1.0.9/d_sky.c new file mode 100644 index 000000000..2f77d9361 --- /dev/null +++ b/contrib/other/sdlquake-1.0.9/d_sky.c @@ -0,0 +1,138 @@ +/* +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. + +*/ +// d_sky.c + +#include "quakedef.h" +#include "r_local.h" +#include "d_local.h" + +#define SKY_SPAN_SHIFT 5 +#define SKY_SPAN_MAX (1 << SKY_SPAN_SHIFT) + + +/* +================= +D_Sky_uv_To_st +================= +*/ +void D_Sky_uv_To_st (int u, int v, fixed16_t *s, fixed16_t *t) +{ + float wu, wv, temp; + vec3_t end; + + if (r_refdef.vrect.width >= r_refdef.vrect.height) + temp = (float)r_refdef.vrect.width; + else + temp = (float)r_refdef.vrect.height; + + wu = 8192.0 * (float)(u-((int)vid.width>>1)) / temp; + wv = 8192.0 * (float)(((int)vid.height>>1)-v) / temp; + + end[0] = 4096*vpn[0] + wu*vright[0] + wv*vup[0]; + end[1] = 4096*vpn[1] + wu*vright[1] + wv*vup[1]; + end[2] = 4096*vpn[2] + wu*vright[2] + wv*vup[2]; + end[2] *= 3; + VectorNormalize (end); + + temp = skytime*skyspeed; // TODO: add D_SetupFrame & set this there + *s = (int)((temp + 6*(SKYSIZE/2-1)*end[0]) * 0x10000); + *t = (int)((temp + 6*(SKYSIZE/2-1)*end[1]) * 0x10000); +} + + +/* +================= +D_DrawSkyScans8 +================= +*/ +void D_DrawSkyScans8 (espan_t *pspan) +{ + int count, spancount, u, v; + unsigned char *pdest; + fixed16_t s, t, snext, tnext, sstep, tstep; + int spancountminus1; + + sstep = 0; // keep compiler happy + tstep = 0; // ditto + + do + { + pdest = (unsigned char *)((byte *)d_viewbuffer + + (screenwidth * pspan->v) + pspan->u); + + count = pspan->count; + + // calculate the initial s & t + u = pspan->u; + v = pspan->v; + D_Sky_uv_To_st (u, v, &s, &t); + + do + { + if (count >= SKY_SPAN_MAX) + spancount = SKY_SPAN_MAX; + else + spancount = count; + + count -= spancount; + + if (count) + { + u += spancount; + + // calculate s and t at far end of span, + // calculate s and t steps across span by shifting + D_Sky_uv_To_st (u, v, &snext, &tnext); + + sstep = (snext - s) >> SKY_SPAN_SHIFT; + tstep = (tnext - t) >> SKY_SPAN_SHIFT; + } + else + { + // calculate s and t at last pixel in span, + // calculate s and t steps across span by division + spancountminus1 = (float)(spancount - 1); + + if (spancountminus1 > 0) + { + u += spancountminus1; + D_Sky_uv_To_st (u, v, &snext, &tnext); + + sstep = (snext - s) / spancountminus1; + tstep = (tnext - t) / spancountminus1; + } + } + + do + { + *pdest++ = r_skysource[((t & R_SKY_TMASK) >> 8) + + ((s & R_SKY_SMASK) >> 16)]; + s += sstep; + t += tstep; + } while (--spancount > 0); + + s = snext; + t = tnext; + + } while (count > 0); + + } while ((pspan = pspan->pnext) != NULL); +} + diff --git a/contrib/other/sdlquake-1.0.9/d_spr8.S b/contrib/other/sdlquake-1.0.9/d_spr8.S new file mode 100644 index 000000000..a8d984518 --- /dev/null +++ b/contrib/other/sdlquake-1.0.9/d_spr8.S @@ -0,0 +1,900 @@ +/* +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. + +*/ +// +// d_spr8.s +// x86 assembly-language horizontal 8-bpp transparent span-drawing code. +// + +#include "asm_i386.h" +#include "quakeasm.h" +#include "asm_draw.h" + +#if id386 + +//---------------------------------------------------------------------- +// 8-bpp horizontal span drawing code for polygons, with transparency. +//---------------------------------------------------------------------- + + .text + +// out-of-line, rarely-needed clamping code + +LClampHigh0: + movl C(bbextents),%esi + jmp LClampReentry0 +LClampHighOrLow0: + jg LClampHigh0 + xorl %esi,%esi + jmp LClampReentry0 + +LClampHigh1: + movl C(bbextentt),%edx + jmp LClampReentry1 +LClampHighOrLow1: + jg LClampHigh1 + xorl %edx,%edx + jmp LClampReentry1 + +LClampLow2: + movl $2048,%ebp + jmp LClampReentry2 +LClampHigh2: + movl C(bbextents),%ebp + jmp LClampReentry2 + +LClampLow3: + movl $2048,%ecx + jmp LClampReentry3 +LClampHigh3: + movl C(bbextentt),%ecx + jmp LClampReentry3 + +LClampLow4: + movl $2048,%eax + jmp LClampReentry4 +LClampHigh4: + movl C(bbextents),%eax + jmp LClampReentry4 + +LClampLow5: + movl $2048,%ebx + jmp LClampReentry5 +LClampHigh5: + movl C(bbextentt),%ebx + jmp LClampReentry5 + + +#define pspans 4+16 + + .align 4 +.globl C(D_SpriteDrawSpans) +C(D_SpriteDrawSpans): + pushl %ebp // preserve caller's stack frame + pushl %edi + pushl %esi // preserve register variables + pushl %ebx + +// +// set up scaled-by-8 steps, for 8-long segments; also set up cacheblock +// and span list pointers, and 1/z step in 0.32 fixed-point +// +// FIXME: any overlap from rearranging? + flds C(d_sdivzstepu) + fmuls fp_8 + movl C(cacheblock),%edx + flds C(d_tdivzstepu) + fmuls fp_8 + movl pspans(%esp),%ebx // point to the first span descriptor + flds C(d_zistepu) + fmuls fp_8 + movl %edx,pbase // pbase = cacheblock + flds C(d_zistepu) + fmuls fp_64kx64k + fxch %st(3) + fstps sdivz8stepu + fstps zi8stepu + fstps tdivz8stepu + fistpl izistep + movl izistep,%eax + rorl $16,%eax // put upper 16 bits in low word + movl sspan_t_count(%ebx),%ecx + movl %eax,izistep + + cmpl $0,%ecx + jle LNextSpan + +LSpanLoop: + +// +// set up the initial s/z, t/z, and 1/z on the FP stack, and generate the +// initial s and t values +// +// FIXME: pipeline FILD? + fildl sspan_t_v(%ebx) + fildl sspan_t_u(%ebx) + + fld %st(1) // dv | du | dv + fmuls C(d_sdivzstepv) // dv*d_sdivzstepv | du | dv + fld %st(1) // du | dv*d_sdivzstepv | du | dv + fmuls C(d_sdivzstepu) // du*d_sdivzstepu | dv*d_sdivzstepv | du | dv + fld %st(2) // du | du*d_sdivzstepu | dv*d_sdivzstepv | du | dv + fmuls C(d_tdivzstepu) // du*d_tdivzstepu | du*d_sdivzstepu | + // dv*d_sdivzstepv | du | dv + fxch %st(1) // du*d_sdivzstepu | du*d_tdivzstepu | + // dv*d_sdivzstepv | du | dv + faddp %st(0),%st(2) // du*d_tdivzstepu | + // du*d_sdivzstepu + dv*d_sdivzstepv | du | dv + fxch %st(1) // du*d_sdivzstepu + dv*d_sdivzstepv | + // du*d_tdivzstepu | du | dv + fld %st(3) // dv | du*d_sdivzstepu + dv*d_sdivzstepv | + // du*d_tdivzstepu | du | dv + fmuls C(d_tdivzstepv) // dv*d_tdivzstepv | + // du*d_sdivzstepu + dv*d_sdivzstepv | + // du*d_tdivzstepu | du | dv + fxch %st(1) // du*d_sdivzstepu + dv*d_sdivzstepv | + // dv*d_tdivzstepv | du*d_tdivzstepu | du | dv + fadds C(d_sdivzorigin) // sdivz = d_sdivzorigin + dv*d_sdivzstepv + + // du*d_sdivzstepu; stays in %st(2) at end + fxch %st(4) // dv | dv*d_tdivzstepv | du*d_tdivzstepu | du | + // s/z + fmuls C(d_zistepv) // dv*d_zistepv | dv*d_tdivzstepv | + // du*d_tdivzstepu | du | s/z + fxch %st(1) // dv*d_tdivzstepv | dv*d_zistepv | + // du*d_tdivzstepu | du | s/z + faddp %st(0),%st(2) // dv*d_zistepv | + // dv*d_tdivzstepv + du*d_tdivzstepu | du | s/z + fxch %st(2) // du | dv*d_tdivzstepv + du*d_tdivzstepu | + // dv*d_zistepv | s/z + fmuls C(d_zistepu) // du*d_zistepu | + // dv*d_tdivzstepv + du*d_tdivzstepu | + // dv*d_zistepv | s/z + fxch %st(1) // dv*d_tdivzstepv + du*d_tdivzstepu | + // du*d_zistepu | dv*d_zistepv | s/z + fadds C(d_tdivzorigin) // tdivz = d_tdivzorigin + dv*d_tdivzstepv + + // du*d_tdivzstepu; stays in %st(1) at end + fxch %st(2) // dv*d_zistepv | du*d_zistepu | t/z | s/z + faddp %st(0),%st(1) // dv*d_zistepv + du*d_zistepu | t/z | s/z + + flds fp_64k // fp_64k | dv*d_zistepv + du*d_zistepu | t/z | s/z + fxch %st(1) // dv*d_zistepv + du*d_zistepu | fp_64k | t/z | s/z + fadds C(d_ziorigin) // zi = d_ziorigin + dv*d_zistepv + + // du*d_zistepu; stays in %st(0) at end + // 1/z | fp_64k | t/z | s/z + + fld %st(0) // FIXME: get rid of stall on FMUL? + fmuls fp_64kx64k + fxch %st(1) + +// +// calculate and clamp s & t +// + fdivr %st(0),%st(2) // 1/z | z*64k | t/z | s/z + fxch %st(1) + + fistpl izi // 0.32 fixed-point 1/z + movl izi,%ebp + +// +// set pz to point to the first z-buffer pixel in the span +// + rorl $16,%ebp // put upper 16 bits in low word + movl sspan_t_v(%ebx),%eax + movl %ebp,izi + movl sspan_t_u(%ebx),%ebp + imull C(d_zrowbytes) + shll $1,%ebp // a word per pixel + addl C(d_pzbuffer),%eax + addl %ebp,%eax + movl %eax,pz + +// +// point %edi to the first pixel in the span +// + movl C(d_viewbuffer),%ebp + movl sspan_t_v(%ebx),%eax + pushl %ebx // preserve spans pointer + movl C(tadjust),%edx + movl C(sadjust),%esi + movl C(d_scantable)(,%eax,4),%edi // v * screenwidth + addl %ebp,%edi + movl sspan_t_u(%ebx),%ebp + addl %ebp,%edi // pdest = &pdestspan[scans->u]; + +// +// now start the FDIV for the end of the span +// + cmpl $8,%ecx + ja LSetupNotLast1 + + decl %ecx + jz LCleanup1 // if only one pixel, no need to start an FDIV + movl %ecx,spancountminus1 + +// finish up the s and t calcs + fxch %st(1) // z*64k | 1/z | t/z | s/z + + fld %st(0) // z*64k | z*64k | 1/z | t/z | s/z + fmul %st(4),%st(0) // s | z*64k | 1/z | t/z | s/z + fxch %st(1) // z*64k | s | 1/z | t/z | s/z + fmul %st(3),%st(0) // t | s | 1/z | t/z | s/z + fxch %st(1) // s | t | 1/z | t/z | s/z + fistpl s // 1/z | t | t/z | s/z + fistpl t // 1/z | t/z | s/z + + fildl spancountminus1 + + flds C(d_tdivzstepu) // _d_tdivzstepu | spancountminus1 + flds C(d_zistepu) // _d_zistepu | _d_tdivzstepu | spancountminus1 + fmul %st(2),%st(0) // _d_zistepu*scm1 | _d_tdivzstepu | scm1 + fxch %st(1) // _d_tdivzstepu | _d_zistepu*scm1 | scm1 + fmul %st(2),%st(0) // _d_tdivzstepu*scm1 | _d_zistepu*scm1 | scm1 + fxch %st(2) // scm1 | _d_zistepu*scm1 | _d_tdivzstepu*scm1 + fmuls C(d_sdivzstepu) // _d_sdivzstepu*scm1 | _d_zistepu*scm1 | + // _d_tdivzstepu*scm1 + fxch %st(1) // _d_zistepu*scm1 | _d_sdivzstepu*scm1 | + // _d_tdivzstepu*scm1 + faddp %st(0),%st(3) // _d_sdivzstepu*scm1 | _d_tdivzstepu*scm1 + fxch %st(1) // _d_tdivzstepu*scm1 | _d_sdivzstepu*scm1 + faddp %st(0),%st(3) // _d_sdivzstepu*scm1 + faddp %st(0),%st(3) + + flds fp_64k + fdiv %st(1),%st(0) // this is what we've gone to all this trouble to + // overlap + jmp LFDIVInFlight1 + +LCleanup1: +// finish up the s and t calcs + fxch %st(1) // z*64k | 1/z | t/z | s/z + + fld %st(0) // z*64k | z*64k | 1/z | t/z | s/z + fmul %st(4),%st(0) // s | z*64k | 1/z | t/z | s/z + fxch %st(1) // z*64k | s | 1/z | t/z | s/z + fmul %st(3),%st(0) // t | s | 1/z | t/z | s/z + fxch %st(1) // s | t | 1/z | t/z | s/z + fistpl s // 1/z | t | t/z | s/z + fistpl t // 1/z | t/z | s/z + jmp LFDIVInFlight1 + + .align 4 +LSetupNotLast1: +// finish up the s and t calcs + fxch %st(1) // z*64k | 1/z | t/z | s/z + + fld %st(0) // z*64k | z*64k | 1/z | t/z | s/z + fmul %st(4),%st(0) // s | z*64k | 1/z | t/z | s/z + fxch %st(1) // z*64k | s | 1/z | t/z | s/z + fmul %st(3),%st(0) // t | s | 1/z | t/z | s/z + fxch %st(1) // s | t | 1/z | t/z | s/z + fistpl s // 1/z | t | t/z | s/z + fistpl t // 1/z | t/z | s/z + + fadds zi8stepu + fxch %st(2) + fadds sdivz8stepu + fxch %st(2) + flds tdivz8stepu + faddp %st(0),%st(2) + flds fp_64k + fdiv %st(1),%st(0) // z = 1/1/z + // this is what we've gone to all this trouble to + // overlap +LFDIVInFlight1: + + addl s,%esi + addl t,%edx + movl C(bbextents),%ebx + movl C(bbextentt),%ebp + cmpl %ebx,%esi + ja LClampHighOrLow0 +LClampReentry0: + movl %esi,s + movl pbase,%ebx + shll $16,%esi + cmpl %ebp,%edx + movl %esi,sfracf + ja LClampHighOrLow1 +LClampReentry1: + movl %edx,t + movl s,%esi // sfrac = scans->sfrac; + shll $16,%edx + movl t,%eax // tfrac = scans->tfrac; + sarl $16,%esi + movl %edx,tfracf + +// +// calculate the texture starting address +// + sarl $16,%eax + addl %ebx,%esi + imull C(cachewidth),%eax // (tfrac >> 16) * cachewidth + addl %eax,%esi // psource = pbase + (sfrac >> 16) + + // ((tfrac >> 16) * cachewidth); + +// +// determine whether last span or not +// + cmpl $8,%ecx + jna LLastSegment + +// +// not the last segment; do full 8-wide segment +// +LNotLastSegment: + +// +// advance s/z, t/z, and 1/z, and calculate s & t at end of span and steps to +// get there +// + +// pick up after the FDIV that was left in flight previously + + fld %st(0) // duplicate it + fmul %st(4),%st(0) // s = s/z * z + fxch %st(1) + fmul %st(3),%st(0) // t = t/z * z + fxch %st(1) + fistpl snext + fistpl tnext + movl snext,%eax + movl tnext,%edx + + subl $8,%ecx // count off this segments' pixels + movl C(sadjust),%ebp + pushl %ecx // remember count of remaining pixels + movl C(tadjust),%ecx + + addl %eax,%ebp + addl %edx,%ecx + + movl C(bbextents),%eax + movl C(bbextentt),%edx + + cmpl $2048,%ebp + jl LClampLow2 + cmpl %eax,%ebp + ja LClampHigh2 +LClampReentry2: + + cmpl $2048,%ecx + jl LClampLow3 + cmpl %edx,%ecx + ja LClampHigh3 +LClampReentry3: + + movl %ebp,snext + movl %ecx,tnext + + subl s,%ebp + subl t,%ecx + +// +// set up advancetable +// + movl %ecx,%eax + movl %ebp,%edx + sarl $19,%edx // sstep >>= 16; + movl C(cachewidth),%ebx + sarl $19,%eax // tstep >>= 16; + jz LIsZero + imull %ebx,%eax // (tstep >> 16) * cachewidth; +LIsZero: + addl %edx,%eax // add in sstep + // (tstep >> 16) * cachewidth + (sstep >> 16); + movl tfracf,%edx + movl %eax,advancetable+4 // advance base in t + addl %ebx,%eax // ((tstep >> 16) + 1) * cachewidth + + // (sstep >> 16); + shll $13,%ebp // left-justify sstep fractional part + movl %ebp,sstep + movl sfracf,%ebx + shll $13,%ecx // left-justify tstep fractional part + movl %eax,advancetable // advance extra in t + movl %ecx,tstep + + movl pz,%ecx + movl izi,%ebp + + cmpw (%ecx),%bp + jl Lp1 + movb (%esi),%al // get first source texel + cmpb $(TRANSPARENT_COLOR),%al + jz Lp1 + movw %bp,(%ecx) + movb %al,(%edi) // store first dest pixel +Lp1: + addl izistep,%ebp + adcl $0,%ebp + addl tstep,%edx // advance tfrac fractional part by tstep frac + + sbbl %eax,%eax // turn tstep carry into -1 (0 if none) + addl sstep,%ebx // advance sfrac fractional part by sstep frac + adcl advancetable+4(,%eax,4),%esi // point to next source texel + + cmpw 2(%ecx),%bp + jl Lp2 + movb (%esi),%al + cmpb $(TRANSPARENT_COLOR),%al + jz Lp2 + movw %bp,2(%ecx) + movb %al,1(%edi) +Lp2: + addl izistep,%ebp + adcl $0,%ebp + addl tstep,%edx + sbbl %eax,%eax + addl sstep,%ebx + adcl advancetable+4(,%eax,4),%esi + + cmpw 4(%ecx),%bp + jl Lp3 + movb (%esi),%al + cmpb $(TRANSPARENT_COLOR),%al + jz Lp3 + movw %bp,4(%ecx) + movb %al,2(%edi) +Lp3: + addl izistep,%ebp + adcl $0,%ebp + addl tstep,%edx + sbbl %eax,%eax + addl sstep,%ebx + adcl advancetable+4(,%eax,4),%esi + + cmpw 6(%ecx),%bp + jl Lp4 + movb (%esi),%al + cmpb $(TRANSPARENT_COLOR),%al + jz Lp4 + movw %bp,6(%ecx) + movb %al,3(%edi) +Lp4: + addl izistep,%ebp + adcl $0,%ebp + addl tstep,%edx + sbbl %eax,%eax + addl sstep,%ebx + adcl advancetable+4(,%eax,4),%esi + + cmpw 8(%ecx),%bp + jl Lp5 + movb (%esi),%al + cmpb $(TRANSPARENT_COLOR),%al + jz Lp5 + movw %bp,8(%ecx) + movb %al,4(%edi) +Lp5: + addl izistep,%ebp + adcl $0,%ebp + addl tstep,%edx + sbbl %eax,%eax + addl sstep,%ebx + adcl advancetable+4(,%eax,4),%esi + +// +// start FDIV for end of next segment in flight, so it can overlap +// + popl %eax + cmpl $8,%eax // more than one segment after this? + ja LSetupNotLast2 // yes + + decl %eax + jz LFDIVInFlight2 // if only one pixel, no need to start an FDIV + movl %eax,spancountminus1 + fildl spancountminus1 + + flds C(d_zistepu) // _d_zistepu | spancountminus1 + fmul %st(1),%st(0) // _d_zistepu*scm1 | scm1 + flds C(d_tdivzstepu) // _d_tdivzstepu | _d_zistepu*scm1 | scm1 + fmul %st(2),%st(0) // _d_tdivzstepu*scm1 | _d_zistepu*scm1 | scm1 + fxch %st(1) // _d_zistepu*scm1 | _d_tdivzstepu*scm1 | scm1 + faddp %st(0),%st(3) // _d_tdivzstepu*scm1 | scm1 + fxch %st(1) // scm1 | _d_tdivzstepu*scm1 + fmuls C(d_sdivzstepu) // _d_sdivzstepu*scm1 | _d_tdivzstepu*scm1 + fxch %st(1) // _d_tdivzstepu*scm1 | _d_sdivzstepu*scm1 + faddp %st(0),%st(3) // _d_sdivzstepu*scm1 + flds fp_64k // 64k | _d_sdivzstepu*scm1 + fxch %st(1) // _d_sdivzstepu*scm1 | 64k + faddp %st(0),%st(4) // 64k + + fdiv %st(1),%st(0) // this is what we've gone to all this trouble to + // overlap + jmp LFDIVInFlight2 + + .align 4 +LSetupNotLast2: + fadds zi8stepu + fxch %st(2) + fadds sdivz8stepu + fxch %st(2) + flds tdivz8stepu + faddp %st(0),%st(2) + flds fp_64k + fdiv %st(1),%st(0) // z = 1/1/z + // this is what we've gone to all this trouble to + // overlap +LFDIVInFlight2: + pushl %eax + + cmpw 10(%ecx),%bp + jl Lp6 + movb (%esi),%al + cmpb $(TRANSPARENT_COLOR),%al + jz Lp6 + movw %bp,10(%ecx) + movb %al,5(%edi) +Lp6: + addl izistep,%ebp + adcl $0,%ebp + addl tstep,%edx + sbbl %eax,%eax + addl sstep,%ebx + adcl advancetable+4(,%eax,4),%esi + + cmpw 12(%ecx),%bp + jl Lp7 + movb (%esi),%al + cmpb $(TRANSPARENT_COLOR),%al + jz Lp7 + movw %bp,12(%ecx) + movb %al,6(%edi) +Lp7: + addl izistep,%ebp + adcl $0,%ebp + addl tstep,%edx + sbbl %eax,%eax + addl sstep,%ebx + adcl advancetable+4(,%eax,4),%esi + + cmpw 14(%ecx),%bp + jl Lp8 + movb (%esi),%al + cmpb $(TRANSPARENT_COLOR),%al + jz Lp8 + movw %bp,14(%ecx) + movb %al,7(%edi) +Lp8: + addl izistep,%ebp + adcl $0,%ebp + addl tstep,%edx + sbbl %eax,%eax + addl sstep,%ebx + adcl advancetable+4(,%eax,4),%esi + + addl $8,%edi + addl $16,%ecx + movl %edx,tfracf + movl snext,%edx + movl %ebx,sfracf + movl tnext,%ebx + movl %edx,s + movl %ebx,t + + movl %ecx,pz + movl %ebp,izi + + popl %ecx // retrieve count + +// +// determine whether last span or not +// + cmpl $8,%ecx // are there multiple segments remaining? + ja LNotLastSegment // yes + +// +// last segment of scan +// +LLastSegment: + +// +// advance s/z, t/z, and 1/z, and calculate s & t at end of span and steps to +// get there. The number of pixels left is variable, and we want to land on the +// last pixel, not step one past it, so we can't run into arithmetic problems +// + testl %ecx,%ecx + jz LNoSteps // just draw the last pixel and we're done + +// pick up after the FDIV that was left in flight previously + + + fld %st(0) // duplicate it + fmul %st(4),%st(0) // s = s/z * z + fxch %st(1) + fmul %st(3),%st(0) // t = t/z * z + fxch %st(1) + fistpl snext + fistpl tnext + + movl C(tadjust),%ebx + movl C(sadjust),%eax + + addl snext,%eax + addl tnext,%ebx + + movl C(bbextents),%ebp + movl C(bbextentt),%edx + + cmpl $2048,%eax + jl LClampLow4 + cmpl %ebp,%eax + ja LClampHigh4 +LClampReentry4: + movl %eax,snext + + cmpl $2048,%ebx + jl LClampLow5 + cmpl %edx,%ebx + ja LClampHigh5 +LClampReentry5: + + cmpl $1,%ecx // don't bother + je LOnlyOneStep // if two pixels in segment, there's only one step, + // of the segment length + subl s,%eax + subl t,%ebx + + addl %eax,%eax // convert to 15.17 format so multiply by 1.31 + addl %ebx,%ebx // reciprocal yields 16.48 + imull reciprocal_table-8(,%ecx,4) // sstep = (snext - s) / (spancount-1) + movl %edx,%ebp + + movl %ebx,%eax + imull reciprocal_table-8(,%ecx,4) // tstep = (tnext - t) / (spancount-1) + +LSetEntryvec: +// +// set up advancetable +// + movl spr8entryvec_table(,%ecx,4),%ebx + movl %edx,%eax + pushl %ebx // entry point into code for RET later + movl %ebp,%ecx + sarl $16,%ecx // sstep >>= 16; + movl C(cachewidth),%ebx + sarl $16,%edx // tstep >>= 16; + jz LIsZeroLast + imull %ebx,%edx // (tstep >> 16) * cachewidth; +LIsZeroLast: + addl %ecx,%edx // add in sstep + // (tstep >> 16) * cachewidth + (sstep >> 16); + movl tfracf,%ecx + movl %edx,advancetable+4 // advance base in t + addl %ebx,%edx // ((tstep >> 16) + 1) * cachewidth + + // (sstep >> 16); + shll $16,%ebp // left-justify sstep fractional part + movl sfracf,%ebx + shll $16,%eax // left-justify tstep fractional part + movl %edx,advancetable // advance extra in t + + movl %eax,tstep + movl %ebp,sstep + movl %ecx,%edx + + movl pz,%ecx + movl izi,%ebp + + ret // jump to the number-of-pixels handler + +//---------------------------------------- + +LNoSteps: + movl pz,%ecx + subl $7,%edi // adjust for hardwired offset + subl $14,%ecx + jmp LEndSpan + + +LOnlyOneStep: + subl s,%eax + subl t,%ebx + movl %eax,%ebp + movl %ebx,%edx + jmp LSetEntryvec + +//---------------------------------------- + +.globl Spr8Entry2_8 +Spr8Entry2_8: + subl $6,%edi // adjust for hardwired offsets + subl $12,%ecx + movb (%esi),%al + jmp LLEntry2_8 + +//---------------------------------------- + +.globl Spr8Entry3_8 +Spr8Entry3_8: + subl $5,%edi // adjust for hardwired offsets + subl $10,%ecx + jmp LLEntry3_8 + +//---------------------------------------- + +.globl Spr8Entry4_8 +Spr8Entry4_8: + subl $4,%edi // adjust for hardwired offsets + subl $8,%ecx + jmp LLEntry4_8 + +//---------------------------------------- + +.globl Spr8Entry5_8 +Spr8Entry5_8: + subl $3,%edi // adjust for hardwired offsets + subl $6,%ecx + jmp LLEntry5_8 + +//---------------------------------------- + +.globl Spr8Entry6_8 +Spr8Entry6_8: + subl $2,%edi // adjust for hardwired offsets + subl $4,%ecx + jmp LLEntry6_8 + +//---------------------------------------- + +.globl Spr8Entry7_8 +Spr8Entry7_8: + decl %edi // adjust for hardwired offsets + subl $2,%ecx + jmp LLEntry7_8 + +//---------------------------------------- + +.globl Spr8Entry8_8 +Spr8Entry8_8: + cmpw (%ecx),%bp + jl Lp9 + movb (%esi),%al + cmpb $(TRANSPARENT_COLOR),%al + jz Lp9 + movw %bp,(%ecx) + movb %al,(%edi) +Lp9: + addl izistep,%ebp + adcl $0,%ebp + addl tstep,%edx + sbbl %eax,%eax + addl sstep,%ebx + adcl advancetable+4(,%eax,4),%esi +LLEntry7_8: + cmpw 2(%ecx),%bp + jl Lp10 + movb (%esi),%al + cmpb $(TRANSPARENT_COLOR),%al + jz Lp10 + movw %bp,2(%ecx) + movb %al,1(%edi) +Lp10: + addl izistep,%ebp + adcl $0,%ebp + addl tstep,%edx + sbbl %eax,%eax + addl sstep,%ebx + adcl advancetable+4(,%eax,4),%esi +LLEntry6_8: + cmpw 4(%ecx),%bp + jl Lp11 + movb (%esi),%al + cmpb $(TRANSPARENT_COLOR),%al + jz Lp11 + movw %bp,4(%ecx) + movb %al,2(%edi) +Lp11: + addl izistep,%ebp + adcl $0,%ebp + addl tstep,%edx + sbbl %eax,%eax + addl sstep,%ebx + adcl advancetable+4(,%eax,4),%esi +LLEntry5_8: + cmpw 6(%ecx),%bp + jl Lp12 + movb (%esi),%al + cmpb $(TRANSPARENT_COLOR),%al + jz Lp12 + movw %bp,6(%ecx) + movb %al,3(%edi) +Lp12: + addl izistep,%ebp + adcl $0,%ebp + addl tstep,%edx + sbbl %eax,%eax + addl sstep,%ebx + adcl advancetable+4(,%eax,4),%esi +LLEntry4_8: + cmpw 8(%ecx),%bp + jl Lp13 + movb (%esi),%al + cmpb $(TRANSPARENT_COLOR),%al + jz Lp13 + movw %bp,8(%ecx) + movb %al,4(%edi) +Lp13: + addl izistep,%ebp + adcl $0,%ebp + addl tstep,%edx + sbbl %eax,%eax + addl sstep,%ebx + adcl advancetable+4(,%eax,4),%esi +LLEntry3_8: + cmpw 10(%ecx),%bp + jl Lp14 + movb (%esi),%al + cmpb $(TRANSPARENT_COLOR),%al + jz Lp14 + movw %bp,10(%ecx) + movb %al,5(%edi) +Lp14: + addl izistep,%ebp + adcl $0,%ebp + addl tstep,%edx + sbbl %eax,%eax + addl sstep,%ebx + adcl advancetable+4(,%eax,4),%esi +LLEntry2_8: + cmpw 12(%ecx),%bp + jl Lp15 + movb (%esi),%al + cmpb $(TRANSPARENT_COLOR),%al + jz Lp15 + movw %bp,12(%ecx) + movb %al,6(%edi) +Lp15: + addl izistep,%ebp + adcl $0,%ebp + addl tstep,%edx + sbbl %eax,%eax + addl sstep,%ebx + adcl advancetable+4(,%eax,4),%esi + +LEndSpan: + cmpw 14(%ecx),%bp + jl Lp16 + movb (%esi),%al // load first texel in segment + cmpb $(TRANSPARENT_COLOR),%al + jz Lp16 + movw %bp,14(%ecx) + movb %al,7(%edi) +Lp16: + +// +// clear s/z, t/z, 1/z from FP stack +// + fstp %st(0) + fstp %st(0) + fstp %st(0) + + popl %ebx // restore spans pointer +LNextSpan: + addl $(sspan_t_size),%ebx // point to next span + movl sspan_t_count(%ebx),%ecx + cmpl $0,%ecx // any more spans? + jg LSpanLoop // yes + jz LNextSpan // yes, but this one's empty + + popl %ebx // restore register variables + popl %esi + popl %edi + popl %ebp // restore the caller's stack frame + ret + +#endif // id386 diff --git a/contrib/other/sdlquake-1.0.9/d_sprite.c b/contrib/other/sdlquake-1.0.9/d_sprite.c new file mode 100644 index 000000000..2f02ad2c6 --- /dev/null +++ b/contrib/other/sdlquake-1.0.9/d_sprite.c @@ -0,0 +1,442 @@ +/* +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. + +*/ +// d_sprite.c: software top-level rasterization driver module for drawing +// sprites + +#include "quakedef.h" +#include "d_local.h" + +static int sprite_height; +static int minindex, maxindex; +static sspan_t *sprite_spans; + +#if !id386 + +/* +===================== +D_SpriteDrawSpans +===================== +*/ +void D_SpriteDrawSpans (sspan_t *pspan) +{ + int count, spancount, izistep; + int izi; + byte *pbase, *pdest; + fixed16_t s, t, snext, tnext, sstep, tstep; + float sdivz, tdivz, zi, z, du, dv, spancountminus1; + float sdivz8stepu, tdivz8stepu, zi8stepu; + byte btemp; + short *pz; + + sstep = 0; // keep compiler happy + tstep = 0; // ditto + + pbase = cacheblock; + + sdivz8stepu = d_sdivzstepu * 8; + tdivz8stepu = d_tdivzstepu * 8; + zi8stepu = d_zistepu * 8; + +// we count on FP exceptions being turned off to avoid range problems + izistep = (int)(d_zistepu * 0x8000 * 0x10000); + + do + { + pdest = (byte *)d_viewbuffer + (screenwidth * pspan->v) + pspan->u; + pz = d_pzbuffer + (d_zwidth * pspan->v) + pspan->u; + + count = pspan->count; + + if (count <= 0) + goto NextSpan; + + // calculate the initial s/z, t/z, 1/z, s, and t and clamp + du = (float)pspan->u; + dv = (float)pspan->v; + + sdivz = d_sdivzorigin + dv*d_sdivzstepv + du*d_sdivzstepu; + tdivz = d_tdivzorigin + dv*d_tdivzstepv + du*d_tdivzstepu; + zi = d_ziorigin + dv*d_zistepv + du*d_zistepu; + z = (float)0x10000 / zi; // prescale to 16.16 fixed-point + // we count on FP exceptions being turned off to avoid range problems + izi = (int)(zi * 0x8000 * 0x10000); + + s = (int)(sdivz * z) + sadjust; + if (s > bbextents) + s = bbextents; + else if (s < 0) + s = 0; + + t = (int)(tdivz * z) + tadjust; + if (t > bbextentt) + t = bbextentt; + else if (t < 0) + t = 0; + + do + { + // calculate s and t at the far end of the span + if (count >= 8) + spancount = 8; + else + spancount = count; + + count -= spancount; + + if (count) + { + // calculate s/z, t/z, zi->fixed s and t at far end of span, + // calculate s and t steps across span by shifting + sdivz += sdivz8stepu; + tdivz += tdivz8stepu; + zi += zi8stepu; + z = (float)0x10000 / zi; // prescale to 16.16 fixed-point + + snext = (int)(sdivz * z) + sadjust; + if (snext > bbextents) + snext = bbextents; + else if (snext < 8) + snext = 8; // prevent round-off error on <0 steps from + // from causing overstepping & running off the + // edge of the texture + + tnext = (int)(tdivz * z) + tadjust; + if (tnext > bbextentt) + tnext = bbextentt; + else if (tnext < 8) + tnext = 8; // guard against round-off error on <0 steps + + sstep = (snext - s) >> 3; + tstep = (tnext - t) >> 3; + } + else + { + // calculate s/z, t/z, zi->fixed s and t at last pixel in span (so + // can't step off polygon), clamp, calculate s and t steps across + // span by division, biasing steps low so we don't run off the + // texture + spancountminus1 = (float)(spancount - 1); + sdivz += d_sdivzstepu * spancountminus1; + tdivz += d_tdivzstepu * spancountminus1; + zi += d_zistepu * spancountminus1; + z = (float)0x10000 / zi; // prescale to 16.16 fixed-point + snext = (int)(sdivz * z) + sadjust; + if (snext > bbextents) + snext = bbextents; + else if (snext < 8) + snext = 8; // prevent round-off error on <0 steps from + // from causing overstepping & running off the + // edge of the texture + + tnext = (int)(tdivz * z) + tadjust; + if (tnext > bbextentt) + tnext = bbextentt; + else if (tnext < 8) + tnext = 8; // guard against round-off error on <0 steps + + if (spancount > 1) + { + sstep = (snext - s) / (spancount - 1); + tstep = (tnext - t) / (spancount - 1); + } + } + + do + { + btemp = *(pbase + (s >> 16) + (t >> 16) * cachewidth); + if (btemp != 255) + { + if (*pz <= (izi >> 16)) + { + *pz = izi >> 16; + *pdest = btemp; + } + } + + izi += izistep; + pdest++; + pz++; + s += sstep; + t += tstep; + } while (--spancount > 0); + + s = snext; + t = tnext; + + } while (count > 0); + +NextSpan: + pspan++; + + } while (pspan->count != DS_SPAN_LIST_END); +} + +#endif + + +/* +===================== +D_SpriteScanLeftEdge +===================== +*/ +void D_SpriteScanLeftEdge (void) +{ + int i, v, itop, ibottom, lmaxindex; + emitpoint_t *pvert, *pnext; + sspan_t *pspan; + float du, dv, vtop, vbottom, slope; + fixed16_t u, u_step; + + pspan = sprite_spans; + i = minindex; + if (i == 0) + i = r_spritedesc.nump; + + lmaxindex = maxindex; + if (lmaxindex == 0) + lmaxindex = r_spritedesc.nump; + + vtop = ceil (r_spritedesc.pverts[i].v); + + do + { + pvert = &r_spritedesc.pverts[i]; + pnext = pvert - 1; + + vbottom = ceil (pnext->v); + + if (vtop < vbottom) + { + du = pnext->u - pvert->u; + dv = pnext->v - pvert->v; + slope = du / dv; + u_step = (int)(slope * 0x10000); + // adjust u to ceil the integer portion + u = (int)((pvert->u + (slope * (vtop - pvert->v))) * 0x10000) + + (0x10000 - 1); + itop = (int)vtop; + ibottom = (int)vbottom; + + for (v=itop ; vu = u >> 16; + pspan->v = v; + u += u_step; + pspan++; + } + } + + vtop = vbottom; + + i--; + if (i == 0) + i = r_spritedesc.nump; + + } while (i != lmaxindex); +} + + +/* +===================== +D_SpriteScanRightEdge +===================== +*/ +void D_SpriteScanRightEdge (void) +{ + int i, v, itop, ibottom; + emitpoint_t *pvert, *pnext; + sspan_t *pspan; + float du, dv, vtop, vbottom, slope, uvert, unext, vvert, vnext; + fixed16_t u, u_step; + + pspan = sprite_spans; + i = minindex; + + vvert = r_spritedesc.pverts[i].v; + if (vvert < r_refdef.fvrecty_adj) + vvert = r_refdef.fvrecty_adj; + if (vvert > r_refdef.fvrectbottom_adj) + vvert = r_refdef.fvrectbottom_adj; + + vtop = ceil (vvert); + + do + { + pvert = &r_spritedesc.pverts[i]; + pnext = pvert + 1; + + vnext = pnext->v; + if (vnext < r_refdef.fvrecty_adj) + vnext = r_refdef.fvrecty_adj; + if (vnext > r_refdef.fvrectbottom_adj) + vnext = r_refdef.fvrectbottom_adj; + + vbottom = ceil (vnext); + + if (vtop < vbottom) + { + uvert = pvert->u; + if (uvert < r_refdef.fvrectx_adj) + uvert = r_refdef.fvrectx_adj; + if (uvert > r_refdef.fvrectright_adj) + uvert = r_refdef.fvrectright_adj; + + unext = pnext->u; + if (unext < r_refdef.fvrectx_adj) + unext = r_refdef.fvrectx_adj; + if (unext > r_refdef.fvrectright_adj) + unext = r_refdef.fvrectright_adj; + + du = unext - uvert; + dv = vnext - vvert; + slope = du / dv; + u_step = (int)(slope * 0x10000); + // adjust u to ceil the integer portion + u = (int)((uvert + (slope * (vtop - vvert))) * 0x10000) + + (0x10000 - 1); + itop = (int)vtop; + ibottom = (int)vbottom; + + for (v=itop ; vcount = (u >> 16) - pspan->u; + u += u_step; + pspan++; + } + } + + vtop = vbottom; + vvert = vnext; + + i++; + if (i == r_spritedesc.nump) + i = 0; + + } while (i != maxindex); + + pspan->count = DS_SPAN_LIST_END; // mark the end of the span list +} + + +/* +===================== +D_SpriteCalculateGradients +===================== +*/ +void D_SpriteCalculateGradients (void) +{ + vec3_t p_normal, p_saxis, p_taxis, p_temp1; + float distinv; + + TransformVector (r_spritedesc.vpn, p_normal); + TransformVector (r_spritedesc.vright, p_saxis); + TransformVector (r_spritedesc.vup, p_taxis); + VectorInverse (p_taxis); + + distinv = 1.0 / (-DotProduct (modelorg, r_spritedesc.vpn)); + + d_sdivzstepu = p_saxis[0] * xscaleinv; + d_tdivzstepu = p_taxis[0] * xscaleinv; + + d_sdivzstepv = -p_saxis[1] * yscaleinv; + d_tdivzstepv = -p_taxis[1] * yscaleinv; + + d_zistepu = p_normal[0] * xscaleinv * distinv; + d_zistepv = -p_normal[1] * yscaleinv * distinv; + + d_sdivzorigin = p_saxis[2] - xcenter * d_sdivzstepu - + ycenter * d_sdivzstepv; + d_tdivzorigin = p_taxis[2] - xcenter * d_tdivzstepu - + ycenter * d_tdivzstepv; + d_ziorigin = p_normal[2] * distinv - xcenter * d_zistepu - + ycenter * d_zistepv; + + TransformVector (modelorg, p_temp1); + + sadjust = ((fixed16_t)(DotProduct (p_temp1, p_saxis) * 0x10000 + 0.5)) - + (-(cachewidth >> 1) << 16); + tadjust = ((fixed16_t)(DotProduct (p_temp1, p_taxis) * 0x10000 + 0.5)) - + (-(sprite_height >> 1) << 16); + +// -1 (-epsilon) so we never wander off the edge of the texture + bbextents = (cachewidth << 16) - 1; + bbextentt = (sprite_height << 16) - 1; +} + + +/* +===================== +D_DrawSprite +===================== +*/ +void D_DrawSprite (void) +{ + int i, nump; + float ymin, ymax; + emitpoint_t *pverts; + sspan_t spans[MAXHEIGHT+1]; + + sprite_spans = spans; + +// find the top and bottom vertices, and make sure there's at least one scan to +// draw + ymin = 999999.9; + ymax = -999999.9; + pverts = r_spritedesc.pverts; + + for (i=0 ; iv < ymin) + { + ymin = pverts->v; + minindex = i; + } + + if (pverts->v > ymax) + { + ymax = pverts->v; + maxindex = i; + } + + pverts++; + } + + ymin = ceil (ymin); + ymax = ceil (ymax); + + if (ymin >= ymax) + return; // doesn't cross any scans at all + + cachewidth = r_spritedesc.pspriteframe->width; + sprite_height = r_spritedesc.pspriteframe->height; + cacheblock = (byte *)&r_spritedesc.pspriteframe->pixels[0]; + +// copy the first vertex to the last vertex, so we don't have to deal with +// wrapping + nump = r_spritedesc.nump; + pverts = r_spritedesc.pverts; + pverts[nump] = pverts[0]; + + D_SpriteCalculateGradients (); + D_SpriteScanLeftEdge (); + D_SpriteScanRightEdge (); + D_SpriteDrawSpans (sprite_spans); +} + diff --git a/contrib/other/sdlquake-1.0.9/d_surf.c b/contrib/other/sdlquake-1.0.9/d_surf.c new file mode 100644 index 000000000..b09c5f896 --- /dev/null +++ b/contrib/other/sdlquake-1.0.9/d_surf.c @@ -0,0 +1,335 @@ +/* +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. + +*/ +// d_surf.c: rasterization driver surface heap manager + +#include "quakedef.h" +#include "d_local.h" +#include "r_local.h" + +float surfscale; +qboolean r_cache_thrash; // set if surface cache is thrashing + +int sc_size; +surfcache_t *sc_rover, *sc_base; + +#define GUARDSIZE 4 + + +int D_SurfaceCacheForRes (int width, int height) +{ + int size, pix; + + if (COM_CheckParm ("-surfcachesize")) + { + size = Q_atoi(com_argv[COM_CheckParm("-surfcachesize")+1]) * 1024; + return size; + } + + size = SURFCACHE_SIZE_AT_320X200; + + pix = width*height; + if (pix > 64000) + size += (pix-64000)*3; + + + return size; +} + +void D_CheckCacheGuard (void) +{ + byte *s; + int i; + + s = (byte *)sc_base + sc_size; + for (i=0 ; inext = NULL; + sc_base->owner = NULL; + sc_base->size = sc_size; + + D_ClearCacheGuard (); +} + + +/* +================== +D_FlushCaches +================== +*/ +void D_FlushCaches (void) +{ + surfcache_t *c; + + if (!sc_base) + return; + + for (c = sc_base ; c ; c = c->next) + { + if (c->owner) + *c->owner = NULL; + } + + sc_rover = sc_base; + sc_base->next = NULL; + sc_base->owner = NULL; + sc_base->size = sc_size; +} + +/* +================= +D_SCAlloc +================= +*/ +surfcache_t *D_SCAlloc (int width, int size) +{ + surfcache_t *new; + qboolean wrapped_this_time; + + if ((width < 0) || (width > 256)) + Sys_Error ("D_SCAlloc: bad cache width %d\n", width); + + if ((size <= 0) || (size > 0x10000)) + Sys_Error ("D_SCAlloc: bad cache size %d\n", size); + + size = (int)&((surfcache_t *)0)->data[size]; + size = (size + 3) & ~3; + if (size > sc_size) + Sys_Error ("D_SCAlloc: %i > cache size",size); + +// if there is not size bytes after the rover, reset to the start + wrapped_this_time = false; + + if ( !sc_rover || (byte *)sc_rover - (byte *)sc_base > sc_size - size) + { + if (sc_rover) + { + wrapped_this_time = true; + } + sc_rover = sc_base; + } + +// colect and free surfcache_t blocks until the rover block is large enough + new = sc_rover; + if (sc_rover->owner) + *sc_rover->owner = NULL; + + while (new->size < size) + { + // free another + sc_rover = sc_rover->next; + if (!sc_rover) + Sys_Error ("D_SCAlloc: hit the end of memory"); + if (sc_rover->owner) + *sc_rover->owner = NULL; + + new->size += sc_rover->size; + new->next = sc_rover->next; + } + +// create a fragment out of any leftovers + if (new->size - size > 256) + { + sc_rover = (surfcache_t *)( (byte *)new + size); + sc_rover->size = new->size - size; + sc_rover->next = new->next; + sc_rover->width = 0; + sc_rover->owner = NULL; + new->next = sc_rover; + new->size = size; + } + else + sc_rover = new->next; + + new->width = width; +// DEBUG + if (width > 0) + new->height = (size - sizeof(*new) + sizeof(new->data)) / width; + + new->owner = NULL; // should be set properly after return + + if (d_roverwrapped) + { + if (wrapped_this_time || (sc_rover >= d_initial_rover)) + r_cache_thrash = true; + } + else if (wrapped_this_time) + { + d_roverwrapped = true; + } + +D_CheckCacheGuard (); // DEBUG + return new; +} + + +/* +================= +D_SCDump +================= +*/ +void D_SCDump (void) +{ + surfcache_t *test; + + for (test = sc_base ; test ; test = test->next) + { + if (test == sc_rover) + Sys_Printf ("ROVER:\n"); + printf ("%p : %i bytes %i width\n",test, test->size, test->width); + } +} + +//============================================================================= + +// if the num is not a power of 2, assume it will not repeat + +int MaskForNum (int num) +{ + if (num==128) + return 127; + if (num==64) + return 63; + if (num==32) + return 31; + if (num==16) + return 15; + return 255; +} + +int D_log2 (int num) +{ + int c; + + c = 0; + + while (num>>=1) + c++; + return c; +} + +//============================================================================= + +/* +================ +D_CacheSurface +================ +*/ +surfcache_t *D_CacheSurface (msurface_t *surface, int miplevel) +{ + surfcache_t *cache; + +// +// if the surface is animating or flashing, flush the cache +// + r_drawsurf.texture = R_TextureAnimation (surface->texinfo->texture); + r_drawsurf.lightadj[0] = d_lightstylevalue[surface->styles[0]]; + r_drawsurf.lightadj[1] = d_lightstylevalue[surface->styles[1]]; + r_drawsurf.lightadj[2] = d_lightstylevalue[surface->styles[2]]; + r_drawsurf.lightadj[3] = d_lightstylevalue[surface->styles[3]]; + +// +// see if the cache holds apropriate data +// + cache = surface->cachespots[miplevel]; + + if (cache && !cache->dlight && surface->dlightframe != r_framecount + && cache->texture == r_drawsurf.texture + && cache->lightadj[0] == r_drawsurf.lightadj[0] + && cache->lightadj[1] == r_drawsurf.lightadj[1] + && cache->lightadj[2] == r_drawsurf.lightadj[2] + && cache->lightadj[3] == r_drawsurf.lightadj[3] ) + return cache; + +// +// determine shape of surface +// + surfscale = 1.0 / (1<extents[0] >> miplevel; + r_drawsurf.rowbytes = r_drawsurf.surfwidth; + r_drawsurf.surfheight = surface->extents[1] >> miplevel; + +// +// allocate memory if needed +// + if (!cache) // if a texture just animated, don't reallocate it + { + cache = D_SCAlloc (r_drawsurf.surfwidth, + r_drawsurf.surfwidth * r_drawsurf.surfheight); + surface->cachespots[miplevel] = cache; + cache->owner = &surface->cachespots[miplevel]; + cache->mipscale = surfscale; + } + + if (surface->dlightframe == r_framecount) + cache->dlight = 1; + else + cache->dlight = 0; + + r_drawsurf.surfdat = (pixel_t *)cache->data; + + cache->texture = r_drawsurf.texture; + cache->lightadj[0] = r_drawsurf.lightadj[0]; + cache->lightadj[1] = r_drawsurf.lightadj[1]; + cache->lightadj[2] = r_drawsurf.lightadj[2]; + cache->lightadj[3] = r_drawsurf.lightadj[3]; + +// +// draw and light the surface texture +// + r_drawsurf.surf = surface; + + c_surf++; + R_DrawSurface (); + + return surface->cachespots[miplevel]; +} + + diff --git a/contrib/other/sdlquake-1.0.9/d_vars.c b/contrib/other/sdlquake-1.0.9/d_vars.c new file mode 100644 index 000000000..88cc841ab --- /dev/null +++ b/contrib/other/sdlquake-1.0.9/d_vars.c @@ -0,0 +1,50 @@ +/* +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_vars.c: global refresh variables + +#include "quakedef.h" + +#if !id386 + +// all global and static refresh variables are collected in a contiguous block +// to avoid cache conflicts. + +//------------------------------------------------------- +// global refresh variables +//------------------------------------------------------- + +// FIXME: make into one big structure, like cl or sv +// FIXME: do separately for refresh engine and driver + +float d_sdivzstepu, d_tdivzstepu, d_zistepu; +float d_sdivzstepv, d_tdivzstepv, d_zistepv; +float d_sdivzorigin, d_tdivzorigin, d_ziorigin; + +fixed16_t sadjust, tadjust, bbextents, bbextentt; + +pixel_t *cacheblock; +int cachewidth; +pixel_t *d_viewbuffer; +short *d_pzbuffer; +unsigned int d_zrowbytes; +unsigned int d_zwidth; + +#endif // !id386 + diff --git a/contrib/other/sdlquake-1.0.9/d_varsa.S b/contrib/other/sdlquake-1.0.9/d_varsa.S new file mode 100644 index 000000000..537c6b42c --- /dev/null +++ b/contrib/other/sdlquake-1.0.9/d_varsa.S @@ -0,0 +1,213 @@ +/* +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. + +*/ +// +// d_varsa.s +// + +#include "asm_i386.h" +#include "quakeasm.h" +#include "asm_draw.h" +#include "d_ifacea.h" + +#if id386 + + .data + +//------------------------------------------------------- +// global refresh variables +//------------------------------------------------------- + +// FIXME: put all refresh variables into one contiguous block. Make into one +// big structure, like cl or sv? + + .align 4 +.globl C(d_sdivzstepu) +.globl C(d_tdivzstepu) +.globl C(d_zistepu) +.globl C(d_sdivzstepv) +.globl C(d_tdivzstepv) +.globl C(d_zistepv) +.globl C(d_sdivzorigin) +.globl C(d_tdivzorigin) +.globl C(d_ziorigin) +C(d_sdivzstepu): .single 0 +C(d_tdivzstepu): .single 0 +C(d_zistepu): .single 0 +C(d_sdivzstepv): .single 0 +C(d_tdivzstepv): .single 0 +C(d_zistepv): .single 0 +C(d_sdivzorigin): .single 0 +C(d_tdivzorigin): .single 0 +C(d_ziorigin): .single 0 + +.globl C(sadjust) +.globl C(tadjust) +.globl C(bbextents) +.globl C(bbextentt) +C(sadjust): .long 0 +C(tadjust): .long 0 +C(bbextents): .long 0 +C(bbextentt): .long 0 + +.globl C(cacheblock) +.globl C(d_viewbuffer) +.globl C(cachewidth) +.globl C(d_pzbuffer) +.globl C(d_zrowbytes) +.globl C(d_zwidth) +C(cacheblock): .long 0 +C(cachewidth): .long 0 +C(d_viewbuffer): .long 0 +C(d_pzbuffer): .long 0 +C(d_zrowbytes): .long 0 +C(d_zwidth): .long 0 + + +//------------------------------------------------------- +// ASM-only variables +//------------------------------------------------------- +.globl izi +izi: .long 0 + +.globl pbase, s, t, sfracf, tfracf, snext, tnext +.globl spancountminus1, zi16stepu, sdivz16stepu, tdivz16stepu +.globl zi8stepu, sdivz8stepu, tdivz8stepu, pz +s: .long 0 +t: .long 0 +snext: .long 0 +tnext: .long 0 +sfracf: .long 0 +tfracf: .long 0 +pbase: .long 0 +zi8stepu: .long 0 +sdivz8stepu: .long 0 +tdivz8stepu: .long 0 +zi16stepu: .long 0 +sdivz16stepu: .long 0 +tdivz16stepu: .long 0 +spancountminus1: .long 0 +pz: .long 0 + +.globl izistep +izistep: .long 0 + +//------------------------------------------------------- +// local variables for d_draw16.s +//------------------------------------------------------- + +.globl reciprocal_table_16, entryvec_table_16 +// 1/2, 1/3, 1/4, 1/5, 1/6, 1/7, 1/8, 1/9, 1/10, 1/11, 1/12, 1/13, +// 1/14, and 1/15 in 0.32 form +reciprocal_table_16: .long 0x40000000, 0x2aaaaaaa, 0x20000000 + .long 0x19999999, 0x15555555, 0x12492492 + .long 0x10000000, 0xe38e38e, 0xccccccc, 0xba2e8ba + .long 0xaaaaaaa, 0x9d89d89, 0x9249249, 0x8888888 + +#ifndef NeXT + .extern Entry2_16 + .extern Entry3_16 + .extern Entry4_16 + .extern Entry5_16 + .extern Entry6_16 + .extern Entry7_16 + .extern Entry8_16 + .extern Entry9_16 + .extern Entry10_16 + .extern Entry11_16 + .extern Entry12_16 + .extern Entry13_16 + .extern Entry14_16 + .extern Entry15_16 + .extern Entry16_16 +#endif + +entryvec_table_16: .long 0, Entry2_16, Entry3_16, Entry4_16 + .long Entry5_16, Entry6_16, Entry7_16, Entry8_16 + .long Entry9_16, Entry10_16, Entry11_16, Entry12_16 + .long Entry13_16, Entry14_16, Entry15_16, Entry16_16 + +//------------------------------------------------------- +// local variables for d_parta.s +//------------------------------------------------------- +.globl DP_Count, DP_u, DP_v, DP_32768, DP_Color, DP_Pix, DP_EntryTable +DP_Count: .long 0 +DP_u: .long 0 +DP_v: .long 0 +DP_32768: .single 32768.0 +DP_Color: .long 0 +DP_Pix: .long 0 + + +#ifndef NeXT + .extern DP_1x1 + .extern DP_2x2 + .extern DP_3x3 + .extern DP_4x4 +#endif + +DP_EntryTable: .long DP_1x1, DP_2x2, DP_3x3, DP_4x4 + +// +// advancetable is 8 bytes, but points to the middle of that range so negative +// offsets will work +// +.globl advancetable, sstep, tstep, pspantemp, counttemp, jumptemp +advancetable: .long 0, 0 +sstep: .long 0 +tstep: .long 0 + +pspantemp: .long 0 +counttemp: .long 0 +jumptemp: .long 0 + +// 1/2, 1/3, 1/4, 1/5, 1/6, and 1/7 in 0.32 form +.globl reciprocal_table, entryvec_table +reciprocal_table: .long 0x40000000, 0x2aaaaaaa, 0x20000000 + .long 0x19999999, 0x15555555, 0x12492492 + +#ifndef NeXT + .extern Entry2_8 + .extern Entry3_8 + .extern Entry4_8 + .extern Entry5_8 + .extern Entry6_8 + .extern Entry7_8 + .extern Entry8_8 +#endif + +entryvec_table: .long 0, Entry2_8, Entry3_8, Entry4_8 + .long Entry5_8, Entry6_8, Entry7_8, Entry8_8 + +#ifndef NeXT + .extern Spr8Entry2_8 + .extern Spr8Entry3_8 + .extern Spr8Entry4_8 + .extern Spr8Entry5_8 + .extern Spr8Entry6_8 + .extern Spr8Entry7_8 + .extern Spr8Entry8_8 +#endif + +.globl spr8entryvec_table +spr8entryvec_table: .long 0, Spr8Entry2_8, Spr8Entry3_8, Spr8Entry4_8 + .long Spr8Entry5_8, Spr8Entry6_8, Spr8Entry7_8, Spr8Entry8_8 + +#endif // id386 + diff --git a/contrib/other/sdlquake-1.0.9/d_zpoint.c b/contrib/other/sdlquake-1.0.9/d_zpoint.c new file mode 100644 index 000000000..909f25013 --- /dev/null +++ b/contrib/other/sdlquake-1.0.9/d_zpoint.c @@ -0,0 +1,47 @@ +/* +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. + +*/ +// d_zpoint.c: software driver module for drawing z-buffered points + +#include "quakedef.h" +#include "d_local.h" + + +/* +===================== +D_DrawZPoint +===================== +*/ +void D_DrawZPoint (void) +{ + byte *pdest; + short *pz; + int izi; + + pz = d_pzbuffer + (d_zwidth * r_zpointdesc.v) + r_zpointdesc.u; + pdest = d_viewbuffer + d_scantable[r_zpointdesc.v] + r_zpointdesc.u; + izi = (int)(r_zpointdesc.zi * 0x8000); + + if (*pz <= izi) + { + *pz = izi; + *pdest = r_zpointdesc.color; + } +} + diff --git a/contrib/other/sdlquake-1.0.9/data/COMEXP.TXT b/contrib/other/sdlquake-1.0.9/data/COMEXP.TXT new file mode 100644 index 000000000..06bc4af84 --- /dev/null +++ b/contrib/other/sdlquake-1.0.9/data/COMEXP.TXT @@ -0,0 +1,487 @@ + 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/contrib/other/sdlquake-1.0.9/data/HELP.TXT b/contrib/other/sdlquake-1.0.9/data/HELP.TXT new file mode 100644 index 000000000..ef79fbdcf --- /dev/null +++ b/contrib/other/sdlquake-1.0.9/data/HELP.TXT @@ -0,0 +1,119 @@ +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/contrib/other/sdlquake-1.0.9/data/LICINFO.TXT b/contrib/other/sdlquake-1.0.9/data/LICINFO.TXT new file mode 100644 index 000000000..f909e3818 --- /dev/null +++ b/contrib/other/sdlquake-1.0.9/data/LICINFO.TXT @@ -0,0 +1,97 @@ +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/contrib/other/sdlquake-1.0.9/data/MANUAL.TXT b/contrib/other/sdlquake-1.0.9/data/MANUAL.TXT new file mode 100644 index 000000000..baf4ca6d7 --- /dev/null +++ b/contrib/other/sdlquake-1.0.9/data/MANUAL.TXT @@ -0,0 +1,1034 @@ +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/contrib/other/sdlquake-1.0.9/data/ORDER.TXT b/contrib/other/sdlquake-1.0.9/data/ORDER.TXT new file mode 100644 index 000000000..fb4598d5c --- /dev/null +++ b/contrib/other/sdlquake-1.0.9/data/ORDER.TXT @@ -0,0 +1,103 @@ +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/contrib/other/sdlquake-1.0.9/data/README.TXT b/contrib/other/sdlquake-1.0.9/data/README.TXT new file mode 100644 index 000000000..fc62729f3 --- /dev/null +++ b/contrib/other/sdlquake-1.0.9/data/README.TXT @@ -0,0 +1,456 @@ +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/contrib/other/sdlquake-1.0.9/data/RLICNSE.TXT b/contrib/other/sdlquake-1.0.9/data/RLICNSE.TXT new file mode 100644 index 000000000..a3fdc3548 --- /dev/null +++ b/contrib/other/sdlquake-1.0.9/data/RLICNSE.TXT @@ -0,0 +1,204 @@ +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/contrib/other/sdlquake-1.0.9/data/SLICNSE.TXT b/contrib/other/sdlquake-1.0.9/data/SLICNSE.TXT new file mode 100644 index 000000000..057302ba7 --- /dev/null +++ b/contrib/other/sdlquake-1.0.9/data/SLICNSE.TXT @@ -0,0 +1,175 @@ +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/contrib/other/sdlquake-1.0.9/data/TECHINFO.TXT b/contrib/other/sdlquake-1.0.9/data/TECHINFO.TXT new file mode 100644 index 000000000..f2e33dbc1 --- /dev/null +++ b/contrib/other/sdlquake-1.0.9/data/TECHINFO.TXT @@ -0,0 +1,1913 @@ +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/contrib/other/sdlquake-1.0.9/docs/INSTALL b/contrib/other/sdlquake-1.0.9/docs/INSTALL new file mode 100644 index 000000000..bf317c1d4 --- /dev/null +++ b/contrib/other/sdlquake-1.0.9/docs/INSTALL @@ -0,0 +1,177 @@ +INSTALL for Linux Quake +----------------------- + +Quake for Linux provides several different binary executables to support +different hardware and drivers. + +Included with Linux Quake are: + - SVGALib Quake (squake) + This is a software renderer Quake that runs at the text console in Linux. + - GLQuake (glquake, glquake.glx and glquake.3dfxgl) + This is a hardware renderer Quake that runs using hardware 3D + acceleration. + - X11 Quake (quake.x11) + Software rendering in a window under X11. + +Installation +------------ + +Mount the Quake CD as one would usually mount a CDROM, this can be +accomplished by using the command: + + mount /dev/cdrom /mnt + +As root. Once the CD is mounted, run the setup script on the CD as root. + + $ su + Password: + # mount /dev/cdrom /mnt + # /bin/sh /mnt/setup + +The script will ask some questions about what options you want to install +and automatically install the software into /usr/local/games/quake. + +Requirements +------------ + +Requirements for SVGALib Quake: + +- SVGALib 1.20 or later (/lib/libvga.so.1.2.10) +- libc 5.2.18 or later (5.0.9 will not work, /lib/libc.so.5.2.18) + or glibc (libc6) for the glibc version +- CD-ROM for CDAudio +- Soundcard capable of mmap'd buffers. USSLite 3.5.4 was used to build squake + with. Works fine on SoundBlaster 16 and Gravis Ultrasound MAX. +- SVGALib supported mouse (usually if it works with X, it'll work with + squake). +- Kernel 2.0.24 or later + - untested with 2.1 kernels, your mileage may vary + +Requirements for GLQuake: + +- 3DFX based card for the GLQuake version, VooDoo, VooDoo Rush or VooDoo2 +at this writing. In order to use 3DFX hardware, you must have 3DFX's +GLIDE drivers installed. RPMs for these drivers are available at: +http://glide.xxedgexx.com/3DfxRPMS.html +- For the glX version, an OpenGL implementation that includes hardware +glX support. +- CD-ROM for CDAudio +- Soundcard capable of mmap'd buffers. USSLite 3.5.4 was used to build squake + with. Works fine on SoundBlaster 16 and Gravis Ultrasound MAX. +- SVGALib compatible mouse for glquake or X11 for glquake.glx +- Kernel 2.0.24 or later + - untested with 2.1 kernels, your mileage may vary + +Requirements for X11 Quake: + +- X11R5 later, only tested with XFree86, should work with most X Servers +- libc 5.2.18 or later (5.0.9 will not work, /lib/libc.so.5.2.18) + or glibc (libc6) for the glibc version +- CD-ROM for CDAudio +- Soundcard capable of mmap'd buffers. USSLite 3.5.4 was used to build squake + with. Works fine on SoundBlaster 16 and Gravis Ultrasound MAX. +- SVGALib supported mouse (usually if it works with X, it'll work with + squake). +- Kernel 2.0.24 or later + - untested with 2.1 kernels, your mileage may vary + +Additional notes for SVGALib Quake +---------------------------------- + +SVGALib may not detect a 3-button mouse properly (it +will only use two buttons). Check your /etc/vga/libvga.config +and set it up for your mouse type. + +Also, newer versions of SVGALib have an mouse_accel_type option. Most +users will want to set this to "off" in /etc/vga/libvga.config. + +Additional notes for GLQuake +---------------------------- + +There are three different ways to execute GLQuake: + +1. The binary "glquake" requires Mesa 3-D 2.5 or later installed and compiled +with 3DFX support (fxMesa..() function interface). It also requires +svgalib 1.3.0 or later for keyboard/mouse input. This binary is a console +application. Mesa 3-D requires GLIDE to be installed. + +2. The shell script "glquake.3dfxgl" runs the "glquake" binary after +preloading the lib3dfxgl.so library. This is a port of 3DFX's Win32 +OpenGL MCD (Mini Client Driver) to Linux. It is faster than Mesa 3-D +since it was written specifically with supporting GLQuake in mind. +lib3dfxgl.so requires that GLIDE be installed. + +3. The binary "glquake.glx" is linked against standard OpenGL libraries. +It should run on many different hardward OpenGL implementations under +Linux and X11. This binary is an X11 application and must be run under +X11. It will work with Mesa 3-D as a standard glX based OpenGL +applications. If the Mesa 3-D library is compiled with 3DFX support, +you can have Mesa 3-D support 3DFX hardware under X11 by setting the +enviroment variable "MESA_GLX_FX" to "fullscreen" for fullscreen mode +and "window" for windowed mode, eg. "export MESA_GLX_FX=fullscreen" for sh +or "setenv MESA_GLX_FX fullscreen" for csh. + +For glquake, you must also have SVGALib or later installed (1.3.0 or later +prefered). GLQuake uses SVGALib for mouse and keyboard handling. + +If you have gpm and/or selection running, you will have to terminate them +before running GLQuake since they will not give up the mouse when GLQuake +attempts to run. You can kill gpm by typing 'killall gpm' as root. + +You must run GLQuake as root or setuid root since it needs to access things +such as sound, keyboard, mouse and the 3DFX video. Future versions may not +require root permissions. + +Additional notes for X11 Quake +------------------------------ + +This is a windowed version that is generic for X11. It runs in a window +and can be resized. You can specify a starting window size with: + -width + -height + -winsize +Default is 320x200. It works in 16bit modes, but it's slower (twice as many +bytes to copy). + +No other video modes are supported (just runs windowed). Mouse is read, but +not "grabbed" by default. Go to the Options menu and turn on Use Mouse to grab +the mouse and use it in the game (or type "_windowed_mouse 1" at the console). + +Command Line Options for Linux Quake +------------------------------------ + +-mem +Specify memory in megabytes to allocate (default is 8MB, which should be fine +for most needs). + +-nostdout +Don't do any output to stdout + +-mdev (SVGALib based versions only) +Mouse device, default is /dev/mouse + +-mrate (SVGALib based versions only) +Mouse baud rate, default is 1200 + +-cddev +CD device, default is /dev/cdrom + +-mode +Use indicated video mode + +-nokdb +Don't initialize keyboard + +-sndbits <8 or 16> +Set sound bit sample size. Default is 16 if supported. + +-sndspeed +Set sound speed. Usual values are 8000, 11025, 22051 and 44100. +Default is 11025. + +-sndmono +Set mono sound + +-sndstereo +Set stereo sound (default if supported) + diff --git a/contrib/other/sdlquake-1.0.9/docs/INSTALL.Q2Mission b/contrib/other/sdlquake-1.0.9/docs/INSTALL.Q2Mission new file mode 100644 index 000000000..e69b63c15 --- /dev/null +++ b/contrib/other/sdlquake-1.0.9/docs/INSTALL.Q2Mission @@ -0,0 +1,39 @@ +INSTALL for Linux Quake2 Mission Packs +-------------------------------------- + +Installation +------------ + +Mount the Quake2 Mission Pack CD as one would usually mount a CDROM, this can +be accomplished by using the command: + + mount /dev/cdrom /mnt + +As root. Once the CD is mounted, run the setup script on the CD as root. + + $ su + Password: + # mount /dev/cdrom /mnt + # /bin/sh /mnt/setup + +The script will ask some questions about what options you want to install +and automatically install the software into /usr/local/games/quake2. + +After Installation +------------------ + +To run Quake2 Mission Pack #1: The Reckoning add the following option when +executing Quake2: + + ./quake2 +set game xatrix + +To run Quake2 Mission Pack #2: Ground Zero add the following: + + ./quake2 +set game rogue + +Requirements +------------ + +The Quake2 Mission Packs require a previous installation of Quake2. + + diff --git a/contrib/other/sdlquake-1.0.9/docs/INSTALL.Quake b/contrib/other/sdlquake-1.0.9/docs/INSTALL.Quake new file mode 100644 index 000000000..bf317c1d4 --- /dev/null +++ b/contrib/other/sdlquake-1.0.9/docs/INSTALL.Quake @@ -0,0 +1,177 @@ +INSTALL for Linux Quake +----------------------- + +Quake for Linux provides several different binary executables to support +different hardware and drivers. + +Included with Linux Quake are: + - SVGALib Quake (squake) + This is a software renderer Quake that runs at the text console in Linux. + - GLQuake (glquake, glquake.glx and glquake.3dfxgl) + This is a hardware renderer Quake that runs using hardware 3D + acceleration. + - X11 Quake (quake.x11) + Software rendering in a window under X11. + +Installation +------------ + +Mount the Quake CD as one would usually mount a CDROM, this can be +accomplished by using the command: + + mount /dev/cdrom /mnt + +As root. Once the CD is mounted, run the setup script on the CD as root. + + $ su + Password: + # mount /dev/cdrom /mnt + # /bin/sh /mnt/setup + +The script will ask some questions about what options you want to install +and automatically install the software into /usr/local/games/quake. + +Requirements +------------ + +Requirements for SVGALib Quake: + +- SVGALib 1.20 or later (/lib/libvga.so.1.2.10) +- libc 5.2.18 or later (5.0.9 will not work, /lib/libc.so.5.2.18) + or glibc (libc6) for the glibc version +- CD-ROM for CDAudio +- Soundcard capable of mmap'd buffers. USSLite 3.5.4 was used to build squake + with. Works fine on SoundBlaster 16 and Gravis Ultrasound MAX. +- SVGALib supported mouse (usually if it works with X, it'll work with + squake). +- Kernel 2.0.24 or later + - untested with 2.1 kernels, your mileage may vary + +Requirements for GLQuake: + +- 3DFX based card for the GLQuake version, VooDoo, VooDoo Rush or VooDoo2 +at this writing. In order to use 3DFX hardware, you must have 3DFX's +GLIDE drivers installed. RPMs for these drivers are available at: +http://glide.xxedgexx.com/3DfxRPMS.html +- For the glX version, an OpenGL implementation that includes hardware +glX support. +- CD-ROM for CDAudio +- Soundcard capable of mmap'd buffers. USSLite 3.5.4 was used to build squake + with. Works fine on SoundBlaster 16 and Gravis Ultrasound MAX. +- SVGALib compatible mouse for glquake or X11 for glquake.glx +- Kernel 2.0.24 or later + - untested with 2.1 kernels, your mileage may vary + +Requirements for X11 Quake: + +- X11R5 later, only tested with XFree86, should work with most X Servers +- libc 5.2.18 or later (5.0.9 will not work, /lib/libc.so.5.2.18) + or glibc (libc6) for the glibc version +- CD-ROM for CDAudio +- Soundcard capable of mmap'd buffers. USSLite 3.5.4 was used to build squake + with. Works fine on SoundBlaster 16 and Gravis Ultrasound MAX. +- SVGALib supported mouse (usually if it works with X, it'll work with + squake). +- Kernel 2.0.24 or later + - untested with 2.1 kernels, your mileage may vary + +Additional notes for SVGALib Quake +---------------------------------- + +SVGALib may not detect a 3-button mouse properly (it +will only use two buttons). Check your /etc/vga/libvga.config +and set it up for your mouse type. + +Also, newer versions of SVGALib have an mouse_accel_type option. Most +users will want to set this to "off" in /etc/vga/libvga.config. + +Additional notes for GLQuake +---------------------------- + +There are three different ways to execute GLQuake: + +1. The binary "glquake" requires Mesa 3-D 2.5 or later installed and compiled +with 3DFX support (fxMesa..() function interface). It also requires +svgalib 1.3.0 or later for keyboard/mouse input. This binary is a console +application. Mesa 3-D requires GLIDE to be installed. + +2. The shell script "glquake.3dfxgl" runs the "glquake" binary after +preloading the lib3dfxgl.so library. This is a port of 3DFX's Win32 +OpenGL MCD (Mini Client Driver) to Linux. It is faster than Mesa 3-D +since it was written specifically with supporting GLQuake in mind. +lib3dfxgl.so requires that GLIDE be installed. + +3. The binary "glquake.glx" is linked against standard OpenGL libraries. +It should run on many different hardward OpenGL implementations under +Linux and X11. This binary is an X11 application and must be run under +X11. It will work with Mesa 3-D as a standard glX based OpenGL +applications. If the Mesa 3-D library is compiled with 3DFX support, +you can have Mesa 3-D support 3DFX hardware under X11 by setting the +enviroment variable "MESA_GLX_FX" to "fullscreen" for fullscreen mode +and "window" for windowed mode, eg. "export MESA_GLX_FX=fullscreen" for sh +or "setenv MESA_GLX_FX fullscreen" for csh. + +For glquake, you must also have SVGALib or later installed (1.3.0 or later +prefered). GLQuake uses SVGALib for mouse and keyboard handling. + +If you have gpm and/or selection running, you will have to terminate them +before running GLQuake since they will not give up the mouse when GLQuake +attempts to run. You can kill gpm by typing 'killall gpm' as root. + +You must run GLQuake as root or setuid root since it needs to access things +such as sound, keyboard, mouse and the 3DFX video. Future versions may not +require root permissions. + +Additional notes for X11 Quake +------------------------------ + +This is a windowed version that is generic for X11. It runs in a window +and can be resized. You can specify a starting window size with: + -width + -height + -winsize +Default is 320x200. It works in 16bit modes, but it's slower (twice as many +bytes to copy). + +No other video modes are supported (just runs windowed). Mouse is read, but +not "grabbed" by default. Go to the Options menu and turn on Use Mouse to grab +the mouse and use it in the game (or type "_windowed_mouse 1" at the console). + +Command Line Options for Linux Quake +------------------------------------ + +-mem +Specify memory in megabytes to allocate (default is 8MB, which should be fine +for most needs). + +-nostdout +Don't do any output to stdout + +-mdev (SVGALib based versions only) +Mouse device, default is /dev/mouse + +-mrate (SVGALib based versions only) +Mouse baud rate, default is 1200 + +-cddev +CD device, default is /dev/cdrom + +-mode +Use indicated video mode + +-nokdb +Don't initialize keyboard + +-sndbits <8 or 16> +Set sound bit sample size. Default is 16 if supported. + +-sndspeed +Set sound speed. Usual values are 8000, 11025, 22051 and 44100. +Default is 11025. + +-sndmono +Set mono sound + +-sndstereo +Set stereo sound (default if supported) + diff --git a/contrib/other/sdlquake-1.0.9/docs/INSTALL.Quake2 b/contrib/other/sdlquake-1.0.9/docs/INSTALL.Quake2 new file mode 100644 index 000000000..6339c76cf --- /dev/null +++ b/contrib/other/sdlquake-1.0.9/docs/INSTALL.Quake2 @@ -0,0 +1,218 @@ +INSTALL for Linux Quake2 +------------------------ + +Quake2 for Linux supports the following video subsystems: + +- SVGALib Console Graphics (ref_soft.so) + - Requires SVGALib 1.2.0 or later +- X11 Window Graphics (ref_softx.so) + - X11R5 or later, XShm shared memory extension supported +- 3DFX fxMesa with Mesa 3-D or 3DFX Miniport (ref_gl.so) + - Mesa 3-D 2.6 or later, specifically compiled for 3DFX support + Mesa 3-D 2.6 compiled with 3DFX support is provided with this archive. +- Generic glX (X11) based OpenGL (ref_glx.so) + - Requires a glX based hardware accelerated OpenGL implementation. + Mesa 3-D 2.6 supports this on 3DFX hardware. + +Also included is a specific 3DFX mini-OpenGL implementation for running Quake2 +on 3DFX hardware. + +Installation +------------ + +Mount the Quake2 CD as one would usually mount a CDROM, this can be +accomplished by using the command: + + mount /dev/cdrom /mnt + +As root. Once the CD is mounted, run the setup script on the CD as root. + + $ su + Password: + # mount /dev/cdrom /mnt + # /bin/sh /mnt/setup + +The script will ask some questions about what options you want to install +and automatically install the software into /usr/local/games/quake2. + +Make sure you have the appropirate hardware, drivers and libraries installed +for the renderer you are going to play on. + +Quake2 for Linux supports the following renderers: + +- ref_soft + Software rendering under SVGALib (console only). SVGALib 1.2.10 or later + is required. Note that SVGALib 1.2.11 supports the ability to run a + SVGALib application under X11 as it will automatically allocate a new + console. The default mode is 320x240 (ModeX) since that is the lowest + resolution supported by Quake2. If SVGALib supports your video card, higher + resolution modes such as 640x480 and 800x600 are also supported. + + Please note that you may need to configure your mouse for SVGALib in + /etc/vga/libvga.config (or /etc/libvga.config). + +- ref_softx + Software rendering under X11. This uses the MITSHM Extension and should + work will virtually all Linux X Servers. **NOTE: Do not resize the window + under X11. You must use the Video menu to change resolution/window size. + + By default, the mouse will not be 'tied' to the Quake2 window. To cause + Quake2 to grab the mouse, select 'Windowed Mouse' from the video menu, + or type '_windowed_mouse 0' at the console. Do the reverse to release it. + You can bind keys to grab and release the mouse in the console, like so: + bind i "_windowed_mouse 1" + bind o "_windowed_mouse 0" + Then "i" will grab the mouse and "o" will release it. + +- ref_gl + This render can be run with two different OpenGL drivers: Mesa 3-D + ontop of Linux GLIDE, or 3DFX's mini-OpenGL Quake driver. + For Mesa 3-D, the necessary libMesaGL.so.2.6 is included with this archive. + You must copy it to /usr/lib or /usr/local/lib and run ldconfig (as root) + in order to use it. You can do this as follows: + tar cf - lib*GL* | (cd /usr/lib; tar xf -) + You should use tar to keep the symlinks intact. Once you copy them over + run ldconfig. + You must also download and install the Linux GLIDE drivers at + http://www.3dfx.com/software/download_glidel.html + And install them as instructed. + RPMs for GLIDE are available at : + http://glide.xxedgexx.com/3DfxRPMS.html + With version 3.20, the GL library is entirely runtime loaded. This means + you can specify what shared object to load for GL display. + To use Mesa 3-D GL (console), run quake with: + ./quake2 +set vid_ref gl +set gl_driver libMesaGL.so.2 + To use the 3DFX OpenGL Miniport, run the included quake2.3dfxgl: + ./quake2 +set vid_ref gl +set gl_driver lib3dfxgl.so + The gl_driver cvar indicates the name of the library to load for GL + functions. It can be in any directory listed in /etc/ld.so.conf + or in /etc/quake2.conf + + **NOTE: There is a problem on libc5 systems where a vid_restart (causing + a reload of the video system) will crash. There doesn't seem to be a + solution to this yet. It looks to be some sort of ld.so dynamic loading + interaction with SVGALib and ref_gl.so. A work around is to start in + software mode (./quake2 +set vid_ref soft), then use the menu to set your + mode and a vid_restart will work when going from software to GL. Exit + out then and save your video mode settings. + This problem does not occur on libc6 (glibc) based systems; vid_restart + works fine on there. + +- ref_glx + ref_glx should run on many different hardward OpenGL implementations under + Linux and X11. This binary is an X11 application and must be run under + X11. It will work with Mesa 3-D as a standard glX based OpenGL + applications. If the Mesa 3-D library is compiled with 3DFX support, + you can have Mesa 3-D support 3DFX hardware under X11 by setting the + enviroment variable "MESA_GLX_FX" to "fullscreen" for fullscreen mode + and "window" for windowed mode, eg. "export MESA_GLX_FX=fullscreen" for sh + or "setenv MESA_GLX_FX fullscreen" for csh. + + As with ref_gl, the "gl_driver" cvar indicates the shared library to load + for OpenGL functions (the glX functions must provided in that library + as well). + +Permissions +----------- + +Quake2 requires root permissions to use the software (SVGALib) and GL (MesaGL +w/3dfx) renders. In order to make this secure, some special considerations +must be made. + +Quake2 should get setuid root: + chown root quake2 + chmod 4711 quake2 + +And the ref_soft.so and ref_gl.so files must owned by root. + +The file /etc/quake2.conf must be installed. This file contains a single +line with the path of where the ref shared libraries can be found. +A sample one is included that lists /usr/games/quake2 as the default +path. The libraries are only loaded out of the directory listed in +/etc/quake2.conf for security considerations. + +Special permissions are not required for the softx renderer, but quake2 may +still need to be setuid root to open the sound device (quake2 will give up +setuid root permissions before loading softx). + +NOTE: If you use a setuid quake2 binary and run it as a normal user, it +will NOT be able to switch renderers on the fly because root permissions +are given up after the renderer is loaded. You can switch renderers on the +fly if you run quake2 as root (su or log in as root). + +NOTE: When the quake2 binary is run in dedicated server mode +(+set dedicated 1), no special permissions are required and +/etc/quake2.conf is not read since no renderer is loaded. + +---- + +The first time you run Quake2, it will use ref_soft or ref_softx based +on whether a DISPLAY environment variable exists. + +To force the loading of a specific renderer at load time, use the following +command lines: + + ./quake2 +set vid_ref soft + ./quake2 +set vid_ref softx + ./quake2 +set vid_ref gl + ./quake2 +set vid_ref glx + +Linux Specific Cvars +-------------------- + +To set this, use +set on the command line, i.e.: + ./quake2 +set cd_dev /dev/hdc +set sndmono 1 + +nocdaudio (defaults to 0) + Do not enable cd audio if not zero + +sndbits (defaults to 16) + Set sound bit sample size. + +sndspeed (defaults to 0) + Set sound speed. Usual values are 8000, 11025, 22051 and 44100. + If set to zero, causes the sound driver to attempt speeds in the following + order: 11025, 22051, 44100, 8000. + +sndchannels (defaults to 2) + Indicates stereo or mono sound. Defaults to 2 (stereo). Use 1 for mono. + +nostdout (defaults to 0) + Whether to output console msgs to standard out. Non-zero is cease output. + +Dedicated server +---------------- + +To run Linux Quake2 as a dedicated server, just run it as follows: + + ./quake2 +set dedicated 1 + +You can also set dmflags, timelimit, etc. in a config file, like so: + set timelimit 20 + set fraglimit 25 + set dmflags 532 + map fact3 + +Then exec that config file on load, like so: + + ./quake2 +set dedicated 1 +exec server.cfg + +If you use a config file, you must put a 'map' command in it or the +server won't load a map. + +To run a dedicated server in the background, use this; + + nohup ./quake2 +set dedicated 1 +exec server.cfg & + +A better way is to run Quake2 on a tty via screen. screen can be found +at ftp://prep.ai.mit.edu/pub/gnu/screen-3.7.4.tar.gz, but it comes with +most modern Linux installations now. + +----------------------------------------------------------------------------- + +Linux Quake2 is an unsupported product. Usage of this product is bound by +the legal notice found on the distribution Quake2 CDROM. + +/// Zoid +zoid@idsoftware.com + diff --git a/contrib/other/sdlquake-1.0.9/docs/README b/contrib/other/sdlquake-1.0.9/docs/README new file mode 100644 index 000000000..ee5a22d5c --- /dev/null +++ b/contrib/other/sdlquake-1.0.9/docs/README @@ -0,0 +1,157 @@ +README for Linux Quake +---------------------- + +This README convers all versions of Quake for Linux: + - SVGALib Quake (squake) + - GLQuake (glquake, glquake.glx and glquake.3dfxgl) + - X11 Quake (quake.x11) + +Requirements for SVGALib Quake: + +- SVGALib 1.20 or later (/lib/libvga.so.1.2.10) +- libc 5.2.18 or later (5.0.9 will not work, /lib/libc.so.5.2.18) + or glibc (libc6) for the glibc version +- CD-ROM for CDAudio +- Soundcard capable of mmap'd buffers. USSLite 3.5.4 was used to build squake + with. Works fine on SoundBlaster 16 and Gravis Ultrasound MAX. +- SVGALib supported mouse (usually if it works with X, it'll work with + squake). +- Kernel 2.0.24 or later + - untested with 2.1 kernels, your mileage may vary + +Requirements for GLQuake: + +- 3DFX based card for the GLQuake version, VooDoo, VooDoo Rush or VooDoo2 +at this writing. In order to use 3DFX hardware, you must have 3DFX's +GLIDE drivers installed. RPMs for these drivers are available at: +http://glide.xxedgexx.com/3DfxRPMS.html +- For the glX version, an OpenGL implementation that includes hardware +glX support. +- CD-ROM for CDAudio +- Soundcard capable of mmap'd buffers. USSLite 3.5.4 was used to build squake + with. Works fine on SoundBlaster 16 and Gravis Ultrasound MAX. +- SVGALib compatible mouse for glquake or X11 for glquake.glx +- Kernel 2.0.24 or later + - untested with 2.1 kernels, your mileage may vary + +Requirements for X11 Quake: + +- X11R5 later, only tested with XFree86, should work with most X Servers +- libc 5.2.18 or later (5.0.9 will not work, /lib/libc.so.5.2.18) + or glibc (libc6) for the glibc version +- CD-ROM for CDAudio +- Soundcard capable of mmap'd buffers. USSLite 3.5.4 was used to build squake + with. Works fine on SoundBlaster 16 and Gravis Ultrasound MAX. +- SVGALib supported mouse (usually if it works with X, it'll work with + squake). +- Kernel 2.0.24 or later + - untested with 2.1 kernels, your mileage may vary + +Additional notes for SVGALib Quake +---------------------------------- + +SVGALib may not detect a 3-button mouse properly (it +will only use two buttons). Check your /etc/vga/libvga.config +and set it up for your mouse type. + +Additional notes for GLQuake +---------------------------- + +There are three different ways to execute GLQuake: + +1. The binary "glquake" requires Mesa 3-D 2.5 or later installed and compiled +with 3DFX support (fxMesa..() function interface). It also requires +svgalib 1.3.0 or later for keyboard/mouse input. This binary is a console +application. Mesa 3-D requires GLIDE to be installed. + +2. The shell script "glquake.3dfxgl" runs the "glquake" binary after +preloading the lib3dfxgl.so library. This is a port of 3DFX's Win32 +OpenGL MCD (Mini Client Driver) to Linux. It is faster than Mesa 3-D +since it was written specifically with supporting GLQuake in mind. +lib3dfxgl.so requires that GLIDE be installed. + +3. The binary "glquake.glx" is linked against standard OpenGL libraries. +It should run on many different hardward OpenGL implementations under +Linux and X11. This binary is an X11 application and must be run under +X11. It will work with Mesa 3-D as a standard glX based OpenGL +applications. If the Mesa 3-D library is compiled with 3DFX support, +you can have Mesa 3-D support 3DFX hardware under X11 by setting the +enviroment variable "MESA_GLX_FX" to "fullscreen" for fullscreen mode +and "window" for windowed mode, eg. "export MESA_GLX_FX=fullscreen" for sh +or "setenv MESA_GLX_FX fullscreen" for csh. + +For glquake, you must also have SVGALib or later installed (1.3.0 or later +prefered). GLQuake uses SVGALib for mouse and keyboard handling. + +If you have gpm and/or selection running, you will have to terminate them +before running GLQuake since they will not give up the mouse when GLQuake +attempts to run. You can kill gpm by typing 'killall gpm' as root. + +You must run GLQuake as root or setuid root since it needs to access things +such as sound, keyboard, mouse and the 3DFX video. Future versions may not +require root permissions. + +Additional notes for X11 Quake +------------------------------ + +This is a windowed version that is generic for X11. It runs in a window +and can be resized. You can specify a starting window size with: + -width + -height + -winsize +Default is 320x200. It works in 16bit modes, but it's slower (twice as many +bytes to copy). + +No other video modes are supported (just runs windowed). Mouse is read, but +not "grabbed" by default. Go to the Options menu and turn on Use Mouse to grab +the mouse and use it in the game (or type "_windowed_mouse 1" at the console). + +Command Line Options for Linux Quake +------------------------------------ + +-mem +Specify memory in megabytes to allocate (default is 8MB, which should be fine +for most needs). + +-nostdout +Don't do any output to stdout + +-mdev (SVGALib based versions only) +Mouse device, default is /dev/mouse + +-mrate (SVGALib based versions only) +Mouse baud rate, default is 1200 + +-cddev +CD device, default is /dev/cdrom + +-mode +Use indicated video mode + +-nokdb +Don't initialize keyboard + +-sndbits <8 or 16> +Set sound bit sample size. Default is 16 if supported. + +-sndspeed +Set sound speed. Usual values are 8000, 11025, 22051 and 44100. +Default is 11025. + +-sndmono +Set mono sound + +-sndstereo +Set stereo sound (default if supported) + +End Notes +--------- + +Linux Quake is *NOT* an officially supported product. Mail about it +will be deleted. Do not email id about this product. If you are having +technical difficultly, you can email me, but make sure you have the correct +kernel, libc, svgalib and other software versions before you email me. + +Dave 'Zoid' Kirsch +zoid@idsoftware.com +Official Quake Unix Port Administrator diff --git a/contrib/other/sdlquake-1.0.9/docs/README.X11 b/contrib/other/sdlquake-1.0.9/docs/README.X11 new file mode 100644 index 000000000..b7a1667cb --- /dev/null +++ b/contrib/other/sdlquake-1.0.9/docs/README.X11 @@ -0,0 +1,107 @@ + +README for Linux SVGALib Quake +------------------------------ + +Requirements: + +- X11R5 later, only tested with XFree86, should work with most X Servers +- libc 5.2.18 or later (5.0.9 will not work, /lib/libc.so.5.2.18) +- CD-ROM for CDAudio +- Soundcard capable of mmap'd buffers. USSLite 3.5.4 was used to build squake + with. Works fine on SoundBlaster 16 and Gravis Ultrasound MAX. +- SVGALib supported mouse (usually if it works with X, it'll work with + squake). +- Kernel 2.0.24 or later + - untested with 2.1 kernels, your mileage may vary + +This is a windowed version that is generic for X11. It runs in a window +and can be resized. You can specify a starting window size with: + -width + -height + -winsize +Default is 320x200. It works in 16bit modes, but it's slower (twice as many +bytes to copy). + +No other video modes are supported (just runs windowed). Mouse is read, but +not "grabbed" by default. Go to the Options menu and turn on Use Mouse to grab +the mouse and use it in the game. If you want to move the mouse out of +QWCL, you have to turn Use Mouse off. + +Full sound support is included. The default sound rate is 16-bit stereo, +11KHz. You can change this in the options section below. + +New Command Line Options for Linux SVGAlib Quake +------------------------------------------------ + +-mem +Specify memory in megabytes to allocate (default is 8MB, which should be fine +for most needs). + +-nostdout +Don't do any output to stdout + +-cddev +CD device, default is /dev/cdrom + +-sndbits <8 or 16> +Set sound bit sample size. Default is 16 if supported. + +-sndspeed +Set sound speed. Usual values are 8000, 11025, 22051 and 44100. +Default is 11025. + +-sndmono +Set mono sound + +-sndstereo +Set stereo sound (default if supported) + +Installation +------------ + +Boot DOS (I know, but you need it to run the Quake install program) and +install Quake from your Quake CD to a DOS parition. + +Boot Linux and make a directory for Quake. Copy everything from the DOS Quake +directory into it. i.e.: + (cd /dos/quake; tar cf - .) | (cd ~/quake; tar xf -) + +Quake for X11 does not need to be setuid root. Sound can fail if /dev/dsp is +not mode 666. + +Quake may segfault if it tries to initialize your sound card and their isn't +one. Same with the CDROM. If it dies, try it with -nosound and/or +-nocdaudio. If you have a sound card it died on and you know it is +supported by USSLite (the driver that comes with the Linux kernel), let me +know and I'll take a look at it. + +It should work with SCSI CDROMs, but is untested. + +Full TCP/IP network support is in, including listen and dedicated server +modes. + +All of the options described in TECHINFO.TXT and MANUAL.TXT from the Quake +distribution will work, 'cept for stuff with vid modes and stuff. + +End Notes +--------- + +Linux Quake is *NOT* an officially supported product. Mail about it +will be deleted. Do not email id about this product. If you are having +technical difficultly, you can email me, but make sure you have the correct +kernel, libc, svgalib and other software versions before you email me. + +Dave 'Zoid' Kirsch +zoid@idsoftware.com +Official Quake Unix Port Administrator + +Acks +---- + +Greg Alexander for initial work in SVGALib +support. +Dave Taylor for basic Linux support. +id Software for Quake and making me port it. :) + +Lots of people on #linux, #quake for testing. + diff --git a/contrib/other/sdlquake-1.0.9/docs/readme.glquake b/contrib/other/sdlquake-1.0.9/docs/readme.glquake new file mode 100644 index 000000000..385625f03 --- /dev/null +++ b/contrib/other/sdlquake-1.0.9/docs/readme.glquake @@ -0,0 +1,162 @@ +Linux Glquake v0.98, Quake v1.09 release notes + +Requirements +------------ + +For 3DFX based hardware, you must download and install Linux GLIDE from +http://glide.xxedgexx.com/3DfxRPMS.html and install as per the +instructions. + +Running GLQuake +--------------- + +There are three different ways to execute GLQuake: + +1. The binary "glquake" requires Mesa 3-D 2.5 or later installed and compiled +with 3DFX support (fxMesa..() function interface). It also requires +svgalib 1.3.0 or later for keyboard/mouse input. This binary is a console +application. Mesa 3-D requires GLIDE to be installed. + +2. The shell script "glquake.3dfxgl" runs the "glquake" binary after +preloading the lib3dfxgl.so library. This is a port of 3DFX's Win32 +OpenGL MCD (Mini Client Driver) to Linux. It is faster than Mesa 3-D +since it was written specifically with supporting GLQuake in mind. +lib3dfxgl.so requires that GLIDE be installed. + +3. The binary "glquake.glx" is linked against standard OpenGL libraries. +It should run on many different hardward OpenGL implementations under +Linux and X11. This binary is an X11 application and must be run under +X11. It will work with Mesa 3-D as a standard glX based OpenGL +applications. If the Mesa 3-D library is compiled with 3DFX support, +you can have Mesa 3-D support 3DFX hardware under X11 by setting the +enviroment variable "MESA_GLX_FX" to "fullscreen" for fullscreen mode +and "window" for windowed mode. + +You must also have SVGALib 1.3.0 or later installed. GLQuake uses SVGALib +for mouse and keyboard handling. + +If you have gpm and/or selection running, you will have to terminate them +before running GLQuake since they will not give up the mouse when GLQuake +attempts to run. You can kill gpm by typing 'killall gpm' as root. + +You must run GLQuake as root or setuid root since it needs to access things +such as sound, keyboard, mouse and the 3DFX video. Future versions may not +require root permissions. + +resolution options +------------------ +glquake -width 512 -height 384 +Tries to run glquake at the specified resolution. +Only highend VooDoo cards support such high resolutions (most +cards on the market right now do not). Another popular and supported mode +is 512x384 (-width 512 -height 384) which can offer a faster speed than +the default 640x480. + +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. + +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/contrib/other/sdlquake-1.0.9/docs/readme.squake b/contrib/other/sdlquake-1.0.9/docs/readme.squake new file mode 100644 index 000000000..3d4ba918d --- /dev/null +++ b/contrib/other/sdlquake-1.0.9/docs/readme.squake @@ -0,0 +1,127 @@ + +README for Linux SVGALib Quake +------------------------------ + +Requirements: + +- SVGALib 1.20 or later (/lib/libvga.so.1.2.10) +- libc 5.2.18 or later (5.0.9 will not work, /lib/libc.so.5.2.18) +- CD-ROM for CDAudio +- Soundcard capable of mmap'd buffers. USSLite 3.5.4 was used to build squake + with. Works fine on SoundBlaster 16 and Gravis Ultrasound MAX. +- SVGALib supported mouse (usually if it works with X, it'll work with + squake). +- Kernel 2.0.24 or later + - untested with 2.1 kernels, your mileage may vary + +Here's the release you've been waiting for. Linux squake supports +320x200x256, the various modeX modes (320x400, 360x400, etc) as well as high +res modes if your card is supported by SVGALib. Use the Quake console command +vid_describemodes to list supported modes and the command vid_mode to +change modes. + +Full sound support is included. The default sound rate is 16-bit stereo, +11KHz. You can change this in the options section below. + +Mouse works great, but SVGALib may not detect a 3-button mouse properly (it +will only use two buttons). Check your /etc/libvga.config (or +/etc/vga/libvga.config for SlackWare users). + +**Version 1.1 fixes some crash bugs with the mission packs. + +New Command Line Options for Linux SVGAlib Quake +------------------------------------------------ + +-mem +Specify memory in megabytes to allocate (default is 8MB, which should be fine +for most needs). + +-nostdout +Don't do any output to stdout + +-mdev +Mouse device, default is /dev/mouse + +-mrate +Mouse baud rate, default is 1200 + +-cddev +CD device, default is /dev/cdrom + +-mode +Use indicated video mode + +-nokdb +Don't initialize keyboard + +-sndbits <8 or 16> +Set sound bit sample size. Default is 16 if supported. + +-sndspeed +Set sound speed. Usual values are 8000, 11025, 22051 and 44100. +Default is 11025. + +-sndmono +Set mono sound + +-sndstereo +Set stereo sound (default if supported) + +Installation +------------ + +Boot DOS (I know, but you need it to run the Quake install program) and +install Quake from your Quake CD to a DOS parition. + +Boot Linux and make a directory for Quake. Copy everything from the DOS Quake +directory into it. i.e.: + (cd /dos/quake; tar cf - .) | (cd ~/quake; tar xf -) + +Place squake into your Quake directory. You must make it setuid root (since +Quake access stuff like direct video writes, the raw keyboard mode, CD, etc). +Quake will setuid back to the normal user as soon as it opens these files. +Make Quake suid root as follows: + chown root squake + chmod 4755 squake + +Run squake. I don't recommend running it as root, since all the saved +config.cfg files will be then owned as root. Use your normal account, unless +you do everything as root, then your mileage will vary. + +squake may segfault if it tries to initialize your sound card and their isn't +one. Same with the CDROM. If it dies, try it with -nosound and/or +-nocdaudio. If you have a sound card it died on and you know it is +supported by USSLite (the driver that comes with the Linux kernel), let me +know and I'll take a look at it. + +It should work with SCSI CDROMs, but is untested. + +Full TCP/IP network support is in, including listen and dedicated server +modes. squake makes a nice dedicated server as you don't need the X11 +libraries kicking around. + +All of the options described in TECHINFO.TXT and MANUAL.TXT from the Quake +distribution will work, 'cept for stuff with vid modes and stuff. + +End Notes +--------- + +Linux SVGALib Quake is *NOT* an officially supported product. Mail about it +will be deleted. Do not email id about this product. If you are having +technical difficultly, you can email me, but make sure you have the correct +kernel, libc, svgalib and other software versions before you email me. + +Dave 'Zoid' Kirsch +zoid@threewave.com +Official Quake Unix Port Administrator + +Acks +---- + +Greg Alexander for initial work in SVGALib +support. +Dave Taylor for basic Linux support. +id Software for Quake and making me port it. :) + +Lots of people on #linux, #quake for testing. + diff --git a/contrib/other/sdlquake-1.0.9/dos_v2.c b/contrib/other/sdlquake-1.0.9/dos_v2.c new file mode 100644 index 000000000..3adf2cb6f --- /dev/null +++ b/contrib/other/sdlquake-1.0.9/dos_v2.c @@ -0,0 +1,257 @@ +/* +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 +#include +#include +#include +#include +#include +#include +// #include +#include + +#include "dosisms.h" + +_go32_dpmi_registers hmm; + +// globals +regs_t regs; +void (*dos_error_func)(char *msg, ...); + +static unsigned conventional_memory = -1; + +__dpmi_regs callback_regs; + +void map_in_conventional_memory(void) +{ + if (conventional_memory == -1) + { + if (__djgpp_nearptr_enable()) + { + conventional_memory = __djgpp_conventional_base; + } + } +} + +unsigned int ptr2real(void *ptr) +{ + map_in_conventional_memory(); + return (int)ptr - conventional_memory; +} + +void *real2ptr(unsigned int real) +{ + map_in_conventional_memory(); + return (void *) (real + conventional_memory); +} + +void *far2ptr(unsigned int farptr) +{ + return real2ptr(((farptr & ~0xffff) >>12) + (farptr&0xffff)); +} + +unsigned int ptr2far(void *ptr) +{ + return ((ptr2real(ptr)&~0xf) << 12) + (ptr2real(ptr) & 0xf); +} + +int dos_inportb(int port) +{ + return inportb(port); +} + +int dos_inportw(int port) +{ + return inportw(port); +} + +void dos_outportb(int port, int val) +{ + outportb(port, val); +} + +void dos_outportw(int port, int val) +{ + outportw(port, val); +} + +void dos_irqenable(void) +{ + enable(); +} + +void dos_irqdisable(void) +{ + disable(); +} + +// +// Returns 0 on success +// + +int dos_int86(int vec) +{ + int rc; + regs.x.ss = regs.x.sp = 0; + rc = _go32_dpmi_simulate_int(vec, (_go32_dpmi_registers *) ®s); + return rc || (regs.x.flags & 1); +} + +int dos_int386(int vec, regs_t *inregs, regs_t *outregs) +{ + int rc; + memcpy(outregs, inregs, sizeof(regs_t)); + outregs->x.ss = outregs->x.sp = 0; + rc = _go32_dpmi_simulate_int(vec, (_go32_dpmi_registers *) outregs); + return rc || (outregs->x.flags & 1); +} + +// +// Because of a quirk in dj's alloc-dos-memory wrapper, you need to keep +// the seginfo structure around for when you free the mem. +// + +static _go32_dpmi_seginfo seginfo[10]; + +void *dos_getmemory(int size) +{ + + int rc; + _go32_dpmi_seginfo info; + static int firsttime=1; + int i; + + if (firsttime) + { + memset(seginfo, 0, sizeof(seginfo)); + firsttime = 0; + } + + info.size = (size+15) / 16; + rc = _go32_dpmi_allocate_dos_memory(&info); + if (rc) + return 0; + + for (i=0;i<10;i++) + if (!seginfo[i].rm_segment) break; + seginfo[i] = info; + return real2ptr((int) info.rm_segment << 4); + +} + +void dos_freememory(void *ptr) +{ + + int i; + int segment; + + segment = ptr2real(ptr) >> 4; + for (i=0 ; i<10 ; i++) + if (seginfo[i].rm_segment == segment) + { + _go32_dpmi_free_dos_memory(&seginfo[i]); + seginfo[i].rm_segment = 0; + break; + } + +} + +static struct handlerhistory_s +{ + int intr; + _go32_dpmi_seginfo pm_oldvec; +} handlerhistory[4]; + +static int handlercount=0; + +void dos_registerintr(int intr, void (*handler)(void)) +{ + _go32_dpmi_seginfo info; + struct handlerhistory_s *oldstuff; + + oldstuff = &handlerhistory[handlercount]; + +// remember old handler + _go32_dpmi_get_protected_mode_interrupt_vector(intr, &oldstuff->pm_oldvec); + oldstuff->intr = intr; + + info.pm_offset = (int) handler; + _go32_dpmi_allocate_iret_wrapper(&info); + +// set new protected mode handler + _go32_dpmi_set_protected_mode_interrupt_vector(intr, &info); + + handlercount++; + +} + +void dos_restoreintr(int intr) +{ + + int i; + struct handlerhistory_s *oldstuff; + +// find and reinstall previous interrupt + for (i=0 ; iintr == intr) + { + _go32_dpmi_set_protected_mode_interrupt_vector(intr, + &oldstuff->pm_oldvec); + oldstuff->intr = -1; + break; + } + } + +} + +void dos_usleep(int usecs) +{ + usleep(usecs); +} + +int dos_getheapsize(void) +{ + return _go32_dpmi_remaining_physical_memory(); +} + +int dos_lockmem(void *addr, int size) +{ + __dpmi_meminfo info; + info.address = (long) addr + __djgpp_base_address; + info.size = size; + if (__dpmi_lock_linear_region(&info)) + return __dpmi_error; + else + return 0; +} + +int dos_unlockmem(void *addr, int size) +{ + __dpmi_meminfo info; + info.address = (long) addr + __djgpp_base_address; + info.size = size; + if (__dpmi_unlock_linear_region(&info)) + return __dpmi_error; + else + return 0; +} + diff --git a/contrib/other/sdlquake-1.0.9/dosasm.S b/contrib/other/sdlquake-1.0.9/dosasm.S new file mode 100644 index 000000000..2633be961 --- /dev/null +++ b/contrib/other/sdlquake-1.0.9/dosasm.S @@ -0,0 +1,77 @@ +#include "asm_i386.h" + +.data +fpenv: .long 0, 0, 0, 0, 0, 0, 0, 0 + +.text +.globl C(StartMSRInterval) +C(StartMSRInterval): + movl $0x11,%ecx // read the CESR + .byte 0x0F + .byte 0x32 // RDMSR + + andl $0xFE3FFE3F,%eax // stop both counters + .byte 0x0F + .byte 0x30 // WRMSR + + movl 4(%esp),%eax // point counter 0 to desired event, with counters + andl $0x3F,%eax // still stopped + movl $0x11,%ecx + .byte 0x0F + .byte 0x30 // WRMSR + + movl $0x12,%ecx // set counter 0 to the value 0 + subl %eax,%eax + subl %edx,%edx + .byte 0x0F + .byte 0x30 // WRMSR + + movl 4(%esp),%eax // restart counter 0 with selected event + andl $0x3F,%eax + subl %edx,%edx + orl $0xC0,%eax + movl $0x11,%ecx // control and event select + .byte 0x0F + .byte 0x30 // WRMSR + + ret + +.globl C(EndMSRInterval) +C(EndMSRInterval): + movl $0x12,%ecx // counter 0 + .byte 0x0F + .byte 0x32 // RDMSR + + ret // lower 32 bits of count in %eax + +#if 0 + .data +Lxxx: .long 0 + + .text + +.globl C(setstackcheck) +C(setstackcheck): + + movl %esp,%eax + subl $0x38000,%eax + movl $0x5A5A5A5A,(%eax) + movl %eax,Lxxx + + ret + + +.globl C(dostackcheck) +C(dostackcheck): + + movl Lxxx,%edx + movl $0,%eax + + cmpl $0x5A5A5A5A,(%edx) + jz qqq + incl %eax +qqq: + + ret +#endif + diff --git a/contrib/other/sdlquake-1.0.9/dosisms.h b/contrib/other/sdlquake-1.0.9/dosisms.h new file mode 100644 index 000000000..7f12268a2 --- /dev/null +++ b/contrib/other/sdlquake-1.0.9/dosisms.h @@ -0,0 +1,100 @@ +/* +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. + +*/ + +// +// dosisms.h: I'd call it dos.h, but the name's taken +// + +#ifndef _DOSISMS_H_ +#define _DOSISMS_H_ + +int dos_lockmem(void *addr, int size); +int dos_unlockmem(void *addr, int size); + +typedef union { + struct { + unsigned long edi; + unsigned long esi; + unsigned long ebp; + unsigned long res; + unsigned long ebx; + unsigned long edx; + unsigned long ecx; + unsigned long eax; + } d; + struct { + unsigned short di, di_hi; + unsigned short si, si_hi; + unsigned short bp, bp_hi; + unsigned short res, res_hi; + unsigned short bx, bx_hi; + unsigned short dx, dx_hi; + unsigned short cx, cx_hi; + unsigned short ax, ax_hi; + unsigned short flags; + unsigned short es; + unsigned short ds; + unsigned short fs; + unsigned short gs; + unsigned short ip; + unsigned short cs; + unsigned short sp; + unsigned short ss; + } x; + struct { + unsigned char edi[4]; + unsigned char esi[4]; + unsigned char ebp[4]; + unsigned char res[4]; + unsigned char bl, bh, ebx_b2, ebx_b3; + unsigned char dl, dh, edx_b2, edx_b3; + unsigned char cl, ch, ecx_b2, ecx_b3; + unsigned char al, ah, eax_b2, eax_b3; + } h; +} regs_t; + +unsigned int ptr2real(void *ptr); +void *real2ptr(unsigned int real); +void *far2ptr(unsigned int farptr); +unsigned int ptr2far(void *ptr); + +int dos_inportb(int port); +int dos_inportw(int port); +void dos_outportb(int port, int val); +void dos_outportw(int port, int val); + +void dos_irqenable(void); +void dos_irqdisable(void); +void dos_registerintr(int intr, void (*handler)(void)); +void dos_restoreintr(int intr); + +int dos_int86(int vec); + +void *dos_getmemory(int size); +void dos_freememory(void *ptr); + +void dos_usleep(int usecs); + +int dos_getheapsize(void); + +extern regs_t regs; + +#endif // _DOSISMS_H_ + diff --git a/contrib/other/sdlquake-1.0.9/draw.c b/contrib/other/sdlquake-1.0.9/draw.c new file mode 100644 index 000000000..00ee0b492 --- /dev/null +++ b/contrib/other/sdlquake-1.0.9/draw.c @@ -0,0 +1,902 @@ +/* +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" + +typedef struct { + vrect_t rect; + int width; + int height; + byte *ptexbytes; + int rowbytes; +} rectdesc_t; + +static rectdesc_t r_rectdesc; + +byte *draw_chars; // 8*8 graphic characters +qpic_t *draw_disc; +qpic_t *draw_backtile; + +//============================================================================= +/* Support Routines */ + +typedef struct cachepic_s +{ + char name[MAX_QPATH]; + cache_user_t cache; +} cachepic_t; + +#define MAX_CACHED_PICS 128 +cachepic_t menu_cachepics[MAX_CACHED_PICS]; +int menu_numcachepics; + + +qpic_t *Draw_PicFromWad (char *name) +{ + return W_GetLumpName (name); +} + +/* +================ +Draw_CachePic +================ +*/ +qpic_t *Draw_CachePic (char *path) +{ + cachepic_t *pic; + int i; + qpic_t *dat; + + for (pic=menu_cachepics, i=0 ; iname)) + break; + + if (i == menu_numcachepics) + { + if (menu_numcachepics == MAX_CACHED_PICS) + Sys_Error ("menu_numcachepics == MAX_CACHED_PICS"); + menu_numcachepics++; + strcpy (pic->name, path); + } + + dat = Cache_Check (&pic->cache); + + if (dat) + return dat; + +// +// load the pic from disk +// + COM_LoadCacheFile (path, &pic->cache); + + dat = (qpic_t *)pic->cache.data; + if (!dat) + { + Sys_Error ("Draw_CachePic: failed to load %s", path); + } + + SwapPic (dat); + + return dat; +} + + + +/* +=============== +Draw_Init +=============== +*/ +void Draw_Init (void) +{ + int i; + + draw_chars = W_GetLumpName ("conchars"); + draw_disc = W_GetLumpName ("disc"); + draw_backtile = W_GetLumpName ("backtile"); + + r_rectdesc.width = draw_backtile->width; + r_rectdesc.height = draw_backtile->height; + r_rectdesc.ptexbytes = draw_backtile->data; + r_rectdesc.rowbytes = draw_backtile->width; +} + + + +/* +================ +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) +{ + byte *dest; + byte *source; + unsigned short *pusdest; + int drawline; + int row, col; + + num &= 255; + + if (y <= -8) + return; // totally off screen + +#ifdef PARANOID + if (y > vid.height - 8 || x < 0 || x > vid.width - 8) + Sys_Error ("Con_DrawCharacter: (%i, %i)", x, y); + if (num < 0 || num > 255) + Sys_Error ("Con_DrawCharacter: char %i", num); +#endif + + row = num>>4; + col = num&15; + source = draw_chars + (row<<10) + (col<<3); + + if (y < 0) + { // clipped + drawline = 8 + y; + source -= 128*y; + y = 0; + } + else + drawline = 8; + + + if (r_pixbytes == 1) + { + dest = vid.conbuffer + y*vid.conrowbytes + x; + + while (drawline--) + { + if (source[0]) + dest[0] = source[0]; + if (source[1]) + dest[1] = source[1]; + if (source[2]) + dest[2] = source[2]; + if (source[3]) + dest[3] = source[3]; + if (source[4]) + dest[4] = source[4]; + if (source[5]) + dest[5] = source[5]; + if (source[6]) + dest[6] = source[6]; + if (source[7]) + dest[7] = source[7]; + source += 128; + dest += vid.conrowbytes; + } + } + else + { + // FIXME: pre-expand to native format? + pusdest = (unsigned short *) + ((byte *)vid.conbuffer + y*vid.conrowbytes + (x<<1)); + + while (drawline--) + { + if (source[0]) + pusdest[0] = d_8to16table[source[0]]; + if (source[1]) + pusdest[1] = d_8to16table[source[1]]; + if (source[2]) + pusdest[2] = d_8to16table[source[2]]; + if (source[3]) + pusdest[3] = d_8to16table[source[3]]; + if (source[4]) + pusdest[4] = d_8to16table[source[4]]; + if (source[5]) + pusdest[5] = d_8to16table[source[5]]; + if (source[6]) + pusdest[6] = d_8to16table[source[6]]; + if (source[7]) + pusdest[7] = d_8to16table[source[7]]; + + source += 128; + pusdest += (vid.conrowbytes >> 1); + } + } +} + +/* +================ +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) +{ + byte *dest; + byte *source; + int drawline; + extern byte *draw_chars; + int row, col; + + if (!vid.direct) + return; // don't have direct FB access, so no debugchars... + + drawline = 8; + + row = num>>4; + col = num&15; + source = draw_chars + (row<<10) + (col<<3); + + dest = vid.direct + 312; + + while (drawline--) + { + dest[0] = source[0]; + dest[1] = source[1]; + dest[2] = source[2]; + dest[3] = source[3]; + dest[4] = source[4]; + dest[5] = source[5]; + dest[6] = source[6]; + dest[7] = source[7]; + source += 128; + dest += 320; + } +} + +/* +============= +Draw_Pic +============= +*/ +void Draw_Pic (int x, int y, qpic_t *pic) +{ + byte *dest, *source; + unsigned short *pusdest; + int v, u; + + if ((x < 0) || + (x + pic->width > vid.width) || + (y < 0) || + (y + pic->height > vid.height)) + { + Sys_Error ("Draw_Pic: bad coordinates"); + } + + source = pic->data; + + if (r_pixbytes == 1) + { + dest = vid.buffer + y * vid.rowbytes + x; + + for (v=0 ; vheight ; v++) + { + Q_memcpy (dest, source, pic->width); + dest += vid.rowbytes; + source += pic->width; + } + } + else + { + // FIXME: pretranslate at load time? + pusdest = (unsigned short *)vid.buffer + y * (vid.rowbytes >> 1) + x; + + for (v=0 ; vheight ; v++) + { + for (u=0 ; uwidth ; u++) + { + pusdest[u] = d_8to16table[source[u]]; + } + + pusdest += vid.rowbytes >> 1; + source += pic->width; + } + } +} + + +/* +============= +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"); + } + + source = pic->data; + + if (r_pixbytes == 1) + { + dest = vid.buffer + y * vid.rowbytes + x; + + if (pic->width & 7) + { // general + for (v=0 ; vheight ; v++) + { + for (u=0 ; uwidth ; u++) + if ( (tbyte=source[u]) != TRANSPARENT_COLOR) + dest[u] = tbyte; + + dest += vid.rowbytes; + source += pic->width; + } + } + else + { // unwound + for (v=0 ; vheight ; v++) + { + for (u=0 ; uwidth ; u+=8) + { + if ( (tbyte=source[u]) != TRANSPARENT_COLOR) + dest[u] = tbyte; + if ( (tbyte=source[u+1]) != TRANSPARENT_COLOR) + dest[u+1] = tbyte; + if ( (tbyte=source[u+2]) != TRANSPARENT_COLOR) + dest[u+2] = tbyte; + if ( (tbyte=source[u+3]) != TRANSPARENT_COLOR) + dest[u+3] = tbyte; + if ( (tbyte=source[u+4]) != TRANSPARENT_COLOR) + dest[u+4] = tbyte; + if ( (tbyte=source[u+5]) != TRANSPARENT_COLOR) + dest[u+5] = tbyte; + if ( (tbyte=source[u+6]) != TRANSPARENT_COLOR) + dest[u+6] = tbyte; + if ( (tbyte=source[u+7]) != TRANSPARENT_COLOR) + dest[u+7] = tbyte; + } + dest += vid.rowbytes; + source += pic->width; + } + } + } + else + { + // FIXME: pretranslate at load time? + pusdest = (unsigned short *)vid.buffer + y * (vid.rowbytes >> 1) + x; + + for (v=0 ; vheight ; v++) + { + for (u=0 ; uwidth ; u++) + { + tbyte = source[u]; + + if (tbyte != TRANSPARENT_COLOR) + { + pusdest[u] = d_8to16table[tbyte]; + } + } + + pusdest += vid.rowbytes >> 1; + source += pic->width; + } + } +} + + +/* +============= +Draw_TransPicTranslate +============= +*/ +void Draw_TransPicTranslate (int x, int y, qpic_t *pic, byte *translation) +{ + 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"); + } + + source = pic->data; + + if (r_pixbytes == 1) + { + dest = vid.buffer + y * vid.rowbytes + x; + + if (pic->width & 7) + { // general + for (v=0 ; vheight ; v++) + { + for (u=0 ; uwidth ; u++) + if ( (tbyte=source[u]) != TRANSPARENT_COLOR) + dest[u] = translation[tbyte]; + + dest += vid.rowbytes; + source += pic->width; + } + } + else + { // unwound + for (v=0 ; vheight ; v++) + { + for (u=0 ; uwidth ; u+=8) + { + if ( (tbyte=source[u]) != TRANSPARENT_COLOR) + dest[u] = translation[tbyte]; + if ( (tbyte=source[u+1]) != TRANSPARENT_COLOR) + dest[u+1] = translation[tbyte]; + if ( (tbyte=source[u+2]) != TRANSPARENT_COLOR) + dest[u+2] = translation[tbyte]; + if ( (tbyte=source[u+3]) != TRANSPARENT_COLOR) + dest[u+3] = translation[tbyte]; + if ( (tbyte=source[u+4]) != TRANSPARENT_COLOR) + dest[u+4] = translation[tbyte]; + if ( (tbyte=source[u+5]) != TRANSPARENT_COLOR) + dest[u+5] = translation[tbyte]; + if ( (tbyte=source[u+6]) != TRANSPARENT_COLOR) + dest[u+6] = translation[tbyte]; + if ( (tbyte=source[u+7]) != TRANSPARENT_COLOR) + dest[u+7] = translation[tbyte]; + } + dest += vid.rowbytes; + source += pic->width; + } + } + } + else + { + // FIXME: pretranslate at load time? + pusdest = (unsigned short *)vid.buffer + y * (vid.rowbytes >> 1) + x; + + for (v=0 ; vheight ; v++) + { + for (u=0 ; uwidth ; u++) + { + tbyte = source[u]; + + if (tbyte != TRANSPARENT_COLOR) + { + pusdest[u] = d_8to16table[tbyte]; + } + } + + pusdest += vid.rowbytes >> 1; + source += pic->width; + } + } +} + + +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]) + dest[x] = 0x60 + source[x]; + source += 128; + dest += 320; + } + +} + +/* +================ +Draw_ConsoleBackground + +================ +*/ +void Draw_ConsoleBackground (int lines) +{ + int x, y, v; + byte *src, *dest; + unsigned short *pusdest; + int f, fstep; + qpic_t *conback; + char ver[100]; + + conback = Draw_CachePic ("gfx/conback.lmp"); + +// hack the version number directly into the pic +#ifdef _WIN32 + sprintf (ver, "(WinQuake) %4.2f", (float)VERSION); + dest = conback->data + 320*186 + 320 - 11 - 8*strlen(ver); +#elif defined(X11) + sprintf (ver, "(X11 Quake %2.2f) %4.2f", (float)X11_VERSION, (float)VERSION); + dest = conback->data + 320*186 + 320 - 11 - 8*strlen(ver); +#elif defined(__linux__) + sprintf (ver, "(Linux Quake %2.2f) %4.2f", (float)LINUX_VERSION, (float)VERSION); + dest = conback->data + 320*186 + 320 - 11 - 8*strlen(ver); +#else + dest = conback->data + 320 - 43 + 320*186; + sprintf (ver, "%4.2f", VERSION); +#endif + + for (x=0 ; xdata + v*320; + if (vid.conwidth == 320) + memcpy (dest, src, vid.conwidth); + else + { + f = 0; + fstep = 320*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 + { + pusdest = (unsigned short *)vid.conbuffer; + + for (y=0 ; y> 1)) + { + // FIXME: pre-expand to native format? + // FIXME: does the endian switching go away in production? + v = (vid.conheight - lines + y)*200/vid.conheight; + src = conback->data + v*320; + f = 0; + fstep = 320*0x10000/vid.conwidth; + for (x=0 ; x>16]]; + f += fstep; + pusdest[x+1] = d_8to16table[src[f>>16]]; + f += fstep; + pusdest[x+2] = d_8to16table[src[f>>16]]; + f += fstep; + pusdest[x+3] = d_8to16table[src[f>>16]]; + f += fstep; + } + } + } +} + + +/* +============== +R_DrawRect8 +============== +*/ +void R_DrawRect8 (vrect_t *prect, int rowbytes, byte *psrc, + int transparent) +{ + byte t; + int i, j, srcdelta, destdelta; + byte *pdest; + + pdest = vid.buffer + (prect->y * vid.rowbytes) + prect->x; + + srcdelta = rowbytes - prect->width; + destdelta = vid.rowbytes - prect->width; + + if (transparent) + { + for (i=0 ; iheight ; i++) + { + for (j=0 ; jwidth ; j++) + { + t = *psrc; + if (t != TRANSPARENT_COLOR) + { + *pdest = t; + } + + psrc++; + pdest++; + } + + psrc += srcdelta; + pdest += destdelta; + } + } + else + { + for (i=0 ; iheight ; i++) + { + memcpy (pdest, psrc, prect->width); + psrc += rowbytes; + pdest += vid.rowbytes; + } + } +} + + +/* +============== +R_DrawRect16 +============== +*/ +void R_DrawRect16 (vrect_t *prect, int rowbytes, byte *psrc, + int transparent) +{ + byte t; + int i, j, srcdelta, destdelta; + unsigned short *pdest; + +// FIXME: would it be better to pre-expand native-format versions? + + pdest = (unsigned short *)vid.buffer + + (prect->y * (vid.rowbytes >> 1)) + prect->x; + + srcdelta = rowbytes - prect->width; + destdelta = (vid.rowbytes >> 1) - prect->width; + + if (transparent) + { + for (i=0 ; iheight ; i++) + { + for (j=0 ; jwidth ; j++) + { + t = *psrc; + if (t != TRANSPARENT_COLOR) + { + *pdest = d_8to16table[t]; + } + + psrc++; + pdest++; + } + + psrc += srcdelta; + pdest += destdelta; + } + } + else + { + for (i=0 ; iheight ; i++) + { + for (j=0 ; jwidth ; j++) + { + *pdest = d_8to16table[*psrc]; + psrc++; + pdest++; + } + + psrc += srcdelta; + pdest += destdelta; + } + } +} + + +/* +============= +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) +{ + int width, height, tileoffsetx, tileoffsety; + byte *psrc; + vrect_t vr; + + r_rectdesc.rect.x = x; + r_rectdesc.rect.y = y; + r_rectdesc.rect.width = w; + r_rectdesc.rect.height = h; + + vr.y = r_rectdesc.rect.y; + height = r_rectdesc.rect.height; + + tileoffsety = vr.y % r_rectdesc.height; + + while (height > 0) + { + vr.x = r_rectdesc.rect.x; + width = r_rectdesc.rect.width; + + if (tileoffsety != 0) + vr.height = r_rectdesc.height - tileoffsety; + else + vr.height = r_rectdesc.height; + + if (vr.height > height) + vr.height = height; + + tileoffsetx = vr.x % r_rectdesc.width; + + while (width > 0) + { + if (tileoffsetx != 0) + vr.width = r_rectdesc.width - tileoffsetx; + else + vr.width = r_rectdesc.width; + + if (vr.width > width) + vr.width = width; + + psrc = r_rectdesc.ptexbytes + + (tileoffsety * r_rectdesc.rowbytes) + tileoffsetx; + + if (r_pixbytes == 1) + { + R_DrawRect8 (&vr, r_rectdesc.rowbytes, psrc, 0); + } + else + { + R_DrawRect16 (&vr, r_rectdesc.rowbytes, psrc, 0); + } + + vr.x += vr.width; + width -= vr.width; + tileoffsetx = 0; // only the left tile can be left-clipped + } + + vr.y += vr.height; + height -= vr.height; + tileoffsety = 0; // only the top tile can be top-clipped + } +} + + +/* +============= +Draw_Fill + +Fills a box of pixels with a single color +============= +*/ +void Draw_Fill (int x, int y, int w, int h, int c) +{ + byte *dest; + unsigned short *pusdest; + unsigned uc; + int u, v; + + if (r_pixbytes == 1) + { + dest = vid.buffer + y*vid.rowbytes + x; + for (v=0 ; v> 1) + x; + for (v=0 ; v> 1)) + for (u=0 ; udata, 24, 24); +} + + +/* +================ +Draw_EndDisc + +Erases the disc icon. +Call after completing any disc IO +================ +*/ +void Draw_EndDisc (void) +{ + + D_EndDirectRect (vid.width - 24, 0, 24, 24); +} + diff --git a/contrib/other/sdlquake-1.0.9/draw.h b/contrib/other/sdlquake-1.0.9/draw.h new file mode 100644 index 000000000..5055b659c --- /dev/null +++ b/contrib/other/sdlquake-1.0.9/draw.h @@ -0,0 +1,40 @@ +/* +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.h -- these are the only functions outside the refresh allowed +// to touch the vid buffer + +extern qpic_t *draw_disc; // also used on sbar + +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_TileClear (int x, int y, int w, int h); +void Draw_Fill (int x, int y, int w, int h, int c); +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); diff --git a/contrib/other/sdlquake-1.0.9/gas2masm/gas2masm.c b/contrib/other/sdlquake-1.0.9/gas2masm/gas2masm.c new file mode 100644 index 000000000..2e1eb8727 --- /dev/null +++ b/contrib/other/sdlquake-1.0.9/gas2masm/gas2masm.c @@ -0,0 +1,1056 @@ +/* +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. + +*/ +// +// gas to MASM source code converter +// + +#include +#include +#include + +#define MAX_TOKENS 100 +#define MAX_TOKEN_LENGTH 1024 +#define LF 0x0A + +typedef enum {NOT_WHITESPACE, WHITESPACE, TOKEN_AVAILABLE, LINE_DONE, FILE_DONE, PARSED_OKAY} tokenstat; +typedef enum {NOSEG, DATASEG, TEXTSEG} segtype; + +int tokennum; +int inline, outline; + +char *token; +char tokens[MAX_TOKENS][MAX_TOKEN_LENGTH+1]; + +segtype currentseg = NOSEG; + +typedef struct { + char *text; + char *emit; + int numtokens; + void (*parsefunc) (void); +} parsefield; + + +void errorexit (void); + + +//============================================== + +typedef struct { + char *text; + char *emit; + int len; +} regdesc; + +regdesc reglist[] = { + {"%eax", "eax", 4}, + {"%ebx", "ebx", 4}, + {"%ecx", "ecx", 4}, + {"%edx", "edx", 4}, + {"%esi", "esi", 4}, + {"%edi", "edi", 4}, + {"%ebp", "ebp", 4}, + {"%esp", "esp", 4}, + {"%ax", "ax", 3}, + {"%bx", "bx", 3}, + {"%cx", "cx", 3}, + {"%dx", "dx", 3}, + {"%si", "si", 3}, + {"%di", "di", 3}, + {"%bp", "bp", 3}, + {"%sp", "sp", 3}, + {"%al", "al", 3}, + {"%bl", "bl", 3}, + {"%cl", "cl", 3}, + {"%dl", "dl", 3}, + {"%ah", "ah", 3}, + {"%bh", "bh", 3}, + {"%ch", "ch", 3}, + {"%dh", "dh", 3}, + {"%st(0)", "st(0)", 6}, + {"%st(1)", "st(1)", 6}, + {"%st(2)", "st(2)", 6}, + {"%st(3)", "st(3)", 6}, + {"%st(4)", "st(4)", 6}, + {"%st(5)", "st(5)", 6}, + {"%st(6)", "st(6)", 6}, + {"%st(7)", "st(7)", 6}, +}; + +int numregs = sizeof (reglist) / sizeof (reglist[0]); + +//============================================== + + +void emitanoperand (int tnum, char *type, int notdata) +{ + int i, index, something_outside_parens, regfound; + int parencount; + char *pt; + char temp[MAX_TOKEN_LENGTH+1]; + + pt = tokens[tnum]; + + if (pt[0] == '%') + { + // register + for (i=0 ; i '9') || (pt[2] < '0')) + { + i = 2; + printf ("offset "); + + parencount = 1; + + while ((pt[i] != ')') || (parencount > 1)) + { + if (!pt[i]) + { + fprintf (stderr, "mismatched parens"); + errorexit (); + } + + if (pt[i] == ')') + parencount--; + else if (pt[i] == '(') + parencount++; + + printf ("%c", pt[i]); + i++; + } + } + else + { + pt++; + + parencount = 1; + + for (i=1 ; (pt[i] != ')') || (parencount > 1) ; i++) + { + if (!pt[i]) + { + fprintf (stderr, "mismatched parens"); + errorexit (); + } + + if (pt[i] == ')') + parencount--; + else if (pt[i] == '(') + parencount++; + } + + pt[i] = 0; + + if ((pt[1] == '0') && ((pt[2] == 'x') || (pt[2] == 'X'))) + { + printf ("0%sh", &pt[3]); + } + else + { + printf ("%s", &pt[1]); + } + } + } + else if ((pt[1] == '0') && ((pt[2] == 'x') || (pt[2] == 'X'))) + { + printf ("0%sh", &pt[3]); + } + else if ((pt[1] >= '0') && (pt[1] <= '9')) + { + printf ("%s", &pt[1]); + } + else + { + printf ("offset %s", &pt[1]); + } + } + else if (!notdata && ((pt[0] >= '0') && (pt[0] <= '9'))) + { + pt--; + + if ((pt[1] == '0') && ((pt[2] == 'x') || (pt[2] == 'X'))) + { + printf ("0%sh", &pt[3]); + } + else + { + printf ("%s", &pt[1]); + } + } + else + { + // must be a memory location + strcpy (temp, type); + index = strlen (temp); + + if (notdata) + temp[index++] = '['; + + something_outside_parens = 0; + + while (*pt) + { + if (index > (MAX_TOKEN_LENGTH - 10)) + { + fprintf (stderr, "Error: operand too long %s\n", + tokens[tnum]); + errorexit (); + } + + if (*pt != ')') + { + if (*pt == '(') + { + if (something_outside_parens) + temp[index++] = '+'; + } + else if (*pt == '%') + { + regfound = 0; + + for (i=0 ; i= '1') && (*pt <= '8')) + { + temp[index++] = '*'; + temp[index++] = *pt; + } + else if (*pt != ')') + { + if (temp[index-1] != '+') + temp[index++] = '+'; + } + } + else + { + something_outside_parens = 1; + + // handle hexadecimal constants in addresses + if ((*pt == '0') && + ((*(pt+1) == 'x') || (*(pt+1) == 'X'))) + { + pt += 2; + + do + { + temp[index++] = *pt++; + } while (((*pt >= '0') && (*pt <= '9')) || + ((*pt >= 'a') && (*pt <= 'f')) || + ((*pt >= 'A') && (*pt <= 'F'))); + + pt--; + temp[index++] = 'h'; + } + else + { + temp[index++] = *pt; + } + } + } + + pt++; + } + + if (notdata) + temp[index++] = ']'; + + temp[index] = 0; + printf ("%s", temp); + } +} + + +void datasegstart (void) +{ + if (currentseg == DATASEG) + return; + + if (currentseg == TEXTSEG) + printf ("_TEXT ENDS\n"); + + printf ("_DATA SEGMENT"); + + currentseg = DATASEG; +} + + +void textsegstart (void) +{ + if (currentseg == TEXTSEG) + return; + + if (currentseg == DATASEG) + printf ("_DATA ENDS\n"); + + printf ("_TEXT SEGMENT"); + + currentseg = TEXTSEG; +} + + +void emitdata (void) +{ + int i; + + for (i=1 ; i<(tokennum-1) ; i++) + printf (" %s,", tokens[i]); + + printf (" %s", tokens[tokennum-1]); +} + + +void emitonedata (void) +{ + + printf (" %s", tokens[1]); +} + + +void emitonecalldata (void) +{ + int i, isaddr, len; + + if (tokens[1][0] == '*') + { + printf (" dword ptr[%s]", &tokens[1][1]); + } + else + { + isaddr = 0; + len = strlen(tokens[1]); + + for (i=0 ; i 127) || + (c == ',')) + { + return WHITESPACE; + } + + return NOT_WHITESPACE; +} + + +int gettoken (void) +{ + char c; + int count, parencount; + tokenstat stat; + + do + { + if ((c = getchar ()) == EOF) + return FILE_DONE; + + if ((stat = whitespace (c)) == LINE_DONE) + return LINE_DONE; + } while (stat == WHITESPACE); + + token[0] = c; + count = 1; + + if (c == '~') + { + count--; + token[count++] = 'n'; + token[count++] = 'o'; + token[count++] = 't'; + token[count++] = ' '; + } + + if (c == '(') + { + do + { + if ((c = getchar ()) == EOF) + { + fprintf (stderr, "EOF in middle of parentheses\n"); + errorexit (); + } + + token[count++] = c; + + } while (c != ')'); + } + + for ( ;; ) + { + if ((c = getchar ()) == EOF) + { + token[count] = 0; + return TOKEN_AVAILABLE; + } + + if (whitespace (c) == LINE_DONE) + { + if (ungetc (c, stdin) == EOF) + { + fprintf (stderr, "Couldn't unget character\n"); + errorexit (); + } + + token[count] = 0; + return TOKEN_AVAILABLE; + } + + if (whitespace (c) == WHITESPACE) + { + token[count] = 0; + return TOKEN_AVAILABLE; + } + + if (count >= MAX_TOKEN_LENGTH) + { + fprintf (stderr, "Error: token too long\n"); + errorexit (); + } + + token[count++] = c; + + if (c == '~') + { + count--; + token[count++] = 'n'; + token[count++] = 'o'; + token[count++] = 't'; + token[count++] = ' '; + } + else if (c == '(') + { + parencount = 1; + + do + { + if ((c = getchar ()) == EOF) + { + fprintf (stderr, "EOF in middle of parentheses\n"); + errorexit (); + } + + if (c == '(') + parencount++; + else if (c == ')') + parencount--; + + if (c == '~') + { + token[count++] = 'n'; + token[count++] = 'o'; + token[count++] = 't'; + token[count++] = ' '; + } + else + { + token[count++] = c; + } + + } while ((c != ')') || (parencount > 0)); + } + } +} + + +tokenstat parseline (void) +{ + tokenstat stat; + int i, j, firsttoken, labelfound; + int mnemfound; + + firsttoken = 1; + tokennum = 0; + labelfound = 0; + + for ( ;; ) + { + token = tokens[tokennum]; + stat = gettoken (); + + switch (stat) + { + case FILE_DONE: + return FILE_DONE; + + case LINE_DONE: + if (!firsttoken && tokennum) + { + mnemfound = 0; + + for (i=0 ; i 0) && + (parsedata[i].numtokens != tokennum)) || + ((parsedata[i].numtokens < 0) && + (tokennum < -parsedata[i].numtokens))) + { + fprintf (stderr, "mismatched number of tokens\n"); + + for (j=0 ; j= MAX_TOKENS) + { + fprintf (stderr, "Error: too many tokens\n"); + exit (0); + } + + tokennum++; + + break; + + default: + fprintf (stderr, "Error: unknown tokenstat %d\n", stat); + exit (0); + } + } +} + + +void main (int argc, char **argv) +{ + tokenstat stat; + + printf (" .386P\n" + " .model FLAT\n"); + inline = 1; + outline = 3; + + for ( ;; ) + { + stat = parseline (); + inline++; + + switch (stat) + { + case FILE_DONE: + if (currentseg == TEXTSEG) + printf ("_TEXT ENDS\n"); + else if (currentseg == DATASEG) + printf ("_DATA ENDS\n"); + + printf (" END\n"); + exit (0); + + case PARSED_OKAY: + break; + + default: + fprintf (stderr, "Error: unknown tokenstat %d\n", stat); + exit (0); + } + } +} + diff --git a/contrib/other/sdlquake-1.0.9/gas2masm/gas2masm.dsp b/contrib/other/sdlquake-1.0.9/gas2masm/gas2masm.dsp new file mode 100644 index 000000000..de661a403 --- /dev/null +++ b/contrib/other/sdlquake-1.0.9/gas2masm/gas2masm.dsp @@ -0,0 +1,100 @@ +# Microsoft Developer Studio Project File - Name="gas2masm" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 + +CFG=gas2masm - Win32 Release +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "gas2masm.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "gas2masm.mak" CFG="gas2masm - Win32 Release" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "gas2masm - Win32 Release" (based on "Win32 (x86) Console Application") +!MESSAGE "gas2masm - Win32 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "gas2masm - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir ".\Release" +# PROP BASE Intermediate_Dir ".\Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir ".\Release" +# PROP Intermediate_Dir ".\Release" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /YX /c +# ADD CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /YX /FD /c +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 + +!ELSEIF "$(CFG)" == "gas2masm - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir ".\Debug" +# PROP BASE Intermediate_Dir ".\Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir ".\Debug" +# PROP Intermediate_Dir ".\Debug" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /YX /c +# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /YX /FD /c +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 + +!ENDIF + +# Begin Target + +# Name "gas2masm - Win32 Release" +# Name "gas2masm - Win32 Debug" +# Begin Group "Source Files" + +# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat;for;f90" +# Begin Source File + +SOURCE=.\gas2masm.c +# End Source File +# End Group +# Begin Group "Header Files" + +# PROP Default_Filter "h;hpp;hxx;hm;inl;fi;fd" +# End Group +# Begin Group "Resource Files" + +# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;cnt;rtf;gif;jpg;jpeg;jpe" +# End Group +# End Target +# End Project diff --git a/contrib/other/sdlquake-1.0.9/gas2masm/gas2masm.dsw b/contrib/other/sdlquake-1.0.9/gas2masm/gas2masm.dsw new file mode 100644 index 000000000..b53625424 --- /dev/null +++ b/contrib/other/sdlquake-1.0.9/gas2masm/gas2masm.dsw @@ -0,0 +1,29 @@ +Microsoft Developer Studio Workspace File, Format Version 6.00 +# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! + +############################################################################### + +Project: "gas2masm"=.\gas2masm.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff --git a/contrib/other/sdlquake-1.0.9/gas2masm/gas2masm.mdp b/contrib/other/sdlquake-1.0.9/gas2masm/gas2masm.mdp new file mode 100644 index 000000000..76bfd31c0 Binary files /dev/null and b/contrib/other/sdlquake-1.0.9/gas2masm/gas2masm.mdp differ diff --git a/contrib/other/sdlquake-1.0.9/gas2masm/gas2masm.plg b/contrib/other/sdlquake-1.0.9/gas2masm/gas2masm.plg new file mode 100644 index 000000000..067e7c780 --- /dev/null +++ b/contrib/other/sdlquake-1.0.9/gas2masm/gas2masm.plg @@ -0,0 +1,32 @@ + + +
+

Build Log

+

+--------------------Configuration: gas2masm - Win32 Debug-------------------- +

+

Command Lines

+Creating temporary file "C:\TEMP\RSP730.tmp" with contents +[ +/nologo /MLd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /Fp".\Debug/gas2masm.pch" /YX /Fo".\Debug/" /Fd".\Debug/" /FD /c +"D:\Work\quake source\WinQuake\gas2masm\gas2masm.c" +] +Creating command line "cl.exe @C:\TEMP\RSP730.tmp" +Creating temporary file "C:\TEMP\RSP731.tmp" with contents +[ +kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /incremental:yes /pdb:".\Debug/gas2masm.pdb" /debug /machine:I386 /out:".\Debug/gas2masm.exe" +".\Debug\gas2masm.obj" +] +Creating command line "link.exe @C:\TEMP\RSP731.tmp" +

Output Window

+Compiling... +gas2masm.c +Linking... + + + +

Results

+gas2masm.exe - 0 error(s), 0 warning(s) +
+ + diff --git a/contrib/other/sdlquake-1.0.9/gl_draw.c b/contrib/other/sdlquake-1.0.9/gl_draw.c new file mode 100644 index 000000000..25a800757 --- /dev/null +++ b/contrib/other/sdlquake-1.0.9/gl_draw.c @@ -0,0 +1,1297 @@ +/* +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" + +#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"}; + +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; + +int gl_lightmap_format = 4; +int gl_solid_format = 3; +int gl_alpha_format = 4; + +int gl_filter_min = GL_LINEAR_MIPMAP_NEAREST; +int gl_filter_max = GL_LINEAR; + + +int texels; + +typedef struct +{ + int texnum; + char identifier[64]; + int width, height; + qboolean mipmap; +} gltexture_t; + +#define MAX_GLTEXTURES 1024 +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 _WIN32 + bindTexFunc (GL_TEXTURE_2D, texnum); +#else + glBindTexture(GL_TEXTURE_2D, texnum); +#endif +} + + +/* +============================================================================= + + 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); + } + } +} + +/* +=============== +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); + + // 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); + + // 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 + char_texture = GL_LoadTexture ("charset", 128, 128, draw_chars, false, true); + + start = Hunk_LowMark(); + + cb = (qpic_t *)COM_LoadTempFile ("gfx/conback.lmp"); + if (!cb) + Sys_Error ("Couldn't load gfx/conback.lmp"); + SwapPic (cb); + + // 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 + + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + + gl = (glpic_t *)conback->data; + gl->texnum = GL_LoadTexture ("conback", conback->width, conback->height, ncdata, false, false); + 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) +{ + 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 (); +} + +/* +================ +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) +{ + 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); +} + + +/* +============= +Draw_Pic +============= +*/ +void Draw_Pic (int x, int y, qpic_t *pic) +{ + 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 (); +} + + +/* +============= +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) +{ + 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); + + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + + 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 (); +} + + +/* +================ +Draw_ConsoleBackground + +================ +*/ +void Draw_ConsoleBackground (int lines) +{ + int y = (vid.height * 3) >> 2; + + if (lines > y) + Draw_Pic(0, lines - vid.height, conback); + else + Draw_AlphaPic (0, lines - vid.height, conback, (float)(1.2 * lines)/y); +} + + +/* +============= +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) +{ + 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 (); +} + + +/* +============= +Draw_Fill + +Fills a box of pixels with a single color +============= +*/ +void Draw_Fill (int x, int y, int w, int h, int c) +{ + 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); +} +//============================================================================= + +/* +================ +Draw_FadeScreen + +================ +*/ +void Draw_FadeScreen (void) +{ + 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(); +} + +//============================================================================= + +/* +================ +Draw_BeginDisc + +Draws the little blue disc in the corner of the screen. +Call before beginning any disc IO. +================ +*/ +void Draw_BeginDisc (void) +{ + if (!draw_disc) + return; + glDrawBuffer (GL_FRONT); + Draw_Pic (vid.width - 24, 0, draw_disc); + glDrawBuffer (GL_BACK); +} + + +/* +================ +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) +{ + 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); +} + +//==================================================================== + +/* +================ +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) +{ + int samples; +static unsigned scaled[1024*512]; // [512*256]; + int scaled_width, scaled_height; + + for (scaled_width = 1 ; scaled_width < width ; scaled_width<<=1) + ; + for (scaled_height = 1 ; scaled_height < height ; scaled_height<<=1) + ; + + 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); + 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, samples, scaled_width, scaled_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, scaled); + } + } +done: ; +#endif + + + 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); + } +} + +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); + } +} + +/* +=============== +GL_Upload8 +=============== +*/ +void GL_Upload8 (byte *data, int width, int height, qboolean mipmap, qboolean alpha) +{ +static unsigned trans[640*480]; // FIXME, temporary + int i, s; + qboolean noalpha; + int p; + + 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 ; iidentifier)) + { + if (width != glt->width || height != glt->height) + Sys_Error ("GL_LoadTexture: cache mismatch"); + return gltextures[i].texnum; + } + } + } + else { + 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; +} + +/* +================ +GL_LoadPicTexture +================ +*/ +int GL_LoadPicTexture (qpic_t *pic) +{ + return GL_LoadTexture ("", pic->width, pic->height, pic->data, false, true); +} + +/****************************************/ + +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; +} diff --git a/contrib/other/sdlquake-1.0.9/gl_mesh.c b/contrib/other/sdlquake-1.0.9/gl_mesh.c new file mode 100644 index 000000000..100c6628d --- /dev/null +++ b/contrib/other/sdlquake-1.0.9/gl_mesh.c @@ -0,0 +1,360 @@ +/* +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); + + // + // 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); + } + } + + + // 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; + + 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); + + + if (!Q_strncmp(mt->name,"sky",3)) + R_InitSky (tx); + else + { + texture_mode = GL_LINEAR_MIPMAP_NEAREST; //_LINEAR; + tx->gl_texturenum = GL_LoadTexture (mt->name, tx->width, tx->height, (byte *)(tx+1), true, false); + 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 +================= +*/ +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); +} + + +/* +================= +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 +================= +*/ +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); +} + + +/* +================= +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 + out->samples = loadmodel->lightdata + i; + + // 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); + if (i != BSPVERSION) + Sys_Error ("Mod_LoadBrushModel: %s has wrong version number (%i should be %i)", mod->name, i, BSPVERSION); + +// 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; + } + } +} + +/* +============================================================================== + +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 *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]; + } + + 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]; + } + + 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; + char name[32]; + 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); + 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); + 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); + pheader->gl_texturenum[i][j&3] = + GL_LoadTexture (name, pheader->skinwidth, + pheader->skinheight, (byte *)(pskintype), true, false); + 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]; + + 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; + +// FIXME: do this right + mod->mins[0] = mod->mins[1] = mod->mins[2] = -16; + mod->maxs[0] = mod->maxs[1] = mod->maxs[2] = 16; + + // + // build the draw lists + // + GL_MakeAliasModelDisplayLists (mod, pheader); + +// +// 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]; + + 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); + + 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/contrib/other/sdlquake-1.0.9/gl_model.h b/contrib/other/sdlquake-1.0.9/gl_model.h new file mode 100644 index 000000000..ae576b88e --- /dev/null +++ b/contrib/other/sdlquake-1.0.9/gl_model.h @@ -0,0 +1,430 @@ +/* +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. + +*/ + +#ifndef __MODEL__ +#define __MODEL__ + +#include "modelgen.h" +#include "spritegn.h" + +/* + +d*_t structures are on-disk representations +m*_t structures are in-memory + +*/ + +// entity effects + +#define EF_BRIGHTFIELD 1 +#define EF_MUZZLEFLASH 2 +#define EF_BRIGHTLIGHT 4 +#define EF_DIMLIGHT 8 + + +/* +============================================================================== + +BRUSH MODELS + +============================================================================== +*/ + + +// +// in memory representation +// +// !!! if this is changed, it must be changed in asm_draw.h too !!! +typedef struct +{ + vec3_t position; +} mvertex_t; + +#define SIDE_FRONT 0 +#define SIDE_BACK 1 +#define SIDE_ON 2 + + +// plane_t structure +// !!! if this is changed, it must be changed in asm_i386.h too !!! +typedef struct mplane_s +{ + vec3_t normal; + float dist; + byte type; // for texture axis selection and fast side tests + byte signbits; // signx + signy<<1 + signz<<1 + byte pad[2]; +} mplane_t; + +typedef struct texture_s +{ + char name[16]; + unsigned width, height; + int gl_texturenum; + 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 +} texture_t; + + +#define SURF_PLANEBACK 2 +#define SURF_DRAWSKY 4 +#define SURF_DRAWSPRITE 8 +#define SURF_DRAWTURB 0x10 +#define SURF_DRAWTILED 0x20 +#define SURF_DRAWBACKGROUND 0x40 +#define SURF_UNDERWATER 0x80 + +// !!! if this is changed, it must be changed in asm_draw.h too !!! +typedef struct +{ + unsigned short v[2]; + unsigned int cachededgeoffset; +} medge_t; + +typedef struct +{ + float vecs[2][4]; + float mipadjust; + texture_t *texture; + int flags; +} mtexinfo_t; + +#define VERTEXSIZE 7 + +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 + + 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]; + + int light_s, light_t; // gl lightmap coordinates + + glpoly_t *polys; // multiple if warped + struct msurface_s *texturechain; + + mtexinfo_t *texinfo; + +// lighting info + int dlightframe; + int dlightbits; + + 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] +} msurface_t; + +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]; + + unsigned short firstsurface; + unsigned short numsurfaces; +} mnode_t; + + + +typedef struct mleaf_s +{ +// common with node + int contents; // wil be a negative contents number + int visframe; // node needs to be traversed if current + + float minmaxs[6]; // for bounding box culling + + struct mnode_s *parent; + +// leaf specific + byte *compressed_vis; + efrag_t *efrags; + + msurface_t **firstmarksurface; + int nummarksurfaces; + int key; // BSP sequence number for leaf's contents + byte ambient_sound_level[NUM_AMBIENTS]; +} mleaf_t; + +// !!! if this is changed, it must be changed in asm_i386.h too !!! +typedef struct +{ + dclipnode_t *clipnodes; + mplane_t *planes; + int firstclipnode; + int lastclipnode; + vec3_t clip_mins; + vec3_t clip_maxs; +} hull_t; + +/* +============================================================================== + +SPRITE MODELS + +============================================================================== +*/ + + +// FIXME: shorten these? +typedef struct mspriteframe_s +{ + int width; + int height; + float up, down, left, right; + int gl_texturenum; +} mspriteframe_t; + +typedef struct +{ + int numframes; + float *intervals; + mspriteframe_t *frames[1]; +} mspritegroup_t; + +typedef struct +{ + spriteframetype_t type; + mspriteframe_t *frameptr; +} mspriteframedesc_t; + +typedef struct +{ + int type; + int maxwidth; + int maxheight; + int numframes; + float beamlength; // remove? + void *cachespot; // remove? + mspriteframedesc_t frames[1]; +} msprite_t; + + +/* +============================================================================== + +ALIAS MODELS + +Alias models are position independent, so the cache manager can move them. +============================================================================== +*/ + +typedef struct +{ + int firstpose; + int numposes; + float interval; + trivertx_t bboxmin; + trivertx_t bboxmax; + int frame; + char name[16]; +} maliasframedesc_t; + +typedef struct +{ + trivertx_t bboxmin; + trivertx_t bboxmax; + int frame; +} maliasgroupframedesc_t; + +typedef struct +{ + int numframes; + int intervals; + maliasgroupframedesc_t frames[1]; +} maliasgroup_t; + +// !!! if this is changed, it must be changed in asm_draw.h too !!! +typedef struct mtriangle_s { + int facesfront; + int vertindex[3]; +} mtriangle_t; + + +#define MAX_SKINS 32 +typedef struct { + int ident; + int version; + vec3_t scale; + vec3_t scale_origin; + float boundingradius; + vec3_t eyeposition; + int numskins; + int skinwidth; + int skinheight; + int numverts; + int numtris; + int numframes; + synctype_t synctype; + int flags; + float size; + + 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]; + int texels[MAX_SKINS]; // only for player skins + maliasframedesc_t frames[1]; // variable sized +} aliashdr_t; + +#define MAXALIASVERTS 1024 +#define MAXALIASFRAMES 256 +#define MAXALIASTRIS 2048 +extern aliashdr_t *pheader; +extern stvert_t stverts[MAXALIASVERTS]; +extern mtriangle_t triangles[MAXALIASTRIS]; +extern trivertx_t *poseverts[MAXALIASFRAMES]; + +//=================================================================== + +// +// Whole model +// + +typedef enum {mod_brush, mod_sprite, mod_alias} modtype_t; + +#define EF_ROCKET 1 // leave a trail +#define EF_GRENADE 2 // leave a trail +#define EF_GIB 4 // leave a trail +#define EF_ROTATE 8 // rotate (bonus items) +#define EF_TRACER 16 // green split trail +#define EF_ZOMGIB 32 // small blood trail +#define EF_TRACER2 64 // orange split trail + rotate +#define EF_TRACER3 128 // purple trail + +typedef struct model_s +{ + char name[MAX_QPATH]; + qboolean needload; // bmodels and sprites don't cache normally + + modtype_t type; + int numframes; + synctype_t synctype; + + int flags; + +// +// volume occupied by the model graphics +// + vec3_t mins, maxs; + float radius; + +// +// solid volume for clipping +// + qboolean clipbox; + vec3_t clipmins, clipmaxs; + +// +// brush model +// + int firstmodelsurface, nummodelsurfaces; + + int numsubmodels; + dmodel_t *submodels; + + int numplanes; + mplane_t *planes; + + int numleafs; // number of visible leafs, not counting 0 + mleaf_t *leafs; + + int numvertexes; + mvertex_t *vertexes; + + int numedges; + medge_t *edges; + + int numnodes; + mnode_t *nodes; + + int numtexinfo; + mtexinfo_t *texinfo; + + int numsurfaces; + msurface_t *surfaces; + + int numsurfedges; + int *surfedges; + + int numclipnodes; + dclipnode_t *clipnodes; + + int nummarksurfaces; + msurface_t **marksurfaces; + + hull_t hulls[MAX_MAP_HULLS]; + + int numtextures; + texture_t **textures; + + byte *visdata; + byte *lightdata; + char *entities; + +// +// additional model data +// + cache_user_t cache; // only access through Mod_Extradata + +} model_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); + +mleaf_t *Mod_PointInLeaf (float *p, model_t *model); +byte *Mod_LeafPVS (mleaf_t *leaf, model_t *model); + +#endif // __MODEL__ diff --git a/contrib/other/sdlquake-1.0.9/gl_refrag.c b/contrib/other/sdlquake-1.0.9/gl_refrag.c new file mode 100644 index 000000000..1b060b359 --- /dev/null +++ b/contrib/other/sdlquake-1.0.9/gl_refrag.c @@ -0,0 +1,234 @@ +/* +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_efrag.c + +#include "quakedef.h" + +mnode_t *r_pefragtopnode; + + +//=========================================================================== + +/* +=============================================================================== + + ENTITY FRAGMENT FUNCTIONS + +=============================================================================== +*/ + +efrag_t **lastlink; + +vec3_t r_emins, r_emaxs; + +entity_t *r_addent; + + +/* +================ +R_RemoveEfrags + +Call when removing an object from the world or moving it to another position +================ +*/ +void R_RemoveEfrags (entity_t *ent) +{ + efrag_t *ef, *old, *walk, **prev; + + ef = ent->efrag; + + while (ef) + { + 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; + + // put it on the free list + old->entnext = cl.free_efrags; + cl.free_efrags = old; + } + + ent->efrag = NULL; +} + +/* +=================== +R_SplitEntityOnNode +=================== +*/ +void R_SplitEntityOnNode (mnode_t *node) +{ + efrag_t *ef; + 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) + { + if (!r_pefragtopnode) + r_pefragtopnode = 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->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 + // if this is the first splitter of this bmodel, remember it + 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_AddEfrags +=========== +*/ +void R_AddEfrags (entity_t *ent) +{ + model_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++) + { + r_emins[i] = ent->origin[i] + entmodel->mins[i]; + r_emaxs[i] = ent->origin[i] + entmodel->maxs[i]; + } + + R_SplitEntityOnNode (cl.worldmodel->nodes); + + ent->topnode = r_pefragtopnode; +} + + +/* +================ +R_StoreEfrags + +// FIXME: a lot of this goes away with edge-based +================ +*/ +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) + { + 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); + } + } +} + + diff --git a/contrib/other/sdlquake-1.0.9/gl_rlight.c b/contrib/other/sdlquake-1.0.9/gl_rlight.c new file mode 100644 index 000000000..80ada45f4 --- /dev/null +++ b/contrib/other/sdlquake-1.0.9/gl_rlight.c @@ -0,0 +1,354 @@ +/* +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_light.c + +#include "quakedef.h" + +int r_dlightframecount; + + +/* +================== +R_AnimateLight +================== +*/ +void R_AnimateLight (void) +{ + int i,j,k; + +// +// light animations +// 'm' is normal light, 'a' is no light, 'z' is double bright + i = (int)(cl.time*10); + for (j=0 ; jradius * 0.35; + + VectorSubtract (light->origin, r_origin, v); + if (Length (v) < rad) + { // view is inside the dlight + AddLightBlend (1, 0.5, 0, light->radius * 0.0003); + return; + } + + glBegin (GL_TRIANGLE_FAN); + glColor3f (0.2,0.1,0.0); + for (i=0 ; i<3 ; i++) + v[i] = light->origin[i] - vpn[i]*rad; + glVertex3fv (v); + glColor3f (0,0,0); + for (i=16 ; i>=0 ; i--) + { + a = i/16.0 * M_PI*2; + for (j=0 ; j<3 ; j++) + v[j] = light->origin[j] + vright[j]*cos(a)*rad + + vup[j]*sin(a)*rad; + glVertex3fv (v); + } + glEnd (); +} + +/* +============= +R_RenderDlights +============= +*/ +void R_RenderDlights (void) +{ + int i; + dlight_t *l; + + if (!gl_flashblend.value) + return; + + r_dlightframecount = r_framecount + 1; // because the count hasn't + // advanced yet for this frame + glDepthMask (0); + glDisable (GL_TEXTURE_2D); + glShadeModel (GL_SMOOTH); + glEnable (GL_BLEND); + glBlendFunc (GL_ONE, GL_ONE); + + l = cl_dlights; + for (i=0 ; idie < cl.time || !l->radius) + continue; + R_RenderDlight (l); + } + + glColor3f (1,1,1); + glDisable (GL_BLEND); + glEnable (GL_TEXTURE_2D); + glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glDepthMask (1); +} + + +/* +============================================================================= + +DYNAMIC LIGHTS + +============================================================================= +*/ + +/* +============= +R_MarkLights +============= +*/ +void R_MarkLights (dlight_t *light, int bit, mnode_t *node) +{ + mplane_t *splitplane; + float dist; + msurface_t *surf; + int i; + + if (node->contents < 0) + return; + + splitplane = node->plane; + dist = DotProduct (light->origin, splitplane->normal) - splitplane->dist; + + if (dist > light->radius) + { + R_MarkLights (light, bit, node->children[0]); + return; + } + if (dist < -light->radius) + { + R_MarkLights (light, bit, node->children[1]); + return; + } + +// mark the polygons + surf = cl.worldmodel->surfaces + node->firstsurface; + for (i=0 ; inumsurfaces ; i++, surf++) + { + if (surf->dlightframe != r_dlightframecount) + { + surf->dlightbits = 0; + surf->dlightframe = r_dlightframecount; + } + surf->dlightbits |= bit; + } + + R_MarkLights (light, bit, node->children[0]); + R_MarkLights (light, bit, node->children[1]); +} + + +/* +============= +R_PushDlights +============= +*/ +void R_PushDlights (void) +{ + int i; + dlight_t *l; + + if (gl_flashblend.value) + return; + + r_dlightframecount = r_framecount + 1; // because the count hasn't + // advanced yet for this frame + l = cl_dlights; + + for (i=0 ; idie < cl.time || !l->radius) + continue; + R_MarkLights ( l, 1<nodes ); + } +} + + +/* +============================================================================= + +LIGHT SAMPLING + +============================================================================= +*/ + +mplane_t *lightplane; +vec3_t lightspot; + +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); +} + +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; +} + diff --git a/contrib/other/sdlquake-1.0.9/gl_rmain.c b/contrib/other/sdlquake-1.0.9/gl_rmain.c new file mode 100644 index 000000000..d9bf41eb5 --- /dev/null +++ b/contrib/other/sdlquake-1.0.9/gl_rmain.c @@ -0,0 +1,1159 @@ +/* +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" + +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; // little dot for particles +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 + + +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"}; +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"}; + +cvar_t gl_finish = {"gl_finish","0"}; +cvar_t gl_clear = {"gl_clear","0"}; +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"}; +cvar_t gl_flashblend = {"gl_flashblend","1"}; +cvar_t gl_playermip = {"gl_playermip","0"}; +cvar_t gl_nocolors = {"gl_nocolors","0"}; +cvar_t gl_keeptjunctions = {"gl_keeptjunctions","0"}; +cvar_t gl_reporttjunctions = {"gl_reporttjunctions","0"}; +cvar_t gl_doubleeyes = {"gl_doubleeys", "1"}; + +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) +{ + 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); +} + +/* +============================================================= + + 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) +{ + 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); + + GL_DisableMultitexture(); + + 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); +} + +/* +============================================================= + + ALIAS MODELS + +============================================================= +*/ + + +#define NUMVERTEXNORMALS 162 + +float r_avertexnormals[NUMVERTEXNORMALS][3] = { +#include "anorms.h" +}; + +vec3_t shadevector; +float shadelight, ambientlight; + +// 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]; + +int lastposenum; + +/* +============= +GL_DrawAliasFrame +============= +*/ +void GL_DrawAliasFrame (aliashdr_t *paliashdr, int posenum) +{ + 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; + +lastposenum = posenum; + + verts = (trivertx_t *)((byte *)paliashdr + paliashdr->posedata); + verts += posenum * paliashdr->poseverts; + order = (int *)((byte *)paliashdr + paliashdr->commands); + + 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 + l = shadedots[verts->lightnormalindex] * shadelight; + glColor3f (l, l, l); + glVertex3f (verts->v[0], verts->v[1], verts->v[2]); + verts++; + } while (--count); + + glEnd (); + } +} + + +/* +============= +GL_DrawAliasShadow +============= +*/ +extern vec3_t lightspot; + +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 (); + } +} + + + +/* +================= +R_SetupAliasFrame + +================= +*/ +void R_SetupAliasFrame (int frame, aliashdr_t *paliashdr) +{ + 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); +} + + + +/* +================= +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; + + 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 + // + + ambientlight = shadelight = R_LightPoint (currententity->origin); + + // allways give the gun some light + if (e == &cl.viewent && ambientlight < 24) + ambientlight = shadelight = 24; + + for (lnum=0 ; lnum= cl.time) + { + VectorSubtract (currententity->origin, + cl_dlights[lnum].origin, + dist); + add = cl_dlights[lnum].radius - Length(dist); + + if (add > 0) { + ambientlight += add; + //ZOID models should be affected by dlights as well + shadelight += add; + } + } + } + + // clamp lighting so it doesn't overbright as much + if (ambientlight > 128) + ambientlight = 128; + if (ambientlight + shadelight > 192) + shadelight = 192 - ambientlight; + + // 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") */) + if (ambientlight < 8) + ambientlight = shadelight = 8; + + // HACK HACK HACK -- no fullbright colors, so make torches full light + if (!strcmp (clmodel->name, "progs/flame2.mdl") + || !strcmp (clmodel->name, "progs/flame.mdl") ) + ambientlight = shadelight = 256; + + shadedots = r_avertexnormal_dots[((int)(e->angles[1] * (SHADEDOT_QUANT / 360.0))) & (SHADEDOT_QUANT - 1)]; + shadelight = shadelight / 200.0; + + an = e->angles[1]/180*M_PI; + shadevector[0] = cos(-an); + shadevector[1] = sin(-an); + shadevector[2] = 1; + VectorNormalize (shadevector); + + // + // locate the proper data + // + paliashdr = (aliashdr_t *)Mod_Extradata (currententity->model); + + c_alias_polys += paliashdr->numtris; + + // + // draw all the triangles + // + + GL_DisableMultitexture(); + + 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); + + 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 (); + + 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 (); + } + +} + +//================================================================================== + +/* +============= +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) +{ + float ambient[4], diffuse[4]; + int j; + int lnum; + vec3_t dist; + float add; + dlight_t *dl; + int ambientlight, shadelight; + + if (!r_drawviewmodel.value) + return; + + if (chase_active.value) + return; + + 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; + + j = R_LightPoint (currententity->origin); + + if (j < 24) + j = 24; // allways give some light on gun + ambientlight = j; + shadelight = j; + +// 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; + } + + ambient[0] = ambient[1] = ambient[2] = ambient[3] = (float)ambientlight / 128; + diffuse[0] = diffuse[1] = diffuse[2] = diffuse[3] = (float)shadelight / 128; + + // 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); +} + + +/* +============ +R_PolyBlend +============ +*/ +void R_PolyBlend (void) +{ + if (!gl_polyblend.value) + return; + if (!v_blend[3]) + return; + + GL_DisableMultitexture(); + + 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); +} + + +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; + +} + + +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 ); +} + + +/* +============= +R_SetupGL +============= +*/ +void R_SetupGL (void) +{ + float screenaspect; + float yfov; + int i; + extern int glwidth, glheight; + int x, x2, y2, y, w, h; + + // + // set up viewpoint + // + glMatrixMode(GL_PROJECTION); + glLoadIdentity (); + 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; + + // 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); + screenaspect = (float)r_refdef.vrect.width/r_refdef.vrect.height; +// yfov = 2*atan((float)r_refdef.vrect.height/r_refdef.vrect.width)*180/M_PI; + MYgluPerspective (r_refdef.fov_y, screenaspect, 4, 4096); + + 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); +} + +/* +================ +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 (); + + GL_DisableMultitexture(); + + R_RenderDlights (); + + R_DrawParticles (); + +#ifdef GLTEST + Test_Draw (); +#endif + +} + + +/* +============= +R_Clear +============= +*/ +void R_Clear (void) +{ + 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); +} + +/* +============= +R_Mirror +============= +*/ +void R_Mirror (void) +{ + 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); +} + +/* +================ +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) + { + glFinish (); + time1 = Sys_FloatTime (); + c_brush_polys = 0; + c_alias_polys = 0; + } + + mirror = false; + + if (gl_finish.value) + glFinish (); + + 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); +********************************************/ + + R_RenderScene (); + R_DrawViewModel (); + R_DrawWaterSurfaces (); + +// More fog right here :) +// glDisable(GL_FOG); +// End of all fog code... + + // render mirror view + R_Mirror (); + + R_PolyBlend (); + + 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/contrib/other/sdlquake-1.0.9/gl_rmisc.c b/contrib/other/sdlquake-1.0.9/gl_rmisc.c new file mode 100644 index 000000000..c9719b52d --- /dev/null +++ b/contrib/other/sdlquake-1.0.9/gl_rmisc.c @@ -0,0 +1,455 @@ +/* +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}, +}; +void R_InitParticleTexture (void) +{ + int x,y; + byte data[8][8][4]; + + // + // particle texture + // + particletexture = texture_extension_number++; + GL_Bind(particletexture); + + 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); +} + +/* +=============== +R_Envmap_f + +Grab six views for environment mapping tests +=============== +*/ +void R_Envmap_f (void) +{ + 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 (); +} + +/* +=============== +R_Init +=============== +*/ +void R_Init (void) +{ + extern byte *hunk_base; + extern cvar_t 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); + Cvar_RegisterVariable (&r_mirroralpha); + Cvar_RegisterVariable (&r_wateralpha); + Cvar_RegisterVariable (&r_dynamic); + Cvar_RegisterVariable (&r_novis); + Cvar_RegisterVariable (&r_speeds); + + Cvar_RegisterVariable (&gl_finish); + Cvar_RegisterVariable (&gl_clear); + Cvar_RegisterVariable (&gl_texsort); + + if (gl_mtexable) + Cvar_SetValue ("gl_texsort", 0.0); + + 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); + + Cvar_RegisterVariable (&gl_keeptjunctions); + Cvar_RegisterVariable (&gl_reporttjunctions); + + Cvar_RegisterVariable (&gl_doubleeyes); + + 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; + + GL_DisableMultitexture(); + + 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; + + // 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; + + 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; + } + + 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 + +} + + +/* +=============== +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 + R_LoadSkys (); +#endif +} + + +/* +==================== +R_TimeRefresh_f + +For program optimization +==================== +*/ +void R_TimeRefresh_f (void) +{ + 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 (); +} + +void D_FlushCaches (void) +{ +} + + diff --git a/contrib/other/sdlquake-1.0.9/gl_rsurf.c b/contrib/other/sdlquake-1.0.9/gl_rsurf.c new file mode 100644 index 000000000..11b5a01a2 --- /dev/null +++ b/contrib/other/sdlquake-1.0.9/gl_rsurf.c @@ -0,0 +1,1694 @@ +/* +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 + + +int lightmap_bytes; // 1, 2, or 4 + +int lightmap_textures; + +unsigned blocklights[18*18]; + +#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; + + smax = (surf->extents[0]>>4)+1; + tmax = (surf->extents[1]>>4)+1; + tex = surf->texinfo; + + for (lnum=0 ; lnumdlightbits & (1<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]; + + for (t = 0 ; t td) + dist = sd + (td>>1); + else + dist = td + (sd>>1); + if (dist < minlight) + blocklights[t*smax + s] += (rad - dist)*256; + } + } + } +} + + +/* +=============== +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; + int i, j, size; + byte *lightmap; + unsigned scale; + int maps; + int lightadj[4]; + 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; + +// set to full bright if no light data + if (r_fullbright.value || !cl.worldmodel->lightdata) + { + for (i=0 ; istyles[maps] != 255 ; + maps++) + { + scale = d_lightstylevalue[surf->styles[maps]]; + surf->cached_light[maps] = scale; // 8.8 fraction + for (i=0 ; idlightframe == r_framecount) + R_AddDynamicLights (surf); + +// bound, invert, and shift +store: + switch (gl_lightmap_format) + { + case GL_RGBA: + stride -= (smax<<2); + bl = blocklights; + for (i=0 ; i>= 7; + if (t > 255) + t = 255; + dest[3] = 255-t; + dest += 4; + } + } + break; + case GL_ALPHA: + case GL_LUMINANCE: + case GL_INTENSITY: + bl = blocklights; + for (i=0 ; i>= 7; + 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); + +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; + } +} + +#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) ) ) + { + 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) +{ + 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) ) ) + { + R_RenderDynamicLightmaps (s); + if (gl_mtexable) { + 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 { + 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_DisableMultitexture(); + GL_Bind (s->texinfo->texture->gl_texturenum); + EmitWaterPolys (s); + return; + } + + // + // subdivided sky warp + // + if (s->flags & SURF_DRAWSKY) + { + GL_DisableMultitexture(); + 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) { + 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 { + 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); + } +} +#endif + + +/* +================ +DrawGLWaterPoly + +Warp the vertex coordinates +================ +*/ +void DrawGLWaterPoly (glpoly_t *p) +{ + int i; + float *v; + float s, t, os, ot; + vec3_t nv; + + GL_DisableMultitexture(); + + glBegin (GL_TRIANGLE_FAN); + v = p->verts[0]; + for (i=0 ; inumverts ; i++, v+= VERTEXSIZE) + { + glTexCoord2f (v[3], v[4]); + + 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 (); +} + +void DrawGLWaterPolyLightmap (glpoly_t *p) +{ + int i; + float *v; + float s, t, os, ot; + vec3_t nv; + + GL_DisableMultitexture(); + + glBegin (GL_TRIANGLE_FAN); + v = p->verts[0]; + for (i=0 ; inumverts ; i++, v+= VERTEXSIZE) + { + glTexCoord2f (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 (); +} + +/* +================ +DrawGLPoly +================ +*/ +void DrawGLPoly (glpoly_t *p) +{ + 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 (); +} + + +/* +================ +R_BlendLightmaps +================ +*/ +void R_BlendLightmaps (void) +{ + int i, j; + glpoly_t *p; + float *v; + glRect_t *theRect; + + if (r_fullbright.value) + return; + 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); + } + + 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); + } + + glDepthMask (1); // back to normal Z buffering +} + +/* +================ +R_RenderBrushPoly +================ +*/ +void R_RenderBrushPoly (msurface_t *fa) +{ + 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; + } + + if (fa->flags & SURF_UNDERWATER) + DrawGLWaterPoly (fa->polys); + else + DrawGLPoly (fa->polys); + + // add the poly to the proper lightmap chain + + fa->polys->chain = lightmap_polys[fa->lightmaptexturenum]; + lightmap_polys[fa->lightmaptexturenum] = 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) + { + 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_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; + + // 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) +{ + 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 + +/* +================ +DrawTextureChains +================ +*/ +void DrawTextureChains (void) +{ + int i; + msurface_t *s; + texture_t *t; + + if (!gl_texsort.value) { + GL_DisableMultitexture(); + + 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) + { + for (k=0 ; knodes + clmodel->hulls[0].firstclipnode); + } + } + + 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 (); + + glPopMatrix (); +} + +/* +============================================================= + + 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 + 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 + R_ClearSkyBox (); +#endif + + R_RecursiveWorldNode (cl.worldmodel->nodes); + + DrawTextureChains (); + + R_BlendLightmaps (); + +#ifdef QUAKE2 + 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 + // + 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; + } + } + } + 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; + } + + gl_lightmap_format = GL_LUMINANCE; + // default differently on the Permedia + if (isPermedia) + gl_lightmap_format = GL_RGBA; + + 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; + } + + 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); + } + } + + if (!gl_texsort.value) + GL_SelectTexture(TEXTURE1_SGIS); + + // + // 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; +} + +/* +================= +SCR_CalcRefdef + +Must be called whenever vid changes +Internal use only +================= +*/ +static void SCR_CalcRefdef (void) +{ + vrect_t vrect; + float size; + int h; + qboolean full = false; + + + scr_fullupdate = 0; // force a background redraw + vid.recalc_refdef = 0; + +// force the status bar to redraw + Sbar_Changed (); + +//======================================== + +// bound viewsize + if (scr_viewsize.value < 30) + Cvar_Set ("viewsize","30"); + if (scr_viewsize.value > 120) + Cvar_Set ("viewsize","120"); + +// bound field of view + if (scr_fov.value < 10) + Cvar_Set ("fov","10"); + if (scr_fov.value > 170) + Cvar_Set ("fov","170"); + +// intermission is always full screen + if (cl.intermission) + size = 120; + else + size = scr_viewsize.value; + + if (size >= 120) + sb_lines = 0; // no status bar at all + else if (size >= 110) + sb_lines = 24; // no inventory + else + sb_lines = 24+16+8; + + if (scr_viewsize.value >= 100.0) { + full = true; + size = 100.0; + } else + size = scr_viewsize.value; + if (cl.intermission) + { + full = true; + size = 100; + sb_lines = 0; + } + size /= 100.0; + + 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; + + r_refdef.fov_x = scr_fov.value; + r_refdef.fov_y = CalcFov (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_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) +{ + + Cvar_RegisterVariable (&scr_fov); + 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); +} + +/* +============== +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 (); + } + 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; +// +// find a file name to save it to +// + strcpy(pcxname,"quake00.tga"); + + for (i=0 ; i<=99 ; i++) + { + pcxname[5] = i/10 + '0'; + pcxname[6] = i%10 + '0'; + 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 PCX 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) { + // left + Draw_TileClear (0, 0, r_refdef.vrect.x, vid.height - sb_lines); + // right + Draw_TileClear (r_refdef.vrect.x + r_refdef.vrect.width, 0, + vid.width - r_refdef.vrect.x + r_refdef.vrect.width, + vid.height - sb_lines); + } + if (r_refdef.vrect.y > 0) { + // top + Draw_TileClear (r_refdef.vrect.x, 0, + r_refdef.vrect.x + 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, + vid.height - sb_lines - + (r_refdef.vrect.height + r_refdef.vrect.y)); + } +} + +/* +================== +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) +{ + static float oldscr_viewsize; + 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 + // + if (oldfov != scr_fov.value) + { + oldfov = scr_fov.value; + vid.recalc_refdef = true; + } + + if (oldscreensize != scr_viewsize.value) + { + oldscreensize = scr_viewsize.value; + vid.recalc_refdef = true; + } + + if (vid.recalc_refdef) + SCR_CalcRefdef (); + +// +// do 3D refresh drawing, and then update the screen +// + SCR_SetUpToDrawConsole (); + + V_RenderView (); + + GL_Set2D (); + + // + // 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) + Draw_Character (scr_vrect.x + scr_vrect.width/2, scr_vrect.y + scr_vrect.height/2, '+'); + + SCR_DrawRam (); + SCR_DrawNet (); + SCR_DrawTurtle (); + SCR_DrawPause (); + SCR_CheckDrawCenterString (); + Sbar_Draw (); + SCR_DrawConsole (); + M_Draw (); + } + + V_UpdatePalette (); + + GL_EndRendering (); +} + diff --git a/contrib/other/sdlquake-1.0.9/gl_test.c b/contrib/other/sdlquake-1.0.9/gl_test.c new file mode 100644 index 000000000..a3b102769 --- /dev/null +++ b/contrib/other/sdlquake-1.0.9/gl_test.c @@ -0,0 +1,182 @@ +/* +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/contrib/other/sdlquake-1.0.9/gl_vidlinux.c b/contrib/other/sdlquake-1.0.9/gl_vidlinux.c new file mode 100644 index 000000000..c29f0423a --- /dev/null +++ b/contrib/other/sdlquake-1.0.9/gl_vidlinux.c @@ -0,0 +1,866 @@ +/* +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 +#include +#include +#include +#include +#include +#include + +#include +#include + +/*#include "vga.h" */ +#include "vgakeyboard.h" +#include "vgamouse.h" + +#include "quakedef.h" +#include "GL/fxmesa.h" + +#define WARP_WIDTH 320 +#define WARP_HEIGHT 200 + +static fxMesaContext fc = NULL; +#define stringify(m) { #m, m } + +unsigned short d_8to16table[256]; +unsigned d_8to24table[256]; +unsigned char d_15to8table[65536]; + +int num_shades=32; + +struct +{ + char *name; + int num; +} mice[] = +{ + stringify(MOUSE_MICROSOFT), + stringify(MOUSE_MOUSESYSTEMS), + stringify(MOUSE_MMSERIES), + stringify(MOUSE_LOGITECH), + stringify(MOUSE_BUSMOUSE), + stringify(MOUSE_PS2), +}; + +static unsigned char scantokey[128]; + +int num_mice = sizeof (mice) / sizeof(mice[0]); + +int d_con_indirect = 0; + +int svgalib_inited=0; +int UseMouse = 1; +int UseKeyboard = 1; + +int mouserate = MOUSE_DEFAULTSAMPLERATE; + +cvar_t vid_mode = {"vid_mode","5",false}; +cvar_t vid_redrawfull = {"vid_redrawfull","0",false}; +cvar_t vid_waitforrefresh = {"vid_waitforrefresh","0",true}; + +char *framebuffer_ptr; + +cvar_t mouse_button_commands[3] = +{ + {"mouse1","+attack"}, + {"mouse2","+strafe"}, + {"mouse3","+forward"}, +}; + +int mouse_buttons; +int mouse_buttonstate; +int mouse_oldbuttonstate; +float mouse_x, mouse_y; +float old_mouse_x, old_mouse_y; +int mx, my; + +cvar_t m_filter = {"m_filter","1"}; + +int scr_width, scr_height; + +/*-----------------------------------------------------------------------*/ + +//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; + +float gldepthmin, gldepthmax; + +cvar_t gl_ztrick = {"gl_ztrick","1"}; + +const char *gl_vendor; +const char *gl_renderer; +const char *gl_version; +const char *gl_extensions; + +void (*qgl3DfxSetPaletteEXT) (GLuint *); +void (*qglColorTableEXT) (int, int, int, int, int, const void *); + +static float vid_gamma = 1.0; + +qboolean is8bit = false; +qboolean isPermedia = false; +qboolean gl_mtexable = false; + +/*-----------------------------------------------------------------------*/ +void D_BeginDirectRect (int x, int y, byte *pbitmap, int width, int height) +{ +} + +void D_EndDirectRect (int x, int y, int width, int height) +{ +} + +int matchmouse(int mouse, char *name) +{ + int i; + for (i=0 ; i> 2)+4; + b = ((i & 0x7C00) >> 7)+4; + pal = (unsigned char *)d_8to24table; + for (v=0,k=0,bestdist=10000*10000; v<256; v++,pal+=4) { + r1 = (int)r - (int)pal[0]; + g1 = (int)g - (int)pal[1]; + b1 = (int)b - (int)pal[2]; + dist = (r1*r1)+(g1*g1)+(b1*b1); + if (dist < bestdist) { + k=v; + bestdist = dist; + } + } + d_15to8table[i]=k; + } +} + +void CheckMultiTextureExtensions(void) +{ + void *prjobj; + + if (strstr(gl_extensions, "GL_SGIS_multitexture ") && !COM_CheckParm("-nomtex")) { + Con_Printf("Found GL_SGIS_multitexture...\n"); + + if ((prjobj = dlopen(NULL, RTLD_LAZY)) == NULL) { + Con_Printf("Unable to open symbol list for main program.\n"); + return; + } + + qglMTexCoord2fSGIS = (void *) dlsym(prjobj, "glMTexCoord2fSGIS"); + qglSelectTextureSGIS = (void *) dlsym(prjobj, "glSelectTextureSGIS"); + + if (qglMTexCoord2fSGIS && qglSelectTextureSGIS) { + Con_Printf("Multitexture extensions found.\n"); + gl_mtexable = true; + } else + Con_Printf("Symbol not found, disabled.\n"); + + dlclose(prjobj); + } +} + +/* +=============== +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); + gl_extensions = glGetString (GL_EXTENSIONS); + Con_Printf ("GL_EXTENSIONS: %s\n", gl_extensions); + +// Con_Printf ("%s %s\n", gl_renderer, gl_version); + + CheckMultiTextureExtensions (); + + glClearColor (1,0,0,0); + glCullFace(GL_FRONT); + glEnable(GL_TEXTURE_2D); + + glEnable(GL_ALPHA_TEST); + glAlphaFunc(GL_GREATER, 0.666); + + 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); +} + +/* +================= +GL_BeginRendering + +================= +*/ +void GL_BeginRendering (int *x, int *y, int *width, int *height) +{ + extern cvar_t gl_clear; + + *x = *y = 0; + *width = scr_width; + *height = scr_height; + +// if (!wglMakeCurrent( maindc, baseRC )) +// Sys_Error ("wglMakeCurrent failed"); + +// glViewport (*x, *y, *width, *height); +} + + +void GL_EndRendering (void) +{ + glFlush(); + fxMesaSwapBuffers(); +} + +void Init_KBD(void) +{ + int i; + + if (COM_CheckParm("-nokbd")) UseKeyboard = 0; + + if (UseKeyboard) + { + for (i=0 ; i<128 ; i++) + scantokey[i] = ' '; + + scantokey[42] = K_SHIFT; + scantokey[54] = K_SHIFT; + scantokey[72] = K_UPARROW; + scantokey[103] = K_UPARROW; + scantokey[80] = K_DOWNARROW; + scantokey[108] = K_DOWNARROW; + scantokey[75] = K_LEFTARROW; + scantokey[105] = K_LEFTARROW; + scantokey[77] = K_RIGHTARROW; + scantokey[106] = K_RIGHTARROW; + scantokey[29] = K_CTRL; + scantokey[97] = K_CTRL; + scantokey[56] = K_ALT; + scantokey[100] = K_ALT; +// scantokey[58] = JK_CAPS; +// scantokey[69] = JK_NUM_LOCK; + scantokey[71] = K_HOME; + scantokey[73] = K_PGUP; + scantokey[79] = K_END; + scantokey[81] = K_PGDN; + scantokey[82] = K_INS; + scantokey[83] = K_DEL; + scantokey[1 ] = K_ESCAPE; + scantokey[28] = K_ENTER; + scantokey[15] = K_TAB; + scantokey[14] = K_BACKSPACE; + scantokey[119] = K_PAUSE; + scantokey[57] = ' '; + + scantokey[102] = K_HOME; + scantokey[104] = K_PGUP; + scantokey[107] = K_END; + scantokey[109] = K_PGDN; + scantokey[110] = K_INS; + scantokey[111] = K_DEL; + + scantokey[2] = '1'; + scantokey[3] = '2'; + scantokey[4] = '3'; + scantokey[5] = '4'; + scantokey[6] = '5'; + scantokey[7] = '6'; + scantokey[8] = '7'; + scantokey[9] = '8'; + scantokey[10] = '9'; + scantokey[11] = '0'; + scantokey[12] = '-'; + scantokey[13] = '='; + scantokey[41] = '`'; + scantokey[26] = '['; + scantokey[27] = ']'; + scantokey[39] = ';'; + scantokey[40] = '\''; + scantokey[51] = ','; + scantokey[52] = '.'; + scantokey[53] = '/'; + scantokey[43] = '\\'; + + scantokey[59] = K_F1; + scantokey[60] = K_F2; + scantokey[61] = K_F3; + scantokey[62] = K_F4; + scantokey[63] = K_F5; + scantokey[64] = K_F6; + scantokey[65] = K_F7; + scantokey[66] = K_F8; + scantokey[67] = K_F9; + scantokey[68] = K_F10; + scantokey[87] = K_F11; + scantokey[88] = K_F12; + scantokey[30] = 'a'; + scantokey[48] = 'b'; + scantokey[46] = 'c'; + scantokey[32] = 'd'; + scantokey[18] = 'e'; + scantokey[33] = 'f'; + scantokey[34] = 'g'; + scantokey[35] = 'h'; + scantokey[23] = 'i'; + scantokey[36] = 'j'; + scantokey[37] = 'k'; + scantokey[38] = 'l'; + scantokey[50] = 'm'; + scantokey[49] = 'n'; + scantokey[24] = 'o'; + scantokey[25] = 'p'; + scantokey[16] = 'q'; + scantokey[19] = 'r'; + scantokey[31] = 's'; + scantokey[20] = 't'; + scantokey[22] = 'u'; + scantokey[47] = 'v'; + scantokey[17] = 'w'; + scantokey[45] = 'x'; + scantokey[21] = 'y'; + scantokey[44] = 'z'; + + scantokey[78] = '+'; + scantokey[74] = '-'; + + if (keyboard_init()) + Sys_Error("keyboard_init() failed"); + keyboard_seteventhandler(keyhandler); + } +} + +#define NUM_RESOLUTIONS 16 + +static int resolutions[NUM_RESOLUTIONS][3]={ + 320,200, GR_RESOLUTION_320x200, + 320,240, GR_RESOLUTION_320x240, + 400,256, GR_RESOLUTION_400x256, + 400,300, GR_RESOLUTION_400x300, + 512,384, GR_RESOLUTION_512x384, + 640,200, GR_RESOLUTION_640x200, + 640,350, GR_RESOLUTION_640x350, + 640,400, GR_RESOLUTION_640x400, + 640,480, GR_RESOLUTION_640x480, + 800,600, GR_RESOLUTION_800x600, + 960,720, GR_RESOLUTION_960x720, + 856,480, GR_RESOLUTION_856x480, + 512,256, GR_RESOLUTION_512x256, + 1024,768, GR_RESOLUTION_1024x768, + 1280,1024,GR_RESOLUTION_1280x1024, + 1600,1200,GR_RESOLUTION_1600x1200 +}; + +int findres(int *width, int *height) +{ + int i; + + for(i=0;i 255) + inf = 255; + palette[i] = inf; + } + + memcpy (pal, palette, sizeof(palette)); +} + +void VID_Init(unsigned char *palette) +{ + int i; + GLint attribs[32]; + char gldir[MAX_OSPATH]; + int width = 640, height = 480; + + Init_KBD(); + + Cvar_RegisterVariable (&vid_mode); + Cvar_RegisterVariable (&vid_redrawfull); + Cvar_RegisterVariable (&vid_waitforrefresh); + Cvar_RegisterVariable (&gl_ztrick); + + vid.maxwarpwidth = WARP_WIDTH; + vid.maxwarpheight = WARP_HEIGHT; + vid.colormap = host_colormap; + vid.fullbright = 256 - LittleLong (*((int *)vid.colormap + 2048)); + +// interpret command-line params + +// set vid parameters + attribs[0] = FXMESA_DOUBLEBUFFER; + attribs[1] = FXMESA_ALPHA_SIZE; + attribs[2] = 1; + attribs[3] = FXMESA_DEPTH_SIZE; + attribs[4] = 1; + attribs[5] = FXMESA_NONE; + + if ((i = COM_CheckParm("-width")) != 0) + width = atoi(com_argv[i+1]); + if ((i = COM_CheckParm("-height")) != 0) + height = atoi(com_argv[i+1]); + + if ((i = COM_CheckParm("-conwidth")) != 0) + vid.conwidth = Q_atoi(com_argv[i+1]); + else + vid.conwidth = 640; + + vid.conwidth &= 0xfff8; // make it a multiple of eight + + if (vid.conwidth < 320) + vid.conwidth = 320; + + // pick a conheight that matches with correct aspect + vid.conheight = vid.conwidth*3 / 4; + + if ((i = COM_CheckParm("-conheight")) != 0) + vid.conheight = Q_atoi(com_argv[i+1]); + if (vid.conheight < 200) + vid.conheight = 200; + + fc = fxMesaCreateContext(0, findres(&width, &height), GR_REFRESH_75Hz, + attribs); + if (!fc) + Sys_Error("Unable to create 3DFX context.\n"); + + InitSig(); // trap evil signals + + scr_width = width; + scr_height = height; + + fxMesaMakeCurrent(fc); + + if (vid.conheight > height) + vid.conheight = height; + if (vid.conwidth > width) + vid.conwidth = width; + vid.width = vid.conwidth; + vid.height = vid.conheight; + + vid.aspect = ((float)vid.height / (float)vid.width) * + (320.0 / 240.0); + vid.numpages = 2; + + GL_Init(); + + sprintf (gldir, "%s/glquake", com_gamedir); + Sys_mkdir (gldir); + + Check_Gamma(palette); + VID_SetPalette(palette); + + // Check for 3DFX Extensions and initialize them. + VID_Init8bitPalette(); + + Con_SafePrintf ("Video mode %dx%d initialized.\n", width, height); + + vid.recalc_refdef = 1; // force a surface cache flush +} + +void Sys_SendKeyEvents(void) +{ + if (UseKeyboard) + while (keyboard_update()); +} + +void Force_CenterView_f (void) +{ + cl.viewangles[PITCH] = 0; +} + + +void mousehandler(int buttonstate, int dx, int dy) +{ + mouse_buttonstate = buttonstate; + mx += dx; + my += dy; +} + +void IN_Init(void) +{ + + int mtype; + char *mousedev; + int mouserate; + + if (UseMouse) + { + + Cvar_RegisterVariable (&mouse_button_commands[0]); + Cvar_RegisterVariable (&mouse_button_commands[1]); + Cvar_RegisterVariable (&mouse_button_commands[2]); + Cmd_AddCommand ("force_centerview", Force_CenterView_f); + + mouse_buttons = 3; + + mtype = vga_getmousetype(); + + mousedev = "/dev/mouse"; + if (getenv("MOUSEDEV")) mousedev = getenv("MOUSEDEV"); + if (COM_CheckParm("-mdev")) + mousedev = com_argv[COM_CheckParm("-mdev")+1]; + + mouserate = 1200; + if (getenv("MOUSERATE")) mouserate = atoi(getenv("MOUSERATE")); + if (COM_CheckParm("-mrate")) + mouserate = atoi(com_argv[COM_CheckParm("-mrate")+1]); + + if (mouse_init(mousedev, mtype, mouserate)) + { + Con_Printf("No mouse found\n"); + UseMouse = 0; + } + else + mouse_seteventhandler(mousehandler); + + } + +} + +void IN_Shutdown(void) +{ + if (UseMouse) + mouse_close(); +} + +/* +=========== +IN_Commands +=========== +*/ +void IN_Commands (void) +{ + if (UseMouse && cls.state != ca_dedicated) + { + // poll mouse values + while (mouse_update()) + ; + + // perform button actions + if ((mouse_buttonstate & MOUSE_LEFTBUTTON) && + !(mouse_oldbuttonstate & MOUSE_LEFTBUTTON)) + Key_Event (K_MOUSE1, true); + else if (!(mouse_buttonstate & MOUSE_LEFTBUTTON) && + (mouse_oldbuttonstate & MOUSE_LEFTBUTTON)) + Key_Event (K_MOUSE1, false); + + if ((mouse_buttonstate & MOUSE_RIGHTBUTTON) && + !(mouse_oldbuttonstate & MOUSE_RIGHTBUTTON)) + Key_Event (K_MOUSE2, true); + else if (!(mouse_buttonstate & MOUSE_RIGHTBUTTON) && + (mouse_oldbuttonstate & MOUSE_RIGHTBUTTON)) + Key_Event (K_MOUSE2, false); + + if ((mouse_buttonstate & MOUSE_MIDDLEBUTTON) && + !(mouse_oldbuttonstate & MOUSE_MIDDLEBUTTON)) + Key_Event (K_MOUSE3, true); + else if (!(mouse_buttonstate & MOUSE_MIDDLEBUTTON) && + (mouse_oldbuttonstate & MOUSE_MIDDLEBUTTON)) + Key_Event (K_MOUSE3, false); + + mouse_oldbuttonstate = mouse_buttonstate; + } +} + +/* +=========== +IN_Move +=========== +*/ +void IN_MouseMove (usercmd_t *cmd) +{ + if (!UseMouse) + return; + + // poll mouse values + while (mouse_update()) + ; + + if (m_filter.value) + { + mouse_x = (mx + old_mouse_x) * 0.5; + mouse_y = (my + old_mouse_y) * 0.5; + } + else + { + mouse_x = mx; + mouse_y = my; + } + old_mouse_x = mx; + old_mouse_y = my; + mx = my = 0; // clear for next update + + mouse_x *= sensitivity.value; + mouse_y *= sensitivity.value; + +// add mouse X/Y movement to cmd + if ( (in_strafe.state & 1) || (lookstrafe.value && (in_mlook.state & 1) )) + cmd->sidemove += m_side.value * mouse_x; + else + cl.viewangles[YAW] -= m_yaw.value * mouse_x; + + if (in_mlook.state & 1) + V_StopPitchDrift (); + + if ( (in_mlook.state & 1) && !(in_strafe.state & 1)) + { + 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; + } +} + +void IN_Move (usercmd_t *cmd) +{ + IN_MouseMove(cmd); +} + + diff --git a/contrib/other/sdlquake-1.0.9/gl_vidlinuxglx.c b/contrib/other/sdlquake-1.0.9/gl_vidlinuxglx.c new file mode 100644 index 000000000..400adb467 --- /dev/null +++ b/contrib/other/sdlquake-1.0.9/gl_vidlinuxglx.c @@ -0,0 +1,997 @@ +/* +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 +#include +#include +#include +#include +#include +#include + +#include + +#include "quakedef.h" + +#include + +#include +#include + +#include +#include + +#define WARP_WIDTH 320 +#define WARP_HEIGHT 200 + +static Display *dpy = NULL; +static int scrnum; +static Window win; +static GLXContext ctx = NULL; + +#define KEY_MASK (KeyPressMask | KeyReleaseMask) +#define MOUSE_MASK (ButtonPressMask | ButtonReleaseMask | \ + PointerMotionMask | ButtonMotionMask ) +#define X_MASK (KEY_MASK | MOUSE_MASK | VisibilityChangeMask | StructureNotifyMask ) + + +unsigned short d_8to16table[256]; +unsigned d_8to24table[256]; +unsigned char d_15to8table[65536]; + +cvar_t vid_mode = {"vid_mode","0",false}; + +static qboolean mouse_avail; +static qboolean mouse_active; +static int mx, my; +static int old_mouse_x, old_mouse_y; + +static cvar_t in_mouse = {"in_mouse", "1", false}; +static cvar_t in_dgamouse = {"in_dgamouse", "1", false}; +static cvar_t m_filter = {"m_filter", "0"}; + +qboolean dgamouse = false; +qboolean vidmode_ext = false; + +static int win_x, win_y; + +static int scr_width, scr_height; + +static XF86VidModeModeInfo **vidmodes; +static int default_dotclock_vidmode; +static int num_vidmodes; +static qboolean vidmode_active = false; + +/*-----------------------------------------------------------------------*/ + +//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; + +float gldepthmin, gldepthmax; + +cvar_t gl_ztrick = {"gl_ztrick","1"}; + +const char *gl_vendor; +const char *gl_renderer; +const char *gl_version; +const char *gl_extensions; + +void (*qglColorTableEXT) (int, int, int, int, int, const void*); +void (*qgl3DfxSetPaletteEXT) (GLuint *); + +static float vid_gamma = 1.0; + +qboolean is8bit = false; +qboolean isPermedia = false; +qboolean gl_mtexable = false; + +/*-----------------------------------------------------------------------*/ +void D_BeginDirectRect (int x, int y, byte *pbitmap, int width, int height) +{ +} + +void D_EndDirectRect (int x, int y, int width, int height) +{ +} + +static int XLateKey(XKeyEvent *ev) +{ + + int key; + char buf[64]; + KeySym keysym; + + key = 0; + + XLookupString(ev, buf, sizeof buf, &keysym, 0); + + switch(keysym) + { + case XK_KP_Page_Up: + case XK_Page_Up: key = K_PGUP; break; + + case XK_KP_Page_Down: + case XK_Page_Down: key = K_PGDN; break; + + case XK_KP_Home: + case XK_Home: key = K_HOME; break; + + case XK_KP_End: + case XK_End: key = K_END; break; + + case XK_KP_Left: + case XK_Left: key = K_LEFTARROW; break; + + case XK_KP_Right: + case XK_Right: key = K_RIGHTARROW; break; + + case XK_KP_Down: + case XK_Down: key = K_DOWNARROW; break; + + case XK_KP_Up: + case XK_Up: key = K_UPARROW; break; + + case XK_Escape: key = K_ESCAPE; break; + + case XK_KP_Enter: + case XK_Return: key = K_ENTER; break; + + case XK_Tab: key = K_TAB; break; + + case XK_F1: key = K_F1; break; + + case XK_F2: key = K_F2; break; + + case XK_F3: key = K_F3; break; + + case XK_F4: key = K_F4; break; + + case XK_F5: key = K_F5; break; + + case XK_F6: key = K_F6; break; + + case XK_F7: key = K_F7; break; + + case XK_F8: key = K_F8; break; + + case XK_F9: key = K_F9; break; + + case XK_F10: key = K_F10; break; + + case XK_F11: key = K_F11; break; + + case XK_F12: key = K_F12; break; + + case XK_BackSpace: key = K_BACKSPACE; break; + + case XK_KP_Delete: + case XK_Delete: key = K_DEL; break; + + case XK_Pause: key = K_PAUSE; break; + + case XK_Shift_L: + case XK_Shift_R: key = K_SHIFT; break; + + case XK_Execute: + case XK_Control_L: + case XK_Control_R: key = K_CTRL; break; + + case XK_Alt_L: + case XK_Meta_L: + case XK_Alt_R: + case XK_Meta_R: key = K_ALT; break; + + case XK_KP_Begin: key = '5'; break; + + case XK_KP_Insert: + case XK_Insert:key = K_INS; break; + + case XK_KP_Multiply: key = '*'; break; + case XK_KP_Add: key = '+'; break; + case XK_KP_Subtract: key = '-'; break; + case XK_KP_Divide: key = '/'; break; + +#if 0 + case 0x021: key = '1';break;/* [!] */ + case 0x040: key = '2';break;/* [@] */ + case 0x023: key = '3';break;/* [#] */ + case 0x024: key = '4';break;/* [$] */ + case 0x025: key = '5';break;/* [%] */ + case 0x05e: key = '6';break;/* [^] */ + case 0x026: key = '7';break;/* [&] */ + case 0x02a: key = '8';break;/* [*] */ + case 0x028: key = '9';;break;/* [(] */ + case 0x029: key = '0';break;/* [)] */ + case 0x05f: key = '-';break;/* [_] */ + case 0x02b: key = '=';break;/* [+] */ + case 0x07c: key = '\'';break;/* [|] */ + case 0x07d: key = '[';break;/* [}] */ + case 0x07b: key = ']';break;/* [{] */ + case 0x022: key = '\'';break;/* ["] */ + case 0x03a: key = ';';break;/* [:] */ + case 0x03f: key = '/';break;/* [?] */ + case 0x03e: key = '.';break;/* [>] */ + case 0x03c: key = ',';break;/* [<] */ +#endif + + default: + key = *(unsigned char*)buf; + if (key >= 'A' && key <= 'Z') + key = key - 'A' + 'a'; + break; + } + + return key; +} + +static Cursor CreateNullCursor(Display *display, Window root) +{ + Pixmap cursormask; + XGCValues xgc; + GC gc; + XColor dummycolour; + Cursor cursor; + + cursormask = XCreatePixmap(display, root, 1, 1, 1/*depth*/); + xgc.function = GXclear; + gc = XCreateGC(display, cursormask, GCFunction, &xgc); + XFillRectangle(display, cursormask, gc, 0, 0, 1, 1); + dummycolour.pixel = 0; + dummycolour.red = 0; + dummycolour.flags = 04; + cursor = XCreatePixmapCursor(display, cursormask, cursormask, + &dummycolour,&dummycolour, 0,0); + XFreePixmap(display,cursormask); + XFreeGC(display,gc); + return cursor; +} + +static void install_grabs(void) +{ + +// inviso cursor + XDefineCursor(dpy, win, CreateNullCursor(dpy, win)); + + XGrabPointer(dpy, win, + True, + 0, + GrabModeAsync, GrabModeAsync, + win, + None, + CurrentTime); + + if (in_dgamouse.value) { + int MajorVersion, MinorVersion; + + if (!XF86DGAQueryVersion(dpy, &MajorVersion, &MinorVersion)) { + // unable to query, probalby not supported + Con_Printf( "Failed to detect XF86DGA Mouse\n" ); + in_dgamouse.value = 0; + } else { + dgamouse = true; + XF86DGADirectVideo(dpy, DefaultScreen(dpy), XF86DGADirectMouse); + XWarpPointer(dpy, None, win, 0, 0, 0, 0, 0, 0); + } + } else { + XWarpPointer(dpy, None, win, + 0, 0, 0, 0, + vid.width / 2, vid.height / 2); + } + + XGrabKeyboard(dpy, win, + False, + GrabModeAsync, GrabModeAsync, + CurrentTime); + + mouse_active = true; + +// XSync(dpy, True); +} + +static void uninstall_grabs(void) +{ + if (!dpy || !win) + return; + + if (dgamouse) { + dgamouse = false; + XF86DGADirectVideo(dpy, DefaultScreen(dpy), 0); + } + + XUngrabPointer(dpy, CurrentTime); + XUngrabKeyboard(dpy, CurrentTime); + +// inviso cursor + XUndefineCursor(dpy, win); + + mouse_active = false; +} + +static void HandleEvents(void) +{ + XEvent event; + KeySym ks; + int b; + qboolean dowarp = false; + int mwx = vid.width/2; + int mwy = vid.height/2; + + if (!dpy) + return; + + while (XPending(dpy)) { + XNextEvent(dpy, &event); + + switch (event.type) { + case KeyPress: + case KeyRelease: + Key_Event(XLateKey(&event.xkey), event.type == KeyPress); + break; + + case MotionNotify: + if (mouse_active) { + if (dgamouse) { + mx += (event.xmotion.x + win_x) * 2; + my += (event.xmotion.y + win_y) * 2; + } + else + { + mx += ((int)event.xmotion.x - mwx) * 2; + my += ((int)event.xmotion.y - mwy) * 2; + mwx = event.xmotion.x; + mwy = event.xmotion.y; + + if (mx || my) + dowarp = true; + } + } + break; + + break; + + case ButtonPress: + b=-1; + if (event.xbutton.button == 1) + b = 0; + else if (event.xbutton.button == 2) + b = 2; + else if (event.xbutton.button == 3) + b = 1; + if (b>=0) + Key_Event(K_MOUSE1 + b, true); + break; + + case ButtonRelease: + b=-1; + if (event.xbutton.button == 1) + b = 0; + else if (event.xbutton.button == 2) + b = 2; + else if (event.xbutton.button == 3) + b = 1; + if (b>=0) + Key_Event(K_MOUSE1 + b, false); + break; + + case CreateNotify : + win_x = event.xcreatewindow.x; + win_y = event.xcreatewindow.y; + break; + + case ConfigureNotify : + win_x = event.xconfigure.x; + win_y = event.xconfigure.y; + break; + } + } + + if (dowarp) { + /* move the mouse to the window center again */ + XWarpPointer(dpy, None, win, 0, 0, 0, 0, vid.width / 2, vid.height / 2); + } + +} + +static void IN_DeactivateMouse( void ) +{ + if (!mouse_avail || !dpy || !win) + return; + + if (mouse_active) { + uninstall_grabs(); + mouse_active = false; + } +} + +static void IN_ActivateMouse( void ) +{ + if (!mouse_avail || !dpy || !win) + return; + + if (!mouse_active) { + mx = my = 0; // don't spazz + install_grabs(); + mouse_active = true; + } +} + + +void VID_Shutdown(void) +{ + if (!ctx || !dpy) + return; + IN_DeactivateMouse(); + if (dpy) { + if (ctx) + glXDestroyContext(dpy, ctx); + if (win) + XDestroyWindow(dpy, win); + if (vidmode_active) + XF86VidModeSwitchToMode(dpy, scrnum, vidmodes[0]); + XCloseDisplay(dpy); + } + vidmode_active = false; + dpy = NULL; + win = 0; + ctx = NULL; +} + +void signal_handler(int sig) +{ + printf("Received signal %d, exiting...\n", sig); + Sys_Quit(); + exit(0); +} + +void InitSig(void) +{ + signal(SIGHUP, signal_handler); + signal(SIGINT, signal_handler); + signal(SIGQUIT, signal_handler); + signal(SIGILL, signal_handler); + signal(SIGTRAP, signal_handler); + signal(SIGIOT, signal_handler); + signal(SIGBUS, signal_handler); + signal(SIGFPE, signal_handler); + signal(SIGSEGV, signal_handler); + signal(SIGTERM, signal_handler); +} + +void VID_ShiftPalette(unsigned char *p) +{ +// VID_SetPalette(p); +} + +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]; + int dist, bestdist; + +// +// 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<<0) + (g<<8) + (b<<16); + *table++ = v; + } + d_8to24table[255] &= 0xffffff; // 255 is transparent + + 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,bestdist=10000*10000; v<256; v++,pal+=4) { + r1 = (int)r - (int)pal[0]; + g1 = (int)g - (int)pal[1]; + b1 = (int)b - (int)pal[2]; + dist = (r1*r1)+(g1*g1)+(b1*b1); + if (dist < bestdist) { + k=v; + bestdist = dist; + } + } + d_15to8table[i]=k; + } +} + +void CheckMultiTextureExtensions(void) +{ + void *prjobj; + + if (strstr(gl_extensions, "GL_SGIS_multitexture ") && !COM_CheckParm("-nomtex")) { + Con_Printf("Found GL_SGIS_multitexture...\n"); + + if ((prjobj = dlopen(NULL, RTLD_LAZY)) == NULL) { + Con_Printf("Unable to open symbol list for main program.\n"); + return; + } + + qglMTexCoord2fSGIS = (void *) dlsym(prjobj, "glMTexCoord2fSGIS"); + qglSelectTextureSGIS = (void *) dlsym(prjobj, "glSelectTextureSGIS"); + + if (qglMTexCoord2fSGIS && qglSelectTextureSGIS) { + Con_Printf("Multitexture extensions found.\n"); + gl_mtexable = true; + } else + Con_Printf("Symbol not found, disabled.\n"); + + dlclose(prjobj); + } +} + +/* +=============== +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); + gl_extensions = glGetString (GL_EXTENSIONS); + Con_Printf ("GL_EXTENSIONS: %s\n", gl_extensions); + +// Con_Printf ("%s %s\n", gl_renderer, gl_version); + + CheckMultiTextureExtensions (); + + glClearColor (1,0,0,0); + glCullFace(GL_FRONT); + glEnable(GL_TEXTURE_2D); + + glEnable(GL_ALPHA_TEST); + glAlphaFunc(GL_GREATER, 0.666); + + 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); +} + +/* +================= +GL_BeginRendering + +================= +*/ +void GL_BeginRendering (int *x, int *y, int *width, int *height) +{ + extern cvar_t gl_clear; + + *x = *y = 0; + *width = scr_width; + *height = scr_height; + +// if (!wglMakeCurrent( maindc, baseRC )) +// Sys_Error ("wglMakeCurrent failed"); + +// glViewport (*x, *y, *width, *height); +} + + +void GL_EndRendering (void) +{ + glFlush(); + glXSwapBuffers(dpy, win); +} + +qboolean VID_Is8bit(void) +{ + return is8bit; +} + +void VID_Init8bitPalette(void) +{ + // Check for 8bit Extensions and initialize them. + int i; + void *prjobj; + + if ((prjobj = dlopen(NULL, RTLD_LAZY)) == NULL) { + Con_Printf("Unable to open symbol list for main program.\n"); + return; + } + + if (strstr(gl_extensions, "3DFX_set_global_palette") && + (qgl3DfxSetPaletteEXT = dlsym(prjobj, "gl3DfxSetPaletteEXT")) != NULL) { + GLubyte table[256][4]; + char *oldpal; + + Con_SafePrintf("8-bit GL extensions enabled.\n"); + glEnable( GL_SHARED_TEXTURE_PALETTE_EXT ); + oldpal = (char *) d_8to24table; //d_8to24table3dfx; + for (i=0;i<256;i++) { + table[i][2] = *oldpal++; + table[i][1] = *oldpal++; + table[i][0] = *oldpal++; + table[i][3] = 255; + oldpal++; + } + qgl3DfxSetPaletteEXT((GLuint *)table); + is8bit = true; + + } else if (strstr(gl_extensions, "GL_EXT_shared_texture_palette") && + (qglColorTableEXT = dlsym(prjobj, "glColorTableEXT")) != NULL) { + char thePalette[256*3]; + char *oldPalette, *newPalette; + + Con_SafePrintf("8-bit GL extensions enabled.\n"); + glEnable( GL_SHARED_TEXTURE_PALETTE_EXT ); + oldPalette = (char *) d_8to24table; //d_8to24table3dfx; + newPalette = thePalette; + for (i=0;i<256;i++) { + *newPalette++ = *oldPalette++; + *newPalette++ = *oldPalette++; + *newPalette++ = *oldPalette++; + oldPalette++; + } + qglColorTableEXT(GL_SHARED_TEXTURE_PALETTE_EXT, GL_RGB, 256, GL_RGB, GL_UNSIGNED_BYTE, (void *) thePalette); + is8bit = true; + } + + dlclose(prjobj); +} + +static void Check_Gamma (unsigned char *pal) +{ + float f, inf; + unsigned char palette[768]; + int i; + + if ((i = COM_CheckParm("-gamma")) == 0) { + if ((gl_renderer && strstr(gl_renderer, "Voodoo")) || + (gl_vendor && strstr(gl_vendor, "3Dfx"))) + vid_gamma = 1; + else + vid_gamma = 0.7; // default to 0.7 on non-3dfx hardware + } else + vid_gamma = Q_atof(com_argv[i+1]); + + for (i=0 ; i<768 ; i++) + { + f = pow ( (pal[i]+1)/256.0 , vid_gamma ); + inf = f*255 + 0.5; + if (inf < 0) + inf = 0; + if (inf > 255) + inf = 255; + palette[i] = inf; + } + + memcpy (pal, palette, sizeof(palette)); +} + +void VID_Init(unsigned char *palette) +{ + int i; + int attrib[] = { + GLX_RGBA, + GLX_RED_SIZE, 1, + GLX_GREEN_SIZE, 1, + GLX_BLUE_SIZE, 1, + GLX_DOUBLEBUFFER, + GLX_DEPTH_SIZE, 1, + None + }; + char gldir[MAX_OSPATH]; + int width = 640, height = 480; + XSetWindowAttributes attr; + unsigned long mask; + Window root; + XVisualInfo *visinfo; + qboolean fullscreen = true; + int MajorVersion, MinorVersion; + int actualWidth, actualHeight; + + Cvar_RegisterVariable (&vid_mode); + Cvar_RegisterVariable (&in_mouse); + Cvar_RegisterVariable (&in_dgamouse); + Cvar_RegisterVariable (&m_filter); + Cvar_RegisterVariable (&gl_ztrick); + + vid.maxwarpwidth = WARP_WIDTH; + vid.maxwarpheight = WARP_HEIGHT; + vid.colormap = host_colormap; + vid.fullbright = 256 - LittleLong (*((int *)vid.colormap + 2048)); + +// interpret command-line params + +// set vid parameters + if ((i = COM_CheckParm("-window")) != 0) + fullscreen = false; + + if ((i = COM_CheckParm("-width")) != 0) + width = atoi(com_argv[i+1]); + + if ((i = COM_CheckParm("-height")) != 0) + height = atoi(com_argv[i+1]); + + if ((i = COM_CheckParm("-conwidth")) != 0) + vid.conwidth = Q_atoi(com_argv[i+1]); + else + vid.conwidth = 640; + + vid.conwidth &= 0xfff8; // make it a multiple of eight + + if (vid.conwidth < 320) + vid.conwidth = 320; + + // pick a conheight that matches with correct aspect + vid.conheight = vid.conwidth*3 / 4; + + if ((i = COM_CheckParm("-conheight")) != 0) + vid.conheight = Q_atoi(com_argv[i+1]); + if (vid.conheight < 200) + vid.conheight = 200; + + if (!(dpy = XOpenDisplay(NULL))) { + fprintf(stderr, "Error couldn't open the X display\n"); + exit(1); + } + + scrnum = DefaultScreen(dpy); + root = RootWindow(dpy, scrnum); + + // Get video mode list + MajorVersion = MinorVersion = 0; + if (!XF86VidModeQueryVersion(dpy, &MajorVersion, &MinorVersion)) { + vidmode_ext = false; + } else { + Con_Printf("Using XFree86-VidModeExtension Version %d.%d\n", MajorVersion, MinorVersion); + vidmode_ext = true; + } + + visinfo = glXChooseVisual(dpy, scrnum, attrib); + if (!visinfo) { + fprintf(stderr, "qkHack: Error couldn't get an RGB, Double-buffered, Depth visual\n"); + exit(1); + } + + if (vidmode_ext) { + int best_fit, best_dist, dist, x, y; + + XF86VidModeGetAllModeLines(dpy, scrnum, &num_vidmodes, &vidmodes); + + // Are we going fullscreen? If so, let's change video mode + if (fullscreen) { + best_dist = 9999999; + best_fit = -1; + + for (i = 0; i < num_vidmodes; i++) { + if (width > vidmodes[i]->hdisplay || + height > vidmodes[i]->vdisplay) + continue; + + x = width - vidmodes[i]->hdisplay; + y = height - vidmodes[i]->vdisplay; + dist = (x * x) + (y * y); + if (dist < best_dist) { + best_dist = dist; + best_fit = i; + } + } + + if (best_fit != -1) { + actualWidth = vidmodes[best_fit]->hdisplay; + actualHeight = vidmodes[best_fit]->vdisplay; + + // change to the mode + XF86VidModeSwitchToMode(dpy, scrnum, vidmodes[best_fit]); + vidmode_active = true; + + // Move the viewport to top left + XF86VidModeSetViewPort(dpy, scrnum, 0, 0); + } else + fullscreen = 0; + } + } + + /* window attributes */ + attr.background_pixel = 0; + attr.border_pixel = 0; + attr.colormap = XCreateColormap(dpy, root, visinfo->visual, AllocNone); + attr.event_mask = X_MASK; + if (vidmode_active) { + mask = CWBackPixel | CWColormap | CWSaveUnder | CWBackingStore | + CWEventMask | CWOverrideRedirect; + attr.override_redirect = True; + attr.backing_store = NotUseful; + attr.save_under = False; + } else + mask = CWBackPixel | CWBorderPixel | CWColormap | CWEventMask; + + win = XCreateWindow(dpy, root, 0, 0, width, height, + 0, visinfo->depth, InputOutput, + visinfo->visual, mask, &attr); + XMapWindow(dpy, win); + + if (vidmode_active) { + XMoveWindow(dpy, win, 0, 0); + XRaiseWindow(dpy, win); + XWarpPointer(dpy, None, win, 0, 0, 0, 0, 0, 0); + XFlush(dpy); + // Move the viewport to top left + XF86VidModeSetViewPort(dpy, scrnum, 0, 0); + } + + XFlush(dpy); + + ctx = glXCreateContext(dpy, visinfo, NULL, True); + + glXMakeCurrent(dpy, win, ctx); + + scr_width = width; + scr_height = height; + + if (vid.conheight > height) + vid.conheight = height; + if (vid.conwidth > width) + vid.conwidth = width; + vid.width = vid.conwidth; + vid.height = vid.conheight; + + vid.aspect = ((float)vid.height / (float)vid.width) * (320.0 / 240.0); + vid.numpages = 2; + + InitSig(); // trap evil signals + + GL_Init(); + + sprintf (gldir, "%s/glquake", com_gamedir); + Sys_mkdir (gldir); + + VID_SetPalette(palette); + + // Check for 3DFX Extensions and initialize them. + VID_Init8bitPalette(); + + Con_SafePrintf ("Video mode %dx%d initialized.\n", width, height); + + vid.recalc_refdef = 1; // force a surface cache flush +} + +void Sys_SendKeyEvents(void) +{ + HandleEvents(); +} + +void Force_CenterView_f (void) +{ + cl.viewangles[PITCH] = 0; +} + +void IN_Init(void) +{ +} + +void IN_Shutdown(void) +{ +} + +/* +=========== +IN_Commands +=========== +*/ +void IN_Commands (void) +{ + if (!dpy || !win) + return; + + if (vidmode_active || key_dest == key_game) + IN_ActivateMouse(); + else + IN_DeactivateMouse (); +} + +/* +=========== +IN_Move +=========== +*/ +void IN_MouseMove (usercmd_t *cmd) +{ + if (!mouse_avail) + return; + + if (m_filter.value) + { + mx = (mx + old_mouse_x) * 0.5; + my = (my + old_mouse_y) * 0.5; + } + old_mouse_x = mx; + old_mouse_y = my; + + mx *= sensitivity.value; + my *= sensitivity.value; + +// add mouse X/Y movement to cmd + if ( (in_strafe.state & 1) || (lookstrafe.value && (in_mlook.state & 1) )) + cmd->sidemove += m_side.value * mx; + else + cl.viewangles[YAW] -= m_yaw.value * mx; + + if (in_mlook.state & 1) + V_StopPitchDrift (); + + if ( (in_mlook.state & 1) && !(in_strafe.state & 1)) + { + cl.viewangles[PITCH] += m_pitch.value * my; + 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 * my; + else + cmd->forwardmove -= m_forward.value * my; + } + mx = my = 0; +} + +void IN_Move (usercmd_t *cmd) +{ + IN_MouseMove(cmd); +} + + diff --git a/contrib/other/sdlquake-1.0.9/gl_vidnt.c b/contrib/other/sdlquake-1.0.9/gl_vidnt.c new file mode 100644 index 000000000..932a68db7 --- /dev/null +++ b/contrib/other/sdlquake-1.0.9/gl_vidnt.c @@ -0,0 +1,1949 @@ +/* +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 +#define VID_ROW_SIZE 3 +#define WARP_WIDTH 320 +#define WARP_HEIGHT 200 +#define MAXWIDTH 10000 +#define MAXHEIGHT 10000 +#define BASEWIDTH 320 +#define BASEHEIGHT 200 + +#define MODE_WINDOWED 0 +#define NO_MODE (MODE_WINDOWED - 1) +#define MODE_FULLSCREEN_DEFAULT (MODE_WINDOWED + 1) + +typedef struct { + modestate_t type; + int width; + int height; + int modenum; + int dib; + int fullscreen; + int bpp; + int halfscreen; + char modedesc[17]; +} vmode_t; + +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; + +static vmode_t modelist[MAX_MODE_LIST]; +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]; +static qboolean fullsbardraw = false; + +static float vid_gamma = 1.0; + +HGLRC baseRC; +HDC maindc; + +glvert_t glv; + +cvar_t gl_ztrick = {"gl_ztrick","1"}; + +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); + +PROC glArrayElementEXT; +PROC glColorPointerEXT; +PROC glTexCoordPointerEXT; +PROC glVertexPointerEXT; + +typedef void (APIENTRY *lp3DFXFUNC) (int, int, int, int, int, const void*); +lp3DFXFUNC glColorTableEXT; +qboolean is8bit = false; +qboolean isPermedia = false; +qboolean gl_mtexable = false; + +//==================================== + +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}; + +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, + "WinQuake", + "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); + + 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; + + 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, + "WinQuake", + "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); + + 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; + + 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; + + CDAudio_Pause (); + + 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 (); + + CDAudio_Resume (); + 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; + } +} + +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"); +} + +//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; + +#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 + +/* +=============== +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); + gl_extensions = glGetString (GL_EXTENSIONS); + Con_Printf ("GL_EXTENSIONS: %s\n", gl_extensions); + +// Con_Printf ("%s %s\n", gl_renderer, gl_version); + + if (strnicmp(gl_renderer,"PowerVR",7)==0) + fullsbardraw = true; + + if (strnicmp(gl_renderer,"Permedia",8)==0) + isPermedia = true; + + CheckTextureExtensions (); + CheckMultiTextureExtensions (); + + glClearColor (1,0,0,0); + glCullFace(GL_FRONT); + glEnable(GL_TEXTURE_2D); + + glEnable(GL_ALPHA_TEST); + glAlphaFunc(GL_GREATER, 0.666); + + 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 +} + +/* +================= +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 (); + } + } + } + if (fullsbardraw) + Sbar_Changed(); +} + +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 + }; + + +/* +======= +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) + { + S_BlockSound (); + sound_active = false; + } + else if (ActiveApp && !sound_active) + { + 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_MOUSEMOVE: + temp = 0; + + if (wParam & MK_LBUTTON) + temp |= 1; + + if (wParam & MK_RBUTTON) + temp |= 2; + + if (wParam & MK_MBUTTON) + temp |= 4; + + 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; + + case MM_MCINOTIFY: + lRet = CDAudio_MessageHandler (hWnd, uMsg, wParam, lParam); + break; + + 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[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); + + if ((devmode.dmBitsPerPel >= 15) && + (devmode.dmPelsWidth <= MAXWIDTH) && + (devmode.dmPelsHeight <= MAXHEIGHT) && + (nummodes < MAX_MODE_LIST)) + { + 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; + sprintf (modelist[nummodes].modedesc, "%dx%dx%d", + devmode.dmPelsWidth, devmode.dmPelsHeight, + devmode.dmBitsPerPel); + + // 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; + sprintf (modelist[nummodes].modedesc, "%dx%dx%d", + modelist[nummodes].width, + modelist[nummodes].height, + modelist[nummodes].bpp); + } + } + + 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); + + 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)); + + InitCommonControls(); + + 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; + } + + if (COM_CheckParm("-bpp")) + { + bpp = Q_atoi(com_argv[COM_CheckParm("-bpp")+1]); + findbpp = 0; + } + else + { + bpp = 15; + findbpp = 1; + } + + 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; + sprintf (modelist[nummodes].modedesc, "%dx%dx%d", + devmode.dmPelsWidth, devmode.dmPelsHeight, + devmode.dmBitsPerPel); + + for (i=nummodes, existingmode = 0 ; iwidth)/2, 4, p); + + vid_wmodes = 0; + lnummodes = VID_NumModes (); + + for (i=1 ; (i 0) + { + M_Print (2*8, 36+0*8, "Fullscreen Modes (WIDTHxHEIGHTxBPP)"); + + column = 8; + row = 36+2*8; + + for (i=0 ; i"); + M_Print (3*8, 36 + MODE_AREA_HEIGHT * 8 + 8*4, + "and -bpp "); + 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/contrib/other/sdlquake-1.0.9/gl_warp.c b/contrib/other/sdlquake-1.0.9/gl_warp.c new file mode 100644 index 000000000..e8b96af88 --- /dev/null +++ b/contrib/other/sdlquake-1.0.9/gl_warp.c @@ -0,0 +1,1092 @@ +/* +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; + +extern cvar_t gl_subdivide_size; + +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; + } +} + +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; + } +} + +/* +================ +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 +float turbsin[] = +{ + #include "gl_warp_sin.h" +}; +#define TURBSCALE (256.0 / (2 * M_PI)) + +/* +============= +EmitWaterPolys + +Does a water warp on the pre-fragmented glpoly_t chain +============= +*/ +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 (); + } +} + + + + +/* +============= +EmitSkyPolys +============= +*/ +void EmitSkyPolys (msurface_t *fa) +{ + glpoly_t *p; + float *v; + int i; + float s, t; + vec3_t dir; + float length; + + 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; + + GL_DisableMultitexture(); + + 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 +================= +*/ +void R_DrawSkyChain (msurface_t *s) +{ + msurface_t *fa; + + GL_DisableMultitexture(); + + // 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); +} + +#endif + +/* +================================================================= + + Quake 2 environment sky + +================================================================= +*/ + +#ifdef QUAKE2 + + +#define SKY_TEX 2000 + +/* +================================================================= + + PCX Loading + +================================================================= +*/ + +typedef struct +{ + char manufacturer; + char version; + char encoding; + char bits_per_pixel; + unsigned short xmin,ymin,xmax,ymax; + unsigned short hres,vres; + unsigned char palette[48]; + char reserved; + char color_planes; + unsigned short bytes_per_line; + unsigned short palette_type; + char filler[58]; + unsigned data; // unbounded +} pcx_t; + +byte *pcx_rgb; + +/* +============ +LoadPCX +============ +*/ +void LoadPCX (FILE *f) +{ + pcx_t *pcx, pcxbuf; + byte palette[768]; + byte *pix; + int x, y; + int dataByte, runLength; + int count; + +// +// parse the PCX file +// + fread (&pcxbuf, 1, sizeof(pcxbuf), f); + + pcx = &pcxbuf; + + if (pcx->manufacturer != 0x0a + || pcx->version != 5 + || pcx->encoding != 1 + || pcx->bits_per_pixel != 8 + || pcx->xmax >= 320 + || pcx->ymax >= 256) + { + Con_Printf ("Bad pcx file\n"); + return; + } + + // seek to palette + fseek (f, -768, SEEK_END); + fread (palette, 1, 768, f); + + fseek (f, sizeof(pcxbuf) - 4, SEEK_SET); + + count = (pcx->xmax+1) * (pcx->ymax+1); + pcx_rgb = malloc( count * 4); + + for (y=0 ; y<=pcx->ymax ; y++) + { + pix = pcx_rgb + 4*y*(pcx->xmax+1); + for (x=0 ; x<=pcx->ymax ; ) + { + dataByte = fgetc(f); + + if((dataByte & 0xC0) == 0xC0) + { + runLength = dataByte & 0x3F; + dataByte = fgetc(f); + } + else + runLength = 1; + + while(runLength-- > 0) + { + pix[0] = palette[dataByte*3]; + pix[1] = palette[dataByte*3+1]; + pix[2] = palette[dataByte*3+2]; + pix[3] = 255; + pix += 4; + x++; + } + } + } +} + +/* +========================================================= + +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; +byte *targa_rgba; + +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 +============= +*/ +void LoadTGA (FILE *fin) +{ + int columns, rows, numPixels; + byte *pixbuf; + int row, column; + + targa_header.id_length = fgetc(fin); + targa_header.colormap_type = fgetc(fin); + targa_header.image_type = fgetc(fin); + + targa_header.colormap_index = fgetLittleShort(fin); + targa_header.colormap_length = fgetLittleShort(fin); + targa_header.colormap_size = fgetc(fin); + targa_header.x_origin = fgetLittleShort(fin); + targa_header.y_origin = fgetLittleShort(fin); + targa_header.width = fgetLittleShort(fin); + targa_header.height = fgetLittleShort(fin); + targa_header.pixel_size = fgetc(fin); + targa_header.attributes = fgetc(fin); + + if (targa_header.image_type!=2 + && targa_header.image_type!=10) + Sys_Error ("LoadTGA: Only type 2 and 10 targa RGB images supported\n"); + + if (targa_header.colormap_type !=0 + || (targa_header.pixel_size!=32 && targa_header.pixel_size!=24)) + Sys_Error ("Texture_LoadTGA: Only 32 or 24 bit images supported (no colormaps)\n"); + + columns = targa_header.width; + rows = targa_header.height; + numPixels = columns * rows; + + targa_rgba = malloc (numPixels*4); + + if (targa_header.id_length != 0) + fseek(fin, targa_header.id_length, SEEK_CUR); // skip TARGA image comment + + if (targa_header.image_type==2) { // Uncompressed, RGB images + 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:; + } + } + + fclose(fin); +} + +/* +================== +R_LoadSkys +================== +*/ +char *suf[6] = {"rt", "bk", "lf", "ft", "up", "dn"}; +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); + 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); + } +} + + +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} +}; + +float skymins[2][6], skymaxs[2][6]; + +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; + } +} + +#define MAX_CLIP_VERTS 64 +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) + { + for (p=fa->polys ; p ; p=p->next) + { + for (i=0 ; inumverts ; i++) + { + VectorSubtract (p->verts[i], r_origin, verts[i]); + } + ClipSkyPolygon (p->numverts, verts[0], 0); + } + } +} + + +/* +============== +R_ClearSkyBox +============== +*/ +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; + } +} + + +void MakeSkyVec (float s, float t, int axis) +{ + vec3_t v, b; + int j, k; + + b[0] = s*2048; + b[1] = t*2048; + b[2] = 2048; + + 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 0 +glEnable (GL_BLEND); +glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); +glColor4f (1,1,1,0.5); +glDisable (GL_DEPTH_TEST); +#endif + 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 +skymins[0][i] = -1; +skymins[1][i] = -1; +skymaxs[0][i] = 1; +skymaxs[1][i] = 1; +#endif + glBegin (GL_QUADS); + MakeSkyVec (skymins[0][i], skymins[1][i], i); + MakeSkyVec (skymins[0][i], skymaxs[1][i], i); + MakeSkyVec (skymaxs[0][i], skymaxs[1][i], i); + MakeSkyVec (skymaxs[0][i], skymins[1][i], i); + glEnd (); + } +#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); +#endif +} + + +#endif + +//=============================================================== + +/* +============= +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; + + 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); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + + + 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); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); +} + diff --git a/contrib/other/sdlquake-1.0.9/gl_warp_sin.h b/contrib/other/sdlquake-1.0.9/gl_warp_sin.h new file mode 100644 index 000000000..22976a736 --- /dev/null +++ b/contrib/other/sdlquake-1.0.9/gl_warp_sin.h @@ -0,0 +1,51 @@ +/* +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/contrib/other/sdlquake-1.0.9/glqnotes.txt b/contrib/other/sdlquake-1.0.9/glqnotes.txt new file mode 100644 index 000000000..22240724c --- /dev/null +++ b/contrib/other/sdlquake-1.0.9/glqnotes.txt @@ -0,0 +1,171 @@ +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/contrib/other/sdlquake-1.0.9/glquake.h b/contrib/other/sdlquake-1.0.9/glquake.h new file mode 100644 index 000000000..f3c253c38 --- /dev/null +++ b/contrib/other/sdlquake-1.0.9/glquake.h @@ -0,0 +1,251 @@ +/* +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 + +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 + +extern int texture_extension_number; +extern int texture_mode; + +extern float gldepthmin, gldepthmax; + +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); +int GL_LoadTexture (char *identifier, int width, int height, byte *data, qboolean mipmap, qboolean alpha); +int GL_FindTexture (char *identifier); + +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; + +#ifdef _WIN32 +extern PROC glArrayElementEXT; +extern PROC glColorPointerEXT; +extern PROC glTexturePointerEXT; +extern PROC glVertexPointerEXT; +#endif + +// 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]; +extern int particletexture; +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; +extern cvar_t r_mirroralpha; +extern cvar_t r_wateralpha; +extern cvar_t r_dynamic; +extern cvar_t r_novis; + +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; +extern cvar_t gl_keeptjunctions; +extern cvar_t gl_reporttjunctions; +extern cvar_t gl_flashblend; +extern cvar_t gl_nocolors; +extern cvar_t gl_doubleeyes; + +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; + +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 +#define TEXTURE0_SGIS 0x835E +#define TEXTURE1_SGIS 0x835F + +#ifndef _WIN32 +#define APIENTRY /* */ +#endif + +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); diff --git a/contrib/other/sdlquake-1.0.9/glquake2.h b/contrib/other/sdlquake-1.0.9/glquake2.h new file mode 100644 index 000000000..06ea6f7e6 --- /dev/null +++ b/contrib/other/sdlquake-1.0.9/glquake2.h @@ -0,0 +1,209 @@ +/* +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 + +#include + +#include +#include + +void GL_BeginRendering (int *x, int *y, int *width, int *height); +void GL_EndRendering (void); + + +// 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; + +extern int texture_extension_number; +extern int texture_mode; + +extern float gldepthmin, gldepthmax; + +void GL_Upload32 (unsigned *data, int width, int height, qboolean mipmap, qboolean alpha, qboolean modulate); +void GL_Upload8 (byte *data, int width, int height, qboolean mipmap, qboolean alpha, qboolean modulate); +int GL_LoadTexture (char *identifier, int width, int height, byte *data, int mipmap, int alpha, int modulate); +int GL_FindTexture (char *identifier); + +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; + +extern PROC glArrayElementEXT; +extern PROC glColorPointerEXT; +extern PROC glTexturePointerEXT; +extern PROC glVertexPointerEXT; + + +// r_local.h -- private refresh defs + +#define MAXALIASVERTS 2000 // TODO: tune this + +#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 particletexture; +extern int playertextures; + +extern int skytexturenum; // index in cl.loadmodel, not gl texture object + +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; +extern cvar_t r_dynamic; + +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_fogblend; +extern cvar_t gl_polyblend; +extern cvar_t gl_keeptjunctions; +extern cvar_t gl_reporttjunctions; + +extern int gl_lightmap_format; +extern int gl_solid_format; +extern int gl_alpha_format; + +void R_TranslatePlayerSkin (int playernum); +void GL_Bind (int texnum); diff --git a/contrib/other/sdlquake-1.0.9/host.c b/contrib/other/sdlquake-1.0.9/host.c new file mode 100644 index 000000000..603f6b3f0 --- /dev/null +++ b/contrib/other/sdlquake-1.0.9/host.c @@ -0,0 +1,958 @@ +/* +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. + +*/ +// host.c -- coordinates spawning and killing of local servers + +#include "quakedef.h" +#include "r_local.h" + +/* + +A server can allways be started, even if the system started out as a client +to a remote system. + +A client can NOT be started if the system started as a dedicated server. + +Memory is cleared / released when a server or client begins, not when they end. + +*/ + +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 minimum_memory; + +client_t *host_client; // current client + +jmp_buf host_abortserver; + +byte *host_basepal; +byte *host_colormap; + +cvar_t host_framerate = {"host_framerate","0"}; // set for slow motion +cvar_t host_speeds = {"host_speeds","0"}; // set for running times + +cvar_t sys_ticrate = {"sys_ticrate","0.05"}; +cvar_t serverprofile = {"serverprofile","0"}; + +cvar_t fraglimit = {"fraglimit","0",false,true}; +cvar_t timelimit = {"timelimit","0",false,true}; +cvar_t teamplay = {"teamplay","0",false,true}; + +cvar_t samelevel = {"samelevel","0"}; +cvar_t noexit = {"noexit","0",false,true}; + +#ifdef QUAKE2 +cvar_t developer = {"developer","1"}; // should be 0 for release! +#else +cvar_t developer = {"developer","0"}; +#endif + +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 pausable = {"pausable","1"}; + +cvar_t temp1 = {"temp1","0"}; + + +/* +================ +Host_EndGame +================ +*/ +void Host_EndGame (char *message, ...) +{ + va_list argptr; + char string[1024]; + + va_start (argptr,message); + vsprintf (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 + CL_Disconnect (); + + longjmp (host_abortserver, 1); +} + +/* +================ +Host_Error + +This shuts down both the client and server +================ +*/ +void Host_Error (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); + va_end (argptr); + Con_Printf ("Host_Error: %s\n",string); + + if (sv.active) + Host_ShutdownServer (false); + + if (cls.state == ca_dedicated) + Sys_Error ("Host_Error: %s\n",string); // dedicated servers exit + + CL_Disconnect (); + cls.demonum = -1; + + inerror = false; + + longjmp (host_abortserver, 1); +} + +/* +================ +Host_FindMaxClients +================ +*/ +void Host_FindMaxClients (void) +{ + int i; + + svs.maxclients = 1; + + i = COM_CheckParm ("-dedicated"); + if (i) + { + cls.state = ca_dedicated; + if (i != (com_argc - 1)) + { + svs.maxclients = Q_atoi (com_argv[i+1]); + } + else + svs.maxclients = 8; + } + else + cls.state = ca_disconnected; + + i = COM_CheckParm ("-listen"); + if (i) + { + if (cls.state == ca_dedicated) + Sys_Error ("Only one of -dedicated or -listen can be specified"); + if (i != (com_argc - 1)) + svs.maxclients = Q_atoi (com_argv[i+1]); + else + svs.maxclients = 8; + } + if (svs.maxclients < 1) + svs.maxclients = 8; + else if (svs.maxclients > MAX_SCOREBOARD) + svs.maxclients = MAX_SCOREBOARD; + + svs.maxclientslimit = svs.maxclients; + if (svs.maxclientslimit < 4) + svs.maxclientslimit = 4; + svs.clients = Hunk_AllocName (svs.maxclientslimit*sizeof(client_t), "clients"); + + if (svs.maxclients > 1) + Cvar_SetValue ("deathmatch", 1.0); + else + Cvar_SetValue ("deathmatch", 0.0); +} + + +/* +======================= +Host_InitLocal +====================== +*/ +void Host_InitLocal (void) +{ + Host_InitCommands (); + + Cvar_RegisterVariable (&host_framerate); + Cvar_RegisterVariable (&host_speeds); + + Cvar_RegisterVariable (&sys_ticrate); + Cvar_RegisterVariable (&serverprofile); + + Cvar_RegisterVariable (&fraglimit); + Cvar_RegisterVariable (&timelimit); + Cvar_RegisterVariable (&teamplay); + Cvar_RegisterVariable (&samelevel); + Cvar_RegisterVariable (&noexit); + Cvar_RegisterVariable (&skill); + Cvar_RegisterVariable (&developer); + Cvar_RegisterVariable (&deathmatch); + Cvar_RegisterVariable (&coop); + + Cvar_RegisterVariable (&pausable); + + Cvar_RegisterVariable (&temp1); + + Host_FindMaxClients (); + + host_time = 1.0; // so a think at time 0 won't get called +} + + +/* +=============== +Host_WriteConfiguration + +Writes key bindings and archived cvars to config.cfg +=============== +*/ +void Host_WriteConfiguration (void) +{ + FILE *f; + +// dedicated servers initialize the host but don't parse and set the +// config.cfg cvars + if (host_initialized & !isDedicated) + { + f = fopen (va("%s/config.cfg",com_gamedir), "w"); + if (!f) + { + Con_Printf ("Couldn't write config.cfg.\n"); + return; + } + + Key_WriteBindings (f); + Cvar_WriteVariables (f); + + fclose (f); + } +} + + +/* +================= +SV_ClientPrintf + +Sends text across to be displayed +FIXME: make this just a stuffed echo? +================= +*/ +void SV_ClientPrintf (char *fmt, ...) +{ + va_list argptr; + char string[1024]; + + va_start (argptr,fmt); + vsprintf (string, fmt,argptr); + va_end (argptr); + + MSG_WriteByte (&host_client->message, svc_print); + MSG_WriteString (&host_client->message, string); +} + +/* +================= +SV_BroadcastPrintf + +Sends text to all active clients +================= +*/ +void SV_BroadcastPrintf (char *fmt, ...) +{ + va_list argptr; + char string[1024]; + int i; + + va_start (argptr,fmt); + vsprintf (string, fmt,argptr); + va_end (argptr); + + for (i=0 ; imessage, svc_stufftext); + MSG_WriteString (&host_client->message, string); +} + +/* +===================== +SV_DropClient + +Called when the player is getting totally kicked off the host +if (crash = true), don't bother sending signofs +===================== +*/ +void SV_DropClient (qboolean crash) +{ + int saveSelf; + int i; + client_t *client; + + if (!crash) + { + // send any final messages (don't check for errors) + if (NET_CanSendMessage (host_client->netconnection)) + { + 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 + // this will set the body to a dead frame, among other things + saveSelf = pr_global_struct->self; + pr_global_struct->self = EDICT_TO_PROG(host_client->edict); + PR_ExecuteProgram (pr_global_struct->ClientDisconnect); + pr_global_struct->self = saveSelf; + } + + Sys_Printf ("Client %s removed\n",host_client->name); + } + +// break the net connection + NET_Close (host_client->netconnection); + host_client->netconnection = NULL; + +// free the client (the body stays around) + host_client->active = false; + host_client->name[0] = 0; + host_client->old_frags = -999999; + net_activeconnections--; + +// send notification to all clients + for (i=0, client = svs.clients ; iactive) + continue; + MSG_WriteByte (&client->message, svc_updatename); + MSG_WriteByte (&client->message, host_client - svs.clients); + MSG_WriteString (&client->message, ""); + MSG_WriteByte (&client->message, svc_updatefrags); + MSG_WriteByte (&client->message, host_client - svs.clients); + MSG_WriteShort (&client->message, 0); + MSG_WriteByte (&client->message, svc_updatecolors); + MSG_WriteByte (&client->message, host_client - svs.clients); + MSG_WriteByte (&client->message, 0); + } +} + +/* +================== +Host_ShutdownServer + +This only happens at the end of a game, not between levels +================== +*/ +void Host_ShutdownServer(qboolean crash) +{ + int i; + int count; + sizebuf_t buf; + char message[4]; + double start; + + if (!sv.active) + return; + + sv.active = false; + +// stop all client sounds immediately + if (cls.state == ca_connected) + CL_Disconnect (); + +// flush any pending messages - like the score!!! + start = Sys_FloatTime(); + do + { + count = 0; + for (i=0, host_client = svs.clients ; iactive && host_client->message.cursize) + { + if (NET_CanSendMessage (host_client->netconnection)) + { + NET_SendMessage(host_client->netconnection, &host_client->message); + SZ_Clear (&host_client->message); + } + else + { + NET_GetMessage(host_client->netconnection); + count++; + } + } + } + if ((Sys_FloatTime() - start) > 3.0) + break; + } + while (count); + +// make sure all the clients know we're disconnecting + buf.data = message; + buf.maxsize = 4; + buf.cursize = 0; + MSG_WriteByte(&buf, svc_disconnect); + count = NET_SendToAll(&buf, 5); + 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 (svs.clients, 0, svs.maxclientslimit*sizeof(client_t)); +} + + +/* +================ +Host_ClearMemory + +This clears all the memory used by both the client and server, but does +not reinitialize anything. +================ +*/ +void Host_ClearMemory (void) +{ + Con_DPrintf ("Clearing memory\n"); + D_FlushCaches (); + Mod_ClearAll (); + if (host_hunklevel) + Hunk_FreeToLowMark (host_hunklevel); + + cls.signon = 0; + memset (&sv, 0, sizeof(sv)); + memset (&cl, 0, sizeof(cl)); +} + + +//============================================================================ + + +/* +=================== +Host_FilterTime + +Returns false if the time is too short to run a frame +=================== +*/ +qboolean Host_FilterTime (float time) +{ + realtime += time; + + if (!cls.timedemo && realtime - oldrealtime < 1.0/72.0) + return false; // framerate is too high + + host_frametime = realtime - oldrealtime; + oldrealtime = realtime; + + 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; + if (host_frametime < 0.001) + host_frametime = 0.001; + } + + return true; +} + + +/* +=================== +Host_GetConsoleCommands + +Add them exactly as if they had been typed at the console +=================== +*/ +void Host_GetConsoleCommands (void) +{ + char *cmd; + + while (1) + { + cmd = Sys_ConsoleInput (); + if (!cmd) + break; + Cbuf_AddText (cmd); + } +} + + +/* +================== +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; + +// 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 (); + +// send all messages to the clients + SV_SendClientMessages (); +} + +#endif + + +/* +================== +Host_Frame + +Runs all active servers +================== +*/ +void _Host_Frame (float time) +{ + static double time1 = 0; + static double time2 = 0; + static double time3 = 0; + int pass1, pass2, pass3; + + if (setjmp (host_abortserver) ) + return; // something bad happened, or the server disconnected + +// 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 + Sys_SendKeyEvents (); + +// allow mice or other external controllers to add commands + IN_Commands (); + +// process console commands + Cbuf_Execute (); + + NET_Poll(); + +// if running the server locally, make intentions now + if (sv.active) + CL_SendCmd (); + +//------------------- +// +// server operations +// +//------------------- + +// check for commands typed to the host + Host_GetConsoleCommands (); + + if (sv.active) + Host_ServerFrame (); + +//------------------- +// +// client operations +// +//------------------- + +// if running the server remotely, send intentions now after +// the incoming messages have been read + 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 (); + + SCR_UpdateScreen (); + + if (host_speeds.value) + time2 = Sys_FloatTime (); + +// update audio + if (cls.signon == SIGNONS) + { + S_Update (r_origin, vpn, vright, vup); + CL_DecayLights (); + } + else + S_Update (vec3_origin, vec3_origin, vec3_origin, vec3_origin); + + CDAudio_Update(); + + if (host_speeds.value) + { + pass1 = (time1 - time3)*1000; + time3 = Sys_FloatTime (); + 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); + } + + host_framecount++; +} + +void Host_Frame (float time) +{ + double time1, time2; + static double timetotal; + static int timecount; + int i, c, m; + + if (!serverprofile.value) + { + _Host_Frame (time); + return; + } + + time1 = Sys_FloatTime (); + _Host_Frame (time); + time2 = Sys_FloatTime (); + + timetotal += time2 - time1; + timecount++; + + if (timecount < 1000) + return; + + m = timetotal*1000/timecount; + 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) +{ + + if (standard_quake) + minimum_memory = MINIMUM_MEMORY; + else + minimum_memory = MINIMUM_MEMORY_LEVELPAK; + + if (COM_CheckParm ("-minmemory")) + parms->memsize = minimum_memory; + + host_parms = *parms; + + if (parms->memsize < minimum_memory) + Sys_Error ("Only %4.1f megs of memory available, can't execute game", parms->memsize / (float)0x100000); + + com_argc = parms->argc; + com_argv = parms->argv; + + Memory_Init (parms->membase, parms->memsize); + Cbuf_Init (); + Cmd_Init (); + V_Init (); + Chase_Init (); + Host_InitVCR (parms); + COM_Init (parms->basedir); + Host_InitLocal (); + W_LoadWadFile ("gfx.wad"); + Key_Init (); + Con_Init (); + M_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 + + 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"); + if (!host_colormap) + Sys_Error ("Couldn't load gfx/colormap.lmp"); + +#ifndef _WIN32 // on non win32, mouse comes before video for security reasons + IN_Init (); +#endif + VID_Init (host_basepal); + + 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 (); + 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"); +} + + +/* +=============== +Host_Shutdown + +FIXME: this is a callback from Sys_Quit and Sys_Error. It would be better +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"); + return; + } + isdown = true; + +// keep Con_Printf from trying to update the screen + scr_disabled_for_loading = true; + + Host_WriteConfiguration (); + + CDAudio_Shutdown (); + NET_Shutdown (); + S_Shutdown(); + IN_Shutdown (); + + if (cls.state != ca_dedicated) + { + VID_Shutdown(); + } +} + diff --git a/contrib/other/sdlquake-1.0.9/host_cmd.c b/contrib/other/sdlquake-1.0.9/host_cmd.c new file mode 100644 index 000000000..e658cd4f7 --- /dev/null +++ b/contrib/other/sdlquake-1.0.9/host_cmd.c @@ -0,0 +1,1925 @@ +/* +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", 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; + } + } + + sprintf (name, "%s/%s", com_gamedir, Cmd_Argv(1)); + 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 + + sprintf (name, "%s/%s", com_gamedir, Cmd_Argv(1)); + 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 = host_client->name - pr_strings; + +// 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", 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_strings + sv_player->v.netname); + } + else + { + SV_BroadcastPrintf ("%s unpaused the game\n",pr_strings + 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 = host_client->name - pr_strings; + + // 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 3) + mouse_buttons = 3; + Con_Printf("%d-button mouse available\n", mouse_buttons); +} + +/* +=========== +IN_Init +=========== +*/ +void IN_Init (void) +{ + int i; + + Cvar_RegisterVariable (&m_filter); + Cvar_RegisterVariable (&in_joystick); + Cvar_RegisterVariable (&joy_numbuttons); + Cvar_RegisterVariable (&aux_look); + Cmd_AddCommand ("toggle_auxlook", Toggle_AuxLook_f); + Cmd_AddCommand ("force_centerview", Force_CenterView_f); + + IN_StartupMouse (); + IN_StartupJoystick (); + + i = COM_CheckParm ("-control"); + if (i) + { + extern_control = real2ptr(Q_atoi (com_argv[i+1])); + IN_StartupExternal (); + } +} + +/* +=========== +IN_Shutdown +=========== +*/ +void IN_Shutdown (void) +{ + +} + + +/* +=========== +IN_Commands +=========== +*/ +void IN_Commands (void) +{ + int i; + + if (mouse_avail) + { + regs.x.ax = 3; // read buttons + dos_int86(0x33); + mouse_buttonstate = regs.x.bx; + + // perform button actions + for (i=0 ; i> 4)&15)^15; + // perform button actions + for (i=0 ; ibuttons; + + // perform button actions + for (i=0 ; isidemove += m_side.value * mouse_x; + else + cl.viewangles[YAW] -= m_yaw.value * mouse_x; + + if (in_mlook.state & 1) + V_StopPitchDrift (); + + if ( (in_mlook.state & 1) && !(in_strafe.state & 1)) + { + 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; + } +} + +/* +=========== +IN_JoyMove +=========== +*/ +void IN_JoyMove (usercmd_t *cmd) +{ + float speed, aspeed; + + if (!joy_avail || !in_joystick.value) + return; + + IN_ReadJoystick (); + if (joysticky > joyyh*2 || joystickx > joyxh*2) + return; // assume something jumped in and messed up the joystick + // reading time (win 95) + + if (in_speed.state & 1) + speed = cl_movespeedkey.value; + else + speed = 1; + aspeed = speed*host_frametime; + + if (in_strafe.state & 1) + { + if (joystickx < joyxl) + cmd->sidemove -= speed*cl_sidespeed.value; + else if (joystickx > joyxh) + cmd->sidemove += speed*cl_sidespeed.value; + } + else + { + if (joystickx < joyxl) + cl.viewangles[YAW] += aspeed*cl_yawspeed.value; + else if (joystickx > joyxh) + cl.viewangles[YAW] -= aspeed*cl_yawspeed.value; + cl.viewangles[YAW] = anglemod(cl.viewangles[YAW]); + } + + if (in_mlook.state & 1) + { + if (m_pitch.value < 0) + speed *= -1; + + if (joysticky < joyyl) + cl.viewangles[PITCH] += aspeed*cl_pitchspeed.value; + else if (joysticky > joyyh) + cl.viewangles[PITCH] -= aspeed*cl_pitchspeed.value; + } + else + { + if (joysticky < joyyl) + cmd->forwardmove += speed*cl_forwardspeed.value; + else if (joysticky > joyyh) + cmd->forwardmove -= speed*cl_backspeed.value; + } +} + +/* +=========== +IN_Move +=========== +*/ +void IN_Move (usercmd_t *cmd) +{ + IN_MouseMove (cmd); + IN_JoyMove (cmd); + IN_ExternalMove (cmd); +} + +/* +============================================================================ + + JOYSTICK + +============================================================================ +*/ + + + +qboolean IN_ReadJoystick (void) +{ + int b; + int count; + + joystickx = 0; + joysticky = 0; + + count = 0; + + b = dos_inportb(0x201); + dos_outportb(0x201, b); + +// clear counters + while (++count < 10000) + { + b = dos_inportb(0x201); + + joystickx += b&1; + joysticky += (b&2)>>1; + if ( !(b&3) ) + return true; + } + + Con_Printf ("IN_ReadJoystick: no response\n"); + joy_avail = false; + return false; +} + +/* +============= +WaitJoyButton +============= +*/ +qboolean WaitJoyButton (void) +{ + int oldbuttons, buttons; + + oldbuttons = 0; + do + { + key_count = -1; + Sys_SendKeyEvents (); + key_count = 0; + if (key_lastpress == K_ESCAPE) + { + Con_Printf ("aborted.\n"); + return false; + } + key_lastpress = 0; + SCR_UpdateScreen (); + buttons = ((dos_inportb(0x201) >> 4)&1)^1; + if (buttons != oldbuttons) + { + oldbuttons = buttons; + continue; + } + } while ( !buttons); + + do + { + key_count = -1; + Sys_SendKeyEvents (); + key_count = 0; + if (key_lastpress == K_ESCAPE) + { + Con_Printf ("aborted.\n"); + return false; + } + key_lastpress = 0; + SCR_UpdateScreen (); + buttons = ((dos_inportb(0x201) >> 4)&1)^1; + if (buttons != oldbuttons) + { + oldbuttons = buttons; + continue; + } + } while ( buttons); + + return true; +} + + + +/* +=============== +IN_StartupJoystick +=============== +*/ +void IN_StartupJoystick (void) +{ + int centerx, centery; + + Con_Printf ("\n"); + + joy_avail = false; + if ( COM_CheckParm ("-nojoy") ) + return; + + if (!IN_ReadJoystick ()) + { + joy_avail = false; + Con_Printf ("joystick not found\n"); + return; + } + + Con_Printf ("joystick found\n"); + + Con_Printf ("CENTER the joystick\nand press button 1 (ESC to skip):\n"); + if (!WaitJoyButton ()) + return; + IN_ReadJoystick (); + centerx = joystickx; + centery = joysticky; + + Con_Printf ("Push the joystick to the UPPER LEFT\nand press button 1 (ESC to skip):\n"); + if (!WaitJoyButton ()) + return; + IN_ReadJoystick (); + joyxl = (centerx + joystickx)/2; + joyyl = (centerx + joysticky)/2; + + Con_Printf ("Push the joystick to the LOWER RIGHT\nand press button 1 (ESC to skip):\n"); + if (!WaitJoyButton ()) + return; + IN_ReadJoystick (); + joyxh = (centerx + joystickx)/2; + joyyh = (centery + joysticky)/2; + + joy_avail = true; + Con_Printf ("joystick configured.\n"); + + Con_Printf ("\n"); +} + + +/* +============================================================================ + + EXTERNAL + +============================================================================ +*/ + + +/* +=============== +IN_StartupExternal +=============== +*/ +void IN_StartupExternal (void) +{ + if (extern_control->numButtons > 32) + extern_control->numButtons = 32; + + Con_Printf("%s Initialized\n", extern_control->deviceName); + Con_Printf(" %u axes %u buttons\n", extern_control->numAxes, extern_control->numButtons); + + extern_avail = true; + extern_buttons = extern_control->numButtons; +} + + +/* +=========== +IN_ExternalMove +=========== +*/ +void IN_ExternalMove (usercmd_t *cmd) +{ + qboolean freelook; + + if (! extern_avail) + return; + + extern_control->viewangles[YAW] = cl.viewangles[YAW]; + extern_control->viewangles[PITCH] = cl.viewangles[PITCH]; + extern_control->viewangles[ROLL] = cl.viewangles[ROLL]; + extern_control->forwardmove = cmd->forwardmove; + extern_control->sidemove = cmd->sidemove; + extern_control->upmove = cmd->upmove; + +Con_DPrintf("IN: y:%f p:%f r:%f f:%f s:%f u:%f\n", extern_control->viewangles[YAW], extern_control->viewangles[PITCH], extern_control->viewangles[ROLL], extern_control->forwardmove, extern_control->sidemove, extern_control->upmove); + + dos_int86(extern_control->interruptVector); + +Con_DPrintf("OUT: y:%f p:%f r:%f f:%f s:%f u:%f\n", extern_control->viewangles[YAW], extern_control->viewangles[PITCH], extern_control->viewangles[ROLL], extern_control->forwardmove, extern_control->sidemove, extern_control->upmove); + + cl.viewangles[YAW] = extern_control->viewangles[YAW]; + cl.viewangles[PITCH] = extern_control->viewangles[PITCH]; + cl.viewangles[ROLL] = extern_control->viewangles[ROLL]; + cmd->forwardmove = extern_control->forwardmove; + cmd->sidemove = extern_control->sidemove; + cmd->upmove = extern_control->upmove; + + if (cl.viewangles[PITCH] > 80) + cl.viewangles[PITCH] = 80; + if (cl.viewangles[PITCH] < -70) + cl.viewangles[PITCH] = -70; + + freelook = (extern_control->flags & AUX_FLAG_FREELOOK || aux_look.value || in_mlook.state & 1); + + if (freelook) + V_StopPitchDrift (); +} + diff --git a/contrib/other/sdlquake-1.0.9/in_null.c b/contrib/other/sdlquake-1.0.9/in_null.c new file mode 100644 index 000000000..1c54ee4da --- /dev/null +++ b/contrib/other/sdlquake-1.0.9/in_null.c @@ -0,0 +1,39 @@ +/* +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. + +*/ +// in_null.c -- for systems without a mouse + +#include "quakedef.h" + +void IN_Init (void) +{ +} + +void IN_Shutdown (void) +{ +} + +void IN_Commands (void) +{ +} + +void IN_Move (usercmd_t *cmd) +{ +} + diff --git a/contrib/other/sdlquake-1.0.9/in_sun.c b/contrib/other/sdlquake-1.0.9/in_sun.c new file mode 100644 index 000000000..3ffede5cf --- /dev/null +++ b/contrib/other/sdlquake-1.0.9/in_sun.c @@ -0,0 +1,245 @@ +/* +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. + +*/ +// in_sun.c -- SUN/X mouse input handler + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "quakedef.h" + + +// +// typedefs and defines +// + +#define MOUSE_SCALE 4 + +// +// externs +// + +extern Display *x_disp; +extern int x_screen, x_screen_width, x_screen_height; +extern int x_center_height, x_center_width; +extern int x_std_event_mask; +extern Window x_win, x_root_win; +extern qboolean x_fullscreen; +extern qboolean x_focus; +extern int global_dx, global_dy; +// +// globals +// + +cvar_t _windowed_mouse = {"_windowed_mouse","1", true}; +int x_root, y_root; +int x_root_old, y_root_old; +// +// locals +// + +static int x_mouse_num, x_mouse_denom, x_mouse_thresh; + + +static qboolean x_grabbed = false; + +// +// IN_CenterMouse - center the mouse in the screen +// + +void IN_CenterMouse( void ) +{ + CheckMouseState(); + + if (!x_grabbed) + return; + + XSelectInput( x_disp, x_win, x_std_event_mask & ~PointerMotionMask ); + XWarpPointer( x_disp, None, x_root_win, 0, 0, 0, 0, x_center_width, + x_center_height ); + XSelectInput( x_disp, x_win, x_std_event_mask ); +} + +// +// Check to see if we have grabbed the mouse or not and deal with it +// appropriately +// +static void CheckMouseState(void) +{ + if (x_focus && _windowed_mouse.value && !x_grabbed) { + x_grabbed = true; + printf("fooling with mouse!\n"); + if (XGetPointerControl( x_disp, &x_mouse_num, &x_mouse_denom, &x_mouse_thresh )) + printf( "XGetPointerControl failed!\n" ); + //printf( "mouse %d/%d thresh %d\n", x_mouse_num, x_mouse_denom, x_mouse_thresh ); + + // make input rawer + XAutoRepeatOff(x_disp); + XGrabKeyboard(x_disp, x_win, True, GrabModeAsync, GrabModeAsync, CurrentTime); + XGrabPointer(x_disp, x_win, True, + PointerMotionMask | ButtonPressMask | ButtonReleaseMask, + GrabModeAsync, GrabModeAsync, None, None, CurrentTime); + +// if (XChangePointerControl( x_disp, True, True, 1, MOUSE_SCALE, x_mouse_thresh )) +// printf( "XChangePointerControl failed!\n" ); + + IN_CenterMouse(); + + // safe initial values + x_root = x_root_old = vid.width >> 1; + y_root = y_root_old = vid.height >> 1; + } else if (x_grabbed && (!_windowed_mouse.value || !x_focus)) { + printf("fooling with mouse!\n"); + x_grabbed = false; + // undo mouse warp + if (XChangePointerControl( x_disp, True, True, x_mouse_num, x_mouse_denom, x_mouse_thresh )) + printf( "XChangePointerControl failed!\n" ); + + XUngrabPointer( x_disp, CurrentTime ); + XUngrabKeyboard( x_disp, CurrentTime ); + XAutoRepeatOn( x_disp ); + } +} + + +// +// IN_Init - setup mouse input +// + +void IN_Init (void) +{ + if (!x_disp) Sys_Error( "X display not open!\n" ); + + Cvar_RegisterVariable (&_windowed_mouse); + + // we really really want to clean these up... + atexit( IN_Shutdown ); +} + +// +// IN_Shutdown - clean up mouse settings (must be done from signal handler too!) +// + +void IN_Shutdown (void) +{ + if (!x_disp) return; + + // undo mouse warp + if (XChangePointerControl( x_disp, True, True, x_mouse_num, x_mouse_denom, x_mouse_thresh )) + printf( "XChangePointerControl failed!\n" ); + + XUngrabPointer( x_disp, CurrentTime ); + XUngrabKeyboard( x_disp, CurrentTime ); + XAutoRepeatOn( x_disp ); +} + +// +// IN_Commands - process buttons +// + +void IN_Commands (void) +{ + // done in X event handler +} + +// +// IN_Move - process mouse moves +// + +void +IN_Move (usercmd_t *cmd) +{ + static int last_dx, last_dy; + static long long last_movement; + long long now, gethrtime(); + + int dx, dy; + + CheckMouseState(); + + + if (!x_grabbed) + return; // no mouse movement + + + now = gethrtime(); + + dx = global_dx; + global_dx = 0; + + dy = global_dy; + global_dy = 0; + +// printf("GOT: dx %d dy %d\n", dx, dy); + + dx *= sensitivity.value; + dy *= sensitivity.value; + +// +// implement low pass filter to smooth motion a bit +// + if (now - last_movement > 100000000) { + dx = .6 * dx; + dy = .6 * dy; + } + last_movement = now; + + dx = .6 * dx + .4 * last_dx; + dy = .6 * dy + .4 * last_dy; + + + last_dx = dx; + last_dy = dy; + + if (!dx && !dy) { + if (in_mlook.state & 1) + V_StopPitchDrift (); + return; + } + + // add mouse X/Y movement to cmd + if ((in_strafe.state & 1) || (lookstrafe.value && (in_mlook.state & 1))) + cmd->sidemove += m_side.value * dx; + else + cl.viewangles[YAW] -= m_yaw.value * dx; + + if (in_mlook.state & 1) + V_StopPitchDrift (); + + if ((in_mlook.state & 1) && !(in_strafe.state & 1)) { + cl.viewangles[PITCH] += m_pitch.value * dy; + 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 * dy; + else cmd->forwardmove -= m_forward.value * dy; + } +} diff --git a/contrib/other/sdlquake-1.0.9/in_win.c b/contrib/other/sdlquake-1.0.9/in_win.c new file mode 100644 index 000000000..d8544fbd2 --- /dev/null +++ b/contrib/other/sdlquake-1.0.9/in_win.c @@ -0,0 +1,1239 @@ +/* +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. + +*/ +// in_win.c -- windows 95 mouse and joystick code +// 02/21/97 JCB Added extended DirectInput code to support external controllers. + +#include +#include "quakedef.h" +#include "winquake.h" +#include "dosisms.h" + +#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 +cvar_t m_filter = {"m_filter","0"}; + +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; + +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","0", true}; +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 + for (i=0 ; isidemove += m_side.value * mouse_x; + else + cl.viewangles[YAW] -= m_yaw.value * mouse_x; + + if (in_mlook.state & 1) + V_StopPitchDrift (); + + if ( (in_mlook.state & 1) && !(in_strafe.state & 1)) + { + 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 (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) && (in_mlook.state & 1)) + { + // 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 + if(lookspring.value == 0.0) + V_StopPitchDrift(); + } + } + 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 && (in_mlook.state & 1))) + { + // 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 (in_mlook.state & 1) + { + 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 + if(lookspring.value == 0.0) + V_StopPitchDrift(); + } + } + 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/contrib/other/sdlquake-1.0.9/input.h b/contrib/other/sdlquake-1.0.9/input.h new file mode 100644 index 000000000..c3daa1700 --- /dev/null +++ b/contrib/other/sdlquake-1.0.9/input.h @@ -0,0 +1,34 @@ +/* +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. + +*/ +// input.h -- external (non-keyboard) input devices + +void IN_Init (void); + +void IN_Shutdown (void); + +void IN_Commands (void); +// oportunity for devices to stick commands on the script buffer + +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 + diff --git a/contrib/other/sdlquake-1.0.9/install-sh b/contrib/other/sdlquake-1.0.9/install-sh new file mode 100644 index 000000000..e9de23842 --- /dev/null +++ b/contrib/other/sdlquake-1.0.9/install-sh @@ -0,0 +1,251 @@ +#!/bin/sh +# +# install - install a program, script, or datafile +# This comes from X11R5 (mit/util/scripts/install.sh). +# +# Copyright 1991 by the Massachusetts Institute of Technology +# +# Permission to use, copy, modify, distribute, and sell this software and its +# documentation for any purpose is hereby granted without fee, provided that +# the above copyright notice appear in all copies and that both that +# copyright notice and this permission notice appear in supporting +# documentation, and that the name of M.I.T. not be used in advertising or +# publicity pertaining to distribution of the software without specific, +# written prior permission. M.I.T. makes no representations about the +# suitability of this software for any purpose. It is provided "as is" +# without express or implied warranty. +# +# Calling this script install-sh is preferred over install.sh, to prevent +# `make' implicit rules from creating a file called install from it +# when there is no Makefile. +# +# This script is compatible with the BSD install script, but was written +# from scratch. It can only install one file at a time, a restriction +# shared with many OS's install programs. + + +# set DOITPROG to echo to test this script + +# Don't use :- since 4.3BSD and earlier shells don't like it. +doit="${DOITPROG-}" + + +# put in absolute paths if you don't have them in your path; or use env. vars. + +mvprog="${MVPROG-mv}" +cpprog="${CPPROG-cp}" +chmodprog="${CHMODPROG-chmod}" +chownprog="${CHOWNPROG-chown}" +chgrpprog="${CHGRPPROG-chgrp}" +stripprog="${STRIPPROG-strip}" +rmprog="${RMPROG-rm}" +mkdirprog="${MKDIRPROG-mkdir}" + +transformbasename="" +transform_arg="" +instcmd="$mvprog" +chmodcmd="$chmodprog 0755" +chowncmd="" +chgrpcmd="" +stripcmd="" +rmcmd="$rmprog -f" +mvcmd="$mvprog" +src="" +dst="" +dir_arg="" + +while [ x"$1" != x ]; do + case $1 in + -c) instcmd="$cpprog" + shift + continue;; + + -d) dir_arg=true + shift + continue;; + + -m) chmodcmd="$chmodprog $2" + shift + shift + continue;; + + -o) chowncmd="$chownprog $2" + shift + shift + continue;; + + -g) chgrpcmd="$chgrpprog $2" + shift + shift + continue;; + + -s) stripcmd="$stripprog" + shift + continue;; + + -t=*) transformarg=`echo $1 | sed 's/-t=//'` + shift + continue;; + + -b=*) transformbasename=`echo $1 | sed 's/-b=//'` + shift + continue;; + + *) if [ x"$src" = x ] + then + src=$1 + else + # this colon is to work around a 386BSD /bin/sh bug + : + dst=$1 + fi + shift + continue;; + esac +done + +if [ x"$src" = x ] +then + echo "install: no input file specified" + exit 1 +else + true +fi + +if [ x"$dir_arg" != x ]; then + dst=$src + src="" + + if [ -d $dst ]; then + instcmd=: + chmodcmd="" + else + instcmd=mkdir + fi +else + +# Waiting for this to be detected by the "$instcmd $src $dsttmp" command +# might cause directories to be created, which would be especially bad +# if $src (and thus $dsttmp) contains '*'. + + if [ -f $src -o -d $src ] + then + true + else + echo "install: $src does not exist" + exit 1 + fi + + if [ x"$dst" = x ] + then + echo "install: no destination specified" + exit 1 + else + true + fi + +# If destination is a directory, append the input filename; if your system +# does not like double slashes in filenames, you may need to add some logic + + if [ -d $dst ] + then + dst="$dst"/`basename $src` + else + true + fi +fi + +## this sed command emulates the dirname command +dstdir=`echo $dst | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'` + +# Make sure that the destination directory exists. +# this part is taken from Noah Friedman's mkinstalldirs script + +# Skip lots of stat calls in the usual case. +if [ ! -d "$dstdir" ]; then +defaultIFS=' +' +IFS="${IFS-${defaultIFS}}" + +oIFS="${IFS}" +# Some sh's can't handle IFS=/ for some reason. +IFS='%' +set - `echo ${dstdir} | sed -e 's@/@%@g' -e 's@^%@/@'` +IFS="${oIFS}" + +pathcomp='' + +while [ $# -ne 0 ] ; do + pathcomp="${pathcomp}${1}" + shift + + if [ ! -d "${pathcomp}" ] ; + then + $mkdirprog "${pathcomp}" + else + true + fi + + pathcomp="${pathcomp}/" +done +fi + +if [ x"$dir_arg" != x ] +then + $doit $instcmd $dst && + + if [ x"$chowncmd" != x ]; then $doit $chowncmd $dst; else true ; fi && + if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dst; else true ; fi && + if [ x"$stripcmd" != x ]; then $doit $stripcmd $dst; else true ; fi && + if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dst; else true ; fi +else + +# If we're going to rename the final executable, determine the name now. + + if [ x"$transformarg" = x ] + then + dstfile=`basename $dst` + else + dstfile=`basename $dst $transformbasename | + sed $transformarg`$transformbasename + fi + +# don't allow the sed command to completely eliminate the filename + + if [ x"$dstfile" = x ] + then + dstfile=`basename $dst` + else + true + fi + +# Make a temp file name in the proper directory. + + dsttmp=$dstdir/#inst.$$# + +# Move or copy the file name to the temp name + + $doit $instcmd $src $dsttmp && + + trap "rm -f ${dsttmp}" 0 && + +# and set any options; do chmod last to preserve setuid bits + +# If any of these fail, we abort the whole thing. If we want to +# ignore errors from any of these, just make sure not to ignore +# errors from the above "$doit $instcmd $src $dsttmp" command. + + if [ x"$chowncmd" != x ]; then $doit $chowncmd $dsttmp; else true;fi && + if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; else true;fi && + if [ x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; else true;fi && + if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; else true;fi && + +# Now rename the file to the real destination. + + $doit $rmcmd -f $dstdir/$dstfile && + $doit $mvcmd $dsttmp $dstdir/$dstfile + +fi && + + +exit 0 diff --git a/contrib/other/sdlquake-1.0.9/keys.c b/contrib/other/sdlquake-1.0.9/keys.c new file mode 100644 index 000000000..6e48ad484 --- /dev/null +++ b/contrib/other/sdlquake-1.0.9/keys.c @@ -0,0 +1,759 @@ +/* +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}, + + {"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/contrib/other/sdlquake-1.0.9/keys.h b/contrib/other/sdlquake-1.0.9/keys.h new file mode 100644 index 000000000..3fbefd080 --- /dev/null +++ b/contrib/other/sdlquake-1.0.9/keys.h @@ -0,0 +1,133 @@ +/* +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. + +*/ + +// +// these are the key numbers that should be passed to Key_Event +// +#define K_TAB 9 +#define K_ENTER 13 +#define K_ESCAPE 27 +#define K_SPACE 32 + +// normal keys should be passed as lowercased ascii + +#define K_BACKSPACE 127 +#define K_UPARROW 128 +#define K_DOWNARROW 129 +#define K_LEFTARROW 130 +#define K_RIGHTARROW 131 + +#define K_ALT 132 +#define K_CTRL 133 +#define K_SHIFT 134 +#define K_F1 135 +#define K_F2 136 +#define K_F3 137 +#define K_F4 138 +#define K_F5 139 +#define K_F6 140 +#define K_F7 141 +#define K_F8 142 +#define K_F9 143 +#define K_F10 144 +#define K_F11 145 +#define K_F12 146 +#define K_INS 147 +#define K_DEL 148 +#define K_PGDN 149 +#define K_PGUP 150 +#define K_HOME 151 +#define K_END 152 + +#define K_PAUSE 255 + +// +// mouse buttons generate virtual keys +// +#define K_MOUSE1 200 +#define K_MOUSE2 201 +#define K_MOUSE3 202 + +// +// joystick buttons +// +#define K_JOY1 203 +#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 +// +#define K_AUX1 207 +#define K_AUX2 208 +#define K_AUX3 209 +#define K_AUX4 210 +#define K_AUX5 211 +#define K_AUX6 212 +#define K_AUX7 213 +#define K_AUX8 214 +#define K_AUX9 215 +#define K_AUX10 216 +#define K_AUX11 217 +#define K_AUX12 218 +#define K_AUX13 219 +#define K_AUX14 220 +#define K_AUX15 221 +#define K_AUX16 222 +#define K_AUX17 223 +#define K_AUX18 224 +#define K_AUX19 225 +#define K_AUX20 226 +#define K_AUX21 227 +#define K_AUX22 228 +#define K_AUX23 229 +#define K_AUX24 230 +#define K_AUX25 231 +#define K_AUX26 232 +#define K_AUX27 233 +#define K_AUX28 234 +#define K_AUX29 235 +#define K_AUX30 236 +#define K_AUX31 237 +#define K_AUX32 238 + +// JACK: Intellimouse(c) Mouse Wheel Support + +#define K_MWHEELUP 239 +#define K_MWHEELDOWN 240 + + + +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; + +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); + diff --git a/contrib/other/sdlquake-1.0.9/makezip.bat b/contrib/other/sdlquake-1.0.9/makezip.bat new file mode 100644 index 000000000..96869539d --- /dev/null +++ b/contrib/other/sdlquake-1.0.9/makezip.bat @@ -0,0 +1 @@ +zip -9 -r code * -x *.obj -x *.sbr -x *.pch -x *.pdb -x *.o -x *.exe -x *.dll -x *.map -x *.bsc -x *.lib -x *.ilk -x *.exp -x *.idb -x *.zip diff --git a/contrib/other/sdlquake-1.0.9/math.S b/contrib/other/sdlquake-1.0.9/math.S new file mode 100644 index 000000000..00fcd09be --- /dev/null +++ b/contrib/other/sdlquake-1.0.9/math.S @@ -0,0 +1,418 @@ +/* +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. + +*/ +// +// math.s +// x86 assembly-language math routines. + +#define GLQUAKE 1 // don't include unneeded defs +#include "asm_i386.h" +#include "quakeasm.h" + + +#if id386 + + .data + + .align 4 +Ljmptab: .long Lcase0, Lcase1, Lcase2, Lcase3 + .long Lcase4, Lcase5, Lcase6, Lcase7 + + .text + +// TODO: rounding needed? +// stack parameter offset +#define val 4 + +.globl C(Invert24To16) +C(Invert24To16): + + movl val(%esp),%ecx + movl $0x100,%edx // 0x10000000000 as dividend + cmpl %edx,%ecx + jle LOutOfRange + + subl %eax,%eax + divl %ecx + + ret + +LOutOfRange: + movl $0xFFFFFFFF,%eax + ret + +#define in 4 +#define out 8 + + .align 2 +.globl C(TransformVector) +C(TransformVector): + movl in(%esp),%eax + movl out(%esp),%edx + + flds (%eax) // in[0] + fmuls C(vright) // in[0]*vright[0] + flds (%eax) // in[0] | in[0]*vright[0] + fmuls C(vup) // in[0]*vup[0] | in[0]*vright[0] + flds (%eax) // in[0] | in[0]*vup[0] | in[0]*vright[0] + fmuls C(vpn) // in[0]*vpn[0] | in[0]*vup[0] | in[0]*vright[0] + + flds 4(%eax) // in[1] | ... + fmuls C(vright)+4 // in[1]*vright[1] | ... + flds 4(%eax) // in[1] | in[1]*vright[1] | ... + fmuls C(vup)+4 // in[1]*vup[1] | in[1]*vright[1] | ... + flds 4(%eax) // in[1] | in[1]*vup[1] | in[1]*vright[1] | ... + fmuls C(vpn)+4 // in[1]*vpn[1] | in[1]*vup[1] | in[1]*vright[1] | ... + fxch %st(2) // in[1]*vright[1] | in[1]*vup[1] | in[1]*vpn[1] | ... + + faddp %st(0),%st(5) // in[1]*vup[1] | in[1]*vpn[1] | ... + faddp %st(0),%st(3) // in[1]*vpn[1] | ... + faddp %st(0),%st(1) // vpn_accum | vup_accum | vright_accum + + flds 8(%eax) // in[2] | ... + fmuls C(vright)+8 // in[2]*vright[2] | ... + flds 8(%eax) // in[2] | in[2]*vright[2] | ... + fmuls C(vup)+8 // in[2]*vup[2] | in[2]*vright[2] | ... + flds 8(%eax) // in[2] | in[2]*vup[2] | in[2]*vright[2] | ... + fmuls C(vpn)+8 // in[2]*vpn[2] | in[2]*vup[2] | in[2]*vright[2] | ... + fxch %st(2) // in[2]*vright[2] | in[2]*vup[2] | in[2]*vpn[2] | ... + + faddp %st(0),%st(5) // in[2]*vup[2] | in[2]*vpn[2] | ... + faddp %st(0),%st(3) // in[2]*vpn[2] | ... + faddp %st(0),%st(1) // vpn_accum | vup_accum | vright_accum + + fstps 8(%edx) // out[2] + fstps 4(%edx) // out[1] + fstps (%edx) // out[0] + + ret + + +#define EMINS 4+4 +#define EMAXS 4+8 +#define P 4+12 + + .align 2 +.globl C(BoxOnPlaneSide) +C(BoxOnPlaneSide): + pushl %ebx + + movl P(%esp),%edx + movl EMINS(%esp),%ecx + xorl %eax,%eax + movl EMAXS(%esp),%ebx + movb pl_signbits(%edx),%al + cmpb $8,%al + jge Lerror + flds pl_normal(%edx) // p->normal[0] + fld %st(0) // p->normal[0] | p->normal[0] + jmp Ljmptab(,%eax,4) + + +//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]; +Lcase0: + fmuls (%ebx) // p->normal[0]*emaxs[0] | p->normal[0] + flds pl_normal+4(%edx) // p->normal[1] | p->normal[0]*emaxs[0] | + // p->normal[0] + fxch %st(2) // p->normal[0] | p->normal[0]*emaxs[0] | + // p->normal[1] + fmuls (%ecx) // p->normal[0]*emins[0] | + // p->normal[0]*emaxs[0] | p->normal[1] + fxch %st(2) // p->normal[1] | p->normal[0]*emaxs[0] | + // p->normal[0]*emins[0] + fld %st(0) // p->normal[1] | p->normal[1] | + // p->normal[0]*emaxs[0] | + // p->normal[0]*emins[0] + fmuls 4(%ebx) // p->normal[1]*emaxs[1] | p->normal[1] | + // p->normal[0]*emaxs[0] | + // p->normal[0]*emins[0] + flds pl_normal+8(%edx) // p->normal[2] | p->normal[1]*emaxs[1] | + // p->normal[1] | p->normal[0]*emaxs[0] | + // p->normal[0]*emins[0] + fxch %st(2) // p->normal[1] | p->normal[1]*emaxs[1] | + // p->normal[2] | p->normal[0]*emaxs[0] | + // p->normal[0]*emins[0] + fmuls 4(%ecx) // p->normal[1]*emins[1] | + // p->normal[1]*emaxs[1] | + // p->normal[2] | p->normal[0]*emaxs[0] | + // p->normal[0]*emins[0] + fxch %st(2) // p->normal[2] | p->normal[1]*emaxs[1] | + // p->normal[1]*emins[1] | + // p->normal[0]*emaxs[0] | + // p->normal[0]*emins[0] + fld %st(0) // p->normal[2] | p->normal[2] | + // p->normal[1]*emaxs[1] | + // p->normal[1]*emins[1] | + // p->normal[0]*emaxs[0] | + // p->normal[0]*emins[0] + fmuls 8(%ebx) // p->normal[2]*emaxs[2] | + // p->normal[2] | + // p->normal[1]*emaxs[1] | + // p->normal[1]*emins[1] | + // p->normal[0]*emaxs[0] | + // p->normal[0]*emins[0] + fxch %st(5) // p->normal[0]*emins[0] | + // p->normal[2] | + // p->normal[1]*emaxs[1] | + // p->normal[1]*emins[1] | + // p->normal[0]*emaxs[0] | + // p->normal[2]*emaxs[2] + faddp %st(0),%st(3) //p->normal[2] | + // p->normal[1]*emaxs[1] | + // p->normal[1]*emins[1]+p->normal[0]*emins[0]| + // p->normal[0]*emaxs[0] | + // p->normal[2]*emaxs[2] + fmuls 8(%ecx) //p->normal[2]*emins[2] | + // p->normal[1]*emaxs[1] | + // p->normal[1]*emins[1]+p->normal[0]*emins[0]| + // p->normal[0]*emaxs[0] | + // p->normal[2]*emaxs[2] + fxch %st(1) //p->normal[1]*emaxs[1] | + // p->normal[2]*emins[2] | + // p->normal[1]*emins[1]+p->normal[0]*emins[0]| + // p->normal[0]*emaxs[0] | + // p->normal[2]*emaxs[2] + faddp %st(0),%st(3) //p->normal[2]*emins[2] | + // p->normal[1]*emins[1]+p->normal[0]*emins[0]| + // p->normal[0]*emaxs[0]+p->normal[1]*emaxs[1]| + // p->normal[2]*emaxs[2] + fxch %st(3) //p->normal[2]*emaxs[2] + + // p->normal[1]*emins[1]+p->normal[0]*emins[0]| + // p->normal[0]*emaxs[0]+p->normal[1]*emaxs[1]| + // p->normal[2]*emins[2] + faddp %st(0),%st(2) //p->normal[1]*emins[1]+p->normal[0]*emins[0]| + // dist1 | p->normal[2]*emins[2] + + jmp LSetSides + +//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]; +Lcase1: + fmuls (%ecx) // emins[0] + flds pl_normal+4(%edx) + fxch %st(2) + fmuls (%ebx) // emaxs[0] + fxch %st(2) + fld %st(0) + fmuls 4(%ebx) // emaxs[1] + flds pl_normal+8(%edx) + fxch %st(2) + fmuls 4(%ecx) // emins[1] + fxch %st(2) + fld %st(0) + fmuls 8(%ebx) // emaxs[2] + fxch %st(5) + faddp %st(0),%st(3) + fmuls 8(%ecx) // emins[2] + fxch %st(1) + faddp %st(0),%st(3) + fxch %st(3) + faddp %st(0),%st(2) + + jmp LSetSides + +//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]; +Lcase2: + fmuls (%ebx) // emaxs[0] + flds pl_normal+4(%edx) + fxch %st(2) + fmuls (%ecx) // emins[0] + fxch %st(2) + fld %st(0) + fmuls 4(%ecx) // emins[1] + flds pl_normal+8(%edx) + fxch %st(2) + fmuls 4(%ebx) // emaxs[1] + fxch %st(2) + fld %st(0) + fmuls 8(%ebx) // emaxs[2] + fxch %st(5) + faddp %st(0),%st(3) + fmuls 8(%ecx) // emins[2] + fxch %st(1) + faddp %st(0),%st(3) + fxch %st(3) + faddp %st(0),%st(2) + + jmp LSetSides + +//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]; +Lcase3: + fmuls (%ecx) // emins[0] + flds pl_normal+4(%edx) + fxch %st(2) + fmuls (%ebx) // emaxs[0] + fxch %st(2) + fld %st(0) + fmuls 4(%ecx) // emins[1] + flds pl_normal+8(%edx) + fxch %st(2) + fmuls 4(%ebx) // emaxs[1] + fxch %st(2) + fld %st(0) + fmuls 8(%ebx) // emaxs[2] + fxch %st(5) + faddp %st(0),%st(3) + fmuls 8(%ecx) // emins[2] + fxch %st(1) + faddp %st(0),%st(3) + fxch %st(3) + faddp %st(0),%st(2) + + jmp LSetSides + +//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]; +Lcase4: + fmuls (%ebx) // emaxs[0] + flds pl_normal+4(%edx) + fxch %st(2) + fmuls (%ecx) // emins[0] + fxch %st(2) + fld %st(0) + fmuls 4(%ebx) // emaxs[1] + flds pl_normal+8(%edx) + fxch %st(2) + fmuls 4(%ecx) // emins[1] + fxch %st(2) + fld %st(0) + fmuls 8(%ecx) // emins[2] + fxch %st(5) + faddp %st(0),%st(3) + fmuls 8(%ebx) // emaxs[2] + fxch %st(1) + faddp %st(0),%st(3) + fxch %st(3) + faddp %st(0),%st(2) + + jmp LSetSides + +//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]; +Lcase5: + fmuls (%ecx) // emins[0] + flds pl_normal+4(%edx) + fxch %st(2) + fmuls (%ebx) // emaxs[0] + fxch %st(2) + fld %st(0) + fmuls 4(%ebx) // emaxs[1] + flds pl_normal+8(%edx) + fxch %st(2) + fmuls 4(%ecx) // emins[1] + fxch %st(2) + fld %st(0) + fmuls 8(%ecx) // emins[2] + fxch %st(5) + faddp %st(0),%st(3) + fmuls 8(%ebx) // emaxs[2] + fxch %st(1) + faddp %st(0),%st(3) + fxch %st(3) + faddp %st(0),%st(2) + + jmp LSetSides + +//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]; +Lcase6: + fmuls (%ebx) // emaxs[0] + flds pl_normal+4(%edx) + fxch %st(2) + fmuls (%ecx) // emins[0] + fxch %st(2) + fld %st(0) + fmuls 4(%ecx) // emins[1] + flds pl_normal+8(%edx) + fxch %st(2) + fmuls 4(%ebx) // emaxs[1] + fxch %st(2) + fld %st(0) + fmuls 8(%ecx) // emins[2] + fxch %st(5) + faddp %st(0),%st(3) + fmuls 8(%ebx) // emaxs[2] + fxch %st(1) + faddp %st(0),%st(3) + fxch %st(3) + faddp %st(0),%st(2) + + jmp LSetSides + +//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]; +Lcase7: + fmuls (%ecx) // emins[0] + flds pl_normal+4(%edx) + fxch %st(2) + fmuls (%ebx) // emaxs[0] + fxch %st(2) + fld %st(0) + fmuls 4(%ecx) // emins[1] + flds pl_normal+8(%edx) + fxch %st(2) + fmuls 4(%ebx) // emaxs[1] + fxch %st(2) + fld %st(0) + fmuls 8(%ecx) // emins[2] + fxch %st(5) + faddp %st(0),%st(3) + fmuls 8(%ebx) // emaxs[2] + fxch %st(1) + faddp %st(0),%st(3) + fxch %st(3) + faddp %st(0),%st(2) + +LSetSides: + +// sides = 0; +// if (dist1 >= p->dist) +// sides = 1; +// if (dist2 < p->dist) +// sides |= 2; + + faddp %st(0),%st(2) // dist1 | dist2 + fcomps pl_dist(%edx) + xorl %ecx,%ecx + fnstsw %ax + fcomps pl_dist(%edx) + andb $1,%ah + xorb $1,%ah + addb %ah,%cl + + fnstsw %ax + andb $1,%ah + addb %ah,%ah + addb %ah,%cl + +// return sides; + + popl %ebx + movl %ecx,%eax // return status + + ret + + +Lerror: + call C(BOPS_Error) + +#endif // id386 diff --git a/contrib/other/sdlquake-1.0.9/mathlib.c b/contrib/other/sdlquake-1.0.9/mathlib.c new file mode 100644 index 000000000..9f5d6445f --- /dev/null +++ b/contrib/other/sdlquake-1.0.9/mathlib.c @@ -0,0 +1,585 @@ +/* +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. + +*/ +// mathlib.c -- math primitives + +#include +#include "quakedef.h" + +void Sys_Error (char *error, ...); + +vec3_t vec3_origin = {0,0,0}; +int nanmask = 255<<23; + +/*-----------------------------------------------------------------*/ + +#define DEG2RAD( a ) ( a * M_PI ) / 180.0F + +void ProjectPointOnPlane( vec3_t dst, const vec3_t p, const vec3_t normal ) +{ + float d; + vec3_t n; + float inv_denom; + + inv_denom = 1.0F / DotProduct( normal, normal ); + + d = DotProduct( normal, p ) * inv_denom; + + n[0] = normal[0] * inv_denom; + n[1] = normal[1] * inv_denom; + n[2] = normal[2] * inv_denom; + + dst[0] = p[0] - d * n[0]; + dst[1] = p[1] - d * n[1]; + dst[2] = p[2] - d * n[2]; +} + +/* +** assumes "src" is normalized +*/ +void PerpendicularVector( vec3_t dst, const vec3_t src ) +{ + int pos; + int i; + float minelem = 1.0F; + vec3_t tempvec; + + /* + ** find the smallest magnitude axially aligned vector + */ + for ( pos = 0, i = 0; i < 3; i++ ) + { + if ( fabs( src[i] ) < minelem ) + { + pos = i; + minelem = fabs( src[i] ); + } + } + tempvec[0] = tempvec[1] = tempvec[2] = 0.0F; + tempvec[pos] = 1.0F; + + /* + ** project the point onto the plane defined by src + */ + ProjectPointOnPlane( dst, tempvec, src ); + + /* + ** normalize the result + */ + 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 + +/*-----------------------------------------------------------------*/ + + +float anglemod(float a) +{ +#if 0 + if (a >= 0) + a -= 360*(int)(a/360); + else + a += 360*( 1 + (int)(-a/360) ); +#endif + a = (360.0/65536) * ((int)(a*(65536/360.0)) & 65535); + return a; +} + +/* +================== +BOPS_Error + +Split out like this for ASM to call. +================== +*/ +void BOPS_Error (void) +{ + Sys_Error ("BoxOnPlaneSide: Bad signbits"); +} + + +#if !id386 + +/* +================== +BoxOnPlaneSide + +Returns 1, 2, or 1 + 2 +================== +*/ +int BoxOnPlaneSide (vec3_t emins, vec3_t emaxs, mplane_t *p) +{ + float dist1, dist2; + int sides; + +#if 0 // this is done by the BOX_ON_PLANE_SIDE macro before calling this + // function +// fast axial cases + if (p->type < 3) + { + if (p->dist <= emins[p->type]) + return 1; + if (p->dist >= emaxs[p->type]) + return 2; + 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]; + 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]; + 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]; + 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]; + 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]; + 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]; + 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]; + 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]; + break; + default: + dist1 = dist2 = 0; // shut up compiler + BOPS_Error (); + break; + } + +#if 0 + int i; + vec3_t corners[2]; + + for (i=0 ; i<3 ; i++) + { + if (plane->normal[i] < 0) + { + corners[0][i] = emins[i]; + corners[1][i] = emaxs[i]; + } + else + { + corners[1][i] = emins[i]; + corners[0][i] = emaxs[i]; + } + } + dist = DotProduct (plane->normal, corners[0]) - plane->dist; + dist2 = DotProduct (plane->normal, corners[1]) - plane->dist; + sides = 0; + if (dist1 >= 0) + sides = 1; + if (dist2 < 0) + sides |= 2; + +#endif + + sides = 0; + if (dist1 >= p->dist) + sides = 1; + if (dist2 < p->dist) + sides |= 2; + +#ifdef PARANOID +if (sides == 0) + Sys_Error ("BoxOnPlaneSide: sides==0"); +#endif + + return sides; +} + +#endif + + +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); + angle = angles[PITCH] * (M_PI*2 / 360); + sp = sin(angle); + cp = cos(angle); + angle = angles[ROLL] * (M_PI*2 / 360); + sr = sin(angle); + cr = cos(angle); + + forward[0] = cp*cy; + forward[1] = cp*sy; + forward[2] = -sp; + right[0] = (-1*sr*sp*cy+-1*cr*-sy); + right[1] = (-1*sr*sp*sy+-1*cr*cy); + right[2] = -1*sr*cp; + up[0] = (cr*sp*cy+-sr*-sy); + up[1] = (cr*sp*sy+-sr*cy); + up[2] = cr*cp; +} + +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; +} + +void VectorMA (vec3_t veca, float scale, vec3_t vecb, vec3_t vecc) +{ + vecc[0] = veca[0] + scale*vecb[0]; + vecc[1] = veca[1] + scale*vecb[1]; + vecc[2] = veca[2] + scale*vecb[2]; +} + + +vec_t _DotProduct (vec3_t v1, vec3_t v2) +{ + return v1[0]*v2[0] + v1[1]*v2[1] + v1[2]*v2[2]; +} + +void _VectorSubtract (vec3_t veca, vec3_t vecb, vec3_t out) +{ + out[0] = veca[0]-vecb[0]; + out[1] = veca[1]-vecb[1]; + out[2] = veca[2]-vecb[2]; +} + +void _VectorAdd (vec3_t veca, vec3_t vecb, vec3_t out) +{ + out[0] = veca[0]+vecb[0]; + out[1] = veca[1]+vecb[1]; + out[2] = veca[2]+vecb[2]; +} + +void _VectorCopy (vec3_t in, vec3_t out) +{ + out[0] = in[0]; + out[1] = in[1]; + out[2] = in[2]; +} + +void CrossProduct (vec3_t v1, vec3_t v2, vec3_t cross) +{ + cross[0] = v1[1]*v2[2] - v1[2]*v2[1]; + cross[1] = v1[2]*v2[0] - v1[0]*v2[2]; + cross[2] = v1[0]*v2[1] - v1[1]*v2[0]; +} + +double sqrt(double x); + +vec_t Length(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; +} + +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 + + if (length) + { + ilength = 1/length; + v[0] *= ilength; + v[1] *= ilength; + v[2] *= ilength; + } + + return length; + +} + +void VectorInverse (vec3_t v) +{ + v[0] = -v[0]; + v[1] = -v[1]; + v[2] = -v[2]; +} + +void VectorScale (vec3_t in, vec_t scale, vec3_t out) +{ + out[0] = in[0]*scale; + out[1] = in[1]*scale; + out[2] = in[2]*scale; +} + + +int Q_log2(int val) +{ + int answer=0; + while (val>>=1) + answer++; + return answer; +} + + +/* +================ +R_ConcatRotations +================ +*/ +void R_ConcatRotations (float in1[3][3], float in2[3][3], float out[3][3]) +{ + out[0][0] = in1[0][0] * in2[0][0] + in1[0][1] * in2[1][0] + + in1[0][2] * in2[2][0]; + out[0][1] = in1[0][0] * in2[0][1] + in1[0][1] * in2[1][1] + + in1[0][2] * in2[2][1]; + out[0][2] = in1[0][0] * in2[0][2] + in1[0][1] * in2[1][2] + + in1[0][2] * in2[2][2]; + out[1][0] = in1[1][0] * in2[0][0] + in1[1][1] * in2[1][0] + + in1[1][2] * in2[2][0]; + out[1][1] = in1[1][0] * in2[0][1] + in1[1][1] * in2[1][1] + + in1[1][2] * in2[2][1]; + out[1][2] = in1[1][0] * in2[0][2] + in1[1][1] * in2[1][2] + + in1[1][2] * in2[2][2]; + out[2][0] = in1[2][0] * in2[0][0] + in1[2][1] * in2[1][0] + + in1[2][2] * in2[2][0]; + out[2][1] = in1[2][0] * in2[0][1] + in1[2][1] * in2[1][1] + + in1[2][2] * in2[2][1]; + out[2][2] = in1[2][0] * in2[0][2] + in1[2][1] * in2[1][2] + + in1[2][2] * in2[2][2]; +} + + +/* +================ +R_ConcatTransforms +================ +*/ +void R_ConcatTransforms (float in1[3][4], float in2[3][4], float out[3][4]) +{ + out[0][0] = in1[0][0] * in2[0][0] + in1[0][1] * in2[1][0] + + in1[0][2] * in2[2][0]; + out[0][1] = in1[0][0] * in2[0][1] + in1[0][1] * in2[1][1] + + in1[0][2] * in2[2][1]; + out[0][2] = in1[0][0] * in2[0][2] + in1[0][1] * in2[1][2] + + in1[0][2] * in2[2][2]; + out[0][3] = in1[0][0] * in2[0][3] + in1[0][1] * in2[1][3] + + in1[0][2] * in2[2][3] + in1[0][3]; + out[1][0] = in1[1][0] * in2[0][0] + in1[1][1] * in2[1][0] + + in1[1][2] * in2[2][0]; + out[1][1] = in1[1][0] * in2[0][1] + in1[1][1] * in2[1][1] + + in1[1][2] * in2[2][1]; + out[1][2] = in1[1][0] * in2[0][2] + in1[1][1] * in2[1][2] + + in1[1][2] * in2[2][2]; + out[1][3] = in1[1][0] * in2[0][3] + in1[1][1] * in2[1][3] + + in1[1][2] * in2[2][3] + in1[1][3]; + out[2][0] = in1[2][0] * in2[0][0] + in1[2][1] * in2[1][0] + + in1[2][2] * in2[2][0]; + out[2][1] = in1[2][0] * in2[0][1] + in1[2][1] * in2[1][1] + + in1[2][2] * in2[2][1]; + out[2][2] = in1[2][0] * in2[0][2] + in1[2][1] * in2[1][2] + + in1[2][2] * in2[2][2]; + out[2][3] = in1[2][0] * in2[0][3] + in1[2][1] * in2[1][3] + + in1[2][2] * in2[2][3] + in1[2][3]; +} + + +/* +=================== +FloorDivMod + +Returns mathematically correct (floor-based) quotient and remainder for +numer and denom, both of which should contain no fractional part. The +quotient must fit in 32 bits. +==================== +*/ + +void FloorDivMod (double numer, double denom, int *quotient, + int *rem) +{ + int q, r; + double x; + +#ifndef PARANOID + if (denom <= 0.0) + Sys_Error ("FloorDivMod: bad denominator %d\n", denom); + +// if ((floor(numer) != numer) || (floor(denom) != denom)) +// Sys_Error ("FloorDivMod: non-integer numer or denom %f %f\n", +// numer, denom); +#endif + + if (numer >= 0.0) + { + + x = floor(numer / denom); + q = (int)x; + r = (int)floor(numer - (x * denom)); + } + else + { + // + // perform operations with positive values, and fix mod to make floor-based + // + x = floor(-numer / denom); + q = -(int)x; + r = (int)floor(-numer - (x * denom)); + if (r != 0) + { + q--; + r = (int)denom - r; + } + } + + *quotient = q; + *rem = r; +} + + +/* +=================== +GreatestCommonDivisor +==================== +*/ +int GreatestCommonDivisor (int i1, int i2) +{ + if (i1 > i2) + { + if (i2 == 0) + return (i1); + return GreatestCommonDivisor (i2, i1 % i2); + } + else + { + if (i1 == 0) + return (i2); + return GreatestCommonDivisor (i1, i2 % i1); + } +} + + +#if !id386 + +// TODO: move to nonintel.c + +/* +=================== +Invert24To16 + +Inverts an 8.24 value to a 16.16 value +==================== +*/ + +fixed16_t Invert24To16(fixed16_t val) +{ + if (val < 256) + return (0xFFFFFFFF); + + return (fixed16_t) + (((double)0x10000 * (double)0x1000000 / (double)val) + 0.5); +} + +#endif diff --git a/contrib/other/sdlquake-1.0.9/mathlib.h b/contrib/other/sdlquake-1.0.9/mathlib.h new file mode 100644 index 000000000..b5506e2b8 --- /dev/null +++ b/contrib/other/sdlquake-1.0.9/mathlib.h @@ -0,0 +1,89 @@ +/* +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. + +*/ +// mathlib.h + +typedef float vec_t; +typedef vec_t vec3_t[3]; +typedef vec_t vec5_t[5]; + +typedef int fixed4_t; +typedef int fixed8_t; +typedef int fixed16_t; + +#ifndef M_PI +#define M_PI 3.14159265358979323846 // matches value in gcc v2 math.h +#endif + +struct mplane_s; + +extern vec3_t vec3_origin; +extern int nanmask; + +#define IS_NAN(x) (((*(int *)&x)&nanmask)==nanmask) + +#define DotProduct(x,y) (x[0]*y[0]+x[1]*y[1]+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];} + +void VectorMA (vec3_t veca, float scale, vec3_t vecb, vec3_t vecc); + +vec_t _DotProduct (vec3_t v1, vec3_t v2); +void _VectorSubtract (vec3_t veca, vec3_t vecb, vec3_t out); +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); +void CrossProduct (vec3_t v1, vec3_t v2, vec3_t cross); +float VectorNormalize (vec3_t v); // returns vector length +void VectorInverse (vec3_t v); +void VectorScale (vec3_t in, vec_t scale, vec3_t out); +int Q_log2(int val); + +void R_ConcatRotations (float in1[3][3], float in2[3][3], float out[3][3]); +void R_ConcatTransforms (float in1[3][4], float in2[3][4], float out[3][4]); + +void FloorDivMod (double numer, double denom, int *quotient, + int *rem); +fixed16_t Invert24To16(fixed16_t val); +int GreatestCommonDivisor (int i1, int i2); + +void AngleVectors (vec3_t angles, vec3_t forward, vec3_t right, vec3_t up); +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)? \ + ( \ + ((p)->dist <= (emins)[(p)->type])? \ + 1 \ + : \ + ( \ + ((p)->dist >= (emaxs)[(p)->type])?\ + 2 \ + : \ + 3 \ + ) \ + ) \ + : \ + BoxOnPlaneSide( (emins), (emaxs), (p))) diff --git a/contrib/other/sdlquake-1.0.9/menu.c b/contrib/other/sdlquake-1.0.9/menu.c new file mode 100644 index 000000000..c3c7ebdd9 --- /dev/null +++ b/contrib/other/sdlquake-1.0.9/menu.c @@ -0,0 +1,3231 @@ +/* +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 _WIN32 +#include "winquake.h" +#endif + +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; + +void M_Menu_Main_f (void); + void M_Menu_SinglePlayer_f (void); + void M_Menu_Load_f (void); + void M_Menu_Save_f (void); + void M_Menu_MultiPlayer_f (void); + void M_Menu_Setup_f (void); + void M_Menu_Net_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); + void M_Load_Draw (void); + void M_Save_Draw (void); + void M_MultiPlayer_Draw (void); + void M_Setup_Draw (void); + void M_Net_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); + void M_Load_Key (int key); + void M_Save_Key (int key); + void M_MultiPlayer_Key (int key); + void M_Setup_Key (int key); + void M_Net_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; +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) + +void M_ConfigureNetSubsystem(void); + +/* +================ +M_DrawCharacter + +Draws one solid graphics character +================ +*/ +void M_DrawCharacter (int cx, int line, int num) +{ + Draw_Character ( cx + ((vid.width - 320)>>1), line, num); +} + +void M_Print (int cx, int cy, char *str) +{ + while (*str) + { + M_DrawCharacter (cx, cy, (*str)+128); + str++; + cx += 8; + } +} + +void M_PrintWhite (int cx, int cy, char *str) +{ + while (*str) + { + M_DrawCharacter (cx, cy, *str); + str++; + cx += 8; + } +} + +void M_DrawTransPic (int x, int y, qpic_t *pic) +{ + Draw_TransPic (x + ((vid.width - 320)>>1), y, pic); +} + +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]; +} + + +void M_DrawTransPicTranslate (int x, int y, qpic_t *pic) +{ + Draw_TransPicTranslate (x + ((vid.width - 320)>>1), y, pic, translationTable); +} + + +void M_DrawTextBox (int x, int y, int width, int lines) +{ + qpic_t *p; + int cx, cy; + int n; + + // draw left side + cx = x; + cy = y; + p = Draw_CachePic ("gfx/box_tl.lmp"); + M_DrawTransPic (cx, cy, p); + p = Draw_CachePic ("gfx/box_ml.lmp"); + for (n = 0; n < lines; n++) + { + cy += 8; + M_DrawTransPic (cx, cy, p); + } + p = Draw_CachePic ("gfx/box_bl.lmp"); + M_DrawTransPic (cx, cy+8, p); + + // draw middle + cx += 8; + while (width > 0) + { + cy = y; + p = Draw_CachePic ("gfx/box_tm.lmp"); + M_DrawTransPic (cx, cy, p); + p = Draw_CachePic ("gfx/box_mm.lmp"); + for (n = 0; n < lines; n++) + { + cy += 8; + if (n == 1) + p = Draw_CachePic ("gfx/box_mm2.lmp"); + M_DrawTransPic (cx, cy, p); + } + p = Draw_CachePic ("gfx/box_bm.lmp"); + M_DrawTransPic (cx, cy+8, p); + width -= 2; + cx += 16; + } + + // draw right side + cy = y; + p = Draw_CachePic ("gfx/box_tr.lmp"); + M_DrawTransPic (cx, cy, p); + p = Draw_CachePic ("gfx/box_mr.lmp"); + for (n = 0; n < lines; n++) + { + cy += 8; + M_DrawTransPic (cx, cy, p); + } + p = Draw_CachePic ("gfx/box_br.lmp"); + M_DrawTransPic (cx, cy+8, p); +} + +//============================================================================= + +int m_save_demonum; + +/* +================ +M_ToggleMenu_f +================ +*/ +void M_ToggleMenu_f (void) +{ + m_entersound = true; + + if (key_dest == key_menu) + { + if (m_state != m_main) + { + M_Menu_Main_f (); + return; + } + key_dest = key_game; + m_state = m_none; + return; + } + if (key_dest == key_console) + { + Con_ToggleConsole_f (); + } + else + { + M_Menu_Main_f (); + } +} + + +//============================================================================= +/* MAIN MENU */ + +int m_main_cursor; +#define MAIN_ITEMS 5 + + +void M_Menu_Main_f (void) +{ + if (key_dest != key_menu) + { + m_save_demonum = cls.demonum; + cls.demonum = -1; + } + key_dest = key_menu; + m_state = m_main; + m_entersound = true; +} + + +void M_Main_Draw (void) +{ + int f; + qpic_t *p; + + M_DrawTransPic (16, 4, Draw_CachePic ("gfx/qplaque.lmp") ); + p = Draw_CachePic ("gfx/ttl_main.lmp"); + M_DrawPic ( (320-p->width)/2, 4, p); + M_DrawTransPic (72, 32, Draw_CachePic ("gfx/mainmenu.lmp") ); + + f = (int)(host_time * 10)%6; + + M_DrawTransPic (54, 32 + m_main_cursor * 20,Draw_CachePic( va("gfx/menudot%i.lmp", f+1 ) ) ); +} + + +void M_Main_Key (int key) +{ + switch (key) + { + case K_ESCAPE: + key_dest = key_game; + m_state = m_none; + cls.demonum = m_save_demonum; + if (cls.demonum != -1 && !cls.demoplayback && cls.state != ca_connected) + CL_NextDemo (); + break; + + case K_DOWNARROW: + S_LocalSound ("misc/menu1.wav"); + if (++m_main_cursor >= MAIN_ITEMS) + m_main_cursor = 0; + break; + + case K_UPARROW: + S_LocalSound ("misc/menu1.wav"); + if (--m_main_cursor < 0) + m_main_cursor = MAIN_ITEMS - 1; + break; + + case K_ENTER: + m_entersound = true; + + switch (m_main_cursor) + { + case 0: + M_Menu_SinglePlayer_f (); + break; + + case 1: + M_Menu_MultiPlayer_f (); + break; + + case 2: + M_Menu_Options_f (); + break; + + case 3: + M_Menu_Help_f (); + break; + + case 4: + M_Menu_Quit_f (); + break; + } + } +} + +//============================================================================= +/* SINGLE PLAYER MENU */ + +int m_singleplayer_cursor; +#define SINGLEPLAYER_ITEMS 3 + + +void M_Menu_SinglePlayer_f (void) +{ + key_dest = key_menu; + m_state = m_singleplayer; + m_entersound = true; +} + + +void M_SinglePlayer_Draw (void) +{ + int f; + qpic_t *p; + + M_DrawTransPic (16, 4, Draw_CachePic ("gfx/qplaque.lmp") ); + p = Draw_CachePic ("gfx/ttl_sgl.lmp"); + M_DrawPic ( (320-p->width)/2, 4, p); + M_DrawTransPic (72, 32, Draw_CachePic ("gfx/sp_menu.lmp") ); + + f = (int)(host_time * 10)%6; + + M_DrawTransPic (54, 32 + m_singleplayer_cursor * 20,Draw_CachePic( va("gfx/menudot%i.lmp", f+1 ) ) ); +} + + +void M_SinglePlayer_Key (int key) +{ + switch (key) + { + case K_ESCAPE: + M_Menu_Main_f (); + break; + + case K_DOWNARROW: + S_LocalSound ("misc/menu1.wav"); + if (++m_singleplayer_cursor >= SINGLEPLAYER_ITEMS) + m_singleplayer_cursor = 0; + break; + + case K_UPARROW: + S_LocalSound ("misc/menu1.wav"); + if (--m_singleplayer_cursor < 0) + m_singleplayer_cursor = SINGLEPLAYER_ITEMS - 1; + break; + + case K_ENTER: + 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")) + break; + key_dest = key_game; + if (sv.active) + Cbuf_AddText ("disconnect\n"); + Cbuf_AddText ("maxplayers 1\n"); + Cbuf_AddText ("map start\n"); + break; + + case 1: + M_Menu_Load_f (); + break; + + case 2: + M_Menu_Save_f (); + break; + } + } +} + +//============================================================================= +/* LOAD/SAVE MENU */ + +int load_cursor; // 0 < load_cursor < MAX_SAVEGAMES + +#define MAX_SAVEGAMES 12 +char m_filenames[MAX_SAVEGAMES][SAVEGAME_COMMENT_LENGTH+1]; +int loadable[MAX_SAVEGAMES]; + +void M_ScanSaves (void) +{ + int i, j; + char name[MAX_OSPATH]; + FILE *f; + int version; + + for (i=0 ; iwidth)/2, 4, p); + + for (i=0 ; i< MAX_SAVEGAMES; i++) + M_Print (16, 32 + 8*i, m_filenames[i]); + +// line cursor + M_DrawCharacter (8, 32 + load_cursor*8, 12+((int)(realtime*4)&1)); +} + + +void M_Save_Draw (void) +{ + int i; + qpic_t *p; + + p = Draw_CachePic ("gfx/p_save.lmp"); + M_DrawPic ( (320-p->width)/2, 4, p); + + for (i=0 ; i= MAX_SAVEGAMES) + load_cursor = 0; + break; + } +} + + +void M_Save_Key (int k) +{ + switch (k) + { + case K_ESCAPE: + M_Menu_SinglePlayer_f (); + break; + + case K_ENTER: + m_state = m_none; + key_dest = key_game; + Cbuf_AddText (va("save s%i\n", load_cursor)); + return; + + case K_UPARROW: + case K_LEFTARROW: + S_LocalSound ("misc/menu1.wav"); + load_cursor--; + if (load_cursor < 0) + load_cursor = MAX_SAVEGAMES-1; + break; + + case K_DOWNARROW: + case K_RIGHTARROW: + S_LocalSound ("misc/menu1.wav"); + load_cursor++; + if (load_cursor >= MAX_SAVEGAMES) + load_cursor = 0; + break; + } +} + +//============================================================================= +/* MULTIPLAYER MENU */ + +int m_multiplayer_cursor; +#define MULTIPLAYER_ITEMS 3 + + +void M_Menu_MultiPlayer_f (void) +{ + key_dest = key_menu; + m_state = m_multiplayer; + m_entersound = true; +} + + +void M_MultiPlayer_Draw (void) +{ + int f; + qpic_t *p; + + M_DrawTransPic (16, 4, Draw_CachePic ("gfx/qplaque.lmp") ); + p = Draw_CachePic ("gfx/p_multi.lmp"); + M_DrawPic ( (320-p->width)/2, 4, p); + M_DrawTransPic (72, 32, Draw_CachePic ("gfx/mp_menu.lmp") ); + + f = (int)(host_time * 10)%6; + + M_DrawTransPic (54, 32 + m_multiplayer_cursor * 20,Draw_CachePic( va("gfx/menudot%i.lmp", f+1 ) ) ); + + if (serialAvailable || ipxAvailable || tcpipAvailable) + return; + M_PrintWhite ((320/2) - ((27*8)/2), 148, "No Communications Available"); +} + + +void M_MultiPlayer_Key (int key) +{ + switch (key) + { + case K_ESCAPE: + M_Menu_Main_f (); + break; + + case K_DOWNARROW: + S_LocalSound ("misc/menu1.wav"); + if (++m_multiplayer_cursor >= MULTIPLAYER_ITEMS) + m_multiplayer_cursor = 0; + break; + + case K_UPARROW: + S_LocalSound ("misc/menu1.wav"); + if (--m_multiplayer_cursor < 0) + m_multiplayer_cursor = MULTIPLAYER_ITEMS - 1; + break; + + case K_ENTER: + m_entersound = true; + switch (m_multiplayer_cursor) + { + case 0: + if (serialAvailable || ipxAvailable || tcpipAvailable) + M_Menu_Net_f (); + break; + + case 1: + if (serialAvailable || ipxAvailable || tcpipAvailable) + M_Menu_Net_f (); + break; + + case 2: + M_Menu_Setup_f (); + break; + } + } +} + +//============================================================================= +/* SETUP MENU */ + +int setup_cursor = 4; +int setup_cursor_table[] = {40, 56, 80, 104, 140}; + +char setup_hostname[16]; +char setup_myname[16]; +int setup_oldtop; +int setup_oldbottom; +int setup_top; +int setup_bottom; + +#define NUM_SETUP_CMDS 5 + +void M_Menu_Setup_f (void) +{ + key_dest = key_menu; + m_state = m_setup; + m_entersound = true; + Q_strcpy(setup_myname, cl_name.string); + Q_strcpy(setup_hostname, hostname.string); + setup_top = setup_oldtop = ((int)cl_color.value) >> 4; + setup_bottom = setup_oldbottom = ((int)cl_color.value) & 15; +} + + +void M_Setup_Draw (void) +{ + qpic_t *p; + + M_DrawTransPic (16, 4, Draw_CachePic ("gfx/qplaque.lmp") ); + p = Draw_CachePic ("gfx/p_multi.lmp"); + M_DrawPic ( (320-p->width)/2, 4, p); + + M_Print (64, 40, "Hostname"); + M_DrawTextBox (160, 32, 16, 1); + M_Print (168, 40, setup_hostname); + + M_Print (64, 56, "Your name"); + M_DrawTextBox (160, 48, 16, 1); + M_Print (168, 56, setup_myname); + + M_Print (64, 80, "Shirt color"); + M_Print (64, 104, "Pants color"); + + M_DrawTextBox (64, 140-8, 14, 1); + M_Print (72, 140, "Accept Changes"); + + 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_DrawCharacter (56, setup_cursor_table [setup_cursor], 12+((int)(realtime*4)&1)); + + if (setup_cursor == 0) + M_DrawCharacter (168 + 8*strlen(setup_hostname), setup_cursor_table [setup_cursor], 10+((int)(realtime*4)&1)); + + if (setup_cursor == 1) + M_DrawCharacter (168 + 8*strlen(setup_myname), setup_cursor_table [setup_cursor], 10+((int)(realtime*4)&1)); +} + + +void M_Setup_Key (int k) +{ + int l; + + switch (k) + { + case K_ESCAPE: + M_Menu_MultiPlayer_f (); + break; + + case K_UPARROW: + S_LocalSound ("misc/menu1.wav"); + setup_cursor--; + if (setup_cursor < 0) + setup_cursor = NUM_SETUP_CMDS-1; + break; + + case K_DOWNARROW: + S_LocalSound ("misc/menu1.wav"); + setup_cursor++; + if (setup_cursor >= NUM_SETUP_CMDS) + setup_cursor = 0; + break; + + case K_LEFTARROW: + if (setup_cursor < 2) + return; + S_LocalSound ("misc/menu3.wav"); + if (setup_cursor == 2) + setup_top = setup_top - 1; + if (setup_cursor == 3) + setup_bottom = setup_bottom - 1; + break; + case K_RIGHTARROW: + if (setup_cursor < 2) + return; +forward: + S_LocalSound ("misc/menu3.wav"); + if (setup_cursor == 2) + setup_top = setup_top + 1; + if (setup_cursor == 3) + setup_bottom = setup_bottom + 1; + break; + + case K_ENTER: + if (setup_cursor == 0 || setup_cursor == 1) + return; + + if (setup_cursor == 2 || setup_cursor == 3) + goto forward; + + // setup_cursor == 4 (OK) + if (Q_strcmp(cl_name.string, setup_myname) != 0) + Cbuf_AddText ( va ("name \"%s\"\n", setup_myname) ); + if (Q_strcmp(hostname.string, setup_hostname) != 0) + Cvar_Set("hostname", setup_hostname); + if (setup_top != setup_oldtop || setup_bottom != setup_oldbottom) + Cbuf_AddText( va ("color %i %i\n", setup_top, setup_bottom) ); + m_entersound = true; + M_Menu_MultiPlayer_f (); + break; + + case K_BACKSPACE: + if (setup_cursor == 0) + { + if (strlen(setup_hostname)) + setup_hostname[strlen(setup_hostname)-1] = 0; + } + + if (setup_cursor == 1) + { + if (strlen(setup_myname)) + 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) + setup_top = 0; + if (setup_top < 0) + setup_top = 13; + if (setup_bottom > 13) + setup_bottom = 0; + if (setup_bottom < 0) + setup_bottom = 13; +} + +//============================================================================= +/* NET MENU */ + +int m_net_cursor; +int m_net_items; +int m_net_saveHeight; + +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. ", + " ", + "(LAN=Local Area Network)", + + " Commonly used to play ", + " over the Internet, but ", + " also used on a Local ", + " Area Network. " +}; + +void M_Menu_Net_f (void) +{ + key_dest = key_menu; + m_state = m_net; + m_entersound = true; + m_net_items = 4; + + if (m_net_cursor >= m_net_items) + m_net_cursor = 0; + m_net_cursor--; + M_Net_Key (K_DOWNARROW); +} + + +void M_Net_Draw (void) +{ + int f; + qpic_t *p; + + M_DrawTransPic (16, 4, Draw_CachePic ("gfx/qplaque.lmp") ); + p = Draw_CachePic ("gfx/p_multi.lmp"); + M_DrawPic ( (320-p->width)/2, 4, p); + + 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 + p = Draw_CachePic ("gfx/dim_ipx.lmp"); + M_DrawTransPic (72, f, p); + + f += 19; + if (tcpipAvailable) + p = Draw_CachePic ("gfx/netmen4.lmp"); + else + 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); + 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]); + + f = (int)(host_time * 10)%6; + M_DrawTransPic (54, 32 + m_net_cursor * 20,Draw_CachePic( va("gfx/menudot%i.lmp", f+1 ) ) ); +} + + +void M_Net_Key (int k) +{ +again: + switch (k) + { + case K_ESCAPE: + M_Menu_MultiPlayer_f (); + break; + + case K_DOWNARROW: + S_LocalSound ("misc/menu1.wav"); + if (++m_net_cursor >= m_net_items) + m_net_cursor = 0; + break; + + case K_UPARROW: + S_LocalSound ("misc/menu1.wav"); + if (--m_net_cursor < 0) + m_net_cursor = m_net_items - 1; + break; + + case K_ENTER: + 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; + } + } + + if (m_net_cursor == 0 && !serialAvailable) + goto again; + if (m_net_cursor == 1 && !serialAvailable) + goto again; + if (m_net_cursor == 2 && !ipxAvailable) + goto again; + if (m_net_cursor == 3 && !tcpipAvailable) + goto again; +} + +//============================================================================= +/* OPTIONS MENU */ + +#ifdef _WIN32 +#define OPTIONS_ITEMS 14 +#else +#define OPTIONS_ITEMS 13 +#endif + +#define SLIDER_RANGE 10 + +int options_cursor; + +void M_Menu_Options_f (void) +{ + key_dest = key_menu; + m_state = m_options; + m_entersound = true; + +#ifdef _WIN32 + if ((options_cursor == 13) && (modestate != MS_WINDOWED)) + { + options_cursor = 0; + } +#endif +} + + +void M_AdjustSliders (int dir) +{ + S_LocalSound ("misc/menu3.wav"); + + switch (options_cursor) + { + case 3: // screen size + scr_viewsize.value += dir * 10; + if (scr_viewsize.value < 30) + scr_viewsize.value = 30; + if (scr_viewsize.value > 120) + scr_viewsize.value = 120; + Cvar_SetValue ("viewsize", scr_viewsize.value); + break; + case 4: // 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; + case 5: // 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 6: // music volume +#ifdef _WIN32 + bgmvolume.value += dir * 1.0; +#else + bgmvolume.value += dir * 0.1; +#endif + if (bgmvolume.value < 0) + bgmvolume.value = 0; + if (bgmvolume.value > 1) + bgmvolume.value = 1; + Cvar_SetValue ("bgmvolume", bgmvolume.value); + break; + case 7: // 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 8: // allways run + if (cl_forwardspeed.value > 200) + { + Cvar_SetValue ("cl_forwardspeed", 200); + Cvar_SetValue ("cl_backspeed", 200); + } + else + { + Cvar_SetValue ("cl_forwardspeed", 400); + Cvar_SetValue ("cl_backspeed", 400); + } + break; + + case 9: // invert mouse + Cvar_SetValue ("m_pitch", -m_pitch.value); + break; + + case 10: // lookspring + Cvar_SetValue ("lookspring", !lookspring.value); + break; + + case 11: // lookstrafe + Cvar_SetValue ("lookstrafe", !lookstrafe.value); + break; + +#ifdef _WIN32 + case 13: // _windowed_mouse + Cvar_SetValue ("_windowed_mouse", !_windowed_mouse.value); + break; +#endif + } +} + + +void M_DrawSlider (int x, int y, float range) +{ + int i; + + if (range < 0) + range = 0; + 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, 48, " Reset to defaults"); + + M_Print (16, 56, " Screen size"); + r = (scr_viewsize.value - 30) / (120 - 30); + M_DrawSlider (220, 56, r); + + M_Print (16, 64, " Brightness"); + r = (1.0 - v_gamma.value) / 0.5; + M_DrawSlider (220, 64, r); + + M_Print (16, 72, " Mouse Speed"); + r = (sensitivity.value - 1)/10; + M_DrawSlider (220, 72, r); + + M_Print (16, 80, " CD Music Volume"); + r = bgmvolume.value; + M_DrawSlider (220, 80, r); + + M_Print (16, 88, " Sound Volume"); + r = volume.value; + M_DrawSlider (220, 88, r); + + M_Print (16, 96, " Always Run"); + M_DrawCheckbox (220, 96, cl_forwardspeed.value > 200); + + M_Print (16, 104, " Invert Mouse"); + M_DrawCheckbox (220, 104, m_pitch.value < 0); + + M_Print (16, 112, " Lookspring"); + M_DrawCheckbox (220, 112, lookspring.value); + + M_Print (16, 120, " Lookstrafe"); + M_DrawCheckbox (220, 120, lookstrafe.value); + + if (vid_menudrawfn) + M_Print (16, 128, " Video Options"); + +#ifdef _WIN32 + if (modestate == MS_WINDOWED) + { + M_Print (16, 136, " Use Mouse"); + M_DrawCheckbox (220, 136, _windowed_mouse.value); + } +#endif + +// cursor + M_DrawCharacter (200, 32 + options_cursor*8, 12+((int)(realtime*4)&1)); +} + + +void M_Options_Key (int k) +{ + switch (k) + { + case K_ESCAPE: + M_Menu_Main_f (); + break; + + case K_ENTER: + m_entersound = true; + switch (options_cursor) + { + case 0: + M_Menu_Keys_f (); + break; + case 1: + m_state = m_none; + Con_ToggleConsole_f (); + break; + case 2: + Cbuf_AddText ("exec default.cfg\n"); + break; + case 12: + M_Menu_Video_f (); + break; + default: + M_AdjustSliders (1); + break; + } + return; + + case K_UPARROW: + S_LocalSound ("misc/menu1.wav"); + options_cursor--; + if (options_cursor < 0) + options_cursor = OPTIONS_ITEMS-1; + break; + + case K_DOWNARROW: + S_LocalSound ("misc/menu1.wav"); + options_cursor++; + if (options_cursor >= OPTIONS_ITEMS) + options_cursor = 0; + break; + + case K_LEFTARROW: + M_AdjustSliders (-1); + break; + + case K_RIGHTARROW: + M_AdjustSliders (1); + break; + } + + if (options_cursor == 12 && vid_menudrawfn == NULL) + { + if (k == K_UPARROW) + options_cursor = 11; + else + options_cursor = 0; + } + +#ifdef _WIN32 + if ((options_cursor == 13) && (modestate != MS_WINDOWED)) + { + if (k == K_UPARROW) + options_cursor = 12; + 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"}, +{"+klook", "keyboard look"}, +{"+moveup", "swim up"}, +{"+movedown", "swim down"} +}; + +#define NUMCOMMANDS (sizeof(bindnames)/sizeof(bindnames[0])) + +int keys_cursor; +int bind_grab; + +void M_Menu_Keys_f (void) +{ + key_dest = key_menu; + m_state = m_keys; + m_entersound = true; +} + + +void M_FindKeysForCommand (char *command, int *twokeys) +{ + int count; + int j; + int l; + char *b; + + twokeys[0] = twokeys[1] = -1; + l = strlen(command); + count = 0; + + for (j=0 ; j<256 ; j++) + { + b = keybindings[j]; + if (!b) + continue; + if (!strncmp (b, command, l) ) + { + twokeys[count] = j; + count++; + if (count == 2) + break; + } + } +} + +void M_UnbindCommand (char *command) +{ + int j; + int l; + char *b; + + l = strlen(command); + + for (j=0 ; j<256 ; j++) + { + b = keybindings[j]; + if (!b) + continue; + if (!strncmp (b, command, l) ) + Key_SetBinding (j, ""); + } +} + + +void M_Keys_Draw (void) +{ + int i, l; + int keys[2]; + char *name; + int x, y; + qpic_t *p; + + p = Draw_CachePic ("gfx/ttl_cstm.lmp"); + M_DrawPic ( (320-p->width)/2, 4, p); + + if (bind_grab) + M_Print (12, 32, "Press a key or button for this action"); + else + M_Print (18, 32, "Enter to change, backspace to clear"); + +// search for known bindings + for (i=0 ; i= NUMCOMMANDS) + keys_cursor = 0; + break; + + case K_ENTER: // go into bind mode + M_FindKeysForCommand (bindnames[keys_cursor][0], keys); + S_LocalSound ("misc/menu2.wav"); + if (keys[1] != -1) + M_UnbindCommand (bindnames[keys_cursor][0]); + bind_grab = true; + break; + + case K_BACKSPACE: // delete bindings + case K_DEL: // delete bindings + S_LocalSound ("misc/menu2.wav"); + M_UnbindCommand (bindnames[keys_cursor][0]); + break; + } +} + +//============================================================================= +/* VIDEO MENU */ + +void M_Menu_Video_f (void) +{ + key_dest = key_menu; + m_state = m_video; + m_entersound = true; +} + + +void M_Video_Draw (void) +{ + (*vid_menudrawfn) (); +} + + +void M_Video_Key (int key) +{ + (*vid_menukeyfn) (key); +} + +//============================================================================= +/* HELP MENU */ + +int help_page; +#define NUM_HELP_PAGES 6 + + +void M_Menu_Help_f (void) +{ + key_dest = key_menu; + m_state = m_help; + m_entersound = true; + help_page = 0; +} + + + +void M_Help_Draw (void) +{ + M_DrawPic (0, 0, Draw_CachePic ( va("gfx/help%i.lmp", help_page)) ); +} + + +void M_Help_Key (int key) +{ + switch (key) + { + case K_ESCAPE: + M_Menu_Main_f (); + break; + + case K_UPARROW: + case K_RIGHTARROW: + m_entersound = true; + if (++help_page >= NUM_HELP_PAGES) + help_page = 0; + break; + + case K_DOWNARROW: + case K_LEFTARROW: + m_entersound = true; + if (--help_page < 0) + help_page = NUM_HELP_PAGES-1; + break; + } + +} + +//============================================================================= +/* QUIT MENU */ + +int msgNumber; +int 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); + key_dest = key_menu; + m_quit_prevstate = m_state; + m_state = m_quit; + m_entersound = true; + msgNumber = rand()&7; +} + + +void M_Quit_Key (int key) +{ + switch (key) + { + case K_ESCAPE: + case 'n': + case 'N': + if (wasInMenus) + { + m_state = m_quit_prevstate; + m_entersound = true; + } + else + { + key_dest = key_game; + m_state = m_none; + } + break; + + case 'Y': + case 'y': + key_dest = key_console; + Host_Quit_f (); + break; + + default: + break; + } + +} + + +void M_Quit_Draw (void) +{ + if (wasInMenus) + { + m_state = m_quit_prevstate; + m_recursiveDraw = true; + M_Draw (); + m_state = m_quit; + } + +#ifdef _WIN32 + M_DrawTextBox (0, 0, 38, 23); + M_PrintWhite (16, 12, " Quake version 1.09 by id Software\n\n"); + M_PrintWhite (16, 28, "Programming Art \n"); + M_Print (16, 36, " John Carmack Adrian Carmack\n"); + M_Print (16, 44, " Michael Abrash Kevin Cloud\n"); + M_Print (16, 52, " John Cash Paul Steed\n"); + M_Print (16, 60, " Dave 'Zoid' Kirsch\n"); + M_PrintWhite (16, 68, "Design Biz\n"); + M_Print (16, 76, " John Romero Jay Wilbur\n"); + M_Print (16, 84, " Sandy Petersen Mike Wilson\n"); + M_Print (16, 92, " American McGee Donna Jackson\n"); + M_Print (16, 100, " Tim Willits Todd Hollenshead\n"); + M_PrintWhite (16, 108, "Support Projects\n"); + M_Print (16, 116, " Barrett Alexander Shawn Green\n"); + M_PrintWhite (16, 124, "Sound Effects\n"); + M_Print (16, 132, " Trent Reznor and Nine Inch Nails\n\n"); + M_PrintWhite (16, 140, "Quake is a trademark of Id Software,\n"); + M_PrintWhite (16, 148, "inc., (c)1996 Id Software, inc. All\n"); + M_PrintWhite (16, 156, "rights reserved. NIN logo is a\n"); + M_PrintWhite (16, 164, "registered trademark licensed to\n"); + M_PrintWhite (16, 172, "Nothing Interactive, Inc. All rights\n"); + M_PrintWhite (16, 180, "reserved. Press y to exit\n"); +#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 +} + +//============================================================================= + +/* SERIAL CONFIG MENU */ + +int serialConfig_cursor; +int serialConfig_cursor_table[] = {48, 64, 80, 96, 112, 132}; +#define NUM_SERIALCONFIG_CMDS 6 + +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 serialConfig_comport; +int serialConfig_irq ; +int serialConfig_baud; +char serialConfig_phone[16]; + +void M_Menu_SerialConfig_f (void) +{ + int n; + int port; + int baudrate; + qboolean useModem; + + key_dest = key_menu; + m_state = m_serialconfig; + 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) + { + n = 0; + serialConfig_irq = 4; + } + 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; + + m_return_onerror = false; + m_return_reason[0] = 0; +} + + +void M_SerialConfig_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; + + 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 (IPXConfig) + protocol = "IPX"; + else + protocol = "TCP/IP"; + M_Print (basex, 32, va ("%s - %s", startJoin, protocol)); + basex += 8; + + M_Print (basex, 52, "Address:"); + if (IPXConfig) + M_Print (basex+9*8, 52, my_ipx_address); + else + M_Print (basex+9*8, 52, my_tcpip_address); + + M_Print (basex, lanConfig_cursor_table[0], "Port"); + M_DrawTextBox (basex+8*8, lanConfig_cursor_table[0]-8, 6, 1); + M_Print (basex+9*8, lanConfig_cursor_table[0], lanConfig_portname); + + if (JoiningGame) + { + M_Print (basex, lanConfig_cursor_table[1], "Search for local games..."); + M_Print (basex, 108, "Join game at:"); + M_DrawTextBox (basex+8, lanConfig_cursor_table[2]-8, 22, 1); + M_Print (basex+16, lanConfig_cursor_table[2], lanConfig_joinname); + } + else + { + M_DrawTextBox (basex, lanConfig_cursor_table[1]-8, 2, 1); + M_Print (basex+8, lanConfig_cursor_table[1], "OK"); + } + + M_DrawCharacter (basex-8, lanConfig_cursor_table [lanConfig_cursor], 12+((int)(realtime*4)&1)); + + if (lanConfig_cursor == 0) + M_DrawCharacter (basex+9*8 + 8*strlen(lanConfig_portname), lanConfig_cursor_table [0], 10+((int)(realtime*4)&1)); + + if (lanConfig_cursor == 2) + M_DrawCharacter (basex+16 + 8*strlen(lanConfig_joinname), lanConfig_cursor_table [2], 10+((int)(realtime*4)&1)); + + if (*m_return_reason) + M_PrintWhite (basex, 148, m_return_reason); +} + + +void M_LanConfig_Key (int key) +{ + int l; + + switch (key) + { + case K_ESCAPE: + M_Menu_Net_f (); + break; + + case K_UPARROW: + S_LocalSound ("misc/menu1.wav"); + lanConfig_cursor--; + if (lanConfig_cursor < 0) + lanConfig_cursor = NUM_LANCONFIG_CMDS-1; + break; + + case K_DOWNARROW: + S_LocalSound ("misc/menu1.wav"); + lanConfig_cursor++; + if (lanConfig_cursor >= NUM_LANCONFIG_CMDS) + lanConfig_cursor = 0; + break; + + case K_ENTER: + if (lanConfig_cursor == 0) + break; + + m_entersound = true; + + M_ConfigureNetSubsystem (); + + if (lanConfig_cursor == 1) + { + if (StartingGame) + { + M_Menu_GameOptions_f (); + break; + } + M_Menu_Search_f(); + break; + } + + if (lanConfig_cursor == 2) + { + m_return_state = m_state; + m_return_onerror = true; + key_dest = key_game; + m_state = m_none; + Cbuf_AddText ( va ("connect \"%s\"\n", lanConfig_joinname) ); + break; + } + + break; + + case K_BACKSPACE: + if (lanConfig_cursor == 0) + { + if (strlen(lanConfig_portname)) + lanConfig_portname[strlen(lanConfig_portname)-1] = 0; + } + + if (lanConfig_cursor == 2) + { + if (strlen(lanConfig_joinname)) + 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) + l = lanConfig_port; + else + lanConfig_port = l; + sprintf(lanConfig_portname, "%u", lanConfig_port); +} + +//============================================================================= +/* GAME OPTIONS MENU */ + +typedef struct +{ + char *name; + char *description; +} level_t; + +level_t levels[] = +{ + {"start", "Entrance"}, // 0 + + {"e1m1", "Slipgate Complex"}, // 1 + {"e1m2", "Castle of the Damned"}, + {"e1m3", "The Necropolis"}, + {"e1m4", "The Grisly Grotto"}, + {"e1m5", "Gloom Keep"}, + {"e1m6", "The Door To Chthon"}, + {"e1m7", "The House of Chthon"}, + {"e1m8", "Ziggurat Vertigo"}, + + {"e2m1", "The Installation"}, // 9 + {"e2m2", "Ogre Citadel"}, + {"e2m3", "Crypt of Decay"}, + {"e2m4", "The Ebon Fortress"}, + {"e2m5", "The Wizard's Manse"}, + {"e2m6", "The Dismal Oubliette"}, + {"e2m7", "Underearth"}, + + {"e3m1", "Termination Central"}, // 16 + {"e3m2", "The Vaults of Zin"}, + {"e3m3", "The Tomb of Terror"}, + {"e3m4", "Satan's Dark Delight"}, + {"e3m5", "Wind Tunnels"}, + {"e3m6", "Chambers of Torment"}, + {"e3m7", "The Haunted Halls"}, + + {"e4m1", "The Sewage System"}, // 23 + {"e4m2", "The Tower of Despair"}, + {"e4m3", "The Elder God Shrine"}, + {"e4m4", "The Palace of Hate"}, + {"e4m5", "Hell's Atrium"}, + {"e4m6", "The Pain Maze"}, + {"e4m7", "Azure Agony"}, + {"e4m8", "The Nameless City"}, + + {"end", "Shub-Niggurath's Pit"}, // 31 + + {"dm1", "Place of Two Deaths"}, // 32 + {"dm2", "Claustrophobopolis"}, + {"dm3", "The Abandoned Base"}, + {"dm4", "The Bad Place"}, + {"dm5", "The Cistern"}, + {"dm6", "The Dark Zone"} +}; + +//MED 01/06/97 added hipnotic levels +level_t hipnoticlevels[] = +{ + {"start", "Command HQ"}, // 0 + + {"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"}, + + {"hip3m1", "Tur Torment"}, // 12 + {"hip3m2", "Pandemonium"}, + {"hip3m3", "Limbo"}, + {"hip3m4", "The Gauntlet"}, + + {"hipend", "Armagon's Lair"}, // 16 + + {"hipdm1", "The Edge of Oblivion"} // 17 +}; + +//PGM 01/07/97 added rogue levels +//PGM 03/02/97 added dmatch level +level_t roguelevels[] = +{ + {"start", "Split Decision"}, + {"r1m1", "Deviant's Domain"}, + {"r1m2", "Dread Portal"}, + {"r1m3", "Judgement Call"}, + {"r1m4", "Cave of Death"}, + {"r1m5", "Towers of Wrath"}, + {"r1m6", "Temple of Pain"}, + {"r1m7", "Tomb of the Overlord"}, + {"r2m1", "Tempus Fugit"}, + {"r2m2", "Elemental Fury I"}, + {"r2m3", "Elemental Fury II"}, + {"r2m4", "Curse of Osiris"}, + {"r2m5", "Wizard's Keep"}, + {"r2m6", "Blood Sacrifice"}, + {"r2m7", "Last Bastion"}, + {"r2m8", "Source of Evil"}, + {"ctf1", "Division of Change"} +}; + +typedef struct +{ + char *description; + int firstLevel; + int levels; +} episode_t; + +episode_t episodes[] = +{ + {"Welcome to Quake", 0, 1}, + {"Doomed Dimension", 1, 8}, + {"Realm of Black Magic", 9, 7}, + {"Netherworld", 16, 7}, + {"The Elder World", 23, 8}, + {"Final Level", 31, 1}, + {"Deathmatch Arena", 32, 6} +}; + +//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} +}; + +//PGM 01/07/97 added rogue episodes +//PGM 03/02/97 added dmatch episode +episode_t rogueepisodes[] = +{ + {"Introduction", 0, 1}, + {"Hell's Fortress", 1, 7}, + {"Corridors of Time", 8, 8}, + {"Deathmatch Arena", 16, 1} +}; + +int startepisode; +int startlevel; +int maxplayers; +qboolean m_serverInfoMessage = false; +double m_serverInfoMessageTime; + +void M_Menu_GameOptions_f (void) +{ + key_dest = key_menu; + m_state = m_gameoptions; + m_entersound = true; + if (maxplayers == 0) + maxplayers = svs.maxclients; + if (maxplayers < 2) + maxplayers = svs.maxclientslimit; +} + + +int gameoptions_cursor_table[] = {40, 56, 64, 72, 80, 88, 96, 112, 120}; +#define NUM_GAMEOPTIONS 9 +int gameoptions_cursor; + +void M_GameOptions_Draw (void) +{ + qpic_t *p; + int x; + + M_DrawTransPic (16, 4, Draw_CachePic ("gfx/qplaque.lmp") ); + p = Draw_CachePic ("gfx/p_multi.lmp"); + M_DrawPic ( (320-p->width)/2, 4, p); + + M_DrawTextBox (152, 32, 10, 1); + M_Print (160, 40, "begin game"); + + M_Print (0, 56, " Max players"); + M_Print (160, 56, va("%i", maxplayers) ); + + M_Print (0, 64, " Game Type"); + if (coop.value) + M_Print (160, 64, "Cooperative"); + else + M_Print (160, 64, "Deathmatch"); + + M_Print (0, 72, " Teamplay"); + if (rogue) + { + char *msg; + + switch((int)teamplay.value) + { + case 1: msg = "No Friendly Fire"; break; + case 2: msg = "Friendly Fire"; break; + case 3: msg = "Tag"; break; + case 4: msg = "Capture the Flag"; break; + case 5: msg = "One Flag CTF"; break; + case 6: msg = "Three Team CTF"; break; + default: msg = "Off"; break; + } + M_Print (160, 72, msg); + } + else + { + char *msg; + + switch((int)teamplay.value) + { + case 1: msg = "No Friendly Fire"; break; + case 2: msg = "Friendly Fire"; break; + default: msg = "Off"; break; + } + M_Print (160, 72, msg); + } + + M_Print (0, 80, " Skill"); + if (skill.value == 0) + M_Print (160, 80, "Easy difficulty"); + else if (skill.value == 1) + M_Print (160, 80, "Normal difficulty"); + else if (skill.value == 2) + M_Print (160, 80, "Hard difficulty"); + else + M_Print (160, 80, "Nightmare difficulty"); + + M_Print (0, 88, " Frag Limit"); + if (fraglimit.value == 0) + M_Print (160, 88, "none"); + else + M_Print (160, 88, va("%i frags", (int)fraglimit.value)); + + M_Print (0, 96, " Time Limit"); + if (timelimit.value == 0) + M_Print (160, 96, "none"); + else + 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); + + 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); + } + +// line cursor + M_DrawCharacter (144, gameoptions_cursor_table[gameoptions_cursor], 12+((int)(realtime*4)&1)); + + if (m_serverInfoMessage) + { + if ((realtime - m_serverInfoMessageTime) < 5.0) + { + x = (320-26*8)/2; + M_DrawTextBox (x, 138, 24, 4); + x += 8; + M_Print (x, 146, " More than 4 players "); + M_Print (x, 154, " requires using command "); + M_Print (x, 162, "line parameters; please "); + M_Print (x, 170, " see techinfo.txt. "); + } + else + { + m_serverInfoMessage = false; + } + } +} + + +void M_NetStart_Change (int dir) +{ + int count; + + switch (gameoptions_cursor) + { + case 1: + maxplayers += dir; + if (maxplayers > svs.maxclientslimit) + { + maxplayers = svs.maxclientslimit; + m_serverInfoMessage = true; + m_serverInfoMessageTime = realtime; + } + if (maxplayers < 2) + maxplayers = 2; + break; + + case 2: + Cvar_SetValue ("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); + 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); + 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); + 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); + break; + + case 7: + startepisode += dir; + //MED 01/06/97 added hipnotic count + if (hipnotic) + count = 6; + //PGM 01/07/97 added rogue count + //PGM 03/02/97 added 1 for dmatch episode + else if (rogue) + count = 4; + else if (registered.value) + count = 7; + else + count = 2; + + if (startepisode < 0) + startepisode = count - 1; + + if (startepisode >= count) + startepisode = 0; + + startlevel = 0; + break; + + case 8: + startlevel += dir; + //MED 01/06/97 added hipnotic episodes + if (hipnotic) + count = hipnoticepisodes[startepisode].levels; + //PGM 01/06/97 added hipnotic episodes + else if (rogue) + count = rogueepisodes[startepisode].levels; + else + count = episodes[startepisode].levels; + + if (startlevel < 0) + startlevel = count - 1; + + if (startlevel >= count) + startlevel = 0; + break; + } +} + +void M_GameOptions_Key (int key) +{ + switch (key) + { + case K_ESCAPE: + M_Menu_Net_f (); + break; + + case K_UPARROW: + S_LocalSound ("misc/menu1.wav"); + gameoptions_cursor--; + if (gameoptions_cursor < 0) + gameoptions_cursor = NUM_GAMEOPTIONS-1; + break; + + case K_DOWNARROW: + S_LocalSound ("misc/menu1.wav"); + gameoptions_cursor++; + if (gameoptions_cursor >= NUM_GAMEOPTIONS) + gameoptions_cursor = 0; + break; + + case K_LEFTARROW: + if (gameoptions_cursor == 0) + break; + S_LocalSound ("misc/menu3.wav"); + M_NetStart_Change (-1); + break; + + case K_RIGHTARROW: + if (gameoptions_cursor == 0) + break; + S_LocalSound ("misc/menu3.wav"); + M_NetStart_Change (1); + break; + + case K_ENTER: + S_LocalSound ("misc/menu2.wav"); + if (gameoptions_cursor == 0) + { + if (sv.active) + Cbuf_AddText ("disconnect\n"); + Cbuf_AddText ("listen 0\n"); // so host_netport will be re-examined + Cbuf_AddText ( va ("maxplayers %u\n", maxplayers) ); + SCR_BeginLoadingPlaque (); + + if (hipnotic) + Cbuf_AddText ( va ("map %s\n", hipnoticlevels[hipnoticepisodes[startepisode].firstLevel + startlevel].name) ); + else if (rogue) + Cbuf_AddText ( va ("map %s\n", roguelevels[rogueepisodes[startepisode].firstLevel + startlevel].name) ); + else + Cbuf_AddText ( va ("map %s\n", levels[episodes[startepisode].firstLevel + startlevel].name) ); + + return; + } + + M_NetStart_Change (1); + break; + } +} + +//============================================================================= +/* SEARCH MENU */ + +qboolean searchComplete = false; +double searchCompleteTime; + +void M_Menu_Search_f (void) +{ + key_dest = key_menu; + m_state = m_search; + m_entersound = false; + slistSilent = true; + slistLocal = false; + searchComplete = false; + NET_Slist_f(); + +} + + +void M_Search_Draw (void) +{ + qpic_t *p; + int x; + + p = Draw_CachePic ("gfx/p_multi.lmp"); + M_DrawPic ( (320-p->width)/2, 4, p); + x = (320/2) - ((12*8)/2) + 4; + M_DrawTextBox (x-8, 32, 12, 1); + M_Print (x, 40, "Searching..."); + + if(slistInProgress) + { + NET_Poll(); + return; + } + + if (! searchComplete) + { + searchComplete = true; + searchCompleteTime = realtime; + } + + if (hostCacheCount) + { + M_Menu_ServerList_f (); + return; + } + + M_PrintWhite ((320/2) - ((22*8)/2), 64, "No Quake servers found"); + if ((realtime - searchCompleteTime) < 3.0) + return; + + M_Menu_LanConfig_f (); +} + + +void M_Search_Key (int key) +{ +} + +//============================================================================= +/* SLIST MENU */ + +int slist_cursor; +qboolean slist_sorted; + +void M_Menu_ServerList_f (void) +{ + key_dest = key_menu; + m_state = m_slist; + m_entersound = true; + slist_cursor = 0; + m_return_onerror = false; + m_return_reason[0] = 0; + slist_sorted = false; +} + + +void M_ServerList_Draw (void) +{ + int n; + char string [64]; + 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; + } + + 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_DrawCharacter (0, 32 + slist_cursor*8, 12+((int)(realtime*4)&1)); + + if (*m_return_reason) + M_PrintWhite (16, 148, m_return_reason); +} + + +void M_ServerList_Key (int k) +{ + switch (k) + { + case K_ESCAPE: + M_Menu_LanConfig_f (); + break; + + case K_SPACE: + M_Menu_Search_f (); + break; + + case K_UPARROW: + case K_LEFTARROW: + S_LocalSound ("misc/menu1.wav"); + slist_cursor--; + if (slist_cursor < 0) + slist_cursor = hostCacheCount - 1; + break; + + case K_DOWNARROW: + case K_RIGHTARROW: + S_LocalSound ("misc/menu1.wav"); + slist_cursor++; + if (slist_cursor >= hostCacheCount) + slist_cursor = 0; + break; + + case K_ENTER: + S_LocalSound ("misc/menu2.wav"); + m_return_state = m_state; + m_return_onerror = true; + slist_sorted = false; + key_dest = key_game; + m_state = m_none; + Cbuf_AddText ( va ("connect \"%s\"\n", hostcache[slist_cursor].cname) ); + break; + + default: + break; + } + +} + +//============================================================================= +/* Menu Subsystem */ + + +void M_Init (void) +{ + Cmd_AddCommand ("togglemenu", M_ToggleMenu_f); + + Cmd_AddCommand ("menu_main", M_Menu_Main_f); + Cmd_AddCommand ("menu_singleplayer", M_Menu_SinglePlayer_f); + Cmd_AddCommand ("menu_load", M_Menu_Load_f); + Cmd_AddCommand ("menu_save", M_Menu_Save_f); + Cmd_AddCommand ("menu_multiplayer", M_Menu_MultiPlayer_f); + Cmd_AddCommand ("menu_setup", M_Menu_Setup_f); + Cmd_AddCommand ("menu_options", M_Menu_Options_f); + Cmd_AddCommand ("menu_keys", M_Menu_Keys_f); + Cmd_AddCommand ("menu_video", M_Menu_Video_f); + Cmd_AddCommand ("help", M_Menu_Help_f); + Cmd_AddCommand ("menu_quit", M_Menu_Quit_f); +} + + +void M_Draw (void) +{ + if (m_state == m_none || key_dest != key_menu) + return; + + if (!m_recursiveDraw) + { + scr_copyeverything = 1; + + if (scr_con_current) + { + Draw_ConsoleBackground (vid.height); + VID_UnlockBuffer (); + S_ExtraUpdate (); + VID_LockBuffer (); + } + else + Draw_FadeScreen (); + + scr_fullupdate = 0; + } + else + { + m_recursiveDraw = false; + } + + switch (m_state) + { + case m_none: + break; + + case m_main: + M_Main_Draw (); + break; + + case m_singleplayer: + M_SinglePlayer_Draw (); + break; + + case m_load: + M_Load_Draw (); + break; + + case m_save: + M_Save_Draw (); + break; + + case m_multiplayer: + M_MultiPlayer_Draw (); + break; + + case m_setup: + M_Setup_Draw (); + break; + + case m_net: + M_Net_Draw (); + break; + + case m_options: + M_Options_Draw (); + break; + + case m_keys: + M_Keys_Draw (); + break; + + case m_video: + M_Video_Draw (); + break; + + case m_help: + M_Help_Draw (); + break; + + case m_quit: + 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; + + case m_gameoptions: + M_GameOptions_Draw (); + break; + + case m_search: + M_Search_Draw (); + break; + + case m_slist: + M_ServerList_Draw (); + break; + } + + if (m_entersound) + { + S_LocalSound ("misc/menu2.wav"); + m_entersound = false; + } + + VID_UnlockBuffer (); + S_ExtraUpdate (); + VID_LockBuffer (); +} + + +void M_Keydown (int key) +{ + switch (m_state) + { + case m_none: + return; + + case m_main: + M_Main_Key (key); + return; + + case m_singleplayer: + M_SinglePlayer_Key (key); + return; + + case m_load: + M_Load_Key (key); + return; + + case m_save: + M_Save_Key (key); + return; + + case m_multiplayer: + M_MultiPlayer_Key (key); + return; + + case m_setup: + M_Setup_Key (key); + return; + + case m_net: + M_Net_Key (key); + return; + + case m_options: + M_Options_Key (key); + return; + + case m_keys: + M_Keys_Key (key); + return; + + case m_video: + M_Video_Key (key); + return; + + case m_help: + M_Help_Key (key); + return; + + case m_quit: + 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; + + case m_gameoptions: + M_GameOptions_Key (key); + return; + + case m_search: + M_Search_Key (key); + break; + + case m_slist: + M_ServerList_Key (key); + return; + } +} + + +void M_ConfigureNetSubsystem(void) +{ +// enable/disable net systems to match desired config + + Cbuf_AddText ("stopdemo\n"); + if (SerialConfig || DirectConfig) + { + Cbuf_AddText ("com1 enable\n"); + } + + if (IPXConfig || TCPIPConfig) + net_hostport = lanConfig_port; +} diff --git a/contrib/other/sdlquake-1.0.9/menu.h b/contrib/other/sdlquake-1.0.9/menu.h new file mode 100644 index 000000000..616de3f84 --- /dev/null +++ b/contrib/other/sdlquake-1.0.9/menu.h @@ -0,0 +1,38 @@ +/* +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/contrib/other/sdlquake-1.0.9/missing b/contrib/other/sdlquake-1.0.9/missing new file mode 100644 index 000000000..7789652e8 --- /dev/null +++ b/contrib/other/sdlquake-1.0.9/missing @@ -0,0 +1,190 @@ +#! /bin/sh +# Common stub for a few missing GNU programs while installing. +# Copyright (C) 1996, 1997 Free Software Foundation, Inc. +# Franc,ois Pinard , 1996. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA +# 02111-1307, USA. + +if test $# -eq 0; then + echo 1>&2 "Try \`$0 --help' for more information" + exit 1 +fi + +case "$1" in + + -h|--h|--he|--hel|--help) + echo "\ +$0 [OPTION]... PROGRAM [ARGUMENT]... + +Handle \`PROGRAM [ARGUMENT]...' for when PROGRAM is missing, or return an +error status if there is no known handling for PROGRAM. + +Options: + -h, --help display this help and exit + -v, --version output version information and exit + +Supported PROGRAM values: + aclocal touch file \`aclocal.m4' + autoconf touch file \`configure' + autoheader touch file \`config.h.in' + automake touch all \`Makefile.in' files + bison create \`y.tab.[ch]', if possible, from existing .[ch] + flex create \`lex.yy.c', if possible, from existing .c + lex create \`lex.yy.c', if possible, from existing .c + makeinfo touch the output file + yacc create \`y.tab.[ch]', if possible, from existing .[ch]" + ;; + + -v|--v|--ve|--ver|--vers|--versi|--versio|--version) + echo "missing - GNU libit 0.0" + ;; + + -*) + echo 1>&2 "$0: Unknown \`$1' option" + echo 1>&2 "Try \`$0 --help' for more information" + exit 1 + ;; + + aclocal) + echo 1>&2 "\ +WARNING: \`$1' is missing on your system. You should only need it if + you modified \`acinclude.m4' or \`configure.in'. You might want + to install the \`Automake' and \`Perl' packages. Grab them from + any GNU archive site." + touch aclocal.m4 + ;; + + autoconf) + echo 1>&2 "\ +WARNING: \`$1' is missing on your system. You should only need it if + you modified \`configure.in'. You might want to install the + \`Autoconf' and \`GNU m4' packages. Grab them from any GNU + archive site." + touch configure + ;; + + autoheader) + echo 1>&2 "\ +WARNING: \`$1' is missing on your system. You should only need it if + you modified \`acconfig.h' or \`configure.in'. You might want + to install the \`Autoconf' and \`GNU m4' packages. Grab them + from any GNU archive site." + files=`sed -n 's/^[ ]*A[CM]_CONFIG_HEADER(\([^)]*\)).*/\1/p' configure.in` + test -z "$files" && files="config.h" + touch_files= + for f in $files; do + case "$f" in + *:*) touch_files="$touch_files "`echo "$f" | + sed -e 's/^[^:]*://' -e 's/:.*//'`;; + *) touch_files="$touch_files $f.in";; + esac + done + touch $touch_files + ;; + + automake) + echo 1>&2 "\ +WARNING: \`$1' is missing on your system. You should only need it if + you modified \`Makefile.am', \`acinclude.m4' or \`configure.in'. + You might want to install the \`Automake' and \`Perl' packages. + Grab them from any GNU archive site." + find . -type f -name Makefile.am -print | + sed 's/\.am$/.in/' | + while read f; do touch "$f"; done + ;; + + bison|yacc) + echo 1>&2 "\ +WARNING: \`$1' is missing on your system. You should only need it if + you modified a \`.y' file. You may need the \`Bison' package + in order for those modifications to take effect. You can get + \`Bison' from any GNU archive site." + rm -f y.tab.c y.tab.h + if [ $# -ne 1 ]; then + eval LASTARG="\${$#}" + case "$LASTARG" in + *.y) + SRCFILE=`echo "$LASTARG" | sed 's/y$/c/'` + if [ -f "$SRCFILE" ]; then + cp "$SRCFILE" y.tab.c + fi + SRCFILE=`echo "$LASTARG" | sed 's/y$/h/'` + if [ -f "$SRCFILE" ]; then + cp "$SRCFILE" y.tab.h + fi + ;; + esac + fi + if [ ! -f y.tab.h ]; then + echo >y.tab.h + fi + if [ ! -f y.tab.c ]; then + echo 'main() { return 0; }' >y.tab.c + fi + ;; + + lex|flex) + echo 1>&2 "\ +WARNING: \`$1' is missing on your system. You should only need it if + you modified a \`.l' file. You may need the \`Flex' package + in order for those modifications to take effect. You can get + \`Flex' from any GNU archive site." + rm -f lex.yy.c + if [ $# -ne 1 ]; then + eval LASTARG="\${$#}" + case "$LASTARG" in + *.l) + SRCFILE=`echo "$LASTARG" | sed 's/l$/c/'` + if [ -f "$SRCFILE" ]; then + cp "$SRCFILE" lex.yy.c + fi + ;; + esac + fi + if [ ! -f lex.yy.c ]; then + echo 'main() { return 0; }' >lex.yy.c + fi + ;; + + makeinfo) + echo 1>&2 "\ +WARNING: \`$1' is missing on your system. You should only need it if + you modified a \`.texi' or \`.texinfo' file, or any other file + indirectly affecting the aspect of the manual. The spurious + call might also be the consequence of using a buggy \`make' (AIX, + DU, IRIX). You might want to install the \`Texinfo' package or + the \`GNU make' package. Grab either from any GNU archive site." + file=`echo "$*" | sed -n 's/.*-o \([^ ]*\).*/\1/p'` + if test -z "$file"; then + file=`echo "$*" | sed 's/.* \([^ ]*\) *$/\1/'` + file=`sed -n '/^@setfilename/ { s/.* \([^ ]*\) *$/\1/; p; q; }' $file` + fi + touch $file + ;; + + *) + echo 1>&2 "\ +WARNING: \`$1' is needed, and you do not seem to have it handy on your + system. You might have modified some files without having the + proper tools for further handling them. Check the \`README' file, + it often tells you about the needed prerequirements for installing + this package. You may also peek at any GNU archive site, in case + some other package would contain this missing \`$1' program." + exit 1 + ;; +esac + +exit 0 diff --git a/contrib/other/sdlquake-1.0.9/mkinstalldirs b/contrib/other/sdlquake-1.0.9/mkinstalldirs new file mode 100644 index 000000000..4f58503ea --- /dev/null +++ b/contrib/other/sdlquake-1.0.9/mkinstalldirs @@ -0,0 +1,40 @@ +#! /bin/sh +# mkinstalldirs --- make directory hierarchy +# Author: Noah Friedman +# Created: 1993-05-16 +# Public domain + +# $Id: mkinstalldirs,v 1.13 1999/01/05 03:18:55 bje Exp $ + +errstatus=0 + +for file +do + set fnord `echo ":$file" | sed -ne 's/^:\//#/;s/^://;s/\// /g;s/^#/\//;p'` + shift + + pathcomp= + for d + do + pathcomp="$pathcomp$d" + case "$pathcomp" in + -* ) pathcomp=./$pathcomp ;; + esac + + if test ! -d "$pathcomp"; then + echo "mkdir $pathcomp" + + mkdir "$pathcomp" || lasterr=$? + + if test ! -d "$pathcomp"; then + errstatus=$lasterr + fi + fi + + pathcomp="$pathcomp/" + done +done + +exit $errstatus + +# mkinstalldirs ends here diff --git a/contrib/other/sdlquake-1.0.9/model.c b/contrib/other/sdlquake-1.0.9/model.c new file mode 100644 index 000000000..577c59406 --- /dev/null +++ b/contrib/other/sdlquake-1.0.9/model.c @@ -0,0 +1,1874 @@ +/* +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. + +*/ +// 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" +#include "r_local.h" + +model_t *loadmodel; +char loadname[32]; // for hunk tags + +void Mod_LoadSpriteModel (model_t *mod, void *buffer); +void Mod_LoadBrushModel (model_t *mod, void *buffer); +void Mod_LoadAliasModel (model_t *mod, void *buffer); +model_t *Mod_LoadModel (model_t *mod, qboolean crash); + +byte mod_novis[MAX_MAP_LEAFS/8]; + +#define MAX_MOD_KNOWN 256 +model_t mod_known[MAX_MOD_KNOWN]; +int mod_numknown; + +// values for model_t's needload +#define NL_PRESENT 0 +#define NL_NEEDS_LOADED 1 +#define NL_UNREFERENCED 2 + +/* +=============== +Mod_Init +=============== +*/ +void Mod_Init (void) +{ + memset (mod_novis, 0xff, sizeof(mod_novis)); +} + +/* +=============== +Mod_Extradata + +Caches the data if needed +=============== +*/ +void *Mod_Extradata (model_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, 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 (!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); + + 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 ; ineedload = NL_UNREFERENCED; +//FIX FOR CACHE_ALLOC ERRORS: + if (mod->type == mod_sprite) mod->cache.data = NULL; + } +} + +/* +================== +Mod_FindName + +================== +*/ +model_t *Mod_FindName (char *name) +{ + int i; + model_t *mod; + model_t *avail = NULL; + + if (!name[0]) + Sys_Error ("Mod_ForName: NULL name"); + +// +// search the currently loaded models +// + for (i=0 , mod=mod_known ; iname, name) ) + break; + if (mod->needload == NL_UNREFERENCED) + if (!avail || mod->type != mod_alias) + avail = mod; + } + + if (i == mod_numknown) + { + if (mod_numknown == MAX_MOD_KNOWN) + { + if (avail) + { + mod = avail; + if (mod->type == mod_alias) + if (Cache_Check (&mod->cache)) + Cache_Free (&mod->cache); + } + else + Sys_Error ("mod_numknown == MAX_MOD_KNOWN"); + } + else + mod_numknown++; + strcpy (mod->name, name); + mod->needload = NL_NEEDS_LOADED; + } + + return mod; +} + +/* +================== +Mod_TouchModel + +================== +*/ +void Mod_TouchModel (char *name) +{ + model_t *mod; + + mod = Mod_FindName (name); + + if (mod->needload == NL_PRESENT) + { + 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) +{ + unsigned *buf; + byte stackbuf[1024]; // avoid dirtying the cache heap + + if (mod->type == mod_alias) + { + if (Cache_Check (&mod->cache)) + { + mod->needload = NL_PRESENT; + return mod; + } + } + else + { + if (mod->needload == NL_PRESENT) + return mod; + } + +// +// because the world is so huge, load it one piece at a time +// + +// +// 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 = NL_PRESENT; + + 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; + + 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); + + if (!Q_strncmp(mt->name,"sky",3)) + R_InitSky (tx); + } + +// +// 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 +================= +*/ +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); +} + + +/* +================= +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 +================= +*/ +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); +} + + +/* +================= +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][0] + j) = LittleFloat (*(&in->vecs[0][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] > 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 + out->samples = loadmodel->lightdata + i; + + // set the drawing flags flag + + if (!Q_strncmp(out->texinfo->texture->name,"sky",3)) // sky + { + out->flags |= (SURF_DRAWSKY | SURF_DRAWTILED); + 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; + } + 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]; + } +} + +/* +================= +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); + if (i != BSPVERSION) + Sys_Error ("Mod_LoadBrushModel: %s has wrong version number (%i should be %i)", mod->name, i, BSPVERSION); + +// 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 + mod->flags = 0; + +// +// 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; + } + } +} + +/* +============================================================================== + +ALIAS MODELS + +============================================================================== +*/ + +/* +================= +Mod_LoadAliasFrame +================= +*/ +void * Mod_LoadAliasFrame (void * pin, int *pframeindex, int numv, + trivertx_t *pbboxmin, trivertx_t *pbboxmax, aliashdr_t *pheader, char *name) +{ + trivertx_t *pframe, *pinframe; + int i, j; + daliasframe_t *pdaliasframe; + + pdaliasframe = (daliasframe_t *)pin; + + strcpy (name, pdaliasframe->name); + + for (i=0 ; i<3 ; i++) + { + // these are byte values, so we don't have to worry about + // endianness + pbboxmin->v[i] = pdaliasframe->bboxmin.v[i]; + pbboxmax->v[i] = pdaliasframe->bboxmax.v[i]; + } + + pinframe = (trivertx_t *)(pdaliasframe + 1); + pframe = Hunk_AllocName (numv * sizeof(*pframe), loadname); + + *pframeindex = (byte *)pframe - (byte *)pheader; + + for (j=0 ; jnumframes); + + paliasgroup = Hunk_AllocName (sizeof (maliasgroup_t) + + (numframes - 1) * sizeof (paliasgroup->frames[0]), loadname); + + paliasgroup->numframes = numframes; + + for (i=0 ; i<3 ; i++) + { + // these are byte values, so we don't have to worry about endianness + pbboxmin->v[i] = pingroup->bboxmin.v[i]; + pbboxmax->v[i] = pingroup->bboxmax.v[i]; + } + + *pframeindex = (byte *)paliasgroup - (byte *)pheader; + + pin_intervals = (daliasinterval_t *)(pingroup + 1); + + poutintervals = Hunk_AllocName (numframes * sizeof (float), loadname); + + paliasgroup->intervals = (byte *)poutintervals - (byte *)pheader; + + for (i=0 ; iinterval); + if (*poutintervals <= 0.0) + Sys_Error ("Mod_LoadAliasGroup: interval<=0"); + + poutintervals++; + pin_intervals++; + } + + ptemp = (void *)pin_intervals; + + for (i=0 ; iframes[i].frame, + numv, + &paliasgroup->frames[i].bboxmin, + &paliasgroup->frames[i].bboxmax, + pheader, name); + } + + return ptemp; +} + + +/* +================= +Mod_LoadAliasSkin +================= +*/ +void * Mod_LoadAliasSkin (void * pin, int *pskinindex, int skinsize, + aliashdr_t *pheader) +{ + int i; + byte *pskin, *pinskin; + unsigned short *pusskin; + + pskin = Hunk_AllocName (skinsize * r_pixbytes, loadname); + pinskin = (byte *)pin; + *pskinindex = (byte *)pskin - (byte *)pheader; + + if (r_pixbytes == 1) + { + Q_memcpy (pskin, pinskin, skinsize); + } + else if (r_pixbytes == 2) + { + pusskin = (unsigned short *)pskin; + + for (i=0 ; inumskins); + + paliasskingroup = Hunk_AllocName (sizeof (maliasskingroup_t) + + (numskins - 1) * sizeof (paliasskingroup->skindescs[0]), + loadname); + + paliasskingroup->numskins = numskins; + + *pskinindex = (byte *)paliasskingroup - (byte *)pheader; + + pinskinintervals = (daliasskininterval_t *)(pinskingroup + 1); + + poutskinintervals = Hunk_AllocName (numskins * sizeof (float),loadname); + + paliasskingroup->intervals = (byte *)poutskinintervals - (byte *)pheader; + + for (i=0 ; iinterval); + if (*poutskinintervals <= 0) + Sys_Error ("Mod_LoadAliasSkinGroup: interval<=0"); + + poutskinintervals++; + pinskinintervals++; + } + + ptemp = (void *)pinskinintervals; + + for (i=0 ; iskindescs[i].skin, skinsize, pheader); + } + + return ptemp; +} + + +/* +================= +Mod_LoadAliasModel +================= +*/ +void Mod_LoadAliasModel (model_t *mod, void *buffer) +{ + int i; + mdl_t *pmodel, *pinmodel; + stvert_t *pstverts, *pinstverts; + aliashdr_t *pheader; + mtriangle_t *ptri; + dtriangle_t *pintriangles; + int version, numframes, numskins; + int size; + daliasframetype_t *pframetype; + daliasskintype_t *pskintype; + maliasskindesc_t *pskindesc; + int skinsize; + 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]) + + sizeof (mdl_t) + + LittleLong (pinmodel->numverts) * sizeof (stvert_t) + + LittleLong (pinmodel->numtris) * sizeof (mtriangle_t); + + pheader = Hunk_AllocName (size, loadname); + pmodel = (mdl_t *) ((byte *)&pheader[1] + + (LittleLong (pinmodel->numframes) - 1) * + sizeof (pheader->frames[0])); + +// mod->cache.data = pheader; + mod->flags = LittleLong (pinmodel->flags); + +// +// endian-adjust and copy the data, starting with the alias model header +// + pmodel->boundingradius = LittleFloat (pinmodel->boundingradius); + pmodel->numskins = LittleLong (pinmodel->numskins); + pmodel->skinwidth = LittleLong (pinmodel->skinwidth); + pmodel->skinheight = LittleLong (pinmodel->skinheight); + + if (pmodel->skinheight > MAX_LBM_HEIGHT) + Sys_Error ("model %s has a skin taller than %d", mod->name, + MAX_LBM_HEIGHT); + + pmodel->numverts = LittleLong (pinmodel->numverts); + + if (pmodel->numverts <= 0) + Sys_Error ("model %s has no vertices", mod->name); + + if (pmodel->numverts > MAXALIASVERTS) + Sys_Error ("model %s has too many vertices", mod->name); + + pmodel->numtris = LittleLong (pinmodel->numtris); + + if (pmodel->numtris <= 0) + Sys_Error ("model %s has no triangles", mod->name); + + pmodel->numframes = LittleLong (pinmodel->numframes); + pmodel->size = LittleFloat (pinmodel->size) * ALIAS_BASE_SIZE_RATIO; + mod->synctype = LittleLong (pinmodel->synctype); + mod->numframes = pmodel->numframes; + + for (i=0 ; i<3 ; i++) + { + pmodel->scale[i] = LittleFloat (pinmodel->scale[i]); + pmodel->scale_origin[i] = LittleFloat (pinmodel->scale_origin[i]); + pmodel->eyeposition[i] = LittleFloat (pinmodel->eyeposition[i]); + } + + numskins = pmodel->numskins; + numframes = pmodel->numframes; + + if (pmodel->skinwidth & 0x03) + Sys_Error ("Mod_LoadAliasModel: skinwidth not multiple of 4"); + + pheader->model = (byte *)pmodel - (byte *)pheader; + +// +// load the skins +// + skinsize = pmodel->skinheight * pmodel->skinwidth; + + if (numskins < 1) + Sys_Error ("Mod_LoadAliasModel: Invalid # of skins: %d\n", numskins); + + pskintype = (daliasskintype_t *)&pinmodel[1]; + + pskindesc = Hunk_AllocName (numskins * sizeof (maliasskindesc_t), + loadname); + + pheader->skindesc = (byte *)pskindesc - (byte *)pheader; + + for (i=0 ; itype); + pskindesc[i].type = skintype; + + if (skintype == ALIAS_SKIN_SINGLE) + { + pskintype = (daliasskintype_t *) + Mod_LoadAliasSkin (pskintype + 1, + &pskindesc[i].skin, + skinsize, pheader); + } + else + { + pskintype = (daliasskintype_t *) + Mod_LoadAliasSkinGroup (pskintype + 1, + &pskindesc[i].skin, + skinsize, pheader); + } + } + +// +// set base s and t vertices +// + pstverts = (stvert_t *)&pmodel[1]; + pinstverts = (stvert_t *)pskintype; + + pheader->stverts = (byte *)pstverts - (byte *)pheader; + + for (i=0 ; inumverts ; i++) + { + pstverts[i].onseam = LittleLong (pinstverts[i].onseam); + // put s and t in 16.16 format + pstverts[i].s = LittleLong (pinstverts[i].s) << 16; + pstverts[i].t = LittleLong (pinstverts[i].t) << 16; + } + +// +// set up the triangles +// + ptri = (mtriangle_t *)&pstverts[pmodel->numverts]; + pintriangles = (dtriangle_t *)&pinstverts[pmodel->numverts]; + + pheader->triangles = (byte *)ptri - (byte *)pheader; + + for (i=0 ; inumtris ; i++) + { + int j; + + ptri[i].facesfront = LittleLong (pintriangles[i].facesfront); + + for (j=0 ; j<3 ; j++) + { + ptri[i].vertindex[j] = + LittleLong (pintriangles[i].vertindex[j]); + } + } + +// +// load the frames +// + if (numframes < 1) + Sys_Error ("Mod_LoadAliasModel: Invalid # of frames: %d\n", numframes); + + pframetype = (daliasframetype_t *)&pintriangles[pmodel->numtris]; + + for (i=0 ; itype); + pheader->frames[i].type = frametype; + + if (frametype == ALIAS_SINGLE) + { + pframetype = (daliasframetype_t *) + Mod_LoadAliasFrame (pframetype + 1, + &pheader->frames[i].frame, + pmodel->numverts, + &pheader->frames[i].bboxmin, + &pheader->frames[i].bboxmax, + pheader, pheader->frames[i].name); + } + else + { + pframetype = (daliasframetype_t *) + Mod_LoadAliasGroup (pframetype + 1, + &pheader->frames[i].frame, + pmodel->numverts, + &pheader->frames[i].bboxmin, + &pheader->frames[i].bboxmax, + pheader, pheader->frames[i].name); + } + } + + mod->type = mod_alias; + +// FIXME: do this right + mod->mins[0] = mod->mins[1] = mod->mins[2] = -16; + mod->maxs[0] = mod->maxs[1] = mod->maxs[2] = 16; + +// +// 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) +{ + dspriteframe_t *pinframe; + mspriteframe_t *pspriteframe; + int i, width, height, size, origin[2]; + unsigned short *ppixout; + byte *ppixin; + + pinframe = (dspriteframe_t *)pin; + + width = LittleLong (pinframe->width); + height = LittleLong (pinframe->height); + size = width * height; + + pspriteframe = Hunk_AllocName (sizeof (mspriteframe_t) + size*r_pixbytes, + loadname); + + Q_memset (pspriteframe, 0, sizeof (mspriteframe_t) + size); + *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]; + + if (r_pixbytes == 1) + { + Q_memcpy (&pspriteframe->pixels[0], (byte *)(pinframe + 1), size); + } + else if (r_pixbytes == 2) + { + ppixin = (byte *)(pinframe + 1); + ppixout = (unsigned short *)&pspriteframe->pixels[0]; + + for (i=0 ; inumframes); + + 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]); + } + + 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; + mod->flags = 0; + + 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); + } + else + { + pframetype = (dspriteframetype_t *) + Mod_LoadSpriteGroup (pframetype + 1, + &psprite->frames[i].frameptr); + } + } + + 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",mod->cache.data, mod->name); + if (mod->needload & NL_UNREFERENCED) + Con_Printf (" (!R)"); + if (mod->needload & NL_NEEDS_LOADED) + Con_Printf (" (!P)"); + Con_Printf ("\n"); + } +} + + diff --git a/contrib/other/sdlquake-1.0.9/model.h b/contrib/other/sdlquake-1.0.9/model.h new file mode 100644 index 000000000..2e89862d6 --- /dev/null +++ b/contrib/other/sdlquake-1.0.9/model.h @@ -0,0 +1,382 @@ +/* +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. + +*/ + +#ifndef __MODEL__ +#define __MODEL__ + +#include "modelgen.h" +#include "spritegn.h" + +/* + +d*_t structures are on-disk representations +m*_t structures are in-memory + +*/ + +/* +============================================================================== + +BRUSH MODELS + +============================================================================== +*/ + + +// +// in memory representation +// +// !!! if this is changed, it must be changed in asm_draw.h too !!! +typedef struct +{ + vec3_t position; +} mvertex_t; + +#define SIDE_FRONT 0 +#define SIDE_BACK 1 +#define SIDE_ON 2 + + +// plane_t structure +// !!! if this is changed, it must be changed in asm_i386.h too !!! +typedef struct mplane_s +{ + vec3_t normal; + float dist; + byte type; // for texture axis selection and fast side tests + byte signbits; // signx + signy<<1 + signz<<1 + byte pad[2]; +} mplane_t; + +typedef struct texture_s +{ + char name[16]; + unsigned width, height; + 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; + + +#define SURF_PLANEBACK 2 +#define SURF_DRAWSKY 4 +#define SURF_DRAWSPRITE 8 +#define SURF_DRAWTURB 0x10 +#define SURF_DRAWTILED 0x20 +#define SURF_DRAWBACKGROUND 0x40 + +// !!! if this is changed, it must be changed in asm_draw.h too !!! +typedef struct +{ + unsigned short v[2]; + unsigned int cachededgeoffset; +} medge_t; + +typedef struct +{ + float vecs[2][4]; + float mipadjust; + texture_t *texture; + int flags; +} mtexinfo_t; + +typedef struct msurface_s +{ + int visframe; // should be drawn when node is crossed + + int dlightframe; + int dlightbits; + + mplane_t *plane; + int flags; + + int firstedge; // look up in model->surfedges[], negative numbers + int numedges; // are backwards edges + +// surface generation data + struct surfcache_s *cachespots[MIPLEVELS]; + + short texturemins[2]; + short extents[2]; + + mtexinfo_t *texinfo; + +// lighting info + byte styles[MAXLIGHTMAPS]; + byte *samples; // [numstyles*surfsize] +} msurface_t; + +typedef struct mnode_s +{ +// common with leaf + int contents; // 0, to differentiate from leafs + int visframe; // node needs to be traversed if current + + short minmaxs[6]; // for bounding box culling + + struct mnode_s *parent; + +// node specific + mplane_t *plane; + struct mnode_s *children[2]; + + unsigned short firstsurface; + unsigned short numsurfaces; +} mnode_t; + + + +typedef struct mleaf_s +{ +// common with node + int contents; // wil be a negative contents number + int visframe; // node needs to be traversed if current + + short minmaxs[6]; // for bounding box culling + + struct mnode_s *parent; + +// leaf specific + byte *compressed_vis; + efrag_t *efrags; + + msurface_t **firstmarksurface; + int nummarksurfaces; + int key; // BSP sequence number for leaf's contents + byte ambient_sound_level[NUM_AMBIENTS]; +} mleaf_t; + +// !!! if this is changed, it must be changed in asm_i386.h too !!! +typedef struct +{ + dclipnode_t *clipnodes; + mplane_t *planes; + int firstclipnode; + int lastclipnode; + vec3_t clip_mins; + vec3_t clip_maxs; +} hull_t; + +/* +============================================================================== + +SPRITE MODELS + +============================================================================== +*/ + + +// FIXME: shorten these? +typedef struct mspriteframe_s +{ + int width; + int height; + void *pcachespot; // remove? + float up, down, left, right; + byte pixels[4]; +} mspriteframe_t; + +typedef struct +{ + int numframes; + float *intervals; + mspriteframe_t *frames[1]; +} mspritegroup_t; + +typedef struct +{ + spriteframetype_t type; + mspriteframe_t *frameptr; +} mspriteframedesc_t; + +typedef struct +{ + int type; + int maxwidth; + int maxheight; + int numframes; + float beamlength; // remove? + void *cachespot; // remove? + mspriteframedesc_t frames[1]; +} msprite_t; + + +/* +============================================================================== + +ALIAS MODELS + +Alias models are position independent, so the cache manager can move them. +============================================================================== +*/ + +typedef struct +{ + aliasframetype_t type; + trivertx_t bboxmin; + trivertx_t bboxmax; + int frame; + char name[16]; +} maliasframedesc_t; + +typedef struct +{ + aliasskintype_t type; + void *pcachespot; + int skin; +} maliasskindesc_t; + +typedef struct +{ + trivertx_t bboxmin; + trivertx_t bboxmax; + int frame; +} maliasgroupframedesc_t; + +typedef struct +{ + int numframes; + int intervals; + maliasgroupframedesc_t frames[1]; +} maliasgroup_t; + +typedef struct +{ + int numskins; + int intervals; + maliasskindesc_t skindescs[1]; +} maliasskingroup_t; + +// !!! if this is changed, it must be changed in asm_draw.h too !!! +typedef struct mtriangle_s { + int facesfront; + int vertindex[3]; +} mtriangle_t; + +typedef struct { + int model; + int stverts; + int skindesc; + int triangles; + maliasframedesc_t frames[1]; +} aliashdr_t; + +//=================================================================== + +// +// Whole model +// + +typedef enum {mod_brush, mod_sprite, mod_alias} modtype_t; + +#define EF_ROCKET 1 // leave a trail +#define EF_GRENADE 2 // leave a trail +#define EF_GIB 4 // leave a trail +#define EF_ROTATE 8 // rotate (bonus items) +#define EF_TRACER 16 // green split trail +#define EF_ZOMGIB 32 // small blood trail +#define EF_TRACER2 64 // orange split trail + rotate +#define EF_TRACER3 128 // purple trail + +typedef struct model_s +{ + char name[MAX_QPATH]; + qboolean needload; // bmodels and sprites don't cache normally + + modtype_t type; + int numframes; + synctype_t synctype; + + int flags; + +// +// volume occupied by the model +// + vec3_t mins, maxs; + float radius; + +// +// brush model +// + int firstmodelsurface, nummodelsurfaces; + + int numsubmodels; + dmodel_t *submodels; + + int numplanes; + mplane_t *planes; + + int numleafs; // number of visible leafs, not counting 0 + mleaf_t *leafs; + + int numvertexes; + mvertex_t *vertexes; + + int numedges; + medge_t *edges; + + int numnodes; + mnode_t *nodes; + + int numtexinfo; + mtexinfo_t *texinfo; + + int numsurfaces; + msurface_t *surfaces; + + int numsurfedges; + int *surfedges; + + int numclipnodes; + dclipnode_t *clipnodes; + + int nummarksurfaces; + msurface_t **marksurfaces; + + hull_t hulls[MAX_MAP_HULLS]; + + int numtextures; + texture_t **textures; + + byte *visdata; + byte *lightdata; + char *entities; + +// +// additional model data +// + cache_user_t cache; // only access through Mod_Extradata + +} model_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); + +mleaf_t *Mod_PointInLeaf (float *p, model_t *model); +byte *Mod_LeafPVS (mleaf_t *leaf, model_t *model); + +#endif // __MODEL__ diff --git a/contrib/other/sdlquake-1.0.9/modelgen.h b/contrib/other/sdlquake-1.0.9/modelgen.h new file mode 100644 index 000000000..be9ad92f9 --- /dev/null +++ b/contrib/other/sdlquake-1.0.9/modelgen.h @@ -0,0 +1,134 @@ +/* +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. + +*/ +// +// modelgen.h: header file for model generation program +// + +// ********************************************************* +// * This file must be identical in the modelgen directory * +// * and in the Quake directory, because it's used to * +// * pass data from one to the other via model files. * +// ********************************************************* + +#ifdef INCLUDELIBS + +#include +#include +#include +#include + +#include "cmdlib.h" +#include "scriplib.h" +#include "trilib.h" +#include "lbmlib.h" +#include "mathlib.h" + +#endif + +#define ALIAS_VERSION 6 + +#define ALIAS_ONSEAM 0x0020 + +// must match definition in spritegn.h +#ifndef SYNCTYPE_T +#define SYNCTYPE_T +typedef enum {ST_SYNC=0, ST_RAND } synctype_t; +#endif + +typedef enum { ALIAS_SINGLE=0, ALIAS_GROUP } aliasframetype_t; + +typedef enum { ALIAS_SKIN_SINGLE=0, ALIAS_SKIN_GROUP } aliasskintype_t; + +typedef struct { + int ident; + int version; + vec3_t scale; + vec3_t scale_origin; + float boundingradius; + vec3_t eyeposition; + int numskins; + int skinwidth; + int skinheight; + int numverts; + int numtris; + int numframes; + synctype_t synctype; + int flags; + float size; +} mdl_t; + +// TODO: could be shorts + +typedef struct { + int onseam; + int s; + int t; +} stvert_t; + +typedef struct dtriangle_s { + int facesfront; + int vertindex[3]; +} dtriangle_t; + +#define DT_FACES_FRONT 0x0010 + +// This mirrors trivert_t in trilib.h, is present so Quake knows how to +// load this data + +typedef struct { + byte v[3]; + byte lightnormalindex; +} trivertx_t; + +typedef struct { + trivertx_t bboxmin; // lightnormal isn't used + trivertx_t bboxmax; // lightnormal isn't used + char name[16]; // frame name from grabbing +} daliasframe_t; + +typedef struct { + int numframes; + trivertx_t bboxmin; // lightnormal isn't used + trivertx_t bboxmax; // lightnormal isn't used +} daliasgroup_t; + +typedef struct { + int numskins; +} daliasskingroup_t; + +typedef struct { + float interval; +} daliasinterval_t; + +typedef struct { + float interval; +} daliasskininterval_t; + +typedef struct { + aliasframetype_t type; +} daliasframetype_t; + +typedef struct { + aliasskintype_t type; +} daliasskintype_t; + +#define IDPOLYHEADER (('O'<<24)+('P'<<16)+('D'<<8)+'I') + // little-endian "IDPO" + diff --git a/contrib/other/sdlquake-1.0.9/mpdosock.h b/contrib/other/sdlquake-1.0.9/mpdosock.h new file mode 100644 index 000000000..75171f4d6 --- /dev/null +++ b/contrib/other/sdlquake-1.0.9/mpdosock.h @@ -0,0 +1,797 @@ +/* WINSOCK.H--definitions to be used with the WINSOCK.DLL + * Copyright (c) 1993-1995, Microsoft Corp. All rights reserved. + * + * This header file corresponds to version 1.1 of the Windows Sockets specification. + * + * This file includes parts which are Copyright (c) 1982-1986 Regents + * of the University of California. All rights reserved. The + * Berkeley Software License Agreement specifies the terms and + * conditions for redistribution. + * + */ + +#ifndef _WINSOCKAPI_ +#define _WINSOCKAPI_ + +#define FAR +#define PASCAL + +/* + * Basic system type definitions, taken from the BSD file sys/types.h. + */ +typedef unsigned char u_char; +typedef unsigned short u_short; +typedef unsigned int u_int; +typedef unsigned long u_long; + +/* + * The new type to be used in all + * instances which refer to sockets. + */ +typedef u_int SOCKET; + +// FIXME +#if 0 +/* + * Select uses arrays of SOCKETs. These macros manipulate such + * arrays. FD_SETSIZE may be defined by the user before including + * this file, but the default here should be >= 64. + * + * CAVEAT IMPLEMENTOR and USER: THESE MACROS AND TYPES MUST BE + * INCLUDED IN WINSOCK.H EXACTLY AS SHOWN HERE. + */ +#ifndef FD_SETSIZE +#define FD_SETSIZE 64 +#endif /* FD_SETSIZE */ + +typedef struct fd_set { + u_int fd_count; /* how many are SET? */ + SOCKET fd_array[FD_SETSIZE]; /* an array of SOCKETs */ +} fd_set; + +#ifdef __cplusplus +extern "C" { +#endif + +extern int PASCAL FAR __WSAFDIsSet(SOCKET, fd_set FAR *); + +#ifdef __cplusplus +} +#endif + + +#define FD_CLR(fd, set) do { \ + u_int __i; \ + for (__i = 0; __i < ((fd_set FAR *)(set))->fd_count ; __i++) { \ + if (((fd_set FAR *)(set))->fd_array[__i] == fd) { \ + while (__i < ((fd_set FAR *)(set))->fd_count-1) { \ + ((fd_set FAR *)(set))->fd_array[__i] = \ + ((fd_set FAR *)(set))->fd_array[__i+1]; \ + __i++; \ + } \ + ((fd_set FAR *)(set))->fd_count--; \ + break; \ + } \ + } \ +} while(0) + +#define FD_SET(fd, set) do { \ + if (((fd_set FAR *)(set))->fd_count < FD_SETSIZE) \ + ((fd_set FAR *)(set))->fd_array[((fd_set FAR *)(set))->fd_count++]=(fd);\ +} while(0) + +#define FD_ZERO(set) (((fd_set FAR *)(set))->fd_count=0) + +#define FD_ISSET(fd, set) __WSAFDIsSet((SOCKET)(fd), (fd_set FAR *)(set)) + +/* + * Structure used in select() call, taken from the BSD file sys/time.h. + */ +struct timeval { + long tv_sec; /* seconds */ + long tv_usec; /* and microseconds */ +}; + +/* + * Operations on timevals. + * + * NB: timercmp does not work for >= or <=. + */ +#define timerisset(tvp) ((tvp)->tv_sec || (tvp)->tv_usec) +#define timercmp(tvp, uvp, cmp) \ + ((tvp)->tv_sec cmp (uvp)->tv_sec || \ + (tvp)->tv_sec == (uvp)->tv_sec && (tvp)->tv_usec cmp (uvp)->tv_usec) +#define timerclear(tvp) (tvp)->tv_sec = (tvp)->tv_usec = 0 +#endif + +/* + * Commands for ioctlsocket(), taken from the BSD file fcntl.h. + * + * + * Ioctl's have the command encoded in the lower word, + * and the size of any in or out parameters in the upper + * word. The high 2 bits of the upper word are used + * to encode the in/out status of the parameter; for now + * we restrict parameters to at most 128 bytes. + */ +#define IOCPARM_MASK 0x7f /* parameters must be < 128 bytes */ +#define IOC_VOID 0x20000000 /* no parameters */ +#define IOC_OUT 0x40000000 /* copy out parameters */ +#define IOC_IN 0x80000000 /* copy in parameters */ +#define IOC_INOUT (IOC_IN|IOC_OUT) + /* 0x20000000 distinguishes new & + old ioctl's */ +#define _IO(x,y) (IOC_VOID|((x)<<8)|(y)) + +#define _IOR(x,y,t) (IOC_OUT|(((long)sizeof(t)&IOCPARM_MASK)<<16)|((x)<<8)|(y)) + +#define _IOW(x,y,t) (IOC_IN|(((long)sizeof(t)&IOCPARM_MASK)<<16)|((x)<<8)|(y)) + +#define FIONREAD _IOR('f', 127, u_long) /* get # bytes to read */ +#define FIONBIO _IOW('f', 126, u_long) /* set/clear non-blocking i/o */ +#define FIOASYNC _IOW('f', 125, u_long) /* set/clear async i/o */ + +/* Socket I/O Controls */ +#define SIOCSHIWAT _IOW('s', 0, u_long) /* set high watermark */ +#define SIOCGHIWAT _IOR('s', 1, u_long) /* get high watermark */ +#define SIOCSLOWAT _IOW('s', 2, u_long) /* set low watermark */ +#define SIOCGLOWAT _IOR('s', 3, u_long) /* get low watermark */ +#define SIOCATMARK _IOR('s', 7, u_long) /* at oob mark? */ + +/* + * Structures returned by network data base library, taken from the + * BSD file netdb.h. All addresses are supplied in host order, and + * returned in network order (suitable for use in system calls). + */ + +struct hostent { + char FAR * h_name; /* official name of host */ + char FAR * FAR * h_aliases; /* alias list */ + short h_addrtype; /* host address type */ + short h_length; /* length of address */ + char FAR * FAR * h_addr_list; /* list of addresses */ +#define h_addr h_addr_list[0] /* address, for backward compat */ +}; + +/* + * It is assumed here that a network number + * fits in 32 bits. + */ +struct netent { + char FAR * n_name; /* official name of net */ + char FAR * FAR * n_aliases; /* alias list */ + short n_addrtype; /* net address type */ + u_long n_net; /* network # */ +}; + +struct servent { + char FAR * s_name; /* official service name */ + char FAR * FAR * s_aliases; /* alias list */ + short s_port; /* port # */ + char FAR * s_proto; /* protocol to use */ +}; + +struct protoent { + char FAR * p_name; /* official protocol name */ + char FAR * FAR * p_aliases; /* alias list */ + short p_proto; /* protocol # */ +}; + +/* + * Constants and structures defined by the internet system, + * Per RFC 790, September 1981, taken from the BSD file netinet/in.h. + */ + +/* + * Protocols + */ +#define IPPROTO_IP 0 /* dummy for IP */ +#define IPPROTO_ICMP 1 /* control message protocol */ +#define IPPROTO_GGP 2 /* gateway^2 (deprecated) */ +#define IPPROTO_TCP 6 /* tcp */ +#define IPPROTO_PUP 12 /* pup */ +#define IPPROTO_UDP 17 /* user datagram protocol */ +#define IPPROTO_IDP 22 /* xns idp */ +#define IPPROTO_ND 77 /* UNOFFICIAL net disk proto */ + +#define IPPROTO_RAW 255 /* raw IP packet */ +#define IPPROTO_MAX 256 + +/* + * Port/socket numbers: network standard functions + */ +#define IPPORT_ECHO 7 +#define IPPORT_DISCARD 9 +#define IPPORT_SYSTAT 11 +#define IPPORT_DAYTIME 13 +#define IPPORT_NETSTAT 15 +#define IPPORT_FTP 21 +#define IPPORT_TELNET 23 +#define IPPORT_SMTP 25 +#define IPPORT_TIMESERVER 37 +#define IPPORT_NAMESERVER 42 +#define IPPORT_WHOIS 43 +#define IPPORT_MTP 57 + +/* + * Port/socket numbers: host specific functions + */ +#define IPPORT_TFTP 69 +#define IPPORT_RJE 77 +#define IPPORT_FINGER 79 +#define IPPORT_TTYLINK 87 +#define IPPORT_SUPDUP 95 + +/* + * UNIX TCP sockets + */ +#define IPPORT_EXECSERVER 512 +#define IPPORT_LOGINSERVER 513 +#define IPPORT_CMDSERVER 514 +#define IPPORT_EFSSERVER 520 + +/* + * UNIX UDP sockets + */ +#define IPPORT_BIFFUDP 512 +#define IPPORT_WHOSERVER 513 +#define IPPORT_ROUTESERVER 520 + /* 520+1 also used */ + +/* + * Ports < IPPORT_RESERVED are reserved for + * privileged processes (e.g. root). + */ +#define IPPORT_RESERVED 1024 + +/* + * Link numbers + */ +#define IMPLINK_IP 155 +#define IMPLINK_LOWEXPER 156 +#define IMPLINK_HIGHEXPER 158 + +/* + * Internet address (old style... should be updated) + */ +struct in_addr { + union { + struct { u_char s_b1,s_b2,s_b3,s_b4; } S_un_b; + struct { u_short s_w1,s_w2; } S_un_w; + u_long S_addr; + } S_un; +#define s_addr S_un.S_addr + /* can be used for most tcp & ip code */ +#define s_host S_un.S_un_b.s_b2 + /* host on imp */ +#define s_net S_un.S_un_b.s_b1 + /* network */ +#define s_imp S_un.S_un_w.s_w2 + /* imp */ +#define s_impno S_un.S_un_b.s_b4 + /* imp # */ +#define s_lh S_un.S_un_b.s_b3 + /* logical host */ +}; + +/* + * Definitions of bits in internet address integers. + * On subnets, the decomposition of addresses to host and net parts + * is done according to subnet mask, not the masks here. + */ +#define IN_CLASSA(i) (((long)(i) & 0x80000000) == 0) +#define IN_CLASSA_NET 0xff000000 +#define IN_CLASSA_NSHIFT 24 +#define IN_CLASSA_HOST 0x00ffffff +#define IN_CLASSA_MAX 128 + +#define IN_CLASSB(i) (((long)(i) & 0xc0000000) == 0x80000000) +#define IN_CLASSB_NET 0xffff0000 +#define IN_CLASSB_NSHIFT 16 +#define IN_CLASSB_HOST 0x0000ffff +#define IN_CLASSB_MAX 65536 + +#define IN_CLASSC(i) (((long)(i) & 0xe0000000) == 0xc0000000) +#define IN_CLASSC_NET 0xffffff00 +#define IN_CLASSC_NSHIFT 8 +#define IN_CLASSC_HOST 0x000000ff + +#define INADDR_ANY (u_long)0x00000000 +#define INADDR_LOOPBACK 0x7f000001 +#define INADDR_BROADCAST (u_long)0xffffffff +#define INADDR_NONE 0xffffffff + +/* + * Socket address, internet style. + */ +struct sockaddr_in { + short sin_family; + u_short sin_port; + struct in_addr sin_addr; + char sin_zero[8]; +}; + +#define WSADESCRIPTION_LEN 256 +#define WSASYS_STATUS_LEN 128 + + +/* + * Options for use with [gs]etsockopt at the IP level. + */ +#define IP_OPTIONS 1 /* set/get IP per-packet options */ +#define IP_MULTICAST_IF 2 /* set/get IP multicast interface */ +#define IP_MULTICAST_TTL 3 /* set/get IP multicast timetolive */ +#define IP_MULTICAST_LOOP 4 /* set/get IP multicast loopback */ +#define IP_ADD_MEMBERSHIP 5 /* add an IP group membership */ +#define IP_DROP_MEMBERSHIP 6 /* drop an IP group membership */ + +#define IP_DEFAULT_MULTICAST_TTL 1 /* normally limit m'casts to 1 hop */ +#define IP_DEFAULT_MULTICAST_LOOP 1 /* normally hear sends if a member */ +#define IP_MAX_MEMBERSHIPS 20 /* per socket; must fit in one mbuf */ + +/* + * Argument structure for IP_ADD_MEMBERSHIP and IP_DROP_MEMBERSHIP. + */ +struct ip_mreq { + struct in_addr imr_multiaddr; /* IP multicast address of group */ + struct in_addr imr_interface; /* local IP address of interface */ +}; + +/* + * Definitions related to sockets: types, address families, options, + * taken from the BSD file sys/socket.h. + */ + +/* + * This is used instead of -1, since the + * SOCKET type is unsigned. + */ +#define INVALID_SOCKET (SOCKET)(~0) +#define SOCKET_ERROR (-1) + +/* + * Types + */ +#define SOCK_STREAM 1 /* stream socket */ +#define SOCK_DGRAM 2 /* datagram socket */ +#define SOCK_RAW 3 /* raw-protocol interface */ +#define SOCK_RDM 4 /* reliably-delivered message */ +#define SOCK_SEQPACKET 5 /* sequenced packet stream */ + +/* + * Option flags per-socket. + */ +#define SO_DEBUG 0x0001 /* turn on debugging info recording */ +#define SO_ACCEPTCONN 0x0002 /* socket has had listen() */ +#define SO_REUSEADDR 0x0004 /* allow local address reuse */ +#define SO_KEEPALIVE 0x0008 /* keep connections alive */ +#define SO_DONTROUTE 0x0010 /* just use interface addresses */ +#define SO_BROADCAST 0x0020 /* permit sending of broadcast msgs */ +#define SO_USELOOPBACK 0x0040 /* bypass hardware when possible */ +#define SO_LINGER 0x0080 /* linger on close if data present */ +#define SO_OOBINLINE 0x0100 /* leave received OOB data in line */ + +#define SO_DONTLINGER (u_int)(~SO_LINGER) + +/* + * Additional options. + */ +#define SO_SNDBUF 0x1001 /* send buffer size */ +#define SO_RCVBUF 0x1002 /* receive buffer size */ +#define SO_SNDLOWAT 0x1003 /* send low-water mark */ +#define SO_RCVLOWAT 0x1004 /* receive low-water mark */ +#define SO_SNDTIMEO 0x1005 /* send timeout */ +#define SO_RCVTIMEO 0x1006 /* receive timeout */ +#define SO_ERROR 0x1007 /* get error status and clear */ +#define SO_TYPE 0x1008 /* get socket type */ + +/* + * Options for connect and disconnect data and options. Used only by + * non-TCP/IP transports such as DECNet, OSI TP4, etc. + */ +#define SO_CONNDATA 0x7000 +#define SO_CONNOPT 0x7001 +#define SO_DISCDATA 0x7002 +#define SO_DISCOPT 0x7003 +#define SO_CONNDATALEN 0x7004 +#define SO_CONNOPTLEN 0x7005 +#define SO_DISCDATALEN 0x7006 +#define SO_DISCOPTLEN 0x7007 + +/* + * Option for opening sockets for synchronous access. + */ +#define SO_OPENTYPE 0x7008 + +#define SO_SYNCHRONOUS_ALERT 0x10 +#define SO_SYNCHRONOUS_NONALERT 0x20 + +/* + * Other NT-specific options. + */ +#define SO_MAXDG 0x7009 +#define SO_MAXPATHDG 0x700A + +/* + * TCP options. + */ +#define TCP_NODELAY 0x0001 +#define TCP_BSDURGENT 0x7000 + +/* + * Address families. + */ +#define AF_UNSPEC 0 /* unspecified */ +#define AF_UNIX 1 /* local to host (pipes, portals) */ +#define AF_INET 2 /* internetwork: UDP, TCP, etc. */ +#define AF_IMPLINK 3 /* arpanet imp addresses */ +#define AF_PUP 4 /* pup protocols: e.g. BSP */ +#define AF_CHAOS 5 /* mit CHAOS protocols */ +#define AF_IPX 6 /* IPX and SPX */ +#define AF_NS 6 /* XEROX NS protocols */ +#define AF_ISO 7 /* ISO protocols */ +#define AF_OSI AF_ISO /* OSI is ISO */ +#define AF_ECMA 8 /* european computer manufacturers */ +#define AF_DATAKIT 9 /* datakit protocols */ +#define AF_CCITT 10 /* CCITT protocols, X.25 etc */ +#define AF_SNA 11 /* IBM SNA */ +#define AF_DECnet 12 /* DECnet */ +#define AF_DLI 13 /* Direct data link interface */ +#define AF_LAT 14 /* LAT */ +#define AF_HYLINK 15 /* NSC Hyperchannel */ +#define AF_APPLETALK 16 /* AppleTalk */ +#define AF_NETBIOS 17 /* NetBios-style addresses */ +#define AF_VOICEVIEW 18 /* VoiceView */ + +#define AF_MAX 19 + +/* + * Structure used by kernel to store most + * addresses. + */ +struct sockaddr { + u_short sa_family; /* address family */ + char sa_data[14]; /* up to 14 bytes of direct address */ +}; + +/* + * Structure used by kernel to pass protocol + * information in raw sockets. + */ +struct sockproto { + u_short sp_family; /* address family */ + u_short sp_protocol; /* protocol */ +}; + +/* + * Protocol families, same as address families for now. + */ +#define PF_UNSPEC AF_UNSPEC +#define PF_UNIX AF_UNIX +#define PF_INET AF_INET +#define PF_IMPLINK AF_IMPLINK +#define PF_PUP AF_PUP +#define PF_CHAOS AF_CHAOS +#define PF_NS AF_NS +#define PF_IPX AF_IPX +#define PF_ISO AF_ISO +#define PF_OSI AF_OSI +#define PF_ECMA AF_ECMA +#define PF_DATAKIT AF_DATAKIT +#define PF_CCITT AF_CCITT +#define PF_SNA AF_SNA +#define PF_DECnet AF_DECnet +#define PF_DLI AF_DLI +#define PF_LAT AF_LAT +#define PF_HYLINK AF_HYLINK +#define PF_APPLETALK AF_APPLETALK +#define PF_VOICEVIEW AF_VOICEVIEW + +#define PF_MAX AF_MAX + +/* + * Structure used for manipulating linger option. + */ +struct linger { + u_short l_onoff; /* option on/off */ + u_short l_linger; /* linger time */ +}; + +/* + * Level number for (get/set)sockopt() to apply to socket itself. + */ +#define SOL_SOCKET 0xffff /* options for socket level */ + +/* + * Maximum queue length specifiable by listen. + */ +#define SOMAXCONN 5 + +#define MSG_OOB 0x1 /* process out-of-band data */ +#define MSG_PEEK 0x2 /* peek at incoming message */ +#define MSG_DONTROUTE 0x4 /* send without using routing tables */ + +#define MSG_MAXIOVLEN 16 + +#define MSG_PARTIAL 0x8000 /* partial send or recv for message xport */ + +/* + * Define constant based on rfc883, used by gethostbyxxxx() calls. + */ +#define MAXGETHOSTSTRUCT 1024 + +/* + * Define flags to be used with the WSAAsyncSelect() call. + */ +#define FD_READ 0x01 +#define FD_WRITE 0x02 +#define FD_OOB 0x04 +#define FD_ACCEPT 0x08 +#define FD_CONNECT 0x10 +#define FD_CLOSE 0x20 + +/* + * All Windows Sockets error constants are biased by WSABASEERR from + * the "normal" + */ +#define WSABASEERR 10000 +/* + * Windows Sockets definitions of regular Microsoft C error constants + */ +#define WSAEINTR (WSABASEERR+4) +#define WSAEBADF (WSABASEERR+9) +#define WSAEACCES (WSABASEERR+13) +#define WSAEFAULT (WSABASEERR+14) +#define WSAEINVAL (WSABASEERR+22) +#define WSAEMFILE (WSABASEERR+24) + +/* + * Windows Sockets definitions of regular Berkeley error constants + */ +#define WSAEWOULDBLOCK (WSABASEERR+35) +#define WSAEINPROGRESS (WSABASEERR+36) +#define WSAEALREADY (WSABASEERR+37) +#define WSAENOTSOCK (WSABASEERR+38) +#define WSAEDESTADDRREQ (WSABASEERR+39) +#define WSAEMSGSIZE (WSABASEERR+40) +#define WSAEPROTOTYPE (WSABASEERR+41) +#define WSAENOPROTOOPT (WSABASEERR+42) +#define WSAEPROTONOSUPPORT (WSABASEERR+43) +#define WSAESOCKTNOSUPPORT (WSABASEERR+44) +#define WSAEOPNOTSUPP (WSABASEERR+45) +#define WSAEPFNOSUPPORT (WSABASEERR+46) +#define WSAEAFNOSUPPORT (WSABASEERR+47) +#define WSAEADDRINUSE (WSABASEERR+48) +#define WSAEADDRNOTAVAIL (WSABASEERR+49) +#define WSAENETDOWN (WSABASEERR+50) +#define WSAENETUNREACH (WSABASEERR+51) +#define WSAENETRESET (WSABASEERR+52) +#define WSAECONNABORTED (WSABASEERR+53) +#define WSAECONNRESET (WSABASEERR+54) +#define WSAENOBUFS (WSABASEERR+55) +#define WSAEISCONN (WSABASEERR+56) +#define WSAENOTCONN (WSABASEERR+57) +#define WSAESHUTDOWN (WSABASEERR+58) +#define WSAETOOMANYREFS (WSABASEERR+59) +#define WSAETIMEDOUT (WSABASEERR+60) +#define WSAECONNREFUSED (WSABASEERR+61) +#define WSAELOOP (WSABASEERR+62) +#define WSAENAMETOOLONG (WSABASEERR+63) +#define WSAEHOSTDOWN (WSABASEERR+64) +#define WSAEHOSTUNREACH (WSABASEERR+65) +#define WSAENOTEMPTY (WSABASEERR+66) +#define WSAEPROCLIM (WSABASEERR+67) +#define WSAEUSERS (WSABASEERR+68) +#define WSAEDQUOT (WSABASEERR+69) +#define WSAESTALE (WSABASEERR+70) +#define WSAEREMOTE (WSABASEERR+71) + +#define WSAEDISCON (WSABASEERR+101) + +/* + * Extended Windows Sockets error constant definitions + */ +#define WSASYSNOTREADY (WSABASEERR+91) +#define WSAVERNOTSUPPORTED (WSABASEERR+92) +#define WSANOTINITIALISED (WSABASEERR+93) + +/* + * Error return codes from gethostbyname() and gethostbyaddr() + * (when using the resolver). Note that these errors are + * retrieved via WSAGetLastError() and must therefore follow + * the rules for avoiding clashes with error numbers from + * specific implementations or language run-time systems. + * For this reason the codes are based at WSABASEERR+1001. + * Note also that [WSA]NO_ADDRESS is defined only for + * compatibility purposes. + */ + +#define h_errno WSAGetLastError() + +/* Authoritative Answer: Host not found */ +#define WSAHOST_NOT_FOUND (WSABASEERR+1001) +#define HOST_NOT_FOUND WSAHOST_NOT_FOUND + +/* Non-Authoritative: Host not found, or SERVERFAIL */ +#define WSATRY_AGAIN (WSABASEERR+1002) +#define TRY_AGAIN WSATRY_AGAIN + +/* Non recoverable errors, FORMERR, REFUSED, NOTIMP */ +#define WSANO_RECOVERY (WSABASEERR+1003) +#define NO_RECOVERY WSANO_RECOVERY + +/* Valid name, no data record of requested type */ +#define WSANO_DATA (WSABASEERR+1004) +#define NO_DATA WSANO_DATA + +/* no address, look for MX record */ +#define WSANO_ADDRESS WSANO_DATA +#define NO_ADDRESS WSANO_ADDRESS + +/* + * Windows Sockets errors redefined as regular Berkeley error constants. + * These are commented out in Windows NT to avoid conflicts with errno.h. + * Use the WSA constants instead. + */ +#if 0 +#define EWOULDBLOCK WSAEWOULDBLOCK +#define EINPROGRESS WSAEINPROGRESS +#define EALREADY WSAEALREADY +#define ENOTSOCK WSAENOTSOCK +#define EDESTADDRREQ WSAEDESTADDRREQ +#define EMSGSIZE WSAEMSGSIZE +#define EPROTOTYPE WSAEPROTOTYPE +#define ENOPROTOOPT WSAENOPROTOOPT +#define EPROTONOSUPPORT WSAEPROTONOSUPPORT +#define ESOCKTNOSUPPORT WSAESOCKTNOSUPPORT +#define EOPNOTSUPP WSAEOPNOTSUPP +#define EPFNOSUPPORT WSAEPFNOSUPPORT +#define EAFNOSUPPORT WSAEAFNOSUPPORT +#define EADDRINUSE WSAEADDRINUSE +#define EADDRNOTAVAIL WSAEADDRNOTAVAIL +#define ENETDOWN WSAENETDOWN +#define ENETUNREACH WSAENETUNREACH +#define ENETRESET WSAENETRESET +#define ECONNABORTED WSAECONNABORTED +#define ECONNRESET WSAECONNRESET +#define ENOBUFS WSAENOBUFS +#define EISCONN WSAEISCONN +#define ENOTCONN WSAENOTCONN +#define ESHUTDOWN WSAESHUTDOWN +#define ETOOMANYREFS WSAETOOMANYREFS +#define ETIMEDOUT WSAETIMEDOUT +#define ECONNREFUSED WSAECONNREFUSED +#define ELOOP WSAELOOP +#define ENAMETOOLONG WSAENAMETOOLONG +#define EHOSTDOWN WSAEHOSTDOWN +#define EHOSTUNREACH WSAEHOSTUNREACH +#define ENOTEMPTY WSAENOTEMPTY +#define EPROCLIM WSAEPROCLIM +#define EUSERS WSAEUSERS +#define EDQUOT WSAEDQUOT +#define ESTALE WSAESTALE +#define EREMOTE WSAEREMOTE +#endif + +/* Socket function prototypes */ + +#ifdef __cplusplus +extern "C" { +#endif + +SOCKET PASCAL FAR accept (SOCKET s, struct sockaddr FAR *addr, + int FAR *addrlen); + +int PASCAL FAR bind (SOCKET s, const struct sockaddr FAR *addr, int namelen); + +int PASCAL FAR closesocket (SOCKET s); + +int PASCAL FAR connect (SOCKET s, const struct sockaddr FAR *name, int namelen); + +int PASCAL FAR ioctlsocket (SOCKET s, long cmd, u_long FAR *argp); + +int PASCAL FAR getpeername (SOCKET s, struct sockaddr FAR *name, + int FAR * namelen); + +int PASCAL FAR getsockname (SOCKET s, struct sockaddr FAR *name, + int FAR * namelen); + +int PASCAL FAR getsockopt (SOCKET s, int level, int optname, + char FAR * optval, int FAR *optlen); + +u_long PASCAL FAR htonl (u_long hostlong); + +u_short PASCAL FAR htons (u_short hostshort); + +unsigned long PASCAL FAR inet_addr (const char FAR * cp); + +char FAR * PASCAL FAR inet_ntoa (struct in_addr in); + +int PASCAL FAR listen (SOCKET s, int backlog); + +u_long PASCAL FAR ntohl (u_long netlong); + +u_short PASCAL FAR ntohs (u_short netshort); + +int PASCAL FAR recv (SOCKET s, char FAR * buf, int len, int flags); + +int PASCAL FAR recvfrom (SOCKET s, char FAR * buf, int len, int flags, + struct sockaddr FAR *from, int FAR * fromlen); + +#if 0 +int PASCAL FAR select (int nfds, fd_set FAR *readfds, fd_set FAR *writefds, + fd_set FAR *exceptfds, const struct timeval FAR *timeout); +#endif + +int PASCAL FAR send (SOCKET s, const char FAR * buf, int len, int flags); + +int PASCAL FAR sendto (SOCKET s, const char FAR * buf, int len, int flags, + const struct sockaddr FAR *to, int tolen); + +int PASCAL FAR setsockopt (SOCKET s, int level, int optname, + const char FAR * optval, int optlen); + +int PASCAL FAR shutdown (SOCKET s, int how); + +SOCKET PASCAL FAR socket (int af, int type, int protocol); + +/* Database function prototypes */ + +struct hostent FAR * PASCAL FAR gethostbyaddr(const char FAR * addr, + int len, int type); + +struct hostent FAR * PASCAL FAR gethostbyname(const char FAR * name); + +int PASCAL FAR gethostname (char FAR * name, int namelen); + +struct servent FAR * PASCAL FAR getservbyport(int port, const char FAR * proto); + +struct servent FAR * PASCAL FAR getservbyname(const char FAR * name, + const char FAR * proto); + +struct protoent FAR * PASCAL FAR getprotobynumber(int proto); + +struct protoent FAR * PASCAL FAR getprotobyname(const char FAR * name); + +#ifdef __cplusplus +} +#endif + +/* Microsoft Windows Extended data types */ +typedef struct sockaddr SOCKADDR; +typedef struct sockaddr *PSOCKADDR; +typedef struct sockaddr FAR *LPSOCKADDR; + +typedef struct sockaddr_in SOCKADDR_IN; +typedef struct sockaddr_in *PSOCKADDR_IN; +typedef struct sockaddr_in FAR *LPSOCKADDR_IN; + +typedef struct linger LINGER; +typedef struct linger *PLINGER; +typedef struct linger FAR *LPLINGER; + +typedef struct in_addr IN_ADDR; +typedef struct in_addr *PIN_ADDR; +typedef struct in_addr FAR *LPIN_ADDR; + +typedef struct fd_set FD_SET; +typedef struct fd_set *PFD_SET; +typedef struct fd_set FAR *LPFD_SET; + +typedef struct hostent HOSTENT; +typedef struct hostent *PHOSTENT; +typedef struct hostent FAR *LPHOSTENT; + +typedef struct servent SERVENT; +typedef struct servent *PSERVENT; +typedef struct servent FAR *LPSERVENT; + +typedef struct protoent PROTOENT; +typedef struct protoent *PPROTOENT; +typedef struct protoent FAR *LPPROTOENT; + +typedef struct timeval TIMEVAL; +typedef struct timeval *PTIMEVAL; +typedef struct timeval FAR *LPTIMEVAL; + +#endif /* _WINSOCKAPI_ */ diff --git a/contrib/other/sdlquake-1.0.9/mplib.c b/contrib/other/sdlquake-1.0.9/mplib.c new file mode 100644 index 000000000..8ad33ff2d --- /dev/null +++ b/contrib/other/sdlquake-1.0.9/mplib.c @@ -0,0 +1,222 @@ +/* +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 + +//#include "types.h" +typedef unsigned char BYTE; +typedef unsigned short WORD; +typedef unsigned long DWORD; + +//#include "mgenord.h" +#define MGENVXD_REGISTER_ORD 1 +#define MGENVXD_GETMEM_ORD 2 +#define MGENVXD_DEREGISTER_ORD 3 +#define MGENVXD_WAKEUP_ORD 4 +#define MGENVXD_MAKEDQS_ORD 5 + + +// Virtual 8086 API Ordinals +#define V86API_GETSELECTOR16_ORD (1) +#define V86API_GETSELECTOR32_ORD (2) +#define V86API_GETFLAT32_ORD (3) +#define V86API_MOVERP_ORD (6) +#define V86API_MOVEPR_ORD (7) +#define V86API_POST_ORD (8) +#define V86API_INIT_ORD (9) +#define V86API_UNINIT_ORD (10) +#define V86API_INSERTKEY_ORD (11) +#define V86API_REMOVEHOTKEY_ORD (12) +#define V86API_INSTALLHOTKEY_ORD (13) +#define V86API_HOOKINT48_ORD (14) +#define V86API_WAKEUPDLL_ORD (15) + +#define DPMIAPI_GETFLAT32_ORD (1) +#define DPMIAPI_POST_WINDOWS_ORD (2) +// these are DPMI functions. Make sure they don't clash with the +// other MGENVXD_XXXX functions above, or the DPMI functions! +#define MGENVXD_GETQUEUECTR_ORD 6 +#define MGENVXD_MOVENODE_ORD 7 +#define MGENVXD_GETNODE_ORD 8 +#define MGENVXD_FLUSHNODE_ORD 9 +#define MGENVXD_MCOUNT_ORD 10 +#define MGENVXD_MASTERNODE_ORD 11 +#define MGENVXD_SANITYCHECK_ORD 12 +#define MGENVXD_WAKEUPDLL_ORD 13 +#define MGENVXD_WAIT_ORD 14 + +// +#define HWND_OFFSET (0) +#define UMSG_OFFSET (1) +#define SIZEREQUEST_OFFSET (2) +#define HVXD_OFFSET (3) +#define DATUM_OFFSET (4) +#define SLOT_OFFSET (5) +#define SIZEGIVEN_OFFSET (6) +#define SELECTOR32_OFFSET (7) +#define SELECTOR16_OFFSET (8) + +//#include "magic.h" +#define MGENVXD_DEVICE_ID 0x18AA + +//#include "rtq.h" +#define RTQ_NODE struct rtq_node + +RTQ_NODE + { + RTQ_NODE *self; // Ring zero address of this node + RTQ_NODE *left; // Ring zero address of preceding node + RTQ_NODE *right; // Ring zero address of succeding node + BYTE * rtqDatum; // Ring 3 Datum of Buffer (start of preface) + BYTE * rtqInsert; // Ring 3 insertion position + WORD rtqLen; // Length of buffer, excluding preface + WORD rtqUpCtr; // Up Counter of bytes used so far + WORD rtqQCtr; // number of nodes attached + WORD padding; // DWORD alignment + }; + +#define RTQ_PARAM_MOVENODE struct rtq_param_movenode +RTQ_PARAM_MOVENODE + { + WORD rtqFromDQ; + WORD rtqToDQ; + }; + +RTQ_NODE* rtq_fetch(RTQ_NODE*, RTQ_NODE*); // To, From + +int _int86(int vector, __dpmi_regs *iregs, __dpmi_regs *oregs); + +#define CHUNNEL_INT 0x48 + +#define int386 _int86 +#define REGISTERS __dpmi_regs + +void +Yield(void) +{ + __dpmi_yield(); +} + +void +PostWindowsMessage(void) +{ + REGISTERS regs; + + regs.d.eax = DPMIAPI_POST_WINDOWS_ORD << 16 | MGENVXD_DEVICE_ID; + regs.d.ebx = 0; + regs.d.ecx = 0; + int386(CHUNNEL_INT, ®s, ®s); +} + +int +MGenWait(void) +{ + REGISTERS regs; + + regs.d.eax = MGENVXD_WAIT_ORD << 16 | MGENVXD_DEVICE_ID; + int386(CHUNNEL_INT, ®s, ®s); + return regs.d.eax; +} + +int MGenGetQueueCtr(int qNo) +{ + REGISTERS regs; + + regs.d.eax = MGENVXD_GETQUEUECTR_ORD << 16 | MGENVXD_DEVICE_ID; + regs.d.ebx = qNo; + int386(CHUNNEL_INT, ®s, ®s); + + return regs.d.eax; +} + +RTQ_NODE *MGenMoveTo(int qFrom, int qTo) +{ + REGISTERS regs; + + regs.d.eax = MGENVXD_MOVENODE_ORD << 16 | MGENVXD_DEVICE_ID; + regs.d.ebx = qFrom; + regs.d.ecx = qTo; + int386(CHUNNEL_INT, ®s, ®s); + + return (RTQ_NODE *) regs.d.eax; +} + +RTQ_NODE *MGenGetNode(int q) +{ + REGISTERS regs; + + regs.d.eax = MGENVXD_GETNODE_ORD << 16 | MGENVXD_DEVICE_ID; + regs.d.ebx = q; + int386(CHUNNEL_INT, ®s, ®s); + + return (RTQ_NODE *) regs.d.eax; +} + +RTQ_NODE *MGenGetMasterNode(unsigned *size) +{ + REGISTERS regs; + + regs.d.eax = MGENVXD_MASTERNODE_ORD << 16 | MGENVXD_DEVICE_ID; + int386(CHUNNEL_INT, ®s, ®s); + *size = regs.d.ecx; + + return (RTQ_NODE *) regs.d.eax; +} + +RTQ_NODE *MGenFlushNodes(int qFrom, int qTo) +{ + REGISTERS regs; + + regs.d.eax = MGENVXD_FLUSHNODE_ORD << 16 | MGENVXD_DEVICE_ID; + regs.d.ebx = qFrom; + regs.d.ecx = qTo; + int386(CHUNNEL_INT, ®s, ®s); + + return (RTQ_NODE *) regs.d.eax; +} + +int MGenMCount(unsigned lowerOrderBits, unsigned upperOrderBits) +{ + REGISTERS regs; + + regs.d.eax = MGENVXD_MCOUNT_ORD << 16 | MGENVXD_DEVICE_ID; + regs.d.ebx = lowerOrderBits; + regs.d.ecx = upperOrderBits; + int386(CHUNNEL_INT, ®s, ®s); + + return regs.d.eax; +} + +int MGenSanityCheck(void) +{ + REGISTERS regs; + + regs.d.eax = MGENVXD_SANITYCHECK_ORD << 16 | MGENVXD_DEVICE_ID; + int386(CHUNNEL_INT, ®s, ®s); + + return regs.d.eax; +} + +void MGenWakeupDll(void) +{ + REGISTERS regs; + + regs.d.eax = MGENVXD_WAKEUPDLL_ORD << 16 | MGENVXD_DEVICE_ID; + int386(CHUNNEL_INT, ®s, ®s); +} diff --git a/contrib/other/sdlquake-1.0.9/mplpc.c b/contrib/other/sdlquake-1.0.9/mplpc.c new file mode 100644 index 000000000..10bc564ba --- /dev/null +++ b/contrib/other/sdlquake-1.0.9/mplpc.c @@ -0,0 +1,1001 @@ +/* +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 +#include "mpdosock.h" + +//#include "types.h" +typedef unsigned char BYTE; +typedef unsigned short WORD; +typedef unsigned long DWORD; + +//#include "lpc.h" +typedef struct { + short version; // version of LPC requested + short sizeOfArgs; // size of arguments + short service; // service # requested + char Data[1]; // data +} LPCData; + +typedef struct { + short version; // LPC version + short sizeOfReturn; // return data size + short error; // any error codes + short noRet; // number of returns + char Data[1]; // data +} LPCReturn; + +//#include "services.h" +#define MAXSOCKETS 20 + +// services +#define LPC_SOCKBIND 4 +#define LPC_SOCKGETHOSTBYNAME 5 +#define LPC_SOCKGETHOSTNAME 6 +#define LPC_SOCKGETHOSTBYADDR 7 +#define LPC_SOCKCLOSE 8 +#define LPC_SOCKSOCKET 9 +#define LPC_SOCKRECVFROM 10 +#define LPC_SOCKSENDTO 11 +#define LPC_SOCKIOCTL 12 +#define LPC_SOCKGETSOCKNAME 13 +#define LPC_SOCKFLUSH 14 +#define LPC_SOCKSETOPT 15 +#define LPC_SOCKGETLASTERROR 16 +#define LPC_SOCKINETADDR 17 + +// htons, ntohs, htonl, ntohl implemented locally + +// errors +#define LPC_UNRECOGNIZED_SERVICE -1 +#define LPC_NOERROR 0 + +// structures for support +typedef struct { + SOCKET s; + int namelen; + char name[1]; +} BindArgs; + +typedef struct { + SOCKET s; + long cmd; + char data[1]; +} IoctlArgs; + +typedef struct { + int retVal; + int namelen; + char name[1]; +} GetSockNameRet; + +typedef GetSockNameRet GetHostNameRet; + +typedef struct { + int retVal; + int h_addr_0; // that's the only important value +} GetHostByNameRet; + +typedef struct { + int len; + int type; + char addr[1]; +} GetHostByAddrArgs; + +typedef struct { + int retVal; + char h_name[1]; // h_name is the only important value +} GetHostByAddrRet; + +typedef struct { + SOCKET s; + int flags; +} RecvFromArgs; + +typedef struct { + int retVal; + int errCode; + int len; // message len + struct sockaddr sockaddr; + int sockaddrlen; + char Data[1]; +} RecvFromRet; + +typedef struct { + SOCKET s; + int flags; + int len; + struct sockaddr sockaddr; + int sockaddrlen; + char Data[1]; +} SendToArgs; + +typedef struct { + int retVal; + int errCode; +} SendToRet; + +typedef struct { + int bufflen; + SOCKET s; + int len; + int sockaddrlen; + struct sockaddr address; + char data[1]; +} SocketChannelData; + +typedef struct { + int af; + int type; + int protocol; +} SocketArgs; + +typedef struct { + SOCKET s; + int len; + int flags; + int addrlen; + struct sockaddr addr; + char data[1]; +} WinSockData; + +typedef struct { + SOCKET s; + int level; + int optname; + int optlen; + char optval[1]; +} SetSockOptArgs; + +typedef struct { + SOCKET sock[MAXSOCKETS]; +} SocketMap; + +//#include "rtq.h" +#define RTQ_NODE struct rtq_node + +RTQ_NODE + { + RTQ_NODE *self; // Ring zero address of this node + RTQ_NODE *left; // Ring zero address of preceding node + RTQ_NODE *right; // Ring zero address of succeding node + BYTE * rtqDatum; // Ring 3 Datum of Buffer (start of preface) + BYTE * rtqInsert; // Ring 3 insertion position + WORD rtqLen; // Length of buffer, excluding preface + WORD rtqUpCtr; // Up Counter of bytes used so far + WORD rtqQCtr; // number of nodes attached + WORD padding; // DWORD alignment + }; + +#define RTQ_PARAM_MOVENODE struct rtq_param_movenode +RTQ_PARAM_MOVENODE + { + WORD rtqFromDQ; + WORD rtqToDQ; + }; + +RTQ_NODE* rtq_fetch(RTQ_NODE*, RTQ_NODE*); // To, From + +//#include "mplib.h" +// give up time slice +void Yield(void); +void MGenWakeupDll(void); + +// post a message to win32 side +void PostWindowsMessage(void); + +// get # of items on qNo +int MGenGetQueueCtr(int qNo); + +// move first node from qFrom to qTo +RTQ_NODE *MGenMoveTo(int qFrom, int qTo); + +// get first node from q +RTQ_NODE *MGenGetNode(int q); + +// get master node, returning size of RTQ_NODE for size verification +RTQ_NODE *MGenGetMasterNode(unsigned *size); + +// move all nodes from qFrom to qTo +RTQ_NODE *MGenFlushNodes(int qFrom, int qTo); + +// count number of nodes in queues designated by bitmask +// lowerOrderBits == 0..31, upperOrderBits == 32-63 +int MGenMCount(unsigned lowerOrderBits, unsigned upperOrderBits); + +// perform consistency check on chunnel address space +int MGenSanityCheck(void); + +#include +#include + +extern short flat_selector; + +#define SOCKET_MAP_QUEUE 41 + +#define IDLE_QUEUE 44 +#define REC_QUEUE 45 +#define SEND_QUEUE 46 + +// queue sizes +#define FREEQBASE 58 +#define FREEQ64 58 +#define FREEQ128 59 +#define FREEQ256 60 +#define FREEQ512 61 +#define FREEQ1024 62 +#define FREEQ2048 63 + +#define NFREEQ 6 + +#define QLIMIT 10 + +#define PRIVATEQ 50 + +#define FARPKL(x) (_farnspeekl((unsigned long) x)) +#define FARPKB(x) (_farnspeekb((unsigned long) x)) +#define FARPKS(x) (_farnspeekw((unsigned long) x)) + +#define FARPOKL(x, y) (_farnspokel((unsigned long) x, (unsigned long) y)) +#define FARPOKB(x, y) (_farnspokeb((unsigned long) x, (unsigned char) y)) + +int Qsizes[] = { 64, 128, 256, 512, 1024, 2048 }; + +int SocketError = 0; + +SocketMap *SockMap; + +#define HOSTENT_ALIAS_LIMIT 5 +#define HOSTENT_STRLEN_LIMIT 50 +#define HOSTENT_ADDR_LIST_LIMIT 5 + +struct hostent HostEnt; + +char HostEnt_hname[HOSTENT_STRLEN_LIMIT]; +char *HostEnt_h_aliases[HOSTENT_ALIAS_LIMIT]; +char HostEnt_names[HOSTENT_ALIAS_LIMIT][HOSTENT_STRLEN_LIMIT]; +struct in_addr* HostEnt_addr_list[HOSTENT_ADDR_LIST_LIMIT]; +struct in_addr HostEnt_addrs[HOSTENT_ADDR_LIST_LIMIT]; + +void +fmemcpyto(void *to, const void *from, int length) +{ + movedata(_my_ds(), (unsigned)from, flat_selector, (unsigned)to, length); +} + +void +fmemcpyfrom(void *to, const void *from, int length) +{ + movedata(flat_selector, (unsigned)from, _my_ds(), (unsigned)to, length); +} + +void +fstrcpyto(char *to, const char *from) +{ + while (*from) { + FARPOKB(to, *from); + to++; from++; + } + FARPOKB(to, 0); +} + +void +fstrncpyto(char *to, const char *from, int len) +{ + while (*from && len) { + FARPOKB(to, *from); + to++; from++; len--; + } + FARPOKB(to, 0); +} + +void +fstrcpyfrom(char *to, const char *from) +{ + while (FARPKB(from)) { + *to = FARPKB(from); + from++; to++; + } + *to = 0; +} + +void +fstrncpyfrom(char *to, const char *from, int len) +{ + while (FARPKB(from) && len) { + *to = FARPKB(from); + from++; to++; len--; + } + *to = 0; +} + +void +GetSocketMap(void) +{ + RTQ_NODE *n = MGenGetNode(SOCKET_MAP_QUEUE); + + SockMap = (SocketMap *) FARPKL(&n->rtqDatum); +} + +void * +GetFreeBufferToQueue(int q, int bufSize) +{ + int i; + + for (i = 0; i < NFREEQ; i++) { + if (Qsizes[i] >= bufSize && MGenGetQueueCtr(i+FREEQBASE)) { + RTQ_NODE *n = MGenMoveTo(i+FREEQBASE, q); + if (!n) + continue; + FARPOKL(&n->rtqUpCtr, bufSize); + return (void *) FARPKL(&n->rtqDatum); + } + } + + return 0; +} + +void +FreeBufferFromQueue(int q) +{ + int i; + RTQ_NODE *n = MGenGetNode(q); + + for (i = 0; i < NFREEQ; i++) { + if (Qsizes[i] == FARPKS(&n->rtqLen)) { + MGenMoveTo(q, i+FREEQBASE); + return; + } + } +} + +void +SetLPCData(LPCData *lpc) +{ + + FARPOKL(&(lpc->version), 1); + FARPOKL(&(lpc->sizeOfArgs), 0); + FARPOKL(&(lpc->service), 0); +} + +int +bind(SOCKET s, const struct sockaddr *name, int namelen) +{ + RTQ_NODE *n = MGenGetNode(IDLE_QUEUE); + LPCData *p; + LPCReturn *r; + BindArgs *bargs; + int retVal; + + _farsetsel(flat_selector); + SocketError = 0; + p = (LPCData *) FARPKL(&n->rtqDatum); + SetLPCData(p); + FARPOKL(&p->service, LPC_SOCKBIND); + bargs = (BindArgs *) p->Data; + FARPOKL(&bargs->s, s); + FARPOKL(&bargs->namelen, namelen); + fmemcpyto(bargs->name, name, namelen); + MGenMoveTo(IDLE_QUEUE, SEND_QUEUE); + PostWindowsMessage(); + + while ((n = MGenGetNode(REC_QUEUE)) == 0) + Yield(); + + r = (LPCReturn *) FARPKL(&n->rtqDatum); + + if (FARPKS(&r->error) != LPC_NOERROR) { + return -1; + } + + retVal = FARPKL(r->Data); + + // get ready for next call + MGenMoveTo(REC_QUEUE, IDLE_QUEUE); + + return retVal; +} + +int +closesocket(SOCKET s) +{ + RTQ_NODE *n = MGenGetNode(IDLE_QUEUE); + LPCData *p; + LPCReturn *r; + int retVal; + + _farsetsel(flat_selector); + SocketError = 0; + p = (LPCData *) FARPKL(&n->rtqDatum); + SetLPCData(p); + FARPOKL(&p->service, LPC_SOCKCLOSE); + FARPOKL(p->Data, s); + + MGenMoveTo(IDLE_QUEUE, SEND_QUEUE); + PostWindowsMessage(); + + while ((n = MGenGetNode(REC_QUEUE)) == 0) + Yield(); + + r = (LPCReturn *) FARPKL(&n->rtqDatum); + + if (FARPKS(&r->error) != LPC_NOERROR) { + return -1; + } + + retVal = FARPKL(r->Data); + + // get ready for next call + MGenMoveTo(REC_QUEUE, IDLE_QUEUE); + + return retVal; +} + +void +ZapHostEnt() +{ + // do nothing +} + +void +ReconstructHostEnt(struct hostent *s, void *flattened) +{ + struct hostent *old = (struct hostent *) flattened; + int i; + char **ptr; + + + s->h_name = HostEnt_hname; + fstrncpyfrom(s->h_name, (char *) FARPKL(&old->h_name), HOSTENT_STRLEN_LIMIT-1); + s->h_name[HOSTENT_STRLEN_LIMIT-1] = 0; + + s->h_aliases = HostEnt_h_aliases; + ptr = (char **) FARPKL(&old->h_aliases); + for (i = 0; i < (HOSTENT_ALIAS_LIMIT-1) && FARPKL(ptr); i++, ptr++) { + s->h_aliases[i] = HostEnt_names[i]; + // fstrncpyfrom(s->h_aliases[i], (void *) FARPKL(ptr), HOSTENT_STRLEN_LIMIT-1); + s->h_aliases[i][HOSTENT_STRLEN_LIMIT-1] = 0; + } + s->h_aliases[i] = 0; + + s->h_addrtype = FARPKS(&old->h_addrtype); + s->h_length = FARPKS(&old->h_length); + + if (FARPKS(&old->h_length) != sizeof(struct in_addr)) { + printf("Error!\n"); + exit(0); + } + + s->h_addr_list = (char **) HostEnt_addr_list; + ptr = (char **) FARPKL(&old->h_addr_list); + for (i = 0; i < (HOSTENT_ADDR_LIST_LIMIT - 1) && FARPKL(ptr); i++, ptr++) { + s->h_addr_list[i] = (char *) &(HostEnt_addrs[i]); + fmemcpyfrom(s->h_addr_list[i], (void *) FARPKL(ptr), s->h_length); + } + s->h_addr_list[i] = 0; +} + + +int +getsockname(SOCKET s, struct sockaddr *name, int *namelen) +{ + RTQ_NODE *n = MGenGetNode(IDLE_QUEUE); + LPCData *p; + LPCReturn *r; + GetSockNameRet *ret; + int retVal; + + SocketError = 0; + _farsetsel(flat_selector); + p = (LPCData *) FARPKL(&n->rtqDatum); + SetLPCData(p); + FARPOKL(&p->service, LPC_SOCKGETSOCKNAME); + FARPOKL(p->Data, s); + + MGenMoveTo(IDLE_QUEUE, SEND_QUEUE); + PostWindowsMessage(); + + while ((n = MGenGetNode(REC_QUEUE)) == 0) + Yield(); + + + r = (LPCReturn *) FARPKL(&n->rtqDatum); + + if (FARPKS(&r->error) != LPC_NOERROR) { + return -1; + } + + ret = (GetSockNameRet *) r->Data; + retVal = FARPKL(&ret->retVal); + fmemcpyfrom(name, ret->name, FARPKL(&ret->namelen)); + *namelen = FARPKL(&ret->namelen); + + // get ready for next call + MGenMoveTo(REC_QUEUE, IDLE_QUEUE); + + return retVal; +} + +int +gethostname(char *name, int namelen) +{ + RTQ_NODE *n; + LPCData *p; + LPCReturn *r; + GetHostNameRet *ret; + int retVal; + char *s; + + _farsetsel(flat_selector); + SocketError = 0; + n = (RTQ_NODE *) MGenGetNode(IDLE_QUEUE); + p = (LPCData *) FARPKL(&n->rtqDatum); + SetLPCData(p); + FARPOKL(&p->service,LPC_SOCKGETHOSTNAME); + MGenMoveTo(IDLE_QUEUE, SEND_QUEUE); + PostWindowsMessage(); + + while ((n = (RTQ_NODE *) (MGenGetNode(REC_QUEUE))) == 0) + Yield(); + + r = (LPCReturn *) FARPKL(&n->rtqDatum); + + if (FARPKS(&r->error) != LPC_NOERROR) { + return -1; + } + + ret = (GetHostNameRet *) r->Data; + + retVal = FARPKL(&ret->retVal); + + s = ret->name; + + fstrncpyfrom(name, s, namelen); + +#if 0 + len = strlen(ret->name); + + if (len > namelen) + memcpy(name, ret->name, ret->namelen); + else + strcpy(name, ret->name); +#endif + + // get ready for next call + MGenMoveTo(REC_QUEUE, IDLE_QUEUE); + + return retVal; +} + +struct hostent * +gethostbyname(const char *name) +{ + RTQ_NODE *n = MGenGetNode(IDLE_QUEUE); + LPCData *p; + LPCReturn *r; + struct hostent *retVal; + + _farsetsel(flat_selector); + SocketError = 0; + p = (LPCData *) FARPKL(&n->rtqDatum); + SetLPCData(p); + FARPOKL(&p->service, LPC_SOCKGETHOSTBYNAME); + fstrcpyto(p->Data, name); + + MGenMoveTo(IDLE_QUEUE, SEND_QUEUE); + PostWindowsMessage(); + + while ((n = MGenGetNode(REC_QUEUE)) == 0) + Yield(); + + r = (LPCReturn *) FARPKL(&n->rtqDatum); + retVal = (struct hostent *) r->Data; + + if (FARPKL(&retVal->h_name) == 0) { + retVal = 0; + } else { + ZapHostEnt(); + ReconstructHostEnt(&HostEnt, (void *) retVal); + retVal = &HostEnt; + } + + // get ready for next call + MGenMoveTo(REC_QUEUE, IDLE_QUEUE); + + return retVal; +} + +struct hostent * +gethostbyaddr(const char *addr, int len, int type) +{ + RTQ_NODE *n = MGenGetNode(IDLE_QUEUE); + LPCData *p; + LPCReturn *r; + GetHostByAddrArgs *args; + struct hostent *retVal; + + SocketError = 0; + _farsetsel(flat_selector); + p = (LPCData *) FARPKL(&n->rtqDatum); + SetLPCData(p); + FARPOKL(&p->service, LPC_SOCKGETHOSTBYADDR); + args = (GetHostByAddrArgs *) p->Data; + FARPOKL(&args->len, len); + FARPOKL(&args->type, type); + fmemcpyto(args->addr, addr, len); + + MGenMoveTo(IDLE_QUEUE, SEND_QUEUE); + PostWindowsMessage(); + + while ((n = MGenGetNode(REC_QUEUE)) == 0) + Yield(); + r = (LPCReturn *) FARPKL(&n->rtqDatum); + retVal = (struct hostent *) r->Data; + + if (FARPKL(&retVal->h_name) == 0) { + retVal = 0; + } else { + ZapHostEnt(); + + ReconstructHostEnt(&HostEnt, (void *) retVal); + retVal = &HostEnt; + } + + // get ready for next call + MGenMoveTo(REC_QUEUE, IDLE_QUEUE); + + return retVal; +} + + +SOCKET +socket(int af, int type, int protocol) +{ + RTQ_NODE *n = MGenGetNode(IDLE_QUEUE); + LPCData *p; + LPCReturn *r; + SocketArgs *args; + int retVal; + + _farsetsel(flat_selector); + SocketError = 0; + p = (LPCData *) FARPKL(&n->rtqDatum); + SetLPCData(p); + FARPOKL(&p->service, LPC_SOCKSOCKET); + args = (SocketArgs *) p->Data; + FARPOKL(&args->af, af); + FARPOKL(&args->type, type); + FARPOKL(&args->protocol, protocol); + + MGenMoveTo(IDLE_QUEUE, SEND_QUEUE); + PostWindowsMessage(); + + while ((n = MGenGetNode(REC_QUEUE)) == 0) + Yield(); + + r = (LPCReturn *) FARPKL(&n->rtqDatum); + + + if (FARPKS(&r->error) != LPC_NOERROR) { + return -1; + } + + retVal = FARPKL(r->Data); + + // get ready for next call + MGenMoveTo(REC_QUEUE, IDLE_QUEUE); + + return retVal; +} + +void +sockets_flush(void) +{ + RTQ_NODE *n = MGenGetNode(IDLE_QUEUE); + LPCData *p; + + SocketError = 0; + p = (LPCData *) FARPKL(&n->rtqDatum); + SetLPCData(p); + FARPOKL(&p->service, LPC_SOCKFLUSH); + + MGenMoveTo(IDLE_QUEUE, SEND_QUEUE); + PostWindowsMessage(); + + while ((n = MGenGetNode(REC_QUEUE)) == 0) + Yield(); + + MGenMoveTo(REC_QUEUE, IDLE_QUEUE); +} + +int +recvfrom(SOCKET s, char *buf, int len, int flags, struct sockaddr *from, + int *fromlen) +{ + int i; + RTQ_NODE *n; + WinSockData *data; + int bytesRead; + + SocketError = 0; + _farsetsel(flat_selector); + if (!SockMap) + GetSocketMap(); + + for (i = 0; i < MAXSOCKETS; i++) { + if (FARPKL(&(SockMap->sock[i])) == s) + break; + } + + if (i == MAXSOCKETS) + return SOCKET_ERROR; + + // pick up node + n = MGenGetNode(i); + if (n == 0) { + SocketError = WSAEWOULDBLOCK; + return -1; + } + + data = (WinSockData *) FARPKL(&n->rtqDatum); + bytesRead = FARPKL(&data->len); + + if (from) { + fmemcpyfrom(from, &data->addr, sizeof(struct sockaddr)); + } + + if (fromlen) { + *fromlen = FARPKL(&data->addrlen); + } + + fmemcpyfrom(buf, data->data, len > bytesRead ? bytesRead : len); + + if ((flags & MSG_PEEK) == 0) { + FreeBufferFromQueue(i); + } + + return bytesRead; +} + +int +sendto(SOCKET s, const char *buf, int len, int flags, const struct sockaddr *to, int tolen) +{ + int i; + int outQ; + WinSockData *data; + + SocketError = 0; + _farsetsel(flat_selector); + if (!SockMap) + GetSocketMap(); + + for (i = 0; i < MAXSOCKETS; i++) { + if (FARPKL(&SockMap->sock[i]) == s) { + break; + } + } + + if (i == MAXSOCKETS) { + SocketError = WSAENOTSOCK; + return SOCKET_ERROR; + } + + outQ = i + MAXSOCKETS; + + if (MGenGetQueueCtr(outQ) >= QLIMIT) { + SocketError = WSAEWOULDBLOCK; + return SOCKET_ERROR; + } + + data = GetFreeBufferToQueue(PRIVATEQ, len + sizeof(WinSockData)); + + if (!data) { + SocketError = WSAEWOULDBLOCK; + return SOCKET_ERROR; + } + + FARPOKL(&data->s, s); + FARPOKL(&data->len, len); + if (to) { + fmemcpyto(&data->addr, to, tolen); + FARPOKL(&data->addrlen, tolen); + } else { + FARPOKL(&data->addrlen, 0); + } + + FARPOKL(&data->flags, flags); + + fmemcpyto(data->data, buf, len); + + MGenMoveTo(PRIVATEQ, outQ); + + return len; +} + +int +ioctlsocket(SOCKET s, long cmd, unsigned long *argp) +{ + RTQ_NODE *n = MGenGetNode(IDLE_QUEUE); + LPCData *p; + LPCReturn *r; + IoctlArgs *args; + int retVal; + + SocketError = 0; + _farsetsel(flat_selector); + p = (LPCData *) FARPKL(&n->rtqDatum); + SetLPCData(p); + FARPOKL(&p->service, LPC_SOCKIOCTL); + args = (IoctlArgs *) p->Data; + FARPOKL(&args->s, s); + FARPOKL(&args->cmd, cmd); + + switch(cmd) { + case FIONBIO: + FARPOKL(args->data, *argp); + break; + default: + return SOCKET_ERROR; + } + + MGenMoveTo(IDLE_QUEUE, SEND_QUEUE); + PostWindowsMessage(); + + while ((n = MGenGetNode(REC_QUEUE)) == 0) + Yield(); + + r = (LPCReturn *) FARPKL(&n->rtqDatum); + + + retVal = FARPKL(r->Data); + + // get ready for next call + MGenMoveTo(REC_QUEUE, IDLE_QUEUE); + + return retVal; +} + +int +setsockopt(SOCKET s, int level, int optname, const char *optval, int optlen) +{ + RTQ_NODE *n = MGenGetNode(IDLE_QUEUE); + LPCData *p; + LPCReturn *r; + SetSockOptArgs *args; + int retVal; + + SocketError = 0; + _farsetsel(flat_selector); + p = (LPCData *) FARPKL(&n->rtqDatum); + SetLPCData(p); + FARPOKL(&p->service, LPC_SOCKSETOPT); + args = (SetSockOptArgs *) p->Data; + FARPOKL(&args->s, s); + FARPOKL(&args->level, level); + FARPOKL(&args->optname, optname); + FARPOKL(&args->optlen, optlen); + fmemcpyto(args->optval, optval, optlen); + + MGenMoveTo(IDLE_QUEUE, SEND_QUEUE); + PostWindowsMessage(); + + while ((n = MGenGetNode(REC_QUEUE)) == 0) + Yield(); + + r = (LPCReturn *) FARPKL(&n->rtqDatum); + + retVal = FARPKL(r->Data); + + // get ready for next call + MGenMoveTo(REC_QUEUE, IDLE_QUEUE); + + return retVal; +} + +int +WSAGetLastError(void) +{ + RTQ_NODE *n = MGenGetNode(IDLE_QUEUE); + LPCData *p; + LPCReturn *r; + int retVal; + + + _farsetsel(flat_selector); + if (SocketError) { + int err = SocketError; + + SocketError = 0; + return err; + } + + p = (LPCData *) FARPKL(&n->rtqDatum); + SetLPCData(p); + FARPOKL(&p->service, LPC_SOCKGETLASTERROR); + + MGenMoveTo(IDLE_QUEUE, SEND_QUEUE); + PostWindowsMessage(); + + while ((n = MGenGetNode(REC_QUEUE)) == 0) + Yield(); + + r = (LPCReturn *) FARPKL(&n->rtqDatum); + + + retVal = FARPKL(r->Data); + + // get ready for next call + MGenMoveTo(REC_QUEUE, IDLE_QUEUE); + + return retVal; +} + +unsigned long inet_addr(const char *cp) +{ + int ret; + unsigned int ha1, ha2, ha3, ha4; + unsigned long ipaddr; + + ret = sscanf(cp, "%d.%d.%d.%d", &ha1, &ha2, &ha3, &ha4); + if (ret != 4) + return -1; + ipaddr = (ha1 << 24) | (ha2 << 16) | (ha3 << 8) | ha4; + return ipaddr; +#if 0 + RTQ_NODE *n = MGenGetNode(IDLE_QUEUE); + LPCData *p; + LPCReturn *r; + int retVal; + + SocketError = 0; + _farsetsel(flat_selector); + p = (LPCData *) FARPKL(&n->rtqDatum); + SetLPCData(p); + FARPOKL(&p->service, LPC_SOCKINETADDR); + + fstrcpyto(p->Data, cp); + + MGenMoveTo(IDLE_QUEUE, SEND_QUEUE); + PostWindowsMessage(); + + while ((n = MGenGetNode(REC_QUEUE)) == 0) + Yield(); + + r = (LPCReturn *) FARPKL(&n->rtqDatum); + + if (FARPKS(&r->error) != LPC_NOERROR) { + return -1; + } + + retVal = FARPKL(r->Data); + + // get ready for next call + MGenMoveTo(REC_QUEUE, IDLE_QUEUE); + + return retVal; + #endif +} + +char *inet_ntoa (struct in_addr in) +{ + static char buf [32]; + + sprintf(buf, "%u.%u.%u.%u", in.S_un.S_un_b.s_b1, in.S_un.S_un_b.s_b2, in.S_un.S_un_b.s_b3, in.S_un.S_un_b.s_b4); + return buf; +} diff --git a/contrib/other/sdlquake-1.0.9/net.h b/contrib/other/sdlquake-1.0.9/net.h new file mode 100644 index 000000000..af461256b --- /dev/null +++ b/contrib/other/sdlquake-1.0.9/net.h @@ -0,0 +1,337 @@ +/* +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/contrib/other/sdlquake-1.0.9/net_bsd.c b/contrib/other/sdlquake-1.0.9/net_bsd.c new file mode 100644 index 000000000..79d62f859 --- /dev/null +++ b/contrib/other/sdlquake-1.0.9/net_bsd.c @@ -0,0 +1,93 @@ +/* +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" + +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_udp.h" + +net_landriver_t net_landrivers[MAX_NET_DRIVERS] = +{ + { + "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 + } +}; + +int net_numlandrivers = 1; diff --git a/contrib/other/sdlquake-1.0.9/net_bw.c b/contrib/other/sdlquake-1.0.9/net_bw.c new file mode 100644 index 000000000..2fb3e062a --- /dev/null +++ b/contrib/other/sdlquake-1.0.9/net_bw.c @@ -0,0 +1,763 @@ +/* +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_bw.c + +#include +#include +#include + +#include "quakedef.h" +#include "dosisms.h" + + +// this section is general Unix stuff that we need + +#define EIO 5 /* I/O error */ +#define EBADS 9 +#define EWOULDBLOCK 35 /* function would block */ +#define EMSGSIZE 40 /* message to big for buffers */ +#define EPROTONOSUPPORT 43 /* Protocol not supported */ +#define ESOCKTNOSUPPORT 44 /* Socket type not supported */ +#define EPFNOSUPPORT 46 /* Protocol family not supported */ +#define EAFNOSUPPORT 47 /* Address family not supported */ +#define ECONNABORTED 53 /* User requested hangup */ +#define ENOBUFS 55 /* No buffers available */ +#define EISCONN 56 /* Socket has closed */ +#define ENOTCONN 57 /* Socket is not connected */ +#define ESHUTDOWN 58 /* Socket is closed */ +#define ETOOMANYREFS 59 /* Too many sockets open */ +#define ETIMEDOUT 60 /* Connection timed out */ +#define ECONNREFUSED 61 /* Connection refused */ + +#define AF_INET 2 /* internet */ + +#define PF_INET AF_INET + +#define SOCK_STREAM 1 /* stream */ +#define SOCK_DGRAM 2 /* datagram */ + +#define IPPROTO_TCP 6 +#define IPPROTO_UDP 17 + +#define INADDR_ANY 0 + +#define SIOCDONE 0x7300 +#define FIONREAD 0x667f +#define FIONBIO 0x667e +#define FIONWIN 0x1000 +#define FIONTIN 0x2000 + +#define BRDINIT 0 +#define BRDADDR 10 + +#define MAXHOSTNAMELEN 256 + +#define SOL_SOCKET 0xffff /* options for socket level */ + +/* + * Option flags per-socket. + */ +#define SO_DEBUG 0x0001 /* turn on debugging info recording */ +#define SO_ACCEPTCONN 0x0002 /* socket has had listen() */ +#define SO_REUSEADDR 0x0004 /* allow local address reuse */ +#define SO_KEEPALIVE 0x0008 /* keep connections alive */ +#define SO_DONTROUTE 0x0010 /* just use interface addresses */ +#define SO_BROADCAST 0x0020 /* permit sending of broadcast msgs */ +#define SO_USELOOPBACK 0x0040 /* bypass hardware when possible */ +#define SO_LINGER 0x0080 /* linger on close if data present */ +#define SO_OOBINLINE 0x0100 /* leave received OOB data in line */ +#define SO_USEPRIV 0x4000 /* allocate from privileged port area */ +#define SO_CANTSIG 0x8000 /* prevent SIGPIPE on SS_CANTSENDMORE */ + +/* + * Additional options, not kept in so_options. + */ +#define SO_SNDBUF 0x1001 /* send buffer size */ +#define SO_RCVBUF 0x1002 /* receive buffer size */ +#define SO_SNDLOWAT 0x1003 /* send low-water mark */ +#define SO_RCVLOWAT 0x1004 /* receive low-water mark */ +#define SO_SNDTIMEO 0x1005 /* send timeout */ +#define SO_RCVTIMEO 0x1006 /* receive timeout */ +#define SO_ERROR 0x1007 /* get error status and clear */ +#define SO_TYPE 0x1008 /* get socket type */ + + +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 */ +#define s_host S_un.S_un_b.s_b2 /* host on imp */ +#define s_net S_un.S_un_b.s_b1 /* network */ +#define s_imp S_un.S_un_w.s_w2 /* imp */ +#define s_impno S_un.S_un_b.s_b4 /* imp # */ +#define s_lh S_un.S_un_b.s_b3 /* logical host */ + +struct sockaddr_in +{ + short sin_family; + unsigned short sin_port; + struct in_addr sin_addr; + char sin_zero[8]; +}; + +struct hostent { + char *h_name; /* official name of host */ + char **h_aliases; /* alias list */ + int h_addrtype; /* host address type */ + int h_length; /* length of address */ + char **h_addr_list; /* list of addresses from name server */ +#define h_addr h_addr_list[0] /* address, for backward compatiblity */ +}; + +char *inet_ntoa(struct in_addr in); + + +// this section is B&W specific constants & structures + +#define BW_IOCTL_BIND 0 +#define BW_IOCTL_CLEAROPTIONS 5 +#define BW_IOCTL_SETOPTIONS 6 +#define BW_IOCTL_PEEK 7 +#define BW_IOCTL_SETWINMASK 8 + +#define BW_OPTION_BLOCKING 0x01 +#define BW_OPTION_REUSEBUFFERS 0x80 + +#define BW_ERR_USR_HANGUP 50 +#define BW_ERR_HANGUP 51 +#define BW_ERR_NET_ERR 52 +#define BW_ERR_IS_CLOSED 53 +#define BW_ERR_TIME_OUT 54 +#define BW_ERR_RESET 55 +#define BW_ERR_FULL 56 +#define BW_ERR_BLOCK 57 +#define BW_ERR_SHUTDOWN 58 + +#pragma pack(1) + +typedef struct +{ + char state; // always 1 + short localPort; + struct in_addr localAddr; + char reason; // always 0 + char options; + short dataAvailable; +} BW_UDPinfo_t; + +typedef struct +{ + char reserved1 [6]; + unsigned short info2Offset; + char reserved2 [18]; + struct in_addr remoteAddr; +} BW_UDPreadInfo1_t; + +typedef struct +{ + short remotePort; + char reserved1 [2]; + unsigned short dataLenPlus8; + char reserved2 [2]; + char data[1]; // actual size is - 8 +} BW_UDPreadInfo2_t; + +typedef struct +{ + char reserved1 [2]; + short remotePort; + unsigned short dataLen; + struct in_addr remoteAddr; + char reserved2 [42]; + char data[1]; // actual size is +} BW_writeInfo_t; + +typedef struct +{ + short ioport; + byte dma; + byte vector; + byte irq; + short bufferSize; + short maxWindow; + short timeZone; + byte myType; + int inetAddr; + short value; + byte subnetMask; + short etherPointer; + short logserverPointer; + short nameserverPointer; + short printserverPointer; + short timeserverPointer; + short gatewayPointer; + short driverSegment; + byte transferSize; + char cardName [9]; +} BW_ethdevinfo_t; + +#pragma pack() + +#define LOWMEM_SIZE 4096 + +static unsigned char *lowmem_buffer; +static int lowmem_bufseg; +static int lowmem_bufoff; +static BW_ethdevinfo_t ethdevinfo; +static int netmask; +static struct in_addr bcastaddr; + +extern regs_t regs; + +static int net_acceptsocket = -1; // socket for fielding new connections +static int net_controlsocket = 0; + +#include "net_bw.h" + +//============================================================================= + +static int BW_ioctl(int s, char *msg, int msglen) +{ + Q_memcpy(lowmem_buffer, msg, msglen); + + regs.x.ax = 0x4403; + regs.x.bx = s; + regs.x.cx = msglen; + regs.x.dx = lowmem_bufoff; + regs.x.ds = lowmem_bufseg; + if (dos_int86(0x21)) + return regs.x.ax; + return 0; +} + +//============================================================================= + +static int BW_TranslateError(int error) +{ + switch(error) + { + case BW_ERR_USR_HANGUP: return ECONNABORTED; + case BW_ERR_HANGUP: return EISCONN; + case BW_ERR_NET_ERR: return ENOTCONN; + case BW_ERR_IS_CLOSED: return ENOTCONN; + case BW_ERR_TIME_OUT: return ETIMEDOUT; + case BW_ERR_RESET: return ECONNREFUSED; + case BW_ERR_FULL: return ETOOMANYREFS; + case BW_ERR_BLOCK: return EWOULDBLOCK; + case BW_ERR_SHUTDOWN: return ESHUTDOWN; + } + return EIO; +} + +//============================================================================= + +static int GetEthdevinfo(void) +{ + int fd; + + Q_strcpy((char *)lowmem_buffer, "ETHDEV27"); + regs.x.ax = 0x3d42; + regs.x.ds = lowmem_bufseg; + regs.x.dx = lowmem_bufoff; + if (dos_int86(0x21)) + return -1; + fd = regs.x.ax; + + regs.x.ax = 0x4401; + regs.x.bx = fd; + regs.x.dx = 0x60; + dos_int86(0x21); + + regs.h.ah = 0x3f; + regs.x.cx = sizeof(ethdevinfo); + regs.x.es = regs.x.ds = lowmem_bufseg; + regs.x.dx = lowmem_bufoff; + regs.x.bx = fd; + if (dos_int86(0x21)) + return -1; + Q_memcpy(ðdevinfo, lowmem_buffer, regs.x.ax); + + regs.h.ah = 0x3e; + regs.x.bx = fd; + dos_int86(0x21); + + return 0; +} + +//============================================================================= + +int BW_Init(void) +{ + struct qsockaddr addr; + char *colon; + + if (COM_CheckParm ("-noudp")) + return -1; + + lowmem_buffer = dos_getmemory(LOWMEM_SIZE); + if (!lowmem_buffer) + Sys_Error("not enough low memory\n"); + lowmem_bufoff = ptr2real(lowmem_buffer) & 0xf; + lowmem_bufseg = ptr2real(lowmem_buffer) >> 4; + + if (GetEthdevinfo()) + { + Con_DPrintf("Beame & Whiteside TCP/IP not detected\n"); + dos_freememory(lowmem_buffer); + return -1; + } + netmask = 0xffffffff >> (32 - ethdevinfo.subnetMask); + bcastaddr.s_addr = (ethdevinfo.inetAddr & netmask) | (~netmask); + + if ((net_controlsocket = BW_OpenSocket (0)) == -1) + { + dos_freememory(lowmem_buffer); + Con_DPrintf ("BW_Init unable to open control socket; disabled\n"); + return -1; + } + + BW_GetSocketAddr (net_controlsocket, &addr); + Q_strcpy(my_tcpip_address, BW_AddrToString (&addr)); + colon = Q_strrchr (my_tcpip_address, ':'); + if (colon) + *colon = 0; + + Con_Printf("BW_Init: UDP initialized\n"); + tcpipAvailable = true; + + return net_controlsocket; +} + +//============================================================================= + +void BW_Shutdown(void) +{ + BW_Listen (false); + BW_CloseSocket (net_controlsocket); + dos_freememory(lowmem_buffer); +} + +//============================================================================= + +void BW_Listen (qboolean state) +{ + // enable listening + if (state) + { + if (net_acceptsocket != -1) + return; + if ((net_acceptsocket = BW_OpenSocket (net_hostport)) == -1) + Sys_Error ("BW_Listen: Unable to open accept socket\n"); + return; + } + + // disable listening + if (net_acceptsocket == -1) + return; + BW_CloseSocket (net_acceptsocket); + net_acceptsocket = -1; +} + + +//============================================================================= + +/* +OpenSocket returns a handle to a network socket that has been opened, +set to nonblocking, and bound to . Additional socket options +should be set here if they are needed. -1 is returned on failure. +*/ + +int BW_OpenSocket(int port) +{ + int s; + int ret; + int deadman = 3 * 1024; + static int dynamic = 1024; + static char reuse_msg[2] = {BW_IOCTL_SETOPTIONS, BW_OPTION_REUSEBUFFERS}; + static char bind_msg[3] = {BW_IOCTL_BIND, 0, 0}; + static char nonblock_msg[2] = {BW_IOCTL_CLEAROPTIONS, BW_OPTION_BLOCKING}; + + // allocate a UDP socket + Q_strcpy((char *)lowmem_buffer, "UDP-IP10"); + regs.x.ax = 0x3d42; + regs.x.ds = lowmem_bufseg; + regs.x.dx = lowmem_bufoff; + if (dos_int86(0x21)) + { + Con_Printf("BW_OpenSocket failed: %u\n", BW_TranslateError(regs.x.ax)); + return -1; + } + s = regs.x.ax; + + // set file descriptor to raw mode + regs.x.ax = 0x4401; + regs.x.bx = s; + regs.x.dx = 0x60; + dos_int86(0x21); + + if (BW_ioctl(s, reuse_msg, 2)) + { + Con_Printf("BW_OpenSocket ioctl(reuse) failed\n"); + return -1; + } + + if (BW_ioctl(s, nonblock_msg, 2)) + { + Con_Printf("BW_OpenSocket ioctl(nonblocking) failed\n"); + return -1; + } + + // if a socket was specified, bind to it and return + if (port) + { + *(short *)&bind_msg[1] = port; + if (BW_ioctl(s, bind_msg, 3)) + { + BW_CloseSocket(s); + return -1; + } + return s; + } + + // B&W does NOT do dynamic allocation, so if port == 0 we must fake it + do + { + port = dynamic++; + if (dynamic == 4096) + dynamic = 1024; + deadman--; + *(short *)&bind_msg[1] = port; + ret = BW_ioctl(s, bind_msg, 3); + } + while (ret && deadman); + if (ret) + return -1; + return s; +} + +//============================================================================= + +int BW_CloseSocket(int socket) +{ + regs.h.ah = 0x3e; + regs.x.bx = socket; + if(dos_int86(0x21)) + { + Con_Printf("BW_CloseSocket %u failed: %u\n", socket, BW_TranslateError(regs.x.ax)); + return -1; + } + return 0; +} + +//============================================================================= + +int BW_Connect (int socket, struct qsockaddr *hostaddr) +{ + return 0; +} + +//============================================================================= + +int BW_CheckNewConnections(void) +{ + if (net_acceptsocket == 0) + return -1; + + // see if there's anything waiting + regs.x.ax = 0x4406; + regs.x.bx = net_acceptsocket; + dos_int86(0x21); + if (regs.x.ax == 0) + return -1; + return net_acceptsocket; +} + +//============================================================================= + +int BW_Read(int s, byte *buf, int len, struct qsockaddr *from) +{ + BW_UDPreadInfo1_t *info1; + BW_UDPreadInfo2_t *info2; + + // ask if there's anything waiting + regs.x.ax = 0x4406; + regs.x.bx = s; + dos_int86(0x21); + if (regs.x.ax == 0) + return 0; + + // there was, so let's get it + regs.h.ah = 0x3f; + regs.x.cx = /* len + 53 */ LOWMEM_SIZE; + regs.x.es = regs.x.ds = lowmem_bufseg; + regs.x.dx = lowmem_bufoff; + regs.x.bx = s; + if (dos_int86(0x21)) + { + Con_Printf("BW UDP read error: %u\n", BW_TranslateError(regs.x.ax)); + return -1; + } + + info1 = (BW_UDPreadInfo1_t *)lowmem_buffer; + info2 = (BW_UDPreadInfo2_t *)(lowmem_buffer + info1->info2Offset); + + if (from) + { + from->sa_family = AF_INET; + ((struct sockaddr_in *)from)->sin_addr = info1->remoteAddr; + ((struct sockaddr_in *)from)->sin_port = htons(info2->remotePort); + } + + len = info2->dataLenPlus8 - 8; + if (len > NET_DATAGRAMSIZE) + { + Con_Printf("BW UDP read packet too large: %u\n", len); + return -1; + } + Q_memcpy(buf, info2->data, len); + + return len; +} + +//============================================================================= + +int BW_Broadcast(int s, byte *msg, int len) +{ + BW_writeInfo_t *writeInfo; + + // ask if we're clear to send + regs.x.ax = 0x4407; + regs.x.bx = s; + dos_int86(0x21); + if (regs.x.ax == 0) + return 0; + + // yes, let's do it + writeInfo = (BW_writeInfo_t *)lowmem_buffer; + writeInfo->remoteAddr = bcastaddr; + writeInfo->remotePort = net_hostport; + writeInfo->dataLen = len; + if (len > NET_DATAGRAMSIZE) + Sys_Error("BW UDP write packet too large: %u\n", len); + Q_memcpy(writeInfo->data, msg, len); + writeInfo->data[len] = 0; + regs.h.ah = 0x40; + regs.x.bx = s; + regs.x.cx = len + sizeof(BW_writeInfo_t); + regs.x.es = regs.x.ds = lowmem_bufseg; + regs.x.dx = lowmem_bufoff; + if (dos_int86(0x21)) + { + Con_Printf("BW_Broadcast failed: %u\n", BW_TranslateError(regs.x.ax)); + return -1; + } + + return len; +} + +//============================================================================= + +int BW_Write(int s, byte *msg, int len, struct qsockaddr *to) +{ + BW_writeInfo_t *writeInfo; + + // ask if we're clear to send + regs.x.ax = 0x4407; + regs.x.bx = s; + dos_int86(0x21); + if (regs.x.ax == 0) + return 0; + + // yes, let's do it + writeInfo = (BW_writeInfo_t *)lowmem_buffer; + writeInfo->remoteAddr = ((struct sockaddr_in *)to)->sin_addr; + writeInfo->remotePort = ntohs(((struct sockaddr_in *)to)->sin_port); + writeInfo->dataLen = len; + if (len > NET_DATAGRAMSIZE) + Sys_Error("BW UDP write packet too large: %u\n", len); + Q_memcpy(writeInfo->data, msg, len); + writeInfo->data[len] = 0; + regs.h.ah = 0x40; + regs.x.bx = s; + regs.x.cx = len + sizeof(BW_writeInfo_t); + regs.x.es = regs.x.ds = lowmem_bufseg; + regs.x.dx = lowmem_bufoff; + if (dos_int86(0x21)) + { + Con_Printf("BW_Write failed: %u\n", BW_TranslateError(regs.x.ax)); + return -1; + } + + return len; +} + +//============================================================================= + + +char *BW_AddrToString (struct qsockaddr *addr) +{ + static char buffer[22]; + + sprintf(buffer, "%d.%d.%d.%d:%d", + ((struct sockaddr_in *)addr)->sin_addr.s_net, + ((struct sockaddr_in *)addr)->sin_addr.s_host, + ((struct sockaddr_in *)addr)->sin_addr.s_lh, + ((struct sockaddr_in *)addr)->sin_addr.s_impno, + ntohs(((struct sockaddr_in *)addr)->sin_port) + ); + return buffer; +} + +//============================================================================= + +int BW_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((short)hp); + return 0; +} + +//============================================================================= + +int BW_GetSocketAddr (int socket, struct qsockaddr *addr) +{ + regs.x.ax = 0x4402; + regs.x.bx = socket; + regs.x.cx = sizeof(BW_UDPinfo_t); + regs.x.dx = lowmem_bufoff; + regs.x.ds = lowmem_bufseg; + dos_int86(0x21); + + addr->sa_family = AF_INET; + ((struct sockaddr_in *)addr)->sin_addr.s_addr = ((BW_UDPinfo_t *)lowmem_buffer)->localAddr.s_addr; + ((struct sockaddr_in *)addr)->sin_port = htons(((BW_UDPinfo_t *)lowmem_buffer)->localPort); + + return 0; +} + +//============================================================================= + +int BW_GetNameFromAddr (struct qsockaddr *addr, char *name) +{ + Q_strcpy(name, BW_AddrToString(addr)); + return 0; +} + +///============================================================================= + +int BW_GetAddrFromName (char *name, struct qsockaddr *hostaddr) +{ + char buff[MAXHOSTNAMELEN]; + char *b; + int addr; + int num; + int mask; + int run; + int port; + + if (name[0] < '0' || name[0] > '9') + return -1; + + buff[0] = '.'; + b = buff; + Q_strcpy(buff+1, name); + 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; + } + addr = htonl(addr); + mask = htonl(mask); + + 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 = + ((ethdevinfo.inetAddr & mask) | addr); + + return 0; +} + +//============================================================================= + +int BW_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 BW_GetSocketPort (struct qsockaddr *addr) +{ + return ntohs(((struct sockaddr_in *)addr)->sin_port); +} + + +int BW_SetSocketPort (struct qsockaddr *addr, int port) +{ + ((struct sockaddr_in *)addr)->sin_port = htons(port); + return 0; +} + +//============================================================================= diff --git a/contrib/other/sdlquake-1.0.9/net_bw.h b/contrib/other/sdlquake-1.0.9/net_bw.h new file mode 100644 index 000000000..341c49ae6 --- /dev/null +++ b/contrib/other/sdlquake-1.0.9/net_bw.h @@ -0,0 +1,39 @@ +/* +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_bw.h + +int BW_Init (void); +void BW_Shutdown (void); +void BW_Listen (qboolean state); +int BW_OpenSocket (int port); +int BW_CloseSocket (int socket); +int BW_Connect (int socket, struct qsockaddr *addr); +int BW_CheckNewConnections (void); +int BW_Read (int socket, byte *buf, int len, struct qsockaddr *addr); +int BW_Write (int socket, byte *buf, int len, struct qsockaddr *addr); +int BW_Broadcast (int socket, byte *buf, int len); +char *BW_AddrToString (struct qsockaddr *addr); +int BW_StringToAddr (char *string, struct qsockaddr *addr); +int BW_GetSocketAddr (int socket, struct qsockaddr *addr); +int BW_GetNameFromAddr (struct qsockaddr *addr, char *name); +int BW_GetAddrFromName (char *name, struct qsockaddr *addr); +int BW_AddrCompare (struct qsockaddr *addr1, struct qsockaddr *addr2); +int BW_GetSocketPort (struct qsockaddr *addr); +int BW_SetSocketPort (struct qsockaddr *addr, int port); diff --git a/contrib/other/sdlquake-1.0.9/net_comx.c b/contrib/other/sdlquake-1.0.9/net_comx.c new file mode 100644 index 000000000..2115a14e2 --- /dev/null +++ b/contrib/other/sdlquake-1.0.9/net_comx.c @@ -0,0 +1,1285 @@ +/* +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_comx.c + +#include +#include + +#define NUM_COM_PORTS 2 + +#define ERR_TTY_LINE_STATUS -1 +#define ERR_TTY_MODEM_STATUS -2 +#define ERR_TTY_NODATA -3 + +#define QUEUESIZE 8192 +#define QUEUEMASK (QUEUESIZE - 1) + +typedef struct +{ + volatile int head; + volatile int tail; + volatile byte data[QUEUESIZE]; +} queue; + +#define FULL(q) (q.head == ((q.tail-1) & QUEUEMASK)) +#define EMPTY(q) (q.tail == q.head) +#define ENQUEUE(q,b) (q.data[q.head] = b, q.head = (q.head + 1) & QUEUEMASK) +#define DEQUEUE(q,b) (b = q.data[q.tail], q.tail = (q.tail + 1) & QUEUEMASK) + +extern cvar_t config_com_port; +extern cvar_t config_com_irq; +extern cvar_t config_com_baud; +extern cvar_t config_com_modem; +extern cvar_t config_modem_dialtype; +extern cvar_t config_modem_clear; +extern cvar_t config_modem_init; +extern cvar_t config_modem_hangup; + +extern int m_return_state; +extern int m_state; +extern qboolean m_return_onerror; +extern char m_return_reason[32]; + +// 8250, 16550 definitions +#define TRANSMIT_HOLDING_REGISTER 0x00 +#define RECEIVE_BUFFER_REGISTER 0x00 +#define INTERRUPT_ENABLE_REGISTER 0x01 +#define IER_RX_DATA_READY 0x01 +#define IER_TX_HOLDING_REGISTER_EMPTY 0x02 +#define IER_LINE_STATUS 0x04 +#define IER_MODEM_STATUS 0x08 +#define INTERRUPT_ID_REGISTER 0x02 +#define IIR_MODEM_STATUS_INTERRUPT 0x00 +#define IIR_TX_HOLDING_REGISTER_INTERRUPT 0x02 +#define IIR_RX_DATA_READY_INTERRUPT 0x04 +#define IIR_LINE_STATUS_INTERRUPT 0x06 +#define IIR_FIFO_TIMEOUT 0x0c +#define IIR_FIFO_ENABLED 0xc0 +#define FIFO_CONTROL_REGISTER 0x02 +#define FCR_FIFO_ENABLE 0x01 +#define FCR_RCVR_FIFO_RESET 0x02 +#define FCR_XMIT_FIFO_RESET 0x04 +#define FCR_TRIGGER_01 0x00 +#define FCR_TRIGGER_04 0x40 +#define FCR_TRIGGER_08 0x80 +#define FCR_TRIGGER_16 0xc0 +#define LINE_CONTROL_REGISTER 0x03 +#define LCR_DATA_BITS_5 0x00 +#define LCR_DATA_BITS_6 0x01 +#define LCR_DATA_BITS_7 0x02 +#define LCR_DATA_BITS_8 0x03 +#define LCR_STOP_BITS_1 0x00 +#define LCR_STOP_BITS_2 0x04 +#define LCR_PARITY_NONE 0x00 +#define LCR_PARITY_ODD 0x08 +#define LCR_PARITY_EVEN 0x18 +#define LCR_PARITY_MARK 0x28 +#define LCR_PARITY_SPACE 0x38 +#define LCR_SET_BREAK 0x40 +#define LCR_DLAB 0x80 +#define MODEM_CONTROL_REGISTER 0x04 +#define MCR_DTR 0x01 +#define MCR_RTS 0x02 +#define MCR_OUT1 0x04 +#define MCR_OUT2 0x08 +#define MCR_LOOPBACK 0x10 +#define LINE_STATUS_REGISTER 0x05 +#define LSR_DATA_READY 0x01 +#define LSR_OVERRUN_ERROR 0x02 +#define LSR_PARITY_ERROR 0x04 +#define LSR_FRAMING_ERROR 0x08 +#define LSR_BREAK_DETECT 0x10 +#define LSR_TRANSMITTER_BUFFER_EMPTY 0x20 +#define LSR_TRANSMITTER_EMPTY 0x40 +#define LSR_FIFO_DIRTY 0x80 +#define MODEM_STATUS_REGISTER 0x06 +#define MSR_DELTA_CTS 0x01 +#define MSR_DELTA_DSR 0x02 +#define MSR_DELTA_RI 0x04 +#define MSR_DELTA_CD 0x08 +#define MSR_CTS 0x10 +#define MSR_DSR 0x20 +#define MSR_RI 0x40 +#define MSR_CD 0x80 +#define DIVISOR_LATCH_LOW 0x00 +#define DIVISOR_LATCH_HIGH 0x01 + +#define MODEM_STATUS_MASK (MSR_CTS | MSR_DSR | MSR_CD) + +#define UART_AUTO 0 +#define UART_8250 1 +#define UART_16550 2 + +static int ISA_uarts[] = {0x3f8,0x2f8,0x3e8,0x2e8}; +static int ISA_IRQs[] = {4,3,4,3}; + +typedef struct ComPort_s +{ + struct ComPort_s *next; + _go32_dpmi_seginfo protectedModeInfo; + _go32_dpmi_seginfo protectedModeSaveInfo; + int uart; + volatile byte modemStatus; + byte modemStatusIgnore; + byte lineStatus; + byte bufferUsed; + qboolean enabled; + volatile qboolean statusUpdated; + qboolean useModem; + qboolean modemInitialized; + qboolean modemRang; + qboolean modemConnected; + queue inputQueue; + queue outputQueue; + char clear[16]; + char startup[32]; + char shutdown[16]; + char buffer[128]; + PollProcedure poll; + double timestamp; + byte uartType; + byte irq; + byte baudBits; + byte lineControl; + byte portNumber; + char dialType; + char name[4]; +} ComPort; + +ComPort *portList = NULL; +ComPort *handleToPort [NUM_COM_PORTS]; + +static int Modem_Command(ComPort *p, char *commandString); +static char *Modem_Response(ComPort *p); +static void Modem_Hangup(ComPort *p); + +int TTY_Init(void); +void TTY_Shutdown(void); +int TTY_Open(int serialPortNumber); +void TTY_Close(int handle); +int TTY_ReadByte(int handle); +int TTY_WriteByte(int handle, byte data); +void TTY_Flush(int handle); +int TTY_Connect(int handle, char *host); +void TTY_Disconnect(int handle); +qboolean TTY_CheckForConnection(int handle); +qboolean TTY_IsEnabled(int serialPortNumber); +qboolean TTY_IsModem(int serialPortNumber); +qboolean TTY_OutputQueueIsEmpty(int handle); + +static void ISR_8250 (ComPort *p) +{ + byte source = 0; + byte b; + + disable(); + + while((source = inportb (p->uart + INTERRUPT_ID_REGISTER) & 0x07) != 1) + { + switch (source) + { + case IIR_RX_DATA_READY_INTERRUPT: + b = inportb (p->uart + RECEIVE_BUFFER_REGISTER); + if (! FULL(p->inputQueue)) + { + ENQUEUE (p->inputQueue, b); + } + else + { + p->lineStatus |= LSR_OVERRUN_ERROR; + p->statusUpdated = true; + } + break; + + case IIR_TX_HOLDING_REGISTER_INTERRUPT: + if (! EMPTY(p->outputQueue)) + { + DEQUEUE (p->outputQueue, b); + outportb (p->uart + TRANSMIT_HOLDING_REGISTER, b); + } + break; + + case IIR_MODEM_STATUS_INTERRUPT: + p->modemStatus = (inportb (p->uart + MODEM_STATUS_REGISTER) & MODEM_STATUS_MASK) | p->modemStatusIgnore; + p->statusUpdated = true; + break; + + case IIR_LINE_STATUS_INTERRUPT: + p->lineStatus = inportb (p->uart + LINE_STATUS_REGISTER); + p->statusUpdated = true; + break; + } + source = inportb (p->uart + INTERRUPT_ID_REGISTER) & 0x07; + } + outportb (0x20, 0x20); +} + +static void COM1_ISR_8250 (void) +{ + ISR_8250 (handleToPort[0]); +} + +static void COM2_ISR_8250 (void) +{ + ISR_8250 (handleToPort[1]); +} + + + +static void ISR_16550 (ComPort *p) +{ + int count; + byte source; + byte b; + + disable(); + while((source = inportb (p->uart + INTERRUPT_ID_REGISTER) & 0x07) != 1) + { + switch (source) + { + case IIR_RX_DATA_READY_INTERRUPT: + do + { + b = inportb (p->uart + RECEIVE_BUFFER_REGISTER); + if (!FULL(p->inputQueue)) + { + ENQUEUE (p->inputQueue, b); + } + else + { + p->lineStatus |= LSR_OVERRUN_ERROR; + p->statusUpdated = true; + } + } while (inportb (p->uart + LINE_STATUS_REGISTER) & LSR_DATA_READY); + break; + + case IIR_TX_HOLDING_REGISTER_INTERRUPT: + count = 16; + while ((! EMPTY(p->outputQueue)) && count--) + { + DEQUEUE (p->outputQueue, b); + outportb (p->uart + TRANSMIT_HOLDING_REGISTER, b); + } + break; + + case IIR_MODEM_STATUS_INTERRUPT: + p->modemStatus = (inportb (p->uart + MODEM_STATUS_REGISTER) & MODEM_STATUS_MASK) | p->modemStatusIgnore; + p->statusUpdated = true; + break; + + case IIR_LINE_STATUS_INTERRUPT: + p->lineStatus = inportb (p->uart + LINE_STATUS_REGISTER); + p->statusUpdated = true; + break; + } + source = inportb (p->uart + INTERRUPT_ID_REGISTER) & 0x07; + } + + // check for lost IIR_TX_HOLDING_REGISTER_INTERRUPT on 16550a! + if (inportb (p->uart + LINE_STATUS_REGISTER ) & LSR_TRANSMITTER_EMPTY) + { + count = 16; + while ((! EMPTY(p->outputQueue)) && count--) + { + DEQUEUE (p->outputQueue, b); + outportb (p->uart + TRANSMIT_HOLDING_REGISTER, b); + } + } + + outportb (0x20, 0x20); +} + +static void COM1_ISR_16550 (void) +{ + ISR_16550 (handleToPort[0]); +} + +static void COM2_ISR_16550 (void) +{ + ISR_16550 (handleToPort[1]); +} + + +void TTY_GetComPortConfig (int portNumber, int *port, int *irq, int *baud, qboolean *useModem) +{ + ComPort *p; + + p = handleToPort[portNumber]; + *port = p->uart; + *irq = p->irq; + *baud = 115200 / p->baudBits; + *useModem = p->useModem; +} + +void TTY_SetComPortConfig (int portNumber, int port, int irq, int baud, qboolean useModem) +{ + ComPort *p; + float temp; + + if (useModem) + { + if (baud == 14400) + baud = 19200; + if (baud == 28800) + baud = 38400; + } + + p = handleToPort[portNumber]; + p->uart = port; + p->irq = irq; + p->baudBits = 115200 / baud; + p->useModem = useModem; + + if (useModem) + temp = 1.0; + else + temp = 0.0; + + Cvar_SetValue ("_config_com_port", (float)port); + Cvar_SetValue ("_config_com_irq", (float)irq); + Cvar_SetValue ("_config_com_baud", (float)baud); + Cvar_SetValue ("_config_com_modem", temp); +} + +void TTY_GetModemConfig (int portNumber, char *dialType, char *clear, char *init, char *hangup) +{ + ComPort *p; + + p = handleToPort[portNumber]; + *dialType = p->dialType; + Q_strcpy(clear, p->clear); + Q_strcpy(init, p->startup); + Q_strcpy(hangup, p->shutdown); +} + +void TTY_SetModemConfig (int portNumber, char *dialType, char *clear, char *init, char *hangup) +{ + ComPort *p; + + p = handleToPort[portNumber]; + p->dialType = dialType[0]; + Q_strcpy(p->clear, clear); + Q_strcpy(p->startup, init); + Q_strcpy(p->shutdown, hangup); + + p->modemInitialized = false; + + Cvar_Set ("_config_modem_dialtype", dialType); + Cvar_Set ("_config_modem_clear", clear); + Cvar_Set ("_config_modem_init", init); + Cvar_Set ("_config_modem_hangup", hangup); +} + + +static void ResetComPortConfig (ComPort *p) +{ + p->useModem = false; + p->uartType = UART_AUTO; + p->uart = ISA_uarts[p->portNumber]; + p->irq = ISA_IRQs[p->portNumber]; + p->modemStatusIgnore = MSR_CD | MSR_CTS | MSR_DSR; + p->baudBits = 115200 / 57600; + p->lineControl = LCR_DATA_BITS_8 | LCR_STOP_BITS_1 | LCR_PARITY_NONE; + Q_strcpy(p->clear, "ATZ"); + Q_strcpy(p->startup, ""); + Q_strcpy(p->shutdown, "AT H"); + p->modemRang = false; + p->modemConnected = false; + p->statusUpdated = false; + p->outputQueue.head = p->outputQueue.tail = 0; + p->inputQueue.head = p->inputQueue.tail = 0; +} + + +static void ComPort_Enable(ComPort *p) +{ + void (*isr)(void); + int n; + byte b; + + if (p->enabled) + { + Con_Printf("Already enabled\n"); + return; + } + + // disable all UART interrupts + outportb (p->uart + INTERRUPT_ENABLE_REGISTER, 0); + + // clear out any buffered uncoming data + while((inportb (p->uart + LINE_STATUS_REGISTER)) & LSR_DATA_READY) + inportb (p->uart + RECEIVE_BUFFER_REGISTER); + + // get the current line and modem status + p->modemStatus = (inportb (p->uart + MODEM_STATUS_REGISTER) & MODEM_STATUS_MASK) | p->modemStatusIgnore; + p->lineStatus = inportb (p->uart + LINE_STATUS_REGISTER); + + // clear any UART interrupts + do + { + n = inportb (p->uart + INTERRUPT_ID_REGISTER) & 7; + if (n == IIR_RX_DATA_READY_INTERRUPT) + inportb (p->uart + RECEIVE_BUFFER_REGISTER); + } while (!(n & 1)); + + if (p->uartType == UART_AUTO) + { + outportb (p->uart + FIFO_CONTROL_REGISTER, FCR_FIFO_ENABLE); + b = inportb (p->uart + INTERRUPT_ID_REGISTER); + if ((b & IIR_FIFO_ENABLED) == IIR_FIFO_ENABLED) + p->uartType = UART_16550; + else + p->uartType = UART_8250; + } + + // save the old interrupt handler + _go32_dpmi_get_protected_mode_interrupt_vector(p->irq + 8, &p->protectedModeSaveInfo); + + if (p->uartType == UART_8250) + { + outportb (p->uart + FIFO_CONTROL_REGISTER, 0); + if (p == handleToPort[0]) + isr = COM1_ISR_8250; + else + isr = COM2_ISR_8250; + } + else + { + outportb (p->uart + FIFO_CONTROL_REGISTER, FCR_FIFO_ENABLE | FCR_RCVR_FIFO_RESET | FCR_XMIT_FIFO_RESET | FCR_TRIGGER_08); + if (p == handleToPort[0]) + isr = COM1_ISR_16550; + else + isr = COM2_ISR_16550; + } + + p->protectedModeInfo.pm_offset = (int)isr; + + n = _go32_dpmi_allocate_iret_wrapper(&p->protectedModeInfo); + if (n) + { + Con_Printf("serial: protected mode callback allocation failed\n"); + return; + } + + // disable interrupts at the processor + disable(); + + // install our interrupt handlers now + _go32_dpmi_set_protected_mode_interrupt_vector(p->irq + 8, &p->protectedModeInfo); + + // enable our interrupt at the PIC + outportb (0x21, inportb (0x21) & ~(1<irq)); + + // enable interrupts at the processor + enable(); + + // enable interrupts at the PIC + outportb (0x20, 0xc2); + + // set baud rate & line control + outportb (p->uart + LINE_CONTROL_REGISTER, LCR_DLAB | p->lineControl); + outportb (p->uart, p->baudBits); + outportb (p->uart + 1, 0); + outportb (p->uart + LINE_CONTROL_REGISTER, p->lineControl); + + // set modem control register & enable uart interrupt generation + outportb(p->uart + MODEM_CONTROL_REGISTER, MCR_OUT2 | MCR_RTS | MCR_DTR); + + // enable the individual interrupts at the uart + outportb (p->uart + INTERRUPT_ENABLE_REGISTER, IER_RX_DATA_READY | IER_TX_HOLDING_REGISTER_EMPTY | IER_LINE_STATUS | IER_MODEM_STATUS); + + p->enabled = true; +} + + +static void ComPort_Disable(ComPort *p) +{ + if (!p->enabled) + { + Con_Printf("Already disabled\n"); + return; + } + + // disable interrupts at the uart + outportb (p->uart + INTERRUPT_ENABLE_REGISTER, 0); + + // disable our interrupt at the PIC + outportb (0x21, inportb (0x21) | (1<irq)); + + // disable interrupts at the processor + disable(); + + // restore the old interrupt handler + _go32_dpmi_set_protected_mode_interrupt_vector(p->irq + 8, &p->protectedModeSaveInfo); + _go32_dpmi_free_iret_wrapper(&p->protectedModeInfo); + + // enable interrupts at the processor + enable(); + + p->enabled = false; +} + + +static int CheckStatus (ComPort *p) +{ + int ret = 0; + + if (p->statusUpdated) + { + p->statusUpdated = false; + + if (p->lineStatus & (LSR_OVERRUN_ERROR | LSR_PARITY_ERROR | LSR_FRAMING_ERROR | LSR_BREAK_DETECT)) + { + if (p->lineStatus & LSR_OVERRUN_ERROR) + Con_DPrintf ("Serial overrun error\n"); + if (p->lineStatus & LSR_PARITY_ERROR) + Con_DPrintf ("Serial parity error\n"); + if (p->lineStatus & LSR_FRAMING_ERROR) + Con_DPrintf ("Serial framing error\n"); + if (p->lineStatus & LSR_BREAK_DETECT) + Con_DPrintf ("Serial break detect\n"); + ret = ERR_TTY_LINE_STATUS; + } + + if ((p->modemStatus & MODEM_STATUS_MASK) != MODEM_STATUS_MASK) + { + if (!(p->modemStatus & MSR_CTS)) + Con_Printf ("Serial lost CTS\n"); + if (!(p->modemStatus & MSR_DSR)) + Con_Printf ("Serial lost DSR\n"); + if (!(p->modemStatus & MSR_CD)) + Con_Printf ("Serial lost Carrier\n"); + ret = ERR_TTY_MODEM_STATUS; + } + } + + return ret; +} + + +static void Modem_Init(ComPort *p) +{ + double start; + char *response; + + Con_Printf ("Initializing modem...\n"); + + // write 0 to MCR, wait 1/2 sec, then write the real value back again + // I got this from the guys at head-to-head who say it's necessary. + outportb(p->uart + MODEM_CONTROL_REGISTER, 0); + start = Sys_FloatTime(); + while ((Sys_FloatTime() - start) < 0.5) + ; + outportb(p->uart + MODEM_CONTROL_REGISTER, MCR_OUT2 | MCR_RTS | MCR_DTR); + start = Sys_FloatTime(); + while ((Sys_FloatTime() - start) < 0.25) + ; + + if (*p->clear) + { + Modem_Command (p, p->clear); + start = Sys_FloatTime(); + while(1) + { + if ((Sys_FloatTime() - start) > 3.0) + { + Con_Printf("No response - clear failed\n"); + p->enabled = false; + goto failed; + } + response = Modem_Response(p); + if (!response) + continue; + if (Q_strncmp(response, "OK", 2) == 0) + break; + if (Q_strncmp(response, "ERROR", 5) == 0) + { + p->enabled = false; + goto failed; + } + } + } + + if (*p->startup) + { + Modem_Command (p, p->startup); + start = Sys_FloatTime(); + while(1) + { + if ((Sys_FloatTime() - start) > 3.0) + { + Con_Printf("No response - init failed\n"); + p->enabled = false; + goto failed; + } + response = Modem_Response(p); + if (!response) + continue; + if (Q_strncmp(response, "OK", 2) == 0) + break; + if (Q_strncmp(response, "ERROR", 5) == 0) + { + p->enabled = false; + goto failed; + } + } + } + + p->modemInitialized = true; + return; + +failed: + if (m_return_onerror) + { + key_dest = key_menu; + m_state = m_return_state; + m_return_onerror = false; + Q_strcpy(m_return_reason, "Initialization Failed"); + } + return; +} + + +void TTY_Enable(int handle) +{ + ComPort *p; + + p = handleToPort [handle]; + if (p->enabled) + return; + + ComPort_Enable(p); + + if (p->useModem && !p->modemInitialized) + Modem_Init (p); +} + + +int TTY_Open(int serialPortNumber) +{ + return serialPortNumber; +} + + +void TTY_Close(int handle) +{ + ComPort *p; + double startTime; + + p = handleToPort [handle]; + + startTime = Sys_FloatTime(); + while ((Sys_FloatTime() - startTime) < 1.0) + if (EMPTY(p->outputQueue)) + break; + + if (p->useModem) + { + if (p->modemConnected) + Modem_Hangup(p); + } +} + + +int TTY_ReadByte(int handle) +{ + int ret; + ComPort *p; + + p = handleToPort [handle]; + + if ((ret = CheckStatus (p)) != 0) + return ret; + + if (EMPTY (p->inputQueue)) + return ERR_TTY_NODATA; + + DEQUEUE (p->inputQueue, ret); + return (ret & 0xff); +} + + +int TTY_WriteByte(int handle, byte data) +{ + ComPort *p; + + p = handleToPort [handle]; + if (FULL(p->outputQueue)) + return -1; + + ENQUEUE (p->outputQueue, data); + return 0; +} + + +void TTY_Flush(int handle) +{ + byte b; + ComPort *p; + + p = handleToPort [handle]; + + if (inportb (p->uart + LINE_STATUS_REGISTER ) & LSR_TRANSMITTER_EMPTY) + { + DEQUEUE (p->outputQueue, b); + outportb(p->uart, b); + } +} + + +int TTY_Connect(int handle, char *host) +{ + double start; + ComPort *p; + char *response = NULL; + keydest_t save_key_dest; + byte dialstring[64]; + byte b; + + p = handleToPort[handle]; + + if ((p->modemStatus & MODEM_STATUS_MASK) != MODEM_STATUS_MASK) + { + Con_Printf ("Serial: line not ready ("); + if ((p->modemStatus & MSR_CTS) == 0) + Con_Printf(" CTS"); + if ((p->modemStatus & MSR_DSR) == 0) + Con_Printf(" DSR"); + if ((p->modemStatus & MSR_CD) == 0) + Con_Printf(" CD"); + Con_Printf(" )"); + return -1; + } + + // discard any scraps in the input buffer + while (! EMPTY (p->inputQueue)) + DEQUEUE (p->inputQueue, b); + + CheckStatus (p); + + if (p->useModem) + { + save_key_dest = key_dest; + key_dest = key_console; + key_count = -2; + + Con_Printf ("Dialing...\n"); + sprintf(dialstring, "AT D%c %s\r", p->dialType, host); + Modem_Command (p, dialstring); + start = Sys_FloatTime(); + while(1) + { + if ((Sys_FloatTime() - start) > 60.0) + { + Con_Printf("Dialing failure!\n"); + break; + } + + Sys_SendKeyEvents (); + if (key_count == 0) + { + if (key_lastpress != K_ESCAPE) + { + key_count = -2; + continue; + } + Con_Printf("Aborting...\n"); + while ((Sys_FloatTime() - start) < 5.0) + ; + disable(); + p->outputQueue.head = p->outputQueue.tail = 0; + p->inputQueue.head = p->inputQueue.tail = 0; + outportb(p->uart + MODEM_CONTROL_REGISTER, inportb(p->uart + MODEM_CONTROL_REGISTER) & ~MCR_DTR); + enable(); + start = Sys_FloatTime(); + while ((Sys_FloatTime() - start) < 0.75) + ; + outportb(p->uart + MODEM_CONTROL_REGISTER, inportb(p->uart + MODEM_CONTROL_REGISTER) | MCR_DTR); + response = "Aborted"; + break; + } + + response = Modem_Response(p); + if (!response) + continue; + if (Q_strncmp(response, "CONNECT", 7) == 0) + { + disable(); + p->modemRang = true; + p->modemConnected = true; + p->outputQueue.head = p->outputQueue.tail = 0; + p->inputQueue.head = p->inputQueue.tail = 0; + enable(); + key_dest = save_key_dest; + key_count = 0; + m_return_onerror = false; + return 0; + } + if (Q_strncmp(response, "NO CARRIER", 10) == 0) + break; + if (Q_strncmp(response, "NO DIALTONE", 11) == 0) + break; + if (Q_strncmp(response, "NO DIAL TONE", 12) == 0) + break; + if (Q_strncmp(response, "NO ANSWER", 9) == 0) + break; + if (Q_strncmp(response, "BUSY", 4) == 0) + break; + if (Q_strncmp(response, "ERROR", 5) == 0) + break; + } + key_dest = save_key_dest; + key_count = 0; + if (m_return_onerror) + { + key_dest = key_menu; + m_state = m_return_state; + m_return_onerror = false; + Q_strncpy(m_return_reason, response, 31); + } + return -1; + } + m_return_onerror = false; + return 0; +} + + +void TTY_Disconnect(int handle) +{ + ComPort *p; + + p = handleToPort[handle]; + + if (p->useModem && p->modemConnected) + Modem_Hangup(p); +} + + +qboolean TTY_CheckForConnection(int handle) +{ + ComPort *p; + + p = handleToPort[handle]; + + CheckStatus (p); + + if (p->useModem) + { + if (!p->modemRang) + { + if (!Modem_Response(p)) + return false; + + if (Q_strncmp(p->buffer, "RING", 4) == 0) + { + Modem_Command (p, "ATA"); + p->modemRang = true; + p->timestamp = net_time; + } + return false; + } + if (!p->modemConnected) + { + if ((net_time - p->timestamp) > 35.0) + { + Con_Printf("Unable to establish modem connection\n"); + p->modemRang = false; + return false; + } + + if (!Modem_Response(p)) + return false; + + if (Q_strncmp (p->buffer, "CONNECT", 7) != 0) + return false; + + disable(); + p->modemConnected = true; + p->outputQueue.head = p->outputQueue.tail = 0; + p->inputQueue.head = p->inputQueue.tail = 0; + enable(); + Con_Printf("Modem Connect\n"); + return true; + } + return true; + } + + // direct connect case + if (EMPTY (p->inputQueue)) + return false; + return true; +} + + +qboolean TTY_IsEnabled(int serialPortNumber) +{ + return handleToPort[serialPortNumber]->enabled; +} + + +qboolean TTY_IsModem(int serialPortNumber) +{ + return handleToPort[serialPortNumber]->useModem; +} + + +qboolean TTY_OutputQueueIsEmpty(int handle) +{ + return EMPTY(handleToPort[handle]->outputQueue); +} + + +void Com_f (void) +{ + ComPort *p; + int portNumber; + int i; + int n; + + // first, determine which port they're messing with + portNumber = Q_atoi(Cmd_Argv (0) + 3) - 1; + if (portNumber > 1) + return; + p = handleToPort[portNumber]; + + if (Cmd_Argc() == 1) + { + Con_Printf("Settings for COM%i\n", portNumber + 1); + Con_Printf("enabled: %s\n", p->enabled ? "true" : "false"); + Con_Printf("uart: "); + if (p->uartType == UART_AUTO) + Con_Printf("auto\n"); + else if (p->uartType == UART_8250) + Con_Printf("8250\n"); + else + Con_Printf("16550\n"); + Con_Printf("port: %x\n", p->uart); + Con_Printf("irq: %i\n", p->irq); + Con_Printf("baud: %i\n", 115200 / p->baudBits); + Con_Printf("CTS: %s\n", (p->modemStatusIgnore & MSR_CTS) ? "ignored" : "honored"); + Con_Printf("DSR: %s\n", (p->modemStatusIgnore & MSR_DSR) ? "ignored" : "honored"); + Con_Printf("CD: %s\n", (p->modemStatusIgnore & MSR_CD) ? "ignored" : "honored"); + if (p->useModem) + { + Con_Printf("type: Modem\n"); + Con_Printf("clear: %s\n", p->clear); + Con_Printf("startup: %s\n", p->startup); + Con_Printf("shutdown: %s\n", p->shutdown); + } + else + Con_Printf("type: Direct connect\n"); + + return; + } + + + if (Cmd_CheckParm ("disable")) + { + if (p->enabled) + ComPort_Disable(p); + p->modemInitialized = false; + return; + } + + if (Cmd_CheckParm ("reset")) + { + ComPort_Disable(p); + ResetComPortConfig (p); + return; + } + + if ((i = Cmd_CheckParm ("port")) != 0) + { + if (p->enabled) + { + Con_Printf("COM port must be disabled to change port\n"); + return; + } + p->uart = Q_atoi (Cmd_Argv (i+1)); + } + + if ((i = Cmd_CheckParm ("irq")) != 0) + { + if (p->enabled) + { + Con_Printf("COM port must be disabled to change irq\n"); + return; + } + p->irq = Q_atoi (Cmd_Argv (i+1)); + } + + if ((i = Cmd_CheckParm ("baud")) != 0) + { + if (p->enabled) + { + Con_Printf("COM port must be disabled to change baud\n"); + return; + } + n = Q_atoi (Cmd_Argv (i+1)); + if (n == 0) + Con_Printf("Invalid baud rate specified\n"); + else + p->baudBits = 115200 / n; + } + + if (Cmd_CheckParm ("8250")) + { + if (p->enabled) + { + Con_Printf("COM port must be disabled to change uart\n"); + return; + } + p->uartType = UART_8250; + } + if (Cmd_CheckParm ("16550")) + { + if (p->enabled) + { + Con_Printf("COM port must be disabled to change uart\n"); + return; + } + p->uartType = UART_16550; + } + if (Cmd_CheckParm ("auto")) + { + if (p->enabled) + { + Con_Printf("COM port must be disabled to change uart\n"); + return; + } + p->uartType = UART_AUTO; + } + + if (Cmd_CheckParm ("pulse")) + p->dialType = 'P'; + if (Cmd_CheckParm ("tone")) + p->dialType = 'T'; + + if (Cmd_CheckParm ("direct")) + p->useModem = false; + if (Cmd_CheckParm ("modem")) + p->useModem = true; + + if ((i = Cmd_CheckParm ("clear")) != 0) + { + Q_strncpy (p->clear, Cmd_Argv (i+1), 16); + } + + if ((i = Cmd_CheckParm ("startup")) != 0) + { + Q_strncpy (p->startup, Cmd_Argv (i+1), 32); + p->modemInitialized = false; + } + + if ((i = Cmd_CheckParm ("shutdown")) != 0) + { + Q_strncpy (p->shutdown, Cmd_Argv (i+1), 16); + } + + if (Cmd_CheckParm ("-cts")) + { + p->modemStatusIgnore |= MSR_CTS; + p->modemStatus |= MSR_CTS; + } + + if (Cmd_CheckParm ("+cts")) + { + p->modemStatusIgnore &= (~MSR_CTS); + p->modemStatus = (inportb (p->uart + MODEM_STATUS_REGISTER) & MODEM_STATUS_MASK) | p->modemStatusIgnore; + } + + if (Cmd_CheckParm ("-dsr")) + { + p->modemStatusIgnore |= MSR_DSR; + p->modemStatus |= MSR_DSR; + } + + if (Cmd_CheckParm ("+dsr")) + { + p->modemStatusIgnore &= (~MSR_DSR); + p->modemStatus = (inportb (p->uart + MODEM_STATUS_REGISTER) & MODEM_STATUS_MASK) | p->modemStatusIgnore; + } + + if (Cmd_CheckParm ("-cd")) + { + p->modemStatusIgnore |= MSR_CD; + p->modemStatus |= MSR_CD; + } + + if (Cmd_CheckParm ("+cd")) + { + p->modemStatusIgnore &= (~MSR_CD); + p->modemStatus = (inportb (p->uart + MODEM_STATUS_REGISTER) & MODEM_STATUS_MASK) | p->modemStatusIgnore; + } + + if (Cmd_CheckParm ("enable")) + { + if (!p->enabled) + ComPort_Enable(p); + if (p->useModem && !p->modemInitialized) + Modem_Init (p); + } +} + + +int TTY_Init(void) +{ + int n; + ComPort *p; + + for (n = 0; n < NUM_COM_PORTS; n++) + { + p = (ComPort *)Hunk_AllocName(sizeof(ComPort), "comport"); + if (p == NULL) + Sys_Error("Hunk alloc failed for com port\n"); + p->next = portList; + portList = p; + handleToPort[n] = p; + p->portNumber = n; + p->dialType = 'T'; + sprintf(p->name, "com%u", n+1); + Cmd_AddCommand (p->name, Com_f); + ResetComPortConfig (p); + } + + GetComPortConfig = TTY_GetComPortConfig; + SetComPortConfig = TTY_SetComPortConfig; + GetModemConfig = TTY_GetModemConfig; + SetModemConfig = TTY_SetModemConfig; + + return 0; +} + + +void TTY_Shutdown(void) +{ + int n; + ComPort *p; + + for (n = 0; n < NUM_COM_PORTS; n++) + { + p = handleToPort[n]; + if (p->enabled) + { + while (p->modemConnected) + NET_Poll(); + ComPort_Disable (p); + } + } +} + + +static int Modem_Command(ComPort *p, char *commandString) +{ + byte b; + + if (CheckStatus (p)) + return -1; + + disable(); + p->outputQueue.head = p->outputQueue.tail = 0; + p->inputQueue.head = p->inputQueue.tail = 0; + enable(); + p->bufferUsed = 0; + + while (*commandString) + ENQUEUE (p->outputQueue, *commandString++); + ENQUEUE (p->outputQueue, '\r'); + + // get the transmit rolling + DEQUEUE (p->outputQueue, b); + outportb(p->uart, b); + + return 0; +} + + +static char *Modem_Response(ComPort *p) +{ + byte b; + + if (CheckStatus (p)) + return NULL; + + while (! EMPTY(p->inputQueue)) + { + DEQUEUE (p->inputQueue, b); + + if (p->bufferUsed == (sizeof(p->buffer) - 1)) + b = '\r'; + + if (b == '\r' && p->bufferUsed) + { + p->buffer[p->bufferUsed] = 0; + Con_Printf("%s\n", p->buffer); + SCR_UpdateScreen (); + p->bufferUsed = 0; + return p->buffer; + } + + if (b < ' ' || b > 'z') + continue; + p->buffer[p->bufferUsed] = b; + p->bufferUsed++; + } + + return NULL; +} + + +static void Modem_Hangup2(ComPort *p); +static void Modem_Hangup3(ComPort *p); +static void Modem_Hangup4(ComPort *p); + +static void Modem_Hangup(ComPort *p) +{ + Con_Printf("Hanging up modem...\n"); + disable(); + p->modemRang = false; + p->outputQueue.head = p->outputQueue.tail = 0; + p->inputQueue.head = p->inputQueue.tail = 0; + outportb(p->uart + MODEM_CONTROL_REGISTER, inportb(p->uart + MODEM_CONTROL_REGISTER) & ~MCR_DTR); + enable(); + p->poll.procedure = Modem_Hangup2; + p->poll.arg = p; + SchedulePollProcedure(&p->poll, 1.5); +} + +static void Modem_Hangup2(ComPort *p) +{ + outportb(p->uart + MODEM_CONTROL_REGISTER, inportb(p->uart + MODEM_CONTROL_REGISTER) | MCR_DTR); + Modem_Command(p, "+++"); + p->poll.procedure = Modem_Hangup3; + SchedulePollProcedure(&p->poll, 1.5); +} + +static void Modem_Hangup3(ComPort *p) +{ + Modem_Command(p, p->shutdown); + p->poll.procedure = Modem_Hangup4; + SchedulePollProcedure(&p->poll, 1.5); +} + +static void Modem_Hangup4(ComPort *p) +{ + Modem_Response(p); + Con_Printf("Hangup complete\n"); + p->modemConnected = false; +} diff --git a/contrib/other/sdlquake-1.0.9/net_dgrm.c b/contrib/other/sdlquake-1.0.9/net_dgrm.c new file mode 100644 index 000000000..a293b77b9 --- /dev/null +++ b/contrib/other/sdlquake-1.0.9/net_dgrm.c @@ -0,0 +1,1390 @@ +/* +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_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 "quakedef.h" +#include "net_dgrm.h" + +// these two macros are to make the code more readable +#define sfunc net_landrivers[sock->landriver] +#define dfunc net_landrivers[net_landriverlevel] + +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 +{ + unsigned int length; + unsigned int sequence; + byte data[MAX_DATAGRAM]; +} packetBuffer; + +extern int m_return_state; +extern int m_state; +extern qboolean m_return_onerror; +extern char m_return_reason[32]; + + +#ifdef DEBUG +char *StrAddr (struct qsockaddr *addr) +{ + static char buf[34]; + byte *p = (byte *)addr; + int n; + + for (n = 0; n < 16; n++) + 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) +{ + char addrStr [32]; + char maskStr [32]; + void (*print) (char *fmt, ...); + + if (cmd_source == src_command) + { + if (!sv.active) + { + Cmd_ForwardToServer (); + return; + } + print = Con_Printf; + } + else + { + if (pr_global_struct->deathmatch && !host_client->privileged) + return; + print = 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; + + default: + print("BAN ip_address [mask]\n"); + break; + } +} +#endif + + +int Datagram_SendMessage (qsocket_t *sock, sizebuf_t *data) +{ + unsigned int packetLen; + unsigned int dataLen; + unsigned int eom; + +#ifdef DEBUG + if (data->cursize == 0) + Sys_Error("Datagram_SendMessage: zero length message\n"); + + if (data->cursize > NET_MAXMESSAGE) + Sys_Error("Datagram_SendMessage: message too big %u\n", data->cursize); + + if (sock->canSend == false) + Sys_Error("SendMessage: called with canSend == false\n"); +#endif + + Q_memcpy(sock->sendMessage, data->data, data->cursize); + sock->sendMessageLength = data->cursize; + + if (data->cursize <= MAX_DATAGRAM) + { + dataLen = data->cursize; + eom = NETFLAG_EOM; + } + else + { + dataLen = MAX_DATAGRAM; + eom = 0; + } + packetLen = NET_HEADERSIZE + dataLen; + + packetBuffer.length = BigLong(packetLen | (NETFLAG_DATA | eom)); + packetBuffer.sequence = BigLong(sock->sendSequence++); + Q_memcpy (packetBuffer.data, sock->sendMessage, dataLen); + + sock->canSend = false; + + if (sfunc.Write (sock->socket, (byte *)&packetBuffer, packetLen, &sock->addr) == -1) + return -1; + + sock->lastSendTime = net_time; + packetsSent++; + return 1; +} + + +int SendMessageNext (qsocket_t *sock) +{ + unsigned int packetLen; + unsigned int dataLen; + unsigned int eom; + + if (sock->sendMessageLength <= MAX_DATAGRAM) + { + dataLen = sock->sendMessageLength; + eom = NETFLAG_EOM; + } + else + { + dataLen = MAX_DATAGRAM; + eom = 0; + } + packetLen = NET_HEADERSIZE + dataLen; + + packetBuffer.length = BigLong(packetLen | (NETFLAG_DATA | eom)); + packetBuffer.sequence = BigLong(sock->sendSequence++); + Q_memcpy (packetBuffer.data, sock->sendMessage, dataLen); + + sock->sendNext = false; + + if (sfunc.Write (sock->socket, (byte *)&packetBuffer, packetLen, &sock->addr) == -1) + return -1; + + sock->lastSendTime = net_time; + packetsSent++; + return 1; +} + + +int ReSendMessage (qsocket_t *sock) +{ + unsigned int packetLen; + unsigned int dataLen; + unsigned int eom; + + if (sock->sendMessageLength <= MAX_DATAGRAM) + { + dataLen = sock->sendMessageLength; + eom = NETFLAG_EOM; + } + else + { + dataLen = MAX_DATAGRAM; + eom = 0; + } + packetLen = NET_HEADERSIZE + dataLen; + + packetBuffer.length = BigLong(packetLen | (NETFLAG_DATA | eom)); + packetBuffer.sequence = BigLong(sock->sendSequence - 1); + Q_memcpy (packetBuffer.data, sock->sendMessage, dataLen); + + sock->sendNext = false; + + if (sfunc.Write (sock->socket, (byte *)&packetBuffer, packetLen, &sock->addr) == -1) + return -1; + + sock->lastSendTime = net_time; + packetsReSent++; + return 1; +} + + +qboolean Datagram_CanSendMessage (qsocket_t *sock) +{ + if (sock->sendNext) + SendMessageNext (sock); + + return sock->canSend; +} + + +qboolean Datagram_CanSendUnreliableMessage (qsocket_t *sock) +{ + return true; +} + + +int Datagram_SendUnreliableMessage (qsocket_t *sock, sizebuf_t *data) +{ + int packetLen; + +#ifdef DEBUG + if (data->cursize == 0) + Sys_Error("Datagram_SendUnreliableMessage: zero length message\n"); + + if (data->cursize > MAX_DATAGRAM) + Sys_Error("Datagram_SendUnreliableMessage: message too big %u\n", data->cursize); +#endif + + packetLen = NET_HEADERSIZE + data->cursize; + + packetBuffer.length = BigLong(packetLen | NETFLAG_UNRELIABLE); + packetBuffer.sequence = BigLong(sock->unreliableSendSequence++); + Q_memcpy (packetBuffer.data, data->data, data->cursize); + + if (sfunc.Write (sock->socket, (byte *)&packetBuffer, packetLen, &sock->addr) == -1) + return -1; + + packetsSent++; + return 1; +} + + +int Datagram_GetMessage (qsocket_t *sock) +{ + unsigned int length; + unsigned int flags; + int ret = 0; + struct qsockaddr readaddr; + unsigned int sequence; + unsigned int count; + + if (!sock->canSend) + if ((net_time - sock->lastSendTime) > 1.0) + ReSendMessage (sock); + + while(1) + { + length = sfunc.Read (sock->socket, (byte *)&packetBuffer, NET_DATAGRAMSIZE, &readaddr); + +// if ((rand() & 255) > 220) +// continue; + + if (length == 0) + break; + + if (length == -1) + { + Con_Printf("Read error\n"); + return -1; + } + + 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 + continue; + } + + if (length < NET_HEADERSIZE) + { + shortPacketCount++; + continue; + } + + length = BigLong(packetBuffer.length); + flags = length & (~NETFLAG_LENGTH_MASK); + length &= NETFLAG_LENGTH_MASK; + + if (flags & NETFLAG_CTL) + continue; + + sequence = BigLong(packetBuffer.sequence); + packetsReceived++; + + if (flags & NETFLAG_UNRELIABLE) + { + if (sequence < sock->unreliableReceiveSequence) + { + Con_DPrintf("Got a stale datagram\n"); + ret = 0; + break; + } + if (sequence != sock->unreliableReceiveSequence) + { + count = sequence - sock->unreliableReceiveSequence; + droppedDatagrams += count; + Con_DPrintf("Dropped %u datagram(s)\n", count); + } + sock->unreliableReceiveSequence = sequence + 1; + + length -= NET_HEADERSIZE; + + SZ_Clear (&net_message); + SZ_Write (&net_message, packetBuffer.data, length); + + ret = 2; + break; + } + + if (flags & NETFLAG_ACK) + { + if (sequence != (sock->sendSequence - 1)) + { + Con_DPrintf("Stale ACK received\n"); + continue; + } + if (sequence == sock->ackSequence) + { + sock->ackSequence++; + if (sock->ackSequence != sock->sendSequence) + Con_DPrintf("ack sequencing error\n"); + } + else + { + Con_DPrintf("Duplicate ACK received\n"); + continue; + } + sock->sendMessageLength -= MAX_DATAGRAM; + if (sock->sendMessageLength > 0) + { + Q_memcpy(sock->sendMessage, sock->sendMessage+MAX_DATAGRAM, sock->sendMessageLength); + sock->sendNext = true; + } + else + { + sock->sendMessageLength = 0; + sock->canSend = true; + } + continue; + } + + if (flags & NETFLAG_DATA) + { + packetBuffer.length = BigLong(NET_HEADERSIZE | NETFLAG_ACK); + packetBuffer.sequence = BigLong(sequence); + sfunc.Write (sock->socket, (byte *)&packetBuffer, NET_HEADERSIZE, &readaddr); + + if (sequence != sock->receiveSequence) + { + receivedDuplicateCount++; + continue; + } + sock->receiveSequence++; + + length -= NET_HEADERSIZE; + + if (flags & NETFLAG_EOM) + { + SZ_Clear(&net_message); + SZ_Write(&net_message, sock->receiveMessage, sock->receiveMessageLength); + SZ_Write(&net_message, packetBuffer.data, length); + sock->receiveMessageLength = 0; + + ret = 1; + break; + } + + Q_memcpy(sock->receiveMessage + sock->receiveMessageLength, packetBuffer.data, length); + sock->receiveMessageLength += length; + continue; + } + } + + if (sock->sendNext) + SendMessageNext (sock); + + return ret; +} + + +void PrintStats(qsocket_t *s) +{ + Con_Printf("canSend = %4u \n", s->canSend); + Con_Printf("sendSeq = %4u ", s->sendSequence); + Con_Printf("recvSeq = %4u \n", s->receiveSequence); + Con_Printf("\n"); +} + +void NET_Stats_f (void) +{ + qsocket_t *s; + + if (Cmd_Argc () == 1) + { + Con_Printf("unreliable messages sent = %i\n", unreliableMessagesSent); + Con_Printf("unreliable messages recv = %i\n", unreliableMessagesReceived); + Con_Printf("reliable messages sent = %i\n", messagesSent); + Con_Printf("reliable messages received = %i\n", messagesReceived); + Con_Printf("packetsSent = %i\n", packetsSent); + Con_Printf("packetsReSent = %i\n", packetsReSent); + Con_Printf("packetsReceived = %i\n", packetsReceived); + Con_Printf("receivedDuplicateCount = %i\n", receivedDuplicateCount); + Con_Printf("shortPacketCount = %i\n", shortPacketCount); + Con_Printf("droppedDatagrams = %i\n", droppedDatagrams); + } + else if (Q_strcmp(Cmd_Argv(1), "*") == 0) + { + for (s = net_activeSockets; s; s = s->next) + PrintStats(s); + for (s = net_freeSockets; s; s = s->next) + PrintStats(s); + } + else + { + for (s = net_activeSockets; s; s = s->next) + 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) + break; + if (s == NULL) + return; + PrintStats(s); + } +} + + +static qboolean testInProgress = false; +static int testPollCount; +static int testDriver; +static int testSocket; + +static void Test_Poll(void); +PollProcedure testPollProcedure = {NULL, 0.0, Test_Poll}; + +static void Test_Poll(void) +{ + struct qsockaddr clientaddr; + int control; + int len; + char name[32]; + char address[64]; + 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)) + break; + + net_message.cursize = len; + + MSG_BeginReading (); + control = BigLong(*((int *)net_message.data)); + MSG_ReadLong(); + if (control == -1) + break; + if ((control & (~NETFLAG_LENGTH_MASK)) != NETFLAG_CTL) + break; + if ((control & NETFLAG_LENGTH_MASK) != len) + break; + + if (MSG_ReadByte() != CCREP_PLAYER_INFO) + Sys_Error("Unexpected repsonse to Player Info request\n"); + + playerNumber = MSG_ReadByte(); + 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); + } + + testPollCount--; + if (testPollCount) + { + SchedulePollProcedure(&testPollProcedure, 0.1); + } + else + { + dfunc.CloseSocket(testSocket); + testInProgress = false; + } +} + +static void Test_f (void) +{ + char *host; + int n; + int max = MAX_SCOREBOARD; + struct qsockaddr sendaddr; + + if (testInProgress) + return; + + host = Cmd_Argv (1); + + if (host && hostCacheCount) + { + for (n = 0; n < hostCacheCount; n++) + if (Q_strcasecmp (host, hostcache[n].name) == 0) + { + if (hostcache[n].driver != myDriverLevel) + continue; + net_landriverlevel = hostcache[n].ldriver; + max = hostcache[n].maxusers; + Q_memcpy(&sendaddr, &hostcache[n].addr, sizeof(struct qsockaddr)); + break; + } + if (n < hostCacheCount) + goto JustDoIt; + } + + for (net_landriverlevel = 0; net_landriverlevel < net_numlandrivers; net_landriverlevel++) + { + if (!net_landrivers[net_landriverlevel].initialized) + continue; + + // see if we can resolve the host name + if (dfunc.GetAddrFromName(host, &sendaddr) != -1) + break; + } + if (net_landriverlevel == net_numlandrivers) + return; + +JustDoIt: + testSocket = dfunc.OpenSocket(0); + if (testSocket == -1) + return; + + testInProgress = true; + testPollCount = 20; + testDriver = net_landriverlevel; + + for (n = 0; n < max; 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)); + dfunc.Write (testSocket, net_message.data, net_message.cursize, &sendaddr); + } + SZ_Clear(&net_message); + SchedulePollProcedure(&testPollProcedure, 0.1); +} + + +static qboolean test2InProgress = false; +static int test2Driver; +static int test2Socket; + +static void Test2_Poll(void); +PollProcedure test2PollProcedure = {NULL, 0.0, Test2_Poll}; + +static void Test2_Poll(void) +{ + struct qsockaddr clientaddr; + int control; + int len; + char name[256]; + char value[256]; + + net_landriverlevel = test2Driver; + name[0] = 0; + + len = dfunc.Read (test2Socket, net_message.data, net_message.maxsize, &clientaddr); + if (len < sizeof(int)) + goto Reschedule; + + net_message.cursize = len; + + MSG_BeginReading (); + control = BigLong(*((int *)net_message.data)); + MSG_ReadLong(); + if (control == -1) + goto Error; + if ((control & (~NETFLAG_LENGTH_MASK)) != NETFLAG_CTL) + goto Error; + if ((control & NETFLAG_LENGTH_MASK) != len) + goto Error; + + if (MSG_ReadByte() != CCREP_RULE_INFO) + goto Error; + + Q_strcpy(name, MSG_ReadString()); + if (name[0] == 0) + goto Done; + Q_strcpy(value, MSG_ReadString()); + + Con_Printf("%-16.16s %-16.16s\n", name, value); + + SZ_Clear(&net_message); + // save space for the header, filled in later + MSG_WriteLong(&net_message, 0); + MSG_WriteByte(&net_message, CCREQ_RULE_INFO); + MSG_WriteString(&net_message, name); + *((int *)net_message.data) = BigLong(NETFLAG_CTL | (net_message.cursize & NETFLAG_LENGTH_MASK)); + dfunc.Write (test2Socket, net_message.data, net_message.cursize, &clientaddr); + SZ_Clear(&net_message); + +Reschedule: + SchedulePollProcedure(&test2PollProcedure, 0.05); + return; + +Error: + Con_Printf("Unexpected repsonse to Rule Info request\n"); +Done: + dfunc.CloseSocket(test2Socket); + test2InProgress = false; + return; +} + +static void Test2_f (void) +{ + char *host; + int n; + struct qsockaddr sendaddr; + + if (test2InProgress) + return; + + host = Cmd_Argv (1); + + if (host && hostCacheCount) + { + for (n = 0; n < hostCacheCount; n++) + if (Q_strcasecmp (host, hostcache[n].name) == 0) + { + if (hostcache[n].driver != myDriverLevel) + continue; + net_landriverlevel = hostcache[n].ldriver; + Q_memcpy(&sendaddr, &hostcache[n].addr, sizeof(struct qsockaddr)); + break; + } + if (n < hostCacheCount) + goto JustDoIt; + } + + for (net_landriverlevel = 0; net_landriverlevel < net_numlandrivers; net_landriverlevel++) + { + if (!net_landrivers[net_landriverlevel].initialized) + continue; + + // see if we can resolve the host name + if (dfunc.GetAddrFromName(host, &sendaddr) != -1) + break; + } + if (net_landriverlevel == net_numlandrivers) + return; + +JustDoIt: + test2Socket = dfunc.OpenSocket(0); + if (test2Socket == -1) + return; + + test2InProgress = true; + test2Driver = net_landriverlevel; + + SZ_Clear(&net_message); + // save space for the header, filled in later + MSG_WriteLong(&net_message, 0); + MSG_WriteByte(&net_message, CCREQ_RULE_INFO); + MSG_WriteString(&net_message, ""); + *((int *)net_message.data) = BigLong(NETFLAG_CTL | (net_message.cursize & NETFLAG_LENGTH_MASK)); + dfunc.Write (test2Socket, net_message.data, net_message.cursize, &sendaddr); + SZ_Clear(&net_message); + SchedulePollProcedure(&test2PollProcedure, 0.05); +} + + +int Datagram_Init (void) +{ + int i; + int csock; + + myDriverLevel = net_driverlevel; + Cmd_AddCommand ("net_stats", NET_Stats_f); + + if (COM_CheckParm("-nolan")) + return -1; + + for (i = 0; i < net_numlandrivers; i++) + { + csock = net_landrivers[i].Init (); + if (csock == -1) + continue; + net_landrivers[i].initialized = true; + net_landrivers[i].controlSock = csock; + } + +#ifdef BAN_TEST + Cmd_AddCommand ("ban", NET_Ban_f); +#endif + Cmd_AddCommand ("test", Test_f); + Cmd_AddCommand ("test2", Test2_f); + + return 0; +} + + +void Datagram_Shutdown (void) +{ + int i; + +// +// shutdown the lan drivers +// + for (i = 0; i < net_numlandrivers; i++) + { + if (net_landrivers[i].initialized) + { + net_landrivers[i].Shutdown (); + net_landrivers[i].initialized = false; + } + } +} + + +void Datagram_Close (qsocket_t *sock) +{ + sfunc.CloseSocket(sock->socket); +} + + +void Datagram_Listen (qboolean state) +{ + int i; + + for (i = 0; i < net_numlandrivers; i++) + if (net_landrivers[i].initialized) + net_landrivers[i].Listen (state); +} + + +static qsocket_t *_Datagram_CheckNewConnections (void) +{ + struct qsockaddr clientaddr; + struct qsockaddr newaddr; + int newsock; + int acceptsock; + qsocket_t *sock; + qsocket_t *s; + int len; + int command; + int control; + int ret; + + acceptsock = dfunc.CheckNewConnections(); + if (acceptsock == -1) + return NULL; + + SZ_Clear(&net_message); + + len = dfunc.Read (acceptsock, net_message.data, net_message.maxsize, &clientaddr); + if (len < sizeof(int)) + return NULL; + net_message.cursize = len; + + MSG_BeginReading (); + control = BigLong(*((int *)net_message.data)); + MSG_ReadLong(); + if (control == -1) + return NULL; + if ((control & (~NETFLAG_LENGTH_MASK)) != NETFLAG_CTL) + return NULL; + if ((control & NETFLAG_LENGTH_MASK) != len) + return NULL; + + command = MSG_ReadByte(); + if (command == CCREQ_SERVER_INFO) + { + if (Q_strcmp(MSG_ReadString(), "QUAKE") != 0) + return NULL; + + SZ_Clear(&net_message); + // save space for the header, filled in later + MSG_WriteLong(&net_message, 0); + MSG_WriteByte(&net_message, CCREP_SERVER_INFO); + dfunc.GetSocketAddr(acceptsock, &newaddr); + MSG_WriteString(&net_message, dfunc.AddrToString(&newaddr)); + MSG_WriteString(&net_message, hostname.string); + MSG_WriteString(&net_message, sv.name); + MSG_WriteByte(&net_message, net_activeconnections); + MSG_WriteByte(&net_message, svs.maxclients); + MSG_WriteByte(&net_message, NET_PROTOCOL_VERSION); + *((int *)net_message.data) = BigLong(NETFLAG_CTL | (net_message.cursize & NETFLAG_LENGTH_MASK)); + dfunc.Write (acceptsock, net_message.data, net_message.cursize, &clientaddr); + SZ_Clear(&net_message); + return NULL; + } + + if (command == CCREQ_PLAYER_INFO) + { + int playerNumber; + 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) + { + activeNumber++; + if (activeNumber == playerNumber) + break; + } + } + if (clientNumber == svs.maxclients) + return NULL; + + SZ_Clear(&net_message); + // save space for the header, filled in later + MSG_WriteLong(&net_message, 0); + MSG_WriteByte(&net_message, CCREP_PLAYER_INFO); + MSG_WriteByte(&net_message, playerNumber); + MSG_WriteString(&net_message, client->name); + MSG_WriteLong(&net_message, client->colors); + MSG_WriteLong(&net_message, (int)client->edict->v.frags); + MSG_WriteLong(&net_message, (int)(net_time - client->netconnection->connecttime)); + MSG_WriteString(&net_message, client->netconnection->address); + *((int *)net_message.data) = BigLong(NETFLAG_CTL | (net_message.cursize & NETFLAG_LENGTH_MASK)); + dfunc.Write (acceptsock, net_message.data, net_message.cursize, &clientaddr); + SZ_Clear(&net_message); + + return NULL; + } + + if (command == CCREQ_RULE_INFO) + { + 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; + } + + // send the response + + SZ_Clear(&net_message); + // save space for the header, filled in later + MSG_WriteLong(&net_message, 0); + MSG_WriteByte(&net_message, CCREP_RULE_INFO); + if (var) + { + MSG_WriteString(&net_message, var->name); + MSG_WriteString(&net_message, var->string); + } + *((int *)net_message.data) = BigLong(NETFLAG_CTL | (net_message.cursize & NETFLAG_LENGTH_MASK)); + dfunc.Write (acceptsock, net_message.data, net_message.cursize, &clientaddr); + SZ_Clear(&net_message); + + return NULL; + } + + if (command != CCREQ_CONNECT) + return NULL; + + if (Q_strcmp(MSG_ReadString(), "QUAKE") != 0) + return NULL; + + if (MSG_ReadByte() != NET_PROTOCOL_VERSION) + { + SZ_Clear(&net_message); + // save space for the header, filled in later + MSG_WriteLong(&net_message, 0); + MSG_WriteByte(&net_message, CCREP_REJECT); + MSG_WriteString(&net_message, "Incompatible version.\n"); + *((int *)net_message.data) = BigLong(NETFLAG_CTL | (net_message.cursize & NETFLAG_LENGTH_MASK)); + dfunc.Write (acceptsock, net_message.data, net_message.cursize, &clientaddr); + SZ_Clear(&net_message); + return NULL; + } + +#ifdef BAN_TEST + // check for a ban + if (clientaddr.sa_family == AF_INET) + { + unsigned long testAddr; + testAddr = ((struct sockaddr_in *)&clientaddr)->sin_addr.s_addr; + if ((testAddr & banMask) == banAddr) + { + SZ_Clear(&net_message); + // save space for the header, filled in later + MSG_WriteLong(&net_message, 0); + MSG_WriteByte(&net_message, CCREP_REJECT); + MSG_WriteString(&net_message, "You have been banned.\n"); + *((int *)net_message.data) = BigLong(NETFLAG_CTL | (net_message.cursize & NETFLAG_LENGTH_MASK)); + dfunc.Write (acceptsock, net_message.data, net_message.cursize, &clientaddr); + SZ_Clear(&net_message); + return NULL; + } + } +#endif + + // see if this guy is already connected + for (s = net_activeSockets; s; s = s->next) + { + if (s->driver != net_driverlevel) + continue; + ret = dfunc.AddrCompare(&clientaddr, &s->addr); + if (ret >= 0) + { + // is this a duplicate connection reqeust? + if (ret == 0 && net_time - s->connecttime < 2.0) + { + // yes, so send a duplicate reply + SZ_Clear(&net_message); + // save space for the header, filled in later + MSG_WriteLong(&net_message, 0); + MSG_WriteByte(&net_message, CCREP_ACCEPT); + dfunc.GetSocketAddr(s->socket, &newaddr); + MSG_WriteLong(&net_message, dfunc.GetSocketPort(&newaddr)); + *((int *)net_message.data) = BigLong(NETFLAG_CTL | (net_message.cursize & NETFLAG_LENGTH_MASK)); + dfunc.Write (acceptsock, net_message.data, net_message.cursize, &clientaddr); + SZ_Clear(&net_message); + return NULL; + } + // it's somebody coming back in from a crash/disconnect + // so close the old qsocket and let their retry get them back in + NET_Close(s); + return NULL; + } + } + + // allocate a QSocket + sock = NET_NewQSocket (); + if (sock == NULL) + { + // no room; try to let him know + SZ_Clear(&net_message); + // save space for the header, filled in later + MSG_WriteLong(&net_message, 0); + MSG_WriteByte(&net_message, CCREP_REJECT); + MSG_WriteString(&net_message, "Server is full.\n"); + *((int *)net_message.data) = BigLong(NETFLAG_CTL | (net_message.cursize & NETFLAG_LENGTH_MASK)); + dfunc.Write (acceptsock, net_message.data, net_message.cursize, &clientaddr); + SZ_Clear(&net_message); + return NULL; + } + + // allocate a network socket + newsock = dfunc.OpenSocket(0); + if (newsock == -1) + { + NET_FreeQSocket(sock); + return NULL; + } + + // connect to the client + if (dfunc.Connect (newsock, &clientaddr) == -1) + { + dfunc.CloseSocket(newsock); + NET_FreeQSocket(sock); + return NULL; + } + + // everything is allocated, just fill in the details + sock->socket = newsock; + sock->landriver = net_landriverlevel; + sock->addr = clientaddr; + Q_strcpy(sock->address, dfunc.AddrToString(&clientaddr)); + + // send him back the info about the server connection he has been allocated + SZ_Clear(&net_message); + // save space for the header, filled in later + MSG_WriteLong(&net_message, 0); + MSG_WriteByte(&net_message, CCREP_ACCEPT); + dfunc.GetSocketAddr(newsock, &newaddr); + MSG_WriteLong(&net_message, dfunc.GetSocketPort(&newaddr)); +// MSG_WriteString(&net_message, dfunc.AddrToString(&newaddr)); + *((int *)net_message.data) = BigLong(NETFLAG_CTL | (net_message.cursize & NETFLAG_LENGTH_MASK)); + dfunc.Write (acceptsock, net_message.data, net_message.cursize, &clientaddr); + SZ_Clear(&net_message); + + return sock; +} + +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; +} + + +static void _Datagram_SearchForHosts (qboolean xmit) +{ + int ret; + int n; + int i; + struct qsockaddr readaddr; + struct qsockaddr myaddr; + int control; + + dfunc.GetSocketAddr (dfunc.controlSock, &myaddr); + if (xmit) + { + SZ_Clear(&net_message); + // save space for the header, filled in later + MSG_WriteLong(&net_message, 0); + MSG_WriteByte(&net_message, CCREQ_SERVER_INFO); + MSG_WriteString(&net_message, "QUAKE"); + MSG_WriteByte(&net_message, NET_PROTOCOL_VERSION); + *((int *)net_message.data) = BigLong(NETFLAG_CTL | (net_message.cursize & NETFLAG_LENGTH_MASK)); + dfunc.Broadcast(dfunc.controlSock, net_message.data, net_message.cursize); + SZ_Clear(&net_message); + } + + while ((ret = dfunc.Read (dfunc.controlSock, net_message.data, net_message.maxsize, &readaddr)) > 0) + { + if (ret < sizeof(int)) + continue; + net_message.cursize = ret; + + // don't answer our own query + if (dfunc.AddrCompare(&readaddr, &myaddr) >= 0) + continue; + + // is the cache full? + if (hostCacheCount == HOSTCACHESIZE) + continue; + + MSG_BeginReading (); + control = BigLong(*((int *)net_message.data)); + MSG_ReadLong(); + if (control == -1) + continue; + if ((control & (~NETFLAG_LENGTH_MASK)) != NETFLAG_CTL) + continue; + if ((control & NETFLAG_LENGTH_MASK) != ret) + continue; + + if (MSG_ReadByte() != CCREP_SERVER_INFO) + continue; + + 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) + continue; + + // add it + hostCacheCount++; + Q_strcpy(hostcache[n].name, MSG_ReadString()); + Q_strcpy(hostcache[n].map, MSG_ReadString()); + hostcache[n].users = MSG_ReadByte(); + hostcache[n].maxusers = MSG_ReadByte(); + if (MSG_ReadByte() != NET_PROTOCOL_VERSION) + { + Q_strcpy(hostcache[n].cname, hostcache[n].name); + hostcache[n].cname[14] = 0; + Q_strcpy(hostcache[n].name, "*"); + Q_strcat(hostcache[n].name, hostcache[n].cname); + } + Q_memcpy(&hostcache[n].addr, &readaddr, sizeof(struct qsockaddr)); + hostcache[n].driver = net_driverlevel; + hostcache[n].ldriver = net_landriverlevel; + Q_strcpy(hostcache[n].cname, dfunc.AddrToString(&readaddr)); + + // check for a name conflict + for (i = 0; i < hostCacheCount; i++) + { + if (i == n) + continue; + 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') + { + hostcache[n].name[i] = '0'; + hostcache[n].name[i+1] = 0; + } + else + hostcache[n].name[i-1]++; + i = -1; + } + } + } +} + +void Datagram_SearchForHosts (qboolean xmit) +{ + for (net_landriverlevel = 0; net_landriverlevel < net_numlandrivers; net_landriverlevel++) + { + if (hostCacheCount == HOSTCACHESIZE) + break; + if (net_landrivers[net_landriverlevel].initialized) + _Datagram_SearchForHosts (xmit); + } +} + + +static qsocket_t *_Datagram_Connect (char *host) +{ + struct qsockaddr sendaddr; + struct qsockaddr readaddr; + qsocket_t *sock; + int newsock; + int ret; + int reps; + double start_time; + int control; + char *reason; + + // see if we can resolve the host name + if (dfunc.GetAddrFromName(host, &sendaddr) == -1) + return NULL; + + newsock = dfunc.OpenSocket (0); + if (newsock == -1) + return NULL; + + sock = NET_NewQSocket (); + if (sock == NULL) + goto ErrorReturn2; + sock->socket = newsock; + sock->landriver = net_landriverlevel; + + // connect to the host + if (dfunc.Connect (newsock, &sendaddr) == -1) + goto ErrorReturn; + + // send the connection request + Con_Printf("trying...\n"); SCR_UpdateScreen (); + start_time = net_time; + + for (reps = 0; reps < 3; reps++) + { + SZ_Clear(&net_message); + // save space for the header, filled in later + MSG_WriteLong(&net_message, 0); + MSG_WriteByte(&net_message, CCREQ_CONNECT); + MSG_WriteString(&net_message, "QUAKE"); + MSG_WriteByte(&net_message, NET_PROTOCOL_VERSION); + *((int *)net_message.data) = BigLong(NETFLAG_CTL | (net_message.cursize & NETFLAG_LENGTH_MASK)); + dfunc.Write (newsock, net_message.data, net_message.cursize, &sendaddr); + SZ_Clear(&net_message); + do + { + ret = dfunc.Read (newsock, net_message.data, net_message.maxsize, &readaddr); + // if we got something, validate it + if (ret > 0) + { + // 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)); + SCR_UpdateScreen (); +#endif + ret = 0; + continue; + } + + if (ret < sizeof(int)) + { + ret = 0; + continue; + } + + net_message.cursize = ret; + MSG_BeginReading (); + + control = BigLong(*((int *)net_message.data)); + MSG_ReadLong(); + if (control == -1) + { + ret = 0; + continue; + } + if ((control & (~NETFLAG_LENGTH_MASK)) != NETFLAG_CTL) + { + ret = 0; + continue; + } + if ((control & NETFLAG_LENGTH_MASK) != ret) + { + ret = 0; + continue; + } + } + } + while (ret == 0 && (SetNetTime() - start_time) < 2.5); + if (ret) + break; + Con_Printf("still trying...\n"); SCR_UpdateScreen (); + start_time = SetNetTime(); + } + + if (ret == 0) + { + reason = "No Response"; + Con_Printf("%s\n", reason); + Q_strcpy(m_return_reason, reason); + goto ErrorReturn; + } + + if (ret == -1) + { + reason = "Network Error"; + Con_Printf("%s\n", reason); + Q_strcpy(m_return_reason, reason); + goto ErrorReturn; + } + + ret = MSG_ReadByte(); + if (ret == CCREP_REJECT) + { + reason = MSG_ReadString(); + Con_Printf(reason); + Q_strncpy(m_return_reason, reason, 31); + goto ErrorReturn; + } + + if (ret == CCREP_ACCEPT) + { + Q_memcpy(&sock->addr, &sendaddr, sizeof(struct qsockaddr)); + dfunc.SetSocketPort (&sock->addr, MSG_ReadLong()); + } + else + { + reason = "Bad Response"; + Con_Printf("%s\n", reason); + Q_strcpy(m_return_reason, reason); + goto ErrorReturn; + } + + dfunc.GetNameFromAddr (&sendaddr, sock->address); + + Con_Printf ("Connection accepted\n"); + sock->lastMessageTime = SetNetTime(); + + // switch the connection to the specified address + if (dfunc.Connect (newsock, &sock->addr) == -1) + { + reason = "Connect to Game failed"; + Con_Printf("%s\n", reason); + Q_strcpy(m_return_reason, reason); + goto ErrorReturn; + } + + m_return_onerror = false; + return sock; + +ErrorReturn: + NET_FreeQSocket(sock); +ErrorReturn2: + dfunc.CloseSocket(newsock); + if (m_return_onerror) + { + key_dest = key_menu; + m_state = m_return_state; + m_return_onerror = false; + } + return NULL; +} + +qsocket_t *Datagram_Connect (char *host) +{ + qsocket_t *ret = NULL; + + 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/contrib/other/sdlquake-1.0.9/net_dgrm.h b/contrib/other/sdlquake-1.0.9/net_dgrm.h new file mode 100644 index 000000000..da052e701 --- /dev/null +++ b/contrib/other/sdlquake-1.0.9/net_dgrm.h @@ -0,0 +1,34 @@ +/* +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_dgrm.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); +int Datagram_GetMessage (qsocket_t *sock); +int Datagram_SendMessage (qsocket_t *sock, sizebuf_t *data); +int Datagram_SendUnreliableMessage (qsocket_t *sock, sizebuf_t *data); +qboolean Datagram_CanSendMessage (qsocket_t *sock); +qboolean Datagram_CanSendUnreliableMessage (qsocket_t *sock); +void Datagram_Close (qsocket_t *sock); +void Datagram_Shutdown (void); diff --git a/contrib/other/sdlquake-1.0.9/net_dos.c b/contrib/other/sdlquake-1.0.9/net_dos.c new file mode 100644 index 000000000..5dbbdcefb --- /dev/null +++ b/contrib/other/sdlquake-1.0.9/net_dos.c @@ -0,0 +1,162 @@ +/* +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 + } + , + { + "Serial", + false, + Serial_Init, + Serial_Listen, + Serial_SearchForHosts, + Serial_Connect, + Serial_CheckNewConnections, + Serial_GetMessage, + Serial_SendMessage, + Serial_SendUnreliableMessage, + Serial_CanSendMessage, + Serial_CanSendUnreliableMessage, + Serial_Close, + Serial_Shutdown + } +}; + +int net_numdrivers = 3; + + +#include "net_bw.h" +#include "net_ipx.h" +#include "net_mp.h" + +net_landriver_t net_landrivers[MAX_NET_DRIVERS] = +{ + { + "Beame & Whiteside TCP/IP", + false, + 0, + BW_Init, + BW_Shutdown, + BW_Listen, + BW_OpenSocket, + BW_CloseSocket, + BW_Connect, + BW_CheckNewConnections, + BW_Read, + BW_Write, + BW_Broadcast, + BW_AddrToString, + BW_StringToAddr, + BW_GetSocketAddr, + BW_GetNameFromAddr, + BW_GetAddrFromName, + BW_AddrCompare, + BW_GetSocketPort, + BW_SetSocketPort + } +, + { + "IPX", + false, + 0, + IPX_Init, + IPX_Shutdown, + IPX_Listen, + IPX_OpenSocket, + IPX_CloseSocket, + IPX_Connect, + IPX_CheckNewConnections, + IPX_Read, + IPX_Write, + IPX_Broadcast, + IPX_AddrToString, + IPX_StringToAddr, + IPX_GetSocketAddr, + IPX_GetNameFromAddr, + IPX_GetAddrFromName, + IPX_AddrCompare, + IPX_GetSocketPort, + IPX_SetSocketPort + } +, + { + "Win95 TCP/IP", + false, + 0, + MPATH_Init, + MPATH_Shutdown, + MPATH_Listen, + MPATH_OpenSocket, + MPATH_CloseSocket, + MPATH_Connect, + MPATH_CheckNewConnections, + MPATH_Read, + MPATH_Write, + MPATH_Broadcast, + MPATH_AddrToString, + MPATH_StringToAddr, + MPATH_GetSocketAddr, + MPATH_GetNameFromAddr, + MPATH_GetAddrFromName, + MPATH_AddrCompare, + MPATH_GetSocketPort, + MPATH_SetSocketPort + } +}; + +int net_numlandrivers = 3; diff --git a/contrib/other/sdlquake-1.0.9/net_ipx.c b/contrib/other/sdlquake-1.0.9/net_ipx.c new file mode 100644 index 000000000..f0ab72ef2 --- /dev/null +++ b/contrib/other/sdlquake-1.0.9/net_ipx.c @@ -0,0 +1,706 @@ +/* +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_ipx.c + +#include +#include +#include + +#include "quakedef.h" +#include "dosisms.h" +#include "net_ipx.h" + +#define EIO 5 /* I/O error */ + +#define AF_NETWARE 64 + +#define IPX_OPEN 0 +#define IPX_CLOSE 1 +#define IPX_GETROUTE 2 +#define IPX_SEND 3 +#define IPX_LISTEN 4 +#define IPX_SCHEDULEEVENT 5 +#define IPX_CANCEL 6 +#define IPX_SCHEDULESPECIALEVENT 7 +#define IPX_GETINTERVALMARKER 8 +#define IPX_GETADDRESS 9 +#define IPX_RELINQUISH 10 + +#define PTYPE_UNKNOWN 0 +#define PTYPE_RIP 1 +#define PTYPE_ECHO 2 +#define PTYPE_ERROR 3 +#define PTYPE_IPX 4 +#define PTYPE_SPX 5 + +#pragma pack(1) + +typedef struct +{ + byte network[4]; + byte node[6]; + short socket; +} IPXaddr; + +struct sockaddr_ipx +{ + short sipx_family; + IPXaddr sipx_addr; + char sipx_zero[2]; +}; +#define sipx_port sipx_addr.socket + +typedef struct +{ + short checkSum; + short length; + byte transportControl; + byte type; + IPXaddr destination; + IPXaddr source; +} IPXheader; + +typedef struct ECBStructure +{ + struct ECBStructure *link; + unsigned short ESR_off; + unsigned short ESR_seg; + byte inUse; + byte completionCode; + short socket; + byte IPXWorkspace[4]; + byte driverWorkspace[12]; + byte immediateAddress[6]; + short fragCount; + short fragOff; + short fragSeg; + short fragSize; +} ECB; + +#pragma pack() + +typedef struct +{ + ECB ecb; + IPXheader header; + int sequence; + char data[NET_DATAGRAMSIZE]; +} ipx_lowmem_buffer_t; + +#define LOWMEMSIZE (100 * 1024) +#define LOWMEMSAVE 256 +#define IPXBUFFERS ((LOWMEMSIZE - LOWMEMSAVE)/ sizeof(ipx_lowmem_buffer_t)) +#define IPXSOCKBUFFERS 5 +#define IPXSOCKETS (IPXBUFFERS / IPXSOCKBUFFERS) + +// each socket's socketbuffer 0 is used for sending, the others for listening + +typedef struct +{ + char reserved[LOWMEMSAVE]; + ipx_lowmem_buffer_t socketbuffer[IPXSOCKETS][IPXSOCKBUFFERS]; +} ipx_lowmem_area_t; + + +static int ipxsocket[IPXSOCKETS]; +static ECB *readlist[IPXSOCKETS]; +static int sequence[IPXSOCKETS]; +static int handlesInUse; +static ipx_lowmem_area_t *lma; +static char *lowmem_buffer; +static int lowmem_bufseg; +static int lowmem_bufoff; +static unsigned short ipx_cs; +static unsigned short ipx_ip; +static int net_acceptsocket = -1; +static int net_controlsocket; + +static void IPX_PollProcedure(void); +static PollProcedure pollProcedure = {NULL, 0.0, IPX_PollProcedure}; + +//============================================================================= + +static void IPX_GetLocalAddress(IPXaddr *addr) +{ + regs.x.cs = ipx_cs; + regs.x.ip = ipx_ip; + regs.x.bx = IPX_GETADDRESS; + regs.x.es = lowmem_bufseg; + regs.x.si = lowmem_bufoff; + __dpmi_simulate_real_mode_procedure_retf((__dpmi_regs *)®s); + Q_memcpy(addr, lowmem_buffer, 10); +} + +//============================================================================= + +static int IPX_GetLocalTarget(IPXaddr *addr, byte *localTarget) +{ + regs.x.cs = ipx_cs; + regs.x.ip = ipx_ip; + regs.x.bx = IPX_GETROUTE; + regs.x.es = lowmem_bufseg; + regs.x.si = lowmem_bufoff; + regs.x.di = lowmem_bufoff + sizeof(IPXaddr); + Q_memcpy(lowmem_buffer, addr, sizeof(IPXaddr)); + __dpmi_simulate_real_mode_procedure_retf((__dpmi_regs *)®s); + if (regs.h.al) + return -1; + Q_memcpy(localTarget, lowmem_buffer + sizeof(IPXaddr), 6); + return 0; +} + +//============================================================================= + +static void IPX_ListenForPacket(ECB *ecb) +{ + regs.x.cs = ipx_cs; + regs.x.ip = ipx_ip; + regs.x.bx = IPX_LISTEN; + regs.x.es = ptr2real(ecb) >> 4; + regs.x.si = ptr2real(ecb) & 0xf; + __dpmi_simulate_real_mode_procedure_retf((__dpmi_regs *)®s); +} + +//============================================================================= + +static void IPX_RelinquishControl(void) +{ + regs.x.cs = ipx_cs; + regs.x.ip = ipx_ip; + regs.x.bx = IPX_RELINQUISH; + __dpmi_simulate_real_mode_procedure_retf((__dpmi_regs *)®s); +} + + +void IPX_PollProcedure(void) +{ + IPX_RelinquishControl(); + SchedulePollProcedure(&pollProcedure, 0.01); +} + +//============================================================================= + +static void ProcessReadyList(int s) +{ + int n; + ECB *ecb; + ECB *prev; + + for (n = 1; n < IPXSOCKBUFFERS; n++) + { + if (lma->socketbuffer[s][n].ecb.inUse == 0) + { + for (ecb = readlist[s], prev = NULL; ecb; ecb = ecb->link) + { + if (lma->socketbuffer[s][n].sequence < ((ipx_lowmem_buffer_t *) ecb)->sequence) + break; + prev = ecb; + } + if (ecb) + lma->socketbuffer[s][n].ecb.link = ecb; + else + lma->socketbuffer[s][n].ecb.link = NULL; + if (prev) + prev->link = &lma->socketbuffer[s][n].ecb; + else + readlist[s] = &lma->socketbuffer[s][n].ecb; + lma->socketbuffer[s][n].ecb.inUse = 0xff; + } + } +} + +//============================================================================= + +int IPX_Init(void) +{ + int s; + int n; + struct qsockaddr addr; + char *colon; + + if (COM_CheckParm ("-noipx")) + return -1; + + // find the IPX far call entry point + regs.x.ax = 0x7a00; + __dpmi_simulate_real_mode_interrupt (0x2f, (__dpmi_regs *)®s); + if (regs.h.al != 0xff) + { + Con_Printf("IPX not detected\n"); + return -1; + } + ipx_cs = regs.x.es; + ipx_ip = regs.x.di; + + // grab a chunk of memory down in DOS land + lowmem_buffer = dos_getmemory(LOWMEMSIZE); + if (!lowmem_buffer) + { + Con_Printf("IPX_Init: Not enough low memory\n"); + return -1; + } + lowmem_bufoff = ptr2real(lowmem_buffer) & 0xf; + lowmem_bufseg = ptr2real(lowmem_buffer) >> 4; + + // init socket handles & buffers + handlesInUse = 0; + lma = (ipx_lowmem_area_t *)lowmem_buffer; + for (s = 0; s < IPXSOCKETS; s++) + { + ipxsocket[s] = 0; + for (n = 0; n < IPXSOCKBUFFERS; n++) + { + lma->socketbuffer[s][n].ecb.link = NULL; + lma->socketbuffer[s][n].ecb.ESR_off = 0; + lma->socketbuffer[s][n].ecb.ESR_seg = 0; + lma->socketbuffer[s][n].ecb.socket = 0; + lma->socketbuffer[s][n].ecb.inUse = 0xff; + lma->socketbuffer[s][n].ecb.completionCode = 0; + lma->socketbuffer[s][n].ecb.fragCount = 1; + lma->socketbuffer[s][n].ecb.fragOff = ptr2real(&lma->socketbuffer[s][n].header) & 0xf; + lma->socketbuffer[s][n].ecb.fragSeg = ptr2real(&lma->socketbuffer[s][n].header) >> 4; + lma->socketbuffer[s][n].ecb.fragSize = sizeof(IPXheader) + sizeof(int) + NET_DATAGRAMSIZE; + } + } + + if ((net_controlsocket = IPX_OpenSocket (0)) == -1) + { + dos_freememory(lowmem_buffer); + Con_DPrintf ("IPX_Init: Unable to open control socket\n"); + return -1; + } + + SchedulePollProcedure(&pollProcedure, 0.01); + + IPX_GetSocketAddr (net_controlsocket, &addr); + Q_strcpy(my_ipx_address, IPX_AddrToString (&addr)); + colon = Q_strrchr (my_ipx_address, ':'); + if (colon) + *colon = 0; + + Con_Printf("IPX initialized\n"); + ipxAvailable = true; + return net_controlsocket; +} + +//============================================================================= + +void IPX_Shutdown(void) +{ + IPX_Listen (false); + IPX_CloseSocket (net_controlsocket); + dos_freememory(lowmem_buffer); +} + +//============================================================================= + +void IPX_Listen (qboolean state) +{ + // enable listening + if (state) + { + if (net_acceptsocket != -1) + return; + if ((net_acceptsocket = IPX_OpenSocket (net_hostport)) == -1) + Sys_Error ("IPX_Listen: Unable to open accept socket\n"); + return; + } + + // disable listening + if (net_acceptsocket == -1) + return; + IPX_CloseSocket (net_acceptsocket); + net_acceptsocket = -1; +} + +//============================================================================= + +int IPX_OpenSocket(int port) +{ + int handle; + int n; + unsigned short socket; + + if (handlesInUse == IPXSOCKETS) + return -1; + + // open the IPX socket + regs.x.cs = ipx_cs; + regs.x.ip = ipx_ip; + regs.x.bx = IPX_OPEN; + regs.h.al = 0; + regs.x.dx = htons(port); + __dpmi_simulate_real_mode_procedure_retf((__dpmi_regs *)®s); + if (regs.h.al == 0xfe) + { + Con_DPrintf("IPX_OpenSocket: all sockets in use\n"); + return -1; + } + if (regs.h.al == 0xff) + { + Con_DPrintf("IPX_OpenSocket: socket already open\n"); + return -1; + } + if (regs.h.al != 0) + { + Con_DPrintf("IPX_OpenSocket: error %02x\n", regs.h.al); + return -1; + } + socket = regs.x.dx; + +// grab a handle; fill in the ECBs, and get them listening + for (handle = 0; handle < IPXSOCKETS; handle++) + { + if (ipxsocket[handle] == 0) + { + ipxsocket[handle] = socket; + readlist[handle] = NULL; + sequence[handle] = 0; + for (n = 0; n < IPXSOCKBUFFERS; n ++) + { + lma->socketbuffer[handle][n].ecb.socket = socket; + lma->socketbuffer[handle][n].ecb.inUse = 0; + if (n) + IPX_ListenForPacket(&lma->socketbuffer[handle][n].ecb); + } + handlesInUse++; + return handle; + } + } + + // "this will NEVER happen" + Sys_Error("IPX_OpenSocket: handle allocation failed\n"); + return -1; +} + +//============================================================================= + +int IPX_CloseSocket(int handle) +{ + // if there's a send in progress, give it one last chance + if (lma->socketbuffer[handle][0].ecb.inUse != 0) + IPX_RelinquishControl(); + + // close the socket (all pending sends/received are cancelled) + regs.x.cs = ipx_cs; + regs.x.ip = ipx_ip; + regs.x.bx = IPX_CLOSE; + regs.x.dx = ipxsocket[handle]; + __dpmi_simulate_real_mode_procedure_retf((__dpmi_regs *)®s); + + ipxsocket[handle] = 0; + handlesInUse--; + + return 0; +} + +//============================================================================= + +int IPX_Connect (int handle, struct qsockaddr *addr) +{ + IPXaddr ipxaddr; + + Q_memcpy(&ipxaddr, &((struct sockaddr_ipx *)addr)->sipx_addr, sizeof(IPXaddr)); + if (IPX_GetLocalTarget(&ipxaddr, lma->socketbuffer[handle][0].ecb.immediateAddress) != 0) + { + Con_Printf("Get Local Target failed\n"); + return -1; + } + + return 0; +} + +//============================================================================= + +int IPX_CheckNewConnections (void) +{ + int n; + + if (net_acceptsocket == -1) + return -1; + + for (n = 1; n < IPXSOCKBUFFERS; n ++) + if (lma->socketbuffer[net_acceptsocket][n].ecb.inUse == 0) + return net_acceptsocket; + return -1; +} + +//============================================================================= + +int IPX_Read (int handle, byte *buf, int len, struct qsockaddr *addr) +{ + ECB *ecb; + ipx_lowmem_buffer_t *rcvbuf; + int copylen; + + ProcessReadyList(handle); +tryagain: + if (readlist[handle] == NULL) + return 0; + ecb = readlist[handle]; + readlist[handle] = ecb->link; + + if (ecb->completionCode != 0) + { + Con_Printf("Warning: IPX_Read error %02x\n", ecb->completionCode); + ecb->fragSize = sizeof(IPXheader) + sizeof(int) + NET_DATAGRAMSIZE; + IPX_ListenForPacket(ecb); + goto tryagain; + } + + rcvbuf = (ipx_lowmem_buffer_t *)ecb; + + // copy the data up to the buffer + copylen = ntohs(rcvbuf->header.length) - (sizeof(int) + sizeof(IPXheader)); + if (len < copylen) + Sys_Error("IPX_Read: buffer too small (%d vs %d)\n", len, copylen); + Q_memcpy(buf, rcvbuf->data, copylen); + + // fill in the addr if they want it + if (addr) + { + ((struct sockaddr_ipx *)addr)->sipx_family = AF_NETWARE; + Q_memcpy(&((struct sockaddr_ipx *)addr)->sipx_addr, rcvbuf->header.source.network, sizeof(IPXaddr)); + ((struct sockaddr_ipx *)addr)->sipx_zero[0] = 0; + ((struct sockaddr_ipx *)addr)->sipx_zero[1] = 0; + } + + // update the send ecb's immediate address + Q_memcpy(lma->socketbuffer[handle][0].ecb.immediateAddress, rcvbuf->ecb.immediateAddress, 6); + + // get this ecb listening again + rcvbuf->ecb.fragSize = sizeof(IPXheader) + sizeof(int) + NET_DATAGRAMSIZE; + IPX_ListenForPacket(&rcvbuf->ecb); + return copylen; +} + +//============================================================================= + +int IPX_Broadcast (int handle, byte *buf, int len) +{ + struct sockaddr_ipx addr; + int ret; + + Q_memset(addr.sipx_addr.network, 0x00, 4); + Q_memset(addr.sipx_addr.node, 0xff, 6); + addr.sipx_port = htons(net_hostport); + Q_memset(lma->socketbuffer[handle][0].ecb.immediateAddress, 0xff, 6); + ret = IPX_Write (handle, buf, len, (struct qsockaddr *)&addr); + return ret; +} + +//============================================================================= + +int IPX_Write (int handle, byte *buf, int len, struct qsockaddr *addr) +{ + // has the previous send completed? + while (lma->socketbuffer[handle][0].ecb.inUse != 0) + IPX_RelinquishControl(); + + switch (lma->socketbuffer[handle][0].ecb.completionCode) + { + case 0x00: // success + case 0xfc: // request cancelled + break; + + case 0xfd: // malformed packet + default: + Con_Printf("IPX driver send failure: %02x\n", lma->socketbuffer[handle][0].ecb.completionCode); + break; + + case 0xfe: // packet undeliverable + case 0xff: // unable to send packet + Con_Printf("IPX lost route, trying to re-establish\n"); + + // look for a new route + if (IPX_GetLocalTarget (&lma->socketbuffer[handle][0].header.destination, lma->socketbuffer[handle][0].ecb.immediateAddress) != 0) + return -1; + + // re-send the one that failed + regs.x.cs = ipx_cs; + regs.x.ip = ipx_ip; + regs.x.bx = IPX_SEND; + regs.x.es = ptr2real(&lma->socketbuffer[handle][0].ecb) >> 4; + regs.x.si = ptr2real(&lma->socketbuffer[handle][0].ecb) & 0xf; + __dpmi_simulate_real_mode_procedure_retf((__dpmi_regs *)®s); + + // report that we did not send the current one + return 0; + } + + // ecb : length + lma->socketbuffer[handle][0].ecb.fragSize = sizeof(IPXheader) + sizeof(int) + len; + + // ipx header : type + lma->socketbuffer[handle][0].header.type = PTYPE_IPX; + + // ipx header : destination + Q_memcpy(&lma->socketbuffer[handle][0].header.destination, &((struct sockaddr_ipx *)addr)->sipx_addr, sizeof(IPXaddr)); + + // sequence number + lma->socketbuffer[handle][0].sequence = sequence[handle]; + sequence[handle]++; + + // copy down the data + Q_memcpy(lma->socketbuffer[handle][0].data, buf, len); + + regs.x.cs = ipx_cs; + regs.x.ip = ipx_ip; + regs.x.bx = IPX_SEND; + regs.x.es = ptr2real(&lma->socketbuffer[handle][0].ecb) >> 4; + regs.x.si = ptr2real(&lma->socketbuffer[handle][0].ecb) & 0xf; + __dpmi_simulate_real_mode_procedure_retf((__dpmi_regs *)®s); + + return len; +} + +//============================================================================= + +char *IPX_AddrToString (struct qsockaddr *addr) +{ + static char buf[28]; + + sprintf(buf, "%02x%02x%02x%02x:%02x%02x%02x%02x%02x%02x:%u", + ((struct sockaddr_ipx *)addr)->sipx_addr.network[0], + ((struct sockaddr_ipx *)addr)->sipx_addr.network[1], + ((struct sockaddr_ipx *)addr)->sipx_addr.network[2], + ((struct sockaddr_ipx *)addr)->sipx_addr.network[3], + ((struct sockaddr_ipx *)addr)->sipx_addr.node[0], + ((struct sockaddr_ipx *)addr)->sipx_addr.node[1], + ((struct sockaddr_ipx *)addr)->sipx_addr.node[2], + ((struct sockaddr_ipx *)addr)->sipx_addr.node[3], + ((struct sockaddr_ipx *)addr)->sipx_addr.node[4], + ((struct sockaddr_ipx *)addr)->sipx_addr.node[5], + ntohs(((struct sockaddr_ipx *)addr)->sipx_port) + ); + return buf; +} + +//============================================================================= + +int IPX_StringToAddr (char *string, struct qsockaddr *addr) +{ + int val; + char buf[3]; + + buf[2] = 0; + Q_memset(addr, 0, sizeof(struct qsockaddr)); + addr->sa_family = AF_NETWARE; + +#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)->sipx_addr.dest = val + + DO(0, network[0]); + DO(2, network[1]); + DO(4, network[2]); + DO(6, network[3]); + DO(9, node[0]); + DO(11, node[1]); + DO(13, node[2]); + DO(15, node[3]); + DO(17, node[4]); + DO(19, node[5]); +#undef DO + + sscanf (&string[22], "%u", &val); + ((struct sockaddr_ipx *)addr)->sipx_port = htons(val); + + return 0; +} + +//============================================================================= + +int IPX_GetSocketAddr (int handle, struct qsockaddr *addr) +{ + Q_memset(addr, 0, sizeof(struct qsockaddr)); + addr->sa_family = AF_NETWARE; + IPX_GetLocalAddress(&((struct sockaddr_ipx *)addr)->sipx_addr); + ((struct sockaddr_ipx *)addr)->sipx_port = ipxsocket[handle]; + return 0; +} + +//============================================================================= + +int IPX_GetNameFromAddr (struct qsockaddr *addr, char *name) +{ + Q_strcpy(name, IPX_AddrToString(addr)); + return 0; +} + +//============================================================================= + +int IPX_GetAddrFromName (char *name, struct qsockaddr *addr) +{ + int n; + char buf[32]; + + n = Q_strlen(name); + + if (n == 12) + { + sprintf(buf, "00000000:%s:%u", name, net_hostport); + return IPX_StringToAddr (buf, addr); + } + if (n == 21) + { + sprintf(buf, "%s:%u", name, net_hostport); + return IPX_StringToAddr (buf, addr); + } + if (n > 21 && n <= 27) + return IPX_StringToAddr (name, addr); + + return -1; +} + +//============================================================================= + +int IPX_AddrCompare (struct qsockaddr *addr1, struct qsockaddr *addr2) +{ + if (addr1->sa_family != addr2->sa_family) + return -1; + + if(Q_memcmp(&((struct sockaddr_ipx *)addr1)->sipx_addr, &((struct sockaddr_ipx *)addr2)->sipx_addr, 10)) + return -1; + + if (((struct sockaddr_ipx *)addr1)->sipx_port != ((struct sockaddr_ipx *)addr2)->sipx_port) + return 1; + + return 0; +} + +//============================================================================= + +int IPX_GetSocketPort (struct qsockaddr *addr) +{ + return ntohs(((struct sockaddr_ipx *)addr)->sipx_port); +} + + +int IPX_SetSocketPort (struct qsockaddr *addr, int port) +{ + ((struct sockaddr_ipx *)addr)->sipx_port = htons(port); + return 0; +} + +//============================================================================= diff --git a/contrib/other/sdlquake-1.0.9/net_ipx.h b/contrib/other/sdlquake-1.0.9/net_ipx.h new file mode 100644 index 000000000..464fec4f6 --- /dev/null +++ b/contrib/other/sdlquake-1.0.9/net_ipx.h @@ -0,0 +1,39 @@ +/* +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_ipx.h + +int IPX_Init (void); +void IPX_Shutdown (void); +void IPX_Listen (qboolean state); +int IPX_OpenSocket (int port); +int IPX_CloseSocket (int socket); +int IPX_Connect (int socket, struct qsockaddr *addr); +int IPX_CheckNewConnections (void); +int IPX_Read (int socket, byte *buf, int len, struct qsockaddr *addr); +int IPX_Write (int socket, byte *buf, int len, struct qsockaddr *addr); +int IPX_Broadcast (int socket, byte *buf, int len); +char *IPX_AddrToString (struct qsockaddr *addr); +int IPX_StringToAddr (char *string, struct qsockaddr *addr); +int IPX_GetSocketAddr (int socket, struct qsockaddr *addr); +int IPX_GetNameFromAddr (struct qsockaddr *addr, char *name); +int IPX_GetAddrFromName (char *name, struct qsockaddr *addr); +int IPX_AddrCompare (struct qsockaddr *addr1, struct qsockaddr *addr2); +int IPX_GetSocketPort (struct qsockaddr *addr); +int IPX_SetSocketPort (struct qsockaddr *addr, int port); diff --git a/contrib/other/sdlquake-1.0.9/net_loop.c b/contrib/other/sdlquake-1.0.9/net_loop.c new file mode 100644 index 000000000..35aa370d9 --- /dev/null +++ b/contrib/other/sdlquake-1.0.9/net_loop.c @@ -0,0 +1,245 @@ +/* +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_loop.c + +#include "quakedef.h" +#include "net_loop.h" + +qboolean localconnectpending = false; +qsocket_t *loop_client = NULL; +qsocket_t *loop_server = NULL; + +int Loop_Init (void) +{ + if (cls.state == ca_dedicated) + return -1; + return 0; +} + + +void Loop_Shutdown (void) +{ +} + + +void Loop_Listen (qboolean state) +{ +} + + +void Loop_SearchForHosts (qboolean xmit) +{ + if (!sv.active) + return; + + hostCacheCount = 1; + if (Q_strcmp(hostname.string, "UNNAMED") == 0) + Q_strcpy(hostcache[0].name, "local"); + else + Q_strcpy(hostcache[0].name, hostname.string); + Q_strcpy(hostcache[0].map, sv.name); + hostcache[0].users = net_activeconnections; + hostcache[0].maxusers = svs.maxclients; + hostcache[0].driver = net_driverlevel; + Q_strcpy(hostcache[0].cname, "local"); +} + + +qsocket_t *Loop_Connect (char *host) +{ + if (Q_strcmp(host,"local") != 0) + return NULL; + + localconnectpending = true; + + if (!loop_client) + { + if ((loop_client = NET_NewQSocket ()) == NULL) + { + Con_Printf("Loop_Connect: no qsocket available\n"); + return NULL; + } + Q_strcpy (loop_client->address, "localhost"); + } + loop_client->receiveMessageLength = 0; + loop_client->sendMessageLength = 0; + loop_client->canSend = true; + + if (!loop_server) + { + if ((loop_server = NET_NewQSocket ()) == NULL) + { + Con_Printf("Loop_Connect: no qsocket available\n"); + return NULL; + } + Q_strcpy (loop_server->address, "LOCAL"); + } + loop_server->receiveMessageLength = 0; + loop_server->sendMessageLength = 0; + loop_server->canSend = true; + + loop_client->driverdata = (void *)loop_server; + loop_server->driverdata = (void *)loop_client; + + return loop_client; +} + + +qsocket_t *Loop_CheckNewConnections (void) +{ + if (!localconnectpending) + return NULL; + + localconnectpending = false; + loop_server->sendMessageLength = 0; + loop_server->receiveMessageLength = 0; + loop_server->canSend = true; + loop_client->sendMessageLength = 0; + loop_client->receiveMessageLength = 0; + loop_client->canSend = true; + return loop_server; +} + + +static int IntAlign(int value) +{ + return (value + (sizeof(int) - 1)) & (~(sizeof(int) - 1)); +} + + +int Loop_GetMessage (qsocket_t *sock) +{ + int ret; + int length; + + if (sock->receiveMessageLength == 0) + return 0; + + ret = sock->receiveMessage[0]; + length = sock->receiveMessage[1] + (sock->receiveMessage[2] << 8); + // alignment byte skipped here + SZ_Clear (&net_message); + SZ_Write (&net_message, &sock->receiveMessage[4], length); + + length = IntAlign(length + 4); + sock->receiveMessageLength -= length; + + if (sock->receiveMessageLength) + Q_memcpy(sock->receiveMessage, &sock->receiveMessage[length], sock->receiveMessageLength); + + if (sock->driverdata && ret == 1) + ((qsocket_t *)sock->driverdata)->canSend = true; + + return ret; +} + + +int Loop_SendMessage (qsocket_t *sock, sizebuf_t *data) +{ + byte *buffer; + int *bufferLength; + + if (!sock->driverdata) + return -1; + + bufferLength = &((qsocket_t *)sock->driverdata)->receiveMessageLength; + + if ((*bufferLength + data->cursize + 4) > NET_MAXMESSAGE) + Sys_Error("Loop_SendMessage: overflow\n"); + + buffer = ((qsocket_t *)sock->driverdata)->receiveMessage + *bufferLength; + + // message type + *buffer++ = 1; + + // length + *buffer++ = data->cursize & 0xff; + *buffer++ = data->cursize >> 8; + + // align + buffer++; + + // message + Q_memcpy(buffer, data->data, data->cursize); + *bufferLength = IntAlign(*bufferLength + data->cursize + 4); + + sock->canSend = false; + return 1; +} + + +int Loop_SendUnreliableMessage (qsocket_t *sock, sizebuf_t *data) +{ + byte *buffer; + int *bufferLength; + + if (!sock->driverdata) + return -1; + + bufferLength = &((qsocket_t *)sock->driverdata)->receiveMessageLength; + + if ((*bufferLength + data->cursize + sizeof(byte) + sizeof(short)) > NET_MAXMESSAGE) + return 0; + + buffer = ((qsocket_t *)sock->driverdata)->receiveMessage + *bufferLength; + + // message type + *buffer++ = 2; + + // length + *buffer++ = data->cursize & 0xff; + *buffer++ = data->cursize >> 8; + + // align + buffer++; + + // message + Q_memcpy(buffer, data->data, data->cursize); + *bufferLength = IntAlign(*bufferLength + data->cursize + 4); + return 1; +} + + +qboolean Loop_CanSendMessage (qsocket_t *sock) +{ + if (!sock->driverdata) + return false; + return sock->canSend; +} + + +qboolean Loop_CanSendUnreliableMessage (qsocket_t *sock) +{ + return true; +} + + +void Loop_Close (qsocket_t *sock) +{ + if (sock->driverdata) + ((qsocket_t *)sock->driverdata)->driverdata = NULL; + sock->receiveMessageLength = 0; + sock->sendMessageLength = 0; + sock->canSend = true; + if (sock == loop_client) + loop_client = NULL; + else + loop_server = NULL; +} diff --git a/contrib/other/sdlquake-1.0.9/net_loop.h b/contrib/other/sdlquake-1.0.9/net_loop.h new file mode 100644 index 000000000..90cdb2c50 --- /dev/null +++ b/contrib/other/sdlquake-1.0.9/net_loop.h @@ -0,0 +1,33 @@ +/* +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_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); +qboolean Loop_CanSendMessage (qsocket_t *sock); +qboolean Loop_CanSendUnreliableMessage (qsocket_t *sock); +void Loop_Close (qsocket_t *sock); +void Loop_Shutdown (void); diff --git a/contrib/other/sdlquake-1.0.9/net_main.c b/contrib/other/sdlquake-1.0.9/net_main.c new file mode 100644 index 000000000..5f5d2cf1a --- /dev/null +++ b/contrib/other/sdlquake-1.0.9/net_main.c @@ -0,0 +1,997 @@ +/* +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_main.c + +#include "quakedef.h" +#include "net_vcr.h" + +qsocket_t *net_activeSockets = NULL; +qsocket_t *net_freeSockets = NULL; +int net_numsockets = 0; + +qboolean serialAvailable = false; +qboolean ipxAvailable = false; +qboolean tcpipAvailable = false; + +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; +qboolean slistSilent = false; +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; + +cvar_t net_messagetimeout = {"net_messagetimeout","300"}; +cvar_t hostname = {"hostname", "UNNAMED"}; + +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}; + +#ifdef IDGODS +cvar_t idgods = {"idgods", "0"}; +#endif + +int vcrFile = -1; +qboolean recording = false; + +// 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; + + +double net_time; + +double SetNetTime(void) +{ + net_time = Sys_FloatTime(); + return net_time; +} + + +/* +=================== +NET_NewQSocket + +Called by drivers when a new communications endpoint is required +The sequence and buffer fields will be filled in properly +=================== +*/ +qsocket_t *NET_NewQSocket (void) +{ + qsocket_t *sock; + + if (net_freeSockets == NULL) + return NULL; + + if (net_activeconnections >= svs.maxclients) + return NULL; + + // get one from free list + sock = net_freeSockets; + net_freeSockets = sock->next; + + // add it to active list + sock->next = net_activeSockets; + net_activeSockets = sock; + + sock->disconnected = false; + sock->connecttime = net_time; + Q_strcpy (sock->address,"UNSET ADDRESS"); + sock->driver = net_driverlevel; + sock->socket = 0; + sock->driverdata = NULL; + sock->canSend = true; + sock->sendNext = false; + sock->lastMessageTime = net_time; + sock->ackSequence = 0; + sock->sendSequence = 0; + sock->unreliableSendSequence = 0; + sock->sendMessageLength = 0; + sock->receiveSequence = 0; + sock->unreliableReceiveSequence = 0; + sock->receiveMessageLength = 0; + + return sock; +} + + +void NET_FreeQSocket(qsocket_t *sock) +{ + qsocket_t *s; + + // remove it from active list + if (sock == net_activeSockets) + net_activeSockets = net_activeSockets->next; + 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"); + } + + // add it to free list + sock->next = net_freeSockets; + net_freeSockets = sock; + sock->disconnected = true; +} + + +static void NET_Listen_f (void) +{ + if (Cmd_Argc () != 2) + { + Con_Printf ("\"listen\" is \"%u\"\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); + } + + if ((n == 1) && listening) + Cbuf_AddText ("listen 0\n"); + + if ((n > 1) && (!listening)) + Cbuf_AddText ("listen 1\n"); + + svs.maxclients = n; + if (n == 1) + Cvar_Set ("deathmatch", "0"); + else + Cvar_Set ("deathmatch", "1"); +} + + +static void NET_Port_f (void) +{ + int n; + + if (Cmd_Argc () != 2) + { + Con_Printf ("\"port\" is \"%u\"\n", net_hostport); + return; + } + + n = Q_atoi(Cmd_Argv(1)); + if (n < 1 || n > 65534) + { + Con_Printf ("Bad value, must be between 1 and 65534\n"); + return; + } + + DEFAULTnet_hostport = n; + net_hostport = n; + + if (listening) + { + // force a change to the new port + Cbuf_AddText ("listen 0\n"); + Cbuf_AddText ("listen 1\n"); + } +} + + +static void PrintSlistHeader(void) +{ + Con_Printf("Server Map Users\n"); + Con_Printf("--------------- --------------- -----\n"); + slistLastShown = 0; +} + + +static void PrintSlist(void) +{ + int n; + + for (n = slistLastShown; n < hostCacheCount; n++) + { + if (hostcache[n].maxusers) + Con_Printf("%-15.15s %-15.15s %2u/%2u\n", hostcache[n].name, hostcache[n].map, hostcache[n].users, hostcache[n].maxusers); + else + Con_Printf("%-15.15s %-15.15s\n", hostcache[n].name, hostcache[n].map); + } + slistLastShown = n; +} + + +static void PrintSlistTrailer(void) +{ + if (hostCacheCount) + Con_Printf("== end list ==\n\n"); + else + Con_Printf("No Quake servers found.\n\n"); +} + + +void NET_Slist_f (void) +{ + if (slistInProgress) + return; + + if (! slistSilent) + { + Con_Printf("Looking for Quake servers...\n"); + PrintSlistHeader(); + } + + slistInProgress = true; + slistStartTime = Sys_FloatTime(); + + SchedulePollProcedure(&slistSendProcedure, 0.0); + SchedulePollProcedure(&slistPollProcedure, 0.1); + + hostCacheCount = 0; +} + + +static void Slist_Send(void) +{ + for (net_driverlevel=0; net_driverlevel < net_numdrivers; net_driverlevel++) + { + if (!slistLocal && net_driverlevel == 0) + continue; + if (net_drivers[net_driverlevel].initialized == false) + continue; + dfunc.SearchForHosts (true); + } + + if ((Sys_FloatTime() - slistStartTime) < 0.5) + SchedulePollProcedure(&slistSendProcedure, 0.75); +} + + +static void Slist_Poll(void) +{ + for (net_driverlevel=0; net_driverlevel < net_numdrivers; net_driverlevel++) + { + if (!slistLocal && net_driverlevel == 0) + continue; + if (net_drivers[net_driverlevel].initialized == false) + continue; + dfunc.SearchForHosts (false); + } + + if (! slistSilent) + PrintSlist(); + + if ((Sys_FloatTime() - slistStartTime) < 1.5) + { + SchedulePollProcedure(&slistPollProcedure, 0.1); + return; + } + + if (! slistSilent) + PrintSlistTrailer(); + slistInProgress = false; + slistSilent = false; + slistLocal = true; +} + + +/* +=================== +NET_Connect +=================== +*/ + +int hostCacheCount = 0; +hostcache_t hostcache[HOSTCACHESIZE]; + +qsocket_t *NET_Connect (char *host) +{ + qsocket_t *ret; + int n; + int numdrivers = net_numdrivers; + + SetNetTime(); + + if (host && *host == 0) + host = NULL; + + if (host) + { + if (Q_strcasecmp (host, "local") == 0) + { + numdrivers = 1; + goto JustDoIt; + } + + if (hostCacheCount) + { + for (n = 0; n < hostCacheCount; n++) + if (Q_strcasecmp (host, hostcache[n].name) == 0) + { + host = hostcache[n].cname; + break; + } + if (n < hostCacheCount) + goto JustDoIt; + } + } + + slistSilent = host ? true : false; + NET_Slist_f (); + + while(slistInProgress) + NET_Poll(); + + if (host == NULL) + { + if (hostCacheCount != 1) + return NULL; + host = hostcache[0].cname; + Con_Printf("Connecting to...\n%s @ %s\n\n", hostcache[0].name, host); + } + + if (hostCacheCount) + for (n = 0; n < hostCacheCount; n++) + 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; +} + +/* +=================== +NET_Close +=================== +*/ +void NET_Close (qsocket_t *sock) +{ + if (!sock) + return; + + if (sock->disconnected) + return; + + SetNetTime(); + + // call the driver_Close function + sfunc.Close (sock); + + NET_FreeQSocket(sock); +} + + +/* +================= +NET_GetMessage + +If there is a complete message, return it in net_message + +returns 0 if no data is waiting +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; + + if (!sock) + return -1; + + if (sock->disconnected) + { + Con_Printf("NET_GetMessage: disconnected socket\n"); + return -1; + } + + SetNetTime(); + + ret = sfunc.QGetMessage(sock); + + // see if this connection has timed out + if (ret == 0 && sock->driver) + { + if (net_time - sock->lastMessageTime > net_messagetimeout.value) + { + NET_Close(sock); + return -1; + } + } + + + if (ret > 0) + { + if (sock->driver) + { + sock->lastMessageTime = net_time; + if (ret == 1) + messagesReceived++; + else if (ret == 2) + unreliableMessagesReceived++; + } + + if (recording) + { + vcrGetMessage.time = host_time; + vcrGetMessage.op = VCR_OP_GETMESSAGE; + vcrGetMessage.session = (long)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 = (long)sock; + vcrGetMessage.ret = ret; + Sys_FileWrite (vcrFile, &vcrGetMessage, 20); + } + } + + return ret; +} + + +/* +================== +NET_SendMessage + +Try to send a complete length+message unit over the reliable stream. +returns 0 if the message cannot be delivered reliably, but the connection + is still considered valid +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; + + if (sock->disconnected) + { + Con_Printf("NET_SendMessage: disconnected socket\n"); + return -1; + } + + SetNetTime(); + r = sfunc.QSendMessage(sock, data); + if (r == 1 && sock->driver) + messagesSent++; + + if (recording) + { + vcrSendMessage.time = host_time; + vcrSendMessage.op = VCR_OP_SENDMESSAGE; + vcrSendMessage.session = (long)sock; + vcrSendMessage.r = r; + Sys_FileWrite (vcrFile, &vcrSendMessage, 20); + } + + return r; +} + + +int NET_SendUnreliableMessage (qsocket_t *sock, sizebuf_t *data) +{ + int r; + + if (!sock) + return -1; + + if (sock->disconnected) + { + Con_Printf("NET_SendMessage: disconnected socket\n"); + return -1; + } + + SetNetTime(); + r = sfunc.SendUnreliableMessage(sock, data); + if (r == 1 && sock->driver) + unreliableMessagesSent++; + + if (recording) + { + vcrSendMessage.time = host_time; + vcrSendMessage.op = VCR_OP_SENDMESSAGE; + vcrSendMessage.session = (long)sock; + vcrSendMessage.r = r; + Sys_FileWrite (vcrFile, &vcrSendMessage, 20); + } + + return r; +} + + +/* +================== +NET_CanSendMessage + +Returns true or false if the given qsocket can currently accept a +message to be transmitted. +================== +*/ +qboolean NET_CanSendMessage (qsocket_t *sock) +{ + int r; + + if (!sock) + return false; + + if (sock->disconnected) + return false; + + SetNetTime(); + + r = sfunc.CanSendMessage(sock); + + if (recording) + { + vcrSendMessage.time = host_time; + vcrSendMessage.op = VCR_OP_CANSENDMESSAGE; + vcrSendMessage.session = (long)sock; + vcrSendMessage.r = r; + Sys_FileWrite (vcrFile, &vcrSendMessage, 20); + } + + return r; +} + + +int NET_SendToAll(sizebuf_t *data, int blocktime) +{ + double start; + int i; + int count = 0; + qboolean state1 [MAX_SCOREBOARD]; + qboolean state2 [MAX_SCOREBOARD]; + + for (i=0, host_client = svs.clients ; inetconnection) + continue; + if (host_client->active) + { + if (host_client->netconnection->driver == 0) + { + NET_SendMessage(host_client->netconnection, data); + state1[i] = true; + state2[i] = true; + continue; + } + count++; + state1[i] = false; + state2[i] = false; + } + else + { + state1[i] = true; + state2[i] = true; + } + } + + start = Sys_FloatTime(); + while (count) + { + count = 0; + for (i=0, host_client = svs.clients ; inetconnection)) + { + state1[i] = true; + NET_SendMessage(host_client->netconnection, data); + } + else + { + NET_GetMessage (host_client->netconnection); + } + count++; + continue; + } + + if (! state2[i]) + { + if (NET_CanSendMessage (host_client->netconnection)) + { + state2[i] = true; + } + else + { + NET_GetMessage (host_client->netconnection); + } + count++; + continue; + } + } + if ((Sys_FloatTime() - start) > blocktime) + break; + } + return count; +} + + +//============================================================================= + +/* +==================== +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"); + if (!i) + i = COM_CheckParm ("-ipxport"); + + if (i) + { + if (i < com_argc-1) + DEFAULTnet_hostport = Q_atoi (com_argv[i+1]); + else + Sys_Error ("NET_Init: you must specify a number after -port"); + } + 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++; + + SetNetTime(); + + for (i = 0; i < net_numsockets; i++) + { + s = (qsocket_t *)Hunk_AllocName(sizeof(qsocket_t), "qsocket"); + s->next = net_freeSockets; + net_freeSockets = s; + s->disconnected = true; + } + + // allocate space for network message buffer + SZ_Alloc (&net_message, NET_MAXMESSAGE); + + 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); + Cmd_AddCommand ("maxplayers", MaxPlayers_f); + Cmd_AddCommand ("port", NET_Port_f); + + // initialize all the drivers + for (net_driverlevel=0 ; net_driverlevelnext) + NET_Close(sock); + +// +// shutdown the drivers +// + for (net_driverlevel = 0; net_driverlevel < net_numdrivers; net_driverlevel++) + { + if (net_drivers[net_driverlevel].initialized == true) + { + net_drivers[net_driverlevel].Shutdown (); + net_drivers[net_driverlevel].initialized = false; + } + } + + if (vcrFile != -1) + { + Con_Printf ("Closing vcrfile.\n"); + Sys_FileClose(vcrFile); + } +} + + +static PollProcedure *pollProcedureList = NULL; + +void NET_Poll(void) +{ + PollProcedure *pp; + qboolean useModem; + + if (!configRestored) + { + if (serialAvailable) + { + if (config_com_modem.value == 1.0) + useModem = true; + else + useModem = false; + SetComPortConfig (0, (int)config_com_port.value, (int)config_com_irq.value, (int)config_com_baud.value, useModem); + SetModemConfig (0, config_modem_dialtype.string, config_modem_clear.string, config_modem_init.string, config_modem_hangup.string); + } + configRestored = true; + } + + SetNetTime(); + + for (pp = pollProcedureList; pp; pp = pp->next) + { + if (pp->nextTime > net_time) + break; + pollProcedureList = pp->next; + pp->procedure(pp->arg); + } +} + + +void SchedulePollProcedure(PollProcedure *proc, double timeOffset) +{ + PollProcedure *pp, *prev; + + proc->nextTime = Sys_FloatTime() + timeOffset; + for (pp = pollProcedureList, prev = NULL; pp; pp = pp->next) + { + if (pp->nextTime >= proc->nextTime) + break; + prev = pp; + } + + if (prev == NULL) + { + proc->next = pollProcedureList; + pollProcedureList = proc; + return; + } + + proc->next = pp; + 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/contrib/other/sdlquake-1.0.9/net_mp.c b/contrib/other/sdlquake-1.0.9/net_mp.c new file mode 100644 index 000000000..5d853a503 --- /dev/null +++ b/contrib/other/sdlquake-1.0.9/net_mp.c @@ -0,0 +1,443 @@ +/* +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_mpath.c + +#include +#include "quakedef.h" +#include "mpdosock.h" + +short flat_selector; + +int WSAGetLastError(void); +void sockets_flush(void); + +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 qboolean ifbcastinit = false; +static struct qsockaddr broadcastaddr; + +static unsigned long myAddr; + +#include "net_mp.h" + + +//============================================================================= + +int MPATH_Init (void) +{ + int i; + struct hostent *local = NULL; + char buff[MAXHOSTNAMELEN]; + struct qsockaddr addr; + char *p; + + if (COM_CheckParm ("-mpath") == 0) + return -1; + + flat_selector = __dpmi_allocate_ldt_descriptors(1); + if (flat_selector == -1) { + Con_Printf("MPATH_Init: Can't get flat selector\n"); + return -1; + } + if (__dpmi_set_segment_base_address(flat_selector, 0) == -1) { + Con_Printf("MPATH_Init: Can't seg flat base!\n"); + return -1; + } + if (__dpmi_set_segment_limit(flat_selector, 0xffffffff) == -1) { + Con_Printf("MPATH_Init: Can't set segment limit\n"); + return -1; + } + // determine my name & address + if (gethostname(buff, MAXHOSTNAMELEN) == 0) + local = gethostbyname(buff); + if (local) + { + myAddr = *(int *)local->h_addr_list[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); + } + } + + if ((net_controlsocket = MPATH_OpenSocket (0)) == -1) + Sys_Error("MPATH_Init: Unable to open control socket\n"); + + ((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(net_hostport); + + MPATH_GetSocketAddr (net_controlsocket, &addr); + Q_strcpy(my_tcpip_address, MPATH_AddrToString (&addr)); + p = Q_strrchr (my_tcpip_address, ':'); + if (p) + *p = 0; + + Con_Printf("MPath Initialized\n"); + tcpipAvailable = true; + + return net_controlsocket; +} + +//============================================================================= + +void MPATH_Shutdown (void) +{ + MPATH_Listen (false); + MPATH_CloseSocket (net_controlsocket); +} + +//============================================================================= + +void MPATH_Listen (qboolean state) +{ + // enable listening + if (state) + { + if (net_acceptsocket != -1) + return; + if ((net_acceptsocket = MPATH_OpenSocket (net_hostport)) == -1) + Sys_Error ("MPATH_Listen: Unable to open accept socket\n"); + return; + } + + // disable listening + if (net_acceptsocket == -1) + return; + MPATH_CloseSocket (net_acceptsocket); + net_acceptsocket = -1; +} + +//============================================================================= + +int MPATH_OpenSocket (int port) +{ + int newsocket; + struct sockaddr_in address; + u_long _true = 1; + + if ((newsocket = socket (PF_INET, SOCK_DGRAM, IPPROTO_UDP)) == -1) + return -1; + + if (ioctlsocket (newsocket, FIONBIO, &_true) == -1) + goto ErrorReturn; + + address.sin_family = AF_INET; + address.sin_addr.s_addr = INADDR_ANY; + address.sin_port = htons(port); + if( bind (newsocket, (void *)&address, sizeof(address)) == -1) + goto ErrorReturn; + + return newsocket; + +ErrorReturn: + closesocket (newsocket); + return -1; +} + +//============================================================================= + +int MPATH_CloseSocket (int socket) +{ + if (socket == net_broadcastsocket) + net_broadcastsocket = 0; + return closesocket (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 MPATH_Connect (int socket, struct qsockaddr *addr) +{ + return 0; +} + +//============================================================================= + +int MPATH_CheckNewConnections (void) +{ + char buf[4]; + + if (net_acceptsocket == -1) + return -1; + + if (recvfrom (net_acceptsocket, buf, 4, MSG_PEEK, NULL, NULL) > 0) + return net_acceptsocket; + return -1; +} + +//============================================================================= + +int MPATH_Read (int socket, byte *buf, int len, struct qsockaddr *addr) +{ + int addrlen = sizeof (struct qsockaddr); + int ret; + + ret = recvfrom (socket, buf, len, 0, (struct sockaddr *)addr, &addrlen); + if (ret == -1) + { + int errno = WSAGetLastError(); + + if (errno == WSAEWOULDBLOCK || errno == WSAECONNREFUSED) + return 0; + + } + return ret; +} + +//============================================================================= + +int MPATH_MakeSocketBroadcastCapable (int socket) +{ + int i = 1; + + // make this socket broadcast capable + if (setsockopt(socket, SOL_SOCKET, SO_BROADCAST, (char *)&i, sizeof(i)) < 0) + return -1; + net_broadcastsocket = socket; + + return 0; +} + +//============================================================================= + +int MPATH_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"); + ret = MPATH_MakeSocketBroadcastCapable (socket); + if (ret == -1) + { + Con_Printf("Unable to make socket broadcast capable\n"); + return ret; + } + } + + return MPATH_Write (socket, buf, len, &broadcastaddr); +} + +//============================================================================= + +int MPATH_Write (int socket, byte *buf, int len, struct qsockaddr *addr) +{ + int ret; + + ret = sendto (socket, buf, len, 0, (struct sockaddr *)addr, sizeof(struct qsockaddr)); + if (ret == -1) + if (WSAGetLastError() == WSAEWOULDBLOCK) + return 0; + + sockets_flush(); + + return ret; +} + +//============================================================================= + +char *MPATH_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 MPATH_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(hp); + return 0; +} + +//============================================================================= + +int MPATH_GetSocketAddr (int socket, struct qsockaddr *addr) +{ + int addrlen = sizeof(struct qsockaddr); + unsigned int a; + + Q_memset(addr, 0, sizeof(struct qsockaddr)); + getsockname(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 MPATH_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, MPATH_AddrToString (addr)); + return 0; +} + +//============================================================================= + +int MPATH_GetAddrFromName(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->sa_family = AF_INET; + ((struct sockaddr_in *)addr)->sin_port = htons(net_hostport); + ((struct sockaddr_in *)addr)->sin_addr.s_addr = *(int *)hostentry->h_addr_list[0]; + + return 0; +} + +//============================================================================= + +int MPATH_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 MPATH_GetSocketPort (struct qsockaddr *addr) +{ + return ntohs(((struct sockaddr_in *)addr)->sin_port); +} + + +int MPATH_SetSocketPort (struct qsockaddr *addr, int port) +{ + ((struct sockaddr_in *)addr)->sin_port = htons(port); + return 0; +} + +//============================================================================= diff --git a/contrib/other/sdlquake-1.0.9/net_mp.h b/contrib/other/sdlquake-1.0.9/net_mp.h new file mode 100644 index 000000000..13e1675b7 --- /dev/null +++ b/contrib/other/sdlquake-1.0.9/net_mp.h @@ -0,0 +1,39 @@ +/* +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_mpath.h + +int MPATH_Init (void); +void MPATH_Shutdown (void); +void MPATH_Listen (qboolean state); +int MPATH_OpenSocket (int port); +int MPATH_CloseSocket (int socket); +int MPATH_Connect (int socket, struct qsockaddr *addr); +int MPATH_CheckNewConnections (void); +int MPATH_Read (int socket, byte *buf, int len, struct qsockaddr *addr); +int MPATH_Write (int socket, byte *buf, int len, struct qsockaddr *addr); +int MPATH_Broadcast (int socket, byte *buf, int len); +char *MPATH_AddrToString (struct qsockaddr *addr); +int MPATH_StringToAddr (char *string, struct qsockaddr *addr); +int MPATH_GetSocketAddr (int socket, struct qsockaddr *addr); +int MPATH_GetNameFromAddr (struct qsockaddr *addr, char *name); +int MPATH_GetAddrFromName (char *name, struct qsockaddr *addr); +int MPATH_AddrCompare (struct qsockaddr *addr1, struct qsockaddr *addr2); +int MPATH_GetSocketPort (struct qsockaddr *addr); +int MPATH_SetSocketPort (struct qsockaddr *addr, int port); diff --git a/contrib/other/sdlquake-1.0.9/net_none.c b/contrib/other/sdlquake-1.0.9/net_none.c new file mode 100644 index 000000000..c00c97505 --- /dev/null +++ b/contrib/other/sdlquake-1.0.9/net_none.c @@ -0,0 +1,46 @@ +/* +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" + +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 + } +}; +int net_numdrivers = 1; + +net_landriver_t net_landrivers[MAX_NET_DRIVERS]; +int net_numlandrivers = 0; diff --git a/contrib/other/sdlquake-1.0.9/net_ser.c b/contrib/other/sdlquake-1.0.9/net_ser.c new file mode 100644 index 000000000..f582f54c0 --- /dev/null +++ b/contrib/other/sdlquake-1.0.9/net_ser.c @@ -0,0 +1,951 @@ +/* +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_ser.c + +#include "quakedef.h" +#include "net_ser.h" +#include "dosisms.h" +#include "crc.h" + +#include "net_comx.c" + +// serial protocol + +#define SERIAL_PROTOCOL_VERSION 3 + +// The serial protocol is message oriented. The high level message format is +// a one byte message type (MTYPE_xxx), data, and a 16-bit checksum. All +// multi-byte fields are sent in network byte order. There are currently 4 +// MTYPEs defined. Their formats are as follows: +// +// MTYPE_RELIABLE sequence data_length data checksum eom +// MTYPE_UNRELIABLE sequence data_length data checksum eom +// MTYPE_ACK sequence checksum eom +// MTYPE_CONTROL data_length data checksum eom +// +// sequence is an 8-bit unsigned value starting from 0 +// data_length is a 16-bit unsigned value; it is the length of the data only +// the checksum is a 16-bit value. the CRC formula used is defined in crc.h. +// the checksum covers the entire messages, excluding itself +// eom is a special 2 byte sequence used to mark the End Of Message. This is +// needed for error recovery. +// +// A lot of behavior is based on knowledge of the upper level Quake network +// layer. For example, only one reliable message can be outstanding (pending +// reception of an MTYPE_ACK) at a time. +// +// The low level routines used to communicate with the modem are not part of +// this protocol. +// +// The CONTROL messages are only used for session establishment. They are +// not reliable or sequenced. + +#define MTYPE_RELIABLE 0x01 +#define MTYPE_UNRELIABLE 0x02 +#define MTYPE_CONTROL 0x03 +#define MTYPE_ACK 0x04 +#define MTYPE_CLIENT 0x80 + +#define ESCAPE_COMMAND 0xe0 +#define ESCAPE_EOM 0x19 + +static qboolean listening = false; + + +typedef struct SerialLine_s +{ + struct SerialLine_s *next; + qsocket_t *sock; + int lengthStated; + int lengthFound; + int tty; + qboolean connected; + qboolean connecting; + qboolean client; + double connect_time; + unsigned short crcStated; + unsigned short crcValue; + byte currState; + byte prevState; + byte mtype; + byte sequence; +} SerialLine; + +#define STATE_READY 0 +#define STATE_SEQUENCE 1 +#define STATE_LENGTH1 2 +#define STATE_LENGTH2 3 +#define STATE_DATA 4 +#define STATE_CRC1 5 +#define STATE_CRC2 6 +#define STATE_EOM 7 +#define STATE_ESCAPE 8 +#define STATE_ABORT 9 + +SerialLine serialLine[NUM_COM_PORTS]; + +int myDriverLevel; + +static void Serial_SendACK (SerialLine *p, byte sequence); + + +static void ResetSerialLineProtocol (SerialLine *p) +{ + p->connected = false; + p->connecting = false; + p->currState = STATE_READY; + p->prevState = STATE_READY; + p->lengthFound = 0; +} + + +static int ProcessInQueue(SerialLine *p) +{ + int b; + + while (1) + { + b = TTY_ReadByte(p->tty); + if (b == ERR_TTY_NODATA) + break; + + if (b == ERR_TTY_LINE_STATUS) + { + p->currState = STATE_ABORT; + continue; + } + if (b == ERR_TTY_MODEM_STATUS) + { + p->currState = STATE_ABORT; + return -1; + } + + if (b == ESCAPE_COMMAND) + if (p->currState != STATE_ESCAPE) + { + p->prevState = p->currState; + p->currState = STATE_ESCAPE; + continue; + } + + if (p->currState == STATE_ESCAPE) + { + if (b == ESCAPE_EOM) + { + if (p->prevState == STATE_ABORT) + { + p->currState = STATE_READY; + p->lengthFound = 0; + continue; + } + + if (p->prevState != STATE_EOM) + { + p->currState = STATE_READY; + p->lengthFound = 0; + Con_DPrintf("Serial: premature EOM\n"); + continue; + } + + switch (p->mtype) + { + case MTYPE_RELIABLE: + Con_DPrintf("Serial: sending ack %u\n", p->sequence); + Serial_SendACK (p, p->sequence); + if (p->sequence == p->sock->receiveSequence) + { + p->sock->receiveSequence = (p->sequence + 1) & 0xff; + p->sock->receiveMessageLength += p->lengthFound; + } + else + Con_DPrintf("Serial: reliable out of order; got %u wanted %u\n", p->sequence, p->sock->receiveSequence); + break; + + case MTYPE_UNRELIABLE: + p->sock->unreliableReceiveSequence = (p->sequence + 1) & 0xff; + p->sock->receiveMessageLength += p->lengthFound; + break; + + case MTYPE_ACK: + Con_DPrintf("Serial: got ack %u\n", p->sequence); + if (p->sequence == p->sock->sendSequence) + { + p->sock->sendSequence = (p->sock->sendSequence + 1) & 0xff; + p->sock->canSend = true; + } + else + Con_DPrintf("Serial: ack out of order; got %u wanted %u\n",p->sequence, p->sock->sendSequence); + break; + + case MTYPE_CONTROL: + p->sock->receiveMessageLength += p->lengthFound; + break; + } + + p->currState = STATE_READY; + p->lengthFound = 0; + continue; + } + + + if (b != ESCAPE_COMMAND) + { + p->currState = STATE_ABORT; + Con_DPrintf("Serial: Bad escape sequence\n"); + continue; + } + + // b == ESCAPE_COMMAND + p->currState = p->prevState; + } + + p->prevState = p->currState; + +//DEBUG + if (p->sock->receiveMessageLength + p->lengthFound > NET_MAXMESSAGE) + { + Con_DPrintf("Serial blew out receive buffer: %u\n", p->sock->receiveMessageLength + p->lengthFound); + p->currState = STATE_ABORT; + } + if (p->sock->receiveMessageLength + p->lengthFound == NET_MAXMESSAGE) + { + Con_DPrintf("Serial hit receive buffer limit: %u\n", p->sock->receiveMessageLength + p->lengthFound); + p->currState = STATE_ABORT; + } +//end DEBUG + + switch (p->currState) + { + case STATE_READY: + CRC_Init(&p->crcValue); + CRC_ProcessByte(&p->crcValue, b); + if (p->client) + { + if ((b & MTYPE_CLIENT) != 0) + { + p->currState = STATE_ABORT; + Con_DPrintf("Serial: client got own message\n"); + break; + } + } + else + { + if ((b & MTYPE_CLIENT) == 0) + { + p->currState = STATE_ABORT; + Con_DPrintf("Serial: server got own message\n"); + break; + } + b &= 0x7f; + } + p->mtype = b; + if (b != MTYPE_CONTROL) + p->currState = STATE_SEQUENCE; + else + p->currState = STATE_LENGTH1; + if (p->mtype < MTYPE_ACK) + { + p->sock->receiveMessage[p->sock->receiveMessageLength] = b; + p->lengthFound++; + } + break; + + case STATE_SEQUENCE: + p->sequence = b; + CRC_ProcessByte(&p->crcValue, b); + if (p->mtype != MTYPE_ACK) + p->currState = STATE_LENGTH1; + else + p->currState = STATE_CRC1; + break; + + case STATE_LENGTH1: + p->lengthStated = b * 256; + CRC_ProcessByte(&p->crcValue, b); + p->currState = STATE_LENGTH2; + break; + + case STATE_LENGTH2: + p->lengthStated += b; + CRC_ProcessByte(&p->crcValue, b); + if (p->mtype == MTYPE_RELIABLE && p->lengthStated > MAX_MSGLEN) + { + p->currState = STATE_ABORT; + Con_DPrintf("Serial: bad reliable message length %u\n", p->lengthStated); + } + else if (p->mtype == MTYPE_UNRELIABLE && p->lengthStated > MAX_DATAGRAM) + { + p->currState = STATE_ABORT; + Con_DPrintf("Serial: bad unreliable message length %u\n", p->lengthStated); + } + else + { + p->currState = STATE_DATA; + if (p->mtype < MTYPE_ACK) + { + *(short *)&p->sock->receiveMessage [p->sock->receiveMessageLength + 1] = p->lengthStated; + p->lengthFound += 2; + } + } + break; + + case STATE_DATA: + p->sock->receiveMessage[p->sock->receiveMessageLength + p->lengthFound] = b; + p->lengthFound++; + CRC_ProcessByte(&p->crcValue, b); + if (p->lengthFound == p->lengthStated + 3) + p->currState = STATE_CRC1; + break; + + case STATE_CRC1: + p->crcStated = b * 256; + p->currState = STATE_CRC2; + break; + + case STATE_CRC2: + p->crcStated += b; + if (p->crcStated == CRC_Value(p->crcValue)) + { + p->currState = STATE_EOM; + } + else + { + p->currState = STATE_ABORT; + Con_DPrintf("Serial: Bad crc\n"); + } + break; + + case STATE_EOM: + p->currState = STATE_ABORT; + Con_DPrintf("Serial: Bad message format\n"); + break; + + case STATE_ABORT: + break; + } + } + return 0; +} + + +int Serial_Init (void) +{ + int n; + +// LATER do Win32 serial support +#ifdef _WIN32 + return -1; +#endif + + if (COM_CheckParm("-nolan")) + return -1; + if (COM_CheckParm ("-noserial")) + return -1; + + myDriverLevel = net_driverlevel; + + if (TTY_Init()) + return -1; + + for (n = 0; n < NUM_COM_PORTS; n++) + { + serialLine[n].tty = TTY_Open(n); + ResetSerialLineProtocol (&serialLine[n]); + } + + Con_Printf("Serial driver initialized\n"); + serialAvailable = true; + + return 0; +} + + +void Serial_Shutdown (void) +{ + int n; + + for (n = 0; n < NUM_COM_PORTS; n++) + { + if (serialLine[n].connected) + Serial_Close(serialLine[n].sock); + } + + TTY_Shutdown(); +} + + +void Serial_Listen (qboolean state) +{ + listening = state; +} + + +qboolean Serial_CanSendMessage (qsocket_t *sock) +{ + return sock->canSend; +} + + +qboolean Serial_CanSendUnreliableMessage (qsocket_t *sock) +{ + return TTY_OutputQueueIsEmpty(((SerialLine *)sock->driverdata)->tty); +} + + +int Serial_SendMessage (qsocket_t *sock, sizebuf_t *message) +{ + SerialLine *p; + int n; + unsigned short crc; + byte b; + + p = (SerialLine *)sock->driverdata; + CRC_Init (&crc); + + // message type + b = MTYPE_RELIABLE; + if (p->client) + b |= MTYPE_CLIENT; + TTY_WriteByte(p->tty, b); + CRC_ProcessByte (&crc, b); + + // sequence + b = p->sock->sendSequence; + TTY_WriteByte(p->tty, b); + if (b == ESCAPE_COMMAND) + TTY_WriteByte(p->tty, b); + CRC_ProcessByte (&crc, b); + + // data length + b = message->cursize >> 8; + TTY_WriteByte(p->tty, b); + if (b == ESCAPE_COMMAND) + TTY_WriteByte(p->tty, b); + CRC_ProcessByte (&crc, b); + b = message->cursize & 0xff; + TTY_WriteByte(p->tty, b); + if (b == ESCAPE_COMMAND) + TTY_WriteByte(p->tty, b); + CRC_ProcessByte (&crc, b); + + // data + for (n = 0; n < message->cursize; n++) + { + b = message->data[n]; + TTY_WriteByte(p->tty, b); + if (b == ESCAPE_COMMAND) + TTY_WriteByte(p->tty, b); + CRC_ProcessByte (&crc, b); + } + + // checksum + b = CRC_Value (crc) >> 8; + TTY_WriteByte(p->tty, b); + if (b == ESCAPE_COMMAND) + TTY_WriteByte(p->tty, b); + b = CRC_Value (crc) & 0xff; + TTY_WriteByte(p->tty, b); + if (b == ESCAPE_COMMAND) + TTY_WriteByte(p->tty, b); + + // end of message + TTY_WriteByte(p->tty, ESCAPE_COMMAND); + TTY_WriteByte(p->tty, ESCAPE_EOM); + + TTY_Flush(p->tty); + + // mark sock as busy and save the message for possible retransmit + sock->canSend = false; + Q_memcpy(sock->sendMessage, message->data, message->cursize); + sock->sendMessageLength = message->cursize; + sock->lastSendTime = net_time; + + return 1; +} + + +static void ReSendMessage (qsocket_t *sock) +{ + sizebuf_t temp; + + Con_DPrintf("Serial: re-sending reliable\n"); + temp.data = sock->sendMessage; + temp.maxsize = sock->sendMessageLength; + temp.cursize = sock->sendMessageLength; + Serial_SendMessage (sock, &temp); +} + + +int Serial_SendUnreliableMessage (qsocket_t *sock, sizebuf_t *message) +{ + SerialLine *p; + int n; + unsigned short crc; + byte b; + + p = (SerialLine *)sock->driverdata; + + if (!TTY_OutputQueueIsEmpty(p->tty)) + { + TTY_Flush(p->tty); + return 1; + } + + CRC_Init (&crc); + + // message type + b = MTYPE_UNRELIABLE; + if (p->client) + b |= MTYPE_CLIENT; + TTY_WriteByte(p->tty, b); + CRC_ProcessByte (&crc, b); + + // sequence + b = p->sock->unreliableSendSequence; + p->sock->unreliableSendSequence = (b + 1) & 0xff; + TTY_WriteByte(p->tty, b); + if (b == ESCAPE_COMMAND) + TTY_WriteByte(p->tty, b); + CRC_ProcessByte (&crc, b); + + // data length + b = message->cursize >> 8; + TTY_WriteByte(p->tty, b); + if (b == ESCAPE_COMMAND) + TTY_WriteByte(p->tty, b); + CRC_ProcessByte (&crc, b); + b = message->cursize & 0xff; + TTY_WriteByte(p->tty, b); + if (b == ESCAPE_COMMAND) + TTY_WriteByte(p->tty, b); + CRC_ProcessByte (&crc, b); + + // data + for (n = 0; n < message->cursize; n++) + { + b = message->data[n]; + TTY_WriteByte(p->tty, b); + if (b == ESCAPE_COMMAND) + TTY_WriteByte(p->tty, b); + CRC_ProcessByte (&crc, b); + } + + // checksum + b = CRC_Value (crc) >> 8; + TTY_WriteByte(p->tty, b); + if (b == ESCAPE_COMMAND) + TTY_WriteByte(p->tty, b); + b = CRC_Value (crc) & 0xff; + TTY_WriteByte(p->tty, b); + if (b == ESCAPE_COMMAND) + TTY_WriteByte(p->tty, b); + + // end of message + TTY_WriteByte(p->tty, ESCAPE_COMMAND); + TTY_WriteByte(p->tty, ESCAPE_EOM); + + TTY_Flush(p->tty); + + return 1; +} + + +static void Serial_SendACK (SerialLine *p, byte sequence) +{ + unsigned short crc; + byte b; + + CRC_Init (&crc); + + // message type + b = MTYPE_ACK; + if (p->client) + b |= MTYPE_CLIENT; + TTY_WriteByte(p->tty, b); + CRC_ProcessByte (&crc, b); + + // sequence + b = sequence; + TTY_WriteByte(p->tty, b); + if (b == ESCAPE_COMMAND) + TTY_WriteByte(p->tty, b); + CRC_ProcessByte (&crc, b); + + // checksum + b = CRC_Value (crc) >> 8; + TTY_WriteByte(p->tty, b); + if (b == ESCAPE_COMMAND) + TTY_WriteByte(p->tty, b); + b = CRC_Value (crc) & 0xff; + TTY_WriteByte(p->tty, b); + if (b == ESCAPE_COMMAND) + TTY_WriteByte(p->tty, b); + + // end of message + TTY_WriteByte(p->tty, ESCAPE_COMMAND); + TTY_WriteByte(p->tty, ESCAPE_EOM); + + TTY_Flush(p->tty); +} + + +static void Serial_SendControlMessage (SerialLine *p, sizebuf_t *message) +{ + unsigned short crc; + int n; + byte b; + + CRC_Init (&crc); + + // message type + b = MTYPE_CONTROL; + if (p->client) + b |= MTYPE_CLIENT; + TTY_WriteByte(p->tty, b); + CRC_ProcessByte (&crc, b); + + // data length + b = message->cursize >> 8; + TTY_WriteByte(p->tty, b); + if (b == ESCAPE_COMMAND) + TTY_WriteByte(p->tty, b); + CRC_ProcessByte (&crc, b); + b = message->cursize & 0xff; + TTY_WriteByte(p->tty, b); + if (b == ESCAPE_COMMAND) + TTY_WriteByte(p->tty, b); + CRC_ProcessByte (&crc, b); + + // data + for (n = 0; n < message->cursize; n++) + { + b = message->data[n]; + TTY_WriteByte(p->tty, b); + if (b == ESCAPE_COMMAND) + TTY_WriteByte(p->tty, b); + CRC_ProcessByte (&crc, b); + } + + // checksum + b = CRC_Value (crc) >> 8; + TTY_WriteByte(p->tty, b); + if (b == ESCAPE_COMMAND) + TTY_WriteByte(p->tty, b); + b = CRC_Value (crc) & 0xff; + TTY_WriteByte(p->tty, b); + if (b == ESCAPE_COMMAND) + TTY_WriteByte(p->tty, b); + + // end of message + TTY_WriteByte(p->tty, ESCAPE_COMMAND); + TTY_WriteByte(p->tty, ESCAPE_EOM); + + TTY_Flush(p->tty); +} + + +static int _Serial_GetMessage (SerialLine *p) +{ + byte ret; + short length; + + if (ProcessInQueue(p)) + return -1; + + if (p->sock->receiveMessageLength == 0) + return 0; + + ret = p->sock->receiveMessage[0]; + length = *(short *)&p->sock->receiveMessage[1]; + if (ret == MTYPE_CONTROL) + ret = 1; + + SZ_Clear (&net_message); + SZ_Write (&net_message, &p->sock->receiveMessage[3], length); + + length += 3; + p->sock->receiveMessageLength -= length; + + if (p->sock->receiveMessageLength + p->lengthFound) + Q_memcpy(p->sock->receiveMessage, &p->sock->receiveMessage[length], p->sock->receiveMessageLength + p->lengthFound); + + return ret; +} + +int Serial_GetMessage (qsocket_t *sock) +{ + SerialLine *p; + int ret; + + p = (SerialLine *)sock->driverdata; + + ret = _Serial_GetMessage (p); + + if (ret == 1) + messagesReceived++; + + if (!sock->canSend) + if ((net_time - sock->lastSendTime) > 1.0) + { + ReSendMessage (sock); + sock->lastSendTime = net_time; + } + + return ret; +} + + +void Serial_Close (qsocket_t *sock) +{ + SerialLine *p = (SerialLine *)sock->driverdata; + TTY_Close(p->tty); + ResetSerialLineProtocol (p); +} + + +char *com_types[] = {"direct", "modem"}; +unsigned com_bauds[] = {9600, 14400, 19200, 28800, 57600}; + +void Serial_SearchForHosts (qboolean xmit) +{ + int n; + SerialLine *p; + + if (sv.active) + return; + + if (hostCacheCount == HOSTCACHESIZE) + return; + + // see if we've already answered + for (n = 0; n < hostCacheCount; n++) + if (Q_strcmp (hostcache[n].cname, "#") == 0) + return; + + for (n = 0; n < NUM_COM_PORTS; n++) + if (TTY_IsEnabled(n)) + break; + if (n == NUM_COM_PORTS) + return; + p = &serialLine[n]; + + if (TTY_IsModem(p->tty)) + return; + + sprintf(hostcache[hostCacheCount].name, "COM%u", n+1); + Q_strcpy(hostcache[hostCacheCount].map, ""); + hostcache[hostCacheCount].users = 0; + hostcache[hostCacheCount].maxusers = 0; + hostcache[hostCacheCount].driver = net_driverlevel; + Q_strcpy(hostcache[hostCacheCount].cname, "#"); + hostCacheCount++; + + return; +} + + +static qsocket_t *_Serial_Connect (char *host, SerialLine *p) +{ + int ret; + double start_time; + double last_time; + + p->client = true; + if (TTY_Connect(p->tty, host)) + return NULL; + + p->sock = NET_NewQSocket (); + p->sock->driver = myDriverLevel; + if (p->sock == NULL) + { + Con_Printf("No sockets available\n"); + return NULL; + } + p->sock->driverdata = p; + + // send the connection request + start_time = SetNetTime(); + last_time = 0.0; + + SZ_Clear(&net_message); + MSG_WriteByte(&net_message, CCREQ_CONNECT); + MSG_WriteString(&net_message, "QUAKE"); + do + { + SetNetTime(); + if ((net_time - last_time) >= 1.0) + { + Serial_SendControlMessage (p, &net_message); + last_time = net_time; + Con_Printf("trying...\n"); SCR_UpdateScreen (); + } + ret = _Serial_GetMessage (p); + } + while (ret == 0 && (net_time - start_time) < 5.0); + + if (ret == 0) + { + Con_Printf("Unable to connect, no response\n"); + goto ErrorReturn; + } + + if (ret == -1) + { + Con_Printf("Connection request error\n"); + goto ErrorReturn; + } + + MSG_BeginReading (); + ret = MSG_ReadByte(); + if (ret == CCREP_REJECT) + { + Con_Printf(MSG_ReadString()); + goto ErrorReturn; + } + if (ret != CCREP_ACCEPT) + { + Con_Printf("Unknown connection response\n"); + goto ErrorReturn; + } + + p->connected = true; + p->sock->lastMessageTime = net_time; + + Con_Printf ("Connection accepted\n"); + + return p->sock; + +ErrorReturn: + TTY_Disconnect(p->tty); + return NULL; +} + +qsocket_t *Serial_Connect (char *host) +{ + int n; + qsocket_t *ret = NULL; + + // see if this looks like a phone number + if (*host == '#') + host++; + for (n = 0; n < Q_strlen(host); n++) + if (host[n] == '.' || host[n] == ':') + return NULL; + + for (n = 0; n < NUM_COM_PORTS; n++) + if (TTY_IsEnabled(n) && !serialLine[n].connected) + if ((ret = _Serial_Connect (host, &serialLine[n]))) + break; + return ret; +} + + +static qsocket_t *_Serial_CheckNewConnections (SerialLine *p) +{ + int command; + + p->client = false; + if (!TTY_CheckForConnection(p->tty)) + return NULL; + + if (TTY_IsModem(p->tty)) + { + if (!p->connecting) + { + p->connecting = true; + p->connect_time = net_time; + } + else if ((net_time - p->connect_time) > 15.0) + { + p->connecting = false; + TTY_Disconnect(p->tty); + return NULL; + } + } + + p->sock = NET_NewQSocket (); + p->sock->driver = myDriverLevel; + if (p->sock == NULL) + { + Con_Printf("No sockets available\n"); + return NULL; + } + p->sock->driverdata = p; + + SZ_Clear(&net_message); + if (_Serial_GetMessage(p) != 1) + { + NET_FreeQSocket(p->sock); + return NULL; + } + + MSG_BeginReading (); + command = MSG_ReadByte(); + + if (command == CCREQ_SERVER_INFO) + { + if (Q_strcmp(MSG_ReadString(), "QUAKE") != 0) + return NULL; + + if (MSG_ReadByte() != SERIAL_PROTOCOL_VERSION) + return NULL; + + SZ_Clear(&net_message); + MSG_WriteByte(&net_message, CCREP_SERVER_INFO); + MSG_WriteString(&net_message, hostname.string); + MSG_WriteString(&net_message, sv.name); + MSG_WriteByte(&net_message, net_activeconnections); + MSG_WriteByte(&net_message, svs.maxclients); + Serial_SendControlMessage (p, &net_message); + SZ_Clear(&net_message); + return NULL; + } + + if (command != CCREQ_CONNECT) + return NULL; + + if (Q_strcmp(MSG_ReadString(), "QUAKE") != 0) + return NULL; + + // send him back the info about the server connection he has been allocated + SZ_Clear(&net_message); + MSG_WriteByte(&net_message, CCREP_ACCEPT); + Serial_SendControlMessage (p, &net_message); + SZ_Clear(&net_message); + + p->connected = true; + p->connecting = false; + p->sock->lastMessageTime = net_time; + sprintf(p->sock->address, "COM%u", (int)((p - serialLine) + 1)); + + return p->sock; +} + +qsocket_t *Serial_CheckNewConnections (void) +{ + int n; + qsocket_t *ret = NULL; + + for (n = 0; n < NUM_COM_PORTS; n++) + if (TTY_IsEnabled(n) && !serialLine[n].connected) + if ((ret = _Serial_CheckNewConnections (&serialLine[n]))) + break; + return ret; +} diff --git a/contrib/other/sdlquake-1.0.9/net_ser.h b/contrib/other/sdlquake-1.0.9/net_ser.h new file mode 100644 index 000000000..5885ab970 --- /dev/null +++ b/contrib/other/sdlquake-1.0.9/net_ser.h @@ -0,0 +1,33 @@ +/* +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_ser.h + +int Serial_Init (void); +void Serial_Listen (qboolean state); +void Serial_SearchForHosts (qboolean xmit); +qsocket_t *Serial_Connect (char *host); +qsocket_t *Serial_CheckNewConnections (void); +int Serial_GetMessage (qsocket_t *sock); +int Serial_SendMessage (qsocket_t *sock, sizebuf_t *data); +int Serial_SendUnreliableMessage (qsocket_t *sock, sizebuf_t *data); +qboolean Serial_CanSendMessage (qsocket_t *sock); +qboolean Serial_CanSendUnreliableMessage (qsocket_t *sock); +void Serial_Close (qsocket_t *sock); +void Serial_Shutdown (void); diff --git a/contrib/other/sdlquake-1.0.9/net_udp.c b/contrib/other/sdlquake-1.0.9/net_udp.c new file mode 100644 index 000000000..c7e825663 --- /dev/null +++ b/contrib/other/sdlquake-1.0.9/net_udp.c @@ -0,0 +1,415 @@ +/* +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_udp.c + +#include "quakedef.h" + +#include +#include +#include +#include +#include +#include +#include + +#ifdef __sun__ +#include +#endif + +#ifdef NeXT +#include +#endif + +extern int gethostname (char *, int); +extern int close (int); + +extern cvar_t hostname; + +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; + +#include "net_udp.h" + +//============================================================================= + +int UDP_Init (void) +{ + struct hostent *local; + char buff[MAXHOSTNAMELEN]; + struct qsockaddr addr; + char *colon; + + if (COM_CheckParm ("-noudp")) + return -1; + + // determine my name & address + gethostname(buff, MAXHOSTNAMELEN); + local = gethostbyname(buff); + myAddr = *(int *)local->h_addr_list[0]; + + // if the quake hostname isn't set, set it to the machine name + if (Q_strcmp(hostname.string, "UNNAMED") == 0) + { + buff[15] = 0; + Cvar_Set ("hostname", buff); + } + + if ((net_controlsocket = UDP_OpenSocket (0)) == -1) + Sys_Error("UDP_Init: Unable to open control socket\n"); + + ((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(net_hostport); + + UDP_GetSocketAddr (net_controlsocket, &addr); + Q_strcpy(my_tcpip_address, UDP_AddrToString (&addr)); + colon = Q_strrchr (my_tcpip_address, ':'); + if (colon) + *colon = 0; + + Con_Printf("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 != -1) + return; + if ((net_acceptsocket = UDP_OpenSocket (net_hostport)) == -1) + Sys_Error ("UDP_Listen: Unable to open accept socket\n"); + return; + } + + // disable listening + if (net_acceptsocket == -1) + return; + UDP_CloseSocket (net_acceptsocket); + net_acceptsocket = -1; +} + +//============================================================================= + +int UDP_OpenSocket (int port) +{ + int newsocket; + struct sockaddr_in address; + qboolean _true = true; + + if ((newsocket = socket (PF_INET, SOCK_DGRAM, IPPROTO_UDP)) == -1) + return -1; + +#if 0 + if (ioctl (newsocket, FIONBIO, (char *)&_true) == -1) + goto ErrorReturn; +#endif + address.sin_family = AF_INET; + address.sin_addr.s_addr = INADDR_ANY; + address.sin_port = htons(port); + if( bind (newsocket, (void *)&address, sizeof(address)) == -1) + goto ErrorReturn; + + return newsocket; + +ErrorReturn: + close (newsocket); + return -1; +} + +//============================================================================= + +int UDP_CloseSocket (int socket) +{ + if (socket == net_broadcastsocket) + net_broadcastsocket = 0; + return close (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 UDP_Connect (int socket, struct qsockaddr *addr) +{ + return 0; +} + +//============================================================================= + +int UDP_CheckNewConnections (void) +{ + unsigned long available; + + if (net_acceptsocket == -1) + return -1; + + if (ioctl (net_acceptsocket, FIONREAD, &available) == -1) + Sys_Error ("UDP: ioctlsocket (FIONREAD) failed\n"); + if (available) + return net_acceptsocket; + return -1; +} + +//============================================================================= + +int UDP_Read (int socket, byte *buf, int len, struct qsockaddr *addr) +{ + int addrlen = sizeof (struct qsockaddr); + int ret; + + ret = recvfrom (socket, buf, len, 0, (struct sockaddr *)addr, &addrlen); + if (ret == -1 && (errno == EWOULDBLOCK || errno == ECONNREFUSED)) + return 0; + return ret; +} + +//============================================================================= + +int UDP_MakeSocketBroadcastCapable (int socket) +{ + int i = 1; + + // make this socket broadcast capable + if (setsockopt(socket, SOL_SOCKET, SO_BROADCAST, (char *)&i, sizeof(i)) < 0) + return -1; + net_broadcastsocket = socket; + + return 0; +} + +//============================================================================= + +int UDP_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"); + ret = UDP_MakeSocketBroadcastCapable (socket); + if (ret == -1) + { + Con_Printf("Unable to make socket broadcast capable\n"); + return ret; + } + } + + return UDP_Write (socket, buf, len, &broadcastaddr); +} + +//============================================================================= + +int UDP_Write (int socket, byte *buf, int len, struct qsockaddr *addr) +{ + int ret; + + ret = sendto (socket, buf, len, 0, (struct sockaddr *)addr, sizeof(struct qsockaddr)); + if (ret == -1 && errno == EWOULDBLOCK) + return 0; + return ret; +} + +//============================================================================= + +char *UDP_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 UDP_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(hp); + return 0; +} + +//============================================================================= + +int UDP_GetSocketAddr (int socket, struct qsockaddr *addr) +{ + int addrlen = sizeof(struct qsockaddr); + unsigned int a; + + Q_memset(addr, 0, sizeof(struct qsockaddr)); + getsockname(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 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) + { + Q_strncpy (name, (char *)hostentry->h_name, NET_NAMELEN - 1); + return 0; + } + + Q_strcpy (name, UDP_AddrToString (addr)); + return 0; +} + +//============================================================================= + +int UDP_GetAddrFromName(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->sa_family = AF_INET; + ((struct sockaddr_in *)addr)->sin_port = htons(net_hostport); + ((struct sockaddr_in *)addr)->sin_addr.s_addr = *(int *)hostentry->h_addr_list[0]; + + return 0; +} + +//============================================================================= + +int UDP_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 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(port); + return 0; +} + +//============================================================================= diff --git a/contrib/other/sdlquake-1.0.9/net_udp.h b/contrib/other/sdlquake-1.0.9/net_udp.h new file mode 100644 index 000000000..75303011c --- /dev/null +++ b/contrib/other/sdlquake-1.0.9/net_udp.h @@ -0,0 +1,39 @@ +/* +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_udp.h + +int UDP_Init (void); +void UDP_Shutdown (void); +void UDP_Listen (qboolean state); +int UDP_OpenSocket (int port); +int UDP_CloseSocket (int socket); +int UDP_Connect (int socket, struct qsockaddr *addr); +int UDP_CheckNewConnections (void); +int UDP_Read (int socket, byte *buf, int len, struct qsockaddr *addr); +int UDP_Write (int socket, byte *buf, int len, struct qsockaddr *addr); +int UDP_Broadcast (int socket, byte *buf, int len); +char *UDP_AddrToString (struct qsockaddr *addr); +int UDP_StringToAddr (char *string, struct qsockaddr *addr); +int UDP_GetSocketAddr (int socket, struct qsockaddr *addr); +int UDP_GetNameFromAddr (struct qsockaddr *addr, char *name); +int UDP_GetAddrFromName (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); diff --git a/contrib/other/sdlquake-1.0.9/net_vcr.c b/contrib/other/sdlquake-1.0.9/net_vcr.c new file mode 100644 index 000000000..ba8f40dcc --- /dev/null +++ b/contrib/other/sdlquake-1.0.9/net_vcr.c @@ -0,0 +1,167 @@ +/* +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/contrib/other/sdlquake-1.0.9/net_vcr.h b/contrib/other/sdlquake-1.0.9/net_vcr.h new file mode 100644 index 000000000..95c2f34c3 --- /dev/null +++ b/contrib/other/sdlquake-1.0.9/net_vcr.h @@ -0,0 +1,37 @@ +/* +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/contrib/other/sdlquake-1.0.9/net_win.c b/contrib/other/sdlquake-1.0.9/net_win.c new file mode 100644 index 000000000..9c9e6cb77 --- /dev/null +++ b/contrib/other/sdlquake-1.0.9/net_win.c @@ -0,0 +1,120 @@ +/* +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/contrib/other/sdlquake-1.0.9/net_wins.c b/contrib/other/sdlquake-1.0.9/net_wins.c new file mode 100644 index 000000000..3d188edf3 --- /dev/null +++ b/contrib/other/sdlquake-1.0.9/net_wins.c @@ -0,0 +1,575 @@ +/* +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) + { + int errno = pWSAGetLastError(); + + if (errno == WSAEWOULDBLOCK || errno == WSAECONNREFUSED) + return 0; + + } + 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/contrib/other/sdlquake-1.0.9/net_wins.h b/contrib/other/sdlquake-1.0.9/net_wins.h new file mode 100644 index 000000000..756ce6459 --- /dev/null +++ b/contrib/other/sdlquake-1.0.9/net_wins.h @@ -0,0 +1,39 @@ +/* +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.h + +int 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); +int WINS_GetNameFromAddr (struct qsockaddr *addr, char *name); +int WINS_GetAddrFromName (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); diff --git a/contrib/other/sdlquake-1.0.9/net_wipx.c b/contrib/other/sdlquake-1.0.9/net_wipx.c new file mode 100644 index 000000000..a2ac6244e --- /dev/null +++ b/contrib/other/sdlquake-1.0.9/net_wipx.c @@ -0,0 +1,432 @@ +/* +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_wipx.c + +#include "quakedef.h" +#include "winquake.h" +#include +#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; + +extern qboolean winsock_initialized; +extern WSADATA winsockdata; + +#define IPXSOCKETS 18 +static int ipxsocket[IPXSOCKETS]; +static int sequence[IPXSOCKETS]; + +//============================================================================= + +int WIPX_Init (void) +{ + int i; + char buff[MAXHOSTNAMELEN]; + struct qsockaddr addr; + char *p; + int r; + WORD wVersionRequested; + + if (COM_CheckParm ("-noipx")) + return -1; + +// make sure LoadLibrary has happened successfully + if (!winsock_lib_initialized) + return -1; + + if (winsock_initialized == 0) + { + wVersionRequested = MAKEWORD(1, 1); + + r = pWSAStartup (MAKEWORD(1, 1), &winsockdata); + + if (r) + { + Con_Printf ("Winsock initialization failed.\n"); + return -1; + } + } + winsock_initialized++; + + for (i = 0; i < IPXSOCKETS; i++) + ipxsocket[i] = 0; + + // determine my name & address + if (pgethostname(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); + } + } + + if ((net_controlsocket = WIPX_OpenSocket (0)) == -1) + { + Con_Printf("WIPX_Init: Unable to open control socket\n"); + if (--winsock_initialized == 0) + pWSACleanup (); + return -1; + } + + ((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); + + WIPX_GetSocketAddr (net_controlsocket, &addr); + Q_strcpy(my_ipx_address, WIPX_AddrToString (&addr)); + p = Q_strrchr (my_ipx_address, ':'); + if (p) + *p = 0; + + Con_Printf("Winsock IPX Initialized\n"); + ipxAvailable = true; + + return net_controlsocket; +} + +//============================================================================= + +void WIPX_Shutdown (void) +{ + WIPX_Listen (false); + WIPX_CloseSocket (net_controlsocket); + if (--winsock_initialized == 0) + pWSACleanup (); +} + +//============================================================================= + +void WIPX_Listen (qboolean state) +{ + // enable listening + if (state) + { + if (net_acceptsocket != -1) + return; + if ((net_acceptsocket = WIPX_OpenSocket (net_hostport)) == -1) + Sys_Error ("WIPX_Listen: Unable to open accept socket\n"); + return; + } + + // disable listening + if (net_acceptsocket == -1) + return; + WIPX_CloseSocket (net_acceptsocket); + net_acceptsocket = -1; +} + +//============================================================================= + +int WIPX_OpenSocket (int port) +{ + int handle; + int 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; + + if ((newsocket = psocket (AF_IPX, SOCK_DGRAM, NSPROTO_IPX)) == INVALID_SOCKET) + return -1; + + if (pioctlsocket (newsocket, FIONBIO, &_true) == -1) + goto ErrorReturn; + + if (psetsockopt(newsocket, SOL_SOCKET, SO_BROADCAST, (char *)&_true, sizeof(_true)) < 0) + 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) + { + ipxsocket[handle] = newsocket; + sequence[handle] = 0; + return handle; + } + + Sys_Error ("Winsock IPX bind failed\n"); +ErrorReturn: + pclosesocket (newsocket); + return -1; +} + +//============================================================================= + +int WIPX_CloseSocket (int handle) +{ + int socket = ipxsocket[handle]; + int ret; + + ret = pclosesocket (socket); + ipxsocket[handle] = 0; + return ret; +} + + +//============================================================================= + +int WIPX_Connect (int handle, struct qsockaddr *addr) +{ + return 0; +} + +//============================================================================= + +int WIPX_CheckNewConnections (void) +{ + unsigned long available; + + if (net_acceptsocket == -1) + return -1; + + if (pioctlsocket (ipxsocket[net_acceptsocket], FIONREAD, &available) == -1) + Sys_Error ("WIPX: ioctlsocket (FIONREAD) failed\n"); + if (available) + return net_acceptsocket; + return -1; +} + +//============================================================================= + +static byte packetBuffer[NET_DATAGRAMSIZE + 4]; + +int WIPX_Read (int handle, byte *buf, int len, struct qsockaddr *addr) +{ + int addrlen = sizeof (struct qsockaddr); + int socket = ipxsocket[handle]; + int ret; + + ret = precvfrom (socket, packetBuffer, len+4, 0, (struct sockaddr *)addr, &addrlen); + if (ret == -1) + { + int errno = pWSAGetLastError(); + + if (errno == WSAEWOULDBLOCK || errno == WSAECONNREFUSED) + return 0; + + } + + if (ret < 4) + return 0; + + // remove sequence number, it's only needed for DOS IPX + ret -= 4; + memcpy(buf, packetBuffer+4, ret); + + return ret; +} + +//============================================================================= + +int WIPX_Broadcast (int handle, byte *buf, int len) +{ + return WIPX_Write (handle, buf, len, &broadcastaddr); +} + +//============================================================================= + +int WIPX_Write (int handle, byte *buf, int len, struct qsockaddr *addr) +{ + int socket = ipxsocket[handle]; + int ret; + + // build packet with sequence number + *(int *)(&packetBuffer[0]) = sequence[handle]; + sequence[handle]++; + memcpy(&packetBuffer[4], buf, len); + len += 4; + + ret = psendto (socket, packetBuffer, len, 0, (struct sockaddr *)addr, sizeof(struct qsockaddr)); + if (ret == -1) + if (pWSAGetLastError() == WSAEWOULDBLOCK) + return 0; + + return ret; +} + +//============================================================================= + +char *WIPX_AddrToString (struct qsockaddr *addr) +{ + static char buf[28]; + + sprintf(buf, "%02x%02x%02x%02x:%02x%02x%02x%02x%02x%02x:%u", + ((struct sockaddr_ipx *)addr)->sa_netnum[0] & 0xff, + ((struct sockaddr_ipx *)addr)->sa_netnum[1] & 0xff, + ((struct sockaddr_ipx *)addr)->sa_netnum[2] & 0xff, + ((struct sockaddr_ipx *)addr)->sa_netnum[3] & 0xff, + ((struct sockaddr_ipx *)addr)->sa_nodenum[0] & 0xff, + ((struct sockaddr_ipx *)addr)->sa_nodenum[1] & 0xff, + ((struct sockaddr_ipx *)addr)->sa_nodenum[2] & 0xff, + ((struct sockaddr_ipx *)addr)->sa_nodenum[3] & 0xff, + ((struct sockaddr_ipx *)addr)->sa_nodenum[4] & 0xff, + ((struct sockaddr_ipx *)addr)->sa_nodenum[5] & 0xff, + ntohs(((struct sockaddr_ipx *)addr)->sa_socket) + ); + return buf; +} + +//============================================================================= + +int WIPX_StringToAddr (char *string, struct qsockaddr *addr) +{ + int val; + char buf[3]; + + buf[2] = 0; + Q_memset(addr, 0, sizeof(struct qsockaddr)); + addr->sa_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 + + DO(0, sa_netnum[0]); + DO(2, sa_netnum[1]); + DO(4, sa_netnum[2]); + DO(6, sa_netnum[3]); + DO(9, sa_nodenum[0]); + DO(11, sa_nodenum[1]); + DO(13, sa_nodenum[2]); + DO(15, sa_nodenum[3]); + DO(17, sa_nodenum[4]); + DO(19, sa_nodenum[5]); +#undef DO + + sscanf (&string[22], "%u", &val); + ((struct sockaddr_ipx *)addr)->sa_socket = htons((unsigned short)val); + + return 0; +} + +//============================================================================= + +int WIPX_GetSocketAddr (int handle, struct qsockaddr *addr) +{ + int socket = ipxsocket[handle]; + int addrlen = sizeof(struct qsockaddr); + unsigned int a; + + Q_memset(addr, 0, sizeof(struct qsockaddr)); + if(pgetsockname(socket, (struct sockaddr *)addr, &addrlen) != 0) + { + int errno = pWSAGetLastError(); + } + + return 0; +} + +//============================================================================= + +int WIPX_GetNameFromAddr (struct qsockaddr *addr, char *name) +{ + Q_strcpy(name, WIPX_AddrToString(addr)); + return 0; +} + +//============================================================================= + +int WIPX_GetAddrFromName(char *name, struct qsockaddr *addr) +{ + int n; + char buf[32]; + + n = Q_strlen(name); + + if (n == 12) + { + sprintf(buf, "00000000:%s:%u", name, net_hostport); + return WIPX_StringToAddr (buf, addr); + } + if (n == 21) + { + sprintf(buf, "%s:%u", name, net_hostport); + return WIPX_StringToAddr (buf, addr); + } + if (n > 21 && n <= 27) + return WIPX_StringToAddr (name, addr); + + return -1; +} + +//============================================================================= + +int WIPX_AddrCompare (struct qsockaddr *addr1, struct qsockaddr *addr2) +{ + if (addr1->sa_family != addr2->sa_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 0; +} + +//============================================================================= + +int WIPX_GetSocketPort (struct qsockaddr *addr) +{ + return ntohs(((struct sockaddr_ipx *)addr)->sa_socket); +} + + +int WIPX_SetSocketPort (struct qsockaddr *addr, int port) +{ + ((struct sockaddr_ipx *)addr)->sa_socket = htons((unsigned short)port); + return 0; +} + +//============================================================================= diff --git a/contrib/other/sdlquake-1.0.9/net_wipx.h b/contrib/other/sdlquake-1.0.9/net_wipx.h new file mode 100644 index 000000000..ed82dc1d9 --- /dev/null +++ b/contrib/other/sdlquake-1.0.9/net_wipx.h @@ -0,0 +1,39 @@ +/* +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_wipx.h + +int 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); +int WIPX_GetNameFromAddr (struct qsockaddr *addr, char *name); +int WIPX_GetAddrFromName (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); diff --git a/contrib/other/sdlquake-1.0.9/net_wso.c b/contrib/other/sdlquake-1.0.9/net_wso.c new file mode 100644 index 000000000..e69de29bb diff --git a/contrib/other/sdlquake-1.0.9/nonintel.c b/contrib/other/sdlquake-1.0.9/nonintel.c new file mode 100644 index 000000000..9e5903969 --- /dev/null +++ b/contrib/other/sdlquake-1.0.9/nonintel.c @@ -0,0 +1,64 @@ +/* +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. + +*/ +// +// nonintel.c: code for non-Intel processors only +// + +#include "quakedef.h" +#include "r_local.h" +#include "d_local.h" + +#if !id386 + +/* +================ +R_Surf8Patch +================ +*/ +void R_Surf8Patch () +{ + // we only patch code on Intel +} + + +/* +================ +R_Surf16Patch +================ +*/ +void R_Surf16Patch () +{ + // we only patch code on Intel +} + + +/* +================ +R_SurfacePatch +================ +*/ +void R_SurfacePatch (void) +{ + // we only patch code on Intel +} + + +#endif // !id386 + diff --git a/contrib/other/sdlquake-1.0.9/pr_cmds.c b/contrib/other/sdlquake-1.0.9/pr_cmds.c new file mode 100644 index 000000000..3593bb931 --- /dev/null +++ b/contrib/other/sdlquake-1.0.9/pr_cmds.c @@ -0,0 +1,1934 @@ +/* +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" + +#define RETURN_EDICT(e) (((int *)pr_globals)[OFS_RETURN] = EDICT_TO_PROG(e)) + +/* +=============================================================================== + + BUILT-IN FUNCTIONS + +=============================================================================== +*/ + +char *PF_VarString (int first) +{ + int i; + static char out[256]; + + out[0] = 0; + for (i=first ; is_name,s); + ed = PROG_TO_EDICT(pr_global_struct->self); + ED_Print (ed); + + Host_Error ("Program error"); +} + +/* +================= +PF_objerror + +Dumps out self, then an error message. The program is aborted and self is +removed, but the level can continue. + +objerror(value) +================= +*/ +void PF_objerror (void) +{ + char *s; + edict_t *ed; + + s = PF_VarString(0); + Con_Printf ("======OBJECT ERROR in %s:\n%s\n" + ,pr_strings + pr_xfunction->s_name,s); + ed = PROG_TO_EDICT(pr_global_struct->self); + ED_Print (ed); + ED_Free (ed); + + Host_Error ("Program error"); +} + + + +/* +============== +PF_makevectors + +Writes new values for v_forward, v_up, and v_right based on angles +makevectors(vector) +============== +*/ +void PF_makevectors (void) +{ + AngleVectors (G_VECTOR(OFS_PARM0), pr_global_struct->v_forward, pr_global_struct->v_right, pr_global_struct->v_up); +} + +/* +================= +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. + +setorigin (entity, origin) +================= +*/ +void PF_setorigin (void) +{ + edict_t *e; + float *org; + + e = G_EDICT(OFS_PARM0); + org = G_VECTOR(OFS_PARM1); + VectorCopy (org, e->v.origin); + SV_LinkEdict (e, false); +} + + +void SetMinMaxSize (edict_t *e, float *min, float *max, qboolean rotate) +{ + float *angles; + vec3_t rmin, rmax; + float bounds[2][3]; + float xvector[2], yvector[2]; + float a; + vec3_t base, transformed; + int i, j, k, l; + + for (i=0 ; i<3 ; i++) + if (min[i] > max[i]) + PR_RunError ("backwards mins/maxs"); + + rotate = false; // FIXME: implement rotation properly again + + if (!rotate) + { + VectorCopy (min, rmin); + VectorCopy (max, 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]); + + rmin[0] = rmin[1] = rmin[2] = 9999; + rmax[0] = rmax[1] = rmax[2] = -9999; + + for (i=0 ; i<= 1 ; i++) + { + base[0] = bounds[i][0]; + for (j=0 ; j<= 1 ; j++) + { + base[1] = bounds[j][1]; + 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++) + { + if (transformed[l] < rmin[l]) + rmin[l] = transformed[l]; + if (transformed[l] > rmax[l]) + rmax[l] = transformed[l]; + } + } + } + } + } + +// set derived values + VectorCopy (rmin, e->v.mins); + VectorCopy (rmax, e->v.maxs); + VectorSubtract (max, min, e->v.size); + + SV_LinkEdict (e, false); +} + +/* +================= +PF_setsize + +the size box is rotated by the current angle + +setsize (entity, minvector, maxvector) +================= +*/ +void PF_setsize (void) +{ + edict_t *e; + float *min, *max; + + e = G_EDICT(OFS_PARM0); + min = G_VECTOR(OFS_PARM1); + max = G_VECTOR(OFS_PARM2); + SetMinMaxSize (e, min, max, false); +} + + +/* +================= +PF_setmodel + +setmodel(entity, model) +================= +*/ +void PF_setmodel (void) +{ + edict_t *e; + char *m, **check; + model_t *mod; + int i; + + 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++) + if (!strcmp(*check, m)) + break; + + if (!*check) + PR_RunError ("no precache: %s\n", m); + + + e->v.model = m - pr_strings; + 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); + else + SetMinMaxSize (e, vec3_origin, vec3_origin, true); +} + +/* +================= +PF_bprint + +broadcast print to everyone on server + +bprint(value) +================= +*/ +void PF_bprint (void) +{ + char *s; + + s = PF_VarString(0); + SV_BroadcastPrintf ("%s", s); +} + +/* +================= +PF_sprint + +single print to a specific client + +sprint(clientent, value) +================= +*/ +void PF_sprint (void) +{ + char *s; + client_t *client; + 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 ); +} + + +/* +================= +PF_centerprint + +single print to a specific client + +centerprint(clientent, value) +================= +*/ +void PF_centerprint (void) +{ + char *s; + client_t *client; + 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 ); +} + + +/* +================= +PF_normalize + +vector normalize(vector) +================= +*/ +void PF_normalize (void) +{ + float *value1; + vec3_t newvalue; + float new; + + value1 = G_VECTOR(OFS_PARM0); + + new = value1[0] * value1[0] + value1[1] * value1[1] + value1[2]*value1[2]; + new = sqrt(new); + + if (new == 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; + } + + VectorCopy (newvalue, G_VECTOR(OFS_RETURN)); +} + +/* +================= +PF_vlen + +scalar vlen(vector) +================= +*/ +void PF_vlen (void) +{ + float *value1; + float new; + + 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; +} + +/* +================= +PF_vectoyaw + +float vectoyaw(vector) +================= +*/ +void PF_vectoyaw (void) +{ + float *value1; + float yaw; + + value1 = G_VECTOR(OFS_PARM0); + + if (value1[1] == 0 && value1[0] == 0) + yaw = 0; + else + { + yaw = (int) (atan2(value1[1], value1[0]) * 180 / M_PI); + if (yaw < 0) + yaw += 360; + } + + G_FLOAT(OFS_RETURN) = yaw; +} + + +/* +================= +PF_vectoangles + +vector vectoangles(vector) +================= +*/ +void PF_vectoangles (void) +{ + float *value1; + float forward; + float yaw, pitch; + + value1 = G_VECTOR(OFS_PARM0); + + if (value1[1] == 0 && value1[0] == 0) + { + yaw = 0; + if (value1[2] > 0) + pitch = 90; + else + pitch = 270; + } + else + { + yaw = (int) (atan2(value1[1], value1[0]) * 180 / M_PI); + if (yaw < 0) + yaw += 360; + + forward = sqrt (value1[0]*value1[0] + value1[1]*value1[1]); + pitch = (int) (atan2(value1[2], forward) * 180 / M_PI); + if (pitch < 0) + pitch += 360; + } + + G_FLOAT(OFS_RETURN+0) = pitch; + G_FLOAT(OFS_RETURN+1) = yaw; + G_FLOAT(OFS_RETURN+2) = 0; +} + +/* +================= +PF_Random + +Returns a number from 0<= num < 1 + +random() +================= +*/ +void PF_random (void) +{ + float num; + + num = (rand ()&0x7fff) / ((float)0x7fff); + + G_FLOAT(OFS_RETURN) = num; +} + +/* +================= +PF_particle + +particle(origin, color, count) +================= +*/ +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); + count = G_FLOAT(OFS_PARM3); + SV_StartParticle (org, dir, color, count); +} + + +/* +================= +PF_ambientsound + +================= +*/ +void PF_ambientsound (void) +{ + char **check; + char *samp; + float *pos; + float vol, attenuation; + int i, soundnum; + + 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)) + break; + + if (!*check) + { + Con_Printf ("no precache: %s\n", samp); + return; + } + +// 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]); + + MSG_WriteByte (&sv.signon, soundnum); + + MSG_WriteByte (&sv.signon, vol*255); + MSG_WriteByte (&sv.signon, attenuation*64); + +} + +/* +================= +PF_sound + +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. + +An attenuation of 0 will play full volume everywhere in the level. +Larger attenuations will drop off. + +================= +*/ +void PF_sound (void) +{ + char *sample; + int channel; + edict_t *entity; + 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); + + if (attenuation < 0 || attenuation > 4) + Sys_Error ("SV_StartSound: attenuation = %f", attenuation); + + if (channel < 0 || channel > 7) + Sys_Error ("SV_StartSound: channel = %i", channel); + + SV_StartSound (entity, channel, sample, volume, attenuation); +} + +/* +================= +PF_break + +break() +================= +*/ +void PF_break (void) +{ +Con_Printf ("break statement\n"); +*(int *)-4 = 0; // dump to debugger +// PR_RunError ("break statement"); +} + +/* +================= +PF_traceline + +Used for use tracing and shot targeting +Traces are blocked by bbox and exact bsp entityes, and also slide box entities +if the tryents flag is set. + +traceline (vector1, vector2, tryents) +================= +*/ +void PF_traceline (void) +{ + float *v1, *v2; + trace_t trace; + int nomonsters; + edict_t *ent; + + v1 = G_VECTOR(OFS_PARM0); + v2 = G_VECTOR(OFS_PARM1); + 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; + + ent = G_EDICT(OFS_PARM0); + ignore = G_EDICT(OFS_PARM1); + + trace = SV_Trace_Toss (ent, ignore); + + 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); +} +#endif + + +/* +================= +PF_checkpos + +Returns true if the given entity can move to the given position from it's +current position by walking or rolling. +FIXME: make work... +scalar checkpos (entity, vector) +================= +*/ +void PF_checkpos (void) +{ +} + +//============================================================================ + +byte checkpvs[MAX_MAP_LEAFS/8]; + +int PF_newcheckclient (int check) +{ + int i; + byte *pvs; + edict_t *ent; + mleaf_t *leaf; + vec3_t org; + +// cycle to the next one + + if (check < 1) + check = 1; + if (check > svs.maxclients) + check = svs.maxclients; + + if (check == svs.maxclients) + i = 1; + else + i = check + 1; + + for ( ; ; i++) + { + if (i == svs.maxclients+1) + i = 1; + + ent = EDICT_NUM(i); + + if (i == check) + break; // didn't find anything else + + if (ent->free) + continue; + if (ent->v.health <= 0) + continue; + if ((int)ent->v.flags & FL_NOTARGET) + continue; + + // anything that is a client, or has a client as an enemy + break; + } + +// get the PVS for the entity + 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 ); + + return i; +} + +/* +================= +PF_checkclient + +Returns a client (or object that has a client enemy) that would be a +valid target. + +If there are more than one valid options, they are cycled each frame + +If (self.origin + self.viewofs) is not in the PVS of the current target, +it is not returned at all. + +name checkclient () +================= +*/ +#define MAX_CHECK 16 +int c_invis, c_notvis; +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) + { + sv.lastcheck = PF_newcheckclient (sv.lastcheck); + sv.lastchecktime = sv.time; + } + +// return check if it might be visible + ent = EDICT_NUM(sv.lastcheck); + if (ent->free || ent->v.health <= 0) + { + RETURN_EDICT(sv.edicts); + return; + } + +// if current entity can't possibly see the check entity, return 0 + self = PROG_TO_EDICT(pr_global_struct->self); + 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)) ) ) + { +c_notvis++; + RETURN_EDICT(sv.edicts); + return; + } + +// might be able to see it +c_invis++; + RETURN_EDICT(ent); +} + +//============================================================================ + + +/* +================= +PF_stuffcmd + +Sends text over to the client's execution buffer + +stuffcmd (clientent, value) +================= +*/ +void PF_stuffcmd (void) +{ + int entnum; + 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); + + old = host_client; + host_client = &svs.clients[entnum-1]; + Host_ClientCommands ("%s", str); + host_client = old; +} + +/* +================= +PF_localcmd + +Sends text over to the client's execution buffer + +localcmd (string) +================= +*/ +void PF_localcmd (void) +{ + char *str; + + str = G_STRING(OFS_PARM0); + Cbuf_AddText (str); +} + +/* +================= +PF_cvar + +float cvar (string) +================= +*/ +void PF_cvar (void) +{ + char *str; + + str = G_STRING(OFS_PARM0); + + G_FLOAT(OFS_RETURN) = Cvar_VariableValue (str); +} + +/* +================= +PF_cvar_set + +float cvar (string) +================= +*/ +void PF_cvar_set (void) +{ + char *var, *val; + + var = G_STRING(OFS_PARM0); + val = G_STRING(OFS_PARM1); + + Cvar_Set (var, val); +} + +/* +================= +PF_findradius + +Returns a chain of entities that have origins within a spherical area + +findradius (origin, radius) +================= +*/ +void PF_findradius (void) +{ + edict_t *ent, *chain; + float rad; + float *org; + vec3_t eorg; + 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) + continue; + + ent->v.chain = EDICT_TO_PROG(chain); + chain = ent; + } + + RETURN_EDICT(chain); +} + + +/* +========= +PF_dprint +========= +*/ +void PF_dprint (void) +{ + Con_DPrintf ("%s",PF_VarString(0)); +} + +char pr_string_temp[128]; + +void PF_ftos (void) +{ + float v; + v = G_FLOAT(OFS_PARM0); + + if (v == (int)v) + sprintf (pr_string_temp, "%d",(int)v); + else + sprintf (pr_string_temp, "%5.1f",v); + G_INT(OFS_RETURN) = pr_string_temp - pr_strings; +} + +void PF_fabs (void) +{ + float v; + v = G_FLOAT(OFS_PARM0); + G_FLOAT(OFS_RETURN) = fabs(v); +} + +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_string_temp - pr_strings; +} + +#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; +} +#endif + +void PF_Spawn (void) +{ + edict_t *ed; + ed = ED_Alloc(); + RETURN_EDICT(ed); +} + +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 +{ + int e; + int f; + 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); + if (ed->free) + continue; + t = E_STRING(ed,f); + if (!t) + continue; + if (!strcmp(t,s)) + { + RETURN_EDICT(ed); + return; + } + } + + RETURN_EDICT(sv.edicts); +} +#endif + +void PR_CheckEmptyString (char *s) +{ + if (s[0] <= ' ') + PR_RunError ("Bad string"); +} + +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) +{ + 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; + 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; +} + +/* +=============== +PF_droptofloor + +void() droptofloor +=============== +*/ +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) + G_FLOAT(OFS_RETURN) = 0; + else + { + VectorCopy (trace.endpos, ent->v.origin); + SV_LinkEdict (ent, false); + ent->v.flags = (int)ent->v.flags | FL_ONGROUND; + ent->v.groundentity = EDICT_TO_PROG(trace.ent); + G_FLOAT(OFS_RETURN) = 1; + } +} + +/* +=============== +PF_lightstyle + +void(float style, string value) lightstyle +=============== +*/ +void PF_lightstyle (void) +{ + int style; + char *val; + client_t *client; + int j; + + style = G_FLOAT(OFS_PARM0); + val = G_STRING(OFS_PARM1); + +// 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_WriteString (&client->message, val); + } +} + +void PF_rint (void) +{ + float f; + f = G_FLOAT(OFS_PARM0); + if (f > 0) + G_FLOAT(OFS_RETURN) = (int)(f + 0.5); + else + G_FLOAT(OFS_RETURN) = (int)(f - 0.5); +} +void PF_floor (void) +{ + G_FLOAT(OFS_RETURN) = floor(G_FLOAT(OFS_PARM0)); +} +void PF_ceil (void) +{ + G_FLOAT(OFS_RETURN) = ceil(G_FLOAT(OFS_PARM0)); +} + + +/* +============= +PF_checkbottom +============= +*/ +void PF_checkbottom (void) +{ + edict_t *ent; + + ent = G_EDICT(OFS_PARM0); + + G_FLOAT(OFS_RETURN) = SV_CheckBottom (ent); +} + +/* +============= +PF_pointcontents +============= +*/ +void PF_pointcontents (void) +{ + float *v; + + v = G_VECTOR(OFS_PARM0); + + G_FLOAT(OFS_RETURN) = SV_PointContents (v); +} + +/* +============= +PF_nextent + +entity nextent(entity) +============= +*/ +void PF_nextent (void) +{ + int i; + edict_t *ent; + + i = G_EDICTNUM(OFS_PARM0); + while (1) + { + i++; + if (i == sv.num_edicts) + { + RETURN_EDICT(sv.edicts); + return; + } + ent = EDICT_NUM(i); + if (!ent->free) + { + RETURN_EDICT(ent); + return; + } + } +} + +/* +============= +PF_aim + +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) +{ + edict_t *ent, *check, *bestent; + vec3_t start, dir, end, bestdir; + int i, j; + trace_t tr; + float dist, bestdist; + float speed; + + ent = G_EDICT(OFS_PARM0); + speed = G_FLOAT(OFS_PARM1); + + VectorCopy (ent->v.origin, start); + start[2] += 20; + +// try sending a trace straight + VectorCopy (pr_global_struct->v_forward, dir); + 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) ) + { + 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; + if (check == ent) + 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]); + VectorSubtract (end, start, dir); + VectorNormalize (dir); + dist = DotProduct (dir, pr_global_struct->v_forward); + if (dist < bestdist) + continue; // to far to turn + tr = SV_Move (start, vec3_origin, vec3_origin, end, false, ent); + if (tr.ent == check) + { // can shoot at this one + bestdist = dist; + bestent = check; + } + } + + if (bestent) + { + VectorSubtract (bestent->v.origin, ent->v.origin, dir); + dist = DotProduct (dir, pr_global_struct->v_forward); + VectorScale (pr_global_struct->v_forward, dist, end); + end[2] = dir[2]; + VectorNormalize (end); + VectorCopy (end, G_VECTOR(OFS_RETURN)); + } + else + { + VectorCopy (bestdir, G_VECTOR(OFS_RETURN)); + } +} + +/* +============== +PF_changeyaw + +This was a major timewaster in progs, so it was converted to C +============== +*/ +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; + 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[0] = anglemod (current + move); +} +#endif + +/* +=============================================================================== + +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) +{ + int entnum; + int dest; + edict_t *ent; + + dest = G_FLOAT(OFS_PARM0); + switch (dest) + { + 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; + + default: + PR_RunError ("WriteDest: bad destination"); + break; + } + + return NULL; +} + +void PF_WriteByte (void) +{ + MSG_WriteByte (WriteDest(), G_FLOAT(OFS_PARM1)); +} + +void PF_WriteChar (void) +{ + MSG_WriteChar (WriteDest(), G_FLOAT(OFS_PARM1)); +} + +void PF_WriteShort (void) +{ + MSG_WriteShort (WriteDest(), G_FLOAT(OFS_PARM1)); +} + +void PF_WriteLong (void) +{ + MSG_WriteLong (WriteDest(), G_FLOAT(OFS_PARM1)); +} + +void PF_WriteAngle (void) +{ + MSG_WriteAngle (WriteDest(), G_FLOAT(OFS_PARM1)); +} + +void PF_WriteCoord (void) +{ + MSG_WriteCoord (WriteDest(), G_FLOAT(OFS_PARM1)); +} + +void PF_WriteString (void) +{ + MSG_WriteString (WriteDest(), G_STRING(OFS_PARM1)); +} + + +void PF_WriteEntity (void) +{ + MSG_WriteShort (WriteDest(), G_EDICTNUM(OFS_PARM1)); +} + +//============================================================================= + +int SV_ModelIndex (char *name); + +void PF_makestatic (void) +{ + edict_t *ent; + int i; + + ent = G_EDICT(OFS_PARM0); + + MSG_WriteByte (&sv.signon,svc_spawnstatic); + + MSG_WriteByte (&sv.signon, SV_ModelIndex(pr_strings + ent->v.model)); + + 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++) + { + MSG_WriteCoord(&sv.signon, ent->v.origin[i]); + MSG_WriteAngle(&sv.signon, ent->v.angles[i]); + } + +// throw the entity away now + ED_Free (ent); +} + +//============================================================================= + +/* +============== +PF_setspawnparms +============== +*/ +void PF_setspawnparms (void) +{ + edict_t *ent; + int i; + client_t *client; + + ent = G_EDICT(OFS_PARM0); + i = NUM_FOR_EDICT(ent); + if (i < 1 || i > svs.maxclients) + PR_RunError ("Entity is not a client"); + + // copy spawn parms out of the client_t + client = svs.clients + (i-1); + + for (i=0 ; i< NUM_SPAWN_PARMS ; i++) + (&pr_global_struct->parm1)[i] = client->spawn_parms[i]; +} + +/* +============== +PF_changelevel +============== +*/ +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; + +// 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 +}; + +builtin_t *pr_builtins = pr_builtin; +int pr_numbuiltins = sizeof(pr_builtin)/sizeof(pr_builtin[0]); + diff --git a/contrib/other/sdlquake-1.0.9/pr_comp.h b/contrib/other/sdlquake-1.0.9/pr_comp.h new file mode 100644 index 000000000..b237ed5f2 --- /dev/null +++ b/contrib/other/sdlquake-1.0.9/pr_comp.h @@ -0,0 +1,180 @@ +/* +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. + +*/ + +// 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; + + +#define OFS_NULL 0 +#define OFS_RETURN 1 +#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 +#define OFS_PARM4 16 +#define OFS_PARM5 19 +#define OFS_PARM6 22 +#define OFS_PARM7 25 +#define RESERVED_OFS 28 + + +enum { + OP_DONE, + OP_MUL_F, + OP_MUL_V, + OP_MUL_FV, + OP_MUL_VF, + OP_DIV_F, + OP_ADD_F, + 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, + OP_GT, + + OP_LOAD_F, + OP_LOAD_V, + OP_LOAD_S, + OP_LOAD_ENT, + OP_LOAD_FLD, + OP_LOAD_FNC, + + OP_ADDRESS, + + OP_STORE_F, + OP_STORE_V, + OP_STORE_S, + OP_STORE_ENT, + OP_STORE_FLD, + OP_STORE_FNC, + + OP_STOREP_F, + OP_STOREP_V, + OP_STOREP_S, + OP_STOREP_ENT, + OP_STOREP_FLD, + OP_STOREP_FNC, + + OP_RETURN, + OP_NOT_F, + OP_NOT_V, + OP_NOT_S, + OP_NOT_ENT, + OP_NOT_FNC, + OP_IF, + OP_IFNOT, + OP_CALL0, + OP_CALL1, + OP_CALL2, + OP_CALL3, + OP_CALL4, + OP_CALL5, + OP_CALL6, + OP_CALL7, + OP_CALL8, + OP_STATE, + OP_GOTO, + OP_AND, + OP_OR, + + OP_BITAND, + OP_BITOR +}; + + +typedef struct statement_s +{ + unsigned short op; + 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 ofs; + int s_name; +} ddef_t; +#define DEF_SAVEGLOBAL (1<<15) + +#define MAX_PARMS 8 + +typedef struct +{ + int first_statement; // negative numbers are builtins + int parm_start; + 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; + + +#define PROG_VERSION 6 +typedef struct +{ + int version; + 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 ofs_globals; + int numglobals; + + int entityfields; +} dprograms_t; + diff --git a/contrib/other/sdlquake-1.0.9/pr_edict.c b/contrib/other/sdlquake-1.0.9/pr_edict.c new file mode 100644 index 000000000..544e01a15 --- /dev/null +++ b/contrib/other/sdlquake-1.0.9/pr_edict.c @@ -0,0 +1,1106 @@ +/* +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. + +*/ +// sv_edict.c -- entity dictionary + +#include "quakedef.h" + +dprograms_t *progs; +dfunction_t *pr_functions; +char *pr_strings; +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; + +int type_size[8] = {1,sizeof(string_t)/4,1,3,1,1,sizeof(func_t)/4,sizeof(void *)/4}; + +ddef_t *ED_FieldAtOfs (int ofs); +qboolean ED_ParseEpair (void *base, ddef_t *key, char *s); + +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}; + +#define MAX_FIELD_LEN 64 +#define GEFV_CACHESIZE 2 + +typedef struct { + ddef_t *pcache; + char field[MAX_FIELD_LEN]; +} gefv_cache; + +static gefv_cache gefvCache[GEFV_CACHESIZE] = {{NULL, ""}, {NULL, ""}}; + +/* +================= +ED_ClearEdict + +Sets everything to NULL +================= +*/ +void ED_ClearEdict (edict_t *e) +{ + memset (&e->v, 0, progs->entityfields * 4); + e->free = false; +} + +/* +================= +ED_Alloc + +Either finds a free edict, or allocates a new one. +Try to avoid reusing an entity that was recently freed, because it +can cause the client to think the entity morphed into something else +instead of being removed and recreated, which can cause interpolated +angles and bad trails. +================= +*/ +edict_t *ED_Alloc (void) +{ + int i; + edict_t *e; + + for ( i=svs.maxclients+1 ; ifree && ( e->freetime < 2 || sv.time - e->freetime > 0.5 ) ) + { + ED_ClearEdict (e); + return e; + } + } + + if (i == MAX_EDICTS) + Sys_Error ("ED_Alloc: no free edicts"); + + sv.num_edicts++; + e = EDICT_NUM(i); + ED_ClearEdict (e); + + return e; +} + +/* +================= +ED_Free + +Marks the edict as free +FIXME: walk all entities and NULL out references to this entity +================= +*/ +void ED_Free (edict_t *ed) +{ + SV_UnlinkEdict (ed); // unlink from world bsp + + ed->free = true; + ed->v.model = 0; + ed->v.takedamage = 0; + ed->v.modelindex = 0; + ed->v.colormap = 0; + ed->v.skin = 0; + ed->v.frame = 0; + VectorCopy (vec3_origin, ed->v.origin); + VectorCopy (vec3_origin, ed->v.angles); + ed->v.nextthink = -1; + ed->v.solid = 0; + + ed->freetime = sv.time; +} + +//=========================================================================== + +/* +============ +ED_GlobalAtOfs +============ +*/ +ddef_t *ED_GlobalAtOfs (int ofs) +{ + ddef_t *def; + int i; + + for (i=0 ; inumglobaldefs ; i++) + { + def = &pr_globaldefs[i]; + if (def->ofs == ofs) + return def; + } + return NULL; +} + +/* +============ +ED_FieldAtOfs +============ +*/ +ddef_t *ED_FieldAtOfs (int ofs) +{ + ddef_t *def; + int i; + + for (i=0 ; inumfielddefs ; i++) + { + def = &pr_fielddefs[i]; + if (def->ofs == ofs) + return def; + } + return NULL; +} + +/* +============ +ED_FindField +============ +*/ +ddef_t *ED_FindField (char *name) +{ + ddef_t *def; + int i; + + for (i=0 ; inumfielddefs ; i++) + { + def = &pr_fielddefs[i]; + if (!strcmp(pr_strings + def->s_name,name) ) + return def; + } + return NULL; +} + + +/* +============ +ED_FindGlobal +============ +*/ +ddef_t *ED_FindGlobal (char *name) +{ + ddef_t *def; + int i; + + for (i=0 ; inumglobaldefs ; i++) + { + def = &pr_globaldefs[i]; + if (!strcmp(pr_strings + def->s_name,name) ) + return def; + } + return NULL; +} + + +/* +============ +ED_FindFunction +============ +*/ +dfunction_t *ED_FindFunction (char *name) +{ + dfunction_t *func; + int i; + + for (i=0 ; inumfunctions ; i++) + { + func = &pr_functions[i]; + if (!strcmp(pr_strings + func->s_name,name) ) + return func; + } + return NULL; +} + + +eval_t *GetEdictFieldValue(edict_t *ed, char *field) +{ + ddef_t *def = NULL; + int i; + static int rep = 0; + + for (i=0 ; iv + def->ofs*4); +} + + +/* +============ +PR_ValueString + +Returns a string describing *data in a type specific manner +============= +*/ +char *PR_ValueString (etype_t type, eval_t *val) +{ + static char line[256]; + ddef_t *def; + dfunction_t *f; + + type &= ~DEF_SAVEGLOBAL; + + switch (type) + { + case ev_string: + sprintf (line, "%s", pr_strings + val->string); + break; + case ev_entity: + sprintf (line, "entity %i", NUM_FOR_EDICT(PROG_TO_EDICT(val->edict)) ); + break; + case ev_function: + f = pr_functions + val->function; + sprintf (line, "%s()", pr_strings + f->s_name); + break; + case ev_field: + def = ED_FieldAtOfs ( val->_int ); + sprintf (line, ".%s", pr_strings + def->s_name); + break; + case ev_void: + sprintf (line, "void"); + break; + case ev_float: + sprintf (line, "%5.1f", val->_float); + break; + case ev_vector: + sprintf (line, "'%5.1f %5.1f %5.1f'", val->vector[0], val->vector[1], val->vector[2]); + break; + case ev_pointer: + sprintf (line, "pointer"); + break; + default: + sprintf (line, "bad type %i", type); + break; + } + + return line; +} + +/* +============ +PR_UglyValueString + +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 char line[256]; + ddef_t *def; + dfunction_t *f; + + type &= ~DEF_SAVEGLOBAL; + + switch (type) + { + case ev_string: + sprintf (line, "%s", pr_strings + val->string); + break; + case ev_entity: + sprintf (line, "%i", NUM_FOR_EDICT(PROG_TO_EDICT(val->edict))); + break; + case ev_function: + f = pr_functions + val->function; + sprintf (line, "%s", pr_strings + f->s_name); + break; + case ev_field: + def = ED_FieldAtOfs ( val->_int ); + sprintf (line, "%s", pr_strings + def->s_name); + break; + case ev_void: + sprintf (line, "void"); + break; + case ev_float: + sprintf (line, "%f", val->_float); + break; + case ev_vector: + sprintf (line, "%f %f %f", val->vector[0], val->vector[1], val->vector[2]); + break; + default: + sprintf (line, "bad type %i", type); + break; + } + + return line; +} + +/* +============ +PR_GlobalString + +Returns a string with a description and the contents of a global, +padded to 20 field width +============ +*/ +char *PR_GlobalString (int ofs) +{ + char *s; + int i; + ddef_t *def; + void *val; + static char line[128]; + + val = (void *)&pr_globals[ofs]; + def = ED_GlobalAtOfs(ofs); + if (!def) + sprintf (line,"%i(???)", ofs); + else + { + s = PR_ValueString (def->type, val); + sprintf (line,"%i(%s)%s", ofs, pr_strings + def->s_name, s); + } + + i = strlen(line); + for ( ; i<20 ; i++) + strcat (line," "); + strcat (line," "); + + return line; +} + +char *PR_GlobalStringNoContents (int ofs) +{ + int i; + ddef_t *def; + static char line[128]; + + def = ED_GlobalAtOfs(ofs); + if (!def) + sprintf (line,"%i(???)", ofs); + else + sprintf (line,"%i(%s)", ofs, pr_strings + def->s_name); + + i = strlen(line); + for ( ; i<20 ; i++) + strcat (line," "); + strcat (line," "); + + return line; +} + + +/* +============= +ED_Print + +For debugging +============= +*/ +void ED_Print (edict_t *ed) +{ + int l; + ddef_t *d; + int *v; + int i, j; + char *name; + int type; + + if (ed->free) + { + Con_Printf ("FREE\n"); + return; + } + + Con_Printf("\nEDICT %i:\n", NUM_FOR_EDICT(ed)); + for (i=1 ; inumfielddefs ; i++) + { + d = &pr_fielddefs[i]; + name = pr_strings + d->s_name; + if (name[strlen(name)-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)); + } +} + +/* +============= +ED_Write + +For savegames +============= +*/ +void ED_Write (FILE *f, edict_t *ed) +{ + ddef_t *d; + int *v; + int i, j; + char *name; + int type; + + fprintf (f, "{\n"); + + if (ed->free) + { + fprintf (f, "}\n"); + return; + } + + for (i=1 ; inumfielddefs ; i++) + { + d = &pr_fielddefs[i]; + name = pr_strings + d->s_name; + if (name[strlen(name)-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, "}\n"); +} + +void ED_PrintNum (int ent) +{ + ED_Print (EDICT_NUM(ent)); +} + +/* +============= +ED_PrintEdicts + +For debugging, prints all the entities in the current server +============= +*/ +void ED_PrintEdicts (void) +{ + int i; + + Con_Printf ("%i entities\n", sv.num_edicts); + for (i=0 ; i= sv.num_edicts) + { + Con_Printf("Bad edict number\n"); + return; + } + ED_PrintNum (i); +} + +/* +============= +ED_Count + +For debugging +============= +*/ +void ED_Count (void) +{ + int i; + edict_t *ent; + int active, models, solid, step; + + active = models = solid = step = 0; + for (i=0 ; ifree) + continue; + active++; + if (ent->v.solid) + solid++; + if (ent->v.model) + models++; + if (ent->v.movetype == MOVETYPE_STEP) + step++; + } + + Con_Printf ("num_edicts:%3i\n", sv.num_edicts); + Con_Printf ("active :%3i\n", active); + Con_Printf ("view :%3i\n", models); + Con_Printf ("touch :%3i\n", solid); + Con_Printf ("step :%3i\n", step); + +} + +/* +============================================================================== + + ARCHIVING GLOBALS + +FIXME: need to tag constants, doesn't really work +============================================================================== +*/ + +/* +============= +ED_WriteGlobals +============= +*/ +void ED_WriteGlobals (FILE *f) +{ + ddef_t *def; + int i; + char *name; + int type; + + fprintf (f,"{\n"); + for (i=0 ; inumglobaldefs ; i++) + { + def = &pr_globaldefs[i]; + type = def->type; + if ( !(def->type & DEF_SAVEGLOBAL) ) + continue; + type &= ~DEF_SAVEGLOBAL; + + if (type != ev_string + && type != ev_float + && type != ev_entity) + continue; + + name = pr_strings + def->s_name; + fprintf (f,"\"%s\" ", name); + fprintf (f,"\"%s\"\n", PR_UglyValueString(type, (eval_t *)&pr_globals[def->ofs])); + } + fprintf (f,"}\n"); +} + +/* +============= +ED_ParseGlobals +============= +*/ +void ED_ParseGlobals (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"); + + strcpy (keyname, com_token); + + // parse value + data = COM_Parse (data); + if (!data) + Sys_Error ("ED_ParseEntity: EOF without closing brace"); + + if (com_token[0] == '}') + Sys_Error ("ED_ParseEntity: closing brace without data"); + + key = ED_FindGlobal (keyname); + if (!key) + { + Con_Printf ("'%s' is not a global\n", keyname); + continue; + } + + if (!ED_ParseEpair ((void *)pr_globals, key, com_token)) + Host_Error ("ED_ParseGlobals: parse error"); + } +} + +//============================================================================ + + +/* +============= +ED_NewString +============= +*/ +char *ED_NewString (char *string) +{ + char *new, *new_p; + int i,l; + + l = strlen(string) + 1; + new = Hunk_Alloc (l); + new_p = new; + + for (i=0 ; i< l ; i++) + { + if (string[i] == '\\' && i < l-1) + { + i++; + if (string[i] == 'n') + *new_p++ = '\n'; + else + *new_p++ = '\\'; + } + else + *new_p++ = string[i]; + } + + return new; +} + + +/* +============= +ED_ParseEval + +Can parse either fields or globals +returns false if error +============= +*/ +qboolean ED_ParseEpair (void *base, ddef_t *key, char *s) +{ + int i; + char string[128]; + ddef_t *def; + char *v, *w; + 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) - pr_strings; + break; + + case ev_float: + *(float *)d = atof (s); + break; + + case ev_vector: + strcpy (string, s); + v = string; + w = string; + for (i=0 ; i<3 ; i++) + { + while (*v && *v != ' ') + v++; + *v = 0; + ((float *)d)[i] = atof (w); + w = v = v+1; + } + 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); + return false; + } + *(int *)d = G_INT(def->ofs); + break; + + case ev_function: + func = ED_FindFunction (s); + if (!func) + { + Con_Printf ("Can't find function %s\n", s); + return false; + } + *(func_t *)d = func - pr_functions; + break; + + default: + break; + } + return true; +} + +/* +==================== +ED_ParseEdict + +Parses an edict out of the given string, returning the new position +ed should be a properly initialized empty edict. +Used for initial level load and for savegames. +==================== +*/ +char *ED_ParseEdict (char *data, edict_t *ent) +{ + ddef_t *key; + qboolean anglehack; + qboolean init; + char keyname[256]; + int n; + + init = false; + +// clear it + if (ent != sv.edicts) // hack + memset (&ent->v, 0, progs->entityfields * 4); + +// go through all the dictionary pairs + while (1) + { + // 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; + +// 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); + + // another hack to fix heynames with trailing spaces + n = strlen(keyname); + while (n && keyname[n-1] == ' ') + { + keyname[n-1] = 0; + n--; + } + + // parse value + data = COM_Parse (data); + if (!data) + Sys_Error ("ED_ParseEntity: EOF without closing brace"); + + if (com_token[0] == '}') + Sys_Error ("ED_ParseEntity: closing brace without data"); + + init = true; + +// keynames with a leading underscore are used for utility comments, +// and are immediately discarded by quake + if (keyname[0] == '_') + continue; + + key = ED_FindField (keyname); + if (!key) + { + Con_Printf ("'%s' is not a field\n", keyname); + continue; + } + +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"); + } + + if (!init) + ent->free = true; + + return data; +} + + +/* +================ +ED_LoadFromFile + +The entities are directly placed in the array, rather than allocated with +ED_Alloc, because otherwise an error loading the map would have entity +number references out of order. + +Creates a server's entity / program execution context by +parsing textual entity definitions out of an ent file. + +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; + dfunction_t *func; + + ent = NULL; + inhibit = 0; + pr_global_struct->time = sv.time; + +// parse ents + while (1) + { +// 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); + + if (!ent) + ent = EDICT_NUM(0); + else + ent = ED_Alloc (); + data = ED_ParseEdict (data, ent); + +// remove things from different skill levels or deathmatch + if (deathmatch.value) + { + if (((int)ent->v.spawnflags & SPAWNFLAG_NOT_DEATHMATCH)) + { + ED_Free (ent); + inhibit++; + continue; + } + } + else if ((current_skill == 0 && ((int)ent->v.spawnflags & SPAWNFLAG_NOT_EASY)) + || (current_skill == 1 && ((int)ent->v.spawnflags & SPAWNFLAG_NOT_MEDIUM)) + || (current_skill >= 2 && ((int)ent->v.spawnflags & SPAWNFLAG_NOT_HARD)) ) + { + ED_Free (ent); + inhibit++; + continue; + } + +// +// immediately call spawn function +// + if (!ent->v.classname) + { + Con_Printf ("No classname for:\n"); + ED_Print (ent); + ED_Free (ent); + continue; + } + + // look for the spawn function + func = ED_FindFunction ( pr_strings + ent->v.classname ); + + if (!func) + { + Con_Printf ("No spawn function for:\n"); + ED_Print (ent); + ED_Free (ent); + continue; + } + + pr_global_struct->self = EDICT_TO_PROG(ent); + PR_ExecuteProgram (func - pr_functions); + } + + Con_DPrintf ("%i entities inhibited\n", inhibit); +} + + +/* +=============== +PR_LoadProgs +=============== +*/ +void PR_LoadProgs (void) +{ + 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); + if (progs->crc != PROGHEADER_CRC) + Sys_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; + pr_globaldefs = (ddef_t *)((byte *)progs + progs->ofs_globaldefs); + pr_fielddefs = (ddef_t *)((byte *)progs + progs->ofs_fielddefs); + pr_statements = (dstatement_t *)((byte *)progs + progs->ofs_statements); + + 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); + +// byte swap the lumps + for (i=0 ; inumstatements ; i++) + { + pr_statements[i].op = LittleShort(pr_statements[i].op); + pr_statements[i].a = LittleShort(pr_statements[i].a); + pr_statements[i].b = LittleShort(pr_statements[i].b); + pr_statements[i].c = LittleShort(pr_statements[i].c); + } + + for (i=0 ; inumfunctions; 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_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_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"); + pr_fielddefs[i].ofs = LittleShort (pr_fielddefs[i].ofs); + pr_fielddefs[i].s_name = LittleLong (pr_fielddefs[i].s_name); + } + + for (i=0 ; inumglobals ; i++) + ((int *)pr_globals)[i] = LittleLong (((int *)pr_globals)[i]); +} + + +/* +=============== +PR_Init +=============== +*/ +void PR_Init (void) +{ + Cmd_AddCommand ("edict", ED_PrintEdict_f); + Cmd_AddCommand ("edicts", ED_PrintEdicts); + Cmd_AddCommand ("edictcount", ED_Count); + Cmd_AddCommand ("profile", PR_Profile_f); + Cvar_RegisterVariable (&nomonsters); + Cvar_RegisterVariable (&gamecfg); + Cvar_RegisterVariable (&scratch1); + Cvar_RegisterVariable (&scratch2); + Cvar_RegisterVariable (&scratch3); + Cvar_RegisterVariable (&scratch4); + Cvar_RegisterVariable (&savedgamecfg); + Cvar_RegisterVariable (&saved1); + Cvar_RegisterVariable (&saved2); + Cvar_RegisterVariable (&saved3); + Cvar_RegisterVariable (&saved4); +} + + + +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); +} + +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"); + return b; +} diff --git a/contrib/other/sdlquake-1.0.9/pr_exec.c b/contrib/other/sdlquake-1.0.9/pr_exec.c new file mode 100644 index 000000000..4f2aa363e --- /dev/null +++ b/contrib/other/sdlquake-1.0.9/pr_exec.c @@ -0,0 +1,668 @@ +/* +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; + +#define MAX_STACK_DEPTH 32 +prstack_t pr_stack[MAX_STACK_DEPTH]; +int pr_depth; + +#define LOCALSTACK_SIZE 2048 +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_strings + f->s_file, pr_strings + 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_strings+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[st->a]; + b = (eval_t *)&pr_globals[st->b]; + c = (eval_t *)&pr_globals[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_strings[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_strings+a->string,pr_strings+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_strings+a->string,pr_strings+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/contrib/other/sdlquake-1.0.9/progdefs.h b/contrib/other/sdlquake-1.0.9/progdefs.h new file mode 100644 index 000000000..db86de156 --- /dev/null +++ b/contrib/other/sdlquake-1.0.9/progdefs.h @@ -0,0 +1,24 @@ +/* +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. + +*/ +#ifdef QUAKE2 +#include "progdefs.q2" +#else +#include "progdefs.q1" +#endif diff --git a/contrib/other/sdlquake-1.0.9/progdefs.q1 b/contrib/other/sdlquake-1.0.9/progdefs.q1 new file mode 100644 index 000000000..eb15c45c6 --- /dev/null +++ b/contrib/other/sdlquake-1.0.9/progdefs.q1 @@ -0,0 +1,143 @@ + +/* 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; + 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; + 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 punchangle; + string_t classname; + string_t model; + float frame; + float skin; + float effects; + 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 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; + 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; +} entvars_t; + +#define PROGHEADER_CRC 5927 diff --git a/contrib/other/sdlquake-1.0.9/progdefs.q2 b/contrib/other/sdlquake-1.0.9/progdefs.q2 new file mode 100644 index 000000000..dc7f3be9b --- /dev/null +++ b/contrib/other/sdlquake-1.0.9/progdefs.q2 @@ -0,0 +1,158 @@ + +/* 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/contrib/other/sdlquake-1.0.9/progs.h b/contrib/other/sdlquake-1.0.9/progs.h new file mode 100644 index 000000000..6d3aa8aca --- /dev/null +++ b/contrib/other/sdlquake-1.0.9/progs.h @@ -0,0 +1,134 @@ +/* +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 char *pr_strings; +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); + +void PR_Profile_f (void); + +edict_t *ED_Alloc (void); +void ED_Free (edict_t *ed); + +char *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_strings + *(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_strings + *(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/contrib/other/sdlquake-1.0.9/protocol.h b/contrib/other/sdlquake-1.0.9/protocol.h new file mode 100644 index 000000000..01780f89d --- /dev/null +++ b/contrib/other/sdlquake-1.0.9/protocol.h @@ -0,0 +1,167 @@ +/* +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 + +// +// 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/contrib/other/sdlquake-1.0.9/q.bat b/contrib/other/sdlquake-1.0.9/q.bat new file mode 100644 index 000000000..5726fcb09 --- /dev/null +++ b/contrib/other/sdlquake-1.0.9/q.bat @@ -0,0 +1 @@ +dos\quake -basedir /quake -game test_gjc %1 %2 %3 %4 %5 %6 %7 %8 %9 diff --git a/contrib/other/sdlquake-1.0.9/qa.bat b/contrib/other/sdlquake-1.0.9/qa.bat new file mode 100644 index 000000000..f6db109c6 --- /dev/null +++ b/contrib/other/sdlquake-1.0.9/qa.bat @@ -0,0 +1 @@ +dos\quake -nocdaudio -basedir /quake -game test_am %1 %2 %3 %4 %5 %6 %7 %8 %9 diff --git a/contrib/other/sdlquake-1.0.9/qb.bat b/contrib/other/sdlquake-1.0.9/qb.bat new file mode 100644 index 000000000..9eeb99d66 --- /dev/null +++ b/contrib/other/sdlquake-1.0.9/qb.bat @@ -0,0 +1 @@ +dos\quake /quake/test_gjc;/quake/id1 %1 %2 %3 %4 %5 %6 %7 %8 %9 diff --git a/contrib/other/sdlquake-1.0.9/qe3.ico b/contrib/other/sdlquake-1.0.9/qe3.ico new file mode 100644 index 000000000..35ee0d278 Binary files /dev/null and b/contrib/other/sdlquake-1.0.9/qe3.ico differ diff --git a/contrib/other/sdlquake-1.0.9/qt.bat b/contrib/other/sdlquake-1.0.9/qt.bat new file mode 100644 index 000000000..d42b93ce6 --- /dev/null +++ b/contrib/other/sdlquake-1.0.9/qt.bat @@ -0,0 +1 @@ +dos\quake /quake/test_am;/quake/test_jc;/quake/id1 %1 %2 %3 %4 %5 %6 %7 %8 %9 diff --git a/contrib/other/sdlquake-1.0.9/quake-data.spec.sh b/contrib/other/sdlquake-1.0.9/quake-data.spec.sh new file mode 100644 index 000000000..dd702e4f6 --- /dev/null +++ b/contrib/other/sdlquake-1.0.9/quake-data.spec.sh @@ -0,0 +1,60 @@ +#!/bin/sh +# Generate quake-data.spec +# $1 is version +# $2 is release +# $3 is install dir (assumed to be in /var/tmp) +cat < +URL: http://www.idsoftware.com/ +Source: quake-data-%{version}.tar.gz +BuildArchitectures: noarch +Group: Games +Copyright: Restricted +Icon: quake.gif +BuildRoot: /var/tmp/%{name}-%{version} +Summary: Quake for Linux + +%description +"Quake is the biggest, baddest, and bloodiest 3-D action game ever +conceived" - PC GAMER + +"The most important PC game ever" - PC ZONE + +""Quake": Bloody Amazing" - USA TODAY + +"The Vanguard of a terrifying new level of immersive interactivity" - +COMPUTER GAMING WORLD + +From the creators of DOOM and DOOM II comes the most intense, technologically +advanced 3-D experience ever captured on CD ROM. Features free and fluid +motion, ambient sound and lighting, and unmatched multiplayer capabilities +(play with up to 15 others). + +This package contians the Quake data files needed to play the game. + +%install + +%files +%attr(644,root,root) $3/comexp.txt +%attr(644,root,root) $3/help.txt +%attr(644,root,root) $3/licinfo.txt +%attr(644,root,root) $3/manual.txt +%attr(644,root,root) $3/readme.txt +%attr(644,root,root) $3/rlicnse.txt +%attr(644,root,root) $3/techinfo.txt +%attr(644,root,root) $3/id1/pak0.pak +%attr(644,root,root) $3/id1/pak1.pak + +%post +/sbin/ldconfig + +EOF + diff --git a/contrib/other/sdlquake-1.0.9/quake-hipnotic.spec.sh b/contrib/other/sdlquake-1.0.9/quake-hipnotic.spec.sh new file mode 100644 index 000000000..b7b42ab72 --- /dev/null +++ b/contrib/other/sdlquake-1.0.9/quake-hipnotic.spec.sh @@ -0,0 +1,113 @@ +#!/bin/sh +# Generate quake-hipnotic.spec +# $1 is version +# $2 is release +# $3 is install dir (assumed to be in /var/tmp) +cat < +URL: http://www.ritual.com/ +Source: quake-hipnotic-%{version}.tar.gz +BuildArchitectures: noarch +Group: Games +Copyright: Restricted +Icon: quake.gif +BuildRoot: /var/tmp/%{name}-%{version} +Summary: Quake Hipnotic Mission Pack #1: Scourge of Armagon + +%description + +The Scourge of Armagon is the highly acclaimed mission pack for id Software's +Quake. Scourge offers 3 new episodes that continue off where Quake ended. Add +some incredible new effects such as rotating doors and objects, new creatures +to battle, and new weapons and powerups to assist you in these battles. + +Looking for a way to breath some new life into Quake? Get Mission Pack #1: +Scourge of Armagon. + +Here is a breakdown of exactly what you will get inside Scourge of Armagon: + +18 Beastly Levels +Strafe and slaughter your way through 18 levels contained in three +monster-infested episodes. Fight your way through the intense Military +Base and Research Facilities, sneak around in the Ancient Realm, and dash +into the final domain controlled by Armagon. You’ll also be able to tear +your friends apart in an all-new DeathMatch level: Edge of Oblivion. + +All-New Flesh-Ripping Demons +Gremlins: Small, blood-thirsty creatures that attack in swarms and can even +steal your weapons. Watch out or these little bastards will turn them back on +you! + +Centroids: Armor-plated scorpion cyborgs with two nail guns fused to their +monstrous bodies. These bad boy monsters can shred you to bits in just +seconds. + +Armagon: This is the father of all monsters. This huge metallic behemoth will +rock your world with rockets and laser fire, so be prepared to die. + +Never-Before-Seen Weapons +Mjolnir: When this war hammer pounds the floor, it fires an electrical force +along the ground, striking and shocking several enemies with its lethal +current. + +Laser Cannon: Disintegrate scores of creatures with scorching laser blasts. +Use the rebounding properties of this weapon to tag your enemies around +corners. + +Proximity Mines: Gameplay reaches new heights with motion sensitive mines. +Plant these nasty toys on walls, floors, or even the ceiling and watch as +unsuspecting foes are blown into little bits. + +Inventive New Powerups +Empathy Shield: This shield allows you to turn the table on those unwitting +opponents. Whatever damage you take they receive half of it back in kind. + +Horn of Conjuring: Blow this horn and out of the mystical bowels of eternity +a new ally will appear. This horn allows you to call upon any of the +creatures in the game to come to your aid in the fight against Armagon. + +Wet Suit: What better way to survive under water longer. Not only that, those +flippers help speed you along as you paddle your way through the dangers that +lucky deep under the surface of those calm waters. + +Environmental Dangers +Undertake atmospheric nightmares like lightning traps, floating spike mines, +gondolas, outdoor environments and stunning architecture never seen before in +Quake. Travel through the dangerous and treacherous mines under the Military +Base. Creep through the catacombs and dark cathedrals that lie in wait for +you in the Ancient Realms. Swallow your fear as you wind our way through the +immense fortress that protect the Lair of Armagon. + +System Requirements + +Full Version of QUAKE required to operate. +CD ROM drive required for Installation +Linux 2.0 +16 MB RAM +Hard Disk Space: 40 MB for Mission Pack +VGA & SVGA graphics support +Mouse support (3 Button Mouse recommended) +Supports IP (Internet) play + +%install + +%files +%attr(644,root,root) $3/hipnotic/pak0.pak +%attr(644,root,root) $3/hipnotic/config.cfg +%attr(644,root,root) $3/hipnotic/docs/manual.doc +%attr(644,root,root) $3/hipnotic/docs/manual.htm +%attr(644,root,root) $3/hipnotic/docs/manual.txt +%attr(644,root,root) $3/hipnotic/docs/readme.doc +%attr(644,root,root) $3/hipnotic/docs/readme.htm +%attr(644,root,root) $3/hipnotic/docs/readme.txt + +EOF + diff --git a/contrib/other/sdlquake-1.0.9/quake-rogue.spec.sh b/contrib/other/sdlquake-1.0.9/quake-rogue.spec.sh new file mode 100644 index 000000000..9f9c8a621 --- /dev/null +++ b/contrib/other/sdlquake-1.0.9/quake-rogue.spec.sh @@ -0,0 +1,108 @@ +#!/bin/sh +# Generate quake-rogue.spec +# $1 is version +# $2 is release +# $3 is install dir (assumed to be in /var/tmp) +cat < +URL: http://www.rogue-ent.com/ +Source: quake-rogue-%{version}.tar.gz +BuildArchitectures: noarch +Group: Games +Copyright: Restricted +Icon: quake.gif +BuildRoot: /var/tmp/%{name}-%{version} +Summary: Quake Rogue Mission Pack #2: Dissolution of Eternity + +%description + +16 entirely new, and totally intense levels! The environmental experience of +Quake is unparalleled. Dissolution of Eternity sustains the same dynamic +sense of reality and dramatic visuals; yet adds an impression of purpose +and continuity. This expansion pack is most definitely not a conglomeration +of clone levels! + +8 new monsters! Quake is solid, hard-hitting action with a host of evil +enemies. We've made additions to the Quake monster roster to intensify the +action and fill every dimly lit and evil corner of the game. + +4 new weapons! The Quake weapons are awesome, but we've pushed them beyond +that with the addition of extreme power-ups to make the arsenal more +effective, and more deadly. + +Oh yeah, the Power-Ups! + +Single player mode power-ups include: + +The Anti-Grav Belt. The theory here is simple. It counters the force of +gravity and allows the player to make difficult jumps. + +The Power Shield. This 'little gem' significantly decreases the damage you +receive from most enemy attacks. If you're feelin' frisky in Deathmatch, +try out the ram attack. It's an added 'weapon' to send your opponents flying. + +Deathmatch will introduce the player to: + +The Vengeance Sphere. We'd like you to experience it before we let you in on +what it does. Here's a hint: Ultimate retribution from the grave! + +Random Respawn. This feature will toss in a bit of Deathmatch variety. Hey, +we can't be responsible for what awesome power up 'pops up' next. + +Multi-player! + +Normal Deathmatch. Friend fraggin' action! +Team Play. Bring a friend, to kill a foe. +Tag. You played it as a kid, but nothin' says "Tag!" like a face full of +Plasma. + +And, a much enhanced version of Capture the Flag! +Capture the Flag. You've seen it on the Internet; now it's in your hands. +Additional value, additional excitement, and additional Deathmatch 'down and +dirty' devastation. CTF is one of the most exciting team multi-player +directions for Quake to date; and the most popular too! + +Including two brand new CTF features. + +One Flag - It's a mad race for the flag, the loser gets a rocket up his +privates. +Three Team - Red, Blue, and the new Rogue (pun intended) Grey team. The good +news? You can take either flag and bring to it either Red or Blue base. The +bad news? You don't have your own base! + +Also, a collection of lethal environmental hazards have been placed at every +turn. They are challenging, and terminal! Here are just a few of them. + +The Pendulums - Set to slice the player to shreds when he least expects it! +Lightning Shooters - Well, they shoot lightning and can be directed at any +angle to make some rooms extremely hazardous. +Lava Nail Shooters - Well, they shoot, you get the idea here! +Earthquakes - Earthshaking environments! Level areas that tremor with +seismic activity. Now the Quake player can literally quake! +Buzz Saws - Compact. Cordless. And completely gib-o-matic! These dreaded +traps are set in floors and ceilings. + +%install + +%files +%attr(644,root,root) $3/rogue/pak0.pak +%attr(644,root,root) $3/rogue/docs/manual.doc +%attr(644,root,root) $3/rogue/docs/manual.htm +%attr(644,root,root) $3/rogue/docs/manual.txt +%attr(644,root,root) $3/rogue/docs/readme.doc +%attr(644,root,root) $3/rogue/docs/readme.htm +%attr(644,root,root) $3/rogue/docs/readme.txt +%attr(644,root,root) $3/rogue/docs/ctf.doc +%attr(644,root,root) $3/rogue/docs/ctf.htm +%attr(644,root,root) $3/rogue/docs/ctf.txt + +EOF + diff --git a/contrib/other/sdlquake-1.0.9/quake-shareware.spec.sh b/contrib/other/sdlquake-1.0.9/quake-shareware.spec.sh new file mode 100644 index 000000000..3f3ff5725 --- /dev/null +++ b/contrib/other/sdlquake-1.0.9/quake-shareware.spec.sh @@ -0,0 +1,69 @@ +#!/bin/sh +# Generate quake-shareware.spec +# $1 is version +# $2 is release +# $3 is install dir (assumed to be in /var/tmp) +cat < +URL: http://www.idsoftware.com/ +Source: quake-%{version}.tar.gz +Group: Games +Copyright: Restricted +Icon: quake.gif +BuildRoot: /var/tmp/%{name}-%{version} +Summary: Quake for Linux + +%description +"Quake is the biggest, baddest, and bloodiest 3-D action game ever +conceived" - PC GAMER + +"The most important PC game ever" - PC ZONE + +""Quake": Bloody Amazing" - USA TODAY + +"The Vanguard of a terrifying new level of immersive interactivity" - +COMPUTER GAMING WORLD + +From the creators of DOOM and DOOM II comes the most intense, technologically +advanced 3-D experience ever captured on CD ROM. Features free and fluid +motion, ambient sound and lighting, and unmatched multiplayer capabilities +(play with up to 15 others). + +Included in this archive are several different versions of Quake. + +- SQuake for SVGALib Console Graphics +- GLQuake for 3DFX and other glX based hardware OpenGL +- Quake.X11 for running Quake under X11 + +%install + +%files +%attr(644,root,root) $3/README +%attr(4755,root,root) $3/squake +%attr(4755,root,root) $3/glquake +%attr(4755,root,root) $3/glquake.glx +%attr(4755,root,root) $3/glquake.3dfxgl +%attr(755,root,root) $3/quake.x11 +%attr(644,root,root) $3/help.txt +%attr(644,root,root) $3/licinfo.txt +%attr(644,root,root) $3/manual.txt +%attr(644,root,root) $3/readme.txt +%attr(644,root,root) $3/slicnse.txt +%attr(644,root,root) $3/techinfo.txt +%attr(644,root,root) $3/id1/pak0.pak +%attr(755,root,root) /usr/lib/lib3dfxgl.so +%attr(755,root,root) /usr/lib/libMesaGL.so.2.6 + +%post +/sbin/ldconfig + +EOF + diff --git a/contrib/other/sdlquake-1.0.9/quake.gif b/contrib/other/sdlquake-1.0.9/quake.gif new file mode 100644 index 000000000..a16ca00a2 Binary files /dev/null and b/contrib/other/sdlquake-1.0.9/quake.gif differ diff --git a/contrib/other/sdlquake-1.0.9/quake.ico b/contrib/other/sdlquake-1.0.9/quake.ico new file mode 100644 index 000000000..507c87d21 Binary files /dev/null and b/contrib/other/sdlquake-1.0.9/quake.ico differ diff --git a/contrib/other/sdlquake-1.0.9/quake.spec.sh b/contrib/other/sdlquake-1.0.9/quake.spec.sh new file mode 100644 index 000000000..c96879348 --- /dev/null +++ b/contrib/other/sdlquake-1.0.9/quake.spec.sh @@ -0,0 +1,61 @@ +#!/bin/sh +# Generate quake.spec +# $1 is version +# $2 is release +# $3 is install dir (assumed to be in /var/tmp) +cat < +URL: http://www.idsoftware.com/ +Source: quake-%{version}.tar.gz +Group: Games +Copyright: Restricted +Icon: quake.gif +BuildRoot: /var/tmp/%{name}-%{version} +Summary: Quake for Linux + +%description +"Quake is the biggest, baddest, and bloodiest 3-D action game ever +conceived" - PC GAMER + +"The most important PC game ever" - PC ZONE + +""Quake": Bloody Amazing" - USA TODAY + +"The Vanguard of a terrifying new level of immersive interactivity" - +COMPUTER GAMING WORLD + +From the creators of DOOM and DOOM II comes the most intense, technologically +advanced 3-D experience ever captured on CD ROM. Features free and fluid +motion, ambient sound and lighting, and unmatched multiplayer capabilities +(play with up to 15 others). + +Included in this archive are several different versions of Quake. + +- SQuake for SVGALib Console Graphics +- GLQuake for 3DFX and other glX based hardware OpenGL +- Quake.X11 for running Quake under X11 + +%install + +%files +%attr(644,root,root) $3/README +%attr(4755,root,root) $3/squake +%attr(4755,root,root) $3/glquake +%attr(4755,root,root) $3/glquake.glx +%attr(4755,root,root) $3/glquake.3dfxgl +%attr(755,root,root) $3/quake.x11 +%attr(755,root,root) /usr/lib/lib3dfxgl.so +%attr(755,root,root) /usr/lib/libMesaGL.so.2.6 + +%post +/sbin/ldconfig +EOF + diff --git a/contrib/other/sdlquake-1.0.9/quakeasm.h b/contrib/other/sdlquake-1.0.9/quakeasm.h new file mode 100644 index 000000000..303853944 --- /dev/null +++ b/contrib/other/sdlquake-1.0.9/quakeasm.h @@ -0,0 +1,280 @@ +/* +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. + +*/ +// +// quakeasm.h: general asm header file +// + +//#define GLQUAKE 1 + +#if defined(_WIN32) && !defined(WINDED) + +#if defined(_M_IX86) +#define __i386__ 1 +#endif + +#endif + +#if defined(__i386__) && defined(USE_ASM) +#define id386 1 +#else +#define id386 0 +#endif + +// !!! must be kept the same as in d_iface.h !!! +#define TRANSPARENT_COLOR 255 + +#ifndef NeXT +#ifndef GLQUAKE + .extern C(d_zistepu) + .extern C(d_pzbuffer) + .extern C(d_zistepv) + .extern C(d_zrowbytes) + .extern C(d_ziorigin) + .extern C(r_turb_s) + .extern C(r_turb_t) + .extern C(r_turb_pdest) + .extern C(r_turb_spancount) + .extern C(r_turb_turb) + .extern C(r_turb_pbase) + .extern C(r_turb_sstep) + .extern C(r_turb_tstep) + .extern C(r_bmodelactive) + .extern C(d_sdivzstepu) + .extern C(d_tdivzstepu) + .extern C(d_sdivzstepv) + .extern C(d_tdivzstepv) + .extern C(d_sdivzorigin) + .extern C(d_tdivzorigin) + .extern C(sadjust) + .extern C(tadjust) + .extern C(bbextents) + .extern C(bbextentt) + .extern C(cacheblock) + .extern C(d_viewbuffer) + .extern C(cachewidth) + .extern C(d_pzbuffer) + .extern C(d_zrowbytes) + .extern C(d_zwidth) + .extern C(d_scantable) + .extern C(r_lightptr) + .extern C(r_numvblocks) + .extern C(prowdestbase) + .extern C(pbasesource) + .extern C(r_lightwidth) + .extern C(lightright) + .extern C(lightrightstep) + .extern C(lightdeltastep) + .extern C(lightdelta) + .extern C(lightright) + .extern C(lightdelta) + .extern C(sourcetstep) + .extern C(surfrowbytes) + .extern C(lightrightstep) + .extern C(lightdeltastep) + .extern C(r_sourcemax) + .extern C(r_stepback) + .extern C(colormap) + .extern C(blocksize) + .extern C(sourcesstep) + .extern C(lightleft) + .extern C(blockdivshift) + .extern C(blockdivmask) + .extern C(lightleftstep) + .extern C(r_origin) + .extern C(r_ppn) + .extern C(r_pup) + .extern C(r_pright) + .extern C(ycenter) + .extern C(xcenter) + .extern C(d_vrectbottom_particle) + .extern C(d_vrectright_particle) + .extern C(d_vrecty) + .extern C(d_vrectx) + .extern C(d_pix_shift) + .extern C(d_pix_min) + .extern C(d_pix_max) + .extern C(d_y_aspect_shift) + .extern C(screenwidth) + .extern C(r_leftclipped) + .extern C(r_leftenter) + .extern C(r_rightclipped) + .extern C(r_rightenter) + .extern C(modelorg) + .extern C(xscale) + .extern C(r_refdef) + .extern C(yscale) + .extern C(r_leftexit) + .extern C(r_rightexit) + .extern C(r_lastvertvalid) + .extern C(cacheoffset) + .extern C(newedges) + .extern C(removeedges) + .extern C(r_pedge) + .extern C(r_framecount) + .extern C(r_u1) + .extern C(r_emitted) + .extern C(edge_p) + .extern C(surface_p) + .extern C(surfaces) + .extern C(r_lzi1) + .extern C(r_v1) + .extern C(r_ceilv1) + .extern C(r_nearzi) + .extern C(r_nearzionly) + .extern C(edge_aftertail) + .extern C(edge_tail) + .extern C(current_iv) + .extern C(edge_head_u_shift20) + .extern C(span_p) + .extern C(edge_head) + .extern C(fv) + .extern C(edge_tail_u_shift20) + .extern C(r_apverts) + .extern C(r_anumverts) + .extern C(aliastransform) + .extern C(r_avertexnormals) + .extern C(r_plightvec) + .extern C(r_ambientlight) + .extern C(r_shadelight) + .extern C(aliasxcenter) + .extern C(aliasycenter) + .extern C(a_sstepxfrac) + .extern C(r_affinetridesc) + .extern C(acolormap) + .extern C(d_pcolormap) + .extern C(r_affinetridesc) + .extern C(d_sfrac) + .extern C(d_ptex) + .extern C(d_pedgespanpackage) + .extern C(d_tfrac) + .extern C(d_light) + .extern C(d_zi) + .extern C(d_pdest) + .extern C(d_pz) + .extern C(d_aspancount) + .extern C(erroradjustup) + .extern C(errorterm) + .extern C(d_xdenom) + .extern C(r_p0) + .extern C(r_p1) + .extern C(r_p2) + .extern C(a_tstepxfrac) + .extern C(r_sstepx) + .extern C(r_tstepx) + .extern C(a_ststepxwhole) + .extern C(zspantable) + .extern C(skintable) + .extern C(r_zistepx) + .extern C(erroradjustdown) + .extern C(d_countextrastep) + .extern C(ubasestep) + .extern C(a_ststepxwhole) + .extern C(a_tstepxfrac) + .extern C(r_lstepx) + .extern C(a_spans) + .extern C(erroradjustdown) + .extern C(d_pdestextrastep) + .extern C(d_pzextrastep) + .extern C(d_sfracextrastep) + .extern C(d_ptexextrastep) + .extern C(d_countextrastep) + .extern C(d_tfracextrastep) + .extern C(d_lightextrastep) + .extern C(d_ziextrastep) + .extern C(d_pdestbasestep) + .extern C(d_pzbasestep) + .extern C(d_sfracbasestep) + .extern C(d_ptexbasestep) + .extern C(ubasestep) + .extern C(d_tfracbasestep) + .extern C(d_lightbasestep) + .extern C(d_zibasestep) + .extern C(zspantable) + .extern C(r_lstepy) + .extern C(r_sstepy) + .extern C(r_tstepy) + .extern C(r_zistepy) + .extern C(D_PolysetSetEdgeTable) + .extern C(D_RasterizeAliasPolySmooth) + + .extern float_point5 + .extern Float2ToThe31nd + .extern izistep + .extern izi + .extern FloatMinus2ToThe31nd + .extern float_1 + .extern float_particle_z_clip + .extern float_minus_1 + .extern float_0 + .extern fp_16 + .extern fp_64k + .extern fp_1m + .extern fp_1m_minus_1 + .extern fp_8 + .extern entryvec_table + .extern advancetable + .extern sstep + .extern tstep + .extern pspantemp + .extern counttemp + .extern jumptemp + .extern reciprocal_table + .extern DP_Count + .extern DP_u + .extern DP_v + .extern DP_32768 + .extern DP_Color + .extern DP_Pix + .extern DP_EntryTable + .extern pbase + .extern s + .extern t + .extern sfracf + .extern tfracf + .extern snext + .extern tnext + .extern spancountminus1 + .extern zi16stepu + .extern sdivz16stepu + .extern tdivz16stepu + .extern zi8stepu + .extern sdivz8stepu + .extern tdivz8stepu + .extern reciprocal_table_16 + .extern entryvec_table_16 + .extern ceil_cw + .extern single_cw + .extern fp_64kx64k + .extern pz + .extern spr8entryvec_table +#endif + + .extern C(snd_scaletable) + .extern C(paintbuffer) + .extern C(snd_linear_count) + .extern C(snd_p) + .extern C(snd_vol) + .extern C(snd_out) + .extern C(vright) + .extern C(vup) + .extern C(vpn) + .extern C(BOPS_Error) + +#endif diff --git a/contrib/other/sdlquake-1.0.9/quakedef.h b/contrib/other/sdlquake-1.0.9/quakedef.h new file mode 100644 index 000000000..d448d520a --- /dev/null +++ b/contrib/other/sdlquake-1.0.9/quakedef.h @@ -0,0 +1,336 @@ +/* +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 + +#undef 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 + +#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(USE_ASM) +#define id386 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 +#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 + +#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<v[1] >= pfv1->v[1]) + { + scale = (ALIAS_Z_CLIP_PLANE - pav0->fv[2]) / + (pav1->fv[2] - pav0->fv[2]); + + avout.fv[0] = pav0->fv[0] + (pav1->fv[0] - pav0->fv[0]) * scale; + avout.fv[1] = pav0->fv[1] + (pav1->fv[1] - pav0->fv[1]) * scale; + avout.fv[2] = ALIAS_Z_CLIP_PLANE; + + out->v[2] = pfv0->v[2] + (pfv1->v[2] - pfv0->v[2]) * scale; + out->v[3] = pfv0->v[3] + (pfv1->v[3] - pfv0->v[3]) * scale; + out->v[4] = pfv0->v[4] + (pfv1->v[4] - pfv0->v[4]) * scale; + } + else + { + scale = (ALIAS_Z_CLIP_PLANE - pav1->fv[2]) / + (pav0->fv[2] - pav1->fv[2]); + + avout.fv[0] = pav1->fv[0] + (pav0->fv[0] - pav1->fv[0]) * scale; + avout.fv[1] = pav1->fv[1] + (pav0->fv[1] - pav1->fv[1]) * scale; + avout.fv[2] = ALIAS_Z_CLIP_PLANE; + + out->v[2] = pfv1->v[2] + (pfv0->v[2] - pfv1->v[2]) * scale; + out->v[3] = pfv1->v[3] + (pfv0->v[3] - pfv1->v[3]) * scale; + out->v[4] = pfv1->v[4] + (pfv0->v[4] - pfv1->v[4]) * scale; + } + + R_AliasProjectFinalVert (out, &avout); + + if (out->v[0] < r_refdef.aliasvrect.x) + out->flags |= ALIAS_LEFT_CLIP; + if (out->v[1] < r_refdef.aliasvrect.y) + out->flags |= ALIAS_TOP_CLIP; + if (out->v[0] > r_refdef.aliasvrectright) + out->flags |= ALIAS_RIGHT_CLIP; + if (out->v[1] > r_refdef.aliasvrectbottom) + out->flags |= ALIAS_BOTTOM_CLIP; +} + + +#if !id386 + +void R_Alias_clip_left (finalvert_t *pfv0, finalvert_t *pfv1, finalvert_t *out) +{ + float scale; + int i; + + if (pfv0->v[1] >= pfv1->v[1]) + { + scale = (float)(r_refdef.aliasvrect.x - pfv0->v[0]) / + (pfv1->v[0] - pfv0->v[0]); + for (i=0 ; i<6 ; i++) + out->v[i] = pfv0->v[i] + (pfv1->v[i] - pfv0->v[i])*scale + 0.5; + } + else + { + scale = (float)(r_refdef.aliasvrect.x - pfv1->v[0]) / + (pfv0->v[0] - pfv1->v[0]); + for (i=0 ; i<6 ; i++) + out->v[i] = pfv1->v[i] + (pfv0->v[i] - pfv1->v[i])*scale + 0.5; + } +} + + +void R_Alias_clip_right (finalvert_t *pfv0, finalvert_t *pfv1, + finalvert_t *out) +{ + float scale; + int i; + + if (pfv0->v[1] >= pfv1->v[1]) + { + scale = (float)(r_refdef.aliasvrectright - pfv0->v[0]) / + (pfv1->v[0] - pfv0->v[0]); + for (i=0 ; i<6 ; i++) + out->v[i] = pfv0->v[i] + (pfv1->v[i] - pfv0->v[i])*scale + 0.5; + } + else + { + scale = (float)(r_refdef.aliasvrectright - pfv1->v[0]) / + (pfv0->v[0] - pfv1->v[0]); + for (i=0 ; i<6 ; i++) + out->v[i] = pfv1->v[i] + (pfv0->v[i] - pfv1->v[i])*scale + 0.5; + } +} + + +void R_Alias_clip_top (finalvert_t *pfv0, finalvert_t *pfv1, finalvert_t *out) +{ + float scale; + int i; + + if (pfv0->v[1] >= pfv1->v[1]) + { + scale = (float)(r_refdef.aliasvrect.y - pfv0->v[1]) / + (pfv1->v[1] - pfv0->v[1]); + for (i=0 ; i<6 ; i++) + out->v[i] = pfv0->v[i] + (pfv1->v[i] - pfv0->v[i])*scale + 0.5; + } + else + { + scale = (float)(r_refdef.aliasvrect.y - pfv1->v[1]) / + (pfv0->v[1] - pfv1->v[1]); + for (i=0 ; i<6 ; i++) + out->v[i] = pfv1->v[i] + (pfv0->v[i] - pfv1->v[i])*scale + 0.5; + } +} + + +void R_Alias_clip_bottom (finalvert_t *pfv0, finalvert_t *pfv1, + finalvert_t *out) +{ + float scale; + int i; + + if (pfv0->v[1] >= pfv1->v[1]) + { + scale = (float)(r_refdef.aliasvrectbottom - pfv0->v[1]) / + (pfv1->v[1] - pfv0->v[1]); + + for (i=0 ; i<6 ; i++) + out->v[i] = pfv0->v[i] + (pfv1->v[i] - pfv0->v[i])*scale + 0.5; + } + else + { + scale = (float)(r_refdef.aliasvrectbottom - pfv1->v[1]) / + (pfv0->v[1] - pfv1->v[1]); + + for (i=0 ; i<6 ; i++) + out->v[i] = pfv1->v[i] + (pfv0->v[i] - pfv1->v[i])*scale + 0.5; + } +} + +#endif + + +int R_AliasClip (finalvert_t *in, finalvert_t *out, int flag, int count, + void(*clip)(finalvert_t *pfv0, finalvert_t *pfv1, finalvert_t *out) ) +{ + int i,j,k; + int flags, oldflags; + + j = count-1; + k = 0; + for (i=0 ; i r_refdef.aliasvrectright) + out[k].flags |= ALIAS_RIGHT_CLIP; + if (out[k].v[1] > r_refdef.aliasvrectbottom) + out[k].flags |= ALIAS_BOTTOM_CLIP; + k++; + } + if (!flags) + { + out[k] = in[i]; + k++; + } + } + + return k; +} + + +/* +================ +R_AliasClipTriangle +================ +*/ +void R_AliasClipTriangle (mtriangle_t *ptri) +{ + int i, k, pingpong; + mtriangle_t mtri; + unsigned clipflags; + +// copy vertexes and fix seam texture coordinates + if (ptri->facesfront) + { + fv[0][0] = pfinalverts[ptri->vertindex[0]]; + fv[0][1] = pfinalverts[ptri->vertindex[1]]; + fv[0][2] = pfinalverts[ptri->vertindex[2]]; + } + else + { + for (i=0 ; i<3 ; i++) + { + fv[0][i] = pfinalverts[ptri->vertindex[i]]; + + if (!ptri->facesfront && (fv[0][i].flags & ALIAS_ONSEAM) ) + fv[0][i].v[2] += r_affinetridesc.seamfixupX16; + } + } + +// clip + clipflags = fv[0][0].flags | fv[0][1].flags | fv[0][2].flags; + + if (clipflags & ALIAS_Z_CLIP) + { + for (i=0 ; i<3 ; i++) + av[i] = pauxverts[ptri->vertindex[i]]; + + k = R_AliasClip (fv[0], fv[1], ALIAS_Z_CLIP, 3, R_Alias_clip_z); + if (k == 0) + return; + + pingpong = 1; + clipflags = fv[1][0].flags | fv[1][1].flags | fv[1][2].flags; + } + else + { + pingpong = 0; + k = 3; + } + + if (clipflags & ALIAS_LEFT_CLIP) + { + k = R_AliasClip (fv[pingpong], fv[pingpong ^ 1], + ALIAS_LEFT_CLIP, k, R_Alias_clip_left); + if (k == 0) + return; + + pingpong ^= 1; + } + + if (clipflags & ALIAS_RIGHT_CLIP) + { + k = R_AliasClip (fv[pingpong], fv[pingpong ^ 1], + ALIAS_RIGHT_CLIP, k, R_Alias_clip_right); + if (k == 0) + return; + + pingpong ^= 1; + } + + if (clipflags & ALIAS_BOTTOM_CLIP) + { + k = R_AliasClip (fv[pingpong], fv[pingpong ^ 1], + ALIAS_BOTTOM_CLIP, k, R_Alias_clip_bottom); + if (k == 0) + return; + + pingpong ^= 1; + } + + if (clipflags & ALIAS_TOP_CLIP) + { + k = R_AliasClip (fv[pingpong], fv[pingpong ^ 1], + ALIAS_TOP_CLIP, k, R_Alias_clip_top); + if (k == 0) + return; + + pingpong ^= 1; + } + + for (i=0 ; i r_refdef.aliasvrectright) + fv[pingpong][i].v[0] = r_refdef.aliasvrectright; + + if (fv[pingpong][i].v[1] < r_refdef.aliasvrect.y) + fv[pingpong][i].v[1] = r_refdef.aliasvrect.y; + else if (fv[pingpong][i].v[1] > r_refdef.aliasvrectbottom) + fv[pingpong][i].v[1] = r_refdef.aliasvrectbottom; + + fv[pingpong][i].flags = 0; + } + +// draw triangles + mtri.facesfront = ptri->facesfront; + r_affinetridesc.ptriangles = &mtri; + r_affinetridesc.pfinalverts = fv[pingpong]; + +// FIXME: do all at once as trifan? + mtri.vertindex[0] = 0; + for (i=1 ; itrivial_accept = 0; + pmodel = currententity->model; + pahdr = Mod_Extradata (pmodel); + pmdl = (mdl_t *)((byte *)pahdr + pahdr->model); + + R_AliasSetUpTransform (0); + +// construct the base bounding box for this frame + frame = currententity->frame; +// TODO: don't repeat this check when drawing? + if ((frame >= pmdl->numframes) || (frame < 0)) + { + Con_DPrintf ("No such frame %d %s\n", frame, + pmodel->name); + frame = 0; + } + + pframedesc = &pahdr->frames[frame]; + +// x worldspace coordinates + basepts[0][0] = basepts[1][0] = basepts[2][0] = basepts[3][0] = + (float)pframedesc->bboxmin.v[0]; + basepts[4][0] = basepts[5][0] = basepts[6][0] = basepts[7][0] = + (float)pframedesc->bboxmax.v[0]; + +// y worldspace coordinates + basepts[0][1] = basepts[3][1] = basepts[5][1] = basepts[6][1] = + (float)pframedesc->bboxmin.v[1]; + basepts[1][1] = basepts[2][1] = basepts[4][1] = basepts[7][1] = + (float)pframedesc->bboxmax.v[1]; + +// z worldspace coordinates + basepts[0][2] = basepts[1][2] = basepts[4][2] = basepts[5][2] = + (float)pframedesc->bboxmin.v[2]; + basepts[2][2] = basepts[3][2] = basepts[6][2] = basepts[7][2] = + (float)pframedesc->bboxmax.v[2]; + + zclipped = false; + zfullyclipped = true; + + minz = 9999; + for (i=0; i<8 ; i++) + { + R_AliasTransformVector (&basepts[i][0], &viewaux[i].fv[0]); + + if (viewaux[i].fv[2] < ALIAS_Z_CLIP_PLANE) + { + // we must clip points that are closer than the near clip plane + viewpts[i].flags = ALIAS_Z_CLIP; + zclipped = true; + } + else + { + if (viewaux[i].fv[2] < minz) + minz = viewaux[i].fv[2]; + viewpts[i].flags = 0; + zfullyclipped = false; + } + } + + + if (zfullyclipped) + { + return false; // everything was near-z-clipped + } + + numv = 8; + + if (zclipped) + { + // organize points by edges, use edges to get new points (possible trivial + // reject) + for (i=0 ; i<12 ; i++) + { + // edge endpoints + pv0 = &viewpts[aedges[i].index0]; + pv1 = &viewpts[aedges[i].index1]; + pa0 = &viewaux[aedges[i].index0]; + pa1 = &viewaux[aedges[i].index1]; + + // if one end is clipped and the other isn't, make a new point + if (pv0->flags ^ pv1->flags) + { + frac = (ALIAS_Z_CLIP_PLANE - pa0->fv[2]) / + (pa1->fv[2] - pa0->fv[2]); + viewaux[numv].fv[0] = pa0->fv[0] + + (pa1->fv[0] - pa0->fv[0]) * frac; + viewaux[numv].fv[1] = pa0->fv[1] + + (pa1->fv[1] - pa0->fv[1]) * frac; + viewaux[numv].fv[2] = ALIAS_Z_CLIP_PLANE; + viewpts[numv].flags = 0; + numv++; + } + } + } + +// project the vertices that remain after clipping + anyclip = 0; + allclip = ALIAS_XY_CLIP_MASK; + +// TODO: probably should do this loop in ASM, especially if we use floats + for (i=0 ; i r_refdef.fvrectright) + flags |= ALIAS_RIGHT_CLIP; + if (v1 > r_refdef.fvrectbottom) + flags |= ALIAS_BOTTOM_CLIP; + + anyclip |= flags; + allclip &= flags; + } + + if (allclip) + return false; // trivial reject off one side + + currententity->trivial_accept = !anyclip & !zclipped; + + if (currententity->trivial_accept) + { + if (minz > (r_aliastransition + (pmdl->size * r_resfudge))) + { + currententity->trivial_accept |= 2; + } + } + + return true; +} + + +/* +================ +R_AliasTransformVector +================ +*/ +void R_AliasTransformVector (vec3_t in, vec3_t out) +{ + out[0] = DotProduct(in, aliastransform[0]) + aliastransform[0][3]; + out[1] = DotProduct(in, aliastransform[1]) + aliastransform[1][3]; + out[2] = DotProduct(in, aliastransform[2]) + aliastransform[2][3]; +} + + +/* +================ +R_AliasPreparePoints + +General clipped case +================ +*/ +void R_AliasPreparePoints (void) +{ + int i; + stvert_t *pstverts; + finalvert_t *fv; + auxvert_t *av; + mtriangle_t *ptri; + finalvert_t *pfv[3]; + + pstverts = (stvert_t *)((byte *)paliashdr + paliashdr->stverts); + r_anumverts = pmdl->numverts; + fv = pfinalverts; + av = pauxverts; + + for (i=0 ; ifv[2] < ALIAS_Z_CLIP_PLANE) + fv->flags |= ALIAS_Z_CLIP; + else + { + R_AliasProjectFinalVert (fv, av); + + if (fv->v[0] < r_refdef.aliasvrect.x) + fv->flags |= ALIAS_LEFT_CLIP; + if (fv->v[1] < r_refdef.aliasvrect.y) + fv->flags |= ALIAS_TOP_CLIP; + if (fv->v[0] > r_refdef.aliasvrectright) + fv->flags |= ALIAS_RIGHT_CLIP; + if (fv->v[1] > r_refdef.aliasvrectbottom) + fv->flags |= ALIAS_BOTTOM_CLIP; + } + } + +// +// clip and draw all triangles +// + r_affinetridesc.numtriangles = 1; + + ptri = (mtriangle_t *)((byte *)paliashdr + paliashdr->triangles); + for (i=0 ; inumtris ; i++, ptri++) + { + pfv[0] = &pfinalverts[ptri->vertindex[0]]; + pfv[1] = &pfinalverts[ptri->vertindex[1]]; + pfv[2] = &pfinalverts[ptri->vertindex[2]]; + + if ( pfv[0]->flags & pfv[1]->flags & pfv[2]->flags & (ALIAS_XY_CLIP_MASK | ALIAS_Z_CLIP) ) + continue; // completely clipped + + if ( ! ( (pfv[0]->flags | pfv[1]->flags | pfv[2]->flags) & + (ALIAS_XY_CLIP_MASK | ALIAS_Z_CLIP) ) ) + { // totally unclipped + r_affinetridesc.pfinalverts = pfinalverts; + r_affinetridesc.ptriangles = ptri; + D_PolysetDraw (); + } + else + { // partially clipped + R_AliasClipTriangle (ptri); + } + } +} + + +/* +================ +R_AliasSetUpTransform +================ +*/ +void R_AliasSetUpTransform (int trivial_accept) +{ + int i; + float rotationmatrix[3][4], t2matrix[3][4]; + static float tmatrix[3][4]; + static float viewmatrix[3][4]; + vec3_t angles; + +// TODO: should really be stored with the entity instead of being reconstructed +// TODO: should use a look-up table +// TODO: could cache lazily, stored in the entity + + angles[ROLL] = currententity->angles[ROLL]; + angles[PITCH] = -currententity->angles[PITCH]; + angles[YAW] = currententity->angles[YAW]; + AngleVectors (angles, alias_forward, alias_right, alias_up); + + tmatrix[0][0] = pmdl->scale[0]; + tmatrix[1][1] = pmdl->scale[1]; + tmatrix[2][2] = pmdl->scale[2]; + + tmatrix[0][3] = pmdl->scale_origin[0]; + tmatrix[1][3] = pmdl->scale_origin[1]; + tmatrix[2][3] = pmdl->scale_origin[2]; + +// TODO: can do this with simple matrix rearrangement + + for (i=0 ; i<3 ; i++) + { + t2matrix[i][0] = alias_forward[i]; + t2matrix[i][1] = -alias_right[i]; + t2matrix[i][2] = alias_up[i]; + } + + t2matrix[0][3] = -modelorg[0]; + t2matrix[1][3] = -modelorg[1]; + t2matrix[2][3] = -modelorg[2]; + +// FIXME: can do more efficiently than full concatenation + R_ConcatTransforms (t2matrix, tmatrix, rotationmatrix); + +// TODO: should be global, set when vright, etc., set + VectorCopy (vright, viewmatrix[0]); + VectorCopy (vup, viewmatrix[1]); + VectorInverse (viewmatrix[1]); + VectorCopy (vpn, viewmatrix[2]); + +// viewmatrix[0][3] = 0; +// viewmatrix[1][3] = 0; +// viewmatrix[2][3] = 0; + + R_ConcatTransforms (viewmatrix, rotationmatrix, aliastransform); + +// do the scaling up of x and y to screen coordinates as part of the transform +// for the unclipped case (it would mess up clipping in the clipped case). +// Also scale down z, so 1/z is scaled 31 bits for free, and scale down x and y +// correspondingly so the projected x and y come out right +// FIXME: make this work for clipped case too? + if (trivial_accept) + { + for (i=0 ; i<4 ; i++) + { + aliastransform[0][i] *= aliasxscale * + (1.0 / ((float)0x8000 * 0x10000)); + aliastransform[1][i] *= aliasyscale * + (1.0 / ((float)0x8000 * 0x10000)); + aliastransform[2][i] *= 1.0 / ((float)0x8000 * 0x10000); + + } + } +} + + +/* +================ +R_AliasTransformFinalVert +================ +*/ +void R_AliasTransformFinalVert (finalvert_t *fv, auxvert_t *av, + trivertx_t *pverts, stvert_t *pstverts) +{ + int temp; + float lightcos, *plightnormal; + + av->fv[0] = DotProduct(pverts->v, aliastransform[0]) + + aliastransform[0][3]; + av->fv[1] = DotProduct(pverts->v, aliastransform[1]) + + aliastransform[1][3]; + av->fv[2] = DotProduct(pverts->v, aliastransform[2]) + + aliastransform[2][3]; + + fv->v[2] = pstverts->s; + fv->v[3] = pstverts->t; + + fv->flags = pstverts->onseam; + +// lighting + plightnormal = r_avertexnormals[pverts->lightnormalindex]; + lightcos = DotProduct (plightnormal, r_plightvec); + temp = r_ambientlight; + + if (lightcos < 0) + { + temp += (int)(r_shadelight * lightcos); + + // clamp; because we limited the minimum ambient and shading light, we + // don't have to clamp low light, just bright + if (temp < 0) + temp = 0; + } + + fv->v[4] = temp; +} + + +#if !id386 + +/* +================ +R_AliasTransformAndProjectFinalVerts +================ +*/ +void R_AliasTransformAndProjectFinalVerts (finalvert_t *fv, stvert_t *pstverts) +{ + int i, temp; + float lightcos, *plightnormal, zi; + trivertx_t *pverts; + + pverts = r_apverts; + + for (i=0 ; iv, aliastransform[2]) + + aliastransform[2][3]); + + // x, y, and z are scaled down by 1/2**31 in the transform, so 1/z is + // scaled up by 1/2**31, and the scaling cancels out for x and y in the + // projection + fv->v[5] = zi; + + fv->v[0] = ((DotProduct(pverts->v, aliastransform[0]) + + aliastransform[0][3]) * zi) + aliasxcenter; + fv->v[1] = ((DotProduct(pverts->v, aliastransform[1]) + + aliastransform[1][3]) * zi) + aliasycenter; + + fv->v[2] = pstverts->s; + fv->v[3] = pstverts->t; + fv->flags = pstverts->onseam; + + // lighting + plightnormal = r_avertexnormals[pverts->lightnormalindex]; + lightcos = DotProduct (plightnormal, r_plightvec); + temp = r_ambientlight; + + if (lightcos < 0) + { + temp += (int)(r_shadelight * lightcos); + + // clamp; because we limited the minimum ambient and shading light, we + // don't have to clamp low light, just bright + if (temp < 0) + temp = 0; + } + + fv->v[4] = temp; + } +} + +#endif + + +/* +================ +R_AliasProjectFinalVert +================ +*/ +void R_AliasProjectFinalVert (finalvert_t *fv, auxvert_t *av) +{ + float zi; + +// project points + zi = 1.0 / av->fv[2]; + + fv->v[5] = zi * ziscale; + + fv->v[0] = (av->fv[0] * aliasxscale * zi) + aliasxcenter; + fv->v[1] = (av->fv[1] * aliasyscale * zi) + aliasycenter; +} + + +/* +================ +R_AliasPrepareUnclippedPoints +================ +*/ +void R_AliasPrepareUnclippedPoints (void) +{ + stvert_t *pstverts; + finalvert_t *fv; + + pstverts = (stvert_t *)((byte *)paliashdr + paliashdr->stverts); + r_anumverts = pmdl->numverts; +// FIXME: just use pfinalverts directly? + fv = pfinalverts; + + R_AliasTransformAndProjectFinalVerts (fv, pstverts); + + if (r_affinetridesc.drawtype) + D_PolysetDrawFinalVerts (fv, r_anumverts); + + r_affinetridesc.pfinalverts = pfinalverts; + r_affinetridesc.ptriangles = (mtriangle_t *) + ((byte *)paliashdr + paliashdr->triangles); + r_affinetridesc.numtriangles = pmdl->numtris; + + D_PolysetDraw (); +} + +/* +=============== +R_AliasSetupSkin +=============== +*/ +void R_AliasSetupSkin (void) +{ + int skinnum; + int i, numskins; + maliasskingroup_t *paliasskingroup; + float *pskinintervals, fullskininterval; + float skintargettime, skintime; + + skinnum = currententity->skinnum; + if ((skinnum >= pmdl->numskins) || (skinnum < 0)) + { + Con_DPrintf ("R_AliasSetupSkin: no such skin # %d\n", skinnum); + skinnum = 0; + } + + pskindesc = ((maliasskindesc_t *) + ((byte *)paliashdr + paliashdr->skindesc)) + skinnum; + a_skinwidth = pmdl->skinwidth; + + if (pskindesc->type == ALIAS_SKIN_GROUP) + { + paliasskingroup = (maliasskingroup_t *)((byte *)paliashdr + + pskindesc->skin); + pskinintervals = (float *) + ((byte *)paliashdr + paliasskingroup->intervals); + numskins = paliasskingroup->numskins; + fullskininterval = pskinintervals[numskins-1]; + + skintime = cl.time + currententity->syncbase; + + // when loading in Mod_LoadAliasSkinGroup, we guaranteed all interval + // values are positive, so we don't have to worry about division by 0 + skintargettime = skintime - + ((int)(skintime / fullskininterval)) * fullskininterval; + + for (i=0 ; i<(numskins-1) ; i++) + { + if (pskinintervals[i] > skintargettime) + break; + } + + pskindesc = &paliasskingroup->skindescs[i]; + } + + r_affinetridesc.pskindesc = pskindesc; + r_affinetridesc.pskin = (void *)((byte *)paliashdr + pskindesc->skin); + r_affinetridesc.skinwidth = a_skinwidth; + r_affinetridesc.seamfixupX16 = (a_skinwidth >> 1) << 16; + r_affinetridesc.skinheight = pmdl->skinheight; +} + +/* +================ +R_AliasSetupLighting +================ +*/ +void R_AliasSetupLighting (alight_t *plighting) +{ + +// guarantee that no vertex will ever be lit below LIGHT_MIN, so we don't have +// to clamp off the bottom + r_ambientlight = plighting->ambientlight; + + if (r_ambientlight < LIGHT_MIN) + r_ambientlight = LIGHT_MIN; + + r_ambientlight = (255 - r_ambientlight) << VID_CBITS; + + if (r_ambientlight < LIGHT_MIN) + r_ambientlight = LIGHT_MIN; + + r_shadelight = plighting->shadelight; + + if (r_shadelight < 0) + r_shadelight = 0; + + r_shadelight *= VID_GRADES; + +// rotate the lighting vector into the model's frame of reference + r_plightvec[0] = DotProduct (plighting->plightvec, alias_forward); + r_plightvec[1] = -DotProduct (plighting->plightvec, alias_right); + r_plightvec[2] = DotProduct (plighting->plightvec, alias_up); +} + +/* +================= +R_AliasSetupFrame + +set r_apverts +================= +*/ +void R_AliasSetupFrame (void) +{ + int frame; + int i, numframes; + maliasgroup_t *paliasgroup; + float *pintervals, fullinterval, targettime, time; + + frame = currententity->frame; + if ((frame >= pmdl->numframes) || (frame < 0)) + { + Con_DPrintf ("R_AliasSetupFrame: no such frame %d\n", frame); + frame = 0; + } + + if (paliashdr->frames[frame].type == ALIAS_SINGLE) + { + r_apverts = (trivertx_t *) + ((byte *)paliashdr + paliashdr->frames[frame].frame); + return; + } + + paliasgroup = (maliasgroup_t *) + ((byte *)paliashdr + paliashdr->frames[frame].frame); + pintervals = (float *)((byte *)paliashdr + paliasgroup->intervals); + numframes = paliasgroup->numframes; + fullinterval = pintervals[numframes-1]; + + time = cl.time + currententity->syncbase; + +// +// when loading in Mod_LoadAliasGroup, 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; + } + + r_apverts = (trivertx_t *) + ((byte *)paliashdr + paliasgroup->frames[i].frame); +} + + +/* +================ +R_AliasDrawModel +================ +*/ +void R_AliasDrawModel (alight_t *plighting) +{ + finalvert_t finalverts[MAXALIASVERTS + + ((CACHE_SIZE - 1) / sizeof(finalvert_t)) + 1]; + auxvert_t auxverts[MAXALIASVERTS]; + + r_amodels_drawn++; + +// cache align + pfinalverts = (finalvert_t *) + (((long)&finalverts[0] + CACHE_SIZE - 1) & ~(CACHE_SIZE - 1)); + pauxverts = &auxverts[0]; + + paliashdr = (aliashdr_t *)Mod_Extradata (currententity->model); + pmdl = (mdl_t *)((byte *)paliashdr + paliashdr->model); + + R_AliasSetupSkin (); + R_AliasSetUpTransform (currententity->trivial_accept); + R_AliasSetupLighting (plighting); + R_AliasSetupFrame (); + + if (!currententity->colormap) + Sys_Error ("R_AliasDrawModel: !currententity->colormap"); + + r_affinetridesc.drawtype = (currententity->trivial_accept == 3) && + r_recursiveaffinetriangles; + + if (r_affinetridesc.drawtype) + { + D_PolysetUpdateTables (); // FIXME: precalc... + } + else + { +#if id386 + D_Aff8Patch (currententity->colormap); +#endif + } + + acolormap = currententity->colormap; + + if (currententity != &cl.viewent) + ziscale = (float)0x8000 * (float)0x10000; + else + ziscale = (float)0x8000 * (float)0x10000 * 3.0; + + if (currententity->trivial_accept) + R_AliasPrepareUnclippedPoints (); + else + R_AliasPreparePoints (); +} + diff --git a/contrib/other/sdlquake-1.0.9/r_aliasa.S b/contrib/other/sdlquake-1.0.9/r_aliasa.S new file mode 100644 index 000000000..b19e97aac --- /dev/null +++ b/contrib/other/sdlquake-1.0.9/r_aliasa.S @@ -0,0 +1,237 @@ +/* +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_aliasa.s +// x86 assembly-language Alias model transform and project code. +// + +#include "asm_i386.h" +#include "quakeasm.h" +#include "asm_draw.h" +#include "d_ifacea.h" + +#if id386 + + .data + +Lfloat_1: .single 1.0 +Ltemp: .long 0 +Lcoords: .long 0, 0, 0 + + .text + +#define fv 12+4 +#define pstverts 12+8 + +.globl C(R_AliasTransformAndProjectFinalVerts) +C(R_AliasTransformAndProjectFinalVerts): + pushl %ebp // preserve caller's stack frame + pushl %edi + pushl %esi // preserve register variables + +// int i, temp; +// float lightcos, *plightnormal, zi; +// trivertx_t *pverts; + +// pverts = r_apverts; + movl C(r_apverts),%esi + +// for (i=0 ; iv, aliastransform[2]) + +// aliastransform[2][3]); + movb (%esi),%dl + movb %dl,Lcoords + fildl Lcoords // v[0] + movb 1(%esi),%dl + movb %dl,Lcoords+4 + fildl Lcoords+4 // v[1] | v[0] + movb 2(%esi),%dl + movb %dl,Lcoords+8 + fildl Lcoords+8 // v[2] | v[1] | v[0] + + fld %st(2) // v[0] | v[2] | v[1] | v[0] + fmuls C(aliastransform)+32 // accum | v[2] | v[1] | v[0] + fld %st(2) // v[1] | accum | v[2] | v[1] | v[0] + fmuls C(aliastransform)+36 // accum2 | accum | v[2] | v[1] | v[0] + fxch %st(1) // accum | accum2 | v[2] | v[1] | v[0] + fadds C(aliastransform)+44 // accum | accum2 | v[2] | v[1] | v[0] + fld %st(2) // v[2] | accum | accum2 | v[2] | v[1] | v[0] + fmuls C(aliastransform)+40 // accum3 | accum | accum2 | v[2] | v[1] | + // v[0] + fxch %st(1) // accum | accum3 | accum2 | v[2] | v[1] | v[0] + faddp %st(0),%st(2) // accum3 | accum | v[2] | v[1] | v[0] + movb tv_lightnormalindex(%esi),%dl + movl stv_s(%ebp),%eax + movl %eax,fv_v+8(%edi) + faddp %st(0),%st(1) // z | v[2] | v[1] | v[0] + + movl stv_t(%ebp),%eax + movl %eax,fv_v+12(%edi) + +// // lighting +// plightnormal = r_avertexnormals[pverts->lightnormalindex]; + + fdivrs Lfloat_1 // zi | v[2] | v[1] | v[0] + +// fv->v[2] = pstverts->s; +// fv->v[3] = pstverts->t; +// fv->flags = pstverts->onseam; + movl stv_onseam(%ebp),%eax + movl %eax,fv_flags(%edi) + + movl fv_size(%edi),%eax + movl stv_size(%ebp),%eax + movl 4(%esi),%eax + + leal (%edx,%edx,2),%eax // index*3 + + fxch %st(3) // v[0] | v[2] | v[1] | zi + +// lightcos = DotProduct (plightnormal, r_plightvec); + flds C(r_avertexnormals)(,%eax,4) + fmuls C(r_plightvec) + flds C(r_avertexnormals)+4(,%eax,4) + fmuls C(r_plightvec)+4 + flds C(r_avertexnormals)+8(,%eax,4) + fmuls C(r_plightvec)+8 + fxch %st(1) + faddp %st(0),%st(2) + fld %st(2) // v[0] | laccum | laccum2 | v[0] | v[2] | + // v[1] | zi + fmuls C(aliastransform)+0 // xaccum | laccum | laccum2 | v[0] | v[2] | + // v[1] | zi + fxch %st(2) // laccum2 | laccum | xaccum | v[0] | v[2] | + // v[1] | zi + faddp %st(0),%st(1) // laccum | xaccum | v[0] | v[2] | v[1] | zi + +// temp = r_ambientlight; +// if (lightcos < 0) +// { + fsts Ltemp + movl C(r_ambientlight),%eax + movb Ltemp+3,%dl + testb $0x80,%dl + jz Lsavelight // no need to clamp if only ambient lit, because + // r_ambientlight is preclamped + +// temp += (int)(r_shadelight * lightcos); + fmuls C(r_shadelight) +// FIXME: fast float->int conversion? + fistpl Ltemp + addl Ltemp,%eax + +// // clamp; because we limited the minimum ambient and shading light, we +// // don't have to clamp low light, just bright +// if (temp < 0) +// temp = 0; + jns Lp1 + subl %eax,%eax + +// } + +Lp1: + +// fv->v[4] = temp; +// +// // x, y, and z are scaled down by 1/2**31 in the transform, so 1/z is +// // scaled up by 1/2**31, and the scaling cancels out for x and y in the +// // projection +// fv->v[0] = ((DotProduct(pverts->v, aliastransform[0]) + +// aliastransform[0][3]) * zi) + aliasxcenter; +// fv->v[1] = ((DotProduct(pverts->v, aliastransform[1]) + +// aliastransform[1][3]) * zi) + aliasycenter; +// fv->v[5] = zi; + fxch %st(1) // v[0] | xaccum | v[2] | v[1] | zi + fmuls C(aliastransform)+16 // yaccum | xaccum | v[2] | v[1] | zi + fxch %st(3) // v[1] | xaccum | v[2] | yaccum | zi + fld %st(0) // v[1] | v[1] | xaccum | v[2] | yaccum | zi + fmuls C(aliastransform)+4 // xaccum2 | v[1] | xaccum | v[2] | yaccum |zi + fxch %st(1) // v[1] | xaccum2 | xaccum | v[2] | yaccum |zi + movl %eax,fv_v+16(%edi) + fmuls C(aliastransform)+20 // yaccum2 | xaccum2 | xaccum | v[2] | yaccum| + // zi + fxch %st(2) // xaccum | xaccum2 | yaccum2 | v[2] | yaccum| + // zi + fadds C(aliastransform)+12 // xaccum | xaccum2 | yaccum2 | v[2] | yaccum| + // zi + fxch %st(4) // yaccum | xaccum2 | yaccum2 | v[2] | xaccum| + // zi + fadds C(aliastransform)+28 // yaccum | xaccum2 | yaccum2 | v[2] | xaccum| + // zi + fxch %st(3) // v[2] | xaccum2 | yaccum2 | yaccum | xaccum| + // zi + fld %st(0) // v[2] | v[2] | xaccum2 | yaccum2 | yaccum | + // xaccum | zi + fmuls C(aliastransform)+8 // xaccum3 | v[2] | xaccum2 | yaccum2 |yaccum| + // xaccum | zi + fxch %st(1) // v[2] | xaccum3 | xaccum2 | yaccum2 |yaccum| + // xaccum | zi + fmuls C(aliastransform)+24 // yaccum3 | xaccum3 | xaccum2 | yaccum2 | + // yaccum | xaccum | zi + fxch %st(5) // xaccum | xaccum3 | xaccum2 | yaccum2 | + // yaccum | yaccum3 | zi + faddp %st(0),%st(2) // xaccum3 | xaccum | yaccum2 | yaccum | + // yaccum3 | zi + fxch %st(3) // yaccum | xaccum | yaccum2 | xaccum3 | + // yaccum3 | zi + faddp %st(0),%st(2) // xaccum | yaccum | xaccum3 | yaccum3 | zi + addl $(tv_size),%esi + faddp %st(0),%st(2) // yaccum | x | yaccum3 | zi + faddp %st(0),%st(2) // x | y | zi + addl $(stv_size),%ebp + fmul %st(2),%st(0) // x/z | y | zi + fxch %st(1) // y | x/z | zi + fmul %st(2),%st(0) // y/z | x/z | zi + fxch %st(1) // x/z | y/z | zi + fadds C(aliasxcenter) // u | y/z | zi + fxch %st(1) // y/z | u | zi + fadds C(aliasycenter) // v | u | zi + fxch %st(2) // zi | u | v +// FIXME: fast float->int conversion? + fistpl fv_v+20(%edi) // u | v + fistpl fv_v+0(%edi) // v + fistpl fv_v+4(%edi) + +// } + + addl $(fv_size),%edi + decl %ecx + jnz Lloop + + popl %esi // restore register variables + popl %edi + popl %ebp // restore the caller's stack frame + ret + +Lsavelight: + fstp %st(0) + jmp Lp1 + +#endif // id386 + diff --git a/contrib/other/sdlquake-1.0.9/r_bsp.c b/contrib/other/sdlquake-1.0.9/r_bsp.c new file mode 100644 index 000000000..70e42f978 --- /dev/null +++ b/contrib/other/sdlquake-1.0.9/r_bsp.c @@ -0,0 +1,674 @@ +/* +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_bsp.c + +#include "quakedef.h" +#include "r_local.h" + +// +// current entity info +// +qboolean insubmodel; +entity_t *currententity; +vec3_t modelorg, base_modelorg; + // modelorg is the viewpoint reletive to + // the currently rendering entity +vec3_t r_entorigin; // the currently rendering entity in world + // coordinates + +float entity_rotation[3][3]; + +vec3_t r_worldmodelorg; + +int r_currentbkey; + +typedef enum {touchessolid, drawnode, nodrawnode} solidstate_t; + +#define MAX_BMODEL_VERTS 500 // 6K +#define MAX_BMODEL_EDGES 1000 // 12K + +static mvertex_t *pbverts; +static bedge_t *pbedges; +static int numbverts, numbedges; + +static mvertex_t *pfrontenter, *pfrontexit; + +static qboolean makeclippededge; + + +//=========================================================================== + +/* +================ +R_EntityRotate +================ +*/ +void R_EntityRotate (vec3_t vec) +{ + vec3_t tvec; + + VectorCopy (vec, tvec); + vec[0] = DotProduct (entity_rotation[0], tvec); + vec[1] = DotProduct (entity_rotation[1], tvec); + vec[2] = DotProduct (entity_rotation[2], tvec); +} + + +/* +================ +R_RotateBmodel +================ +*/ +void R_RotateBmodel (void) +{ + float angle, s, c, temp1[3][3], temp2[3][3], temp3[3][3]; + +// TODO: should use a look-up table +// TODO: should really be stored with the entity instead of being reconstructed +// TODO: could cache lazily, stored in the entity +// TODO: share work with R_SetUpAliasTransform + +// yaw + angle = currententity->angles[YAW]; + angle = angle * M_PI*2 / 360; + s = sin(angle); + c = cos(angle); + + temp1[0][0] = c; + temp1[0][1] = s; + temp1[0][2] = 0; + temp1[1][0] = -s; + temp1[1][1] = c; + temp1[1][2] = 0; + temp1[2][0] = 0; + temp1[2][1] = 0; + temp1[2][2] = 1; + + +// pitch + angle = currententity->angles[PITCH]; + angle = angle * M_PI*2 / 360; + s = sin(angle); + c = cos(angle); + + temp2[0][0] = c; + temp2[0][1] = 0; + temp2[0][2] = -s; + temp2[1][0] = 0; + temp2[1][1] = 1; + temp2[1][2] = 0; + temp2[2][0] = s; + temp2[2][1] = 0; + temp2[2][2] = c; + + R_ConcatRotations (temp2, temp1, temp3); + +// roll + angle = currententity->angles[ROLL]; + angle = angle * M_PI*2 / 360; + s = sin(angle); + c = cos(angle); + + temp1[0][0] = 1; + temp1[0][1] = 0; + temp1[0][2] = 0; + temp1[1][0] = 0; + temp1[1][1] = c; + temp1[1][2] = s; + temp1[2][0] = 0; + temp1[2][1] = -s; + temp1[2][2] = c; + + R_ConcatRotations (temp1, temp3, entity_rotation); + +// +// rotate modelorg and the transformation matrix +// + R_EntityRotate (modelorg); + R_EntityRotate (vpn); + R_EntityRotate (vright); + R_EntityRotate (vup); + + R_TransformFrustum (); +} + + +/* +================ +R_RecursiveClipBPoly +================ +*/ +void R_RecursiveClipBPoly (bedge_t *pedges, mnode_t *pnode, msurface_t *psurf) +{ + bedge_t *psideedges[2], *pnextedge, *ptedge; + int i, side, lastside; + float dist, frac, lastdist; + mplane_t *splitplane, tplane; + mvertex_t *pvert, *plastvert, *ptvert; + mnode_t *pn; + + psideedges[0] = psideedges[1] = NULL; + + makeclippededge = false; + +// transform the BSP plane into model space +// FIXME: cache these? + splitplane = pnode->plane; + tplane.dist = splitplane->dist - + DotProduct(r_entorigin, splitplane->normal); + tplane.normal[0] = DotProduct (entity_rotation[0], splitplane->normal); + tplane.normal[1] = DotProduct (entity_rotation[1], splitplane->normal); + tplane.normal[2] = DotProduct (entity_rotation[2], splitplane->normal); + +// clip edges to BSP plane + for ( ; pedges ; pedges = pnextedge) + { + pnextedge = pedges->pnext; + + // set the status for the last point as the previous point + // FIXME: cache this stuff somehow? + plastvert = pedges->v[0]; + lastdist = DotProduct (plastvert->position, tplane.normal) - + tplane.dist; + + if (lastdist > 0) + lastside = 0; + else + lastside = 1; + + pvert = pedges->v[1]; + + dist = DotProduct (pvert->position, tplane.normal) - tplane.dist; + + if (dist > 0) + side = 0; + else + side = 1; + + if (side != lastside) + { + // clipped + if (numbverts >= MAX_BMODEL_VERTS) + return; + + // generate the clipped vertex + frac = lastdist / (lastdist - dist); + ptvert = &pbverts[numbverts++]; + ptvert->position[0] = plastvert->position[0] + + frac * (pvert->position[0] - + plastvert->position[0]); + ptvert->position[1] = plastvert->position[1] + + frac * (pvert->position[1] - + plastvert->position[1]); + ptvert->position[2] = plastvert->position[2] + + frac * (pvert->position[2] - + plastvert->position[2]); + + // split into two edges, one on each side, and remember entering + // and exiting points + // FIXME: share the clip edge by having a winding direction flag? + if (numbedges >= (MAX_BMODEL_EDGES - 1)) + { + Con_Printf ("Out of edges for bmodel\n"); + return; + } + + ptedge = &pbedges[numbedges]; + ptedge->pnext = psideedges[lastside]; + psideedges[lastside] = ptedge; + ptedge->v[0] = plastvert; + ptedge->v[1] = ptvert; + + ptedge = &pbedges[numbedges + 1]; + ptedge->pnext = psideedges[side]; + psideedges[side] = ptedge; + ptedge->v[0] = ptvert; + ptedge->v[1] = pvert; + + numbedges += 2; + + if (side == 0) + { + // entering for front, exiting for back + pfrontenter = ptvert; + makeclippededge = true; + } + else + { + pfrontexit = ptvert; + makeclippededge = true; + } + } + else + { + // add the edge to the appropriate side + pedges->pnext = psideedges[side]; + psideedges[side] = pedges; + } + } + +// if anything was clipped, reconstitute and add the edges along the clip +// plane to both sides (but in opposite directions) + if (makeclippededge) + { + if (numbedges >= (MAX_BMODEL_EDGES - 2)) + { + Con_Printf ("Out of edges for bmodel\n"); + return; + } + + ptedge = &pbedges[numbedges]; + ptedge->pnext = psideedges[0]; + psideedges[0] = ptedge; + ptedge->v[0] = pfrontexit; + ptedge->v[1] = pfrontenter; + + ptedge = &pbedges[numbedges + 1]; + ptedge->pnext = psideedges[1]; + psideedges[1] = ptedge; + ptedge->v[0] = pfrontenter; + ptedge->v[1] = pfrontexit; + + numbedges += 2; + } + +// draw or recurse further + for (i=0 ; i<2 ; i++) + { + if (psideedges[i]) + { + // draw if we've reached a non-solid leaf, done if all that's left is a + // solid leaf, and continue down the tree if it's not a leaf + pn = pnode->children[i]; + + // we're done with this branch if the node or leaf isn't in the PVS + if (pn->visframe == r_visframecount) + { + if (pn->contents < 0) + { + if (pn->contents != CONTENTS_SOLID) + { + r_currentbkey = ((mleaf_t *)pn)->key; + R_RenderBmodelFace (psideedges[i], psurf); + } + } + else + { + R_RecursiveClipBPoly (psideedges[i], pnode->children[i], + psurf); + } + } + } + } +} + + +/* +================ +R_DrawSolidClippedSubmodelPolygons +================ +*/ +void R_DrawSolidClippedSubmodelPolygons (model_t *pmodel) +{ + int i, j, lindex; + vec_t dot; + msurface_t *psurf; + int numsurfaces; + mplane_t *pplane; + mvertex_t bverts[MAX_BMODEL_VERTS]; + bedge_t bedges[MAX_BMODEL_EDGES], *pbedge; + medge_t *pedge, *pedges; + +// FIXME: use bounding-box-based frustum clipping info? + + psurf = &pmodel->surfaces[pmodel->firstmodelsurface]; + numsurfaces = pmodel->nummodelsurfaces; + pedges = pmodel->edges; + + for (i=0 ; iplane; + + 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))) + { + // FIXME: use bounding-box-based frustum clipping info? + + // copy the edges to bedges, flipping if necessary so always + // clockwise winding + // FIXME: if edges and vertices get caches, these assignments must move + // outside the loop, and overflow checking must be done here + pbverts = bverts; + pbedges = bedges; + numbverts = numbedges = 0; + + if (psurf->numedges > 0) + { + pbedge = &bedges[numbedges]; + numbedges += psurf->numedges; + + for (j=0 ; jnumedges ; j++) + { + lindex = pmodel->surfedges[psurf->firstedge+j]; + + if (lindex > 0) + { + pedge = &pedges[lindex]; + pbedge[j].v[0] = &r_pcurrentvertbase[pedge->v[0]]; + pbedge[j].v[1] = &r_pcurrentvertbase[pedge->v[1]]; + } + else + { + lindex = -lindex; + pedge = &pedges[lindex]; + pbedge[j].v[0] = &r_pcurrentvertbase[pedge->v[1]]; + pbedge[j].v[1] = &r_pcurrentvertbase[pedge->v[0]]; + } + + pbedge[j].pnext = &pbedge[j+1]; + } + + pbedge[j-1].pnext = NULL; // mark end of edges + + R_RecursiveClipBPoly (pbedge, currententity->topnode, psurf); + } + else + { + Sys_Error ("no edges in bmodel"); + } + } + } +} + + +/* +================ +R_DrawSubmodelPolygons +================ +*/ +void R_DrawSubmodelPolygons (model_t *pmodel, int clipflags) +{ + int i; + vec_t dot; + msurface_t *psurf; + int numsurfaces; + mplane_t *pplane; + +// FIXME: use bounding-box-based frustum clipping info? + + psurf = &pmodel->surfaces[pmodel->firstmodelsurface]; + numsurfaces = pmodel->nummodelsurfaces; + + for (i=0 ; iplane; + + 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))) + { + r_currentkey = ((mleaf_t *)currententity->topnode)->key; + + // FIXME: use bounding-box-based frustum clipping info? + R_RenderFace (psurf, clipflags); + } + } +} + + +/* +================ +R_RecursiveWorldNode +================ +*/ +void R_RecursiveWorldNode (mnode_t *node, int clipflags) +{ + int i, c, side, *pindex; + vec3_t acceptpt, rejectpt; + mplane_t *plane; + msurface_t *surf, **mark; + mleaf_t *pleaf; + double d, dot; + + if (node->contents == CONTENTS_SOLID) + return; // solid + + if (node->visframe != r_visframecount) + return; + +// cull the clipping planes if not trivial accept +// FIXME: the compiler is doing a lousy job of optimizing here; it could be +// twice as fast in ASM + if (clipflags) + { + for (i=0 ; i<4 ; i++) + { + if (! (clipflags & (1<minmaxs[pindex[0]]; + rejectpt[1] = (float)node->minmaxs[pindex[1]]; + rejectpt[2] = (float)node->minmaxs[pindex[2]]; + + d = DotProduct (rejectpt, view_clipplanes[i].normal); + d -= view_clipplanes[i].dist; + + if (d <= 0) + return; + + acceptpt[0] = (float)node->minmaxs[pindex[3+0]]; + acceptpt[1] = (float)node->minmaxs[pindex[3+1]]; + acceptpt[2] = (float)node->minmaxs[pindex[3+2]]; + + d = DotProduct (acceptpt, view_clipplanes[i].normal); + d -= view_clipplanes[i].dist; + + if (d >= 0) + clipflags &= ~(1<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); + } + + pleaf->key = r_currentkey; + r_currentkey++; // all bmodels in a leaf share the same key + } + else + { + // 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], clipflags); + + // draw stuff + c = node->numsurfaces; + + if (c) + { + surf = cl.worldmodel->surfaces + node->firstsurface; + + if (dot < -BACKFACE_EPSILON) + { + do + { + if ((surf->flags & SURF_PLANEBACK) && + (surf->visframe == r_framecount)) + { + if (r_drawpolys) + { + if (r_worldpolysbacktofront) + { + if (numbtofpolys < MAX_BTOFPOLYS) + { + pbtofpolys[numbtofpolys].clipflags = + clipflags; + pbtofpolys[numbtofpolys].psurf = surf; + numbtofpolys++; + } + } + else + { + R_RenderPoly (surf, clipflags); + } + } + else + { + R_RenderFace (surf, clipflags); + } + } + + surf++; + } while (--c); + } + else if (dot > BACKFACE_EPSILON) + { + do + { + if (!(surf->flags & SURF_PLANEBACK) && + (surf->visframe == r_framecount)) + { + if (r_drawpolys) + { + if (r_worldpolysbacktofront) + { + if (numbtofpolys < MAX_BTOFPOLYS) + { + pbtofpolys[numbtofpolys].clipflags = + clipflags; + pbtofpolys[numbtofpolys].psurf = surf; + numbtofpolys++; + } + } + else + { + R_RenderPoly (surf, clipflags); + } + } + else + { + R_RenderFace (surf, clipflags); + } + } + + surf++; + } while (--c); + } + + // all surfaces on the same node share the same sequence number + r_currentkey++; + } + + // recurse down the back side + R_RecursiveWorldNode (node->children[!side], clipflags); + } +} + + + +/* +================ +R_RenderWorld +================ +*/ +void R_RenderWorld (void) +{ + int i; + model_t *clmodel; + btofpoly_t btofpolys[MAX_BTOFPOLYS]; + + pbtofpolys = btofpolys; + + currententity = &cl_entities[0]; + VectorCopy (r_origin, modelorg); + clmodel = currententity->model; + r_pcurrentvertbase = clmodel->vertexes; + + R_RecursiveWorldNode (clmodel->nodes, 15); + +// if the driver wants the polygons back to front, play the visible ones back +// in that order + if (r_worldpolysbacktofront) + { + for (i=numbtofpolys-1 ; i>=0 ; i--) + { + R_RenderPoly (btofpolys[i].psurf, btofpolys[i].clipflags); + } + } +} + + diff --git a/contrib/other/sdlquake-1.0.9/r_draw.c b/contrib/other/sdlquake-1.0.9/r_draw.c new file mode 100644 index 000000000..2ccf316e2 --- /dev/null +++ b/contrib/other/sdlquake-1.0.9/r_draw.c @@ -0,0 +1,908 @@ +/* +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_draw.c + +#include "quakedef.h" +#include "r_local.h" +#include "d_local.h" // FIXME: shouldn't need to include this + +#define MAXLEFTCLIPEDGES 100 + +// !!! if these are changed, they must be changed in asm_draw.h too !!! +#define FULLY_CLIPPED_CACHED 0x80000000 +#define FRAMECOUNT_MASK 0x7FFFFFFF + +unsigned int cacheoffset; + +int c_faceclip; // number of faces clipped + +zpointdesc_t r_zpointdesc; + +polydesc_t r_polydesc; + + + +clipplane_t *entity_clipplanes; +clipplane_t view_clipplanes[4]; +clipplane_t world_clipplanes[16]; + +medge_t *r_pedge; + +qboolean r_leftclipped, r_rightclipped; +static qboolean makeleftedge, makerightedge; +qboolean r_nearzionly; + +int sintable[SIN_BUFFER_SIZE]; +int intsintable[SIN_BUFFER_SIZE]; + +mvertex_t r_leftenter, r_leftexit; +mvertex_t r_rightenter, r_rightexit; + +typedef struct +{ + float u,v; + int ceilv; +} evert_t; + +int r_emitted; +float r_nearzi; +float r_u1, r_v1, r_lzi1; +int r_ceilv1; + +qboolean r_lastvertvalid; + + +#if !id386 + +/* +================ +R_EmitEdge +================ +*/ +void R_EmitEdge (mvertex_t *pv0, mvertex_t *pv1) +{ + edge_t *edge, *pcheck; + int u_check; + float u, u_step; + vec3_t local, transformed; + float *world; + int v, v2, ceilv0; + float scale, lzi0, u0, v0; + int side; + + if (r_lastvertvalid) + { + u0 = r_u1; + v0 = r_v1; + lzi0 = r_lzi1; + ceilv0 = r_ceilv1; + } + else + { + world = &pv0->position[0]; + + // transform and project + VectorSubtract (world, modelorg, local); + TransformVector (local, transformed); + + if (transformed[2] < NEAR_CLIP) + transformed[2] = NEAR_CLIP; + + lzi0 = 1.0 / transformed[2]; + + // FIXME: build x/yscale into transform? + scale = xscale * lzi0; + u0 = (xcenter + scale*transformed[0]); + if (u0 < r_refdef.fvrectx_adj) + u0 = r_refdef.fvrectx_adj; + if (u0 > r_refdef.fvrectright_adj) + u0 = r_refdef.fvrectright_adj; + + scale = yscale * lzi0; + v0 = (ycenter - scale*transformed[1]); + if (v0 < r_refdef.fvrecty_adj) + v0 = r_refdef.fvrecty_adj; + if (v0 > r_refdef.fvrectbottom_adj) + v0 = r_refdef.fvrectbottom_adj; + + ceilv0 = (int) ceil(v0); + } + + world = &pv1->position[0]; + +// transform and project + VectorSubtract (world, modelorg, local); + TransformVector (local, transformed); + + if (transformed[2] < NEAR_CLIP) + transformed[2] = NEAR_CLIP; + + r_lzi1 = 1.0 / transformed[2]; + + scale = xscale * r_lzi1; + r_u1 = (xcenter + scale*transformed[0]); + if (r_u1 < r_refdef.fvrectx_adj) + r_u1 = r_refdef.fvrectx_adj; + if (r_u1 > r_refdef.fvrectright_adj) + r_u1 = r_refdef.fvrectright_adj; + + scale = yscale * r_lzi1; + r_v1 = (ycenter - scale*transformed[1]); + if (r_v1 < r_refdef.fvrecty_adj) + r_v1 = r_refdef.fvrecty_adj; + if (r_v1 > r_refdef.fvrectbottom_adj) + r_v1 = r_refdef.fvrectbottom_adj; + + if (r_lzi1 > lzi0) + lzi0 = r_lzi1; + + if (lzi0 > r_nearzi) // for mipmap finding + r_nearzi = lzi0; + +// for right edges, all we want is the effect on 1/z + if (r_nearzionly) + return; + + r_emitted = 1; + + r_ceilv1 = (int) ceil(r_v1); + + +// create the edge + if (ceilv0 == r_ceilv1) + { + // we cache unclipped horizontal edges as fully clipped + if (cacheoffset != 0x7FFFFFFF) + { + cacheoffset = FULLY_CLIPPED_CACHED | + (r_framecount & FRAMECOUNT_MASK); + } + + return; // horizontal edge + } + + side = ceilv0 > r_ceilv1; + + edge = edge_p++; + + edge->owner = r_pedge; + + edge->nearzi = lzi0; + + if (side == 0) + { + // trailing edge (go from p1 to p2) + v = ceilv0; + v2 = r_ceilv1 - 1; + + edge->surfs[0] = surface_p - surfaces; + edge->surfs[1] = 0; + + u_step = ((r_u1 - u0) / (r_v1 - v0)); + u = u0 + ((float)v - v0) * u_step; + } + else + { + // leading edge (go from p2 to p1) + v2 = ceilv0 - 1; + v = r_ceilv1; + + edge->surfs[0] = 0; + edge->surfs[1] = surface_p - surfaces; + + u_step = ((u0 - r_u1) / (v0 - r_v1)); + u = r_u1 + ((float)v - r_v1) * u_step; + } + + edge->u_step = u_step*0x100000; + edge->u = u*0x100000 + 0xFFFFF; + +// we need to do this to avoid stepping off the edges if a very nearly +// horizontal edge is less than epsilon above a scan, and numeric error causes +// it to incorrectly extend to the scan, and the extension of the line goes off +// the edge of the screen +// FIXME: is this actually needed? + if (edge->u < r_refdef.vrect_x_adj_shift20) + edge->u = r_refdef.vrect_x_adj_shift20; + if (edge->u > r_refdef.vrectright_adj_shift20) + edge->u = r_refdef.vrectright_adj_shift20; + +// +// sort the edge in normally +// + u_check = edge->u; + if (edge->surfs[0]) + u_check++; // sort trailers after leaders + + if (!newedges[v] || newedges[v]->u >= u_check) + { + edge->next = newedges[v]; + newedges[v] = edge; + } + else + { + pcheck = newedges[v]; + while (pcheck->next && pcheck->next->u < u_check) + pcheck = pcheck->next; + edge->next = pcheck->next; + pcheck->next = edge; + } + + edge->nextremove = removeedges[v2]; + removeedges[v2] = edge; +} + + +/* +================ +R_ClipEdge +================ +*/ +void R_ClipEdge (mvertex_t *pv0, mvertex_t *pv1, clipplane_t *clip) +{ + float d0, d1, f; + mvertex_t clipvert; + + if (clip) + { + do + { + d0 = DotProduct (pv0->position, clip->normal) - clip->dist; + d1 = DotProduct (pv1->position, clip->normal) - clip->dist; + + if (d0 >= 0) + { + // point 0 is unclipped + if (d1 >= 0) + { + // both points are unclipped + continue; + } + + // only point 1 is clipped + + // we don't cache clipped edges + cacheoffset = 0x7FFFFFFF; + + f = d0 / (d0 - d1); + clipvert.position[0] = pv0->position[0] + + f * (pv1->position[0] - pv0->position[0]); + clipvert.position[1] = pv0->position[1] + + f * (pv1->position[1] - pv0->position[1]); + clipvert.position[2] = pv0->position[2] + + f * (pv1->position[2] - pv0->position[2]); + + if (clip->leftedge) + { + r_leftclipped = true; + r_leftexit = clipvert; + } + else if (clip->rightedge) + { + r_rightclipped = true; + r_rightexit = clipvert; + } + + R_ClipEdge (pv0, &clipvert, clip->next); + return; + } + else + { + // point 0 is clipped + if (d1 < 0) + { + // both points are clipped + // we do cache fully clipped edges + if (!r_leftclipped) + cacheoffset = FULLY_CLIPPED_CACHED | + (r_framecount & FRAMECOUNT_MASK); + return; + } + + // only point 0 is clipped + r_lastvertvalid = false; + + // we don't cache partially clipped edges + cacheoffset = 0x7FFFFFFF; + + f = d0 / (d0 - d1); + clipvert.position[0] = pv0->position[0] + + f * (pv1->position[0] - pv0->position[0]); + clipvert.position[1] = pv0->position[1] + + f * (pv1->position[1] - pv0->position[1]); + clipvert.position[2] = pv0->position[2] + + f * (pv1->position[2] - pv0->position[2]); + + if (clip->leftedge) + { + r_leftclipped = true; + r_leftenter = clipvert; + } + else if (clip->rightedge) + { + r_rightclipped = true; + r_rightenter = clipvert; + } + + R_ClipEdge (&clipvert, pv1, clip->next); + return; + } + } while ((clip = clip->next) != NULL); + } + +// add the edge + R_EmitEdge (pv0, pv1); +} + +#endif // !id386 + + +/* +================ +R_EmitCachedEdge +================ +*/ +void R_EmitCachedEdge (void) +{ + edge_t *pedge_t; + + pedge_t = (edge_t *)((unsigned long)r_edges + r_pedge->cachededgeoffset); + + if (!pedge_t->surfs[0]) + pedge_t->surfs[0] = surface_p - surfaces; + else + pedge_t->surfs[1] = surface_p - surfaces; + + if (pedge_t->nearzi > r_nearzi) // for mipmap finding + r_nearzi = pedge_t->nearzi; + + r_emitted = 1; +} + + +/* +================ +R_RenderFace +================ +*/ +void R_RenderFace (msurface_t *fa, int clipflags) +{ + int i, lindex; + unsigned mask; + mplane_t *pplane; + float distinv; + vec3_t p_normal; + medge_t *pedges, tedge; + clipplane_t *pclip; + +// skip out if no more surfs + if ((surface_p) >= surf_max) + { + r_outofsurfaces++; + return; + } + +// ditto if not enough edges left, or switch to auxedges if possible + if ((edge_p + fa->numedges + 4) >= edge_max) + { + r_outofedges += fa->numedges; + return; + } + + c_faceclip++; + +// set up clip planes + pclip = NULL; + + for (i=3, mask = 0x08 ; i>=0 ; i--, mask >>= 1) + { + if (clipflags & mask) + { + view_clipplanes[i].next = pclip; + pclip = &view_clipplanes[i]; + } + } + +// push the edges through + r_emitted = 0; + r_nearzi = 0; + r_nearzionly = false; + makeleftedge = makerightedge = false; + pedges = currententity->model->edges; + r_lastvertvalid = false; + + for (i=0 ; inumedges ; i++) + { + lindex = currententity->model->surfedges[fa->firstedge + i]; + + if (lindex > 0) + { + r_pedge = &pedges[lindex]; + + // if the edge is cached, we can just reuse the edge + if (!insubmodel) + { + if (r_pedge->cachededgeoffset & FULLY_CLIPPED_CACHED) + { + if ((r_pedge->cachededgeoffset & FRAMECOUNT_MASK) == + r_framecount) + { + r_lastvertvalid = false; + continue; + } + } + else + { + if ((((unsigned long)edge_p - (unsigned long)r_edges) > + r_pedge->cachededgeoffset) && + (((edge_t *)((unsigned long)r_edges + + r_pedge->cachededgeoffset))->owner == r_pedge)) + { + R_EmitCachedEdge (); + r_lastvertvalid = false; + continue; + } + } + } + + // assume it's cacheable + cacheoffset = (byte *)edge_p - (byte *)r_edges; + r_leftclipped = r_rightclipped = false; + R_ClipEdge (&r_pcurrentvertbase[r_pedge->v[0]], + &r_pcurrentvertbase[r_pedge->v[1]], + pclip); + r_pedge->cachededgeoffset = cacheoffset; + + if (r_leftclipped) + makeleftedge = true; + if (r_rightclipped) + makerightedge = true; + r_lastvertvalid = true; + } + else + { + lindex = -lindex; + r_pedge = &pedges[lindex]; + // if the edge is cached, we can just reuse the edge + if (!insubmodel) + { + if (r_pedge->cachededgeoffset & FULLY_CLIPPED_CACHED) + { + if ((r_pedge->cachededgeoffset & FRAMECOUNT_MASK) == + r_framecount) + { + r_lastvertvalid = false; + continue; + } + } + else + { + // it's cached if the cached edge is valid and is owned + // by this medge_t + if ((((unsigned long)edge_p - (unsigned long)r_edges) > + r_pedge->cachededgeoffset) && + (((edge_t *)((unsigned long)r_edges + + r_pedge->cachededgeoffset))->owner == r_pedge)) + { + R_EmitCachedEdge (); + r_lastvertvalid = false; + continue; + } + } + } + + // assume it's cacheable + cacheoffset = (byte *)edge_p - (byte *)r_edges; + r_leftclipped = r_rightclipped = false; + R_ClipEdge (&r_pcurrentvertbase[r_pedge->v[1]], + &r_pcurrentvertbase[r_pedge->v[0]], + pclip); + r_pedge->cachededgeoffset = cacheoffset; + + if (r_leftclipped) + makeleftedge = true; + if (r_rightclipped) + makerightedge = true; + r_lastvertvalid = true; + } + } + +// if there was a clip off the left edge, add that edge too +// FIXME: faster to do in screen space? +// FIXME: share clipped edges? + if (makeleftedge) + { + r_pedge = &tedge; + r_lastvertvalid = false; + R_ClipEdge (&r_leftexit, &r_leftenter, pclip->next); + } + +// if there was a clip off the right edge, get the right r_nearzi + if (makerightedge) + { + r_pedge = &tedge; + r_lastvertvalid = false; + r_nearzionly = true; + R_ClipEdge (&r_rightexit, &r_rightenter, view_clipplanes[1].next); + } + +// if no edges made it out, return without posting the surface + if (!r_emitted) + return; + + r_polycount++; + + surface_p->data = (void *)fa; + surface_p->nearzi = r_nearzi; + surface_p->flags = fa->flags; + surface_p->insubmodel = insubmodel; + surface_p->spanstate = 0; + surface_p->entity = currententity; + surface_p->key = r_currentkey++; + surface_p->spans = NULL; + + pplane = fa->plane; +// FIXME: cache this? + TransformVector (pplane->normal, p_normal); +// FIXME: cache this? + distinv = 1.0 / (pplane->dist - DotProduct (modelorg, pplane->normal)); + + surface_p->d_zistepu = p_normal[0] * xscaleinv * distinv; + surface_p->d_zistepv = -p_normal[1] * yscaleinv * distinv; + surface_p->d_ziorigin = p_normal[2] * distinv - + xcenter * surface_p->d_zistepu - + ycenter * surface_p->d_zistepv; + +//JDC VectorCopy (r_worldmodelorg, surface_p->modelorg); + surface_p++; +} + + +/* +================ +R_RenderBmodelFace +================ +*/ +void R_RenderBmodelFace (bedge_t *pedges, msurface_t *psurf) +{ + int i; + unsigned mask; + mplane_t *pplane; + float distinv; + vec3_t p_normal; + medge_t tedge; + clipplane_t *pclip; + +// skip out if no more surfs + if (surface_p >= surf_max) + { + r_outofsurfaces++; + return; + } + +// ditto if not enough edges left, or switch to auxedges if possible + if ((edge_p + psurf->numedges + 4) >= edge_max) + { + r_outofedges += psurf->numedges; + return; + } + + c_faceclip++; + +// this is a dummy to give the caching mechanism someplace to write to + r_pedge = &tedge; + +// set up clip planes + pclip = NULL; + + for (i=3, mask = 0x08 ; i>=0 ; i--, mask >>= 1) + { + if (r_clipflags & mask) + { + view_clipplanes[i].next = pclip; + pclip = &view_clipplanes[i]; + } + } + +// push the edges through + r_emitted = 0; + r_nearzi = 0; + r_nearzionly = false; + makeleftedge = makerightedge = false; +// FIXME: keep clipped bmodel edges in clockwise order so last vertex caching +// can be used? + r_lastvertvalid = false; + + for ( ; pedges ; pedges = pedges->pnext) + { + r_leftclipped = r_rightclipped = false; + R_ClipEdge (pedges->v[0], pedges->v[1], pclip); + + if (r_leftclipped) + makeleftedge = true; + if (r_rightclipped) + makerightedge = true; + } + +// if there was a clip off the left edge, add that edge too +// FIXME: faster to do in screen space? +// FIXME: share clipped edges? + if (makeleftedge) + { + r_pedge = &tedge; + R_ClipEdge (&r_leftexit, &r_leftenter, pclip->next); + } + +// if there was a clip off the right edge, get the right r_nearzi + if (makerightedge) + { + r_pedge = &tedge; + r_nearzionly = true; + R_ClipEdge (&r_rightexit, &r_rightenter, view_clipplanes[1].next); + } + +// if no edges made it out, return without posting the surface + if (!r_emitted) + return; + + r_polycount++; + + surface_p->data = (void *)psurf; + surface_p->nearzi = r_nearzi; + surface_p->flags = psurf->flags; + surface_p->insubmodel = true; + surface_p->spanstate = 0; + surface_p->entity = currententity; + surface_p->key = r_currentbkey; + surface_p->spans = NULL; + + pplane = psurf->plane; +// FIXME: cache this? + TransformVector (pplane->normal, p_normal); +// FIXME: cache this? + distinv = 1.0 / (pplane->dist - DotProduct (modelorg, pplane->normal)); + + surface_p->d_zistepu = p_normal[0] * xscaleinv * distinv; + surface_p->d_zistepv = -p_normal[1] * yscaleinv * distinv; + surface_p->d_ziorigin = p_normal[2] * distinv - + xcenter * surface_p->d_zistepu - + ycenter * surface_p->d_zistepv; + +//JDC VectorCopy (r_worldmodelorg, surface_p->modelorg); + surface_p++; +} + + +/* +================ +R_RenderPoly +================ +*/ +void R_RenderPoly (msurface_t *fa, int clipflags) +{ + int i, lindex, lnumverts, s_axis, t_axis; + float dist, lastdist, lzi, scale, u, v, frac; + unsigned mask; + vec3_t local, transformed; + clipplane_t *pclip; + medge_t *pedges; + mplane_t *pplane; + mvertex_t verts[2][100]; //FIXME: do real number + polyvert_t pverts[100]; //FIXME: do real number, safely + int vertpage, newverts, newpage, lastvert; + qboolean visible; + +// FIXME: clean this up and make it faster +// FIXME: guard against running out of vertices + + s_axis = t_axis = 0; // keep compiler happy + +// set up clip planes + pclip = NULL; + + for (i=3, mask = 0x08 ; i>=0 ; i--, mask >>= 1) + { + if (clipflags & mask) + { + view_clipplanes[i].next = pclip; + pclip = &view_clipplanes[i]; + } + } + +// reconstruct the polygon +// FIXME: these should be precalculated and loaded off disk + pedges = currententity->model->edges; + lnumverts = fa->numedges; + vertpage = 0; + + for (i=0 ; imodel->surfedges[fa->firstedge + i]; + + if (lindex > 0) + { + r_pedge = &pedges[lindex]; + verts[0][i] = r_pcurrentvertbase[r_pedge->v[0]]; + } + else + { + r_pedge = &pedges[-lindex]; + verts[0][i] = r_pcurrentvertbase[r_pedge->v[1]]; + } + } + +// clip the polygon, done if not visible + while (pclip) + { + lastvert = lnumverts - 1; + lastdist = DotProduct (verts[vertpage][lastvert].position, + pclip->normal) - pclip->dist; + + visible = false; + newverts = 0; + newpage = vertpage ^ 1; + + for (i=0 ; inormal) - + pclip->dist; + + if ((lastdist > 0) != (dist > 0)) + { + frac = dist / (dist - lastdist); + verts[newpage][newverts].position[0] = + verts[vertpage][i].position[0] + + ((verts[vertpage][lastvert].position[0] - + verts[vertpage][i].position[0]) * frac); + verts[newpage][newverts].position[1] = + verts[vertpage][i].position[1] + + ((verts[vertpage][lastvert].position[1] - + verts[vertpage][i].position[1]) * frac); + verts[newpage][newverts].position[2] = + verts[vertpage][i].position[2] + + ((verts[vertpage][lastvert].position[2] - + verts[vertpage][i].position[2]) * frac); + newverts++; + } + + if (dist >= 0) + { + verts[newpage][newverts] = verts[vertpage][i]; + newverts++; + visible = true; + } + + lastvert = i; + lastdist = dist; + } + + if (!visible || (newverts < 3)) + return; + + lnumverts = newverts; + vertpage ^= 1; + pclip = pclip->next; + } + +// transform and project, remembering the z values at the vertices and +// r_nearzi, and extract the s and t coordinates at the vertices + pplane = fa->plane; + switch (pplane->type) + { + case PLANE_X: + case PLANE_ANYX: + s_axis = 1; + t_axis = 2; + break; + case PLANE_Y: + case PLANE_ANYY: + s_axis = 0; + t_axis = 2; + break; + case PLANE_Z: + case PLANE_ANYZ: + s_axis = 0; + t_axis = 1; + break; + } + + r_nearzi = 0; + + for (i=0 ; i r_nearzi) // for mipmap finding + r_nearzi = lzi; + + // FIXME: build x/yscale into transform? + scale = xscale * lzi; + u = (xcenter + scale*transformed[0]); + if (u < r_refdef.fvrectx_adj) + u = r_refdef.fvrectx_adj; + if (u > r_refdef.fvrectright_adj) + u = r_refdef.fvrectright_adj; + + scale = yscale * lzi; + v = (ycenter - scale*transformed[1]); + if (v < r_refdef.fvrecty_adj) + v = r_refdef.fvrecty_adj; + if (v > r_refdef.fvrectbottom_adj) + v = r_refdef.fvrectbottom_adj; + + pverts[i].u = u; + pverts[i].v = v; + pverts[i].zi = lzi; + pverts[i].s = verts[vertpage][i].position[s_axis]; + pverts[i].t = verts[vertpage][i].position[t_axis]; + } + +// build the polygon descriptor, including fa, r_nearzi, and u, v, s, t, and z +// for each vertex + r_polydesc.numverts = lnumverts; + r_polydesc.nearzi = r_nearzi; + r_polydesc.pcurrentface = fa; + r_polydesc.pverts = pverts; + +// draw the polygon + D_DrawPoly (); +} + + +/* +================ +R_ZDrawSubmodelPolys +================ +*/ +void R_ZDrawSubmodelPolys (model_t *pmodel) +{ + int i, numsurfaces; + msurface_t *psurf; + float dot; + mplane_t *pplane; + + psurf = &pmodel->surfaces[pmodel->firstmodelsurface]; + numsurfaces = pmodel->nummodelsurfaces; + + for (i=0 ; iplane; + + 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))) + { + // FIXME: use bounding-box-based frustum clipping info? + R_RenderPoly (psurf, 15); + } + } +} + diff --git a/contrib/other/sdlquake-1.0.9/r_drawa.S b/contrib/other/sdlquake-1.0.9/r_drawa.S new file mode 100644 index 000000000..3cb22394e --- /dev/null +++ b/contrib/other/sdlquake-1.0.9/r_drawa.S @@ -0,0 +1,838 @@ +/* +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_drawa.s +// x86 assembly-language edge clipping and emission code +// + +#include "asm_i386.h" +#include "quakeasm.h" +#include "asm_draw.h" +#include "d_ifacea.h" + +#if id386 + +// !!! if these are changed, they must be changed in r_draw.c too !!! +#define FULLY_CLIPPED_CACHED 0x80000000 +#define FRAMECOUNT_MASK 0x7FFFFFFF + + .data + +Ld0: .single 0.0 +Ld1: .single 0.0 +Lstack: .long 0 +Lfp_near_clip: .single NEAR_CLIP +Lceilv0: .long 0 +Lv: .long 0 +Lu0: .long 0 +Lv0: .long 0 +Lzi0: .long 0 + + .text + +//---------------------------------------------------------------------- +// edge clipping code +//---------------------------------------------------------------------- + +#define pv0 4+12 +#define pv1 8+12 +#define clip 12+12 + + .align 4 +.globl C(R_ClipEdge) +C(R_ClipEdge): + pushl %esi // preserve register variables + pushl %edi + pushl %ebx + movl %esp,Lstack // for clearing the stack later + +// float d0, d1, f; +// mvertex_t clipvert; + + movl clip(%esp),%ebx + movl pv0(%esp),%esi + movl pv1(%esp),%edx + +// if (clip) +// { + testl %ebx,%ebx + jz Lemit + +// do +// { + +Lcliploop: + +// d0 = DotProduct (pv0->position, clip->normal) - clip->dist; +// d1 = DotProduct (pv1->position, clip->normal) - clip->dist; + flds mv_position+0(%esi) + fmuls cp_normal+0(%ebx) + flds mv_position+4(%esi) + fmuls cp_normal+4(%ebx) + flds mv_position+8(%esi) + fmuls cp_normal+8(%ebx) + fxch %st(1) + faddp %st(0),%st(2) // d0mul2 | d0add0 + + flds mv_position+0(%edx) + fmuls cp_normal+0(%ebx) + flds mv_position+4(%edx) + fmuls cp_normal+4(%ebx) + flds mv_position+8(%edx) + fmuls cp_normal+8(%ebx) + fxch %st(1) + faddp %st(0),%st(2) // d1mul2 | d1add0 | d0mul2 | d0add0 + fxch %st(3) // d0add0 | d1add0 | d0mul2 | d1mul2 + + faddp %st(0),%st(2) // d1add0 | dot0 | d1mul2 + faddp %st(0),%st(2) // dot0 | dot1 + + fsubs cp_dist(%ebx) // d0 | dot1 + fxch %st(1) // dot1 | d0 + fsubs cp_dist(%ebx) // d1 | d0 + fxch %st(1) + fstps Ld0 + fstps Ld1 + +// if (d0 >= 0) +// { + movl Ld0,%eax + movl Ld1,%ecx + orl %eax,%ecx + js Lp2 + +// both points are unclipped + +Lcontinue: + +// +// R_ClipEdge (&clipvert, pv1, clip->next); +// return; +// } +// } while ((clip = clip->next) != NULL); + movl cp_next(%ebx),%ebx + testl %ebx,%ebx + jnz Lcliploop + +// } + +//// add the edge +// R_EmitEdge (pv0, pv1); +Lemit: + +// +// set integer rounding to ceil mode, set to single precision +// +// FIXME: do away with by manually extracting integers from floats? +// FIXME: set less often + fldcw ceil_cw + +// edge_t *edge, *pcheck; +// int u_check; +// float u, u_step; +// vec3_t local, transformed; +// float *world; +// int v, v2, ceilv0; +// float scale, lzi0, u0, v0; +// int side; + +// if (r_lastvertvalid) +// { + cmpl $0,C(r_lastvertvalid) + jz LCalcFirst + +// u0 = r_u1; +// v0 = r_v1; +// lzi0 = r_lzi1; +// ceilv0 = r_ceilv1; + movl C(r_lzi1),%eax + movl C(r_u1),%ecx + movl %eax,Lzi0 + movl %ecx,Lu0 + movl C(r_v1),%ecx + movl C(r_ceilv1),%eax + movl %ecx,Lv0 + movl %eax,Lceilv0 + jmp LCalcSecond + +// } + +LCalcFirst: + +// else +// { +// world = &pv0->position[0]; + + call LTransformAndProject // v0 | lzi0 | u0 + + fsts Lv0 + fxch %st(2) // u0 | lzi0 | v0 + fstps Lu0 // lzi0 | v0 + fstps Lzi0 // v0 + +// ceilv0 = (int)(v0 - 2000) + 2000; // ceil(v0); + fistpl Lceilv0 + +// } + +LCalcSecond: + +// world = &pv1->position[0]; + movl %edx,%esi + + call LTransformAndProject // v1 | lzi1 | u1 + + flds Lu0 // u0 | v1 | lzi1 | u1 + fxch %st(3) // u1 | v1 | lzi1 | u0 + flds Lzi0 // lzi0 | u1 | v1 | lzi1 | u0 + fxch %st(3) // lzi1 | u1 | v1 | lzi0 | u0 + flds Lv0 // v0 | lzi1 | u1 | v1 | lzi0 | u0 + fxch %st(3) // v1 | lzi1 | u1 | v0 | lzi0 | u0 + +// r_ceilv1 = (int)(r_v1 - 2000) + 2000; // ceil(r_v1); + fistl C(r_ceilv1) + + fldcw single_cw // put back normal floating-point state + + fsts C(r_v1) + fxch %st(4) // lzi0 | lzi1 | u1 | v0 | v1 | u0 + +// if (r_lzi1 > lzi0) +// lzi0 = r_lzi1; + fcom %st(1) + fnstsw %ax + testb $1,%ah + jz LP0 + fstp %st(0) + fld %st(0) +LP0: + + fxch %st(1) // lzi1 | lzi0 | u1 | v0 | v1 | u0 + fstps C(r_lzi1) // lzi0 | u1 | v0 | v1 | u0 + fxch %st(1) + fsts C(r_u1) + fxch %st(1) + +// if (lzi0 > r_nearzi) // for mipmap finding +// r_nearzi = lzi0; + fcoms C(r_nearzi) + fnstsw %ax + testb $0x45,%ah + jnz LP1 + fsts C(r_nearzi) +LP1: + +// // for right edges, all we want is the effect on 1/z +// if (r_nearzionly) +// return; + movl C(r_nearzionly),%eax + testl %eax,%eax + jz LP2 +LPop5AndDone: + movl C(cacheoffset),%eax + movl C(r_framecount),%edx + cmpl $0x7FFFFFFF,%eax + jz LDoPop + andl $(FRAMECOUNT_MASK),%edx + orl $(FULLY_CLIPPED_CACHED),%edx + movl %edx,C(cacheoffset) + +LDoPop: + fstp %st(0) // u1 | v0 | v1 | u0 + fstp %st(0) // v0 | v1 | u0 + fstp %st(0) // v1 | u0 + fstp %st(0) // u0 + fstp %st(0) + jmp Ldone + +LP2: + +// // create the edge +// if (ceilv0 == r_ceilv1) +// return; // horizontal edge + movl Lceilv0,%ebx + movl C(edge_p),%edi + movl C(r_ceilv1),%ecx + movl %edi,%edx + movl C(r_pedge),%esi + addl $(et_size),%edx + cmpl %ecx,%ebx + jz LPop5AndDone + + movl C(r_pedge),%eax + movl %eax,et_owner(%edi) + +// side = ceilv0 > r_ceilv1; +// +// edge->nearzi = lzi0; + fstps et_nearzi(%edi) // u1 | v0 | v1 | u0 + +// if (side == 1) +// { + jc LSide0 + +LSide1: + +// // leading edge (go from p2 to p1) + +// u_step = ((u0 - r_u1) / (v0 - r_v1)); + fsubrp %st(0),%st(3) // v0 | v1 | u0-u1 + fsub %st(1),%st(0) // v0-v1 | v1 | u0-u1 + fdivrp %st(0),%st(2) // v1 | ustep + +// r_emitted = 1; + movl $1,C(r_emitted) + +// edge = edge_p++; + movl %edx,C(edge_p) + +// pretouch next edge + movl (%edx),%eax + +// v2 = ceilv0 - 1; +// v = r_ceilv1; + movl %ecx,%eax + leal -1(%ebx),%ecx + movl %eax,%ebx + +// edge->surfs[0] = 0; +// edge->surfs[1] = surface_p - surfaces; + movl C(surface_p),%eax + movl C(surfaces),%esi + subl %edx,%edx + subl %esi,%eax + shrl $(SURF_T_SHIFT),%eax + movl %edx,et_surfs(%edi) + movl %eax,et_surfs+2(%edi) + + subl %esi,%esi + +// u = r_u1 + ((float)v - r_v1) * u_step; + movl %ebx,Lv + fildl Lv // v | v1 | ustep + fsubp %st(0),%st(1) // v-v1 | ustep + fmul %st(1),%st(0) // (v-v1)*ustep | ustep + fadds C(r_u1) // u | ustep + + jmp LSideDone + +// } + +LSide0: + +// else +// { +// // trailing edge (go from p1 to p2) + +// u_step = ((r_u1 - u0) / (r_v1 - v0)); + fsub %st(3),%st(0) // u1-u0 | v0 | v1 | u0 + fxch %st(2) // v1 | v0 | u1-u0 | u0 + fsub %st(1),%st(0) // v1-v0 | v0 | u1-u0 | u0 + fdivrp %st(0),%st(2) // v0 | ustep | u0 + +// r_emitted = 1; + movl $1,C(r_emitted) + +// edge = edge_p++; + movl %edx,C(edge_p) + +// pretouch next edge + movl (%edx),%eax + +// v = ceilv0; +// v2 = r_ceilv1 - 1; + decl %ecx + +// edge->surfs[0] = surface_p - surfaces; +// edge->surfs[1] = 0; + movl C(surface_p),%eax + movl C(surfaces),%esi + subl %edx,%edx + subl %esi,%eax + shrl $(SURF_T_SHIFT),%eax + movl %edx,et_surfs+2(%edi) + movl %eax,et_surfs(%edi) + + movl $1,%esi + +// u = u0 + ((float)v - v0) * u_step; + movl %ebx,Lv + fildl Lv // v | v0 | ustep | u0 + fsubp %st(0),%st(1) // v-v0 | ustep | u0 + fmul %st(1),%st(0) // (v-v0)*ustep | ustep | u0 + faddp %st(0),%st(2) // ustep | u + fxch %st(1) // u | ustep + +// } + +LSideDone: + +// edge->u_step = u_step*0x100000; +// edge->u = u*0x100000 + 0xFFFFF; + + fmuls fp_1m // u*0x100000 | ustep + fxch %st(1) // ustep | u*0x100000 + fmuls fp_1m // ustep*0x100000 | u*0x100000 + fxch %st(1) // u*0x100000 | ustep*0x100000 + fadds fp_1m_minus_1 // u*0x100000 + 0xFFFFF | ustep*0x100000 + fxch %st(1) // ustep*0x100000 | u*0x100000 + 0xFFFFF + fistpl et_u_step(%edi) // u*0x100000 + 0xFFFFF + fistpl et_u(%edi) + +// // we need to do this to avoid stepping off the edges if a very nearly +// // horizontal edge is less than epsilon above a scan, and numeric error +// // causes it to incorrectly extend to the scan, and the extension of the +// // line goes off the edge of the screen +// // FIXME: is this actually needed? +// if (edge->u < r_refdef.vrect_x_adj_shift20) +// edge->u = r_refdef.vrect_x_adj_shift20; +// if (edge->u > r_refdef.vrectright_adj_shift20) +// edge->u = r_refdef.vrectright_adj_shift20; + movl et_u(%edi),%eax + movl C(r_refdef)+rd_vrect_x_adj_shift20,%edx + cmpl %edx,%eax + jl LP4 + movl C(r_refdef)+rd_vrectright_adj_shift20,%edx + cmpl %edx,%eax + jng LP5 +LP4: + movl %edx,et_u(%edi) + movl %edx,%eax +LP5: + +// // sort the edge in normally +// u_check = edge->u; +// +// if (edge->surfs[0]) +// u_check++; // sort trailers after leaders + addl %esi,%eax + +// if (!newedges[v] || newedges[v]->u >= u_check) +// { + movl C(newedges)(,%ebx,4),%esi + testl %esi,%esi + jz LDoFirst + cmpl %eax,et_u(%esi) + jl LNotFirst +LDoFirst: + +// edge->next = newedges[v]; +// newedges[v] = edge; + movl %esi,et_next(%edi) + movl %edi,C(newedges)(,%ebx,4) + + jmp LSetRemove + +// } + +LNotFirst: + +// else +// { +// pcheck = newedges[v]; +// +// while (pcheck->next && pcheck->next->u < u_check) +// pcheck = pcheck->next; +LFindInsertLoop: + movl %esi,%edx + movl et_next(%esi),%esi + testl %esi,%esi + jz LInsertFound + cmpl %eax,et_u(%esi) + jl LFindInsertLoop + +LInsertFound: + +// edge->next = pcheck->next; +// pcheck->next = edge; + movl %esi,et_next(%edi) + movl %edi,et_next(%edx) + +// } + +LSetRemove: + +// edge->nextremove = removeedges[v2]; +// removeedges[v2] = edge; + movl C(removeedges)(,%ecx,4),%eax + movl %edi,C(removeedges)(,%ecx,4) + movl %eax,et_nextremove(%edi) + +Ldone: + movl Lstack,%esp // clear temporary variables from stack + + popl %ebx // restore register variables + popl %edi + popl %esi + ret + +// at least one point is clipped + +Lp2: + testl %eax,%eax + jns Lp1 + +// else +// { +// // point 0 is clipped + +// if (d1 < 0) +// { + movl Ld1,%eax + testl %eax,%eax + jns Lp3 + +// // both points are clipped +// // we do cache fully clipped edges +// if (!leftclipped) + movl C(r_leftclipped),%eax + movl C(r_pedge),%ecx + testl %eax,%eax + jnz Ldone + +// r_pedge->framecount = r_framecount; + movl C(r_framecount),%eax + andl $(FRAMECOUNT_MASK),%eax + orl $(FULLY_CLIPPED_CACHED),%eax + movl %eax,C(cacheoffset) + +// return; + jmp Ldone + +// } + +Lp1: + +// // point 0 is unclipped +// if (d1 >= 0) +// { +// // both points are unclipped +// continue; + +// // only point 1 is clipped + +// f = d0 / (d0 - d1); + flds Ld0 + flds Ld1 + fsubr %st(1),%st(0) + +// // we don't cache partially clipped edges + movl $0x7FFFFFFF,C(cacheoffset) + + fdivrp %st(0),%st(1) + + subl $(mv_size),%esp // allocate space for clipvert + +// clipvert.position[0] = pv0->position[0] + +// f * (pv1->position[0] - pv0->position[0]); +// clipvert.position[1] = pv0->position[1] + +// f * (pv1->position[1] - pv0->position[1]); +// clipvert.position[2] = pv0->position[2] + +// f * (pv1->position[2] - pv0->position[2]); + flds mv_position+8(%edx) + fsubs mv_position+8(%esi) + flds mv_position+4(%edx) + fsubs mv_position+4(%esi) + flds mv_position+0(%edx) + fsubs mv_position+0(%esi) // 0 | 1 | 2 + +// replace pv1 with the clip point + movl %esp,%edx + movl cp_leftedge(%ebx),%eax + testb %al,%al + + fmul %st(3),%st(0) + fxch %st(1) // 1 | 0 | 2 + fmul %st(3),%st(0) + fxch %st(2) // 2 | 0 | 1 + fmulp %st(0),%st(3) // 0 | 1 | 2 + fadds mv_position+0(%esi) + fxch %st(1) // 1 | 0 | 2 + fadds mv_position+4(%esi) + fxch %st(2) // 2 | 0 | 1 + fadds mv_position+8(%esi) + fxch %st(1) // 0 | 2 | 1 + fstps mv_position+0(%esp) // 2 | 1 + fstps mv_position+8(%esp) // 1 + fstps mv_position+4(%esp) + +// if (clip->leftedge) +// { + jz Ltestright + +// r_leftclipped = true; +// r_leftexit = clipvert; + movl $1,C(r_leftclipped) + movl mv_position+0(%esp),%eax + movl %eax,C(r_leftexit)+mv_position+0 + movl mv_position+4(%esp),%eax + movl %eax,C(r_leftexit)+mv_position+4 + movl mv_position+8(%esp),%eax + movl %eax,C(r_leftexit)+mv_position+8 + + jmp Lcontinue + +// } + +Ltestright: +// else if (clip->rightedge) +// { + testb %ah,%ah + jz Lcontinue + +// r_rightclipped = true; +// r_rightexit = clipvert; + movl $1,C(r_rightclipped) + movl mv_position+0(%esp),%eax + movl %eax,C(r_rightexit)+mv_position+0 + movl mv_position+4(%esp),%eax + movl %eax,C(r_rightexit)+mv_position+4 + movl mv_position+8(%esp),%eax + movl %eax,C(r_rightexit)+mv_position+8 + +// } +// +// R_ClipEdge (pv0, &clipvert, clip->next); +// return; +// } + jmp Lcontinue + +// } + +Lp3: + +// // only point 0 is clipped +// r_lastvertvalid = false; + + movl $0,C(r_lastvertvalid) + +// f = d0 / (d0 - d1); + flds Ld0 + flds Ld1 + fsubr %st(1),%st(0) + +// // we don't cache partially clipped edges + movl $0x7FFFFFFF,C(cacheoffset) + + fdivrp %st(0),%st(1) + + subl $(mv_size),%esp // allocate space for clipvert + +// clipvert.position[0] = pv0->position[0] + +// f * (pv1->position[0] - pv0->position[0]); +// clipvert.position[1] = pv0->position[1] + +// f * (pv1->position[1] - pv0->position[1]); +// clipvert.position[2] = pv0->position[2] + +// f * (pv1->position[2] - pv0->position[2]); + flds mv_position+8(%edx) + fsubs mv_position+8(%esi) + flds mv_position+4(%edx) + fsubs mv_position+4(%esi) + flds mv_position+0(%edx) + fsubs mv_position+0(%esi) // 0 | 1 | 2 + + movl cp_leftedge(%ebx),%eax + testb %al,%al + + fmul %st(3),%st(0) + fxch %st(1) // 1 | 0 | 2 + fmul %st(3),%st(0) + fxch %st(2) // 2 | 0 | 1 + fmulp %st(0),%st(3) // 0 | 1 | 2 + fadds mv_position+0(%esi) + fxch %st(1) // 1 | 0 | 2 + fadds mv_position+4(%esi) + fxch %st(2) // 2 | 0 | 1 + fadds mv_position+8(%esi) + fxch %st(1) // 0 | 2 | 1 + fstps mv_position+0(%esp) // 2 | 1 + fstps mv_position+8(%esp) // 1 + fstps mv_position+4(%esp) + +// replace pv0 with the clip point + movl %esp,%esi + +// if (clip->leftedge) +// { + jz Ltestright2 + +// r_leftclipped = true; +// r_leftenter = clipvert; + movl $1,C(r_leftclipped) + movl mv_position+0(%esp),%eax + movl %eax,C(r_leftenter)+mv_position+0 + movl mv_position+4(%esp),%eax + movl %eax,C(r_leftenter)+mv_position+4 + movl mv_position+8(%esp),%eax + movl %eax,C(r_leftenter)+mv_position+8 + + jmp Lcontinue + +// } + +Ltestright2: +// else if (clip->rightedge) +// { + testb %ah,%ah + jz Lcontinue + +// r_rightclipped = true; +// r_rightenter = clipvert; + movl $1,C(r_rightclipped) + movl mv_position+0(%esp),%eax + movl %eax,C(r_rightenter)+mv_position+0 + movl mv_position+4(%esp),%eax + movl %eax,C(r_rightenter)+mv_position+4 + movl mv_position+8(%esp),%eax + movl %eax,C(r_rightenter)+mv_position+8 + +// } + jmp Lcontinue + +// %esi = vec3_t point to transform and project +// %edx preserved +LTransformAndProject: + +// // transform and project +// VectorSubtract (world, modelorg, local); + flds mv_position+0(%esi) + fsubs C(modelorg)+0 + flds mv_position+4(%esi) + fsubs C(modelorg)+4 + flds mv_position+8(%esi) + fsubs C(modelorg)+8 + fxch %st(2) // local[0] | local[1] | local[2] + +// TransformVector (local, transformed); +// +// if (transformed[2] < NEAR_CLIP) +// transformed[2] = NEAR_CLIP; +// +// lzi0 = 1.0 / transformed[2]; + fld %st(0) // local[0] | local[0] | local[1] | local[2] + fmuls C(vpn)+0 // zm0 | local[0] | local[1] | local[2] + fld %st(1) // local[0] | zm0 | local[0] | local[1] | + // local[2] + fmuls C(vright)+0 // xm0 | zm0 | local[0] | local[1] | local[2] + fxch %st(2) // local[0] | zm0 | xm0 | local[1] | local[2] + fmuls C(vup)+0 // ym0 | zm0 | xm0 | local[1] | local[2] + fld %st(3) // local[1] | ym0 | zm0 | xm0 | local[1] | + // local[2] + fmuls C(vpn)+4 // zm1 | ym0 | zm0 | xm0 | local[1] | + // local[2] + fld %st(4) // local[1] | zm1 | ym0 | zm0 | xm0 | + // local[1] | local[2] + fmuls C(vright)+4 // xm1 | zm1 | ym0 | zm0 | xm0 | + // local[1] | local[2] + fxch %st(5) // local[1] | zm1 | ym0 | zm0 | xm0 | + // xm1 | local[2] + fmuls C(vup)+4 // ym1 | zm1 | ym0 | zm0 | xm0 | + // xm1 | local[2] + fxch %st(1) // zm1 | ym1 | ym0 | zm0 | xm0 | + // xm1 | local[2] + faddp %st(0),%st(3) // ym1 | ym0 | zm2 | xm0 | xm1 | local[2] + fxch %st(3) // xm0 | ym0 | zm2 | ym1 | xm1 | local[2] + faddp %st(0),%st(4) // ym0 | zm2 | ym1 | xm2 | local[2] + faddp %st(0),%st(2) // zm2 | ym2 | xm2 | local[2] + fld %st(3) // local[2] | zm2 | ym2 | xm2 | local[2] + fmuls C(vpn)+8 // zm3 | zm2 | ym2 | xm2 | local[2] + fld %st(4) // local[2] | zm3 | zm2 | ym2 | xm2 | local[2] + fmuls C(vright)+8 // xm3 | zm3 | zm2 | ym2 | xm2 | local[2] + fxch %st(5) // local[2] | zm3 | zm2 | ym2 | xm2 | xm3 + fmuls C(vup)+8 // ym3 | zm3 | zm2 | ym2 | xm2 | xm3 + fxch %st(1) // zm3 | ym3 | zm2 | ym2 | xm2 | xm3 + faddp %st(0),%st(2) // ym3 | zm4 | ym2 | xm2 | xm3 + fxch %st(4) // xm3 | zm4 | ym2 | xm2 | ym3 + faddp %st(0),%st(3) // zm4 | ym2 | xm4 | ym3 + fxch %st(1) // ym2 | zm4 | xm4 | ym3 + faddp %st(0),%st(3) // zm4 | xm4 | ym4 + + fcoms Lfp_near_clip + fnstsw %ax + testb $1,%ah + jz LNoClip + fstp %st(0) + flds Lfp_near_clip + +LNoClip: + + fdivrs float_1 // lzi0 | x | y + fxch %st(1) // x | lzi0 | y + +// // FIXME: build x/yscale into transform? +// scale = xscale * lzi0; +// u0 = (xcenter + scale*transformed[0]); + flds C(xscale) // xscale | x | lzi0 | y + fmul %st(2),%st(0) // scale | x | lzi0 | y + fmulp %st(0),%st(1) // scale*x | lzi0 | y + fadds C(xcenter) // u0 | lzi0 | y + +// if (u0 < r_refdef.fvrectx_adj) +// u0 = r_refdef.fvrectx_adj; +// if (u0 > r_refdef.fvrectright_adj) +// u0 = r_refdef.fvrectright_adj; +// FIXME: use integer compares of floats? + fcoms C(r_refdef)+rd_fvrectx_adj + fnstsw %ax + testb $1,%ah + jz LClampP0 + fstp %st(0) + flds C(r_refdef)+rd_fvrectx_adj +LClampP0: + fcoms C(r_refdef)+rd_fvrectright_adj + fnstsw %ax + testb $0x45,%ah + jnz LClampP1 + fstp %st(0) + flds C(r_refdef)+rd_fvrectright_adj +LClampP1: + + fld %st(1) // lzi0 | u0 | lzi0 | y + +// scale = yscale * lzi0; +// v0 = (ycenter - scale*transformed[1]); + fmuls C(yscale) // scale | u0 | lzi0 | y + fmulp %st(0),%st(3) // u0 | lzi0 | scale*y + fxch %st(2) // scale*y | lzi0 | u0 + fsubrs C(ycenter) // v0 | lzi0 | u0 + +// if (v0 < r_refdef.fvrecty_adj) +// v0 = r_refdef.fvrecty_adj; +// if (v0 > r_refdef.fvrectbottom_adj) +// v0 = r_refdef.fvrectbottom_adj; +// FIXME: use integer compares of floats? + fcoms C(r_refdef)+rd_fvrecty_adj + fnstsw %ax + testb $1,%ah + jz LClampP2 + fstp %st(0) + flds C(r_refdef)+rd_fvrecty_adj +LClampP2: + fcoms C(r_refdef)+rd_fvrectbottom_adj + fnstsw %ax + testb $0x45,%ah + jnz LClampP3 + fstp %st(0) + flds C(r_refdef)+rd_fvrectbottom_adj +LClampP3: + ret + +#endif // id386 + diff --git a/contrib/other/sdlquake-1.0.9/r_edge.c b/contrib/other/sdlquake-1.0.9/r_edge.c new file mode 100644 index 000000000..d4347995b --- /dev/null +++ b/contrib/other/sdlquake-1.0.9/r_edge.c @@ -0,0 +1,774 @@ +/* +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_edge.c + +#include "quakedef.h" +#include "r_local.h" + +#if 0 +// FIXME +the complex cases add new polys on most lines, so dont optimize for keeping them the same +have multiple free span lists to try to get better coherence? +low depth complexity -- 1 to 3 or so + +this breaks spans at every edge, even hidden ones (bad) + +have a sentinal at both ends? +#endif + + +edge_t *auxedges; +edge_t *r_edges, *edge_p, *edge_max; + +surf_t *surfaces, *surface_p, *surf_max; + +// surfaces are generated in back to front order by the bsp, so if a surf +// pointer is greater than another one, it should be drawn in front +// surfaces[1] is the background, and is used as the active surface stack + +edge_t *newedges[MAXHEIGHT]; +edge_t *removeedges[MAXHEIGHT]; + +espan_t *span_p, *max_span_p; + +int r_currentkey; + +extern int screenwidth; + +int current_iv; + +int edge_head_u_shift20, edge_tail_u_shift20; + +static void (*pdrawfunc)(void); + +edge_t edge_head; +edge_t edge_tail; +edge_t edge_aftertail; +edge_t edge_sentinel; + +float fv; + +void R_GenerateSpans (void); +void R_GenerateSpansBackward (void); + +void R_LeadingEdge (edge_t *edge); +void R_LeadingEdgeBackwards (edge_t *edge); +void R_TrailingEdge (surf_t *surf, edge_t *edge); + + +//============================================================================= + + +/* +============== +R_DrawCulledPolys +============== +*/ +void R_DrawCulledPolys (void) +{ + surf_t *s; + msurface_t *pface; + + currententity = &cl_entities[0]; + + if (r_worldpolysbacktofront) + { + for (s=surface_p-1 ; s>&surfaces[1] ; s--) + { + if (!s->spans) + continue; + + if (!(s->flags & SURF_DRAWBACKGROUND)) + { + pface = (msurface_t *)s->data; + R_RenderPoly (pface, 15); + } + } + } + else + { + for (s = &surfaces[1] ; sspans) + continue; + + if (!(s->flags & SURF_DRAWBACKGROUND)) + { + pface = (msurface_t *)s->data; + R_RenderPoly (pface, 15); + } + } + } +} + + +/* +============== +R_BeginEdgeFrame +============== +*/ +void R_BeginEdgeFrame (void) +{ + int v; + + edge_p = r_edges; + edge_max = &r_edges[r_numallocatededges]; + + surface_p = &surfaces[2]; // background is surface 1, + // surface 0 is a dummy + surfaces[1].spans = NULL; // no background spans yet + surfaces[1].flags = SURF_DRAWBACKGROUND; + +// put the background behind everything in the world + if (r_draworder.value) + { + pdrawfunc = R_GenerateSpansBackward; + surfaces[1].key = 0; + r_currentkey = 1; + } + else + { + pdrawfunc = R_GenerateSpans; + surfaces[1].key = 0x7FFFFFFF; + r_currentkey = 0; + } + +// FIXME: set with memset + for (v=r_refdef.vrect.y ; vnext; +edgesearch: + if (edgelist->u >= edgestoadd->u) + goto addedge; + edgelist=edgelist->next; + if (edgelist->u >= edgestoadd->u) + goto addedge; + edgelist=edgelist->next; + if (edgelist->u >= edgestoadd->u) + goto addedge; + edgelist=edgelist->next; + if (edgelist->u >= edgestoadd->u) + goto addedge; + edgelist=edgelist->next; + goto edgesearch; + + // insert edgestoadd before edgelist +addedge: + edgestoadd->next = edgelist; + edgestoadd->prev = edgelist->prev; + edgelist->prev->next = edgestoadd; + edgelist->prev = edgestoadd; + } while ((edgestoadd = next_edge) != NULL); +} + +#endif // !id386 + + +#if !id386 + +/* +============== +R_RemoveEdges +============== +*/ +void R_RemoveEdges (edge_t *pedge) +{ + + do + { + pedge->next->prev = pedge->prev; + pedge->prev->next = pedge->next; + } while ((pedge = pedge->nextremove) != NULL); +} + +#endif // !id386 + + +#if !id386 + +/* +============== +R_StepActiveU +============== +*/ +void R_StepActiveU (edge_t *pedge) +{ + edge_t *pnext_edge, *pwedge; + + while (1) + { +nextedge: + pedge->u += pedge->u_step; + if (pedge->u < pedge->prev->u) + goto pushback; + pedge = pedge->next; + + pedge->u += pedge->u_step; + if (pedge->u < pedge->prev->u) + goto pushback; + pedge = pedge->next; + + pedge->u += pedge->u_step; + if (pedge->u < pedge->prev->u) + goto pushback; + pedge = pedge->next; + + pedge->u += pedge->u_step; + if (pedge->u < pedge->prev->u) + goto pushback; + pedge = pedge->next; + + goto nextedge; + +pushback: + if (pedge == &edge_aftertail) + return; + + // push it back to keep it sorted + pnext_edge = pedge->next; + + // pull the edge out of the edge list + pedge->next->prev = pedge->prev; + pedge->prev->next = pedge->next; + + // find out where the edge goes in the edge list + pwedge = pedge->prev->prev; + + while (pwedge->u > pedge->u) + { + pwedge = pwedge->prev; + } + + // put the edge back into the edge list + pedge->next = pwedge->next; + pedge->prev = pwedge; + pedge->next->prev = pedge; + pwedge->next = pedge; + + pedge = pnext_edge; + if (pedge == &edge_tail) + return; + } +} + +#endif // !id386 + + +/* +============== +R_CleanupSpan +============== +*/ +void R_CleanupSpan () +{ + surf_t *surf; + int iu; + espan_t *span; + +// now that we've reached the right edge of the screen, we're done with any +// unfinished surfaces, so emit a span for whatever's on top + surf = surfaces[1].next; + iu = edge_tail_u_shift20; + if (iu > surf->last_u) + { + span = span_p++; + span->u = surf->last_u; + span->count = iu - span->u; + span->v = current_iv; + span->pnext = surf->spans; + surf->spans = span; + } + +// reset spanstate for all surfaces in the surface stack + do + { + surf->spanstate = 0; + surf = surf->next; + } while (surf != &surfaces[1]); +} + + +/* +============== +R_LeadingEdgeBackwards +============== +*/ +void R_LeadingEdgeBackwards (edge_t *edge) +{ + espan_t *span; + surf_t *surf, *surf2; + int iu; + +// it's adding a new surface in, so find the correct place + surf = &surfaces[edge->surfs[1]]; + +// don't start a span if this is an inverted span, with the end +// edge preceding the start edge (that is, we've already seen the +// end edge) + if (++surf->spanstate == 1) + { + surf2 = surfaces[1].next; + + if (surf->key > surf2->key) + goto newtop; + + // if it's two surfaces on the same plane, the one that's already + // active is in front, so keep going unless it's a bmodel + if (surf->insubmodel && (surf->key == surf2->key)) + { + // must be two bmodels in the same leaf; don't care, because they'll + // never be farthest anyway + goto newtop; + } + +continue_search: + + do + { + surf2 = surf2->next; + } while (surf->key < surf2->key); + + if (surf->key == surf2->key) + { + // if it's two surfaces on the same plane, the one that's already + // active is in front, so keep going unless it's a bmodel + if (!surf->insubmodel) + goto continue_search; + + // must be two bmodels in the same leaf; don't care which is really + // in front, because they'll never be farthest anyway + } + + goto gotposition; + +newtop: + // emit a span (obscures current top) + iu = edge->u >> 20; + + if (iu > surf2->last_u) + { + span = span_p++; + span->u = surf2->last_u; + span->count = iu - span->u; + span->v = current_iv; + span->pnext = surf2->spans; + surf2->spans = span; + } + + // set last_u on the new span + surf->last_u = iu; + +gotposition: + // insert before surf2 + surf->next = surf2; + surf->prev = surf2->prev; + surf2->prev->next = surf; + surf2->prev = surf; + } +} + + +/* +============== +R_TrailingEdge +============== +*/ +void R_TrailingEdge (surf_t *surf, edge_t *edge) +{ + espan_t *span; + int iu; + +// don't generate a span if this is an inverted span, with the end +// edge preceding the start edge (that is, we haven't seen the +// start edge yet) + if (--surf->spanstate == 0) + { + if (surf->insubmodel) + r_bmodelactive--; + + if (surf == surfaces[1].next) + { + // emit a span (current top going away) + iu = edge->u >> 20; + if (iu > surf->last_u) + { + span = span_p++; + span->u = surf->last_u; + span->count = iu - span->u; + span->v = current_iv; + span->pnext = surf->spans; + surf->spans = span; + } + + // set last_u on the surface below + surf->next->last_u = iu; + } + + surf->prev->next = surf->next; + surf->next->prev = surf->prev; + } +} + + +#if !id386 + +/* +============== +R_LeadingEdge +============== +*/ +void R_LeadingEdge (edge_t *edge) +{ + espan_t *span; + surf_t *surf, *surf2; + int iu; + double fu, newzi, testzi, newzitop, newzibottom; + + if (edge->surfs[1]) + { + // it's adding a new surface in, so find the correct place + surf = &surfaces[edge->surfs[1]]; + + // don't start a span if this is an inverted span, with the end + // edge preceding the start edge (that is, we've already seen the + // end edge) + if (++surf->spanstate == 1) + { + if (surf->insubmodel) + r_bmodelactive++; + + surf2 = surfaces[1].next; + + if (surf->key < surf2->key) + goto newtop; + + // if it's two surfaces on the same plane, the one that's already + // active is in front, so keep going unless it's a bmodel + if (surf->insubmodel && (surf->key == surf2->key)) + { + // must be two bmodels in the same leaf; sort on 1/z + fu = (float)(edge->u - 0xFFFFF) * (1.0 / 0x100000); + newzi = surf->d_ziorigin + fv*surf->d_zistepv + + fu*surf->d_zistepu; + newzibottom = newzi * 0.99; + + testzi = surf2->d_ziorigin + fv*surf2->d_zistepv + + fu*surf2->d_zistepu; + + if (newzibottom >= testzi) + { + goto newtop; + } + + newzitop = newzi * 1.01; + if (newzitop >= testzi) + { + if (surf->d_zistepu >= surf2->d_zistepu) + { + goto newtop; + } + } + } + +continue_search: + + do + { + surf2 = surf2->next; + } while (surf->key > surf2->key); + + if (surf->key == surf2->key) + { + // if it's two surfaces on the same plane, the one that's already + // active is in front, so keep going unless it's a bmodel + if (!surf->insubmodel) + goto continue_search; + + // must be two bmodels in the same leaf; sort on 1/z + fu = (float)(edge->u - 0xFFFFF) * (1.0 / 0x100000); + newzi = surf->d_ziorigin + fv*surf->d_zistepv + + fu*surf->d_zistepu; + newzibottom = newzi * 0.99; + + testzi = surf2->d_ziorigin + fv*surf2->d_zistepv + + fu*surf2->d_zistepu; + + if (newzibottom >= testzi) + { + goto gotposition; + } + + newzitop = newzi * 1.01; + if (newzitop >= testzi) + { + if (surf->d_zistepu >= surf2->d_zistepu) + { + goto gotposition; + } + } + + goto continue_search; + } + + goto gotposition; + +newtop: + // emit a span (obscures current top) + iu = edge->u >> 20; + + if (iu > surf2->last_u) + { + span = span_p++; + span->u = surf2->last_u; + span->count = iu - span->u; + span->v = current_iv; + span->pnext = surf2->spans; + surf2->spans = span; + } + + // set last_u on the new span + surf->last_u = iu; + +gotposition: + // insert before surf2 + surf->next = surf2; + surf->prev = surf2->prev; + surf2->prev->next = surf; + surf2->prev = surf; + } + } +} + + +/* +============== +R_GenerateSpans +============== +*/ +void R_GenerateSpans (void) +{ + edge_t *edge; + surf_t *surf; + + r_bmodelactive = 0; + +// clear active surfaces to just the background surface + surfaces[1].next = surfaces[1].prev = &surfaces[1]; + surfaces[1].last_u = edge_head_u_shift20; + +// generate spans + for (edge=edge_head.next ; edge != &edge_tail; edge=edge->next) + { + if (edge->surfs[0]) + { + // it has a left surface, so a surface is going away for this span + surf = &surfaces[edge->surfs[0]]; + + R_TrailingEdge (surf, edge); + + if (!edge->surfs[1]) + continue; + } + + R_LeadingEdge (edge); + } + + R_CleanupSpan (); +} + +#endif // !id386 + + +/* +============== +R_GenerateSpansBackward +============== +*/ +void R_GenerateSpansBackward (void) +{ + edge_t *edge; + + r_bmodelactive = 0; + +// clear active surfaces to just the background surface + surfaces[1].next = surfaces[1].prev = &surfaces[1]; + surfaces[1].last_u = edge_head_u_shift20; + +// generate spans + for (edge=edge_head.next ; edge != &edge_tail; edge=edge->next) + { + if (edge->surfs[0]) + R_TrailingEdge (&surfaces[edge->surfs[0]], edge); + + if (edge->surfs[1]) + R_LeadingEdgeBackwards (edge); + } + + R_CleanupSpan (); +} + + +/* +============== +R_ScanEdges + +Input: +newedges[] array + this has links to edges, which have links to surfaces + +Output: +Each surface has a linked list of its visible spans +============== +*/ +void R_ScanEdges (void) +{ + int iv, bottom; + byte basespans[MAXSPANS*sizeof(espan_t)+CACHE_SIZE]; + espan_t *basespan_p; + surf_t *s; + + basespan_p = (espan_t *) + ((long)(basespans + CACHE_SIZE - 1) & ~(CACHE_SIZE - 1)); + max_span_p = &basespan_p[MAXSPANS - r_refdef.vrect.width]; + + span_p = basespan_p; + +// clear active edges to just the background edges around the whole screen +// FIXME: most of this only needs to be set up once + edge_head.u = r_refdef.vrect.x << 20; + edge_head_u_shift20 = edge_head.u >> 20; + edge_head.u_step = 0; + edge_head.prev = NULL; + edge_head.next = &edge_tail; + edge_head.surfs[0] = 0; + edge_head.surfs[1] = 1; + + edge_tail.u = (r_refdef.vrectright << 20) + 0xFFFFF; + edge_tail_u_shift20 = edge_tail.u >> 20; + edge_tail.u_step = 0; + edge_tail.prev = &edge_head; + edge_tail.next = &edge_aftertail; + edge_tail.surfs[0] = 1; + edge_tail.surfs[1] = 0; + + edge_aftertail.u = -1; // force a move + edge_aftertail.u_step = 0; + edge_aftertail.next = &edge_sentinel; + edge_aftertail.prev = &edge_tail; + +// FIXME: do we need this now that we clamp x in r_draw.c? + edge_sentinel.u = 2000 << 24; // make sure nothing sorts past this + edge_sentinel.prev = &edge_aftertail; + +// +// process all scan lines +// + bottom = r_refdef.vrectbottom - 1; + + for (iv=r_refdef.vrect.y ; iv= max_span_p) + { + VID_UnlockBuffer (); + S_ExtraUpdate (); // don't let sound get messed up if going slow + VID_LockBuffer (); + + if (r_drawculledpolys) + { + R_DrawCulledPolys (); + } + else + { + D_DrawSurfaces (); + } + + // clear the surface span pointers + for (s = &surfaces[1] ; sspans = NULL; + + span_p = basespan_p; + } + + if (removeedges[iv]) + R_RemoveEdges (removeedges[iv]); + + if (edge_head.next != &edge_tail) + R_StepActiveU (edge_head.next); + } + +// do the last scan (no need to step or sort or remove on the last scan) + + current_iv = iv; + fv = (float)iv; + +// mark that the head (background start) span is pre-included + surfaces[1].spanstate = 1; + + if (newedges[iv]) + R_InsertNewEdges (newedges[iv], edge_head.next); + + (*pdrawfunc) (); + +// draw whatever's left in the span list + if (r_drawculledpolys) + R_DrawCulledPolys (); + else + D_DrawSurfaces (); +} + + diff --git a/contrib/other/sdlquake-1.0.9/r_edgea.S b/contrib/other/sdlquake-1.0.9/r_edgea.S new file mode 100644 index 000000000..f67130f11 --- /dev/null +++ b/contrib/other/sdlquake-1.0.9/r_edgea.S @@ -0,0 +1,750 @@ +/* +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_edgea.s +// x86 assembly-language edge-processing code. +// + +#include "asm_i386.h" +#include "quakeasm.h" +#include "asm_draw.h" + +#if id386 + + .data +Ltemp: .long 0 +float_1_div_0100000h: .long 0x35800000 // 1.0/(float)0x100000 +float_point_999: .single 0.999 +float_1_point_001: .single 1.001 + + .text + +//-------------------------------------------------------------------- + +#define edgestoadd 4+8 // note odd stack offsets because of interleaving +#define edgelist 8+12 // with pushes + +.globl C(R_EdgeCodeStart) +C(R_EdgeCodeStart): + +.globl C(R_InsertNewEdges) +C(R_InsertNewEdges): + pushl %edi + pushl %esi // preserve register variables + movl edgestoadd(%esp),%edx + pushl %ebx + movl edgelist(%esp),%ecx + +LDoNextEdge: + movl et_u(%edx),%eax + movl %edx,%edi + +LContinueSearch: + movl et_u(%ecx),%ebx + movl et_next(%ecx),%esi + cmpl %ebx,%eax + jle LAddedge + movl et_u(%esi),%ebx + movl et_next(%esi),%ecx + cmpl %ebx,%eax + jle LAddedge2 + movl et_u(%ecx),%ebx + movl et_next(%ecx),%esi + cmpl %ebx,%eax + jle LAddedge + movl et_u(%esi),%ebx + movl et_next(%esi),%ecx + cmpl %ebx,%eax + jg LContinueSearch + +LAddedge2: + movl et_next(%edx),%edx + movl et_prev(%esi),%ebx + movl %esi,et_next(%edi) + movl %ebx,et_prev(%edi) + movl %edi,et_next(%ebx) + movl %edi,et_prev(%esi) + movl %esi,%ecx + + cmpl $0,%edx + jnz LDoNextEdge + jmp LDone + + .align 4 +LAddedge: + movl et_next(%edx),%edx + movl et_prev(%ecx),%ebx + movl %ecx,et_next(%edi) + movl %ebx,et_prev(%edi) + movl %edi,et_next(%ebx) + movl %edi,et_prev(%ecx) + + cmpl $0,%edx + jnz LDoNextEdge + +LDone: + popl %ebx // restore register variables + popl %esi + popl %edi + + ret + +//-------------------------------------------------------------------- + +#define predge 4+4 + +.globl C(R_RemoveEdges) +C(R_RemoveEdges): + pushl %ebx + movl predge(%esp),%eax + +Lre_loop: + movl et_next(%eax),%ecx + movl et_nextremove(%eax),%ebx + movl et_prev(%eax),%edx + testl %ebx,%ebx + movl %edx,et_prev(%ecx) + jz Lre_done + movl %ecx,et_next(%edx) + + movl et_next(%ebx),%ecx + movl et_prev(%ebx),%edx + movl et_nextremove(%ebx),%eax + movl %edx,et_prev(%ecx) + testl %eax,%eax + movl %ecx,et_next(%edx) + jnz Lre_loop + + popl %ebx + ret + +Lre_done: + movl %ecx,et_next(%edx) + popl %ebx + + ret + +//-------------------------------------------------------------------- + +#define pedgelist 4+4 // note odd stack offset because of interleaving + // with pushes + +.globl C(R_StepActiveU) +C(R_StepActiveU): + pushl %edi + movl pedgelist(%esp),%edx + pushl %esi // preserve register variables + pushl %ebx + + movl et_prev(%edx),%esi + +LNewEdge: + movl et_u(%esi),%edi + +LNextEdge: + movl et_u(%edx),%eax + movl et_u_step(%edx),%ebx + addl %ebx,%eax + movl et_next(%edx),%esi + movl %eax,et_u(%edx) + cmpl %edi,%eax + jl LPushBack + + movl et_u(%esi),%edi + movl et_u_step(%esi),%ebx + addl %ebx,%edi + movl et_next(%esi),%edx + movl %edi,et_u(%esi) + cmpl %eax,%edi + jl LPushBack2 + + movl et_u(%edx),%eax + movl et_u_step(%edx),%ebx + addl %ebx,%eax + movl et_next(%edx),%esi + movl %eax,et_u(%edx) + cmpl %edi,%eax + jl LPushBack + + movl et_u(%esi),%edi + movl et_u_step(%esi),%ebx + addl %ebx,%edi + movl et_next(%esi),%edx + movl %edi,et_u(%esi) + cmpl %eax,%edi + jnl LNextEdge + +LPushBack2: + movl %edx,%ebx + movl %edi,%eax + movl %esi,%edx + movl %ebx,%esi + +LPushBack: +// push it back to keep it sorted + movl et_prev(%edx),%ecx + movl et_next(%edx),%ebx + +// done if the -1 in edge_aftertail triggered this + cmpl $(C(edge_aftertail)),%edx + jz LUDone + +// pull the edge out of the edge list + movl et_prev(%ecx),%edi + movl %ecx,et_prev(%esi) + movl %ebx,et_next(%ecx) + +// find out where the edge goes in the edge list +LPushBackLoop: + movl et_prev(%edi),%ecx + movl et_u(%edi),%ebx + cmpl %ebx,%eax + jnl LPushBackFound + + movl et_prev(%ecx),%edi + movl et_u(%ecx),%ebx + cmpl %ebx,%eax + jl LPushBackLoop + + movl %ecx,%edi + +// put the edge back into the edge list +LPushBackFound: + movl et_next(%edi),%ebx + movl %edi,et_prev(%edx) + movl %ebx,et_next(%edx) + movl %edx,et_next(%edi) + movl %edx,et_prev(%ebx) + + movl %esi,%edx + movl et_prev(%esi),%esi + + cmpl $(C(edge_tail)),%edx + jnz LNewEdge + +LUDone: + popl %ebx // restore register variables + popl %esi + popl %edi + + ret + +//-------------------------------------------------------------------- + +#define surf 4 // note this is loaded before any pushes + + .align 4 +TrailingEdge: + movl st_spanstate(%esi),%eax // check for edge inversion + decl %eax + jnz LInverted + + movl %eax,st_spanstate(%esi) + movl st_insubmodel(%esi),%ecx + movl 0x12345678,%edx // surfaces[1].st_next +LPatch0: + movl C(r_bmodelactive),%eax + subl %ecx,%eax + cmpl %esi,%edx + movl %eax,C(r_bmodelactive) + jnz LNoEmit // surface isn't on top, just remove + +// emit a span (current top going away) + movl et_u(%ebx),%eax + shrl $20,%eax // iu = integral pixel u + movl st_last_u(%esi),%edx + movl st_next(%esi),%ecx + cmpl %edx,%eax + jle LNoEmit2 // iu <= surf->last_u, so nothing to emit + + movl %eax,st_last_u(%ecx) // surf->next->last_u = iu; + subl %edx,%eax + movl %edx,espan_t_u(%ebp) // span->u = surf->last_u; + + movl %eax,espan_t_count(%ebp) // span->count = iu - span->u; + movl C(current_iv),%eax + movl %eax,espan_t_v(%ebp) // span->v = current_iv; + movl st_spans(%esi),%eax + movl %eax,espan_t_pnext(%ebp) // span->pnext = surf->spans; + movl %ebp,st_spans(%esi) // surf->spans = span; + addl $(espan_t_size),%ebp + + movl st_next(%esi),%edx // remove the surface from the surface + movl st_prev(%esi),%esi // stack + + movl %edx,st_next(%esi) + movl %esi,st_prev(%edx) + ret + +LNoEmit2: + movl %eax,st_last_u(%ecx) // surf->next->last_u = iu; + movl st_next(%esi),%edx // remove the surface from the surface + movl st_prev(%esi),%esi // stack + + movl %edx,st_next(%esi) + movl %esi,st_prev(%edx) + ret + +LNoEmit: + movl st_next(%esi),%edx // remove the surface from the surface + movl st_prev(%esi),%esi // stack + + movl %edx,st_next(%esi) + movl %esi,st_prev(%edx) + ret + +LInverted: + movl %eax,st_spanstate(%esi) + ret + +//-------------------------------------------------------------------- + +// trailing edge only +Lgs_trailing: + pushl $Lgs_nextedge + jmp TrailingEdge + + +.globl C(R_GenerateSpans) +C(R_GenerateSpans): + pushl %ebp // preserve caller's stack frame + pushl %edi + pushl %esi // preserve register variables + pushl %ebx + +// clear active surfaces to just the background surface + movl C(surfaces),%eax + movl C(edge_head_u_shift20),%edx + addl $(st_size),%eax +// %ebp = span_p throughout + movl C(span_p),%ebp + + movl $0,C(r_bmodelactive) + + movl %eax,st_next(%eax) + movl %eax,st_prev(%eax) + movl %edx,st_last_u(%eax) + movl C(edge_head)+et_next,%ebx // edge=edge_head.next + +// generate spans + cmpl $(C(edge_tail)),%ebx // done if empty list + jz Lgs_lastspan + +Lgs_edgeloop: + + movl et_surfs(%ebx),%edi + movl C(surfaces),%eax + movl %edi,%esi + andl $0xFFFF0000,%edi + andl $0xFFFF,%esi + jz Lgs_leading // not a trailing edge + +// it has a left surface, so a surface is going away for this span + shll $(SURF_T_SHIFT),%esi + addl %eax,%esi + testl %edi,%edi + jz Lgs_trailing + +// both leading and trailing + call TrailingEdge + movl C(surfaces),%eax + +// --------------------------------------------------------------- +// handle a leading edge +// --------------------------------------------------------------- + +Lgs_leading: + shrl $16-SURF_T_SHIFT,%edi + movl C(surfaces),%eax + addl %eax,%edi + movl 0x12345678,%esi // surf2 = surfaces[1].next; +LPatch2: + movl st_spanstate(%edi),%edx + movl st_insubmodel(%edi),%eax + testl %eax,%eax + jnz Lbmodel_leading + +// handle a leading non-bmodel edge + +// don't start a span if this is an inverted span, with the end edge preceding +// the start edge (that is, we've already seen the end edge) + testl %edx,%edx + jnz Lxl_done + + +// if (surf->key < surf2->key) +// goto newtop; + incl %edx + movl st_key(%edi),%eax + movl %edx,st_spanstate(%edi) + movl st_key(%esi),%ecx + cmpl %ecx,%eax + jl Lnewtop + +// main sorting loop to search through surface stack until insertion point +// found. Always terminates because background surface is sentinel +// do +// { +// surf2 = surf2->next; +// } while (surf->key >= surf2->key); +Lsortloopnb: + movl st_next(%esi),%esi + movl st_key(%esi),%ecx + cmpl %ecx,%eax + jge Lsortloopnb + + jmp LInsertAndExit + + +// handle a leading bmodel edge + .align 4 +Lbmodel_leading: + +// don't start a span if this is an inverted span, with the end edge preceding +// the start edge (that is, we've already seen the end edge) + testl %edx,%edx + jnz Lxl_done + + movl C(r_bmodelactive),%ecx + incl %edx + incl %ecx + movl %edx,st_spanstate(%edi) + movl %ecx,C(r_bmodelactive) + +// if (surf->key < surf2->key) +// goto newtop; + movl st_key(%edi),%eax + movl st_key(%esi),%ecx + cmpl %ecx,%eax + jl Lnewtop + +// if ((surf->key == surf2->key) && surf->insubmodel) +// { + jz Lzcheck_for_newtop + +// main sorting loop to search through surface stack until insertion point +// found. Always terminates because background surface is sentinel +// do +// { +// surf2 = surf2->next; +// } while (surf->key > surf2->key); +Lsortloop: + movl st_next(%esi),%esi + movl st_key(%esi),%ecx + cmpl %ecx,%eax + jg Lsortloop + + jne LInsertAndExit + +// Do 1/z sorting to see if we've arrived in the right position + movl et_u(%ebx),%eax + subl $0xFFFFF,%eax + movl %eax,Ltemp + fildl Ltemp + + fmuls float_1_div_0100000h // fu = (float)(edge->u - 0xFFFFF) * + // (1.0 / 0x100000); + + fld %st(0) // fu | fu + fmuls st_d_zistepu(%edi) // fu*surf->d_zistepu | fu + flds C(fv) // fv | fu*surf->d_zistepu | fu + fmuls st_d_zistepv(%edi) // fv*surf->d_zistepv | fu*surf->d_zistepu | fu + fxch %st(1) // fu*surf->d_zistepu | fv*surf->d_zistepv | fu + fadds st_d_ziorigin(%edi) // fu*surf->d_zistepu + surf->d_ziorigin | + // fv*surf->d_zistepv | fu + + flds st_d_zistepu(%esi) // surf2->d_zistepu | + // fu*surf->d_zistepu + surf->d_ziorigin | + // fv*surf->d_zistepv | fu + fmul %st(3),%st(0) // fu*surf2->d_zistepu | + // fu*surf->d_zistepu + surf->d_ziorigin | + // fv*surf->d_zistepv | fu + fxch %st(1) // fu*surf->d_zistepu + surf->d_ziorigin | + // fu*surf2->d_zistepu | + // fv*surf->d_zistepv | fu + faddp %st(0),%st(2) // fu*surf2->d_zistepu | newzi | fu + + flds C(fv) // fv | fu*surf2->d_zistepu | newzi | fu + fmuls st_d_zistepv(%esi) // fv*surf2->d_zistepv | + // fu*surf2->d_zistepu | newzi | fu + fld %st(2) // newzi | fv*surf2->d_zistepv | + // fu*surf2->d_zistepu | newzi | fu + fmuls float_point_999 // newzibottom | fv*surf2->d_zistepv | + // fu*surf2->d_zistepu | newzi | fu + + fxch %st(2) // fu*surf2->d_zistepu | fv*surf2->d_zistepv | + // newzibottom | newzi | fu + fadds st_d_ziorigin(%esi) // fu*surf2->d_zistepu + surf2->d_ziorigin | + // fv*surf2->d_zistepv | newzibottom | newzi | + // fu + faddp %st(0),%st(1) // testzi | newzibottom | newzi | fu + fxch %st(1) // newzibottom | testzi | newzi | fu + +// if (newzibottom >= testzi) +// goto Lgotposition; + + fcomp %st(1) // testzi | newzi | fu + + fxch %st(1) // newzi | testzi | fu + fmuls float_1_point_001 // newzitop | testzi | fu + fxch %st(1) // testzi | newzitop | fu + + fnstsw %ax + testb $0x01,%ah + jz Lgotposition_fpop3 + +// if (newzitop >= testzi) +// { + + fcomp %st(1) // newzitop | fu + fnstsw %ax + testb $0x45,%ah + jz Lsortloop_fpop2 + +// if (surf->d_zistepu >= surf2->d_zistepu) +// goto newtop; + + flds st_d_zistepu(%edi) // surf->d_zistepu | newzitop| fu + fcomps st_d_zistepu(%esi) // newzitop | fu + fnstsw %ax + testb $0x01,%ah + jz Lgotposition_fpop2 + + fstp %st(0) // clear the FPstack + fstp %st(0) + movl st_key(%edi),%eax + jmp Lsortloop + + +Lgotposition_fpop3: + fstp %st(0) +Lgotposition_fpop2: + fstp %st(0) + fstp %st(0) + jmp LInsertAndExit + + +// emit a span (obscures current top) + +Lnewtop_fpop3: + fstp %st(0) +Lnewtop_fpop2: + fstp %st(0) + fstp %st(0) + movl st_key(%edi),%eax // reload the sorting key + +Lnewtop: + movl et_u(%ebx),%eax + movl st_last_u(%esi),%edx + shrl $20,%eax // iu = integral pixel u + movl %eax,st_last_u(%edi) // surf->last_u = iu; + cmpl %edx,%eax + jle LInsertAndExit // iu <= surf->last_u, so nothing to emit + + subl %edx,%eax + movl %edx,espan_t_u(%ebp) // span->u = surf->last_u; + + movl %eax,espan_t_count(%ebp) // span->count = iu - span->u; + movl C(current_iv),%eax + movl %eax,espan_t_v(%ebp) // span->v = current_iv; + movl st_spans(%esi),%eax + movl %eax,espan_t_pnext(%ebp) // span->pnext = surf->spans; + movl %ebp,st_spans(%esi) // surf->spans = span; + addl $(espan_t_size),%ebp + +LInsertAndExit: +// insert before surf2 + movl %esi,st_next(%edi) // surf->next = surf2; + movl st_prev(%esi),%eax + movl %eax,st_prev(%edi) // surf->prev = surf2->prev; + movl %edi,st_prev(%esi) // surf2->prev = surf; + movl %edi,st_next(%eax) // surf2->prev->next = surf; + +// --------------------------------------------------------------- +// leading edge done +// --------------------------------------------------------------- + +// --------------------------------------------------------------- +// see if there are any more edges +// --------------------------------------------------------------- + +Lgs_nextedge: + movl et_next(%ebx),%ebx + cmpl $(C(edge_tail)),%ebx + jnz Lgs_edgeloop + +// clean up at the right edge +Lgs_lastspan: + +// now that we've reached the right edge of the screen, we're done with any +// unfinished surfaces, so emit a span for whatever's on top + movl 0x12345678,%esi // surfaces[1].st_next +LPatch3: + movl C(edge_tail_u_shift20),%eax + xorl %ecx,%ecx + movl st_last_u(%esi),%edx + subl %edx,%eax + jle Lgs_resetspanstate + + movl %edx,espan_t_u(%ebp) + movl %eax,espan_t_count(%ebp) + movl C(current_iv),%eax + movl %eax,espan_t_v(%ebp) + movl st_spans(%esi),%eax + movl %eax,espan_t_pnext(%ebp) + movl %ebp,st_spans(%esi) + addl $(espan_t_size),%ebp + +// reset spanstate for all surfaces in the surface stack +Lgs_resetspanstate: + movl %ecx,st_spanstate(%esi) + movl st_next(%esi),%esi + cmpl $0x12345678,%esi // &surfaces[1] +LPatch4: + jnz Lgs_resetspanstate + +// store the final span_p + movl %ebp,C(span_p) + + popl %ebx // restore register variables + popl %esi + popl %edi + popl %ebp // restore the caller's stack frame + ret + + +// --------------------------------------------------------------- +// 1/z sorting for bmodels in the same leaf +// --------------------------------------------------------------- + .align 4 +Lxl_done: + incl %edx + movl %edx,st_spanstate(%edi) + + jmp Lgs_nextedge + + + .align 4 +Lzcheck_for_newtop: + movl et_u(%ebx),%eax + subl $0xFFFFF,%eax + movl %eax,Ltemp + fildl Ltemp + + fmuls float_1_div_0100000h // fu = (float)(edge->u - 0xFFFFF) * + // (1.0 / 0x100000); + + fld %st(0) // fu | fu + fmuls st_d_zistepu(%edi) // fu*surf->d_zistepu | fu + flds C(fv) // fv | fu*surf->d_zistepu | fu + fmuls st_d_zistepv(%edi) // fv*surf->d_zistepv | fu*surf->d_zistepu | fu + fxch %st(1) // fu*surf->d_zistepu | fv*surf->d_zistepv | fu + fadds st_d_ziorigin(%edi) // fu*surf->d_zistepu + surf->d_ziorigin | + // fv*surf->d_zistepv | fu + + flds st_d_zistepu(%esi) // surf2->d_zistepu | + // fu*surf->d_zistepu + surf->d_ziorigin | + // fv*surf->d_zistepv | fu + fmul %st(3),%st(0) // fu*surf2->d_zistepu | + // fu*surf->d_zistepu + surf->d_ziorigin | + // fv*surf->d_zistepv | fu + fxch %st(1) // fu*surf->d_zistepu + surf->d_ziorigin | + // fu*surf2->d_zistepu | + // fv*surf->d_zistepv | fu + faddp %st(0),%st(2) // fu*surf2->d_zistepu | newzi | fu + + flds C(fv) // fv | fu*surf2->d_zistepu | newzi | fu + fmuls st_d_zistepv(%esi) // fv*surf2->d_zistepv | + // fu*surf2->d_zistepu | newzi | fu + fld %st(2) // newzi | fv*surf2->d_zistepv | + // fu*surf2->d_zistepu | newzi | fu + fmuls float_point_999 // newzibottom | fv*surf2->d_zistepv | + // fu*surf2->d_zistepu | newzi | fu + + fxch %st(2) // fu*surf2->d_zistepu | fv*surf2->d_zistepv | + // newzibottom | newzi | fu + fadds st_d_ziorigin(%esi) // fu*surf2->d_zistepu + surf2->d_ziorigin | + // fv*surf2->d_zistepv | newzibottom | newzi | + // fu + faddp %st(0),%st(1) // testzi | newzibottom | newzi | fu + fxch %st(1) // newzibottom | testzi | newzi | fu + +// if (newzibottom >= testzi) +// goto newtop; + + fcomp %st(1) // testzi | newzi | fu + + fxch %st(1) // newzi | testzi | fu + fmuls float_1_point_001 // newzitop | testzi | fu + fxch %st(1) // testzi | newzitop | fu + + fnstsw %ax + testb $0x01,%ah + jz Lnewtop_fpop3 + +// if (newzitop >= testzi) +// { + + fcomp %st(1) // newzitop | fu + fnstsw %ax + testb $0x45,%ah + jz Lsortloop_fpop2 + +// if (surf->d_zistepu >= surf2->d_zistepu) +// goto newtop; + + flds st_d_zistepu(%edi) // surf->d_zistepu | newzitop | fu + fcomps st_d_zistepu(%esi) // newzitop | fu + fnstsw %ax + testb $0x01,%ah + jz Lnewtop_fpop2 + +Lsortloop_fpop2: + fstp %st(0) // clear the FP stack + fstp %st(0) + movl st_key(%edi),%eax + jmp Lsortloop + + +.globl C(R_EdgeCodeEnd) +C(R_EdgeCodeEnd): + + +//---------------------------------------------------------------------- +// Surface array address code patching routine +//---------------------------------------------------------------------- + + .align 4 +.globl C(R_SurfacePatch) +C(R_SurfacePatch): + + movl C(surfaces),%eax + addl $(st_size),%eax + movl %eax,LPatch4-4 + + addl $(st_next),%eax + movl %eax,LPatch0-4 + movl %eax,LPatch2-4 + movl %eax,LPatch3-4 + + ret + +#endif // id386 + diff --git a/contrib/other/sdlquake-1.0.9/r_efrag.c b/contrib/other/sdlquake-1.0.9/r_efrag.c new file mode 100644 index 000000000..5e4d3f9e0 --- /dev/null +++ b/contrib/other/sdlquake-1.0.9/r_efrag.c @@ -0,0 +1,276 @@ +/* +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_efrag.c + +#include "quakedef.h" +#include "r_local.h" + +mnode_t *r_pefragtopnode; + + +//=========================================================================== + +/* +=============================================================================== + + ENTITY FRAGMENT FUNCTIONS + +=============================================================================== +*/ + +efrag_t **lastlink; + +vec3_t r_emins, r_emaxs; + +entity_t *r_addent; + + +/* +================ +R_RemoveEfrags + +Call when removing an object from the world or moving it to another position +================ +*/ +void R_RemoveEfrags (entity_t *ent) +{ + efrag_t *ef, *old, *walk, **prev; + + ef = ent->efrag; + + while (ef) + { + 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; + + // put it on the free list + old->entnext = cl.free_efrags; + cl.free_efrags = old; + } + + ent->efrag = NULL; +} + +/* +=================== +R_SplitEntityOnNode +=================== +*/ +void R_SplitEntityOnNode (mnode_t *node) +{ + efrag_t *ef; + 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) + { + if (!r_pefragtopnode) + r_pefragtopnode = 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->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 + // if this is the first splitter of this bmodel, remember it + 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_SplitEntityOnNode2 +=================== +*/ +void R_SplitEntityOnNode2 (mnode_t *node) +{ + mplane_t *splitplane; + int sides; + + if (node->visframe != r_visframecount) + return; + + if (node->contents < 0) + { + if (node->contents != CONTENTS_SOLID) + r_pefragtopnode = node; // we've reached a non-solid leaf, so it's + // visible and not BSP clipped + return; + } + + splitplane = node->plane; + sides = BOX_ON_PLANE_SIDE(r_emins, r_emaxs, splitplane); + + if (sides == 3) + { + // remember first splitter + r_pefragtopnode = node; + return; + } + +// not split yet; recurse down the contacted side + if (sides & 1) + R_SplitEntityOnNode2 (node->children[0]); + else + R_SplitEntityOnNode2 (node->children[1]); +} + + +/* +=========== +R_AddEfrags +=========== +*/ +void R_AddEfrags (entity_t *ent) +{ + model_t *entmodel; + int i; + + if (!ent->model) + return; + + if (ent == cl_entities) + return; // never add the world + + r_addent = ent; + + lastlink = &ent->efrag; + r_pefragtopnode = NULL; + + entmodel = ent->model; + + for (i=0 ; i<3 ; i++) + { + r_emins[i] = ent->origin[i] + entmodel->mins[i]; + r_emaxs[i] = ent->origin[i] + entmodel->maxs[i]; + } + + R_SplitEntityOnNode (cl.worldmodel->nodes); + + ent->topnode = r_pefragtopnode; +} + + +/* +================ +R_StoreEfrags + +// FIXME: a lot of this goes away with edge-based +================ +*/ +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) + { + 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); + } + } +} + + diff --git a/contrib/other/sdlquake-1.0.9/r_light.c b/contrib/other/sdlquake-1.0.9/r_light.c new file mode 100644 index 000000000..f735d50d8 --- /dev/null +++ b/contrib/other/sdlquake-1.0.9/r_light.c @@ -0,0 +1,260 @@ +/* +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_light.c + +#include "quakedef.h" +#include "r_local.h" + +int r_dlightframecount; + + +/* +================== +R_AnimateLight +================== +*/ +void R_AnimateLight (void) +{ + int i,j,k; + +// +// light animations +// 'm' is normal light, 'a' is no light, 'z' is double bright + i = (int)(cl.time*10); + for (j=0 ; jcontents < 0) + return; + + splitplane = node->plane; + dist = DotProduct (light->origin, splitplane->normal) - splitplane->dist; + + if (dist > light->radius) + { + R_MarkLights (light, bit, node->children[0]); + return; + } + if (dist < -light->radius) + { + R_MarkLights (light, bit, node->children[1]); + return; + } + +// mark the polygons + surf = cl.worldmodel->surfaces + node->firstsurface; + for (i=0 ; inumsurfaces ; i++, surf++) + { + if (surf->dlightframe != r_dlightframecount) + { + surf->dlightbits = 0; + surf->dlightframe = r_dlightframecount; + } + surf->dlightbits |= bit; + } + + R_MarkLights (light, bit, node->children[0]); + R_MarkLights (light, bit, node->children[1]); +} + + +/* +============= +R_PushDlights +============= +*/ +void R_PushDlights (void) +{ + int i; + dlight_t *l; + + r_dlightframecount = r_framecount + 1; // because the count hasn't + // advanced yet for this frame + l = cl_dlights; + + for (i=0 ; idie < cl.time || !l->radius) + continue; + R_MarkLights ( l, 1<nodes ); + } +} + + +/* +============================================================================= + +LIGHT SAMPLING + +============================================================================= +*/ + +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 + + 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); +} + +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; + + if (r < r_refdef.ambientlight) + r = r_refdef.ambientlight; + + return r; +} + diff --git a/contrib/other/sdlquake-1.0.9/r_local.h b/contrib/other/sdlquake-1.0.9/r_local.h new file mode 100644 index 000000000..e75f59717 --- /dev/null +++ b/contrib/other/sdlquake-1.0.9/r_local.h @@ -0,0 +1,316 @@ +/* +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_local.h -- private refresh defs + +#ifndef GLQUAKE +#include "r_shared.h" + +#define ALIAS_BASE_SIZE_RATIO (1.0 / 11.0) + // normalizing factor so player model works out to about + // 1 pixel per triangle + +#define BMODEL_FULLY_CLIPPED 0x10 // value returned by R_BmodelCheckBBox () + // if bbox is trivially rejected + +//=========================================================================== +// viewmodel lighting + +typedef struct { + int ambientlight; + int shadelight; + float *plightvec; +} alight_t; + +//=========================================================================== +// clipped bmodel edges + +typedef struct bedge_s +{ + mvertex_t *v[2]; + struct bedge_s *pnext; +} bedge_t; + +typedef struct { + float fv[3]; // viewspace x, y +} auxvert_t; + +//=========================================================================== + +extern cvar_t r_draworder; +extern cvar_t r_speeds; +extern cvar_t r_timegraph; +extern cvar_t r_graphheight; +extern cvar_t r_clearcolor; +extern cvar_t r_waterwarp; +extern cvar_t r_fullbright; +extern cvar_t r_drawentities; +extern cvar_t r_aliasstats; +extern cvar_t r_dspeeds; +extern cvar_t r_drawflat; +extern cvar_t r_ambient; +extern cvar_t r_reportsurfout; +extern cvar_t r_maxsurfs; +extern cvar_t r_numsurfs; +extern cvar_t r_reportedgeout; +extern cvar_t r_maxedges; +extern cvar_t r_numedges; + +#define XCENTERING (1.0 / 2.0) +#define YCENTERING (1.0 / 2.0) + +#define CLIP_EPSILON 0.001 + +#define BACKFACE_EPSILON 0.01 + +//=========================================================================== + +#define DIST_NOT_SET 98765 + +// !!! if this is changed, it must be changed in asm_draw.h too !!! +typedef struct clipplane_s +{ + vec3_t normal; + float dist; + struct clipplane_s *next; + byte leftedge; + byte rightedge; + byte reserved[2]; +} clipplane_t; + +extern clipplane_t view_clipplanes[4]; + +//============================================================================= + +void R_RenderWorld (void); + +//============================================================================= + +extern mplane_t screenedge[4]; + +extern vec3_t r_origin; + +extern vec3_t r_entorigin; + +extern float screenAspect; +extern float verticalFieldOfView; +extern float xOrigin, yOrigin; + +extern int r_visframecount; + +//============================================================================= + +extern int vstartscan; + + +void R_ClearPolyList (void); +void R_DrawPolyList (void); + +// +// current entity info +// +extern qboolean insubmodel; +extern vec3_t r_worldmodelorg; + + +void R_DrawSprite (void); +void R_RenderFace (msurface_t *fa, int clipflags); +void R_RenderPoly (msurface_t *fa, int clipflags); +void R_RenderBmodelFace (bedge_t *pedges, msurface_t *psurf); +void R_TransformPlane (mplane_t *p, float *normal, float *dist); +void R_TransformFrustum (void); +void R_SetSkyFrame (void); +void R_DrawSurfaceBlock16 (void); +void R_DrawSurfaceBlock8 (void); +texture_t *R_TextureAnimation (texture_t *base); + +#if id386 + +void R_DrawSurfaceBlock8_mip0 (void); +void R_DrawSurfaceBlock8_mip1 (void); +void R_DrawSurfaceBlock8_mip2 (void); +void R_DrawSurfaceBlock8_mip3 (void); + +#endif + +void R_GenSkyTile (void *pdest); +void R_GenSkyTile16 (void *pdest); +void R_Surf8Patch (void); +void R_Surf16Patch (void); +void R_DrawSubmodelPolygons (model_t *pmodel, int clipflags); +void R_DrawSolidClippedSubmodelPolygons (model_t *pmodel); + +void R_AddPolygonEdges (emitpoint_t *pverts, int numverts, int miplevel); +surf_t *R_GetSurf (void); +void R_AliasDrawModel (alight_t *plighting); +void R_BeginEdgeFrame (void); +void R_ScanEdges (void); +void D_DrawSurfaces (void); +void R_InsertNewEdges (edge_t *edgestoadd, edge_t *edgelist); +void R_StepActiveU (edge_t *pedge); +void R_RemoveEdges (edge_t *pedge); + +extern void R_Surf8Start (void); +extern void R_Surf8End (void); +extern void R_Surf16Start (void); +extern void R_Surf16End (void); +extern void R_EdgeCodeStart (void); +extern void R_EdgeCodeEnd (void); + +extern void R_RotateBmodel (void); + +extern int c_faceclip; +extern int r_polycount; +extern int r_wholepolycount; + +extern model_t *cl_worldmodel; + +extern int *pfrustum_indexes[4]; + +// !!! if this is changed, it must be changed in asm_draw.h too !!! +#define NEAR_CLIP 0.01 + +extern int ubasestep, errorterm, erroradjustup, erroradjustdown; +extern int vstartscan; + +extern fixed16_t sadjust, tadjust; +extern fixed16_t bbextents, bbextentt; + +#define MAXBVERTINDEXES 1000 // new clipped vertices when clipping bmodels + // to the world BSP +extern mvertex_t *r_ptverts, *r_ptvertsmax; + +extern vec3_t sbaseaxis[3], tbaseaxis[3]; +extern float entity_rotation[3][3]; + +extern int reinit_surfcache; + +extern int r_currentkey; +extern int r_currentbkey; + +typedef struct btofpoly_s { + int clipflags; + msurface_t *psurf; +} btofpoly_t; + +#define MAX_BTOFPOLYS 5000 // FIXME: tune this + +extern int numbtofpolys; +extern btofpoly_t *pbtofpolys; + +void R_InitTurb (void); +void R_ZDrawSubmodelPolys (model_t *clmodel); + +//========================================================= +// Alias models +//========================================================= + +#define MAXALIASVERTS 2000 // TODO: tune this +#define ALIAS_Z_CLIP_PLANE 5 + +extern int numverts; +extern int a_skinwidth; +extern mtriangle_t *ptriangles; +extern int numtriangles; +extern aliashdr_t *paliashdr; +extern mdl_t *pmdl; +extern float leftclip, topclip, rightclip, bottomclip; +extern int r_acliptype; +extern finalvert_t *pfinalverts; +extern auxvert_t *pauxverts; + +qboolean R_AliasCheckBBox (void); + +//========================================================= +// turbulence stuff + +#define AMP 8*0x10000 +#define AMP2 3 +#define SPEED 20 + +//========================================================= +// particle stuff + +void R_DrawParticles (void); +void R_InitParticles (void); +void R_ClearParticles (void); +void R_ReadPointFile_f (void); +void R_SurfacePatch (void); + +extern int r_amodels_drawn; +extern edge_t *auxedges; +extern int r_numallocatededges; +extern edge_t *r_edges, *edge_p, *edge_max; + +extern edge_t *newedges[MAXHEIGHT]; +extern edge_t *removeedges[MAXHEIGHT]; + +extern int screenwidth; + +// FIXME: make stack vars when debugging done +extern edge_t edge_head; +extern edge_t edge_tail; +extern edge_t edge_aftertail; +extern int r_bmodelactive; +extern vrect_t *pconupdate; + +extern float aliasxscale, aliasyscale, aliasxcenter, aliasycenter; +extern float r_aliastransition, r_resfudge; + +extern int r_outofsurfaces; +extern int r_outofedges; + +extern mvertex_t *r_pcurrentvertbase; +extern int r_maxvalidedgeoffset; + +void R_AliasClipTriangle (mtriangle_t *ptri); + +extern float r_time1; +extern float dp_time1, dp_time2, db_time1, db_time2, rw_time1, rw_time2; +extern float se_time1, se_time2, de_time1, de_time2, dv_time1, dv_time2; +extern int r_frustum_indexes[4*6]; +extern int r_maxsurfsseen, r_maxedgesseen, r_cnumsurfs; +extern qboolean r_surfsonstack; +extern cshift_t cshift_water; +extern qboolean r_dowarpold, r_viewchanged; + +extern mleaf_t *r_viewleaf, *r_oldviewleaf; + +extern vec3_t r_emins, r_emaxs; +extern mnode_t *r_pefragtopnode; +extern int r_clipflags; +extern int r_dlightframecount; +extern qboolean r_fov_greater_than_90; + +void R_StoreEfrags (efrag_t **ppefrag); +void R_TimeRefresh_f (void); +void R_TimeGraph (void); +void R_PrintAliasStats (void); +void R_PrintTimes (void); +void R_PrintDSpeeds (void); +void R_AnimateLight (void); +int R_LightPoint (vec3_t p); +void R_SetupFrame (void); +void R_cshift_f (void); +void R_EmitEdge (mvertex_t *pv0, mvertex_t *pv1); +void R_ClipEdge (mvertex_t *pv0, mvertex_t *pv1, clipplane_t *clip); +void R_SplitEntityOnNode2 (mnode_t *node); +void R_MarkLights (dlight_t *light, int bit, mnode_t *node); + +#endif \ No newline at end of file diff --git a/contrib/other/sdlquake-1.0.9/r_main.c b/contrib/other/sdlquake-1.0.9/r_main.c new file mode 100644 index 000000000..3fe51464f --- /dev/null +++ b/contrib/other/sdlquake-1.0.9/r_main.c @@ -0,0 +1,1085 @@ +/* +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" +#include "r_local.h" + +//define PASSAGES + +void *colormap; +vec3_t viewlightvec; +alight_t r_viewlighting = {128, 192, viewlightvec}; +float r_time1; +int r_numallocatededges; +qboolean r_drawpolys; +qboolean r_drawculledpolys; +qboolean r_worldpolysbacktofront; +qboolean r_recursiveaffinetriangles = true; +int r_pixbytes = 1; +float r_aliasuvscale = 1.0; +int r_outofsurfaces; +int r_outofedges; + +qboolean r_dowarp, r_dowarpold, r_viewchanged; + +int numbtofpolys; +btofpoly_t *pbtofpolys; +mvertex_t *r_pcurrentvertbase; + +int c_surf; +int r_maxsurfsseen, r_maxedgesseen, r_cnumsurfs; +qboolean r_surfsonstack; +int r_clipflags; + +byte *r_warpbuffer; + +byte *r_stack_start; + +qboolean r_fov_greater_than_90; + +// +// view origin +// +vec3_t vup, base_vup; +vec3_t vpn, base_vpn; +vec3_t vright, base_vright; +vec3_t r_origin; + +// +// screen size info +// +refdef_t r_refdef; +float xcenter, ycenter; +float xscale, yscale; +float xscaleinv, yscaleinv; +float xscaleshrink, yscaleshrink; +float aliasxscale, aliasyscale, aliasxcenter, aliasycenter; + +int screenwidth; + +float pixelAspect; +float screenAspect; +float verticalFieldOfView; +float xOrigin, yOrigin; + +mplane_t screenedge[4]; + +// +// refresh flags +// +int r_framecount = 1; // so frame counts initialized to 0 don't match +int r_visframecount; +int d_spanpixcount; +int r_polycount; +int r_drawnpolycount; +int r_wholepolycount; + +#define VIEWMODNAME_LENGTH 256 +char viewmodname[VIEWMODNAME_LENGTH+1]; +int modcount; + +int *pfrustum_indexes[4]; +int r_frustum_indexes[4*6]; + +int reinit_surfcache = 1; // if 1, surface cache is currently empty and + // must be reinitialized for current cache size + +mleaf_t *r_viewleaf, *r_oldviewleaf; + +texture_t *r_notexture_mip; + +float r_aliastransition, r_resfudge; + +int d_lightstylevalue[256]; // 8.8 fraction of base light value + +float dp_time1, dp_time2, db_time1, db_time2, rw_time1, rw_time2; +float se_time1, se_time2, de_time1, de_time2, dv_time1, dv_time2; + +void R_MarkLeaves (void); + +cvar_t r_draworder = {"r_draworder","0"}; +cvar_t r_speeds = {"r_speeds","0"}; +cvar_t r_timegraph = {"r_timegraph","0"}; +cvar_t r_graphheight = {"r_graphheight","10"}; +cvar_t r_clearcolor = {"r_clearcolor","2"}; +cvar_t r_waterwarp = {"r_waterwarp","1"}; +cvar_t r_fullbright = {"r_fullbright","0"}; +cvar_t r_drawentities = {"r_drawentities","1"}; +cvar_t r_drawviewmodel = {"r_drawviewmodel","1"}; +cvar_t r_aliasstats = {"r_polymodelstats","0"}; +cvar_t r_dspeeds = {"r_dspeeds","0"}; +cvar_t r_drawflat = {"r_drawflat", "0"}; +cvar_t r_ambient = {"r_ambient", "0"}; +cvar_t r_reportsurfout = {"r_reportsurfout", "0"}; +cvar_t r_maxsurfs = {"r_maxsurfs", "0"}; +cvar_t r_numsurfs = {"r_numsurfs", "0"}; +cvar_t r_reportedgeout = {"r_reportedgeout", "0"}; +cvar_t r_maxedges = {"r_maxedges", "0"}; +cvar_t r_numedges = {"r_numedges", "0"}; +cvar_t r_aliastransbase = {"r_aliastransbase", "200"}; +cvar_t r_aliastransadj = {"r_aliastransadj", "100"}; + +extern cvar_t scr_fov; + +void CreatePassages (void); +void SetVisibilityByPassages (void); + +/* +================== +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; + } + } +} + +/* +=============== +R_Init +=============== +*/ +void R_Init (void) +{ + int dummy; + +// get stack position so we can guess if we are going to overflow + r_stack_start = (byte *)&dummy; + + R_InitTurb (); + + Cmd_AddCommand ("timerefresh", R_TimeRefresh_f); + Cmd_AddCommand ("pointfile", R_ReadPointFile_f); + + Cvar_RegisterVariable (&r_draworder); + Cvar_RegisterVariable (&r_speeds); + Cvar_RegisterVariable (&r_timegraph); + Cvar_RegisterVariable (&r_graphheight); + Cvar_RegisterVariable (&r_drawflat); + Cvar_RegisterVariable (&r_ambient); + Cvar_RegisterVariable (&r_clearcolor); + Cvar_RegisterVariable (&r_waterwarp); + Cvar_RegisterVariable (&r_fullbright); + Cvar_RegisterVariable (&r_drawentities); + Cvar_RegisterVariable (&r_drawviewmodel); + Cvar_RegisterVariable (&r_aliasstats); + Cvar_RegisterVariable (&r_dspeeds); + Cvar_RegisterVariable (&r_reportsurfout); + Cvar_RegisterVariable (&r_maxsurfs); + Cvar_RegisterVariable (&r_numsurfs); + Cvar_RegisterVariable (&r_reportedgeout); + Cvar_RegisterVariable (&r_maxedges); + Cvar_RegisterVariable (&r_numedges); + Cvar_RegisterVariable (&r_aliastransbase); + Cvar_RegisterVariable (&r_aliastransadj); + + Cvar_SetValue ("r_maxedges", (float)NUMSTACKEDGES); + Cvar_SetValue ("r_maxsurfs", (float)NUMSTACKSURFACES); + + view_clipplanes[0].leftedge = true; + view_clipplanes[1].rightedge = true; + view_clipplanes[1].leftedge = view_clipplanes[2].leftedge = + view_clipplanes[3].leftedge = false; + view_clipplanes[0].rightedge = view_clipplanes[2].rightedge = + view_clipplanes[3].rightedge = false; + + r_refdef.xOrigin = XCENTERING; + r_refdef.yOrigin = YCENTERING; + + R_InitParticles (); + +// TODO: collect 386-specific code in one place +#if id386 + Sys_MakeCodeWriteable ((long)R_EdgeCodeStart, + (long)R_EdgeCodeEnd - (long)R_EdgeCodeStart); +#endif // id386 + + D_Init (); +} + +/* +=============== +R_NewMap +=============== +*/ +void R_NewMap (void) +{ + int i; + +// 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 (); + + r_cnumsurfs = r_maxsurfs.value; + + if (r_cnumsurfs <= MINSURFACES) + r_cnumsurfs = MINSURFACES; + + if (r_cnumsurfs > NUMSTACKSURFACES) + { + surfaces = Hunk_AllocName (r_cnumsurfs * sizeof(surf_t), "surfaces"); + surface_p = surfaces; + surf_max = &surfaces[r_cnumsurfs]; + r_surfsonstack = false; + // surface 0 doesn't really exist; it's just a dummy because index 0 + // is used to indicate no edge attached to surface + surfaces--; + R_SurfacePatch (); + } + else + { + r_surfsonstack = true; + } + + r_maxedgesseen = 0; + r_maxsurfsseen = 0; + + r_numallocatededges = r_maxedges.value; + + if (r_numallocatededges < MINEDGES) + r_numallocatededges = MINEDGES; + + if (r_numallocatededges <= NUMSTACKEDGES) + { + auxedges = NULL; + } + else + { + auxedges = Hunk_AllocName (r_numallocatededges * sizeof(edge_t), + "edges"); + } + + r_dowarpold = false; + r_viewchanged = false; +#ifdef PASSAGES +CreatePassages (); +#endif +} + + +/* +=============== +R_SetVrect +=============== +*/ +void R_SetVrect (vrect_t *pvrectin, vrect_t *pvrect, int lineadj) +{ + int h; + float size; + + size = scr_viewsize.value > 100 ? 100 : scr_viewsize.value; + if (cl.intermission) + { + size = 100; + lineadj = 0; + } + size /= 100; + + h = pvrectin->height - lineadj; + pvrect->width = pvrectin->width * size; + if (pvrect->width < 96) + { + size = 96.0 / pvrectin->width; + pvrect->width = 96; // min for icons + } + pvrect->width &= ~7; + pvrect->height = pvrectin->height * size; + if (pvrect->height > pvrectin->height - lineadj) + pvrect->height = pvrectin->height - lineadj; + + pvrect->height &= ~1; + + pvrect->x = (pvrectin->width - pvrect->width)/2; + pvrect->y = (h - pvrect->height)/2; + + { + if (lcd_x.value) + { + pvrect->y >>= 1; + pvrect->height >>= 1; + } + } +} + + +/* +=============== +R_ViewChanged + +Called every time the vid structure or r_refdef changes. +Guaranteed to be called before the first refresh +=============== +*/ +void R_ViewChanged (vrect_t *pvrect, int lineadj, float aspect) +{ + int i; + float res_scale; + + r_viewchanged = true; + + R_SetVrect (pvrect, &r_refdef.vrect, lineadj); + + r_refdef.horizontalFieldOfView = 2.0 * tan (r_refdef.fov_x/360*M_PI); + r_refdef.fvrectx = (float)r_refdef.vrect.x; + r_refdef.fvrectx_adj = (float)r_refdef.vrect.x - 0.5; + r_refdef.vrect_x_adj_shift20 = (r_refdef.vrect.x<<20) + (1<<19) - 1; + r_refdef.fvrecty = (float)r_refdef.vrect.y; + r_refdef.fvrecty_adj = (float)r_refdef.vrect.y - 0.5; + r_refdef.vrectright = r_refdef.vrect.x + r_refdef.vrect.width; + r_refdef.vrectright_adj_shift20 = (r_refdef.vrectright<<20) + (1<<19) - 1; + r_refdef.fvrectright = (float)r_refdef.vrectright; + r_refdef.fvrectright_adj = (float)r_refdef.vrectright - 0.5; + r_refdef.vrectrightedge = (float)r_refdef.vrectright - 0.99; + r_refdef.vrectbottom = r_refdef.vrect.y + r_refdef.vrect.height; + r_refdef.fvrectbottom = (float)r_refdef.vrectbottom; + r_refdef.fvrectbottom_adj = (float)r_refdef.vrectbottom - 0.5; + + r_refdef.aliasvrect.x = (int)(r_refdef.vrect.x * r_aliasuvscale); + r_refdef.aliasvrect.y = (int)(r_refdef.vrect.y * r_aliasuvscale); + r_refdef.aliasvrect.width = (int)(r_refdef.vrect.width * r_aliasuvscale); + r_refdef.aliasvrect.height = (int)(r_refdef.vrect.height * r_aliasuvscale); + r_refdef.aliasvrectright = r_refdef.aliasvrect.x + + r_refdef.aliasvrect.width; + r_refdef.aliasvrectbottom = r_refdef.aliasvrect.y + + r_refdef.aliasvrect.height; + + pixelAspect = aspect; + xOrigin = r_refdef.xOrigin; + yOrigin = r_refdef.yOrigin; + + screenAspect = r_refdef.vrect.width*pixelAspect / + r_refdef.vrect.height; +// 320*200 1.0 pixelAspect = 1.6 screenAspect +// 320*240 1.0 pixelAspect = 1.3333 screenAspect +// proper 320*200 pixelAspect = 0.8333333 + + verticalFieldOfView = r_refdef.horizontalFieldOfView / screenAspect; + +// values for perspective projection +// if math were exact, the values would range from 0.5 to to range+0.5 +// hopefully they wll be in the 0.000001 to range+.999999 and truncate +// the polygon rasterization will never render in the first row or column +// but will definately render in the [range] row and column, so adjust the +// buffer origin to get an exact edge to edge fill + xcenter = ((float)r_refdef.vrect.width * XCENTERING) + + r_refdef.vrect.x - 0.5; + aliasxcenter = xcenter * r_aliasuvscale; + ycenter = ((float)r_refdef.vrect.height * YCENTERING) + + r_refdef.vrect.y - 0.5; + aliasycenter = ycenter * r_aliasuvscale; + + xscale = r_refdef.vrect.width / r_refdef.horizontalFieldOfView; + aliasxscale = xscale * r_aliasuvscale; + xscaleinv = 1.0 / xscale; + yscale = xscale * pixelAspect; + aliasyscale = yscale * r_aliasuvscale; + yscaleinv = 1.0 / yscale; + xscaleshrink = (r_refdef.vrect.width-6)/r_refdef.horizontalFieldOfView; + yscaleshrink = xscaleshrink*pixelAspect; + +// left side clip + screenedge[0].normal[0] = -1.0 / (xOrigin*r_refdef.horizontalFieldOfView); + screenedge[0].normal[1] = 0; + screenedge[0].normal[2] = 1; + screenedge[0].type = PLANE_ANYZ; + +// right side clip + screenedge[1].normal[0] = + 1.0 / ((1.0-xOrigin)*r_refdef.horizontalFieldOfView); + screenedge[1].normal[1] = 0; + screenedge[1].normal[2] = 1; + screenedge[1].type = PLANE_ANYZ; + +// top side clip + screenedge[2].normal[0] = 0; + screenedge[2].normal[1] = -1.0 / (yOrigin*verticalFieldOfView); + screenedge[2].normal[2] = 1; + screenedge[2].type = PLANE_ANYZ; + +// bottom side clip + screenedge[3].normal[0] = 0; + screenedge[3].normal[1] = 1.0 / ((1.0-yOrigin)*verticalFieldOfView); + screenedge[3].normal[2] = 1; + screenedge[3].type = PLANE_ANYZ; + + for (i=0 ; i<4 ; i++) + VectorNormalize (screenedge[i].normal); + + res_scale = sqrt ((double)(r_refdef.vrect.width * r_refdef.vrect.height) / + (320.0 * 152.0)) * + (2.0 / r_refdef.horizontalFieldOfView); + r_aliastransition = r_aliastransbase.value * res_scale; + r_resfudge = r_aliastransadj.value * res_scale; + + if (scr_fov.value <= 90.0) + r_fov_greater_than_90 = false; + else + r_fov_greater_than_90 = true; + +// TODO: collect 386-specific code in one place +#if id386 + if (r_pixbytes == 1) + { + Sys_MakeCodeWriteable ((long)R_Surf8Start, + (long)R_Surf8End - (long)R_Surf8Start); + colormap = vid.colormap; + R_Surf8Patch (); + } + else + { + Sys_MakeCodeWriteable ((long)R_Surf16Start, + (long)R_Surf16End - (long)R_Surf16Start); + colormap = vid.colormap16; + R_Surf16Patch (); + } +#endif // id386 + + D_ViewChanged (); +} + + +/* +=============== +R_MarkLeaves +=============== +*/ +void R_MarkLeaves (void) +{ + byte *vis; + mnode_t *node; + int i; + + if (r_oldviewleaf == r_viewleaf) + return; + + r_visframecount++; + r_oldviewleaf = r_viewleaf; + + 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); + } + } +} + + +/* +============= +R_DrawEntitiesOnList +============= +*/ +void R_DrawEntitiesOnList (void) +{ + int i, j; + int lnum; + alight_t lighting; +// FIXME: remove and do real lighting + float lightvec[3] = {-1, 0, 0}; + vec3_t dist; + float add; + + if (!r_drawentities.value) + return; + + for (i=0 ; imodel->type) + { + case mod_sprite: + VectorCopy (currententity->origin, r_entorigin); + VectorSubtract (r_origin, r_entorigin, modelorg); + R_DrawSprite (); + break; + + case mod_alias: + VectorCopy (currententity->origin, r_entorigin); + VectorSubtract (r_origin, r_entorigin, modelorg); + + // see if the bounding box lets us trivially reject, also sets + // trivial accept status + if (R_AliasCheckBBox ()) + { + j = R_LightPoint (currententity->origin); + + lighting.ambientlight = j; + lighting.shadelight = j; + + lighting.plightvec = lightvec; + + for (lnum=0 ; lnum= cl.time) + { + VectorSubtract (currententity->origin, + cl_dlights[lnum].origin, + dist); + add = cl_dlights[lnum].radius - Length(dist); + + if (add > 0) + lighting.ambientlight += add; + } + } + + // clamp lighting so it doesn't overbright as much + if (lighting.ambientlight > 128) + lighting.ambientlight = 128; + if (lighting.ambientlight + lighting.shadelight > 192) + lighting.shadelight = 192 - lighting.ambientlight; + + R_AliasDrawModel (&lighting); + } + + break; + + default: + break; + } + } +} + +/* +============= +R_DrawViewModel +============= +*/ +void R_DrawViewModel (void) +{ +// FIXME: remove and do real lighting + float lightvec[3] = {-1, 0, 0}; + int j; + int lnum; + vec3_t dist; + float add; + dlight_t *dl; + + if (!r_drawviewmodel.value || r_fov_greater_than_90) + return; + + if (cl.items & IT_INVISIBILITY) + return; + + if (cl.stats[STAT_HEALTH] <= 0) + return; + + currententity = &cl.viewent; + if (!currententity->model) + return; + + VectorCopy (currententity->origin, r_entorigin); + VectorSubtract (r_origin, r_entorigin, modelorg); + + VectorCopy (vup, viewlightvec); + VectorInverse (viewlightvec); + + j = R_LightPoint (currententity->origin); + + if (j < 24) + j = 24; // allways give some light on gun + r_viewlighting.ambientlight = j; + r_viewlighting.shadelight = j; + +// 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) + r_viewlighting.ambientlight += add; + } + +// clamp lighting so it doesn't overbright as much + if (r_viewlighting.ambientlight > 128) + r_viewlighting.ambientlight = 128; + if (r_viewlighting.ambientlight + r_viewlighting.shadelight > 192) + r_viewlighting.shadelight = 192 - r_viewlighting.ambientlight; + + r_viewlighting.plightvec = lightvec; + +#ifdef QUAKE2 + cl.light_level = r_viewlighting.ambientlight; +#endif + + R_AliasDrawModel (&r_viewlighting); +} + + +/* +============= +R_BmodelCheckBBox +============= +*/ +int R_BmodelCheckBBox (model_t *clmodel, float *minmaxs) +{ + int i, *pindex, clipflags; + vec3_t acceptpt, rejectpt; + double d; + + clipflags = 0; + + if (currententity->angles[0] || currententity->angles[1] + || currententity->angles[2]) + { + for (i=0 ; i<4 ; i++) + { + d = DotProduct (currententity->origin, view_clipplanes[i].normal); + d -= view_clipplanes[i].dist; + + if (d <= -clmodel->radius) + return BMODEL_FULLY_CLIPPED; + + if (d <= clmodel->radius) + clipflags |= (1<model->type) + { + case mod_brush: + + clmodel = currententity->model; + + // see if the bounding box lets us trivially reject, also sets + // trivial accept status + for (j=0 ; j<3 ; j++) + { + minmaxs[j] = currententity->origin[j] + + clmodel->mins[j]; + minmaxs[3+j] = currententity->origin[j] + + clmodel->maxs[j]; + } + + clipflags = R_BmodelCheckBBox (clmodel, minmaxs); + + if (clipflags != BMODEL_FULLY_CLIPPED) + { + VectorCopy (currententity->origin, r_entorigin); + VectorSubtract (r_origin, r_entorigin, modelorg); + // FIXME: is this needed? + VectorCopy (modelorg, r_worldmodelorg); + + r_pcurrentvertbase = clmodel->vertexes; + + // FIXME: stop transforming twice + R_RotateBmodel (); + + // calculate dynamic lighting for bmodel if it's not an + // instanced model + if (clmodel->firstmodelsurface != 0) + { + for (k=0 ; knodes + clmodel->hulls[0].firstclipnode); + } + } + + // if the driver wants polygons, deliver those. Z-buffering is on + // at this point, so no clipping to the world tree is needed, just + // frustum clipping + if (r_drawpolys | r_drawculledpolys) + { + R_ZDrawSubmodelPolys (clmodel); + } + else + { + r_pefragtopnode = NULL; + + for (j=0 ; j<3 ; j++) + { + r_emins[j] = minmaxs[j]; + r_emaxs[j] = minmaxs[3+j]; + } + + R_SplitEntityOnNode2 (cl.worldmodel->nodes); + + if (r_pefragtopnode) + { + currententity->topnode = r_pefragtopnode; + + if (r_pefragtopnode->contents >= 0) + { + // not a leaf; has to be clipped to the world BSP + r_clipflags = clipflags; + R_DrawSolidClippedSubmodelPolygons (clmodel); + } + else + { + // falls entirely in one leaf, so we just put all the + // edges in the edge list and let 1/z sorting handle + // drawing order + R_DrawSubmodelPolygons (clmodel, clipflags); + } + + currententity->topnode = NULL; + } + } + + // put back world rotation and frustum clipping + // FIXME: R_RotateBmodel should just work off base_vxx + VectorCopy (base_vpn, vpn); + VectorCopy (base_vup, vup); + VectorCopy (base_vright, vright); + VectorCopy (base_modelorg, modelorg); + VectorCopy (oldorigin, modelorg); + R_TransformFrustum (); + } + + break; + + default: + break; + } + } + + insubmodel = false; +} + + +/* +================ +R_EdgeDrawing +================ +*/ +void R_EdgeDrawing (void) +{ + edge_t ledges[NUMSTACKEDGES + + ((CACHE_SIZE - 1) / sizeof(edge_t)) + 1]; + surf_t lsurfs[NUMSTACKSURFACES + + ((CACHE_SIZE - 1) / sizeof(surf_t)) + 1]; + + if (auxedges) + { + r_edges = auxedges; + } + else + { + r_edges = (edge_t *) + (((long)&ledges[0] + CACHE_SIZE - 1) & ~(CACHE_SIZE - 1)); + } + + if (r_surfsonstack) + { + surfaces = (surf_t *) + (((long)&lsurfs[0] + CACHE_SIZE - 1) & ~(CACHE_SIZE - 1)); + surf_max = &surfaces[r_cnumsurfs]; + // surface 0 doesn't really exist; it's just a dummy because index 0 + // is used to indicate no edge attached to surface + surfaces--; + R_SurfacePatch (); + } + + R_BeginEdgeFrame (); + + if (r_dspeeds.value) + { + rw_time1 = Sys_FloatTime (); + } + + R_RenderWorld (); + + if (r_drawculledpolys) + R_ScanEdges (); + +// only the world can be drawn back to front with no z reads or compares, just +// z writes, so have the driver turn z compares on now + D_TurnZOn (); + + if (r_dspeeds.value) + { + rw_time2 = Sys_FloatTime (); + db_time1 = rw_time2; + } + + R_DrawBEntitiesOnList (); + + if (r_dspeeds.value) + { + db_time2 = Sys_FloatTime (); + se_time1 = db_time2; + } + + if (!r_dspeeds.value) + { + VID_UnlockBuffer (); + S_ExtraUpdate (); // don't let sound get messed up if going slow + VID_LockBuffer (); + } + + if (!(r_drawpolys | r_drawculledpolys)) + R_ScanEdges (); +} + + +/* +================ +R_RenderView + +r_refdef must be set before the first call +================ +*/ +void R_RenderView_ (void) +{ + byte warpbuffer[WARP_WIDTH * WARP_HEIGHT]; + + r_warpbuffer = warpbuffer; + + if (r_timegraph.value || r_speeds.value || r_dspeeds.value) + r_time1 = Sys_FloatTime (); + + R_SetupFrame (); + +#ifdef PASSAGES +SetVisibilityByPassages (); +#else + R_MarkLeaves (); // done here so we know if we're in water +#endif + +// make FDIV fast. This reduces timing precision after we've been running for a +// while, so we don't do it globally. This also sets chop mode, and we do it +// here so that setup stuff like the refresh area calculations match what's +// done in screen.c + Sys_LowFPPrecision (); + + if (!cl_entities[0].model || !cl.worldmodel) + Sys_Error ("R_RenderView: NULL worldmodel"); + + if (!r_dspeeds.value) + { + VID_UnlockBuffer (); + S_ExtraUpdate (); // don't let sound get messed up if going slow + VID_LockBuffer (); + } + + R_EdgeDrawing (); + + if (!r_dspeeds.value) + { + VID_UnlockBuffer (); + S_ExtraUpdate (); // don't let sound get messed up if going slow + VID_LockBuffer (); + } + + if (r_dspeeds.value) + { + se_time2 = Sys_FloatTime (); + de_time1 = se_time2; + } + + R_DrawEntitiesOnList (); + + if (r_dspeeds.value) + { + de_time2 = Sys_FloatTime (); + dv_time1 = de_time2; + } + + R_DrawViewModel (); + + if (r_dspeeds.value) + { + dv_time2 = Sys_FloatTime (); + dp_time1 = Sys_FloatTime (); + } + + R_DrawParticles (); + + if (r_dspeeds.value) + dp_time2 = Sys_FloatTime (); + + if (r_dowarp) + D_WarpScreen (); + + V_SetContentsColor (r_viewleaf->contents); + + if (r_timegraph.value) + R_TimeGraph (); + + if (r_aliasstats.value) + R_PrintAliasStats (); + + if (r_speeds.value) + R_PrintTimes (); + + if (r_dspeeds.value) + R_PrintDSpeeds (); + + if (r_reportsurfout.value && r_outofsurfaces) + Con_Printf ("Short %d surfaces\n", r_outofsurfaces); + + if (r_reportedgeout.value && r_outofedges) + Con_Printf ("Short roughly %d edges\n", r_outofedges * 2 / 3); + +// back to high floating-point precision + Sys_HighFPPrecision (); +} + +void R_RenderView (void) +{ + int dummy; + int delta; + + delta = (byte *)&dummy - r_stack_start; + if (delta < -10000 || delta > 10000) + Sys_Error ("R_RenderView: called without enough stack"); + + if ( Hunk_LowMark() & 3 ) + Sys_Error ("Hunk is missaligned"); + + if ( (long)(&dummy) & 3 ) + Sys_Error ("Stack is missaligned"); + + if ( (long)(&r_warpbuffer) & 3 ) + Sys_Error ("Globals are missaligned"); + + R_RenderView_ (); +} + +/* +================ +R_InitTurb +================ +*/ +void R_InitTurb (void) +{ + int i; + + for (i=0 ; i<(SIN_BUFFER_SIZE) ; i++) + { + sintable[i] = AMP + sin(i*3.14159*2/CYCLE)*AMP; + intsintable[i] = AMP2 + sin(i*3.14159*2/CYCLE)*AMP2; // AMP2, not 20 + } +} + diff --git a/contrib/other/sdlquake-1.0.9/r_misc.c b/contrib/other/sdlquake-1.0.9/r_misc.c new file mode 100644 index 000000000..c0aa7e991 --- /dev/null +++ b/contrib/other/sdlquake-1.0.9/r_misc.c @@ -0,0 +1,523 @@ +/* +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" +#include "r_local.h" + + +/* +=============== +R_CheckVariables +=============== +*/ +void R_CheckVariables (void) +{ + static float oldbright; + + if (r_fullbright.value != oldbright) + { + oldbright = r_fullbright.value; + D_FlushCaches (); // so all lighting changes + } +} + + +/* +============ +Show + +Debugging use +============ +*/ +void Show (void) +{ + vrect_t vr; + + vr.x = vr.y = 0; + vr.width = vid.width; + vr.height = vid.height; + vr.pnext = NULL; + VID_Update (&vr); +} + + +/* +==================== +R_TimeRefresh_f + +For program optimization +==================== +*/ +void R_TimeRefresh_f (void) +{ + int i; + float start, stop, time; + int startangle; + vrect_t vr; + + startangle = r_refdef.viewangles[1]; + + start = Sys_FloatTime (); + for (i=0 ; i<128 ; i++) + { + r_refdef.viewangles[1] = i/128.0*360.0; + + VID_LockBuffer (); + + R_RenderView (); + + VID_UnlockBuffer (); + + vr.x = r_refdef.vrect.x; + vr.y = r_refdef.vrect.y; + vr.width = r_refdef.vrect.width; + vr.height = r_refdef.vrect.height; + vr.pnext = NULL; + VID_Update (&vr); + } + stop = Sys_FloatTime (); + time = stop-start; + Con_Printf ("%f seconds (%f fps)\n", time, 128/time); + + r_refdef.viewangles[1] = startangle; +} + + +/* +================ +R_LineGraph + +Only called by R_DisplayTime +================ +*/ +void R_LineGraph (int x, int y, int h) +{ + int i; + byte *dest; + int s; + +// FIXME: should be disabled on no-buffer adapters, or should be in the driver + + x += r_refdef.vrect.x; + y += r_refdef.vrect.y; + + dest = vid.buffer + vid.rowbytes*y + x; + + s = r_graphheight.value; + + if (h>s) + h = s; + + for (i=0 ; inormal); + *dist = p->dist - d; +// TODO: when we have rotating entities, this will need to use the view matrix + TransformVector (p->normal, normal); +} + + +/* +=============== +R_SetUpFrustumIndexes +=============== +*/ +void R_SetUpFrustumIndexes (void) +{ + int i, j, *pindex; + + pindex = r_frustum_indexes; + + for (i=0 ; i<4 ; i++) + { + for (j=0 ; j<3 ; j++) + { + if (view_clipplanes[i].normal[j] < 0) + { + pindex[j] = j; + pindex[j+3] = j+3; + } + else + { + pindex[j] = j+3; + pindex[j+3] = j; + } + } + + // FIXME: do just once at start + pfrustum_indexes[i] = pindex; + pindex += 6; + } +} + + +/* +=============== +R_SetupFrame +=============== +*/ +void R_SetupFrame (void) +{ + int edgecount; + vrect_t vrect; + float w, h; + +// don't allow cheats in multiplayer + if (cl.maxclients > 1) + { + Cvar_Set ("r_draworder", "0"); + Cvar_Set ("r_fullbright", "0"); + Cvar_Set ("r_ambient", "0"); + Cvar_Set ("r_drawflat", "0"); + } + + if (r_numsurfs.value) + { + if ((surface_p - surfaces) > r_maxsurfsseen) + r_maxsurfsseen = surface_p - surfaces; + + Con_Printf ("Used %d of %d surfs; %d max\n", surface_p - surfaces, + surf_max - surfaces, r_maxsurfsseen); + } + + if (r_numedges.value) + { + edgecount = edge_p - r_edges; + + if (edgecount > r_maxedgesseen) + r_maxedgesseen = edgecount; + + Con_Printf ("Used %d of %d edges; %d max\n", edgecount, + r_numallocatededges, r_maxedgesseen); + } + + r_refdef.ambientlight = r_ambient.value; + + if (r_refdef.ambientlight < 0) + r_refdef.ambientlight = 0; + + if (!sv.active) + r_draworder.value = 0; // don't let cheaters look behind walls + + R_CheckVariables (); + + R_AnimateLight (); + + r_framecount++; + + numbtofpolys = 0; + +// debugging +#if 0 +r_refdef.vieworg[0]= 80; +r_refdef.vieworg[1]= 64; +r_refdef.vieworg[2]= 40; +r_refdef.viewangles[0]= 0; +r_refdef.viewangles[1]= 46.763641357; +r_refdef.viewangles[2]= 0; +#endif + +// build the transformation matrix for the given view angles + VectorCopy (r_refdef.vieworg, modelorg); + 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); + + r_dowarpold = r_dowarp; + r_dowarp = r_waterwarp.value && (r_viewleaf->contents <= CONTENTS_WATER); + + if ((r_dowarp != r_dowarpold) || r_viewchanged || lcd_x.value) + { + if (r_dowarp) + { + if ((vid.width <= vid.maxwarpwidth) && + (vid.height <= vid.maxwarpheight)) + { + vrect.x = 0; + vrect.y = 0; + vrect.width = vid.width; + vrect.height = vid.height; + + R_ViewChanged (&vrect, sb_lines, vid.aspect); + } + else + { + w = vid.width; + h = vid.height; + + if (w > vid.maxwarpwidth) + { + h *= (float)vid.maxwarpwidth / w; + w = vid.maxwarpwidth; + } + + if (h > vid.maxwarpheight) + { + h = vid.maxwarpheight; + w *= (float)vid.maxwarpheight / h; + } + + vrect.x = 0; + vrect.y = 0; + vrect.width = (int)w; + vrect.height = (int)h; + + R_ViewChanged (&vrect, + (int)((float)sb_lines * (h/(float)vid.height)), + vid.aspect * (h / w) * + ((float)vid.width / (float)vid.height)); + } + } + else + { + vrect.x = 0; + vrect.y = 0; + vrect.width = vid.width; + vrect.height = vid.height; + + R_ViewChanged (&vrect, sb_lines, vid.aspect); + } + + r_viewchanged = false; + } + +// start off with just the four screen edge clip planes + R_TransformFrustum (); + +// save base values + VectorCopy (vpn, base_vpn); + VectorCopy (vright, base_vright); + VectorCopy (vup, base_vup); + VectorCopy (modelorg, base_modelorg); + + R_SetSkyFrame (); + + R_SetUpFrustumIndexes (); + + r_cache_thrash = false; + +// clear frame counts + c_faceclip = 0; + d_spanpixcount = 0; + r_polycount = 0; + r_drawnpolycount = 0; + r_wholepolycount = 0; + r_amodels_drawn = 0; + r_outofsurfaces = 0; + r_outofedges = 0; + + D_SetupFrame (); +} + diff --git a/contrib/other/sdlquake-1.0.9/r_part.c b/contrib/other/sdlquake-1.0.9/r_part.c new file mode 100644 index 000000000..a58c9663e --- /dev/null +++ b/contrib/other/sdlquake-1.0.9/r_part.c @@ -0,0 +1,800 @@ +/* +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 "r_local.h" + +#define MAX_PARTICLES 2048 // default max # of particles at one + // time +#define ABSOLUTE_MIN_PARTICLES 512 // no fewer than this no matter what's + // on the command line + +int ramp1[8] = {0x6f, 0x6d, 0x6b, 0x69, 0x67, 0x65, 0x63, 0x61}; +int ramp2[8] = {0x6f, 0x6e, 0x6d, 0x6c, 0x6b, 0x6a, 0x68, 0x66}; +int ramp3[8] = {0x6d, 0x6b, 6, 5, 4, 3}; + +particle_t *active_particles, *free_particles; + +particle_t *particles; +int r_numparticles; + +vec3_t r_pright, r_pup, r_ppn; + + +/* +=============== +R_InitParticles +=============== +*/ +void R_InitParticles (void) +{ + int i; + + i = COM_CheckParm ("-particles"); + + if (i) + { + r_numparticles = (int)(Q_atoi(com_argv[i+1])); + if (r_numparticles < ABSOLUTE_MIN_PARTICLES) + r_numparticles = ABSOLUTE_MIN_PARTICLES; + } + else + { + r_numparticles = MAX_PARTICLES; + } + + 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 + + +/* +=============== +R_EntityParticles +=============== +*/ + +#define NUMVERTEXNORMALS 162 +extern float r_avertexnormals[NUMVERTEXNORMALS][3]; +vec3_t avelocities[NUMVERTEXNORMALS]; +float beamlength = 16; +vec3_t avelocity = {23, 7, 3}; +float partstep = 0.01; +float timescale = 0.01; + +void R_EntityParticles (entity_t *ent) +{ + int count; + int i; + particle_t *p; + float angle; + float sr, sp, sy, cr, cp, cy; + vec3_t forward; + float dist; + + dist = 64; + count = 50; + +if (!avelocities[0][0]) +{ +for (i=0 ; inext; + p->next = active_particles; + active_particles = p; + + p->die = 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; + } +} + + +/* +=============== +R_ClearParticles +=============== +*/ +void R_ClearParticles (void) +{ + int i; + + free_particles = &particles[0]; + active_particles = NULL; + + for (i=0 ;inext; + p->next = active_particles; + active_particles = p; + + p->die = 99999; + p->color = (-c)&15; + p->type = pt_static; + VectorCopy (vec3_origin, p->vel); + VectorCopy (org, p->org); + } + + fclose (f); + Con_Printf ("%i points read\n", c); +} + +/* +=============== +R_ParseParticleEffect + +Parse an effect out of the server message +=============== +*/ +void R_ParseParticleEffect (void) +{ + vec3_t org, dir; + int i, count, msgcount, color; + + for (i=0 ; i<3 ; i++) + org[i] = MSG_ReadCoord (); + 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; + + 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) + return; + p = free_particles; + free_particles = p->next; + p->next = active_particles; + active_particles = p; + + p->die = cl.time + 5; + p->color = ramp1[0]; + p->ramp = rand()&3; + if (i & 1) + { + p->type = pt_explode; + for (j=0 ; j<3 ; j++) + { + p->org[j] = org[j] + ((rand()%32)-16); + p->vel[j] = (rand()%512)-256; + } + } + else + { + p->type = pt_explode2; + for (j=0 ; j<3 ; j++) + { + p->org[j] = org[j] + ((rand()%32)-16); + p->vel[j] = (rand()%512)-256; + } + } + } +} + +/* +=============== +R_ParticleExplosion2 + +=============== +*/ +void R_ParticleExplosion2 (vec3_t org, int colorStart, int colorLength) +{ + int i, j; + particle_t *p; + int colorMod = 0; + + for (i=0; i<512; i++) + { + if (!free_particles) + return; + p = free_particles; + free_particles = p->next; + p->next = active_particles; + active_particles = p; + + p->die = cl.time + 0.3; + p->color = colorStart + (colorMod % colorLength); + colorMod++; + + p->type = pt_blob; + for (j=0 ; j<3 ; j++) + { + p->org[j] = org[j] + ((rand()%32)-16); + p->vel[j] = (rand()%512)-256; + } + } +} + +/* +=============== +R_BlobExplosion + +=============== +*/ +void R_BlobExplosion (vec3_t org) +{ + int i, j; + particle_t *p; + + for (i=0 ; i<1024 ; i++) + { + if (!free_particles) + return; + p = free_particles; + free_particles = p->next; + p->next = active_particles; + active_particles = p; + + p->die = cl.time + 1 + (rand()&8)*0.05; + + if (i & 1) + { + p->type = pt_blob; + p->color = 66 + rand()%6; + for (j=0 ; j<3 ; j++) + { + p->org[j] = org[j] + ((rand()%32)-16); + p->vel[j] = (rand()%512)-256; + } + } + else + { + p->type = pt_blob2; + p->color = 150 + rand()%6; + for (j=0 ; j<3 ; j++) + { + p->org[j] = org[j] + ((rand()%32)-16); + p->vel[j] = (rand()%512)-256; + } + } + } +} + +/* +=============== +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; + + if (count == 1024) + { // rocket explosion + p->die = cl.time + 5; + p->color = ramp1[0]; + p->ramp = rand()&3; + if (i & 1) + { + p->type = pt_explode; + for (j=0 ; j<3 ; j++) + { + p->org[j] = org[j] + ((rand()%32)-16); + p->vel[j] = (rand()%512)-256; + } + } + else + { + p->type = pt_explode2; + for (j=0 ; j<3 ; j++) + { + p->org[j] = org[j] + ((rand()%32)-16); + p->vel[j] = (rand()%512)-256; + } + } + } + else + { + p->die = cl.time + 0.1*(rand()%5); + p->color = (color&~7) + (rand()&7); + p->type = pt_slowgrav; + for (j=0 ; j<3 ; j++) + { + p->org[j] = org[j] + ((rand()&15)-8); + p->vel[j] = dir[j]*15;// + (rand()%300)-150; + } + } + } +} + + +/* +=============== +R_LavaSplash + +=============== +*/ +void R_LavaSplash (vec3_t org) +{ + int i, j, k; + particle_t *p; + float vel; + vec3_t dir; + + for (i=-16 ; i<16 ; i++) + for (j=-16 ; j<16 ; j++) + for (k=0 ; k<1 ; k++) + { + if (!free_particles) + return; + p = free_particles; + free_particles = p->next; + 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); + vel = 50 + (rand()&63); + VectorScale (dir, vel, p->vel); + } +} + +/* +=============== +R_TeleportSplash + +=============== +*/ +void R_TeleportSplash (vec3_t org) +{ + int i, j, k; + particle_t *p; + float vel; + vec3_t dir; + + for (i=-16 ; i<16 ; i+=4) + for (j=-16 ; j<16 ; j+=4) + for (k=-24 ; k<32 ; k+=4) + { + 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 = 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); + vel = 50 + (rand()&63); + VectorScale (dir, vel, p->vel); + } +} + +void R_RocketTrail (vec3_t start, vec3_t end, int type) +{ + vec3_t vec; + float len; + int j; + particle_t *p; + int dec; + static int tracercount; + + VectorSubtract (end, start, vec); + len = VectorNormalize (vec); + if (type < 128) + dec = 3; + else + { + dec = 1; + type -= 128; + } + + while (len > 0) + { + len -= dec; + + if (!free_particles) + return; + p = free_particles; + free_particles = p->next; + p->next = active_particles; + active_particles = p; + + VectorCopy (vec3_origin, p->vel); + p->die = cl.time + 2; + + switch (type) + { + case 0: // rocket trail + p->ramp = (rand()&3); + p->color = ramp3[(int)p->ramp]; + p->type = pt_fire; + for (j=0 ; j<3 ; j++) + p->org[j] = start[j] + ((rand()%6)-3); + break; + + case 1: // smoke smoke + p->ramp = (rand()&3) + 2; + p->color = ramp3[(int)p->ramp]; + p->type = pt_fire; + for (j=0 ; j<3 ; j++) + p->org[j] = start[j] + ((rand()%6)-3); + break; + + case 2: // blood + p->type = pt_grav; + p->color = 67 + (rand()&3); + for (j=0 ; j<3 ; j++) + p->org[j] = start[j] + ((rand()%6)-3); + break; + + case 3: + case 5: // tracer + p->die = cl.time + 0.5; + p->type = pt_static; + if (type == 3) + p->color = 52 + ((tracercount&4)<<1); + else + p->color = 230 + ((tracercount&4)<<1); + + tracercount++; + + VectorCopy (start, p->org); + if (tracercount & 1) + { + p->vel[0] = 30*vec[1]; + p->vel[1] = 30*-vec[0]; + } + else + { + p->vel[0] = 30*-vec[1]; + p->vel[1] = 30*vec[0]; + } + break; + + case 4: // slight blood + p->type = pt_grav; + p->color = 67 + (rand()&3); + for (j=0 ; j<3 ; j++) + p->org[j] = start[j] + ((rand()%6)-3); + len -= 3; + break; + + case 6: // voor trail + p->color = 9*16 + 8 + (rand()&3); + p->type = pt_static; + p->die = cl.time + 0.3; + for (j=0 ; j<3 ; j++) + p->org[j] = start[j] + ((rand()&15)-8); + break; + } + + + VectorAdd (start, vec, start); + } +} + + +/* +=============== +R_DrawParticles +=============== +*/ +extern cvar_t sv_gravity; + +void R_DrawParticles (void) +{ + 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; + + GL_Bind(particletexture); + 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; + time1 = frametime * 5; + grav = frametime * sv_gravity.value * 0.05; + dvel = 4*frametime; + + for ( ;; ) + { + kill = active_particles; + if (kill && kill->die < cl.time) + { + active_particles = kill->next; + kill->next = free_particles; + free_particles = kill; + continue; + } + break; + } + + for (p=active_particles ; p ; p=p->next) + { + for ( ;; ) + { + kill = p->next; + if (kill && kill->die < cl.time) + { + p->next = kill->next; + kill->next = free_particles; + free_particles = kill; + continue; + } + 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: + break; + case pt_fire: + p->ramp += time1; + if (p->ramp >= 6) + p->die = -1; + else + p->color = ramp3[(int)p->ramp]; + p->vel[2] += grav; + break; + + case pt_explode: + p->ramp += time2; + if (p->ramp >=8) + p->die = -1; + else + p->color = ramp1[(int)p->ramp]; + for (i=0 ; i<3 ; i++) + p->vel[i] += p->vel[i]*dvel; + p->vel[2] -= grav; + break; + + case pt_explode2: + p->ramp += time3; + if (p->ramp >=8) + p->die = -1; + else + p->color = ramp2[(int)p->ramp]; + for (i=0 ; i<3 ; i++) + p->vel[i] -= p->vel[i]*frametime; + p->vel[2] -= grav; + break; + + case pt_blob: + for (i=0 ; i<3 ; i++) + p->vel[i] += p->vel[i]*dvel; + p->vel[2] -= grav; + break; + + case pt_blob2: + for (i=0 ; i<2 ; i++) + p->vel[i] -= p->vel[i]*dvel; + p->vel[2] -= grav; + break; + + case pt_grav: +#ifdef QUAKE2 + p->vel[2] -= grav * 20; + break; +#endif + case pt_slowgrav: + p->vel[2] -= grav; + break; + } + } + +#ifdef GLQUAKE + glEnd (); + glDisable (GL_BLEND); + glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); +#else + D_EndParticles (); +#endif +} + diff --git a/contrib/other/sdlquake-1.0.9/r_shared.h b/contrib/other/sdlquake-1.0.9/r_shared.h new file mode 100644 index 000000000..f2a6db309 --- /dev/null +++ b/contrib/other/sdlquake-1.0.9/r_shared.h @@ -0,0 +1,157 @@ +/* +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. + +*/ +#ifndef GLQUAKE +// r_shared.h: general refresh-related stuff shared between the refresh and the +// driver + +// FIXME: clean up and move into d_iface.h + +#ifndef _R_SHARED_H_ +#define _R_SHARED_H_ + +#define MAXVERTS 16 // max points in a surface polygon +#define MAXWORKINGVERTS (MAXVERTS+4) // max points in an intermediate + // polygon (while processing) +// !!! if this is changed, it must be changed in d_ifacea.h too !!! +#define MAXHEIGHT 1024 +#define MAXWIDTH 1280 +#define MAXDIMENSION ((MAXHEIGHT > MAXWIDTH) ? MAXHEIGHT : MAXWIDTH) + +#define SIN_BUFFER_SIZE (MAXDIMENSION+CYCLE) + +#define INFINITE_DISTANCE 0x10000 // distance that's always guaranteed to + // be farther away than anything in + // the scene + +//=================================================================== + +extern void R_DrawLine (polyvert_t *polyvert0, polyvert_t *polyvert1); + +extern int cachewidth; +extern pixel_t *cacheblock; +extern int screenwidth; + +extern float pixelAspect; + +extern int r_drawnpolycount; + +extern cvar_t r_clearcolor; + +extern int sintable[SIN_BUFFER_SIZE]; +extern int intsintable[SIN_BUFFER_SIZE]; + +extern vec3_t vup, base_vup; +extern vec3_t vpn, base_vpn; +extern vec3_t vright, base_vright; +extern entity_t *currententity; + +#define NUMSTACKEDGES 2400 +#define MINEDGES NUMSTACKEDGES +#define NUMSTACKSURFACES 800 +#define MINSURFACES NUMSTACKSURFACES +#define MAXSPANS 3000 + +// !!! if this is changed, it must be changed in asm_draw.h too !!! +typedef struct espan_s +{ + int u, v, count; + struct espan_s *pnext; +} espan_t; + +// FIXME: compress, make a union if that will help +// insubmodel is only 1, flags is fewer than 32, spanstate could be a byte +typedef struct surf_s +{ + struct surf_s *next; // active surface stack in r_edge.c + struct surf_s *prev; // used in r_edge.c for active surf stack + struct espan_s *spans; // pointer to linked list of spans to draw + int key; // sorting key (BSP order) + int last_u; // set during tracing + int spanstate; // 0 = not in span + // 1 = in span + // -1 = in inverted span (end before + // start) + int flags; // currentface flags + void *data; // associated data like msurface_t + entity_t *entity; + float nearzi; // nearest 1/z on surface, for mipmapping + qboolean insubmodel; + float d_ziorigin, d_zistepu, d_zistepv; + + int pad[2]; // to 64 bytes +} surf_t; + +extern surf_t *surfaces, *surface_p, *surf_max; + +// surfaces are generated in back to front order by the bsp, so if a surf +// pointer is greater than another one, it should be drawn in front +// surfaces[1] is the background, and is used as the active surface stack. +// surfaces[0] is a dummy, because index 0 is used to indicate no surface +// attached to an edge_t + +//=================================================================== + +extern vec3_t sxformaxis[4]; // s axis transformed into viewspace +extern vec3_t txformaxis[4]; // t axis transformed into viewspac + +extern vec3_t modelorg, base_modelorg; + +extern float xcenter, ycenter; +extern float xscale, yscale; +extern float xscaleinv, yscaleinv; +extern float xscaleshrink, yscaleshrink; + +extern int d_lightstylevalue[256]; // 8.8 frac of base light value + +extern void TransformVector (vec3_t in, vec3_t out); +extern void SetUpForLineScan(fixed8_t startvertu, fixed8_t startvertv, + fixed8_t endvertu, fixed8_t endvertv); + +extern int r_skymade; +extern void R_MakeSky (void); + +extern int ubasestep, errorterm, erroradjustup, erroradjustdown; + +// flags in finalvert_t.flags +#define ALIAS_LEFT_CLIP 0x0001 +#define ALIAS_TOP_CLIP 0x0002 +#define ALIAS_RIGHT_CLIP 0x0004 +#define ALIAS_BOTTOM_CLIP 0x0008 +#define ALIAS_Z_CLIP 0x0010 +// !!! if this is changed, it must be changed in d_ifacea.h too !!! +#define ALIAS_ONSEAM 0x0020 // also defined in modelgen.h; + // must be kept in sync +#define ALIAS_XY_CLIP_MASK 0x000F + +// !!! if this is changed, it must be changed in asm_draw.h too !!! +typedef struct edge_s +{ + fixed16_t u; + fixed16_t u_step; + struct edge_s *prev, *next; + unsigned short surfs[2]; + struct edge_s *nextremove; + float nearzi; + medge_t *owner; +} edge_t; + +#endif // _R_SHARED_H_ + +#endif // GLQUAKE diff --git a/contrib/other/sdlquake-1.0.9/r_sky.c b/contrib/other/sdlquake-1.0.9/r_sky.c new file mode 100644 index 000000000..c8bfffd2c --- /dev/null +++ b/contrib/other/sdlquake-1.0.9/r_sky.c @@ -0,0 +1,280 @@ +/* +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_sky.c + +#include "quakedef.h" +#include "r_local.h" +#include "d_local.h" + + +int iskyspeed = 8; +int iskyspeed2 = 2; +float skyspeed, skyspeed2; + +float skytime; + +byte *r_skysource; + +int r_skymade; +int r_skydirect; // not used? + + +// TODO: clean up these routines + +byte bottomsky[128*131]; +byte bottommask[128*131]; +byte newsky[128*256]; // newsky and topsky both pack in here, 128 bytes + // of newsky on the left of each scan, 128 bytes + // of topsky on the right, because the low-level + // drawers need 256-byte scan widths + + +/* +============= +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; + byte *src; + + src = (byte *)mt + mt->offsets[0]; + + for (i=0 ; i<128 ; i++) + { + for (j=0 ; j<128 ; j++) + { + newsky[(i*256) + j + 128] = src[i*256 + j + 128]; + } + } + + for (i=0 ; i<128 ; i++) + { + for (j=0 ; j<131 ; j++) + { + if (src[i*256 + (j & 0x7F)]) + { + bottomsky[(i*131) + j] = src[i*256 + (j & 0x7F)]; + bottommask[(i*131) + j] = 0; + } + else + { + bottomsky[(i*131) + j] = 0; + bottommask[(i*131) + j] = 0xff; + } + } + } + + r_skysource = newsky; +} + + +/* +================= +R_MakeSky +================= +*/ +void R_MakeSky (void) +{ + int x, y; + int ofs, baseofs; + int xshift, yshift; + unsigned *pnewsky; + static int xlast = -1, ylast = -1; + + xshift = skytime*skyspeed; + yshift = skytime*skyspeed; + + if ((xshift == xlast) && (yshift == ylast)) + return; + + xlast = xshift; + ylast = yshift; + + pnewsky = (unsigned *)&newsky[0]; + + for (y=0 ; ydist; + pclipnormal = pclipplane->normal; + +// calc dists + if (clip_current) + { + in = clip_verts[1][0]; + outstep = clip_verts[0][0]; + clip_current = 0; + } + else + { + in = clip_verts[0][0]; + outstep = clip_verts[1][0]; + clip_current = 1; + } + + instep = in; + for (i=0 ; i= 0) + { + Q_memcpy (outstep, instep, sizeof (vec5_t)); + outstep += sizeof (vec5_t) / sizeof (float); + outcount++; + } + + if (dists[i] == 0 || dists[i+1] == 0) + continue; + + if ( (dists[i] > 0) == (dists[i+1] > 0) ) + continue; + + // split it into a new vertex + frac = dists[i] / (dists[i] - dists[i+1]); + + vert2 = instep + sizeof (vec5_t) / sizeof (float); + + outstep[0] = instep[0] + frac*(vert2[0] - instep[0]); + outstep[1] = instep[1] + frac*(vert2[1] - instep[1]); + outstep[2] = instep[2] + frac*(vert2[2] - instep[2]); + outstep[3] = instep[3] + frac*(vert2[3] - instep[3]); + outstep[4] = instep[4] + frac*(vert2[4] - instep[4]); + + outstep += sizeof (vec5_t) / sizeof (float); + outcount++; + } + + return outcount; +} + + +/* +================ +R_SetupAndDrawSprite +================ +*/ +void R_SetupAndDrawSprite () +{ + int i, nump; + float dot, scale, *pv; + vec5_t *pverts; + vec3_t left, up, right, down, transformed, local; + emitpoint_t outverts[MAXWORKINGVERTS+1], *pout; + + dot = DotProduct (r_spritedesc.vpn, modelorg); + +// backface cull + if (dot >= 0) + return; + +// build the sprite poster in worldspace + VectorScale (r_spritedesc.vright, r_spritedesc.pspriteframe->right, right); + VectorScale (r_spritedesc.vup, r_spritedesc.pspriteframe->up, up); + VectorScale (r_spritedesc.vright, r_spritedesc.pspriteframe->left, left); + VectorScale (r_spritedesc.vup, r_spritedesc.pspriteframe->down, down); + + pverts = clip_verts[0]; + + pverts[0][0] = r_entorigin[0] + up[0] + left[0]; + pverts[0][1] = r_entorigin[1] + up[1] + left[1]; + pverts[0][2] = r_entorigin[2] + up[2] + left[2]; + pverts[0][3] = 0; + pverts[0][4] = 0; + + pverts[1][0] = r_entorigin[0] + up[0] + right[0]; + pverts[1][1] = r_entorigin[1] + up[1] + right[1]; + pverts[1][2] = r_entorigin[2] + up[2] + right[2]; + pverts[1][3] = sprite_width; + pverts[1][4] = 0; + + pverts[2][0] = r_entorigin[0] + down[0] + right[0]; + pverts[2][1] = r_entorigin[1] + down[1] + right[1]; + pverts[2][2] = r_entorigin[2] + down[2] + right[2]; + pverts[2][3] = sprite_width; + pverts[2][4] = sprite_height; + + pverts[3][0] = r_entorigin[0] + down[0] + left[0]; + pverts[3][1] = r_entorigin[1] + down[1] + left[1]; + pverts[3][2] = r_entorigin[2] + down[2] + left[2]; + pverts[3][3] = 0; + pverts[3][4] = sprite_height; + +// clip to the frustum in worldspace + nump = 4; + clip_current = 0; + + for (i=0 ; i<4 ; i++) + { + nump = R_ClipSpriteFace (nump, &view_clipplanes[i]); + if (nump < 3) + return; + if (nump >= MAXWORKINGVERTS) + Sys_Error("R_SetupAndDrawSprite: too many points"); + } + +// transform vertices into viewspace and project + pv = &clip_verts[clip_current][0][0]; + r_spritedesc.nearzi = -999999; + + for (i=0 ; izi = 1.0 / transformed[2]; + if (pout->zi > r_spritedesc.nearzi) + r_spritedesc.nearzi = pout->zi; + + pout->s = pv[3]; + pout->t = pv[4]; + + scale = xscale * pout->zi; + pout->u = (xcenter + scale * transformed[0]); + + scale = yscale * pout->zi; + pout->v = (ycenter - scale * transformed[1]); + + pv += sizeof (vec5_t) / sizeof (*pv); + } + +// draw it + r_spritedesc.nump = nump; + r_spritedesc.pverts = outverts; + D_DrawSprite (); +} + + +/* +================ +R_GetSpriteframe +================ +*/ +mspriteframe_t *R_GetSpriteframe (msprite_t *psprite) +{ + mspritegroup_t *pspritegroup; + mspriteframe_t *pspriteframe; + int i, numframes, frame; + float *pintervals, fullinterval, targettime, time; + + 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_DrawSprite +================ +*/ +void R_DrawSprite (void) +{ + int i; + msprite_t *psprite; + vec3_t tvec; + float dot, angle, sr, cr; + + psprite = currententity->model->cache.data; + + r_spritedesc.pspriteframe = R_GetSpriteframe (psprite); + + sprite_width = r_spritedesc.pspriteframe->width; + sprite_height = r_spritedesc.pspriteframe->height; + +// TODO: make this caller-selectable + if (psprite->type == SPR_FACING_UPRIGHT) + { + // generate the sprite's axes, with vup straight up in worldspace, and + // r_spritedesc.vright perpendicular to modelorg. + // This will not work if the view direction is very close to straight up or + // down, because the cross product will be between two nearly parallel + // vectors and starts to approach an undefined state, so we don't draw if + // the two vectors are less than 1 degree apart + tvec[0] = -modelorg[0]; + tvec[1] = -modelorg[1]; + tvec[2] = -modelorg[2]; + VectorNormalize (tvec); + dot = tvec[2]; // same as DotProduct (tvec, r_spritedesc.vup) because + // r_spritedesc.vup is 0, 0, 1 + if ((dot > 0.999848) || (dot < -0.999848)) // cos(1 degree) = 0.999848 + return; + r_spritedesc.vup[0] = 0; + r_spritedesc.vup[1] = 0; + r_spritedesc.vup[2] = 1; + r_spritedesc.vright[0] = tvec[1]; + // CrossProduct(r_spritedesc.vup, -modelorg, + r_spritedesc.vright[1] = -tvec[0]; + // r_spritedesc.vright) + r_spritedesc.vright[2] = 0; + VectorNormalize (r_spritedesc.vright); + r_spritedesc.vpn[0] = -r_spritedesc.vright[1]; + r_spritedesc.vpn[1] = r_spritedesc.vright[0]; + r_spritedesc.vpn[2] = 0; + // CrossProduct (r_spritedesc.vright, r_spritedesc.vup, + // r_spritedesc.vpn) + } + else if (psprite->type == SPR_VP_PARALLEL) + { + // generate the sprite's axes, completely parallel to the viewplane. There + // are no problem situations, because the sprite is always in the same + // position relative to the viewer + for (i=0 ; i<3 ; i++) + { + r_spritedesc.vup[i] = vup[i]; + r_spritedesc.vright[i] = vright[i]; + r_spritedesc.vpn[i] = vpn[i]; + } + } + else if (psprite->type == SPR_VP_PARALLEL_UPRIGHT) + { + // generate the sprite's axes, with vup straight up in worldspace, and + // r_spritedesc.vright parallel to the viewplane. + // This will not work if the view direction is very close to straight up or + // down, because the cross product will be between two nearly parallel + // vectors and starts to approach an undefined state, so we don't draw if + // the two vectors are less than 1 degree apart + dot = vpn[2]; // same as DotProduct (vpn, r_spritedesc.vup) because + // r_spritedesc.vup is 0, 0, 1 + if ((dot > 0.999848) || (dot < -0.999848)) // cos(1 degree) = 0.999848 + return; + r_spritedesc.vup[0] = 0; + r_spritedesc.vup[1] = 0; + r_spritedesc.vup[2] = 1; + r_spritedesc.vright[0] = vpn[1]; + // CrossProduct (r_spritedesc.vup, vpn, + r_spritedesc.vright[1] = -vpn[0]; // r_spritedesc.vright) + r_spritedesc.vright[2] = 0; + VectorNormalize (r_spritedesc.vright); + r_spritedesc.vpn[0] = -r_spritedesc.vright[1]; + r_spritedesc.vpn[1] = r_spritedesc.vright[0]; + r_spritedesc.vpn[2] = 0; + // CrossProduct (r_spritedesc.vright, r_spritedesc.vup, + // r_spritedesc.vpn) + } + else if (psprite->type == SPR_ORIENTED) + { + // generate the sprite's axes, according to the sprite's world orientation + AngleVectors (currententity->angles, r_spritedesc.vpn, + r_spritedesc.vright, r_spritedesc.vup); + } + else if (psprite->type == SPR_VP_PARALLEL_ORIENTED) + { + // generate the sprite's axes, parallel to the viewplane, but rotated in + // that plane around the center according to the sprite entity's roll + // angle. So vpn stays the same, but vright and vup rotate + angle = currententity->angles[ROLL] * (M_PI*2 / 360); + sr = sin(angle); + cr = cos(angle); + + for (i=0 ; i<3 ; i++) + { + r_spritedesc.vpn[i] = vpn[i]; + r_spritedesc.vright[i] = vright[i] * cr + vup[i] * sr; + r_spritedesc.vup[i] = vright[i] * -sr + vup[i] * cr; + } + } + else + { + Sys_Error ("R_DrawSprite: Bad sprite type %d", psprite->type); + } + + R_RotateSprite (psprite->beamlength); + + R_SetupAndDrawSprite (); +} + diff --git a/contrib/other/sdlquake-1.0.9/r_surf.c b/contrib/other/sdlquake-1.0.9/r_surf.c new file mode 100644 index 000000000..a2436d51b --- /dev/null +++ b/contrib/other/sdlquake-1.0.9/r_surf.c @@ -0,0 +1,678 @@ +/* +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" +#include "r_local.h" + +drawsurf_t r_drawsurf; + +int lightleft, sourcesstep, blocksize, sourcetstep; +int lightdelta, lightdeltastep; +int lightright, lightleftstep, lightrightstep, blockdivshift; +unsigned blockdivmask; +void *prowdestbase; +unsigned char *pbasesource; +int surfrowbytes; // used by ASM files +unsigned *r_lightptr; +int r_stepback; +int r_lightwidth; +int r_numhblocks, r_numvblocks; +unsigned char *r_source, *r_sourcemax; + +void R_DrawSurfaceBlock8_mip0 (void); +void R_DrawSurfaceBlock8_mip1 (void); +void R_DrawSurfaceBlock8_mip2 (void); +void R_DrawSurfaceBlock8_mip3 (void); + +static void (*surfmiptable[4])(void) = { + R_DrawSurfaceBlock8_mip0, + R_DrawSurfaceBlock8_mip1, + R_DrawSurfaceBlock8_mip2, + R_DrawSurfaceBlock8_mip3 +}; + + + +unsigned blocklights[18*18]; + +/* +=============== +R_AddDynamicLights +=============== +*/ +void R_AddDynamicLights (void) +{ + 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; + + surf = r_drawsurf.surf; + smax = (surf->extents[0]>>4)+1; + tmax = (surf->extents[1]>>4)+1; + tex = surf->texinfo; + + for (lnum=0 ; lnumdlightbits & (1<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]; + + for (t = 0 ; t td) + dist = sd + (td>>1); + else + dist = td + (sd>>1); + if (dist < minlight) +#ifdef QUAKE2 + { + unsigned temp; + temp = (rad - dist)*256; + i = t*smax + s; + if (!cl_dlights[lnum].dark) + blocklights[i] += temp; + else + { + if (blocklights[i] > temp) + blocklights[i] -= temp; + else + blocklights[i] = 0; + } + } +#else + blocklights[t*smax + s] += (rad - dist)*256; +#endif + } + } + } +} + +/* +=============== +R_BuildLightMap + +Combine and scale multiple lightmaps into the 8.8 format in blocklights +=============== +*/ +void R_BuildLightMap (void) +{ + int smax, tmax; + int t; + int i, size; + byte *lightmap; + unsigned scale; + int maps; + msurface_t *surf; + + surf = r_drawsurf.surf; + + smax = (surf->extents[0]>>4)+1; + tmax = (surf->extents[1]>>4)+1; + size = smax*tmax; + lightmap = surf->samples; + + if (r_fullbright.value || !cl.worldmodel->lightdata) + { + for (i=0 ; istyles[maps] != 255 ; + maps++) + { + scale = r_drawsurf.lightadj[maps]; // 8.8 fraction + for (i=0 ; idlightframe == r_framecount) + R_AddDynamicLights (); + +// bound, invert, and shift + for (i=0 ; i> (8 - VID_CBITS); + + if (t < (1 << 6)) + t = (1 << 6); + + blocklights[i] = t; + } +} + + +/* +=============== +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; +} + + +/* +=============== +R_DrawSurface +=============== +*/ +void R_DrawSurface (void) +{ + unsigned char *basetptr; + int smax, tmax, twidth; + int u; + int soffset, basetoffset, texwidth; + int horzblockstep; + unsigned char *pcolumndest; + void (*pblockdrawer)(void); + texture_t *mt; + +// calculate the lightings + R_BuildLightMap (); + + surfrowbytes = r_drawsurf.rowbytes; + + mt = r_drawsurf.texture; + + r_source = (byte *)mt + mt->offsets[r_drawsurf.surfmip]; + +// the fractional light values should range from 0 to (VID_GRADES - 1) << 16 +// from a source range of 0 - 255 + + texwidth = mt->width >> r_drawsurf.surfmip; + + blocksize = 16 >> r_drawsurf.surfmip; + blockdivshift = 4 - r_drawsurf.surfmip; + blockdivmask = (1 << blockdivshift) - 1; + + r_lightwidth = (r_drawsurf.surf->extents[0]>>4)+1; + + r_numhblocks = r_drawsurf.surfwidth >> blockdivshift; + r_numvblocks = r_drawsurf.surfheight >> blockdivshift; + +//============================== + + if (r_pixbytes == 1) + { + pblockdrawer = surfmiptable[r_drawsurf.surfmip]; + // TODO: only needs to be set when there is a display settings change + horzblockstep = blocksize; + } + else + { + pblockdrawer = R_DrawSurfaceBlock16; + // TODO: only needs to be set when there is a display settings change + horzblockstep = blocksize << 1; + } + + smax = mt->width >> r_drawsurf.surfmip; + twidth = texwidth; + tmax = mt->height >> r_drawsurf.surfmip; + sourcetstep = texwidth; + r_stepback = tmax * twidth; + + r_sourcemax = r_source + (tmax * smax); + + soffset = r_drawsurf.surf->texturemins[0]; + basetoffset = r_drawsurf.surf->texturemins[1]; + +// << 16 components are to guarantee positive values for % + soffset = ((soffset >> r_drawsurf.surfmip) + (smax << 16)) % smax; + basetptr = &r_source[((((basetoffset >> r_drawsurf.surfmip) + + (tmax << 16)) % tmax) * twidth)]; + + pcolumndest = r_drawsurf.surfdat; + + for (u=0 ; u= smax) + soffset = 0; + + pcolumndest += horzblockstep; + } +} + + +//============================================================================= + +#if !id386 + +/* +================ +R_DrawSurfaceBlock8_mip0 +================ +*/ +void R_DrawSurfaceBlock8_mip0 (void) +{ + int v, i, b, lightstep, lighttemp, light; + unsigned char pix, *psource, *prowdest; + + psource = pbasesource; + prowdest = prowdestbase; + + for (v=0 ; v> 4; + lightrightstep = (r_lightptr[1] - lightright) >> 4; + + for (i=0 ; i<16 ; i++) + { + lighttemp = lightleft - lightright; + lightstep = lighttemp >> 4; + + light = lightright; + + for (b=15; b>=0; b--) + { + pix = psource[b]; + prowdest[b] = ((unsigned char *)vid.colormap) + [(light & 0xFF00) + pix]; + light += lightstep; + } + + psource += sourcetstep; + lightright += lightrightstep; + lightleft += lightleftstep; + prowdest += surfrowbytes; + } + + if (psource >= r_sourcemax) + psource -= r_stepback; + } +} + + +/* +================ +R_DrawSurfaceBlock8_mip1 +================ +*/ +void R_DrawSurfaceBlock8_mip1 (void) +{ + int v, i, b, lightstep, lighttemp, light; + unsigned char pix, *psource, *prowdest; + + psource = pbasesource; + prowdest = prowdestbase; + + for (v=0 ; v> 3; + lightrightstep = (r_lightptr[1] - lightright) >> 3; + + for (i=0 ; i<8 ; i++) + { + lighttemp = lightleft - lightright; + lightstep = lighttemp >> 3; + + light = lightright; + + for (b=7; b>=0; b--) + { + pix = psource[b]; + prowdest[b] = ((unsigned char *)vid.colormap) + [(light & 0xFF00) + pix]; + light += lightstep; + } + + psource += sourcetstep; + lightright += lightrightstep; + lightleft += lightleftstep; + prowdest += surfrowbytes; + } + + if (psource >= r_sourcemax) + psource -= r_stepback; + } +} + + +/* +================ +R_DrawSurfaceBlock8_mip2 +================ +*/ +void R_DrawSurfaceBlock8_mip2 (void) +{ + int v, i, b, lightstep, lighttemp, light; + unsigned char pix, *psource, *prowdest; + + psource = pbasesource; + prowdest = prowdestbase; + + for (v=0 ; v> 2; + lightrightstep = (r_lightptr[1] - lightright) >> 2; + + for (i=0 ; i<4 ; i++) + { + lighttemp = lightleft - lightright; + lightstep = lighttemp >> 2; + + light = lightright; + + for (b=3; b>=0; b--) + { + pix = psource[b]; + prowdest[b] = ((unsigned char *)vid.colormap) + [(light & 0xFF00) + pix]; + light += lightstep; + } + + psource += sourcetstep; + lightright += lightrightstep; + lightleft += lightleftstep; + prowdest += surfrowbytes; + } + + if (psource >= r_sourcemax) + psource -= r_stepback; + } +} + + +/* +================ +R_DrawSurfaceBlock8_mip3 +================ +*/ +void R_DrawSurfaceBlock8_mip3 (void) +{ + int v, i, b, lightstep, lighttemp, light; + unsigned char pix, *psource, *prowdest; + + psource = pbasesource; + prowdest = prowdestbase; + + for (v=0 ; v> 1; + lightrightstep = (r_lightptr[1] - lightright) >> 1; + + for (i=0 ; i<2 ; i++) + { + lighttemp = lightleft - lightright; + lightstep = lighttemp >> 1; + + light = lightright; + + for (b=1; b>=0; b--) + { + pix = psource[b]; + prowdest[b] = ((unsigned char *)vid.colormap) + [(light & 0xFF00) + pix]; + light += lightstep; + } + + psource += sourcetstep; + lightright += lightrightstep; + lightleft += lightleftstep; + prowdest += surfrowbytes; + } + + if (psource >= r_sourcemax) + psource -= r_stepback; + } +} + + +/* +================ +R_DrawSurfaceBlock16 + +FIXME: make this work +================ +*/ +void R_DrawSurfaceBlock16 (void) +{ + int k; + unsigned char *psource; + int lighttemp, lightstep, light; + unsigned short *prowdest; + + prowdest = (unsigned short *)prowdestbase; + + for (k=0 ; k> blockdivshift; + + light = lightleft; + pdest = prowdest; + + for (b=0; b> 16) & 63; + t = (((i << 16) + turb[j & (CYCLE-1)]) >> 16) & 63; + *pd++ = *(pbasetex + (t<<6) + s); + } + } +} + + +/* +================ +R_GenTurbTile16 +================ +*/ +void R_GenTurbTile16 (pixel_t *pbasetex, void *pdest) +{ + int *turb; + int i, j, s, t; + unsigned short *pd; + + turb = sintable + ((int)(cl.time*SPEED)&(CYCLE-1)); + pd = (unsigned short *)pdest; + + for (i=0 ; i> 16) & 63; + t = (((i << 16) + turb[j & (CYCLE-1)]) >> 16) & 63; + *pd++ = d_8to16table[*(pbasetex + (t<<6) + s)]; + } + } +} + + +/* +================ +R_GenTile +================ +*/ +void R_GenTile (msurface_t *psurf, void *pdest) +{ + if (psurf->flags & SURF_DRAWTURB) + { + if (r_pixbytes == 1) + { + R_GenTurbTile ((pixel_t *) + ((byte *)psurf->texinfo->texture + psurf->texinfo->texture->offsets[0]), pdest); + } + else + { + R_GenTurbTile16 ((pixel_t *) + ((byte *)psurf->texinfo->texture + psurf->texinfo->texture->offsets[0]), pdest); + } + } + else if (psurf->flags & SURF_DRAWSKY) + { + if (r_pixbytes == 1) + { + R_GenSkyTile (pdest); + } + else + { + R_GenSkyTile16 (pdest); + } + } + else + { + Sys_Error ("Unknown tile type"); + } +} + diff --git a/contrib/other/sdlquake-1.0.9/r_vars.c b/contrib/other/sdlquake-1.0.9/r_vars.c new file mode 100644 index 000000000..eb41290e9 --- /dev/null +++ b/contrib/other/sdlquake-1.0.9/r_vars.c @@ -0,0 +1,39 @@ +/* +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_vars.c: global refresh variables + +#include "quakedef.h" + +#if !id386 + +// all global and static refresh variables are collected in a contiguous block +// to avoid cache conflicts. + +//------------------------------------------------------- +// global refresh variables +//------------------------------------------------------- + +// FIXME: make into one big structure, like cl or sv +// FIXME: do separately for refresh engine and driver + +int r_bmodelactive; + +#endif // !id386 + diff --git a/contrib/other/sdlquake-1.0.9/r_varsa.S b/contrib/other/sdlquake-1.0.9/r_varsa.S new file mode 100644 index 000000000..2c3f9e541 --- /dev/null +++ b/contrib/other/sdlquake-1.0.9/r_varsa.S @@ -0,0 +1,64 @@ +/* +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_varsa.s +// + +#include "asm_i386.h" +#include "quakeasm.h" +#include "asm_draw.h" +#include "d_ifacea.h" + +#if id386 + + .data + +//------------------------------------------------------- +// ASM-only variables +//------------------------------------------------------- +.globl float_1, float_particle_z_clip, float_point5 +.globl float_minus_1, float_0 +float_0: .single 0.0 +float_1: .single 1.0 +float_minus_1: .single -1.0 +float_particle_z_clip: .single PARTICLE_Z_CLIP +float_point5: .single 0.5 + +.globl fp_16, fp_64k, fp_1m, fp_64kx64k +.globl fp_1m_minus_1 +.globl fp_8 +fp_1m: .single 1048576.0 +fp_1m_minus_1: .single 1048575.0 +fp_64k: .single 65536.0 +fp_8: .single 8.0 +fp_16: .single 16.0 +fp_64kx64k: .long 0x4f000000 // (float)0x8000*0x10000 + + +.globl FloatZero, Float2ToThe31nd, FloatMinus2ToThe31nd +FloatZero: .long 0 +Float2ToThe31nd: .long 0x4f000000 +FloatMinus2ToThe31nd: .long 0xcf000000 + +.globl C(r_bmodelactive) +C(r_bmodelactive): .long 0 + +#endif // id386 + diff --git a/contrib/other/sdlquake-1.0.9/render.h b/contrib/other/sdlquake-1.0.9/render.h new file mode 100644 index 000000000..b5f8382c3 --- /dev/null +++ b/contrib/other/sdlquake-1.0.9/render.h @@ -0,0 +1,158 @@ +/* +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. + +*/ + +// refresh.h -- public interface to refresh functions + +#define MAXCLIPPLANES 11 + +#define TOP_RANGE 16 // soldier uniform colors +#define BOTTOM_RANGE 96 + +//============================================================================= + +typedef struct efrag_s +{ + struct mleaf_s *leaf; + struct efrag_s *leafnext; + struct entity_s *entity; + struct efrag_s *entnext; +} efrag_t; + + +typedef struct entity_s +{ + qboolean forcelink; // model changed + + int update_type; + + 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 origin; + vec3_t msg_angles[2]; // last two updates (0 is newest) + vec3_t angles; + struct model_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 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 +} entity_t; + +// !!! if this is changed, it must be changed in asm_draw.h too !!! +typedef struct +{ + vrect_t vrect; // subwindow in video for refresh + // FIXME: not need vrect next field here? + vrect_t aliasvrect; // scaled Alias version + int vrectright, vrectbottom; // right & bottom screen coords + int aliasvrectright, aliasvrectbottom; // scaled Alias versions + float vrectrightedge; // rightmost right edge we care about, + // for use in edge list + float fvrectx, fvrecty; // for floating-point compares + float fvrectx_adj, fvrecty_adj; // left and top edges, for clamping + int vrect_x_adj_shift20; // (vrect.x + 0.5 - epsilon) << 20 + int vrectright_adj_shift20; // (vrectright + 0.5 - epsilon) << 20 + float fvrectright_adj, fvrectbottom_adj; + // 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 + // 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; +} refdef_t; + + +// +// refresh +// +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); +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 + +void R_AddEfrags (entity_t *ent); +void R_RemoveEfrags (entity_t *ent); + +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); +void R_ParticleExplosion2 (vec3_t org, int colorStart, int colorLength); +void R_LavaSplash (vec3_t org); +void R_TeleportSplash (vec3_t org); + +void R_PushDlights (void); + + +// +// surface cache related +// +extern int reinit_surfcache; // if 1, surface cache is currently empty and +extern qboolean r_cache_thrash; // set if thrashing the surface cache + +int D_SurfaceCacheForRes (int width, int height); +void D_FlushCaches (void); +void D_DeleteSurfaceCache (void); +void D_InitCaches (void *buffer, int size); +void R_SetVrect (vrect_t *pvrect, vrect_t *pvrectin, int lineadj); + diff --git a/contrib/other/sdlquake-1.0.9/resource.h b/contrib/other/sdlquake-1.0.9/resource.h new file mode 100644 index 000000000..afabb2eb2 --- /dev/null +++ b/contrib/other/sdlquake-1.0.9/resource.h @@ -0,0 +1,20 @@ +//{{NO_DEPENDENCIES}} +// Microsoft Developer Studio generated include file. +// Used by winquake.rc +// +#define IDS_STRING1 1 +#define IDI_ICON2 1 +#define IDD_DIALOG1 108 +#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 111 +#define _APS_NEXT_COMMAND_VALUE 40001 +#define _APS_NEXT_CONTROL_VALUE 1004 +#define _APS_NEXT_SYMED_VALUE 101 +#endif +#endif diff --git a/contrib/other/sdlquake-1.0.9/sbar.c b/contrib/other/sdlquake-1.0.9/sbar.c new file mode 100644 index 000000000..be9ec9cd7 --- /dev/null +++ b/contrib/other/sdlquake-1.0.9/sbar.c @@ -0,0 +1,1323 @@ +/* +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. + +*/ +// sbar.c -- status bar code + +#include "quakedef.h" + + +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_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 + // 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; + +qboolean sb_showscores; + +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 + +//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 +//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}; +//MED 01/04/97 added hipnotic items array +qpic_t *hsb_items[2]; + +void Sbar_MiniDeathmatchOverlay (void); +void Sbar_DeathmatchOverlay (void); +void M_DrawPic (int x, int y, qpic_t *pic); + +/* +=============== +Sbar_ShowScores + +Tab key down +=============== +*/ +void Sbar_ShowScores (void) +{ + if (sb_showscores) + return; + sb_showscores = true; + sb_updates = 0; +} + +/* +=============== +Sbar_DontShowScores + +Tab key up +=============== +*/ +void Sbar_DontShowScores (void) +{ + sb_showscores = false; + sb_updates = 0; +} + +/* +=============== +Sbar_Changed +=============== +*/ +void Sbar_Changed (void) +{ + sb_updates = 0; // update next frame +} + +/* +=============== +Sbar_Init +=============== +*/ +void Sbar_Init (void) +{ + int 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)); + } + + sb_nums[0][10] = Draw_PicFromWad ("num_minus"); + sb_nums[1][10] = Draw_PicFromWad ("anum_minus"); + + sb_colon = Draw_PicFromWad ("num_colon"); + sb_slash = Draw_PicFromWad ("num_slash"); + + sb_weapons[0][0] = Draw_PicFromWad ("inv_shotgun"); + sb_weapons[0][1] = Draw_PicFromWad ("inv_sshotgun"); + sb_weapons[0][2] = Draw_PicFromWad ("inv_nailgun"); + sb_weapons[0][3] = Draw_PicFromWad ("inv_snailgun"); + sb_weapons[0][4] = Draw_PicFromWad ("inv_rlaunch"); + sb_weapons[0][5] = Draw_PicFromWad ("inv_srlaunch"); + sb_weapons[0][6] = Draw_PicFromWad ("inv_lightng"); + + sb_weapons[1][0] = Draw_PicFromWad ("inv2_shotgun"); + sb_weapons[1][1] = Draw_PicFromWad ("inv2_sshotgun"); + sb_weapons[1][2] = Draw_PicFromWad ("inv2_nailgun"); + sb_weapons[1][3] = Draw_PicFromWad ("inv2_snailgun"); + sb_weapons[1][4] = Draw_PicFromWad ("inv2_rlaunch"); + sb_weapons[1][5] = Draw_PicFromWad ("inv2_srlaunch"); + sb_weapons[1][6] = Draw_PicFromWad ("inv2_lightng"); + + 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)); + sb_weapons[2+i][2] = Draw_PicFromWad (va("inva%i_nailgun",i+1)); + sb_weapons[2+i][3] = Draw_PicFromWad (va("inva%i_snailgun",i+1)); + sb_weapons[2+i][4] = Draw_PicFromWad (va("inva%i_rlaunch",i+1)); + sb_weapons[2+i][5] = Draw_PicFromWad (va("inva%i_srlaunch",i+1)); + sb_weapons[2+i][6] = Draw_PicFromWad (va("inva%i_lightng",i+1)); + } + + sb_ammo[0] = Draw_PicFromWad ("sb_shells"); + sb_ammo[1] = Draw_PicFromWad ("sb_nails"); + sb_ammo[2] = Draw_PicFromWad ("sb_rocket"); + sb_ammo[3] = Draw_PicFromWad ("sb_cells"); + + sb_armor[0] = Draw_PicFromWad ("sb_armor1"); + sb_armor[1] = Draw_PicFromWad ("sb_armor2"); + sb_armor[2] = Draw_PicFromWad ("sb_armor3"); + + sb_items[0] = Draw_PicFromWad ("sb_key1"); + sb_items[1] = Draw_PicFromWad ("sb_key2"); + sb_items[2] = Draw_PicFromWad ("sb_invis"); + sb_items[3] = Draw_PicFromWad ("sb_invuln"); + sb_items[4] = Draw_PicFromWad ("sb_suit"); + sb_items[5] = Draw_PicFromWad ("sb_quad"); + + sb_sigil[0] = Draw_PicFromWad ("sb_sigil1"); + sb_sigil[1] = Draw_PicFromWad ("sb_sigil2"); + sb_sigil[2] = Draw_PicFromWad ("sb_sigil3"); + sb_sigil[3] = Draw_PicFromWad ("sb_sigil4"); + + sb_faces[4][0] = Draw_PicFromWad ("face1"); + sb_faces[4][1] = Draw_PicFromWad ("face_p1"); + sb_faces[3][0] = Draw_PicFromWad ("face2"); + sb_faces[3][1] = Draw_PicFromWad ("face_p2"); + sb_faces[2][0] = Draw_PicFromWad ("face3"); + sb_faces[2][1] = Draw_PicFromWad ("face_p3"); + sb_faces[1][0] = Draw_PicFromWad ("face4"); + sb_faces[1][1] = Draw_PicFromWad ("face_p4"); + sb_faces[0][0] = Draw_PicFromWad ("face5"); + sb_faces[0][1] = Draw_PicFromWad ("face_p5"); + + sb_face_invis = Draw_PicFromWad ("face_invis"); + sb_face_invuln = Draw_PicFromWad ("face_invul2"); + 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"); + +//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"); + } + + if (rogue) + { + rsb_invbar[0] = Draw_PicFromWad ("r_invbar1"); + rsb_invbar[1] = Draw_PicFromWad ("r_invbar2"); + + rsb_weapons[0] = Draw_PicFromWad ("r_lava"); + rsb_weapons[1] = Draw_PicFromWad ("r_superlava"); + rsb_weapons[2] = Draw_PicFromWad ("r_gren"); + rsb_weapons[3] = Draw_PicFromWad ("r_multirock"); + rsb_weapons[4] = Draw_PicFromWad ("r_plasma"); + + rsb_items[0] = Draw_PicFromWad ("r_shield1"); + rsb_items[1] = Draw_PicFromWad ("r_agrav1"); + +// PGM 01/19/97 - team color border + rsb_teambord = Draw_PicFromWad ("r_teambord"); +// PGM 01/19/97 - team color border + + rsb_ammo[0] = Draw_PicFromWad ("r_ammolava"); + rsb_ammo[1] = Draw_PicFromWad ("r_ammomulti"); + rsb_ammo[2] = Draw_PicFromWad ("r_ammoplasma"); + } +} + + +//============================================================================= + +// drawing routines are relative to the status bar location + +/* +============= +Sbar_DrawPic +============= +*/ +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); + else + Draw_Pic (x + ((vid.width - 320)>>1), y + (vid.height-SBAR_HEIGHT), pic); +} + +/* +============= +Sbar_DrawTransPic +============= +*/ +void Sbar_DrawTransPic (int x, int y, qpic_t *pic) +{ + if (cl.gametype == GAME_DEATHMATCH) + Draw_TransPic (x /*+ ((vid.width - 320)>>1)*/, y + (vid.height-SBAR_HEIGHT), pic); + else + Draw_TransPic (x + ((vid.width - 320)>>1), y + (vid.height-SBAR_HEIGHT), pic); +} + +/* +================ +Sbar_DrawCharacter + +Draws one solid graphics character +================ +*/ +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); + else + Draw_Character ( x + ((vid.width - 320)>>1) + 4 , y + vid.height-SBAR_HEIGHT, num); +} + +/* +================ +Sbar_DrawString +================ +*/ +void Sbar_DrawString (int x, int y, char *str) +{ + if (cl.gametype == GAME_DEATHMATCH) + Draw_String (x /*+ ((vid.width - 320)>>1)*/, y+ vid.height-SBAR_HEIGHT, str); + else + Draw_String (x + ((vid.width - 320)>>1), y+ vid.height-SBAR_HEIGHT, str); +} + +/* +============= +Sbar_itoa +============= +*/ +int Sbar_itoa (int num, char *buf) +{ + char *str; + int pow10; + int dig; + + str = buf; + + if (num < 0) + { + *str++ = '-'; + num = -num; + } + + for (pow10 = 10 ; num >= pow10 ; pow10 *= 10) + ; + + do + { + pow10 /= 10; + dig = num/pow10; + *str++ = '0'+dig; + num -= dig*pow10; + } while (pow10 != 1); + + *str = 0; + + return str-buf; +} + + +/* +============= +Sbar_DrawNum +============= +*/ +void Sbar_DrawNum (int x, int y, int num, int digits, int color) +{ + char str[12]; + char *ptr; + int l, frame; + + l = Sbar_itoa (num, str); + ptr = str; + if (l > digits) + ptr += (l-digits); + if (l < digits) + x += (digits-l)*24; + + while (*ptr) + { + if (*ptr == '-') + frame = STAT_MINUS; + else + frame = *ptr -'0'; + + Sbar_DrawTransPic (x,y,sb_nums[color][frame]); + x += 24; + ptr++; + } +} + +//============================================================================= + +int fragsort[MAX_SCOREBOARD]; + +char scoreboardtext[MAX_SCOREBOARD][20]; +int scoreboardtop[MAX_SCOREBOARD]; +int scoreboardbottom[MAX_SCOREBOARD]; +int scoreboardcount[MAX_SCOREBOARD]; +int scoreboardlines; + +/* +=============== +Sbar_SortFrags +=============== +*/ +void Sbar_SortFrags (void) +{ + int i, j, k; + +// sort by frags + scoreboardlines = 0; + for (i=0 ; ifrags, s->name); + + top = s->colors & 0xf0; + bottom = (s->colors & 15) <<4; + scoreboardtop[i] = Sbar_ColorForMap (top); + scoreboardbottom[i] = Sbar_ColorForMap (bottom); + } +} + + + +/* +=============== +Sbar_SoloScoreboard +=============== +*/ +void Sbar_SoloScoreboard (void) +{ + char str[80]; + int minutes, seconds, tens, units; + int l; + + sprintf (str,"Monsters:%3i /%3i", cl.stats[STAT_MONSTERS], cl.stats[STAT_TOTALMONSTERS]); + Sbar_DrawString (8, 4, str); + + sprintf (str,"Secrets :%3i /%3i", cl.stats[STAT_SECRETS], cl.stats[STAT_TOTALSECRETS]); + Sbar_DrawString (8, 12, str); + +// time + 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); + +// draw level name + l = strlen (cl.levelname); + Sbar_DrawString (232 - l*4, 12, cl.levelname); +} + +/* +=============== +Sbar_DrawScoreboard +=============== +*/ +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 +} + +//============================================================================= + +/* +=============== +Sbar_DrawInventory +=============== +*/ +void Sbar_DrawInventory (void) +{ + int i; + char num[6]; + float time; + int flashon; + + if (rogue) + { + if ( cl.stats[STAT_ACTIVEWEAPON] >= RIT_LAVA_NAILGUN ) + Sbar_DrawPic (0, -24, rsb_invbar[0]); + else + Sbar_DrawPic (0, -24, rsb_invbar[1]); + } + else + { + Sbar_DrawPic (0, -24, sb_ibar); + } + +// weapons + for (i=0 ; i<7 ; i++) + { + if (cl.items & (IT_SHOTGUN<= 10) + { + if ( cl.stats[STAT_ACTIVEWEAPON] == (IT_SHOTGUN< 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 + } + } + } + + if (rogue) + { + // check for powered up weapon. + if ( cl.stats[STAT_ACTIVEWEAPON] >= RIT_LAVA_NAILGUN ) + { + for (i=0;i<5;i++) + { + if (cl.stats[STAT_ACTIVEWEAPON] == (RIT_LAVA_NAILGUN << i)) + { + Sbar_DrawPic ((i+2)*24, -16, rsb_weapons[i]); + } + } + } + } + +// ammo counts + for (i=0 ; i<4 ; i++) + { + sprintf (num, "%3i",cl.stats[STAT_SHELLS+i] ); + if (num[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'); + if (num[2] != ' ') + 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; + } + 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++) + { + if (cl.items & (1<<(29+i))) + { + time = cl.item_gettime[29+i]; + + if (time && time > cl.time - 2 && flashon ) + { // flash frame + sb_updates = 0; + } + else + { + Sbar_DrawPic (288 + i*16, -16, rsb_items[i]); + } + + if (time && time > cl.time - 2) + sb_updates = 0; + } + } + } + else + { + // sigils + 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 ) + { // flash frame + sb_updates = 0; + } + else + Sbar_DrawPic (320-32 + i*8, -16, sb_sigil[i]); + if (time && time > cl.time - 2) + sb_updates = 0; + } + } + } +} + +//============================================================================= + +/* +=============== +Sbar_DrawFrags +=============== +*/ +void Sbar_DrawFrags (void) +{ + int i, k, l; + int top, bottom; + int x, y, f; + int xofs; + char num[12]; + scoreboard_t *s; + + Sbar_SortFrags (); + +// draw the text + l = scoreboardlines <= 4 ? scoreboardlines : 4; + + x = 23; + if (cl.gametype == GAME_DEATHMATCH) + xofs = 0; + else + xofs = (vid.width - 320)>>1; + y = vid.height - SBAR_HEIGHT - 23; + + 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); + + // draw number + f = s->frags; + sprintf (num, "%3i",f); + + Sbar_DrawCharacter ( (x+1)*8 , -24, num[0]); + Sbar_DrawCharacter ( (x+2)*8 , -24, num[1]); + Sbar_DrawCharacter ( (x+3)*8 , -24, num[2]); + + if (k == cl.viewentity - 1) + { + Sbar_DrawCharacter (x*8+2, -24, 16); + Sbar_DrawCharacter ( (x+4)*8-4, -24, 17); + } + x+=4; + } +} + +//============================================================================= + + +/* +=============== +Sbar_DrawFace +=============== +*/ +void Sbar_DrawFace (void) +{ + 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)) + { + int top, bottom; + int xofs; + char num[12]; + scoreboard_t *s; + + s = &cl.scores[cl.viewentity - 1]; + // draw background + top = s->colors & 0xf0; + bottom = (s->colors & 15)<<4; + top = Sbar_ColorForMap (top); + bottom = Sbar_ColorForMap (bottom); + + 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 number + f = s->frags; + sprintf (num, "%3i",f); + + if (top==8) + { + if (num[0] != ' ') + Sbar_DrawCharacter(109, 3, 18 + num[0] - '0'); + if (num[1] != ' ') + Sbar_DrawCharacter(116, 3, 18 + num[1] - '0'); + if (num[2] != ' ') + Sbar_DrawCharacter(123, 3, 18 + num[2] - '0'); + } + else + { + Sbar_DrawCharacter ( 109, 3, num[0]); + Sbar_DrawCharacter ( 116, 3, num[1]); + Sbar_DrawCharacter ( 123, 3, num[2]); + } + + return; + } +// PGM 01/19/97 - team color drawing + + if ( (cl.items & (IT_INVISIBILITY | IT_INVULNERABILITY) ) + == (IT_INVISIBILITY | IT_INVULNERABILITY) ) + { + Sbar_DrawPic (112, 0, sb_face_invis_invuln); + return; + } + if (cl.items & IT_QUAD) + { + Sbar_DrawPic (112, 0, sb_face_quad ); + return; + } + if (cl.items & IT_INVISIBILITY) + { + Sbar_DrawPic (112, 0, sb_face_invis ); + return; + } + if (cl.items & IT_INVULNERABILITY) + { + Sbar_DrawPic (112, 0, sb_face_invuln); + return; + } + + if (cl.stats[STAT_HEALTH] >= 100) + f = 4; + else + f = cl.stats[STAT_HEALTH] / 20; + + if (cl.time <= cl.faceanimtime) + { + anim = 1; + sb_updates = 0; // make sure the anim gets drawn over + } + else + anim = 0; + Sbar_DrawPic (112, 0, sb_faces[f][anim]); +} + +/* +=============== +Sbar_Draw +=============== +*/ +void Sbar_Draw (void) +{ + if (scr_con_current == vid.height) + return; // console is full screen + + if (sb_updates >= vid.numpages) + return; + + scr_copyeverything = 1; + + sb_updates++; + + if (sb_lines && vid.width > 320) + Draw_TileClear (0, vid.height - sb_lines, vid.width, sb_lines); + + if (sb_lines > 24) + { + Sbar_DrawInventory (); + if (cl.maxclients != 1) + Sbar_DrawFrags (); + } + + if (sb_showscores || cl.stats[STAT_HEALTH] <= 0) + { + Sbar_DrawPic (0, 0, sb_scorebar); + Sbar_DrawScoreboard (); + sb_updates = 0; + } + else if (sb_lines) + { + Sbar_DrawPic (0, 0, sb_sbar); + + // 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 + if (cl.items & IT_INVULNERABILITY) + { + Sbar_DrawNum (24, 0, 666, 3, 1); + Sbar_DrawPic (0, 0, draw_disc); + } + else + { + if (rogue) + { + Sbar_DrawNum (24, 0, cl.stats[STAT_ARMOR], 3, + cl.stats[STAT_ARMOR] <= 25); + if (cl.items & RIT_ARMOR3) + Sbar_DrawPic (0, 0, sb_armor[2]); + else if (cl.items & RIT_ARMOR2) + Sbar_DrawPic (0, 0, sb_armor[1]); + else if (cl.items & RIT_ARMOR1) + Sbar_DrawPic (0, 0, sb_armor[0]); + } + else + { + Sbar_DrawNum (24, 0, cl.stats[STAT_ARMOR], 3 + , cl.stats[STAT_ARMOR] <= 25); + if (cl.items & IT_ARMOR3) + Sbar_DrawPic (0, 0, sb_armor[2]); + else if (cl.items & IT_ARMOR2) + Sbar_DrawPic (0, 0, sb_armor[1]); + else if (cl.items & IT_ARMOR1) + Sbar_DrawPic (0, 0, sb_armor[0]); + } + } + + // face + Sbar_DrawFace (); + + // health + Sbar_DrawNum (136, 0, cl.stats[STAT_HEALTH], 3 + , cl.stats[STAT_HEALTH] <= 25); + + // ammo icon + if (rogue) + { + if (cl.items & RIT_SHELLS) + Sbar_DrawPic (224, 0, sb_ammo[0]); + else if (cl.items & RIT_NAILS) + Sbar_DrawPic (224, 0, sb_ammo[1]); + else if (cl.items & RIT_ROCKETS) + Sbar_DrawPic (224, 0, sb_ammo[2]); + else if (cl.items & RIT_CELLS) + Sbar_DrawPic (224, 0, sb_ammo[3]); + else if (cl.items & RIT_LAVA_NAILS) + Sbar_DrawPic (224, 0, rsb_ammo[0]); + else if (cl.items & RIT_PLASMA_AMMO) + Sbar_DrawPic (224, 0, rsb_ammo[1]); + else if (cl.items & RIT_MULTI_ROCKETS) + Sbar_DrawPic (224, 0, rsb_ammo[2]); + } + else + { + if (cl.items & IT_SHELLS) + Sbar_DrawPic (224, 0, sb_ammo[0]); + else if (cl.items & IT_NAILS) + Sbar_DrawPic (224, 0, sb_ammo[1]); + else if (cl.items & IT_ROCKETS) + Sbar_DrawPic (224, 0, sb_ammo[2]); + else if (cl.items & IT_CELLS) + Sbar_DrawPic (224, 0, sb_ammo[3]); + } + + Sbar_DrawNum (248, 0, cl.stats[STAT_AMMO], 3, + cl.stats[STAT_AMMO] <= 10); + } + + if (vid.width > 320) { + if (cl.gametype == GAME_DEATHMATCH) + Sbar_MiniDeathmatchOverlay (); + } +} + +//============================================================================= + +/* +================== +Sbar_IntermissionNumber + +================== +*/ +void Sbar_IntermissionNumber (int x, int y, int num, int digits, int color) +{ + char str[12]; + char *ptr; + int l, frame; + + l = Sbar_itoa (num, str); + ptr = str; + if (l > digits) + ptr += (l-digits); + if (l < digits) + x += (digits-l)*24; + + while (*ptr) + { + if (*ptr == '-') + frame = STAT_MINUS; + else + frame = *ptr -'0'; + + Draw_TransPic (x,y,sb_nums[color][frame]); + x += 24; + ptr++; + } +} + +/* +================== +Sbar_DeathmatchOverlay + +================== +*/ +void Sbar_DeathmatchOverlay (void) +{ + 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; + + pic = Draw_CachePic ("gfx/ranking.lmp"); + M_DrawPic ((320-pic->width)/2, 8, pic); + +// scores + Sbar_SortFrags (); + +// draw the text + l = scoreboardlines; + + x = 80 + ((vid.width - 320)>>1); + y = 40; + 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, y, 40, 4, top); + Draw_Fill ( x, y+4, 40, 4, bottom); + + // draw 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]); + + if (k == cl.viewentity - 1) + Draw_Character ( x - 8, y, 12); + +#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 + Draw_String (x+64, y, s->name); + + y += 10; + } +} + +/* +================== +Sbar_DeathmatchOverlay + +================== +*/ +void Sbar_MiniDeathmatchOverlay (void) +{ + qpic_t *pic; + int i, k, l; + int top, bottom; + int x, y, f; + char num[12]; + scoreboard_t *s; + int numlines; + + if (vid.width < 512 || !sb_lines) + return; + + scr_copyeverything = 1; + scr_fullupdate = 0; + +// scores + Sbar_SortFrags (); + +// draw the text + l = scoreboardlines; + y = vid.height - sb_lines; + numlines = sb_lines/8; + if (numlines < 3) + return; + + //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 = 324; + for (/* */; i < scoreboardlines && y < vid.height - 8 ; i++) + { + k = fragsort[i]; + s = &cl.scores[k]; + if (!s->name[0]) + continue; + + // draw background + 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 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]); + + 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 + Draw_String (x+48, y, s->name); + + y += 8; + } +} + +/* +================== +Sbar_IntermissionOverlay + +================== +*/ +void Sbar_IntermissionOverlay (void) +{ + qpic_t *pic; + int dig; + int num; + + scr_copyeverything = 1; + scr_fullupdate = 0; + + if (cl.gametype == GAME_DEATHMATCH) + { + Sbar_DeathmatchOverlay (); + return; + } + + pic = Draw_CachePic ("gfx/complete.lmp"); + Draw_Pic (64, 24, pic); + + pic = Draw_CachePic ("gfx/inter.lmp"); + Draw_TransPic (0, 56, pic); + +// time + dig = cl.completed_time/60; + Sbar_IntermissionNumber (160, 64, dig, 3, 0); + num = cl.completed_time - dig*60; + 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); + +} + + +/* +================== +Sbar_FinaleOverlay + +================== +*/ +void Sbar_FinaleOverlay (void) +{ + qpic_t *pic; + + scr_copyeverything = 1; + + pic = Draw_CachePic ("gfx/finale.lmp"); + Draw_TransPic ( (vid.width-pic->width)/2, 16, pic); +} diff --git a/contrib/other/sdlquake-1.0.9/sbar.h b/contrib/other/sdlquake-1.0.9/sbar.h new file mode 100644 index 000000000..286b3b6a7 --- /dev/null +++ b/contrib/other/sdlquake-1.0.9/sbar.h @@ -0,0 +1,39 @@ +/* +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 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_Changed (void); +// call whenever any of the client stats represented on the sbar changes + +void Sbar_Draw (void); +// called every frame by screen + +void Sbar_IntermissionOverlay (void); +// called each frame after the level has been completed + +void Sbar_FinaleOverlay (void); diff --git a/contrib/other/sdlquake-1.0.9/scitech/INCLUDE/DEBUG.H b/contrib/other/sdlquake-1.0.9/scitech/INCLUDE/DEBUG.H new file mode 100644 index 000000000..1e9367640 --- /dev/null +++ b/contrib/other/sdlquake-1.0.9/scitech/INCLUDE/DEBUG.H @@ -0,0 +1,290 @@ +/**************************************************************************** +* +* Copyright (C) 1996 SciTech Software +* All rights reserved. +* +* Filename: $Workfile: debug.h $ +* Version: $Revision: 1.17 $ +* +* Language: ANSI C +* Environment: any +* +* Description: General header file for operating system portable code. +* +* $Date: 04 Mar 1997 11:34:08 $ $Author: KendallB $ +* +****************************************************************************/ + +#ifndef __DEBUG_H +#define __DEBUG_H + +/* We have the following defines to identify the compilation environment: + * + * __16BIT__ Compiling for 16 bit code (any environment) + * __32BIT__ Compiling for 32 bit code (any environment) + * __MSDOS__ Compiling for MS-DOS (includes __WINDOWS16__, __WIN386__) + * __REALDOS__ Compiling for MS-DOS (excludes __WINDOWS16__) + * __MSDOS16__ Compiling for 16 bit MS-DOS + * __MSDOS32__ Compiling for 32 bit MS-DOS + * __WINDOWS__ Compiling for Windows + * __WINDOWS16__ Compiling for 16 bit Windows (__MSDOS__ also defined) + * __WINDOWS32__ Compiling for 32 bit Windows + * __WIN386__ Compiling for Watcom C++ Win386 extended Windows + * __OS2__ Compiling for OS/2 + * __OS2_16__ Compiling for 16 bit OS/2 + * __OS2_32__ Compiling for 32 bit OS/2 + * __UNIX__ Compiling for Unix + * + */ + +#ifdef __SC__ +#if __INTSIZE == 4 +#define __SC386__ +#endif +#endif + +#ifdef __GNUC__ +#define __cdecl /* GCC doesn't know about __cdecl modifiers */ +#define __FLAT__ /* GCC is always 32 bit flat model */ +#define __HAS_BOOL__ /* Latest GNU C++ has bool type */ +#endif + +#ifdef __BORLANDC__ +#if (__BORLANDC__ >= 0x500) || defined(CLASSLIB_DEFS_H) +#define __HAS_BOOL__ /* Borland C++ 5.0 and later define bool type */ +#endif +#endif + +/* For the Metaware High C/C++ compiler, there is no _cdecl calling + * convention. The conventions can be changed, but it is a complicated + * process involving #pragmas, and all externally referenced functions + * will use stack based calling conventions. We also need to change the + * global aliasing conventions to use underscores for external function + * and variables names, so that our assembler routines will link + * correctly (except of course the main function - man what a PAIN!). + */ + +#ifdef __HIGHC__ +#define __cdecl +#define __FLAT__ /* High C is always 32 bit flat model */ +#pragma Global_aliasing_convention("_%r") +extern main(); +#pragma Alias(main,"main") +#endif + +#if defined(__MSDOS__) || defined(__DOS__) || defined(__DPMI32__) || (defined(M_I86) && !defined(__SC386__)) +#ifndef __MSDOS__ +#define __MSDOS__ +#endif +#if defined(__386__) || defined(__FLAT__) || defined(__NT__) || defined(__SC386__) +#ifndef __MSDOS32__ +#define __MSDOS32__ +#endif +#ifndef __32BIT__ +#define __32BIT__ +#endif +#ifndef __REALDOS__ +#define __REALDOS__ +#endif +#elif (defined(_Windows) || defined(_WINDOWS)) && !defined(__DPMI16__) +#ifndef __16BIT__ +#define __16BIT__ +#endif +#ifndef __WINDOWS16__ +#define __WINDOWS16__ +#endif +#ifndef __WINDOWS__ +#define __WINDOWS__ +#endif +#ifndef __MSDOS__ +#define __MSDOS__ +#endif +#else +#ifndef __16BIT__ +#define __16BIT__ +#endif +#ifndef __MSDOS16__ +#define __MSDOS16__ +#endif +#ifndef __REALDOS__ +#define __REALDOS__ +#endif +#endif +#elif defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__NT__) +#ifndef __32BIT__ +#define __32BIT__ +#endif +#ifndef __WINDOWS32__ +#define __WINDOWS32__ +#endif +#ifndef _WIN32 +#define _WIN32 /* Microsoft Win32 SDK headers use _WIN32 */ +#endif +#ifndef WIN32 +#define WIN32 /* OpenGL headers use WIN32 */ +#endif +#ifndef __WINDOWS__ +#define __WINDOWS__ +#endif +#elif defined(__WINDOWS_386__) +#ifndef __32BIT__ +#define __32BIT__ +#endif +#ifndef __WIN386__ +#define __WIN386__ +#endif +#ifndef __WINDOWS__ +#define __WINDOWS__ +#endif +#ifndef __MSDOS__ +#define __MSDOS__ +#endif +#elif defined(__OS2__) +#ifndef __OS2__ /* TODO: to be completed */ +#define __OS2__ +#define __OS2_32__ /* Default to 32 bit OS/2 */ +#endif +#else +#define __UNIX__ /* TODO: to be completed */ +#endif + +/* We have the following defines to define the calling conventions for + * publicly accesible functions: + * + * _PUBAPI - Compiler default calling conventions for all public 'C' functions + * _ASMAPI - Calling conventions for all public assembler functions + * _DLLAPI - Calling conventions for all DLL exported functions + * _DLLVAR - Modifier to export/import globals in 32 bit DLL's + * _EXPORT - Expands to _export when compiling a DLL + * _VARAPI - Modifiers for variables; Watcom C++ mangles C++ globals + */ + +#define _PUBAPI +#define _ASMAPI __cdecl + +#if defined(_MSC_VER) && defined(_WIN32) && !defined(__SC__) +#define __PASCAL __stdcall +#define __export +#define __import +#else +#define __PASCAL __pascal +#endif + +#if defined(__WATCOMC__) +#define _VARAPI __cdecl +#else +#define _VARAPI +#endif + +#if defined(__WINDOWS__) +#ifdef BUILD_DLL +#define _DLLASM __export __cdecl +#define _EXPORT __export +#ifdef __WINDOWS32__ +#define _DLLAPI __export __PASCAL +#define _DLLVAR __export +#else +#define _DLLAPI __export __far __pascal +#define _DLLVAR +#endif +#else +#define _DLLASM __cdecl +#define _EXPORT +#ifdef __WINDOWS32__ +#define _DLLAPI __PASCAL +#define _DLLVAR __import +#else +#define _DLLAPI __far __pascal +#define _DLLVAR +#endif +#endif +#else +#define _EXPORT +#define _DLLAPI +#define _DLLVAR +#endif + +/* Useful macros */ + +#define PRIVATE static +#define PUBLIC + +#ifdef DEBUG +# define DBG(x) x +#else +# define DBG(x) +#endif + +#ifndef NULL +# define NULL 0L +#endif + +#ifndef MAX +# define MAX(a,b) ( ((a) > (b)) ? (a) : (b)) +#endif +#ifndef MIN +# define MIN(a,b) ( ((a) < (b)) ? (a) : (b)) +#endif +#ifndef ABS +# define ABS(a) ((a) >= 0 ? (a) : -(a)) +#endif +#ifndef SIGN +# define SIGN(a) ((a) > 0 ? 1 : -1) +#endif + +/* General typedefs */ + +#ifndef __GENDEFS +#define __GENDEFS +typedef unsigned char uchar; +typedef unsigned short ushort; +typedef unsigned int uint; +typedef unsigned long ulong; +typedef int ibool; /* Integer boolean type */ +#ifndef __cplusplus +#define bool ibool /* Standard C */ +#else +#ifndef __HAS_BOOL__ +#define bool ibool /* Older C++ compilers */ +#endif +#endif /* __cplusplus */ +#endif /* __GENDEFS */ + +/* Includes Windows headers, as they define TRUE and FALSE */ + +#ifdef __WINDOWS__ +#ifndef _WINDOWS_ /* Dont include if already included */ +#ifndef __WIN386__ +#define STRICT +#define WIN32_LEAN_AND_MEAN +#endif +#include +#endif +#endif + +/* Boolean truth values */ + +#undef false +#undef true +#undef NO +#undef YES +#undef FALSE +#undef TRUE + +#ifdef __cplusplus /* Cast to bool's for C++ code */ +#define false ((bool)0) +#define true ((bool)1) +#define NO ((bool)0) +#define YES ((bool)1) +#define FALSE ((bool)0) +#define TRUE ((bool)1) +#else /* Define to 0 and 1 for C code */ +#define false 0 +#define true 1 +#define NO 0 +#define YES 1 +#define FALSE 0 +#define TRUE 1 +#endif + +#endif /* __DEBUG_H */ diff --git a/contrib/other/sdlquake-1.0.9/scitech/INCLUDE/MGLDOS.H b/contrib/other/sdlquake-1.0.9/scitech/INCLUDE/MGLDOS.H new file mode 100644 index 000000000..aa286c000 --- /dev/null +++ b/contrib/other/sdlquake-1.0.9/scitech/INCLUDE/MGLDOS.H @@ -0,0 +1,83 @@ +/**************************************************************************** +* +* MegaGraph Graphics Library +* +* Copyright (C) 1996 SciTech Software. +* All rights reserved. +* +* Filename: $Workfile: mgldos.h $ +* Version: $Revision: 1.9 $ +* +* Language: ANSI C +* Environment: IBM PC (MS DOS) +* +* Description: Header file for the MGLDOS binding for the MSDOS environment. +* +* $Date: 30 Jan 1997 17:31:58 $ $Author: KendallB $ +* +****************************************************************************/ + +#ifndef __MGLDOS_H +#define __MGLDOS_H + +#ifndef MGLDOS +#define MGLDOS +#endif + +/*---------------------- Macros and type definitions ----------------------*/ + +typedef void *MGL_HWND; + +/*------------------------- Function Prototypes ---------------------------*/ + +#ifdef __cplusplus +extern "C" { /* Use "C" linkage when in C++ mode */ +#endif + +/* Initialise the MGL for fullscreen output */ + +bool MGLAPI MGL_init(m_int *driver,m_int *mode,const char *mglpath); + +/* Change the active display mode. You must destroy all display device + * contexts before calling this function, and re-create them again with + * the new display mode. Does not affect any event handling hooks. + */ + +bool MGLAPI MGL_changeDisplayMode(m_int mode); + +/* Disable/enable event handling (call before calling MGL_init */ + +void MGLAPI MGL_useEvents(bool use); + +/* Device context management */ + +MGLDC * MGLAPI MGL_createDisplayDC(m_int numBuffers); +MGLDC * MGLAPI MGL_createScrollingDC(m_int virtualX,m_int virtualY,m_int numBuffers); +MGLDC * MGLAPI MGL_createOffscreenDC(void); +MGLDC * MGLAPI MGL_createLinearOffscreenDC(void); +MGLDC * MGLAPI MGL_createMemoryDC(m_int xSize,m_int ySize,m_int bitsPerPixel,pixel_format_t *pf); +bool MGLAPI MGL_destroyDC(MGLDC *dc); + +/* Generic helper functions */ + +ulong MGLAPI MGL_getTicks(void); +ulong MGLAPI MGL_getTickResolution(void); +void MGLAPI MGL_delay(m_int millseconds); +void MGLAPI MGL_beep(m_int freq,m_int milliseconds); +void MGLAPI MGL_suspend(void); +void MGLAPI MGL_resume(void); + +/* Fullscreen specific routines */ + +void MGLAPI MGL_setPaletteSnowLevel(MGLDC *dc,m_int level); +m_int MGLAPI MGL_getPaletteSnowLevel(MGLDC *dc); + +/* Determine if a specific scancode'ed key is held down (PC specific) */ + +bool MGLAPI EVT_isKeyDown(uchar scanCode); + +#ifdef __cplusplus +} /* End of "C" linkage for C++ */ +#endif + +#endif /* __MGLDOS_H */ diff --git a/contrib/other/sdlquake-1.0.9/scitech/INCLUDE/MGLWIN.H b/contrib/other/sdlquake-1.0.9/scitech/INCLUDE/MGLWIN.H new file mode 100644 index 000000000..c5b9c301f --- /dev/null +++ b/contrib/other/sdlquake-1.0.9/scitech/INCLUDE/MGLWIN.H @@ -0,0 +1,152 @@ +/**************************************************************************** +* +* MegaGraph Graphics Library +* +* Copyright (C) 1996 SciTech Software. +* All rights reserved. +* +* Filename: $Workfile: mglwin.h $ +* Version: $Revision: 1.14 $ +* +* Language: ANSI C +* Environment: IBM PC (MS DOS) +* +* Description: Header file for the MGLWIN bindings for MS Windows using +* WinG in a window and WinDirect for full screen. The MGLWIN +* binding only targets Win32 applications, so cannot be used +* for 16 bit Windows development. +* +* $Date: 14 Mar 1997 16:09:34 $ $Author: KendallB $ +* +****************************************************************************/ + +#ifndef __MGLWIN_H +#define __MGLWIN_H + +#ifndef MGLWIN +#define MGLWIN +#endif + +/*---------------------- Macros and type definitions ----------------------*/ + +typedef HWND MGL_HWND; +typedef HDC MGL_HDC; +typedef HINSTANCE MGL_HINSTANCE; + +/*------------------------- Function Prototypes ---------------------------*/ + +#ifdef __cplusplus +extern "C" { /* Use "C" linkage when in C++ mode */ +#endif + +/* Initialise the MGL for fullscreen output */ + +bool MGLAPI MGL_init(m_int *driver,m_int *mode,const char *mglpath); + +/* Initialise the MGL just for Windowed output, not full screen */ + +bool MGLAPI MGL_initWindowed(const char *mglpath); + +/* Function to register a fullscreen window with the MGL. If you wish + * for the MGL to use your own window for fullscreen modes, you can + * register it with this function. Note that when the MGL goes into + * fullscreen modes, the attributes, size and position of the window are + * modified to make it into a fullscreen Window necessary to cover the + * entire desktop, and the state of the window will be restore to the original + * format on return to normal GDI mode. + * + * Note that if you are using a common window for Windowed mode and fullscreen + * modes of your application, you will need to ensure that certain messages + * that you window normally handles in windowed modes are ignored when in + * fullscreen modes. + */ + +void MGLAPI MGL_registerFullScreenWindow(HWND hwndFullScreen); + +/* Function to register a fullscreen event handling window procedure. + * If you wish to do your own event handling, you can register your window + * procedure with the MGL using this function and it will be called + * when there are messages to be handled. You can still call the MGL_event() + * functions even if you have registered an event handling procedure. + */ + +void MGLAPI MGL_registerEventProc(WNDPROC userWndProc); + +/* Change the active display mode. You must destroy all display device + * contexts before calling this function, and re-create them again with + * the new display mode. Does not affect any event handling hooks. + */ + +bool MGLAPI MGL_changeDisplayMode(m_int mode); + +/* Obtain the handle to the MGL fullscreen window when in fullscreen modes */ + +MGL_HWND MGLAPI MGL_getFullScreenWindow(void); + +/* Tell the MGL what your applications main window is */ + +void MGLAPI MGL_setMainWindow(MGL_HWND hwnd); + +/* Tell the MGL your applications instance handle (call before all funcs!) */ + +void MGLAPI MGL_setAppInstance(MGL_HINSTANCE hInstApp); + +/* Device context management */ + +MGLDC * MGLAPI MGL_createDisplayDC(m_int numBuffers); +MGLDC * MGLAPI MGL_createSrollingDC(m_int virtualX,m_int virtualY,m_int numBuffers); +MGLDC * MGLAPI MGL_createOffscreenDC(void); +MGLDC * MGLAPI MGL_createLinearOffscreenDC(void); +MGLDC * MGLAPI MGL_createWindowedDC(MGL_HWND hwnd); +MGLDC * MGLAPI MGL_createMemoryDC(m_int xSize,m_int ySize,m_int bitsPerPixel,pixel_format_t *pf); +bool MGLAPI MGL_destroyDC(MGLDC *dc); + +/* Get a Windows HDC for the MGL device context. You can use this returned + * HDC to get GDI to draw to the device context surface, such as rendering + * and using TrueType fonts with the MGL. If a Windows compatible HDC is not + * available, this function will return NULL. + */ + +HDC MGLAPI MGL_getWinDC(MGLDC *dc); + +/* Associate a Window manager DC with the MGLDC for painting */ + +bool MGLAPI MGL_setWinDC(MGLDC *dc,MGL_HDC hdc); + +/* Activate the WindowDC's palette */ + +bool MGLAPI MGL_activatePalette(MGLDC *dc,bool unrealize); + +/* Let the MGL know when your application is being activated or deactivated. + * This function only needs to be called when running in Windowed modes and + * you have set the system palette to SYSPAL_NOSTATIC mode, to ensure + * that the MGL can properly re-map your application palette when your + * app is not active and allow Windows to re-map your bitmap colors on the + * fly. This function should be passed a pointer to the currently active + * MGL Windowed DC and a flag to indicate whether the app is in the background + * or not. + */ + +void MGLAPI MGL_appActivate(MGLDC *winDC,bool active); + +/* Generic helper functions */ + +ulong MGLAPI MGL_getTicks(void); +ulong MGLAPI MGL_getTickResolution(void); +void MGLAPI MGL_delay(m_int millseconds); +void MGLAPI MGL_beep(m_int freq,m_int milliseconds); + +/* Fullscreen specific routines */ + +void MGLAPI MGL_setPaletteSnowLevel(MGLDC *dc,m_int level); +m_int MGLAPI MGL_getPaletteSnowLevel(MGLDC *dc); + +/* Determine if a specific scancode'ed key is held down (PC specific) */ + +bool MGLAPI EVT_isKeyDown(uchar scanCode); + +#ifdef __cplusplus +} /* End of "C" linkage for C++ */ +#endif + +#endif /* __MGLWIN_H */ diff --git a/contrib/other/sdlquake-1.0.9/scitech/INCLUDE/MGRAPH.H b/contrib/other/sdlquake-1.0.9/scitech/INCLUDE/MGRAPH.H new file mode 100644 index 000000000..1b72f3f89 --- /dev/null +++ b/contrib/other/sdlquake-1.0.9/scitech/INCLUDE/MGRAPH.H @@ -0,0 +1,1951 @@ +/**************************************************************************** +* +* MegaGraph Graphics Library +* +* Copyright (C) 1996 SciTech Software. +* All rights reserved. +* +* Filename: $Workfile: mgraph.h $ +* Version: $Revision: 1.29 $ +* +* Language: ANSI C +* Environment: IBM PC (MS DOS) +* +* Description: Header file for the MegaGraph Graphics Library. You can +* defined one of the following to specify which MGL API you +* wish to use. +* +* MGL_LITE - Compile for the MGL/Lite API +* MGL_PRO - Compile for the MGL/Pro API +* MGL_FIX3D - Compile for the MGL/3D API (fixed point) +* MGL_FLT3D - Compile for the MGL/3D API (floating point) +* +* If you do not define any of these, MGL_FIX3D will be defined +* automatically for compatibility with older versions of the +* MGL. +* +* $Date: 11 Mar 1997 16:46:42 $ $Author: KendallB $ +* +****************************************************************************/ + +#ifndef __MGRAPH_H +#define __MGRAPH_H + +#include + +#ifndef __DEBUG_H +#include "debug.h" +#endif + +#if !defined(MGL_LITE) && !defined(MGL_PRO) && !defined(MGL_FIX3D) \ + && !defined(MGL_FLT3D) +#define MGL_FIX3D +#endif + +#if defined(MGL_FIX3D) || defined(MGL_FLT3D) +#define MGL_3D +#endif + +/*---------------------- Macros and type definitions ----------------------*/ + +#pragma pack(1) /* Pack structures to byte granularity */ + +/* Define the version number for the MGL release */ + +#define MGL_VERSION_STR "3.1" + +/* Define the calling conventions for all public MGL functions. If we + * are compiling the MGL as a DLL, then all public functions are compiled + * and exported with standard C calling conventions, otherwise we use + * the default calling conventions provided by the compiler. + * + * Note that because Watcom C++ uses register based parameter passing + * by default we also provide special DLL's for watcom that are compiled + * with register parameter passing. This is necessary to work with all + * the extra libraries provided as they are all compiled to call MGL + * functions with arguments in registers whenever possible. You can still + * use the standard DLL but if you do you will need to re-compile all + * of the extra libraries with the MGL_DLL #define to change the calling + * conventions for the MGL functions. + */ + +#if defined(MGL_DLL) +#define MGLAPI _EXPORT __cdecl +#else +#define MGLAPI _EXPORT _PUBAPI +#endif +#define ASMAPI _EXPORT __cdecl + +/* Define a type for integers used in the library. For most environments + * we simply define it as a normal integer (16 or 32 bits), however for + * 16 bit Windows it is defined as a 32 bit integer as all the real code + * lives in a 32 bit DLL that uses 32 bit integers. + */ + +#ifndef __M_INT_DEFINED +#if defined(__WINDOWS16__) +typedef long m_int; +typedef unsigned long m_uint; +#else +typedef int m_int; +typedef unsigned int m_uint; +#endif +#define __M_INT_DEFINED +#endif + +/* Define the graphics subsystems available */ + +typedef enum { + grDETECT = -1, /* Auto detect the graphics subsystem */ + grNONE = 0, /* No graphics hardware detected */ + grVGA, /* Standard VGA */ + grVESA, /* VESA VBE compliant SuperVGA */ + grSVGA, /* Unaccelerated SuperVGA */ + grACCEL, /* Accelerated SuperVGA */ + grDDRAW, /* Unaccelerated DirectDraw */ + grDDRAWACCEL, /* Accelerated DirectDraw */ + grDDRAW3D, /* 3D Accelerated DirectDraw */ + grMAXDRIVER, /* Maximum driver number */ + } MGL_driverType; + +/* Graphics modes supported - the only video modes supported by this + * graphics library are those that support at least 16 colors per pixel. + */ + +typedef enum { + /* 16 color VGA video modes */ + + grVGA_320x200x16, + grVGA_640x200x16, + grVGA_640x350x16, + grVGA_640x400x16, + grVGA_640x480x16, + grSVGA_800x600x16, + + /* 256 color VGA ModeX video modes */ + + grVGAX_320x200x256, + grVGAX_320x240x256, + grVGAX_320x400x256, + grVGAX_320x480x256, + + /* 256 color VGA video modes */ + + grVGA_320x200x256, + + /* 256 color VGA/SuperVGA video modes */ + + grSVGA_320x200x256, + grSVGA_320x240x256, + grSVGA_320x400x256, + grSVGA_320x480x256, + grSVGA_400x300x256, + grSVGA_512x384x256, + grSVGA_640x350x256, + grSVGA_640x400x256, + grSVGA_640x480x256, + grSVGA_800x600x256, + grSVGA_1024x768x256, + grSVGA_1152x864x256, + grSVGA_1280x960x256, + grSVGA_1280x1024x256, + grSVGA_1600x1200x256, + + /* 32,768 color Super VGA video modes */ + + grSVGA_320x200x32k, + grSVGA_320x240x32k, + grSVGA_320x400x32k, + grSVGA_320x480x32k, + grSVGA_400x300x32k, + grSVGA_512x384x32k, + grSVGA_640x350x32k, + grSVGA_640x400x32k, + grSVGA_640x480x32k, + grSVGA_800x600x32k, + grSVGA_1024x768x32k, + grSVGA_1152x864x32k, + grSVGA_1280x960x32k, + grSVGA_1280x1024x32k, + grSVGA_1600x1200x32k, + + /* 65,536 color Super VGA video modes */ + + grSVGA_320x200x64k, + grSVGA_320x240x64k, + grSVGA_320x400x64k, + grSVGA_320x480x64k, + grSVGA_400x300x64k, + grSVGA_512x384x64k, + grSVGA_640x350x64k, + grSVGA_640x400x64k, + grSVGA_640x480x64k, + grSVGA_800x600x64k, + grSVGA_1024x768x64k, + grSVGA_1152x864x64k, + grSVGA_1280x960x64k, + grSVGA_1280x1024x64k, + grSVGA_1600x1200x64k, + + /* 16 million color, 24 bits per pixel Super VGA video modes */ + + grSVGA_320x200x16m, + grSVGA_320x240x16m, + grSVGA_320x400x16m, + grSVGA_320x480x16m, + grSVGA_400x300x16m, + grSVGA_512x384x16m, + grSVGA_640x350x16m, + grSVGA_640x400x16m, + grSVGA_640x480x16m, + grSVGA_800x600x16m, + grSVGA_1024x768x16m, + grSVGA_1152x864x16m, + grSVGA_1280x960x16m, + grSVGA_1280x1024x16m, + grSVGA_1600x1200x16m, + + /* 16 million color, 32 bits per pixel Super VGA video modes */ + + grSVGA_320x200x4G, + grSVGA_320x240x4G, + grSVGA_320x400x4G, + grSVGA_320x480x4G, + grSVGA_400x300x4G, + grSVGA_512x384x4G, + grSVGA_640x350x4G, + grSVGA_640x400x4G, + grSVGA_640x480x4G, + grSVGA_800x600x4G, + grSVGA_1024x768x4G, + grSVGA_1152x864x4G, + grSVGA_1280x960x4G, + grSVGA_1280x1024x4G, + grSVGA_1600x1200x4G, + + /* Render into Windowing System DC (Windows, OS/2 PM, X11) */ + + grWINDOWED, + + grMAXMODE, /* Maximum mode number */ + } MGL_modeType; + +/* MGL_result() error codes */ + +typedef enum { + grOK = 0, /* No error */ + grNoInit = -1, /* Graphics driver has not been installed */ + grNotDetected = -2, /* Graphics hardware was not detected */ + grDriverNotFound= -3, /* Graphics driver file not found */ + grBadDriver = -4, /* File loaded was not a graphics driver */ + grLoadMem = -5, /* Not enough memory to load graphics driver*/ + grInvalidMode = -6, /* Invalid graphics mode for selected driver*/ + grError = -8, /* General graphics error */ + grInvalidName = -9, /* Invalid driver name */ + grNoMem = -10, /* Not enough memory to perform operation */ + grNoModeSupport = -11, /* Select video mode not supported by hard. */ + grInvalidFont = -12, /* Invalid font data */ + grBadFontFile = -13, /* File loaded was not a font file */ + grFontNotFound = -14, /* Font file was not found */ + grOldDriver = -15, /* Driver file is an old version */ + grInvalidDevice = -16, /* Invalid device for selected operation */ + grInvalidDC = -17, /* Invalid device context */ + grInvalidCursor = -18, /* Invalid cursor file */ + grCursorNotFound= -19, /* Cursor file was not found */ + grInvalidIcon = -20, /* Invalid icon file */ + grIconNotFound = -21, /* Icon file was not found */ + grInvalidBitmap = -22, /* Invalid bitmap file */ + grBitmapNotFound= -23, /* Bitmap file was not found */ + grZbufferTooBig = -24, /* Zbuffer allocation is too large */ + grNewFontFile = -25, /* Only Windows 2.x font files supported */ + grNoDoubleBuff = -26, /* Double buffering is not available */ + grNoHardwareBlt = -28, /* No hardware bitBlt for OffscreenDC */ + grNoOffscreenMem= -29, /* No available offscreen memory */ + grInvalidPF = -30, /* Invalid pixel format for memory DC */ + + grLastError = -31, /* Last error number in list */ + } MGL_errorType; + +#define MGL_CLIPON true +#define MGL_CLIPOFF false + +/* Color mapped modes */ + +typedef enum { + MGL_CMAP_MODE, /* Normal Color mapped mode */ + MGL_DITHER_RGB_MODE, /* 24 bit RGB halftone dithered */ + } MGL_colorModes; + +/* Standard colors - this is the standard set of colors for the IBM PC. The + * default palette will have been programmed to contain these values when a + * graphics modes is started. If the palette has been changed, they will + * not correspond to the actual colors on the screen. Under a Windowing + * manage environment these colors will also not be setup by default. + */ + +enum MGL_COLORS { + MGL_BLACK, /* dark colors */ + MGL_BLUE, + MGL_GREEN, + MGL_CYAN, + MGL_RED, + MGL_MAGENTA, + MGL_BROWN, + MGL_LIGHTGRAY, + MGL_DARKGRAY, /* light colors */ + MGL_LIGHTBLUE, + MGL_LIGHTGREEN, + MGL_LIGHTCYAN, + MGL_LIGHTRED, + MGL_LIGHTMAGENTA, + MGL_YELLOW, + MGL_WHITE, + }; + +/* Windows standard color indices for 256 color bitmaps. 8,9,246,247 are + * reserved and you should not count on these colors always being the + * same. For 16 color bitmaps, colors 248-255 map to colors 8-15. + */ + +enum MGL_WIN_COLORS { + MGL_WIN_BLACK = 0, + MGL_WIN_DARKRED = 1, + MGL_WIN_DARKGREEN = 2, + MGL_WIN_DARKYELLOW = 3, + MGL_WIN_DARKBLUE = 4, + MGL_WIN_DARKMAGENTA = 5, + MGL_WIN_DARKCYAN = 6, + MGL_WIN_LIGHTGRAY = 7, + MGL_WIN_TURQUOISE = 8, /* Reserved; dont count on this */ + MGL_WIN_SKYBLUE = 9, /* Reserved; dont count on this */ + MGL_WIN_CREAM = 246, /* Reserved; dont count on this */ + MGL_WIN_MEDIUMGRAY = 247, /* Reserved; dont count on this */ + MGL_WIN_DARKGRAY = 248, + MGL_WIN_LIGHTRED = 249, + MGL_WIN_LIGHTGREEN = 250, + MGL_WIN_LIGHTYELLOW = 251, + MGL_WIN_LIGHTBLUE = 252, + MGL_WIN_LIGHTMAGENTA = 253, + MGL_WIN_LIGHTCYAN = 254, + MGL_WIN_WHITE = 255, + }; + +typedef enum { + MGL_MARKER_SQUARE, + MGL_MARKER_CIRCLE, + MGL_MARKER_X, + } MGL_markerStyleType; + +typedef enum { /* Write mode operators */ + MGL_REPLACE_MODE, /* Replace mode */ + MGL_AND_MODE, /* AND mode */ + MGL_OR_MODE, /* OR mode */ + MGL_XOR_MODE, /* XOR mode */ + } MGL_writeModeType; + +typedef enum { + MGL_BITMAP_SOLID, + MGL_BITMAP_OPAQUE, + MGL_BITMAP_TRANSPARENT, + MGL_PIXMAP, + } MGL_fillStyleType; + +typedef enum { + MGL_LINE_PENSTYLE, /* Line drawn in current pen style */ + MGL_LINE_STIPPLE, /* Line drawn with current stipple */ + } MGL_lineStyleType; + +typedef enum { + MGL_CONVEX_POLYGON, /* Monotone vertical polygon */ + MGL_COMPLEX_POLYGON, /* Non-Simple polygons */ + MGL_AUTO_POLYGON, /* Auto detect the polygon type */ + } MGL_polygonType; + +/* Text manipulation defines */ + +typedef enum { + MGL_LEFT_TEXT = 0, /* Justify from left */ + MGL_TOP_TEXT = 0, /* Justify from top */ + MGL_CENTER_TEXT = 1, /* Center the text */ + MGL_RIGHT_TEXT = 2, /* Justify from right */ + MGL_BOTTOM_TEXT = 2, /* Justify from bottom */ + MGL_BASELINE_TEXT = 3, /* Justify from the baseline */ + } MGL_textJustType; + +typedef enum { + MGL_LEFT_DIR = 0, /* Text goes to left */ + MGL_UP_DIR = 1, /* Text goes up */ + MGL_RIGHT_DIR = 2, /* Text goes right */ + MGL_DOWN_DIR = 3, /* Text goes down */ + } MGL_textDirType; + +/* Font types */ + +typedef enum { + MGL_VECTORFONT = 1, /* Vector font */ + MGL_FIXEDFONT, /* Fixed width bitmap font */ + MGL_PROPFONT, /* Proportional width bitmap font */ + } MGL_fontType; + +/* Palette rotation directions */ + +typedef enum { + MGL_ROTATE_UP, /* Rotate the palette values up */ + MGL_ROTATE_DOWN, /* Rotate the palette values down */ + } MGL_palRotateType; + +/* Border drawing routine styles */ + +typedef enum { + MGL_BDR_INSET, /* Interior is inset into screen */ + MGL_BDR_OUTSET, /* Interior is outset from screen */ + MGL_BDR_OUTLINE, /* Border is 3d outline */ + } MGL_bdrStyleType; + +/* Standard display driver names */ + +#define MGL_VGA4NAME "VGA4.DRV" /* Standard VGA drivers */ +#define MGL_VGA8NAME "VGA8.DRV" +#define MGL_VGAXNAME "VGAX.DRV" + +#define MGL_SVGA4NAME "SVGA4.DRV" /* Generic SuperVGA drivers */ +#define MGL_SVGA8NAME "SVGA8.DRV" +#define MGL_SVGA16NAME "SVGA16.DRV" +#define MGL_SVGA24NAME "SVGA24.DRV" +#define MGL_SVGA32NAME "SVGA32.DRV" + +#define MGL_LINEAR8NAME "LINEAR8.DRV" /* Linear framebuffer drivers */ +#define MGL_LINEAR16NAME "LINEAR16.DRV" +#define MGL_LINEAR24NAME "LINEAR24.DRV" +#define MGL_LINEAR32NAME "LINEAR32.DRV" + +#define MGL_ACCEL8NAME "ACCEL8.DRV" /* VBE/AF Accelerated drivers */ +#define MGL_ACCEL16NAME "ACCEL16.DRV" +#define MGL_ACCEL24NAME "ACCEL24.DRV" +#define MGL_ACCEL32NAME "ACCEL32.DRV" + +#define MGL_DDRAW8NAME "DDRAW8.DRV" /* DirectDraw drivers */ +#define MGL_DDRAW16NAME "DDRAW16.DRV" +#define MGL_DDRAW24NAME "DDRAW24.DRV" +#define MGL_DDRAW32NAME "DDRAW32.DRV" + +/* Standard memory driver names */ + +#define MGL_PACKED1NAME "PACK1.DRV" +#define MGL_PACKED4NAME "PACK4.DRV" +#define MGL_PACKED8NAME "PACK8.DRV" +#define MGL_PACKED16NAME "PACK16.DRV" +#define MGL_PACKED24NAME "PACK24.DRV" +#define MGL_PACKED32NAME "PACK32.DRV" + +/* Standard bitmap names */ + +#define MGL_EMPTY_FILL _MGL_getEmptyPat() +#define MGL_GRAY_FILL _MGL_getGrayPat() +#define MGL_SOLID_FILL _MGL_getSolidPat() + +/* Event message masks for keyDown events */ + +#define EVT_ASCIIMASK 0x00FF /* Ascii code of key pressed */ +#define EVT_SCANMASK 0xFF00 /* Scan code of key pressed */ +#define EVT_COUNTMASK 0x7FFF0000L /* Count for KEYREPEAT's */ + +#define EVT_asciiCode(m) ( (uchar) (m & EVT_ASCIIMASK) ) +#define EVT_scanCode(m) ( (uchar) ( (m & EVT_SCANMASK) >> 8 ) ) +#define EVT_repeatCount(m) ( (short) ( (m & EVT_COUNTMASK) >> 16 ) ) + +/* Event message masks for mouse events */ + +#define EVT_LEFTBMASK 0x0001 /* Left button is bit 0 */ +#define EVT_RIGHTBMASK 0x0004 /* Right button is bit 1 */ +#define EVT_BOTHBMASK 0x0005 /* Both left and right together */ +#define EVT_ALLBMASK 0x0005 /* All buttons pressed */ + +/* Modifier masks */ + +#define EVT_LEFTBUT 0x0001 /* Set if left button was down */ +#define EVT_RIGHTBUT 0x0002 /* Set if right button was down */ +#define EVT_RIGHTSHIFT 0x0008 /* Set if right shift down */ +#define EVT_LEFTSHIFT 0x0010 /* Set if left shift down */ +#define EVT_CTRLSTATE 0x0020 /* Set if ctrl key down */ +#define EVT_ALTSTATE 0x0040 /* Set if alt key down */ +#define EVT_LEFTCTRL 0x0080 /* Set if left ctrl key down */ +#define EVT_LEFTALT 0x0100 /* Set if left alt key down */ +#define EVT_SHIFTKEY 0x0018 /* Any shift key */ + +/* Event codes */ + +#define EVT_NULLEVT 0x0000 /* A null event */ +#define EVT_KEYDOWN 0x0001 /* Key down event */ +#define EVT_KEYREPEAT 0x0002 /* Key repeat event */ +#define EVT_KEYUP 0x0004 /* Key up event */ +#define EVT_MOUSEDOWN 0x0008 /* Mouse down event */ +#define EVT_MOUSEUP 0x0010 /* Mouse up event */ +#define EVT_MOUSEMOVE 0x0020 /* Mouse movement event */ +#define EVT_TIMERTICK 0x0040 /* Timer tick event */ +#define EVT_USEREVT 0x0080 /* First user event */ + +/* Event code masks */ + +#define EVT_KEYEVT (EVT_KEYDOWN | EVT_KEYREPEAT | EVT_KEYUP) +#define EVT_MOUSEEVT (EVT_MOUSEDOWN | EVT_MOUSEUP | EVT_MOUSEMOVE) +#define EVT_MOUSECLICK (EVT_MOUSEDOWN | EVT_MOUSEUP) +#define EVT_EVERYEVT 0xFFFF + +/* Suspend Application callback type codes. This callback is called + * when the user presses one of the corresponding keys indicating that + * they wish to change the active application. The MGL will catch these + * events and if you have registered a callback, will call the callback to + * save the state of the application so that it can be properly restored + * when the user switches back to your application. The MGL takes care of + * all the details about saving and restoring the state of the hardware, + * and all your application needs to do is save its own state so that you can + * re-draw the application screen upon re-activation. + * + * NOTE: Your application suspend callback may get called twice with the + * MGL_DEACTIVATE flag in order to test whether the switch should + * occur (under both DirectDraw and WinDirect fullscreen modes). + * + * NOTE: When your callback is called with the MGL_DEACTIVATE flag, you + * cannot assume that you have access to the display memory surfaces + * as they may have been lost by the time your callback has been called. + */ + +#define MGL_DEACTIVATE 0x0001 /* Application losing active focus */ +#define MGL_REACTIVATE 0x0002 /* Application regaining active focus */ + +/* Return codes from the suspend application callback. The normal value + * to be returned is MGL_SUSPEND_APP and this will cause the app to be + * suspended while back in GDI mode until the app is re-activated again + * by the user. + * + * MGL_NO_DEACTIVATE signals to WinDirect that the application does not want + * to allow switching to occur, and the switch request will be ignored and + * the app will remain in fullscreen mode. + * + * MGL_NO_SUSPEND_APP can be used to tell WinDirect to switch back to the + * desktop, but not to suspend the application. This must be used with + * care as the suspend application callback is then responsible for setting + * a flag in the application that will stop the application from doing any + * rendering to the framebuffer while the application is in GDI mode. This + * return value is useful for games that need to maintain network + * connectivity while the user has temporarily switched back to GDI mode. + */ + +#define MGL_NO_DEACTIVATE 0 /* Dont allow app to be deactivated */ +#define MGL_SUSPEND_APP 1 /* Suspend application until restored */ +#define MGL_NO_SUSPEND_APP 2 /* Dont suspend, but allow switch */ + +/* Here we define the structures used to represent points and rectangles */ + +typedef struct { + m_int x,y; + } point_t; + +typedef struct { + m_int left; + m_int top; + m_int right; + m_int bottom; + } rect_t; + +/* All colors are represented as longs by the library. This allows + * code to work correctly with up to 24 bit color device drivers. The + * device drivers themselves expect the color to be a color index if in + * a color mapped mode, or a 15/16/24 bit RGB tuple in a hicolor or truecolor + * mode. You can use the appropriate routines to pack and unpack + * colors into the color_t format. + */ + +typedef ulong color_t; + +/* Define the value used to clear the software ZBuffer. The MGL always uses + * a > operator for the z compare, and the smallest value is 0. + */ + +#define MGL_ZCLEARVAL 0 + +/* Structures for passing vertex information to polygon rendering routines. + * All fixed point coordinates are passed in 16.16 signed fixed point + * format, while zbuffer coordinates are passed in 4.28 signed fixed point + * format. The sign bit is used purely for overflow and arithmetic + * internally, and all user passed zbuffer values should be greater than + * 0. All shaded rendering routines either take a color index in 8.16 fixed + * point format (range 0-255.9) or separate RGB components in 8.16 fixed + * point format (range 0-255.9). + */ + +#ifdef __FX_FIXED_H +#define fix32_t FXFixed +#else +typedef long fix32_t; +#endif +typedef fix32_t fxcolor_t; +typedef long zfix32_t; + +typedef struct { + fix32_t x,y; + } fxpoint_t; + +typedef struct { + fxcolor_t r,g,b; + } fxrgb_t; + +typedef struct { + fix32_t w,s,t; + } fxtex_t; + +typedef struct { + fxcolor_t c; + fxpoint_t p; + } fxpointc_t; + +typedef struct { + fxrgb_t c; + fxpoint_t p; + } fxpointrgb_t; + +typedef struct { + fxpoint_t p; + zfix32_t z; + } fxpointz_t; + +typedef struct { + fxcolor_t c; + fxpoint_t p; + zfix32_t z; + } fxpointcz_t; + +typedef struct { + fxrgb_t c; + fxpoint_t p; + zfix32_t z; + } fxpointrgbz_t; + +/* Macros to convert between integer and 32 bit fixed point format */ + +#define MGL_FIX_1 0x10000L +#define MGL_FIX_2 0x20000L +#define MGL_FIX_HALF 0x08000L +#define MGL_TOFIX(i) ((long)(i) << 16) +#define MGL_FIXTOINT(f) ((m_int)((f) >> 16)) +#define MGL_FIXROUND(f) ((m_int)(((f) + MGL_FIX_HALF) >> 16)) + +#define MGL_ZFIX_1 0x10000000L +#define MGL_ZFIX_HALF 0x08000000L +#define MGL_FIXTOZ(i) ((i) << 12) +#define MGL_ZTOFIX(i) ((i) >> 12) +#define MGL_TOZFIX(i) ((long)(i) << 28) +#define MGL_ZFIXTOINT(f) ((m_int)((f) >> 28)) +#define MGL_ZFIXROUND(f) ((m_int)(((f) + MGL_ZFIX_HALF) >> 28)) + +/* Region structure */ + +#ifdef BUILD_MGL +struct _span_t; +typedef struct _span_t span_t; +#else +typedef void span_t; +#endif + +typedef struct { + rect_t rect; /* Bounding rectangle for region */ + span_t *spans; /* Start of span list for region */ + } region_t; + +/* Palette entry structure */ + +typedef struct { + uchar blue; /* Blue component of color */ + uchar green; /* Green component of color */ + uchar red; /* Blue component of color */ + uchar alpha; /* Alpha or alignment byte */ + } palette_t; + +/* Maximum value for each palette entry component */ + +#define PALMAX 255 /* Max value for palette components */ + +/* Pixel format structure */ + +typedef struct { + uchar redMask,greenMask; /* Mask values for pixels */ + uchar blueMask,rsvdMask; + m_int redPos,redAdjust; /* Red position and adjustment */ + m_int greenPos,greenAdjust; /* Green position and adjustment */ + m_int bluePos,blueAdjust; /* Blue position and adjustment */ + m_int rsvdPos,rsvdAdjust; /* Reserved position and adjustment */ + } pixel_format_t; + +/* Structure to hold arc coordinate information */ + +typedef struct { + m_int x,y; /* Centre point of the arc */ + m_int startX,startY; /* Starting point on arc */ + m_int endX,endY; /* Ending point on arc */ + } arc_coords_t; + +/* Mouse cursor structure */ + +typedef struct { + ulong xorMask[32]; + ulong andMask[32]; + m_int xHotSpot; + m_int yHotSpot; + } cursor_t; + +/* Bitmap structure - always packed pixel DIB format */ + +typedef struct { + m_int width; /* Width of bitmap in pixels */ + m_int height; /* Height of bitmap in pixels */ + m_int bitsPerPixel; /* Pixel width */ + m_int bytesPerLine; /* Bytes per line value for surface */ + uchar *surface; /* Pointer to bitmap surface */ + palette_t *pal; /* Palette (NULL if not loaded) */ + pixel_format_t *pf; /* Pixel format (NULL if none) */ + + /* ... palette, pixel format and bitmap data are store contiguously */ + } bitmap_t; + +/* Icon structure - can be 32x23, 64x64 or in fact any size */ + +typedef struct { + m_int byteWidth; /* Byte with for AND mask */ + uchar *andMask; /* Hold punch mask for icon */ + bitmap_t xorMask; /* XOR mask for the icon */ + + /* ... AND mask and bitmap structure are stored contiguously */ + } icon_t; + +/* Default cursor name */ + +#define MGL_DEF_CURSOR _MGL_getDefCursor() + +/* Generic Font structure */ + +#define _MGL_FNAMESIZE 58 + +typedef struct { + char name[_MGL_FNAMESIZE];/* Name of the font */ + short fontType; /* Type of font */ + short maxWidth; /* Maximum character width */ + short maxKern; /* Maximum character kern */ + short fontWidth; /* Font width */ + short fontHeight; /* Font height */ + short ascent; /* Font ascent value */ + short descent; /* Font descent value */ + short leading; /* Font leading value */ + } font_t; + +/* Character and font metrics structure */ + +typedef struct { + m_int width; /* Width of character or font */ + m_int fontWidth; /* Character width (tightest fit) */ + m_int fontHeight; /* Height of the font */ + m_int ascent; /* Ascent value */ + m_int descent; /* Descent value */ + m_int leading; /* Leading value */ + m_int kern; /* Kern value */ + } metrics_t; + +/* Text settings structure */ + +typedef struct { + m_int horizJust; /* Horizontal justfication */ + m_int vertJust; /* Vertical justification */ + m_int dir; /* Text drawing direction */ + m_int szNumerx; /* Text x size numerator */ + m_int szNumery; /* Text y size numerator */ + m_int szDenomx; /* Text x size denominator */ + m_int szDenomy; /* Text y size denominator */ + m_int spaceExtra; /* Space extra term */ + font_t *font; /* Currently selected font */ + } text_settings_t; + +/* Macros to access the (left,top) and (right,bottom) points of a + * rectangle. + */ + +#define MGL_leftTop(r) (((point_t *) &(r))[0]) +#define MGL_rightBottom(r) (((point_t *) &(r))[1]) + +typedef uchar pattern_t[8]; +typedef color_t pixpattern_t[8][8]; + +/* Attributes structure */ + +typedef struct { + color_t color; /* Foreground color */ + color_t backColor; /* Background color */ + m_int colorMode; /* Current color mode */ + m_int markerSize; /* Size of markers in pixels */ + m_int markerStyle; /* Style of markers */ + color_t markerColor; /* Color to draw markers in */ + color_t bdrBright; /* Border bright color */ + color_t bdrDark; /* Border dark color */ + point_t CP; /* Graphics pen position */ + m_int writeMode; /* Scan conversion write mode op. */ + m_int penStyle; /* Pen style */ + m_int penHeight; /* Height of pen */ + m_int penWidth; /* Width of pen */ + pattern_t penPat; /* Pattern for pen */ + pixpattern_t penPixPat; /* Pixmap pattern for pen */ + m_int lineStyle; /* Line style */ + ushort lineStipple; /* Line stipple */ + m_uint stippleCount; /* Current line stipple count */ + rect_t viewPort; /* Viewport dimensions */ + point_t viewPortOrg; /* Logical viewport origin */ + rect_t clipRect; /* Clipping rectangle dimensions */ + m_int clip; /* Is clipping on? */ + m_int polyType; /* Polygon drawing type */ + text_settings_t ts; /* Text drawing attributes */ + } attributes_t; + +/* Mode specific format information. This structrure can be used by + * the device driver to build tables of values for all supported modes + */ + +typedef struct { + m_int xRes; /* Device x resolution - 1 */ + m_int yRes; /* Device y resolution - 1 */ + m_int bitsPerPixel; /* Number of bits per pixel */ + m_int numberOfPlanes; /* Number of planes in image */ + color_t maxColor; /* Maximum number of colors - 1 */ + m_int maxPage; /* Maximum number of video pages - 1 */ + m_int bytesPerLine; /* Number of bytes in a line */ + m_int aspectRatio; /* Mode aspect ratio (horiz/vert * 1000) */ + long pageSize; /* Number of bytes in a page */ + m_int scratch1; /* Scratch pad value 1 */ + m_int scratch2; /* Scratch pad value 2 */ + char redMaskSize; /* Size of direct color red mask */ + char redFieldPosition; /* Bit posn of lsb of red mask */ + char greenMaskSize; /* Size of direct color green mask */ + char greenFieldPosition; /* Bit posn of lsb of green mask */ + char blueMaskSize; /* Size of direct color blue mask */ + char blueFieldPosition; /* Bit posn of lsb of blue mask */ + char rsvdMaskSize; /* Size of reserved mask */ + char rsvdFieldPosition; /* Bit posn of reserved mask */ + } gmode_t; + +/* Public Device Context Structure. The 'surface' member along with the + * gmode_t information block, provides direct access to the active + * display surface for user applications. The MGL virtualises the surface + * in SuperVGA modes that dont have a real linear framebuffer. + */ + +typedef struct { + attributes_t a; /* Active device attributes */ + void *surface; /* Pointer to active device surface */ + void *zbuffer; /* Pointer to Z-buffer if allocated */ + m_int zbits; /* Bits per zbuffer element */ + m_int zwidth; /* Width of the zbuffer in pixels */ + gmode_t mi; /* Mode specific information block */ + pixel_format_t pf; /* Current pixel format for device context */ + color_t *colorTab; /* Color lookup table cache */ + color_t *shadeTab; /* Currently active shade table */ + m_int bankOffset; /* Offset of starting bank number */ + + /* Remainder of Device Context structure is private and internal */ + } publicDevCtx_t; + +#ifndef BUILD_MGL +typedef publicDevCtx_t MGLDC; +#else +struct internalDevCtx_t; +typedef struct internalDevCtx_t MGLDC; +#endif + +typedef struct { + ulong which; /* Which window for window manager code */ + m_uint what; /* Event code */ + ulong when; /* Clock ticks since midnight */ + m_int where_x; /* Mouse location */ + m_int where_y; + ulong message; /* Event specific message */ + ulong modifiers; /* Modifier flags */ + m_int next; /* Next event in queue */ + m_int prev; /* Previous event in queue */ + } event_t; + +/* Structure containing file I/O functions allowing the user application to + * completely replace the MGL's file I/O functions with their own. This + * allows the app to store all MGL related files in a single large file, + * with encryption or compression is desired. By default normal file I/O + * functions will be used. + */ + +typedef struct { + FILE * (*fopen)(const char *filename,const char *mode); + int (*fclose)(FILE *f); + int (*fseek)(FILE *f,long offset,int whence); + long (*ftell)(FILE *f); + size_t (*fread)(void *ptr,size_t size,size_t n,FILE *f); + size_t (*fwrite)(const void *ptr,size_t size,size_t n,FILE *f); + } fileio_t; + +/* Define the flags for the types of direct surface access provided */ + +#define MGL_NO_ACCESS 0x0 /* Surface cannot be accessed */ +#define MGL_VIRTUAL_ACCESS 0x1 /* Surface is virtualised */ +#define MGL_LINEAR_ACCESS 0x2 /* Surface can be linearly accessed */ +#define MGL_SURFACE_FLAGS 0x3 + +/* Define the flags for the types of direct zbuffer access provided */ + +#define MGL_NO_ZACCESS 0x0 /* Zbuffer cannot be accessed */ +#define MGL_VIRTUAL_ZACCESS 0x4 /* Zbuffer is virtualised in */ +#define MGL_LINEAR_ZACCESS 0x8 /* Zbuffer can be linearly accessed */ +#define MGL_ZBUFFER_FLAGS 0xC + +/* Define the flags for the types of hardware acceleration supported by + * the device context. This will allow the application to tailor the use of + * MGL functions depending upon whether specific hardware support is + * available. Hence applications can use specialised software rendering + * support if the desired hardware support is not available. + * + * NOTE: If the hardware flags are not MGL_HW_NONE, you *must* call + * the MGL_beginDirectAccess() and MGL_endDirectAccess() functions + * before and after any custom code that does direct framebuffer + * rendering!! + * + * This is not necessary for non-accelerated device context, so you + * might want to optimise these calls out if there is no hardware + * acceleration support. + */ + +#define MGL_HW_NONE 0x0000 /* No hardware acceleration */ +#define MGL_HW_LINE 0x0010 /* Hardware line drawing */ +#define MGL_HW_STIPPLE_LINE 0x0020 /* Hardware stippled line drawing */ +#define MGL_HW_POLY 0x0040 /* Hardware polygon filling */ +#define MGL_HW_RECT 0x0080 /* Hardware rectangle fill */ +#define MGL_HW_PATT_RECT 0x0100 /* Hardware pattern rectangle fill */ +#define MGL_HW_CLRPATT_RECT 0x0200 /* Hardware color pattern fill */ +#define MGL_HW_SCR_BLT 0x0400 /* Hardware screen/screen bitBlt */ +#define MGL_HW_SRCTRANS_BLT 0x0800 /* Hardware source transparent blt */ +#define MGL_HW_DSTTRANS_BLT 0x1000 /* Hardware dest. transparent blt */ +#define MGL_HW_MONO_BLT 0x2000 /* Hardware monochrome blt */ +#define MGL_HW_CLIP 0x4000 /* Hardware clipping */ +#define MGL_HW_FLAGS 0xFFF0 + +#ifdef __cplusplus +extern "C" { /* Use "C" linkage when in C++ mode */ +#endif + +/*------------------------- Function Prototypes ---------------------------*/ + +/*--------------------------------------------------------------------------- + * Routines bound to a specific device context. These routines all take + * an MGLDC as a parmeter for the context to work with and hence dont work + * with the current context. If however the context passed is the currently + * active context, all changes to that context are reflected in the + * currently active context as well. + *-------------------------------------------------------------------------*/ + +/* Environment detection and initialisation */ + +m_int MGLAPI MGL_registerDriver(const char *name,void *driver); +void MGLAPI MGL_unregisterAllDrivers(void); +void MGLAPI MGL_registerAllDispDrivers(bool useLinear,bool useDirectDraw,bool useWinDirect); +void MGLAPI MGL_registerAllMemDrivers(void); +void MGLAPI MGL_detectGraph(m_int *driver,m_int *mode); +uchar * MGLAPI MGL_availableModes(void); +m_int MGLAPI MGL_availablePages(m_int mode); +m_int MGLAPI MGL_modeResolution(m_int mode,m_int *xRes,m_int *yRes,m_int *bitsPerPixel); +bool MGLAPI MGL_isDisplayDC(MGLDC *dc); +bool MGLAPI MGL_isWindowedDC(MGLDC *dc); +bool MGLAPI MGL_isMemoryDC(MGLDC *dc); +void MGLAPI MGL_exit(void); +void MGLAPI MGL_setBufSize(unsigned size); +void MGLAPI MGL_fatalError(const char *msg); +m_int MGLAPI MGL_result(void); +void MGLAPI MGL_setResult(m_int result); +const char * MGLAPI MGL_errorMsg(m_int err); +const char * MGLAPI MGL_modeName(m_int mode); +const char * MGLAPI MGL_modeDriverName(m_int mode); +const char * MGLAPI MGL_driverName(m_int driver); +m_int MGLAPI MGL_getDriver(MGLDC *dc); +m_int MGLAPI MGL_getMode(MGLDC *dc); +m_int MGLAPI MGL_surfaceAccessType(MGLDC *dc); +m_int MGLAPI MGL_zbufferAccessType(MGLDC *dc); +long MGLAPI MGL_getHardwareFlags(MGLDC *dc); +void MGLAPI MGL_defaultAttributes(MGLDC *dc); +void MGLAPI MGL_makeSubDC(MGLDC *dc,m_int left,m_int top,m_int right,m_int bottom); + +/* Viewport and clip rectangle manipulation bound to a specific DC */ + +void MGLAPI MGL_setViewportDC(MGLDC *dc,rect_t view); +void MGLAPI MGL_setRelViewportDC(MGLDC *dc,rect_t view); +void MGLAPI MGL_getViewportDC(MGLDC *dc,rect_t *view); +void MGLAPI MGL_setViewportOrgDC(MGLDC *dc,point_t org); +void MGLAPI MGL_getViewportOrgDC(MGLDC *dc,point_t *org); +void MGLAPI MGL_globalToLocalDC(MGLDC *dc,point_t *p); +void MGLAPI MGL_localToGlobalDC(MGLDC *dc,point_t *p); +m_int MGLAPI MGL_maxxDC(MGLDC *dc); +m_int MGLAPI MGL_maxyDC(MGLDC *dc); +void MGLAPI MGL_setClipRectDC(MGLDC *dc,rect_t clip); +void MGLAPI MGL_getClipRectDC(MGLDC *dc,rect_t *clip); +void MGLAPI MGL_setClipModeDC(MGLDC *dc,bool mode); +bool MGLAPI MGL_getClipModeDC(MGLDC *dc); + +/* Color and palette manipulation */ + +color_t MGLAPI MGL_realColor(MGLDC *dc,m_int color); +color_t MGLAPI MGL_rgbColor(MGLDC *dc,uchar R,uchar G,uchar B); +void MGLAPI MGL_setPaletteEntry(MGLDC *dc,m_int entry,uchar red,uchar green,uchar blue); +void MGLAPI MGL_getPaletteEntry(MGLDC *dc,m_int entry,uchar *red,uchar *green,uchar *blue); +void MGLAPI MGL_setPalette(MGLDC *dc,palette_t *pal,m_int numColors,m_int startIndex); +void MGLAPI MGL_getPalette(MGLDC *dc,palette_t *pal,m_int numColors,m_int startIndex); +void ASMAPI MGL_rotatePalette(MGLDC *dc,m_int numColors,m_int startIndex,m_int direction); +bool ASMAPI MGL_fadePalette(MGLDC *dc,palette_t *fullIntensity,m_int numColors,m_int startIndex,uchar intensity); +void MGLAPI MGL_realizePalette(MGLDC *dc,m_int numColors,m_int startIndex,m_int waitVRT); +m_int MGLAPI MGL_getPaletteSize(MGLDC *dc); +void MGLAPI MGL_getDefaultPalette(MGLDC *dc,palette_t *pal); +void MGLAPI MGL_setDefaultPalette(MGLDC *dc); +#ifndef MGL_LITE +bool MGLAPI MGL_checkIdentityPalette(bool enable); +void MGLAPI MGL_mapToPalette(MGLDC *dc,palette_t *pal); +#endif + +/* Generic device context information and manipulation */ + +bool MGLAPI MGL_haveWidePalette(MGLDC *dc); +m_int MGLAPI MGL_getBitsPerPixel(MGLDC *dc); +color_t MGLAPI MGL_maxColor(MGLDC *dc); +m_int MGLAPI MGL_maxPage(MGLDC *dc); +m_int MGLAPI MGL_sizex(MGLDC *dc); +m_int MGLAPI MGL_sizey(MGLDC *dc); +void MGLAPI MGL_getPixelFormat(MGLDC *dc,pixel_format_t *pf); +void * MGLAPI MGL_computePixelAddr(MGLDC *dc,int x,int y); + +/* Double buffering support */ + +void MGLAPI MGL_setActivePage(MGLDC *dc,m_int page); +m_int MGLAPI MGL_getActivePage(MGLDC *dc); +void MGLAPI MGL_setVisualPage(MGLDC *dc,m_int page,m_int waitVRT); +m_int MGLAPI MGL_getVisualPage(MGLDC *dc); +void MGLAPI MGL_setDisplayStart(MGLDC *dc,m_int x,m_int y,m_int waitFlag); +void MGLAPI MGL_getDisplayStart(MGLDC *dc,m_int *x,m_int *y); +void MGLAPI MGL_vSync(MGLDC *dc); +bool MGLAPI MGL_doubleBuffer(MGLDC *dc); +void MGLAPI MGL_singleBuffer(MGLDC *dc); +void MGLAPI MGL_swapBuffers(MGLDC *dc,m_int waitVRT); + +/* Zbuffering support */ + +#ifdef MGL_3D +m_int MGLAPI MGL_getHardwareZBufferDepth(MGLDC *dc); +bool ASMAPI MGL_zBegin(MGLDC *dc,m_int zbits); +bool MGLAPI MGL_zShareZBuffer(MGLDC *dc,MGLDC *dcShared,m_int zbits); +#endif + +/* Event handling support */ + +bool MGLAPI EVT_getNext(event_t *evt,m_uint mask); +bool MGLAPI EVT_peekNext(event_t *evt,m_uint mask); +bool MGLAPI EVT_post(ulong which,m_uint what,ulong message,ulong modifiers); +void MGLAPI EVT_flush(m_uint mask); +void MGLAPI EVT_halt(event_t *evt,m_uint mask); +m_int MGLAPI EVT_setTimerTick(m_int ticks); + +/*--------------------------------------------------------------------------- + * Routines bound to the currently active context. All these routines work + * with the currently active context and do not reflect any changes made + * to the global context to the original user supplied context (because it + * may be cached). The cached DC is automatically flushed back to the + * original DC when a new context is enabled with MGL_makeCurrentDC(). + * + * Before destroying a DC that is current, make sure you call + * MGL_makeCurrentDC(NULL) first! + *-------------------------------------------------------------------------*/ + +/* Routines to change the active global device context */ + +MGLDC * MGLAPI MGL_makeCurrentDC(MGLDC *dc); +bool MGLAPI MGL_isCurrentDC(MGLDC *dc); + +/* Current device context information and manipulation */ + +m_int MGLAPI MGL_getAspectRatio(void); +void MGLAPI MGL_setAspectRatio(m_int aspectRatio); +void ASMAPI MGL_setColor(color_t color); +void MGLAPI MGL_setColorRGB(uchar R,uchar G,uchar B); +void MGLAPI MGL_setColorCI(m_int index); +color_t MGLAPI MGL_getColor(void); +void ASMAPI MGL_setBackColor(color_t color); +color_t MGLAPI MGL_getBackColor(void); +color_t ASMAPI MGL_packColor(pixel_format_t *pf,uchar R,uchar G,uchar B); +void MGLAPI MGL_unpackColor(pixel_format_t *pf,color_t color,uchar *R,uchar *G,uchar *B); +color_t ASMAPI MGL_packColorRGB(uchar R,uchar G,uchar B); +void MGLAPI MGL_unpackColorRGB(color_t color,uchar *R,uchar *G,uchar *B); +color_t MGLAPI MGL_defaultColor(void); +#ifndef MGL_LITE +void MGLAPI MGL_setMarkerSize(m_int size); +m_int MGLAPI MGL_getMarkerSize(void); +void MGLAPI MGL_setMarkerStyle(m_int style); +m_int MGLAPI MGL_getMarkerStyle(void); +void MGLAPI MGL_setMarkerColor(color_t color); +color_t MGLAPI MGL_getMarkerColor(void); +void MGLAPI MGL_setBorderColors(color_t bright,color_t dark); +void MGLAPI MGL_getBorderColors(color_t *bright,color_t *dark); +void ASMAPI MGL_setWriteMode(m_int mode); +m_int MGLAPI MGL_getWriteMode(void); +void ASMAPI MGL_setPenStyle(m_int style); +m_int MGLAPI MGL_getPenStyle(void); +void MGLAPI MGL_setLineStyle(m_int style); +m_int MGLAPI MGL_getLineStyle(void); +void ASMAPI MGL_setLineStipple(ushort stipple); +ushort MGLAPI MGL_getLineStipple(void); +void ASMAPI MGL_setLineStippleCount(m_uint stippleCount); +m_uint MGLAPI MGL_getLineStippleCount(void); +void ASMAPI MGL_setPenBitmapPattern(const pattern_t *pat); +void MGLAPI MGL_getPenBitmapPattern(pattern_t *pat); +void ASMAPI MGL_setPenPixmapPattern(const pixpattern_t *pat); +void MGLAPI MGL_getPenPixmapPattern(pixpattern_t *pat); +void MGLAPI MGL_setPenSize(m_int height,m_int width); +void MGLAPI MGL_getPenSize(m_int *height,m_int *width); +#ifndef MGL_LITE +void MGLAPI MGL_setColorMapMode(m_int mode); +m_int MGLAPI MGL_getColorMapMode(void); +#endif +void MGLAPI MGL_setPolygonType(m_int type); +m_int MGLAPI MGL_getPolygonType(void); +#endif +void MGLAPI MGL_getAttributes(attributes_t *attr); +void MGLAPI MGL_restoreAttributes(attributes_t *attr); + +/* Device clearing */ + +void ASMAPI MGL_clearDevice(void); +void MGLAPI MGL_clearViewport(void); + +/* Viewport and clip rectangle manipulation */ + +void MGLAPI MGL_setViewport(rect_t view); +void MGLAPI MGL_setRelViewport(rect_t view); +void MGLAPI MGL_getViewport(rect_t *view); +void MGLAPI MGL_setViewportOrg(point_t org); +void MGLAPI MGL_getViewportOrg(point_t *org); +void MGLAPI MGL_globalToLocal(point_t *p); +void MGLAPI MGL_localToGlobal(point_t *p); +m_int MGLAPI MGL_maxx(void); +m_int MGLAPI MGL_maxy(void); +void MGLAPI MGL_setClipRect(rect_t clip); +void MGLAPI MGL_getClipRect(rect_t *clip); +void MGLAPI MGL_setClipMode(bool mode); +bool MGLAPI MGL_getClipMode(void); + +/* Pixel plotting */ + +void MGLAPI MGL_pixelCoord(m_int x,m_int y); +color_t MGLAPI MGL_getPixelCoord(m_int x,m_int y); +void ASMAPI MGL_beginPixel(void); +void MGLAPI MGL_pixelCoordFast(m_int x,m_int y); +color_t MGLAPI MGL_getPixelCoordFast(m_int x,m_int y); +void ASMAPI MGL_endPixel(void); + +/* Line drawing and clipping */ + +void MGLAPI MGL_moveToCoord(m_int x,m_int y); +void MGLAPI MGL_moveRelCoord(m_int dx,m_int dy); +void MGLAPI MGL_lineToCoord(m_int x,m_int y); +void MGLAPI MGL_lineRelCoord(m_int dx,m_int dy); +m_int MGLAPI MGL_getX(void); +m_int MGLAPI MGL_getY(void); +void MGLAPI MGL_getCP(point_t* CP); +void MGLAPI MGL_lineCoord(m_int x1,m_int y1,m_int x2,m_int y2); +void MGLAPI MGL_lineCoordFX(fix32_t x1,fix32_t y1,fix32_t x2,fix32_t y2); +void MGLAPI MGL_lineCoordFast(m_int x1,m_int y1,m_int x2,m_int y2); +void MGLAPI MGL_lineCoordFastFX(fix32_t x1,fix32_t y1,fix32_t x2,fix32_t y2); +void MGLAPI MGL_lineEngine(fix32_t x1,fix32_t y1,fix32_t x2,fix32_t y2,void (ASMAPI *plotPoint)(m_int x,m_int y)); +bool MGLAPI MGL_clipLineFX(fix32_t *x1,fix32_t *y1,fix32_t *x2,fix32_t *y2,fix32_t left,fix32_t top,fix32_t right,fix32_t bottom); +#ifndef MGL_LITE +void ASMAPI MGL_scanLine(m_int y,m_int x1,m_int x2); +#endif + +/* Routines to perform bank switching for banked framebuffers for custom + * rendering code. The first version is callable only from assembler and + * requires the new bank value to be passed in the DL register. The second + * version is callable directly from C. DO NOT CALL THESE FUNCTIONS WHEN + * RUNNING WITH A LINEAR FRAMEBUFFER!!! + */ + +void _ASMAPI SVGA_setBank(void); +void _ASMAPI SVGA_setBankC(int bank); + +/* Routines to begin/end direct framebuffer access. You must call these + * functions is you wish to render directly to a hardware accelerated + * device surface. + */ + +void ASMAPI MGL_beginDirectAccess(void); +void ASMAPI MGL_endDirectAccess(void); + +/* Routines to begin/end fast rendering of flat shaded lines, scanlines + * and polygons. + */ + +void ASMAPI MGL_beginDrawing(void); +void ASMAPI MGL_endDrawing(void); + +/* Routines to begin/end fast rendering of smooth shaded lines, scanlines + * and polygons. + */ + +#ifdef MGL_3D +void ASMAPI MGL_beginShadedDrawing(void); +void ASMAPI MGL_endShadedDrawing(void); +#endif + +/* Routines to begin/end fast rendering of flat shaded, zbuffered lines and + * polygons. + */ + +#ifdef MGL_3D +void ASMAPI MGL_beginZDrawing(void); +void ASMAPI MGL_endZDrawing(void); +#endif + +/* Routines to begin/end fast rendering of smooth shaded, zbuffered lines and + * polygons. + */ + +#ifdef MGL_3D +void ASMAPI MGL_beginZShadedDrawing(void); +void ASMAPI MGL_endZShadedDrawing(void); +#endif + +/* Polygon drawing: Note that the following fast polygon routines + * only work with convex polygons. The integer coordinate versions are + * provided for compatibility only, and convert the coordinates to fixed + * point and call the appropriate fixed point routines below. + */ + +#ifndef MGL_LITE +void MGLAPI MGL_fillPolygon(m_int count,point_t *vArray,m_int xOffset,m_int yOffset); +void MGLAPI MGL_fillPolygonFast(m_int count,point_t *vArray,m_int xOffset,m_int yOffset); +void ASMAPI MGL_fillPolygonFX(m_int count,fxpoint_t *vArray,m_int vinc,fix32_t xOffset,fix32_t yOffset); +void ASMAPI MGL_fillPolygonFastFX(m_int count,fxpoint_t *vArray,m_int vinc,fix32_t xOffset,fix32_t yOffset); +#endif + +/* 3D rasterization routines */ + +#ifdef MGL_3D +void MGLAPI MGL_zClearCoord(m_int left,m_int top,m_int right,m_int bottom,zfix32_t clearVal); +#endif + +#ifdef MGL_FIX3D +void ASMAPI MGL_cLineCoordFast(fix32_t x1,fix32_t y1,fix32_t c1,fix32_t x2,fix32_t y2,fix32_t c2); +void ASMAPI MGL_rgbLineCoordFast(fix32_t x1,fix32_t y1,fix32_t r1,fix32_t g1,fix32_t b1,fix32_t x2,fix32_t y2,fix32_t r2,fix32_t g2,fix32_t b2); +void ASMAPI MGL_zLineCoordFast(fix32_t x1,fix32_t y1,zfix32_t z1,fix32_t x2,fix32_t y2,zfix32_t z2); +void ASMAPI MGL_czLineCoordFast(fix32_t x1,fix32_t y1,zfix32_t z1,fix32_t c1,fix32_t x2,fix32_t y2,zfix32_t z2,fix32_t c2); +void ASMAPI MGL_rgbzLineCoordFast(fix32_t x1,fix32_t y1,zfix32_t z1,fix32_t r1,fix32_t g1,fix32_t b1,fix32_t x2,fix32_t y2,zfix32_t z2,fix32_t r2,fix32_t g2,fix32_t b2); + +void ASMAPI MGL_triFast(fxpoint_t *v1,fxpoint_t *v2,fxpoint_t *v3,fix32_t xOffset,fix32_t yOffset); +void ASMAPI MGL_cTriFast(fxpointc_t *v1,fxpointc_t *v2,fxpointc_t *v3,fix32_t xOffset,fix32_t yOffset); +void ASMAPI MGL_rgbTriFast(fxpointrgb_t *v1,fxpointrgb_t *v2,fxpointrgb_t *v3,fix32_t xOffset,fix32_t yOffset); +void ASMAPI MGL_zTriFast(fxpointz_t *v1,fxpointz_t *v2,fxpointz_t *v3,fix32_t xOffset,fix32_t yOffset,zfix32_t zOffset); +void ASMAPI MGL_czTriFast(fxpointcz_t *v1,fxpointcz_t *v2,fxpointcz_t *v3,fix32_t xOffset,fix32_t yOffset,zfix32_t zOffset); +void ASMAPI MGL_rgbzTriFast(fxpointrgbz_t *v1,fxpointrgbz_t *v2,fxpointrgbz_t *v3,fix32_t xOffset,fix32_t yOffset,zfix32_t zOffset); + +void ASMAPI MGL_quadFast(fxpoint_t *v1,fxpoint_t *v2,fxpoint_t *v3,fxpoint_t *v4,fix32_t xOffset,fix32_t yOffset); +void ASMAPI MGL_cQuadFast(fxpointc_t *v1,fxpointc_t *v2,fxpointc_t *v3,fxpointc_t *v4,fix32_t xOffset,fix32_t yOffset); +void ASMAPI MGL_rgbQuadFast(fxpointrgb_t *v1,fxpointrgb_t *v2,fxpointrgb_t *v3,fxpointrgb_t *v4,fix32_t xOffset,fix32_t yOffset); +void ASMAPI MGL_zQuadFast(fxpointz_t *v1,fxpointz_t *v2,fxpointz_t *v3,fxpointz_t *v4,fix32_t xOffset,fix32_t yOffset,zfix32_t zOffset); +void ASMAPI MGL_czQuadFast(fxpointcz_t *v1,fxpointcz_t *v2,fxpointcz_t *v3,fxpointcz_t *v4,fix32_t xOffset,fix32_t yOffset,zfix32_t zOffset); +void ASMAPI MGL_rgbzQuadFast(fxpointrgbz_t *v1,fxpointrgbz_t *v2,fxpointrgbz_t *v3,fxpointrgbz_t *v4,fix32_t xOffset,fix32_t yOffset,zfix32_t zOffset); +#endif + +/* Routine to set the currently active shade table. In HiColor and TrueColor + * video modes, you must set a valid shadeTable before you call any of the + * color index shaded rendering routines (MGL_cTri() etc). These routines + * will interpolate an index into the current shade table rather than + * each of the RGB color channels, and the appropriate full RGB color is + * extracted directly from the shade table. The shade table can be any size, + * but the application must ensure that the indices passed in are within + * the range of the current shade table. + */ + +#ifdef MGL_3D +void MGLAPI MGL_setShadeTable(color_t *shadeTab); +#endif + +/* Polyline drawing */ + +#ifndef MGL_LITE +void MGLAPI MGL_marker(point_t p); +void MGLAPI MGL_polyPoint(m_int count,point_t *vArray); +void MGLAPI MGL_polyMarker(m_int count,point_t *vArray); +void MGLAPI MGL_polyLine(m_int count,point_t *vArray); +#endif + +/* Rectangle drawing */ + +#ifndef MGL_LITE +void MGLAPI MGL_rectCoord(m_int left,m_int top,m_int right,m_int bottom); +void MGLAPI MGL_fillRectCoord(m_int left,m_int top,m_int right,m_int bottom); +#endif + +/* Scanline color scanning. Thee routines are primitive, and do not perform + * any clipping or viewport mapping, so can be used to build you own + * high performance floodfilling routines (see the example file ffill.c + * for pre-built high speed floodfill routines). + */ + +#ifndef MGL_LITE +m_int ASMAPI MGL_scanRightForColor(m_int x,m_int y,color_t color); +m_int ASMAPI MGL_scanLeftForColor(m_int x,m_int y,color_t color); +m_int ASMAPI MGL_scanRightWhileColor(m_int x,m_int y,color_t color); +m_int ASMAPI MGL_scanLeftWhileColor(m_int x,m_int y,color_t color); +#endif + +/* Psuedo 3D border drawing */ + +#ifndef MGL_LITE +void MGLAPI MGL_drawBorderCoord(m_int left,m_int top,m_int right,m_int bottom,m_int style,m_int thickness); +void MGLAPI MGL_drawHDivider(m_int y,m_int x1,m_int x2); +void MGLAPI MGL_drawVDivider(m_int x,m_int y1,m_int y2); +#endif + +/* Ellipse drawing */ + +#ifndef MGL_LITE +void MGLAPI MGL_ellipseArc(rect_t extentRect,m_int startAngle,m_int endAngle); +void MGLAPI MGL_ellipseArcCoord(m_int x,m_int y,m_int xradius,m_int yradius,m_int startAngle,m_int endAngle); +void ASMAPI MGL_getArcCoords(arc_coords_t *coords); +void MGLAPI MGL_ellipse(rect_t extentRect); +void MGLAPI MGL_ellipseCoord(m_int x,m_int y,m_int xradius,m_int yradius); +void MGLAPI MGL_fillEllipseArc(rect_t extentRect,m_int startAngle,m_int endAngle); +void MGLAPI MGL_fillEllipseArcCoord(m_int x,m_int y,m_int xradius,m_int yradius,m_int startAngle,m_int endAngle); +void MGLAPI MGL_fillEllipse(rect_t extentRect); +void MGLAPI MGL_fillEllipseCoord(m_int x,m_int y,m_int xradius,m_int yradius); +void MGLAPI MGL_ellipseEngine(rect_t extentRect,void (ASMAPI *setup)(m_int topY,m_int botY,m_int left,m_int right),void (ASMAPI *set4pixels)(bool inc_x,bool inc_y,bool region1),void (ASMAPI *finished)(void)); +void MGLAPI MGL_ellipseArcEngine(rect_t extentRect,m_int startAngle,m_int endAngle,arc_coords_t *ac,void (ASMAPI *plotPoint)(m_int x,m_int y)); +#endif + +/* Text attribute manipulation */ + +#ifndef MGL_LITE +void MGLAPI MGL_setTextJustify(m_int horiz,m_int vert); +void MGLAPI MGL_getTextJustify(m_int *horiz,m_int *vert); +void MGLAPI MGL_setTextDirection(m_int direction); +m_int MGLAPI MGL_getTextDirection(void); +void MGLAPI MGL_setTextSize(m_int numerx,m_int denomx,m_int numery,m_int denomy); +void MGLAPI MGL_getTextSize(m_int *numerx,m_int *denomx,m_int *numery,m_int *denomy); +void MGLAPI MGL_setSpaceExtra(m_int extra); +m_int MGLAPI MGL_getSpaceExtra(void); +void MGLAPI MGL_setTextSettings(text_settings_t *settings); +void MGLAPI MGL_getTextSettings(text_settings_t *settings); +m_int MGLAPI MGL_textHeight(void); +m_int MGLAPI MGL_textWidth(const char *str); +void MGLAPI MGL_textBounds(m_int x,m_int y,const char *str,rect_t *bounds); +m_int MGLAPI MGL_charWidth(char ch); +void MGLAPI MGL_getFontMetrics(metrics_t *metrics); +void MGLAPI MGL_getCharMetrics(char ch,metrics_t *metrics); +m_int MGLAPI MGL_maxCharWidth(void); +void MGLAPI MGL_underScoreLocation(m_int *x,m_int *y,const char *str); +#endif + +/* Text drawing */ + +#ifndef MGL_LITE +void MGLAPI MGL_drawStr(const char *str); +void MGLAPI MGL_drawStrXY(m_int x,m_int y,const char *str); +bool MGLAPI MGL_useFont(font_t *font); +font_t * MGLAPI MGL_getFont(void); +bool MGLAPI MGL_vecFontEngine(m_int x,m_int y,const char *str,void (ASMAPI *move)(m_int x,m_int y),void (ASMAPI *draw)(m_int x,m_int y)); +#endif + +/* BitBlt support */ + +void MGLAPI MGL_bitBltCoord(MGLDC *dst,MGLDC *src,m_int left,m_int top,m_int right,m_int bottom,m_int dstLeft,m_int dstTop,m_int op); +void MGLAPI MGL_stretchBltCoord(MGLDC *dst,MGLDC *src,m_int left,m_int top,m_int right,m_int bottom,m_int dstLeft,m_int dstTop,m_int dstRight,m_int dstBottom); +#ifndef MGL_LITE +void MGLAPI MGL_getDivotCoord(MGLDC *dc,m_int left,m_int top,m_int right,m_int bottom,void *divot); +void MGLAPI MGL_putDivot(MGLDC *dc,void *divot); +long MGLAPI MGL_divotSizeCoord(MGLDC *dc,m_int left,m_int top,m_int right,m_int bottom); +void MGLAPI MGL_putMonoImage(MGLDC *dc,m_int x,m_int y,m_int byteWidth,m_int height,void *image); +void MGLAPI MGL_putBitmap(MGLDC *dc,m_int x,m_int y,const bitmap_t *bitmap,m_int op); +void MGLAPI MGL_putBitmapSection(MGLDC *dc,m_int left,m_int top,m_int right,m_int bottom,m_int dstLeft,m_int dstTop,const bitmap_t *bitmap,m_int op); +void MGLAPI MGL_putBitmapTransparent(MGLDC *dc,m_int x,m_int y,const bitmap_t *bitmap,color_t transparent,bool sourceTrans); +void MGLAPI MGL_putBitmapTransparentSection(MGLDC *dc,m_int left,m_int top,m_int right,m_int bottom,m_int dstLeft,m_int dstTop,const bitmap_t *bitmap,color_t transparent,bool sourceTrans); +void MGLAPI MGL_putBitmapMask(MGLDC *dc,m_int x,m_int y,const bitmap_t *mask,color_t color); +void MGLAPI MGL_stretchBitmap(MGLDC *dc,m_int left,m_int top,m_int right,m_int bottom,const bitmap_t *bitmap); +void MGLAPI MGL_putIcon(MGLDC *dc,m_int x,m_int y,const icon_t *icon); +void MGLAPI MGL_transBltCoord(MGLDC *dst,MGLDC *src,m_int left,m_int top,m_int right,m_int bottom,m_int dstLeft,m_int dstTop,color_t transparent,bool sourceTrans); +#endif + +/* Linear offscreen DC BitBlt support */ + +#ifndef MGL_LITE +void MGLAPI MGL_bitBltLinCoord(MGLDC *dst,MGLDC *src,ulong srcOfs,m_int dstLeft,m_int dstTop,m_int dstRight,m_int dstBottom,m_int op); +void MGLAPI MGL_transBltLinCoord(MGLDC *dst,MGLDC *src,ulong srcOfs,m_int dstLeft,m_int dstTop,m_int dstRight,m_int dstBottom,color_t transparent,bool sourceTrans); +#endif + +/* Monochrome bitmap manipulation */ + +#ifndef MGL_LITE +void MGLAPI MGL_drawGlyph(font_t *g,m_int x,m_int y,uchar glyph); +m_int MGLAPI MGL_getGlyphWidth(font_t *font,uchar glyph); +m_int MGLAPI MGL_getGlyphHeight(font_t *font); +void MGLAPI MGL_rotateGlyph(uchar *dst,uchar *src,m_int *byteWidth,m_int *height,m_int rotation); +void MGLAPI MGL_mirrorGlyph(uchar *dst,uchar *src,m_int byteWidth,m_int height); +#endif + +/* Region management */ + +#ifndef MGL_LITE +region_t * MGLAPI MGL_newRegion(void); +region_t * MGLAPI MGL_copyRegion(const region_t *s); +void MGLAPI MGL_clearRegion(region_t *r); +void MGLAPI MGL_freeRegion(region_t *r); +void MGLAPI MGL_drawRegion(m_int x,m_int y,const region_t *r); +#endif + +/* Region generation primitives */ + +#ifndef MGL_LITE +region_t * MGLAPI MGL_rgnLineCoord(m_int x1,m_int y1,m_int x2,m_int y2,const region_t *pen); +region_t * MGLAPI MGL_rgnLineCoordFX(fix32_t x1,fix32_t y1,fix32_t x2,fix32_t y2,const region_t *pen); +/*region_t * MGLAPI MGL_rgnPolygon(m_int count,point_t *vArray);*/ +/*region_t * MGLAPI MGL_rgnPolygonFast(m_int count,point_t *vArray);*/ +region_t * MGLAPI MGL_rgnSolidRectCoord(m_int left,m_int top,m_int right,m_int bottom); +region_t * MGLAPI MGL_rgnEllipse(rect_t extentRect,const region_t *pen); +region_t * MGLAPI MGL_rgnEllipseArc(rect_t extentRect,m_int startAngle,m_int endAngle,const region_t *pen); +void MGLAPI MGL_rgnGetArcCoords(arc_coords_t *coords); +region_t * MGLAPI MGL_rgnSolidEllipse(rect_t extentRect); +region_t * MGLAPI MGL_rgnSolidEllipseArc(rect_t extentRect,m_int startAngle,m_int endAngle); +#endif + +/* Region alegbra */ + +#ifndef MGL_LITE +region_t * MGLAPI MGL_sectRegion(const region_t *r1,const region_t *r2); +region_t * MGLAPI MGL_sectRegionRect(const region_t *r1,const rect_t *r2); +bool MGLAPI MGL_unionRegion(region_t *r1,const region_t *r2); +bool MGLAPI MGL_unionRegionRect(region_t *r1,const rect_t *r2); +bool MGLAPI MGL_unionRegionOfs(region_t *r1,const region_t *r2,m_int xOffset,m_int yOffset); +bool MGLAPI MGL_diffRegion(region_t *r1,const region_t *r2); +bool MGLAPI MGL_diffRegionRect(region_t *r1,const rect_t *r2); +void MGLAPI MGL_optimizeRegion(region_t *r); +void MGLAPI MGL_offsetRegion(region_t *r,m_int dx,m_int dy); +bool MGLAPI MGL_emptyRegion(const region_t *r); +bool MGLAPI MGL_equalRegion(const region_t *r1,const region_t *r2); +bool MGLAPI MGL_ptInRegionCoord(m_int x,m_int y,const region_t *r); +#endif + +/* Region traversal */ + +#ifndef MGL_LITE +typedef void (ASMAPI *rgncallback_t)(const rect_t *r); + +void MGLAPI MGL_traverseRegion(region_t *rgn,rgncallback_t doRect); +#endif + +/* RGB to 8 bit halftone dithering routines */ + +#ifndef MGL_LITE +void MGLAPI MGL_getHalfTonePalette(palette_t *pal); +uchar MGLAPI MGL_halfTonePixel(m_int x,m_int y,uchar R,uchar G,uchar B); +#endif + +/* Resource loading/unloading */ + +font_t * MGLAPI MGL_loadFont(const char *fontname); +bool MGLAPI MGL_availableFont(const char *fontname); +void MGLAPI MGL_unloadFont(font_t *font); +cursor_t * MGLAPI MGL_loadCursor(const char *cursorName); +bool MGLAPI MGL_availableCursor(const char *cursorName); +void MGLAPI MGL_unloadCursor(cursor_t *cursor); +#ifndef MGL_LITE +icon_t * MGLAPI MGL_loadIcon(const char *iconName,bool loadPalette); +bool MGLAPI MGL_availableIcon(const char *iconName); +void MGLAPI MGL_unloadIcon(icon_t *icon); +#endif + +/* Windows BMP bitmap loading/unloading/saving */ + +#ifndef MGL_LITE +bitmap_t * MGLAPI MGL_loadBitmap(const char *bitmapName,bool loadPalette); +bool MGLAPI MGL_availableBitmap(const char *bitmapName); +void MGLAPI MGL_unloadBitmap(bitmap_t *bitmap); +bool MGLAPI MGL_getBitmapSize(const char *bitmapName,m_int *width,m_int *height,m_int *bitsPerPixel,pixel_format_t *pf); +bool MGLAPI MGL_loadBitmapIntoDC(MGLDC *dc,const char *bitmapName,m_int dstLeft,m_int dstTop,bool loadPalette); +bool MGLAPI MGL_saveBitmapFromDC(MGLDC *dc,const char *bitmapName,m_int left,m_int top,m_int right,m_int bottom); +bitmap_t * MGLAPI MGL_getBitmapFromDC(MGLDC *dc,m_int left,m_int top,m_int right,m_int bottom,bool savePalette); +bitmap_t * MGLAPI MGL_buildMonoMask(bitmap_t *bitmap,color_t transparent); +#endif + +/* PCX bitmap loading/unloading/saving (1/4/8 bpp only) */ + +#ifndef MGL_LITE +bitmap_t * MGLAPI MGL_loadPCX(const char *bitmapName,bool loadPalette); +bool MGLAPI MGL_availablePCX(const char *bitmapName); +bool MGLAPI MGL_getPCXSize(const char *bitmapName,m_int *width,m_int *height,m_int *bitsPerPixel); +bool MGLAPI MGL_loadPCXIntoDC(MGLDC *dc,const char *bitmapName,m_int dstLeft,m_int dstTop,bool loadPalette); +bool MGLAPI MGL_savePCXFromDC(MGLDC *dc,const char *bitmapName,m_int left,m_int top,m_int right,m_int bottom); +#endif + +/* Random number generation routines for shorts and longs with full range */ + +void ASMAPI MGL_srand(m_uint seed); +ushort ASMAPI MGL_random(ushort max); +ulong ASMAPI MGL_randoml(ulong max); + +/* Mouse support */ + +bool MGLAPI MS_available(void); +void MGLAPI MS_show(void); +void MGLAPI MS_hide(void); +void MGLAPI MS_obscure(void); +void MGLAPI MS_setCursor(cursor_t *curs); +void MGLAPI MS_setCursorColor(color_t color); +void MGLAPI MS_moveTo(m_int x,m_int y); +void MGLAPI MS_getPos(m_int *x,m_int *y); +void MGLAPI MS_drawCursor(void); + +/* Rectangle and Point manipulation */ + +rect_t MGLAPI MGL_defRect(m_int left,m_int top,m_int right,m_int bottom); +rect_t MGLAPI MGL_defRectPt(point_t leftTop,point_t rightBottom); +bool MGLAPI MGL_sectRect(rect_t s1,rect_t s2,rect_t *d); +bool MGLAPI MGL_sectRectCoord(m_int left1,m_int top1,m_int right1,m_int bottom1,m_int left2,m_int top2,m_int right2,m_int bottom2,rect_t *d); +void MGLAPI MGL_unionRect(rect_t s1,rect_t s2,rect_t *d); +void MGLAPI MGL_unionRectCoord(m_int left1,m_int top1,m_int right1,m_int bottom1,m_int left2,m_int top2,m_int right2,m_int bottom2,rect_t *d); + +/* Built-in patterns and mouse cursor */ + +#ifndef MGL_LITE +pattern_t * MGLAPI _MGL_getEmptyPat(void); +pattern_t * MGLAPI _MGL_getGrayPat(void); +pattern_t * MGLAPI _MGL_getSolidPat(void); +#endif +cursor_t * MGLAPI _MGL_getDefCursor(void); + +/* Fixed point multiplication/divide routines */ + +#if defined(__WATCOMC__) && defined(__386__) + +/* For Watcom C++ we can use special inline assembler code that is much + * faster than calling the 386 assembler functions. Currently this is the + * the only compiler that will allow inline assembler to be expanded + * directly as inline functions. + */ + +fix32_t MGL_FixMul(fix32_t a,fix32_t b); +#pragma aux MGL_FixMul = \ + "imul edx" \ + "add eax,8000h" \ + "adc edx,0" \ + "shrd eax,edx,16" \ + parm [eax] [edx] \ + value [eax] \ + modify exact [eax edx]; + +fix32_t MGL_FixDiv(fix32_t a,fix32_t b); +#pragma aux MGL_FixDiv = \ + "xor eax,eax" \ + "shrd eax,edx,16" \ + "sar edx,16" \ + "idiv ebx" \ + parm [edx] [ebx] \ + value [eax] \ + modify exact [eax edx]; + +fix32_t MGL_FixMulDiv(fix32_t a,fix32_t b,fix32_t c); +#pragma aux MGL_FixMulDiv = \ + "imul ebx" \ + "idiv ecx" \ + parm [eax] [ebx] [ecx] \ + value [eax] \ + modify exact [eax edx]; + +m_int MGL_backfacing(fix32_t dx1,fix32_t dy1,fix32_t dx2,fix32_t dy2); +#pragma aux MGL_backfacing = \ + "imul ebx" \ + "mov ebx,eax" \ + "mov ecx,edx" \ + "mov eax,esi" \ + "imul edi" \ + "sub eax,ebx" \ + "mov eax,1" \ + "sbb edx,ecx" \ + "jns @@Backfacing" \ + "xor eax,eax" \ + "@@Backfacing:" \ + parm [eax] [esi] [edi] [ebx] \ + value [eax] \ + modify exact [eax ecx edx]; + +void MGL_memcpy(void *dst,void *src,m_int n); +#pragma aux MGL_memcpy = \ + "mov eax,ecx" \ + "shr ecx,2" \ + "rep movsd" \ + "mov cl,al" \ + "and cl,3" \ + "rep movsb" \ + parm [edi] [esi] [ecx] \ + modify exact [eax ecx esi edi]; + +#else + +fix32_t ASMAPI MGL_FixMul(fix32_t a,fix32_t b); +fix32_t ASMAPI MGL_FixDiv(fix32_t a,fix32_t b); +fix32_t ASMAPI MGL_FixMulDiv(fix32_t a,fix32_t b,fix32_t c); +m_int ASMAPI MGL_backfacing(fix32_t dx1,fix32_t dy1,fix32_t dx2,fix32_t dy2); +void ASMAPI MGL_memcpy(void *dst,void *src,m_int n); + +#endif + +/* The following are special memcpy routines that properly handler reading + * and writing to virtual linear buffer memory by forcing the proper + * alignment. Note that the copy is extended to use a DWORD copy of speed. + */ + +void ASMAPI MGL_memcpyVIRTSRC(void *dst,void *src,m_int n); +void ASMAPI MGL_memcpyVIRTDST(void *dst,void *src,m_int n); + +/* Function to find an MGL system file's full pathname */ + +bool MGLAPI _MGL_findFile(char *validpath,const char *dir, const char *filename, const char *mode); + +/* Override the internal MGL file I/O functions */ + +void MGLAPI MGL_setFileIO(fileio_t *fio); + +/* The following dummy symbols are used to link in driver files to be used. A + * driver is not active until it is linked in with the MGL_registerDriver + * call. Because we dont export globals in DLLs, we provide functions to + * get the address of the drivers. However for a static link library we + * need to use globals so that if the driver data is unreferenced, it will + * not be linked in with the code. + */ + +#ifndef BUILD_MGL +#if defined(MGL_DLL) && !defined(BUILD_MGLDLL) +void * MGLAPI VGA4_getDriverAddr(void); +void * MGLAPI VGAX_getDriverAddr(void); +void * MGLAPI SVGA4_getDriverAddr(void); +void * MGLAPI SVGA8_getDriverAddr(void); +void * MGLAPI SVGA16_getDriverAddr(void); +void * MGLAPI SVGA24_getDriverAddr(void); +void * MGLAPI SVGA32_getDriverAddr(void); +#if !defined(__16BIT__) +void * MGLAPI VGA8_getDriverAddr(void); +void * MGLAPI LINEAR8_getDriverAddr(void); +void * MGLAPI LINEAR16_getDriverAddr(void); +void * MGLAPI LINEAR24_getDriverAddr(void); +void * MGLAPI LINEAR32_getDriverAddr(void); +void * MGLAPI ACCEL8_getDriverAddr(void); +void * MGLAPI ACCEL16_getDriverAddr(void); +void * MGLAPI ACCEL24_getDriverAddr(void); +void * MGLAPI ACCEL32_getDriverAddr(void); +#if defined(MGLWIN) || defined(__WINDOWS__) +void * MGLAPI DDRAW8_getDriverAddr(void); +void * MGLAPI DDRAW16_getDriverAddr(void); +void * MGLAPI DDRAW24_getDriverAddr(void); +void * MGLAPI DDRAW32_getDriverAddr(void); +#endif +#endif +void * MGLAPI PACKED1_getDriverAddr(void); +void * MGLAPI PACKED4_getDriverAddr(void); +void * MGLAPI PACKED8_getDriverAddr(void); +void * MGLAPI PACKED16_getDriverAddr(void); +void * MGLAPI PACKED24_getDriverAddr(void); +void * MGLAPI PACKED32_getDriverAddr(void); +#define VGA4_driver VGA4_getDriverAddr() +#define VGAX_driver VGAX_getDriverAddr() +#define SVGA4_driver SVGA4_getDriverAddr() +#define SVGA8_driver SVGA8_getDriverAddr() +#define SVGA16_driver SVGA16_getDriverAddr() +#define SVGA24_driver SVGA24_getDriverAddr() +#define SVGA32_driver SVGA32_getDriverAddr() +#if !defined(__16BIT__) +#define VGA8_driver VGA8_getDriverAddr() +#define LINEAR8_driver LINEAR8_getDriverAddr() +#define LINEAR16_driver LINEAR16_getDriverAddr() +#define LINEAR24_driver LINEAR24_getDriverAddr() +#define LINEAR32_driver LINEAR32_getDriverAddr() +#define ACCEL8_driver ACCEL8_getDriverAddr() +#define ACCEL16_driver ACCEL16_getDriverAddr() +#define ACCEL24_driver ACCEL24_getDriverAddr() +#define ACCEL32_driver ACCEL32_getDriverAddr() +#if defined(MGLWIN) || defined(__WINDOWS__) +#define DDRAW8_driver DDRAW8_getDriverAddr() +#define DDRAW16_driver DDRAW16_getDriverAddr() +#define DDRAW24_driver DDRAW24_getDriverAddr() +#define DDRAW32_driver DDRAW32_getDriverAddr() +#endif +#endif +#define PACKED1_driver PACKED1_getDriverAddr() +#define PACKED4_driver PACKED4_getDriverAddr() +#define PACKED8_driver PACKED8_getDriverAddr() +#define PACKED16_driver PACKED16_getDriverAddr() +#define PACKED24_driver PACKED24_getDriverAddr() +#define PACKED32_driver PACKED32_getDriverAddr() +#else +extern m_int _VARAPI VGA4_driver[]; +extern m_int _VARAPI VGAX_driver[]; +extern m_int _VARAPI SVGA4_driver[]; +extern m_int _VARAPI SVGA8_driver[]; +extern m_int _VARAPI SVGA16_driver[]; +extern m_int _VARAPI SVGA24_driver[]; +extern m_int _VARAPI SVGA32_driver[]; +#if !defined(__16BIT__) +extern m_int _VARAPI VGA8_driver[]; +extern m_int _VARAPI LINEAR8_driver[]; +extern m_int _VARAPI LINEAR16_driver[]; +extern m_int _VARAPI LINEAR24_driver[]; +extern m_int _VARAPI LINEAR32_driver[]; +extern m_int _VARAPI ACCEL8_driver[]; +extern m_int _VARAPI ACCEL16_driver[]; +extern m_int _VARAPI ACCEL24_driver[]; +extern m_int _VARAPI ACCEL32_driver[]; +#if defined(MGLWIN) || defined(__WINDOWS__) +extern m_int _VARAPI DDRAW8_driver[]; +extern m_int _VARAPI DDRAW16_driver[]; +extern m_int _VARAPI DDRAW24_driver[]; +extern m_int _VARAPI DDRAW32_driver[]; +#endif +#endif +extern m_int _VARAPI PACKED1_driver[]; +extern m_int _VARAPI PACKED4_driver[]; +extern m_int _VARAPI PACKED8_driver[]; +extern m_int _VARAPI PACKED16_driver[]; +extern m_int _VARAPI PACKED24_driver[]; +extern m_int _VARAPI PACKED32_driver[]; +#endif +#endif + +/*--------------------------------------------------------------------------- + * Memory allocation and utility functions. + *-------------------------------------------------------------------------*/ + +#ifndef __16BIT__ +#define _HUGE +#else +#define _HUGE _huge +#endif + +void MGL_availableMemory(ulong *physical,ulong *total); +void MGL_useLocalMalloc(void _HUGE * (*malloc)(long size),void (*free)(void _HUGE *p)); +void * MGLAPI MGL_malloc(long size); +void * MGLAPI MGL_calloc(long size,long n); +void MGLAPI MGL_free(void _HUGE *p); +void MGLAPI MGL_memset(void _HUGE *s,m_int c,long n); +void MGLAPI MGL_memsetw(void _HUGE *s,m_int c,long n); +void MGLAPI MGL_memsetl(void _HUGE *s,long c,long n); + +/*--------------------------------------------------------------------------- + * Set a fullscreen suspend application callback function. This is used in + * fullscreen video modes to allow switching back to the normal operating + * system graphical shell (such as Windows GDI, OS/2 PM etc). + *-------------------------------------------------------------------------*/ + +typedef m_int (ASMAPI *MGL_suspend_cb_t)(MGLDC *dc,m_int flags); +void MGLAPI MGL_setSuspendAppCallback(MGL_suspend_cb_t staveState); + +/*--------------------------------------------------------------------------- + * Tell the MGL to use a pre-loaded ACCEL.DRV driver file. This allows + * you to link with the SciTech WinDirect/Pro and WinDirect/Ultra device + * support libraries and tell the MGL to use the device support drivers. + * If the user has a real ACCEL.DRV driver file in the standard location + * on their machine, this driver file will still be used. + *-------------------------------------------------------------------------*/ + +void MGLAPI MGL_setACCELDriver(void *driver); + +/*---------------------- Inline functions as Macros -----------------------*/ + +#define MGL_equalPoint(p1,p2) ((p1).x == (p2).x && (p1).y == (p2).y) + +#define MGL_equalRect(r1,r2) ((r1).left == (r2).left && \ + (r1).top == (r2).top && \ + (r1).right == (r2).right && \ + (r1).bottom == (r2).bottom) + +#define MGL_emptyRect(r) ((r).bottom <= (r).top || \ + (r).right <= (r).left) + +#define MGL_disjointRect(r1,r2) ((r1).right <= (r2).left || \ + (r1).left >= (r2).right || \ + (r1).bottom <= (r2).top || \ + (r1).top >= (r2).bottom) + +#define MGL_sectRect(s1,s2,d) \ + ((d)->left = MAX((s1).left,(s2).left), \ + (d)->right = MIN((s1).right,(s2).right), \ + (d)->top = MAX((s1).top,(s2).top), \ + (d)->bottom = MIN((s1).bottom,(s2).bottom), \ + !MGL_emptyRect(*d)) + +#define MGL_sectRectFast(s1,s2,d) \ + (d)->left = MAX((s1).left,(s2).left); \ + (d)->right = MIN((s1).right,(s2).right); \ + (d)->top = MAX((s1).top,(s2).top); \ + (d)->bottom = MIN((s1).bottom,(s2).bottom) + +#define MGL_sectRectCoord(l1,t1,r1,b1,l2,t2,r2,b2,d) \ + ((d)->left = MAX(l1,l2), \ + (d)->right = MIN(r1,r2), \ + (d)->top = MAX(t1,t2), \ + (d)->bottom = MIN(b1,b2), \ + !MGL_emptyRect(*d)) + +#define MGL_sectRectFastCoord(l1,t1,r1,b1,l2,t2,r2,b2,d) \ + (d)->left = MAX(l1,l2); \ + (d)->right = MIN(r1,r2); \ + (d)->top = MAX(t1,t2); \ + (d)->bottom = MIN(b1,b2) + +#define MGL_unionRect(s1,s2,d) \ + (d)->left = MIN((s1).left,(s2).left); \ + (d)->right = MAX((s1).right,(s2).right); \ + (d)->top = MIN((s1).top,(s2).top); \ + (d)->bottom = MAX((s1).bottom,(s2).bottom) + +#define MGL_unionRectCoord(l1,t1,r1,b1,l2,t2,r2,b2,d) \ + (d)->left = MIN(l1,l2); \ + (d)->right = MAX(r1,r2); \ + (d)->top = MIN(t1,t2); \ + (d)->bottom = MAX(b1,b2) + +#define MGL_offsetRect(r,dx,dy) \ + { (r).left += dx; (r).right += dx; \ + (r).top += dy; (r).bottom += dy; } + +#define MGL_insetRect(r,dx,dy) \ + { (r).left += dx; (r).right -= dx; \ + (r).top += dy; (r).bottom -= dy; \ + if (MGL_emptyRect(r)) \ + (r).left = (r).right = (r).top = (r).bottom = 0; } + +#define MGL_ptInRect(p,r) ((p).x >= (r).left && \ + (p).x < (r).right && \ + (p).y >= (r).top && \ + (p).y < (r).bottom) + +#define MGL_ptInRectCoord(x,y,r) ((x) >= (r).left && \ + (x) < (r).right && \ + (y) >= (r).top && \ + (y) < (r).bottom) + +#define MGL_ptInRegion(p,r) MGL_ptInRegionCoord((p).x,(p).y,r) + +#define MGL_pixel(p) MGL_pixelCoord((p).x,(p).y) +#define MGL_getPixel(p) MGL_getPixelCoord((p).x,(p).y) +#define MGL_pixelFast(p) MGL_pixelCoordFast((p).x,(p).y) +#define MGL_getPixelFast(p) MGL_getPixelCoordFast((p).x,(p).y) +#define MGL_moveTo(p) MGL_moveToCoord((p).x,(p).y) +#define MGL_moveRel(p) MGL_moveRelCoord((p).x,(p).y) +#define MGL_line(p1,p2) MGL_lineCoord((p1).x,(p1).y,(p2).x,(p2).y) +#define MGL_lineFast(p1,p2) MGL_lineCoordFast((p1).x,(p1).y,(p2).x,(p2).y) +#define MGL_lineFX(p1,p2) MGL_lineCoordFX((p1).x,(p1).y,(p2).x,(p2).y) +#define MGL_lineFastFX(p1,p2) MGL_lineCoordFastFX((p1).x,(p1).y,(p2).x,(p2).y) +#define MGL_cLineFast(p1,p2) MGL_cLineCoordFast((p1).p.x,(p1).p.y,(p1).c,(p2).p.x,(p2).p.y,(p2).c) +#define MGL_rgbLineFast(p1,p2) MGL_rgbLineCoordFast((p1).p.x,(p1).p.y,(p1).c.r,(p1).c.g,(p1).c.b,(p2).p.x,(p2).p.y,(p2).c.r,(p2).c.g,(p2).c.b) +#define MGL_zLineFast(p1,p2) MGL_zLineCoordFast((p1).p.x,(p1).p.y,(p1).z,(p2).p.x,(p2).p.y,(p2).z) +#define MGL_czLineFast(p1,p2) MGL_czLineCoordFast((p1).p.x,(p1).p.y,(p1).z,(p1).c,(p2).p.x,(p2).p.y,(p2).z,(p2).c) +#define MGL_rgbzLineFast(p1,p2) MGL_rgbzLineCoordFast((p1).p.x,(p1).p.y,(p1).z,(p1).c.r,(p1).c.g,(p1).c.b,(p2).p.x,(p2).p.y,(p2).z,(p2).c.r,(p2).c.g,(p2).c.b) + +#define MGL_zClearPt(lt,rb,z) MGL_zClearCoord((lt).x,(lt).y, \ + (rb).x,(rb).y,z) +#define MGL_zClear(r,z) MGL_zClearCoord((r).left,(r).top, \ + (r).right,(r).bottom,z) +#define MGL_lineTo(p) MGL_lineToCoord((p).x,(p).y) +#define MGL_lineRel(p) MGL_lineRelCoord((p).x,(p).y); +#define MGL_rectPt(lt,rb) MGL_rectCoord((lt).x,(lt).y,(rb).x,(rb).y) +#define MGL_rect(r) MGL_rectCoord((r).left,(r).top, \ + (r).right,(r).bottom) +#define MGL_drawBorder(r,s,t) MGL_drawBorderCoord((r).left,(r).top, \ + (r).right,(r).bottom,(s),(t)) +#define MGL_fillRectPt(lt,rb) MGL_fillRectCoord((lt).x,(lt).y, \ + (rb).x,(rb).y) +#define MGL_fillRect(r) MGL_fillRectCoord((r).left,(r).top, \ + (r).right,(r).bottom) +#define MGL_bitBlt(d,s,r,dl,dt,op) MGL_bitBltCoord((d),(s),(r).left, \ + (r).top,(r).right,(r).bottom,dl,dt,op) +#define MGL_bitBltLin(d,s,so,r,op) MGL_bitBltLinCoord((d),(s),so, \ + (r).left,(r).top,(r).right,(r).bottom,op) +#define MGL_stretchBlt(d,s,sr,dr) MGL_stretchBltCoord((d),(s),(sr).left, \ + (sr).top,(sr).right,(sr).bottom, \ + (dr).left,(dr).top,(dr).right,(dr).bottom) +#define MGL_transBlt(d,s,r,dl,dt,c,st) MGL_transBltCoord((d),(s),(r).left, \ + (r).top,(r).right,(r).bottom,dl,dt,c,st) +#define MGL_transBltLin(d,s,so,r,c,st) MGL_transBltLinCoord((d),(s),so, \ + (r).left,(r).top,(r).right,(r).bottom,c,st) +#define MGL_getDivot(dc,r,divot) MGL_getDivotCoord(dc,(r).left,(r).top, \ + (r).right,(r).bottom,divot) +#define MGL_divotSize(dc,r) MGL_divotSizeCoord(dc,(r).left,(r).top,\ + (r).right,(r).bottom) +#define MGL_isSimpleRegion(r) (((region_t*)(r))->spans == NULL) +#define MGL_rgnLine(p1,p2,p) MGL_rgnLineCoord((p1).x,(p1).y,(p2).x,(p2).y,p) +#define MGL_rgnLineFX(p1,p2,p) MGL_rgnLineCoordFX((p1).x,(p1).y,(p2).x,(p2).y,p) +#define MGL_rgnSolidRectPt(lt,rb) MGL_rgnSolidRectCoord((lt).x,(lt).y, \ + (rb).x,(rb).y) +#define MGL_rgnSolidRect(r) MGL_rgnSolidRectCoord((r).left,(r).top, \ + (r).right,(r).bottom) + +/* Fast color packing/unpacking routines implemented as macros */ + +#define MGL_packColorFast(pf,R,G,B) \ + ((ulong)(((uchar)(R) >> (pf)->redAdjust) & (pf)->redMask) << (pf)->redPos) \ + | ((ulong)(((uchar)(G) >> (pf)->greenAdjust) & (pf)->greenMask) << (pf)->greenPos) \ + | ((ulong)(((uchar)(B) >> (pf)->blueAdjust) & (pf)->blueMask) << (pf)->bluePos) + +#define MGL_unpackColorFast(pf,c,R,G,B) \ +{ \ + (R) = (uchar)((((ulong)(c) >> (pf)->redPos) & (pf)->redMask) << (pf)->redAdjust); \ + (G) = (uchar)((((ulong)(c) >> (pf)->greenPos) & (pf)->greenMask) << (pf)->greenAdjust);\ + (B) = (uchar)((((ulong)(c) >> (pf)->bluePos) & (pf)->blueMask) << (pf)->blueAdjust); \ +} + +/* Macros to access the RGB components in a packed 24 bit RGB tuple */ + +#define MGL_rgbRed(c) (((uchar*)&(c))[2]) +#define MGL_rgbGreen(c) (((uchar*)&(c))[1]) +#define MGL_rgbBlue(c) (((uchar*)&(c))[0]) + +/* Fast 24 bit color packing/unpacking routines implemented as macros */ + +#define MGL_packColorRGBFast(R,G,B) \ + (((ulong)((uchar)(R)) << 16) | ((ulong)((uchar)(G)) << 8) | (uchar)(B)) + +#define MGL_packColorRGBFast2(c,R,G,B) \ +{ \ + MGL_rgbRed(c) = (uchar)(R); \ + MGL_rgbGreen(c) = (uchar)(G); \ + MGL_rgbBlue(c) = (uchar)(B); \ +} + +#define MGL_unpackColorRGBFast(c,R,G,B) \ +{ \ + (R) = MGL_rgbRed(c); \ + (G) = MGL_rgbGreen(c); \ + (B) = MGL_rgbBlue(c); \ +} + +#ifdef __cplusplus +} /* End of "C" linkage for C++ */ + +#include "mglrect.hpp" /* Include C++ point/rectangle classes */ + +#endif /* __cplusplus */ + +/* Include appropriate platform specific bindings */ + +#if defined(MGLWIN) || defined(__WINDOWS__) +#include "mglwin.h" +#elif defined(MGLPM) || defined(__OS2__) +/*#include "mglpm.h"*/ +#elif defined(MGLX) || defined(__UNIX__) +/*#include "mglx.h"*/ +#else +#include "mgldos.h" +#endif + +#pragma pack() /* Return to default packing */ + +#endif /* __MGRAPH_H */ diff --git a/contrib/other/sdlquake-1.0.9/scitech/LIB/WIN32/VC/MGLLT.LIB b/contrib/other/sdlquake-1.0.9/scitech/LIB/WIN32/VC/MGLLT.LIB new file mode 100644 index 000000000..6416e2767 Binary files /dev/null and b/contrib/other/sdlquake-1.0.9/scitech/LIB/WIN32/VC/MGLLT.LIB differ diff --git a/contrib/other/sdlquake-1.0.9/screen.c b/contrib/other/sdlquake-1.0.9/screen.c new file mode 100644 index 000000000..b39be678e --- /dev/null +++ b/contrib/other/sdlquake-1.0.9/screen.c @@ -0,0 +1,991 @@ +/* +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. + +*/ +// screen.c -- master for refresh, status bar, console, chat, notify, etc + +#include "quakedef.h" +#include "r_local.h" + +// only the refresh window will be updated unless these variables are flagged +int scr_copytop; +int scr_copyeverything; + +float scr_con_current; +float scr_conlines; // lines of console to display + +float oldscreensize, oldfov; +cvar_t scr_viewsize = {"viewsize","100", true}; +cvar_t scr_fov = {"fov","90"}; // 10 - 170 +cvar_t scr_conspeed = {"scr_conspeed","300"}; +cvar_t scr_centertime = {"scr_centertime","2"}; +cvar_t scr_showram = {"showram","1"}; +cvar_t scr_showturtle = {"showturtle","0"}; +cvar_t scr_showpause = {"showpause","1"}; +cvar_t scr_printspeed = {"scr_printspeed","8"}; + +qboolean scr_initialized; // ready to draw + +qpic_t *scr_ram; +qpic_t *scr_net; +qpic_t *scr_turtle; + +int scr_fullupdate; + +int clearconsole; +int clearnotify; + +viddef_t vid; // global video state + +vrect_t *pconupdate; +vrect_t scr_vrect; + +qboolean scr_disabled_for_loading; +qboolean scr_drawloading; +float scr_disabled_time; +qboolean scr_skipupdate; + +qboolean block_drawing; + +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 (char *str) +{ + 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; + while (*str) + { + if (*str == '\n') + scr_center_lines++; + str++; + } +} + +void SCR_EraseCenterString (void) +{ + int y; + + if (scr_erase_center++ > vid.numpages) + { + scr_erase_lines = 0; + return; + } + + if (scr_center_lines <= 4) + y = vid.height*0.35; + else + y = 48; + + scr_copytop = 1; + Draw_TileClear (0, y,vid.width, 8*scr_erase_lines); +} + +void SCR_DrawCenterString (void) +{ + char *start; + int l; + int j; + int x, y; + int remaining; + +// 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 = vid.height*0.35; + else + y = 48; + + 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 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; +} + +/* +================= +SCR_CalcRefdef + +Must be called whenever vid changes +Internal use only +================= +*/ +static void SCR_CalcRefdef (void) +{ + vrect_t vrect; + float size; + + scr_fullupdate = 0; // force a background redraw + vid.recalc_refdef = 0; + +// force the status bar to redraw + Sbar_Changed (); + +//======================================== + +// bound viewsize + if (scr_viewsize.value < 30) + Cvar_Set ("viewsize","30"); + if (scr_viewsize.value > 120) + Cvar_Set ("viewsize","120"); + +// bound field of view + if (scr_fov.value < 10) + Cvar_Set ("fov","10"); + if (scr_fov.value > 170) + Cvar_Set ("fov","170"); + + r_refdef.fov_x = scr_fov.value; + r_refdef.fov_y = CalcFov (r_refdef.fov_x, r_refdef.vrect.width, r_refdef.vrect.height); + +// intermission is always full screen + if (cl.intermission) + size = 120; + else + size = scr_viewsize.value; + + if (size >= 120) + sb_lines = 0; // no status bar at all + else if (size >= 110) + sb_lines = 24; // no inventory + else + sb_lines = 24+16+8; + +// these calculations mirror those in R_Init() for r_refdef, but take no +// account of water warping + vrect.x = 0; + vrect.y = 0; + vrect.width = vid.width; + vrect.height = vid.height; + + R_SetVrect (&vrect, &scr_vrect, sb_lines); + +// guard against going from one mode to another that's less than half the +// vertical resolution + if (scr_con_current > vid.height) + scr_con_current = vid.height; + +// notify the refresh of the change + R_ViewChanged (&vrect, sb_lines, vid.aspect); +} + + +/* +================= +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) +{ + Cvar_RegisterVariable (&scr_fov); + 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); + +// +// 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); +} + +/* +============== +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) + { + scr_copytop = 1; + Draw_TileClear (0,(int)scr_con_current,vid.width, vid.height - (int)scr_con_current); + Sbar_Changed (); + } + else if (clearnotify++ < vid.numpages) + { + scr_copytop = 1; + Draw_TileClear (0,0,vid.width, con_notifylines); + } + 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 +{ + char manufacturer; + char version; + char encoding; + char bits_per_pixel; + unsigned short xmin,ymin,xmax,ymax; + unsigned short hres,vres; + unsigned char palette[48]; + char reserved; + char color_planes; + unsigned short bytes_per_line; + unsigned short palette_type; + char filler[58]; + unsigned char data; // unbounded +} pcx_t; + +/* +============== +WritePCXfile +============== +*/ +void WritePCXfile (char *filename, byte *data, int width, int height, + int rowbytes, byte *palette) +{ + int i, j, length; + pcx_t *pcx; + byte *pack; + + pcx = Hunk_TempAlloc (width*height*2+1000); + if (pcx == NULL) + { + Con_Printf("SCR_ScreenShot_f: not enough memory\n"); + return; + } + + pcx->manufacturer = 0x0a; // PCX id + pcx->version = 5; // 256 color + pcx->encoding = 1; // uncompressed + pcx->bits_per_pixel = 8; // 256 color + pcx->xmin = 0; + pcx->ymin = 0; + pcx->xmax = LittleShort((short)(width-1)); + pcx->ymax = LittleShort((short)(height-1)); + pcx->hres = LittleShort((short)width); + pcx->vres = LittleShort((short)height); + Q_memset (pcx->palette,0,sizeof(pcx->palette)); + pcx->color_planes = 1; // chunky image + pcx->bytes_per_line = LittleShort((short)width); + pcx->palette_type = LittleShort(2); // not a grey scale + Q_memset (pcx->filler,0,sizeof(pcx->filler)); + +// pack the image + pack = &pcx->data; + + for (i=0 ; i 60) + { + scr_disabled_for_loading = false; + Con_Printf ("load failed.\n"); + } + else + return; + } + + if (cls.state == ca_dedicated) + return; // stdout only + + if (!scr_initialized || !con_initialized) + return; // not initialized yet + + if (scr_viewsize.value != oldscr_viewsize) + { + oldscr_viewsize = scr_viewsize.value; + vid.recalc_refdef = 1; + } + +// +// check for vid changes +// + if (oldfov != scr_fov.value) + { + oldfov = scr_fov.value; + vid.recalc_refdef = true; + } + + if (oldlcd_x != lcd_x.value) + { + oldlcd_x = lcd_x.value; + vid.recalc_refdef = true; + } + + if (oldscreensize != scr_viewsize.value) + { + oldscreensize = scr_viewsize.value; + vid.recalc_refdef = true; + } + + if (vid.recalc_refdef) + { + // something changed, so reorder the screen + SCR_CalcRefdef (); + } + +// +// do 3D refresh drawing, and then update the screen +// + D_EnableBackBufferAccess (); // of all overlay stuff if drawing directly + + if (scr_fullupdate++ < vid.numpages) + { // clear the entire screen + scr_copyeverything = 1; + Draw_TileClear (0,0,vid.width,vid.height); + Sbar_Changed (); + } + + pconupdate = NULL; + + + SCR_SetUpToDrawConsole (); + SCR_EraseCenterString (); + + D_DisableBackBufferAccess (); // for adapters that can't stay mapped in + // for linear writes all the time + + VID_LockBuffer (); + + V_RenderView (); + + VID_UnlockBuffer (); + + D_EnableBackBufferAccess (); // of all overlay stuff if drawing directly + + 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 (cl.intermission == 3 && key_dest == key_game) + { + SCR_CheckDrawCenterString (); + } + else + { + SCR_DrawRam (); + SCR_DrawNet (); + SCR_DrawTurtle (); + SCR_DrawPause (); + SCR_CheckDrawCenterString (); + Sbar_Draw (); + SCR_DrawConsole (); + M_Draw (); + } + + D_DisableBackBufferAccess (); // for adapters that can't stay mapped in + // for linear writes all the time + if (pconupdate) + { + D_UpdateRects (pconupdate); + } + + V_UpdatePalette (); + +// +// update one of three areas +// + + if (scr_copyeverything) + { + vrect.x = 0; + vrect.y = 0; + vrect.width = vid.width; + vrect.height = vid.height; + vrect.pnext = 0; + + VID_Update (&vrect); + } + else if (scr_copytop) + { + vrect.x = 0; + vrect.y = 0; + vrect.width = vid.width; + vrect.height = vid.height - sb_lines; + vrect.pnext = 0; + + VID_Update (&vrect); + } + else + { + vrect.x = scr_vrect.x; + vrect.y = scr_vrect.y; + vrect.width = scr_vrect.width; + vrect.height = scr_vrect.height; + vrect.pnext = 0; + + VID_Update (&vrect); + } +} + + +/* +================== +SCR_UpdateWholeScreen +================== +*/ +void SCR_UpdateWholeScreen (void) +{ + scr_fullupdate = 0; + SCR_UpdateScreen (); +} diff --git a/contrib/other/sdlquake-1.0.9/screen.h b/contrib/other/sdlquake-1.0.9/screen.h new file mode 100644 index 000000000..845ab55a3 --- /dev/null +++ b/contrib/other/sdlquake-1.0.9/screen.h @@ -0,0 +1,57 @@ +/* +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. + +*/ +// screen.h + +void SCR_Init (void); + +void SCR_UpdateScreen (void); + + +void SCR_SizeUp (void); +void SCR_SizeDown (void); +void SCR_BringDownConsole (void); +void SCR_CenterPrint (char *str); + +void SCR_BeginLoadingPlaque (void); +void SCR_EndLoadingPlaque (void); + +int SCR_ModalMessage (char *text); + +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 +extern qboolean scr_disabled_for_loading; +extern qboolean scr_skipupdate; + +extern cvar_t scr_viewsize; + +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; + +void SCR_UpdateWholeScreen (void); diff --git a/contrib/other/sdlquake-1.0.9/server.h b/contrib/other/sdlquake-1.0.9/server.h new file mode 100644 index 000000000..2d4dfeb06 --- /dev/null +++ b/contrib/other/sdlquake-1.0.9/server.h @@ -0,0 +1,257 @@ +/* +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. + +*/ +// server.h + +typedef struct +{ + int maxclients; + int maxclientslimit; + struct client_s *clients; // [maxclients] + int serverflags; // episode completion information + qboolean changelevel_issued; // cleared when at SV_SpawnServer +} server_static_t; + +//============================================================================= + +typedef enum {ss_loading, ss_active} server_state_t; + +typedef struct +{ + qboolean active; // false if only a net client + + qboolean paused; + qboolean loadgame; // handle connections specially + + double time; + + int lastcheck; // used by PF_checkclient + double lastchecktime; + + char name[64]; // map name +#ifdef QUAKE2 + char startspot[64]; +#endif + 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]; + int num_edicts; + int max_edicts; + edict_t *edicts; // can NOT be array indexed, because + // edict_t is variable sized, but can + // be used to reference the world ent + server_state_t state; // some actions are only valid during load + + sizebuf_t datagram; + byte datagram_buf[MAX_DATAGRAM]; + + sizebuf_t reliable_datagram; // copied to all clients at end of frame + byte reliable_datagram_buf[MAX_DATAGRAM]; + + sizebuf_t signon; + byte signon_buf[8192]; +} server_t; + + +#define NUM_PING_TIMES 16 +#define NUM_SPAWN_PARMS 16 + +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 + // periodically + + struct qsocket_s *netconnection; // communications handle + + usercmd_t cmd; // movement + vec3_t wishdir; // intended motion calced from cmd + + sizebuf_t message; // can be added to at any time, + // copied and clear once per frame + byte msgbuf[MAX_MSGLEN]; + 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 + int old_frags; +} client_t; + + +//============================================================================= + +// edict->movetype values +#define MOVETYPE_NONE 0 // never moves +#define MOVETYPE_ANGLENOCLIP 1 +#define MOVETYPE_ANGLECLIP 2 +#define MOVETYPE_WALK 3 // gravity +#define MOVETYPE_STEP 4 // gravity, special edge handling +#define MOVETYPE_FLY 5 +#define MOVETYPE_TOSS 6 // gravity +#define MOVETYPE_PUSH 7 // no clip to world, push and crush +#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 +#define SOLID_TRIGGER 1 // touch on edge, but not blocking +#define SOLID_BBOX 2 // touch on edge, block +#define SOLID_SLIDEBOX 3 // touch on edge, but not an onground +#define SOLID_BSP 4 // bsp clip, touch on edge, block + +// edict->deadflag values +#define DEAD_NO 0 +#define DEAD_DYING 1 +#define DEAD_DEAD 2 + +#define DAMAGE_NO 0 +#define DAMAGE_YES 1 +#define DAMAGE_AIM 2 + +// edict->flags +#define FL_FLY 1 +#define FL_SWIM 2 +//#define FL_GLIMPSE 4 +#define FL_CONVEYOR 4 +#define FL_CLIENT 8 +#define FL_INWATER 16 +#define FL_MONSTER 32 +#define FL_GODMODE 64 +#define FL_NOTARGET 128 +#define FL_ITEM 256 +#define FL_ONGROUND 512 +#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 + +#define EF_BRIGHTFIELD 1 +#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; +extern cvar_t skill; +extern cvar_t deathmatch; +extern cvar_t coop; +extern cvar_t fraglimit; +extern cvar_t timelimit; + +extern server_static_t svs; // persistant server info +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; + +//=========================================================== + +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, + float attenuation); + +void SV_DropClient (qboolean crash); + +void SV_SendClientMessages (void); +void SV_ClearDatagram (void); + +int SV_ModelIndex (char *name); + +void SV_SetIdealPitch (void); + +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_Physics (void); + +qboolean SV_CheckBottom (edict_t *ent); +qboolean SV_movestep (edict_t *ent, vec3_t move, qboolean relink); + +void SV_WriteClientdataToMessage (edict_t *ent, sizebuf_t *msg); + +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 diff --git a/contrib/other/sdlquake-1.0.9/snd_dma.c b/contrib/other/sdlquake-1.0.9/snd_dma.c new file mode 100644 index 000000000..f17942063 --- /dev/null +++ b/contrib/other/sdlquake-1.0.9/snd_dma.c @@ -0,0 +1,1022 @@ +/* +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_dma.c -- main control for any streaming sound output device + +#include "quakedef.h" + +#ifdef _WIN32 +#include "winquake.h" +#endif + +void S_Play(void); +void S_PlayVol(void); +void S_SoundList(void); +void S_Update_(); +void S_StopAllSounds(qboolean clear); +void S_StopAllSoundsC(void); + +// ======================================================================= +// Internal sound data & structures +// ======================================================================= + +channel_t channels[MAX_CHANNELS]; +int total_channels; + +int snd_blocked = 0; +static qboolean snd_ambient = 1; +qboolean snd_initialized = false; + +// pointer should go away +volatile dma_t *shm = 0; +volatile dma_t sn; + +vec3_t listener_origin; +vec3_t listener_forward; +vec3_t listener_right; +vec3_t listener_up; +vec_t sound_nominal_clip_dist=1000.0; + +int soundtime; // sample PAIRS +int paintedtime; // sample PAIRS + + +#define MAX_SFX 512 +sfx_t *known_sfx; // hunk allocated [MAX_SFX] +int num_sfx; + +sfx_t *ambient_sfx[NUM_AMBIENTS]; + +int desired_speed = 11025; +int desired_bits = 16; + +int sound_started=0; + +cvar_t bgmvolume = {"bgmvolume", "1", true}; +cvar_t volume = {"volume", "0.7", true}; + +cvar_t nosound = {"nosound", "0"}; +cvar_t precache = {"precache", "1"}; +cvar_t loadas8bit = {"loadas8bit", "0"}; +cvar_t bgmbuffer = {"bgmbuffer", "4096"}; +cvar_t ambient_level = {"ambient_level", "0.3"}; +cvar_t ambient_fade = {"ambient_fade", "100"}; +cvar_t snd_noextraupdate = {"snd_noextraupdate", "0"}; +cvar_t snd_show = {"snd_show", "0"}; +cvar_t _snd_mixahead = {"_snd_mixahead", "0.1", true}; + + +// ==================================================================== +// User-setable variables +// ==================================================================== + + +// +// 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. +// + +qboolean fakedma = false; +int fakedma_updates = 15; + + +void S_AmbientOff (void) +{ + snd_ambient = false; +} + + +void S_AmbientOn (void) +{ + snd_ambient = true; +} + + +void S_SoundInfo_f(void) +{ + if (!sound_started || !shm) + { + Con_Printf ("sound system not started\n"); + return; + } + + Con_Printf("%5d stereo\n", shm->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"); + + 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"); + } + + if ( shm ) { + 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); +} + + +// ======================================================================= +// 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) +{ +#ifndef SDL + + 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 (); +#endif /* ! SDL */ +} + +/* +=============================================================================== + +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/contrib/other/sdlquake-1.0.9/snd_dos.c b/contrib/other/sdlquake-1.0.9/snd_dos.c new file mode 100644 index 000000000..bcb93b2d4 --- /dev/null +++ b/contrib/other/sdlquake-1.0.9/snd_dos.c @@ -0,0 +1,653 @@ +/* +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 "dosisms.h" + +int BLASTER_GetDMAPos(void); + +/* +=============================================================================== +GUS SUPPORT + +=============================================================================== +*/ + +qboolean GUS_Init (void); +int GUS_GetDMAPos (void); +void GUS_Shutdown (void); + + +/* +=============================================================================== + +BLASTER SUPPORT + +=============================================================================== +*/ + +short *dma_buffer=0; +static int dma_size; +static int dma; + +static int dsp_port; +static int irq; +static int low_dma; +static int high_dma; +static int mixer_port; +static int mpu401_port; + +int dsp_version; +int dsp_minor_version; + +int timeconstant=-1; + + +void PrintBits (byte b) +{ + int i; + char str[9]; + + for (i=0 ; i<8 ; i++) + str[i] = '0' + ((b & (1<<(7-i))) > 0); + + str[8] = 0; + Con_Printf ("%s (%i)", str, b); +} + +void SB_Info_f(void) +{ + Con_Printf ("BLASTER=%s\n", getenv("BLASTER")); + Con_Printf("dsp version=%d.%d\n", dsp_version, dsp_minor_version); + Con_Printf("dma=%d\n", dma); + if (timeconstant != -1) + Con_Printf("timeconstant=%d\n", timeconstant); + Con_Printf("dma position:%i\n", BLASTER_GetDMAPos ()); +} + +// ======================================================================= +// Interprets BLASTER variable +// ======================================================================= + +int GetBLASTER(void) +{ + char *BLASTER; + char *param; + + BLASTER = getenv("BLASTER"); + if (!BLASTER) + return 0; + + param = strchr(BLASTER, 'A'); + if (!param) + param = strchr(BLASTER, 'a'); + if (!param) + return 0; + sscanf(param+1, "%x", &dsp_port); + + param = strchr(BLASTER, 'I'); + if (!param) + param = strchr(BLASTER, 'i'); + if (!param) + return 0; + sscanf(param+1, "%d", &irq); + + param = strchr(BLASTER, 'D'); + if (!param) + param = strchr(BLASTER, 'd'); + if (!param) + return 0; + sscanf(param+1, "%d", &low_dma); + + param = strchr(BLASTER, 'H'); + if (!param) + param = strchr(BLASTER, 'h'); + if (param) + sscanf(param+1, "%d", &high_dma); + + param = strchr(BLASTER, 'M'); + if (!param) + param = strchr(BLASTER, 'm'); + if (param) + sscanf(param+1, "%x", &mixer_port); + else + mixer_port = dsp_port; + + param = strchr(BLASTER, 'P'); + if (!param) + param = strchr(BLASTER, 'p'); + if (param) + sscanf(param+1, "%x", &mpu401_port); + + return 1; + +} + +// ================================================================== +// Resets DSP. Returns 0 on success. +// ================================================================== + +int ResetDSP(void) +{ + volatile int i; + + dos_outportb(dsp_port + 6, 1); + for (i=65536 ; i ; i--) ; + dos_outportb(dsp_port + 6, 0); + for (i=65536 ; i ; i--) + { + if (!(dos_inportb(dsp_port + 0xe) & 0x80)) continue; + if (dos_inportb(dsp_port + 0xa) == 0xaa) break; + } + if (i) return 0; + else return 1; + +} + +int ReadDSP(void) +{ + while (!(dos_inportb(dsp_port+0xe)&0x80)) ; + return dos_inportb(dsp_port+0xa); +} + +void WriteDSP(int val) +{ + while ((dos_inportb(dsp_port+0xc)&0x80)) ; + dos_outportb(dsp_port+0xc, val); +} + +int ReadMixer(int addr) +{ + dos_outportb(mixer_port+4, addr); + return dos_inportb(mixer_port+5); +} + +void WriteMixer(int addr, int val) +{ + dos_outportb(mixer_port+4, addr); + dos_outportb(mixer_port+5, val); +} + +int oldmixervalue; + +/* +================ +StartSB + +================ +*/ +void StartSB(void) +{ + int i; + +// version 4.xx startup code + if (dsp_version >= 4) + { + Con_Printf("Version 4 SB startup\n"); + WriteDSP(0xd1); // turn on speaker + + WriteDSP(0x41); + + WriteDSP(shm->speed>>8); + WriteDSP(shm->speed&0xff); + + WriteDSP(0xb6); // 16-bit output + WriteDSP(0x30); // stereo + WriteDSP((shm->samples-1) & 0xff); // # of samples - 1 + WriteDSP((shm->samples-1) >> 8); + } +// version 3.xx startup code + else if (dsp_version == 3) + { + Con_Printf("Version 3 SB startup\n"); + WriteDSP(0xd1); // turn on speaker + + oldmixervalue = ReadMixer (0xe); + WriteMixer (0xe, oldmixervalue | 0x2);// turn on stereo + + WriteDSP(0x14); // send one byte + WriteDSP(0x0); + WriteDSP(0x0); + + for (i=0 ; i<0x10000 ; i++) + dos_inportb(dsp_port+0xe); // ack the dsp + + timeconstant = 65536-(256000000/(shm->channels*shm->speed)); + WriteDSP(0x40); + WriteDSP(timeconstant>>8); + + WriteMixer (0xe, ReadMixer(0xe) | 0x20);// turn off filter + + WriteDSP(0x48); + WriteDSP((shm->samples-1) & 0xff); // # of samples - 1 + WriteDSP((shm->samples-1) >> 8); + + WriteDSP(0x90); // high speed 8 bit stereo + } +// normal speed mono + else + { + Con_Printf("Version 2 SB startup\n"); + WriteDSP(0xd1); // turn on speaker + + timeconstant = 65536-(256000000/(shm->channels*shm->speed)); + WriteDSP(0x40); + WriteDSP(timeconstant>>8); + + WriteDSP(0x48); + WriteDSP((shm->samples-1) & 0xff); // # of samples - 1 + WriteDSP((shm->samples-1) >> 8); + + WriteDSP(0x1c); // normal speed 8 bit mono + } +} + +static int page_reg[] = { 0x87, 0x83, 0x81, 0x82, 0x8f, 0x8b, 0x89, 0x8a }; +static int addr_reg[] = { 0, 2, 4, 6, 0xc0, 0xc4, 0xc8, 0xcc }; +static int count_reg[] = { 1, 3, 5, 7, 0xc2, 0xc6, 0xca, 0xce }; + +static int mode_reg; +static int flipflop_reg; +static int disable_reg; +static int clear_reg; + +/* +================ +StartDMA + +================ +*/ +void StartDMA(void) +{ + int mode; + int realaddr; + + realaddr = ptr2real(dma_buffer); + +// use a high dma channel if specified + if (high_dma && dsp_version >= 4) // 8 bit snd can never use 16 bit dma + dma = high_dma; + else + dma = low_dma; + + Con_Printf ("Using DMA channel %i\n", dma); + + if (dma > 3) + { + mode_reg = 0xd6; + flipflop_reg = 0xd8; + disable_reg = 0xd4; + clear_reg = 0xdc; + } + else + { + mode_reg = 0xb; + flipflop_reg = 0xc; + disable_reg = 0xa; + clear_reg = 0xe; + } + + dos_outportb(disable_reg, dma|4); // disable channel + // set mode- see "undocumented pc", p.876 + mode = (1<<6) // single-cycle + +(0<<5) // address increment + +(1<<4) // auto-init dma + +(2<<2) // read + +(dma&3); // channel # + dos_outportb(mode_reg, mode); + +// set address + // set page + dos_outportb(page_reg[dma], realaddr >> 16); + + if (dma > 3) + { // address is in words + dos_outportb(flipflop_reg, 0); // prepare to send 16-bit value + dos_outportb(addr_reg[dma], (realaddr>>1) & 0xff); + dos_outportb(addr_reg[dma], (realaddr>>9) & 0xff); + + dos_outportb(flipflop_reg, 0); // prepare to send 16-bit value + dos_outportb(count_reg[dma], ((dma_size>>1)-1) & 0xff); + dos_outportb(count_reg[dma], ((dma_size>>1)-1) >> 8); + } + else + { // address is in bytes + dos_outportb(flipflop_reg, 0); // prepare to send 16-bit value + dos_outportb(addr_reg[dma], realaddr & 0xff); + dos_outportb(addr_reg[dma], (realaddr>>8) & 0xff); + + dos_outportb(flipflop_reg, 0); // prepare to send 16-bit value + dos_outportb(count_reg[dma], (dma_size-1) & 0xff); + dos_outportb(count_reg[dma], (dma_size-1) >> 8); + } + + dos_outportb(clear_reg, 0); // clear write mask + dos_outportb(disable_reg, dma&~4); +} + + +/* +================== +BLASTER_Init + +Returns false if nothing is found. +================== +*/ +qboolean BLASTER_Init(void) +{ + int size; + int realaddr; + int rc; + int p; + + shm = 0; + rc = 0; + +// +// must have a blaster variable set +// + if (!GetBLASTER()) + { + Con_NotifyBox ( + "The BLASTER environment variable\n" + "is not set, sound effects are\n" + "disabled. See README.TXT for help.\n" + ); + return 0; + } + + if (ResetDSP()) + { + Con_Printf("Could not reset SB"); + return 0; + } + +// +// get dsp version +// + WriteDSP(0xe1); + dsp_version = ReadDSP(); + dsp_minor_version = ReadDSP(); + +// we need at least v2 for auto-init dma + if (dsp_version < 2) + { + Con_Printf ("Sound blaster must be at least v2.0\n"); + return 0; + } + +// allow command line parm to set quality down + p = COM_CheckParm ("-dsp"); + if (p && p < com_argc - 1) + { + p = Q_atoi (com_argv[p+1]); + if (p < 2 || p > 4) + Con_Printf ("-dsp parameter can only be 2, 3, or 4\n"); + else if (p > dsp_version) + Con_Printf ("Can't -dsp %i on v%i hardware\n", p, dsp_version); + else + dsp_version = p; + } + + +// everyone does 11khz sampling rate unless told otherwise + shm = &sn; + shm->speed = 11025; + rc = COM_CheckParm("-sspeed"); + if (rc) + shm->speed = Q_atoi(com_argv[rc+1]); + +// version 4 cards (sb 16) do 16 bit stereo + if (dsp_version >= 4) + { + shm->channels = 2; + shm->samplebits = 16; + } +// version 3 cards (sb pro) do 8 bit stereo + else if (dsp_version == 3) + { + shm->channels = 2; + shm->samplebits = 8; + } +// v2 cards do 8 bit mono + else + { + shm->channels = 1; + shm->samplebits = 8; + } + + + Cmd_AddCommand("sbinfo", SB_Info_f); + size = 4096; + +// allocate 8k and get a 4k-aligned buffer from it + dma_buffer = dos_getmemory(size*2); + if (!dma_buffer) + { + Con_Printf("Couldn't allocate sound dma buffer"); + return false; + } + + realaddr = ptr2real(dma_buffer); + realaddr = (realaddr + size) & ~(size-1); + dma_buffer = (short *) real2ptr(realaddr); + dma_size = size; + + memset(dma_buffer, 0, dma_size); + + shm->soundalive = true; + shm->splitbuffer = false; + + shm->samples = size/(shm->samplebits/8); + shm->samplepos = 0; + shm->submission_chunk = 1; + shm->buffer = (unsigned char *) dma_buffer; + shm->samples = size/(shm->samplebits/8); + + StartDMA(); + StartSB(); + + return true; +} + + +/* +============== +BLASTER_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 BLASTER_GetDMAPos(void) +{ + int count; + +// this function is called often. acknowledge the transfer completions +// all the time so that it loops + if (dsp_version >= 4) + dos_inportb(dsp_port+0xf); // 16 bit audio + else + dos_inportb(dsp_port+0xe); // 8 bit audio + +// clear 16-bit reg flip-flop +// load the current dma count register + if (dma < 4) + { + dos_outportb(0xc, 0); + count = dos_inportb(dma*2+1); + count += dos_inportb(dma*2+1) << 8; + if (shm->samplebits == 16) + count /= 2; + count = shm->samples - (count+1); + } + else + { + dos_outportb(0xd8, 0); + count = dos_inportb(0xc0+(dma-4)*4+2); + count += dos_inportb(0xc0+(dma-4)*4+2) << 8; + if (shm->samplebits == 8) + count *= 2; + count = shm->samples - (count+1); + } + +// Con_Printf("DMA pos = 0x%x\n", count); + + shm->samplepos = count & (shm->samples-1); + return shm->samplepos; + +} + +/* +============== +BLASTER_Shutdown + +Reset the sound device for exiting +=============== +*/ +void BLASTER_Shutdown(void) +{ + if (dsp_version >= 4) + { + } + else if (dsp_version == 3) + { + ResetDSP (); // stop high speed mode + WriteMixer (0xe, oldmixervalue); // turn stereo off and filter on + } + else + { + + } + + WriteDSP(0xd3); // turn off speaker + ResetDSP (); + + dos_outportb(disable_reg, dma|4); // disable dma channel +} + + + +/* +=============================================================================== + +INTERFACE + +=============================================================================== +*/ + +typedef enum +{ + dma_none, + dma_blaster, + dma_gus +} dmacard_t; + +dmacard_t dmacard; + +/* +================== +SNDDM_Init + +Try to find a sound device to mix for. +Returns false if nothing is found. +Returns true and fills in the "shm" structure with information for the mixer. +================== +*/ +qboolean SNDDMA_Init(void) +{ + if (GUS_Init ()) + { + dmacard = dma_gus; + return true; + } + if (BLASTER_Init ()) + { + dmacard = dma_blaster; + return true; + } + + dmacard = dma_none; + + return false; +} + + +/* +============== +SNDDMA_GetDMAPos + +return the current sample position (in mono samples, not stereo) +inside the recirculating dma buffer, so the mixing code will know +how many sample are required to fill it up. +=============== +*/ +int SNDDMA_GetDMAPos(void) +{ + switch (dmacard) + { + case dma_blaster: + return BLASTER_GetDMAPos (); + case dma_gus: + return GUS_GetDMAPos (); + case dma_none: + break; + } + + return 0; +} + +/* +============== +SNDDMA_Shutdown + +Reset the sound device for exiting +=============== +*/ +void SNDDMA_Shutdown(void) +{ + switch (dmacard) + { + case dma_blaster: + BLASTER_Shutdown (); + break; + case dma_gus: + GUS_Shutdown (); + break; + case dma_none: + break; + } + + dmacard = dma_none; + return; +} + +/* +============== +SNDDMA_Submit + +Send sound to device if buffer isn't really the dma buffer +=============== +*/ +void SNDDMA_Submit(void) +{ +} + diff --git a/contrib/other/sdlquake-1.0.9/snd_gus.c b/contrib/other/sdlquake-1.0.9/snd_gus.c new file mode 100644 index 000000000..dd1376f77 --- /dev/null +++ b/contrib/other/sdlquake-1.0.9/snd_gus.c @@ -0,0 +1,1293 @@ +/* +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. + +*/ +//============================================================================= +// Routines for GUS support in QUAKE +// +// Author(s): Jayeson Lee-Steere +//============================================================================= + +#include "quakedef.h" +#include "dosisms.h" + +//============================================================================= +// Author(s): Jayeson Lee-Steere + +#define INI_STRING_SIZE 0x100 + +FILE *ini_fopen(const char *filename, const char *modes); +int ini_fclose(FILE *f); +void ini_fgets(FILE *f, const char *section, const char *field, char *s); + +// Routines for reading from .INI files +// The read routines are fairly efficient. +// +// Author(s): Jayeson Lee-Steere + +#define MAX_SECTION_WIDTH 20 +#define MAX_FIELD_WIDTH 20 + +#define NUM_SECTION_BUFFERS 10 +#define NUM_FIELD_BUFFERS 20 + +struct section_buffer +{ + long offset; + char name[MAX_SECTION_WIDTH+1]; +}; + +struct field_buffer +{ + long offset; + int section; + char name[MAX_FIELD_WIDTH+1]; +}; + +static FILE *current_file=NULL; +static int current_section; + +static int current_section_buffer=0; +static int current_field_buffer=0; + +static struct section_buffer section_buffers[NUM_SECTION_BUFFERS]; +static struct field_buffer field_buffers[NUM_FIELD_BUFFERS]; +//*************************************************************************** +// Internal routines +//*************************************************************************** +static char toupper(char c) +{ + if (c>='a' && c<='z') + c-=('a'-'A'); + return(c); +} + +static void reset_buffer(FILE *f) +{ + int i; + + for (i=0;i0 && out[i-1]==' ') + i--; + // Null terminate the output string. + out[i]=0; +} + +// Extracts the field name from a field line +// e.g. in="sooty=life be in it" gives out="sooty" +static void get_field_name(char *out, char *in) +{ + int i=0; + + // Skip leading spaces + while (in[0]==' ') + in++; + // Copy name to output string + while (in[0]!='=' && in[0]!=13 && in[0]!=10 && in[0]!=0) + { + if (iNUM_SECTION_BUFFERS) + current_section_buffer=0; + // Delete any field buffers that correspond to this section + for (i=0;iNUM_FIELD_BUFFERS) + current_field_buffer=0; + // Set buffer information + strcpy(field_buffers[current_field_buffer].name,field); + field_buffers[current_field_buffer].section=section; + field_buffers[current_field_buffer].offset=offset; +} + +// Identical to fgets except the string is trucated at the first ';', +// carriage return or line feed. +static char *stripped_fgets(char *s, int n, FILE *f) +{ + int i=0; + + if (fgets(s,n,f)==NULL) + return(NULL); + + while (s[i]!=';' && s[i]!=13 && s[i]!=10 && s[i]!=0) + i++; + s[i]=0; + + return(s); +} + +//*************************************************************************** +// Externally accessable routines +//*************************************************************************** +// Opens an .INI file. Works like fopen +FILE *ini_fopen(const char *filename, const char *modes) +{ + return(fopen(filename,modes)); +} + +// Closes a .INI file. Works like fclose +int ini_fclose(FILE *f) +{ + if (f==current_file) + reset_buffer(NULL); + return(fclose(f)); +} + +// Puts "field" from "section" from .ini file "f" into "s". +// If "section" does not exist or "field" does not exist in +// section then s=""; +void ini_fgets(FILE *f, const char *section, const char *field, char *s) +{ + int i; + long start_pos,string_start_pos; + char ts[INI_STRING_SIZE*2]; + + if (f!=current_file) + reset_buffer(f); + + // Default to "Not found" + s[0]=0; + + // See if section is in buffer + for (i=0;i>1) & 0x0001FFFF) | (Address & 0x000C0000L) ); +} + +void ClearGf1Ints(void) +{ + int i; + + SetGf18(DMA_CONTROL,0x00); + SetGf18(ADLIB_CONTROL,0x00); + SetGf18(RECORD_CONTROL,0x00); + + GetGf18(DMA_CONTROL); + GetGf18(RECORD_CONTROL); + for (i=0;i<32;i++); + GetGf18(GET_IRQV); +} + + +//============================================================================= +// Get Interwave (UltraSound PnP) configuration if any +//============================================================================= +static qboolean GUS_GetIWData(void) +{ + char *Interwave,s[INI_STRING_SIZE]; + FILE *IwFile; + int CodecBase,CodecDma,i; + + Interwave=getenv("INTERWAVE"); + if (Interwave==NULL) + return(false); + + // Open IW.INI + IwFile=ini_fopen(Interwave,"rt"); + if (IwFile==NULL) + return(false); + + // Read codec base and codec DMA + ini_fgets(IwFile,"setup 0","CodecBase",s); + sscanf(s,"%X",&CodecBase); + ini_fgets(IwFile,"setup 0","DMA2",s); + sscanf(s,"%i",&CodecDma); + + ini_fclose(IwFile); + + // Make sure numbers OK + if (CodecBase==0 || CodecDma==0) + return(false); + + CodecRegisterSelect=CodecBase; + CodecData=CodecBase+1; + CodecStatus=CodecBase+2; + DmaChannel=CodecDma; + + // Make sure there is a CODEC at the CODEC base + + // Clear any pending IRQs + dos_inportb(CodecStatus); + dos_outportb(CodecStatus,0); + + // Wait for 'INIT' bit to clear + for (i=0;i<0xFFFF;i++) + if ((dos_inportb(CodecRegisterSelect) & 0x80) == 0) + break; + if (i==0xFFFF) + return(false); + + // Get chip revision - can not be zero + dos_outportb(CodecRegisterSelect,CODEC_MODE_AND_ID); + if ((dos_inportb(CodecRegisterSelect) & 0x7F) != CODEC_MODE_AND_ID) + return(false); + if ((dos_inportb(CodecData) & 0x0F) == 0) + return(false); + + HaveCodec=1; + Con_Printf("Sound Card is UltraSound PnP\n"); + return(true); +} + +//============================================================================= +// Get UltraSound MAX configuration if any +//============================================================================= +static qboolean GUS_GetMAXData(void) +{ + char *Ultrasnd,*Ultra16; + int i; + int GusBase,Dma1,Dma2,Irq1,Irq2; + int CodecBase,CodecDma,CodecIrq,CodecType; + BYTE MaxVal; + + Ultrasnd=getenv("ULTRASND"); + Ultra16=getenv("ULTRA16"); + if (Ultrasnd==NULL || Ultra16==NULL) + return(false); + + sscanf(Ultrasnd,"%x,%i,%i,%i,%i",&GusBase,&Dma1,&Dma2,&Irq1,&Irq2); + sscanf(Ultra16,"%x,%i,%i,%i",&CodecBase,&CodecDma,&CodecIrq,&CodecType); + + if (CodecType==0 && CodecDma!=0) + DmaChannel=CodecDma & 0x07; + else + DmaChannel=Dma2 & 0x07; + + // Make sure there is a GUS at GUS base + dos_outportb(GusBase+0x08,0x55); + if (dos_inportb(GusBase+0x0A)!=0x55) + return(false); + dos_outportb(GusBase+0x08,0xAA); + if (dos_inportb(GusBase+0x0A)!=0xAA) + return(false); + + // Program CODEC control register + MaxVal=((CodecBase & 0xF0)>>4) | 0x40; + if (Dma1 > 3) + MaxVal|=0x10; + if (Dma2 > 3) + MaxVal|=0x20; + dos_outportb(GusBase+0x106,MaxVal); + + CodecRegisterSelect=CodecBase; + CodecData=CodecBase+1; + CodecStatus=CodecBase+2; + + // Make sure there is a CODEC at the CODEC base + + // Clear any pending IRQs + dos_inportb(CodecStatus); + dos_outportb(CodecStatus,0); + + // Wait for 'INIT' bit to clear + for (i=0;i<0xFFFF;i++) + if ((dos_inportb(CodecRegisterSelect) & 0x80) == 0) + break; + if (i==0xFFFF) + return(false); + + // Get chip revision - can not be zero + dos_outportb(CodecRegisterSelect,CODEC_MODE_AND_ID); + if ((dos_inportb(CodecRegisterSelect) & 0x7F) != CODEC_MODE_AND_ID) + return(false); + if ((dos_inportb(CodecData) & 0x0F) == 0) + return(false); + + HaveCodec=1; + Con_Printf("Sound Card is UltraSound MAX\n"); + return(true); +} + +//============================================================================= +// Get regular UltraSound configuration if any +//============================================================================= +static qboolean GUS_GetGUSData(void) +{ + char *Ultrasnd; + int GusBase,Dma1,Dma2,Irq1,Irq2,i; + + Ultrasnd=getenv("ULTRASND"); + if (Ultrasnd==NULL) + return(false); + + sscanf(Ultrasnd,"%x,%i,%i,%i,%i",&GusBase,&Dma1,&Dma2,&Irq1,&Irq2); + + DmaChannel=Dma1 & 0x07; + + // Make sure there is a GUS at GUS base + dos_outportb(GusBase+0x08,0x55); + if (dos_inportb(GusBase+0x0A)!=0x55) + return(false); + dos_outportb(GusBase+0x08,0xAA); + if (dos_inportb(GusBase+0x0A)!=0xAA) + return(false); + + Gf1TimerControl = GusBase+0x008; + Gf1PageRegister = GusBase+0x102; + Gf1RegisterSelect = GusBase+0x103; + Gf1DataLow = GusBase+0x104; + Gf1DataHigh = GusBase+0x105; + + // Reset the GUS + SetGf18(MASTER_RESET,0x00); + Gf1Delay(); + Gf1Delay(); + SetGf18(MASTER_RESET,0x01); + Gf1Delay(); + Gf1Delay(); + + // Set to max (32) voices + SetGf18(SET_VOICES,0xDF); + + // Clear any pending IRQ's + ClearGf1Ints(); + + // Set all registers to known values + for (i=0;i<32;i++) + { + dos_outportb(Gf1PageRegister,i); + SetGf18(SET_CONTROL,0x03); + SetGf18(SET_VOLUME_CONTROL,0x03); + Gf1Delay(); + SetGf18(SET_CONTROL,0x03); + SetGf18(SET_VOLUME_CONTROL,0x03); + SetGf116(SET_START_HIGH,0); + SetGf116(SET_START_LOW,0); + SetGf116(SET_END_HIGH,0); + SetGf116(SET_END_LOW,0); + SetGf116(SET_ACC_HIGH,0); + SetGf116(SET_ACC_LOW,0); + SetGf18(SET_VOLUME_RATE,63); + SetGf18(SET_VOLUME_START,5); + SetGf18(SET_VOLUME_END,251); + SetGf116(SET_VOLUME,5<<8); + } + + // Clear any pending IRQ's + ClearGf1Ints(); + + // Enable DAC etc. + SetGf18(MASTER_RESET,0x07); + + // Enable line output so we can hear something + dos_outportb(GusBase,0x08); + + HaveCodec=0; + Con_Printf("Sound Card is UltraSound\n"); + return(true); +} + + +//============================================================================= +// Programs the DMA controller to start DMAing in Auto-init mode +//============================================================================= +static void GUS_StartDMA(BYTE DmaChannel,short *dma_buffer,int count) +{ + int mode; + int RealAddr; + + RealAddr = ptr2real(dma_buffer); + + if (DmaChannel <= 3) + { + ModeReg = 0x0B; + DisableReg = 0x0A; + ClearReg = 0x0E; + } + else + { + ModeReg = 0xD6; + DisableReg = 0xD4; + ClearReg = 0xDC; + } + CountReg=CountRegs[DmaChannel]; + AddrReg=AddrRegs[DmaChannel]; + + dos_outportb(DisableReg, DmaChannel | 4); // disable channel + + // set mode- see "undocumented pc", p.876 + mode = (1<<6) // single-cycle + +(0<<5) // address increment + +(1<<4) // auto-init dma + +(2<<2) // read + +(DmaChannel & 0x03); // channel # + dos_outportb(ModeReg, mode); + + // set page + dos_outportb(PageRegs[DmaChannel], RealAddr >> 16); + + if (DmaChannel <= 3) + { // address is in bytes + dos_outportb(0x0C, 0); // prepare to send 16-bit value + dos_outportb(AddrReg, RealAddr & 0xff); + dos_outportb(AddrReg, (RealAddr>>8) & 0xff); + + dos_outportb(0x0C, 0); // prepare to send 16-bit value + dos_outportb(CountReg, (count-1) & 0xff); + dos_outportb(CountReg, (count-1) >> 8); + } + else + { // address is in words + dos_outportb(0xD8, 0); // prepare to send 16-bit value + dos_outportb(AddrReg, (RealAddr>>1) & 0xff); + dos_outportb(AddrReg, (RealAddr>>9) & 0xff); + + dos_outportb(0xD8, 0); // prepare to send 16-bit value + dos_outportb(CountReg, ((count>>1)-1) & 0xff); + dos_outportb(CountReg, ((count>>1)-1) >> 8); + } + + dos_outportb(ClearReg, 0); // clear write mask + dos_outportb(DisableReg, DmaChannel & ~4); +} + +//============================================================================= +// Starts the CODEC playing +//============================================================================= +static void GUS_StartCODEC(int count,BYTE FSVal) +{ + int i,j; + + // Clear any pending IRQs + dos_inportb(CodecStatus); + dos_outportb(CodecStatus,0); + + // Set mode to 2 + dos_outportb(CodecRegisterSelect,CODEC_MODE_AND_ID); + dos_outportb(CodecData,0xC0); + + // Stop any playback or capture which may be happening + dos_outportb(CodecRegisterSelect,CODEC_INTERFACE_CONFIG); + dos_outportb(CodecData,dos_inportb(CodecData) & 0xFC); + + // Set FS + dos_outportb(CodecRegisterSelect,CODEC_FS_FORMAT | 0x40); + dos_outportb(CodecData,FSVal | 0x50); // Or in stereo and 16 bit bits + + // Wait a bit + for (i=0;i<10;i++) + dos_inportb(CodecData); + + // Routine 1 to counter CODEC bug - wait for init bit to clear and then a + // bit longer (i=min loop count, j=timeout + for (i=0,j=0;i<1000 && j<0x7FFFF;j++) + if ((dos_inportb(CodecRegisterSelect) & 0x80)==0) + i++; + + // Routine 2 to counter CODEC bug - this is from Forte's code. For me it + // does not seem to cure the problem, but is added security + // Waits till we can modify index register + for (j=0;j<0x7FFFF;j++) + { + dos_outportb(CodecRegisterSelect,CODEC_INTERFACE_CONFIG | 0x40); + if (dos_inportb(CodecRegisterSelect)==(CODEC_INTERFACE_CONFIG | 0x40)) + break; + } + + // Perform ACAL + dos_outportb(CodecRegisterSelect,CODEC_INTERFACE_CONFIG | 0x40); + dos_outportb(CodecData,0x08); + + // Clear MCE bit - this makes ACAL happen + dos_outportb(CodecRegisterSelect,CODEC_INTERFACE_CONFIG); + + // Wait for ACAL to finish + for (j=0;j<0x7FFFF;j++) + { + if ((dos_inportb(CodecRegisterSelect) & 0x80) != 0) + continue; + dos_outportb(CodecRegisterSelect,CODEC_ERROR_STATUS_AND_INIT); + if ((dos_inportb(CodecData) & 0x20) == 0) + break; + } + + // Clear ACAL bit + dos_outportb(CodecRegisterSelect,CODEC_INTERFACE_CONFIG | 0x40); + dos_outportb(CodecData,0x00); + dos_outportb(CodecRegisterSelect,CODEC_INTERFACE_CONFIG); + + // Set some other junk + dos_outportb(CodecRegisterSelect,CODEC_LOOPBACK_CONTROL); + dos_outportb(CodecData,0x00); + dos_outportb(CodecRegisterSelect,CODEC_PIN_CONTROL); + dos_outportb(CodecData,0x08); // IRQ is disabled in PIN control + + // Set count (it doesn't really matter what value we stuff in here + dos_outportb(CodecRegisterSelect,CODEC_PLAYBACK_LOWER_BASE_COUNT); + dos_outportb(CodecData,count & 0xFF); + dos_outportb(CodecRegisterSelect,CODEC_PLAYBACK_UPPER_BASE_COUNT); + dos_outportb(CodecData,count >> 8); + + // Start playback + dos_outportb(CodecRegisterSelect,CODEC_INTERFACE_CONFIG); + dos_outportb(CodecData,0x01); +} + +//============================================================================= +// Starts the GF1 playing +//============================================================================= +static void GUS_StartGf1(int count,BYTE Voices) +{ + DWORD StartAddressL,EndAddressL,StartAddressR,EndAddressR; + + // Set number of voices to give us the sampling rate we want + SetGf18(SET_VOICES,0xC0 | (Voices-1)); + + // Figure out addresses + StartAddressL=ConvertTo16(0); + EndAddressL=ConvertTo16(count-2-2); + StartAddressR=ConvertTo16(2); + EndAddressR=ConvertTo16(count-2); + + // Set left voice addresses + dos_outportb(Gf1PageRegister,0); + SetGf116(SET_START_LOW,StartAddressL<<9); + SetGf116(SET_START_HIGH,StartAddressL>>7); + SetGf116(SET_ACC_LOW,StartAddressL<<9); + SetGf116(SET_ACC_HIGH,StartAddressL>>7); + SetGf116(SET_END_LOW,EndAddressL<<9); + SetGf116(SET_END_HIGH,EndAddressL>>7); + // Set balance to full left + SetGf18(SET_BALANCE,0); + // Set volume to full + SetGf116(SET_VOLUME,0xFFF0); + // Set FC to 2 (so we play every second sample) + SetGf116(SET_FREQUENCY,0x0800); + + // Set right voice addresses + dos_outportb(Gf1PageRegister,1); + SetGf116(SET_START_LOW,StartAddressR<<9); + SetGf116(SET_START_HIGH,StartAddressR>>7); + SetGf116(SET_ACC_LOW,StartAddressR<<9); + SetGf116(SET_ACC_HIGH,StartAddressR>>7); + SetGf116(SET_END_LOW,EndAddressR<<9); + SetGf116(SET_END_HIGH,EndAddressR>>7); + // Set balance to full right + SetGf18(SET_BALANCE,15); + // Set volume to full + SetGf116(SET_VOLUME,0xFFF0); + // Set FC to 2 (so we play every second sample) + SetGf116(SET_FREQUENCY,0x0800); + + // Start voices + dos_outportb(Gf1PageRegister,0); + SetGf18(SET_CONTROL,0x0C); + dos_outportb(Gf1PageRegister,1); + SetGf18(SET_CONTROL,0x0C); + Gf1Delay(); + dos_outportb(Gf1PageRegister,0); + SetGf18(SET_CONTROL,0x0C); + dos_outportb(Gf1PageRegister,1); + SetGf18(SET_CONTROL,0x0C); +} + + +//============================================================================= +// Figures out what kind of UltraSound we have, if any, and starts it playing +//============================================================================= +qboolean GUS_Init(void) +{ + int rc; + int RealAddr; + BYTE FSVal,Voices; + struct CodecRateStruct *CodecRate; + struct Gf1RateStruct *Gf1Rate; + + // See what kind of UltraSound we have, if any + if (GUS_GetIWData()==false) + if (GUS_GetMAXData()==false) + if (GUS_GetGUSData()==false) + return(false); + + shm = &sn; + + if (HaveCodec) + { + // do 11khz sampling rate unless command line parameter wants different + shm->speed = 11025; + FSVal = 0x03; + rc = COM_CheckParm("-sspeed"); + if (rc) + { + shm->speed = Q_atoi(com_argv[rc+1]); + + // Make sure rate not too high + if (shm->speed>48000) + shm->speed=48000; + + // Adjust speed to match one of the possible CODEC rates + for (CodecRate=CodecRates;CodecRate->Rate!=0;CodecRate++) + { + if (shm->speed <= CodecRate->Rate) + { + shm->speed=CodecRate->Rate; + FSVal=CodecRate->FSVal; + break; + } + } + } + + + // Always do 16 bit stereo + shm->channels = 2; + shm->samplebits = 16; + + // allocate buffer twice the size we need so we can get aligned buffer + dma_buffer = dos_getmemory(BUFFER_SIZE*2); + if (dma_buffer==NULL) + { + Con_Printf("Couldn't allocate sound dma buffer"); + return false; + } + + RealAddr = ptr2real(dma_buffer); + RealAddr = (RealAddr + BUFFER_SIZE) & ~(BUFFER_SIZE-1); + dma_buffer = (short *) real2ptr(RealAddr); + + // Zero off DMA buffer + memset(dma_buffer, 0, BUFFER_SIZE); + + shm->soundalive = true; + shm->splitbuffer = false; + + shm->samplepos = 0; + shm->submission_chunk = 1; + shm->buffer = (unsigned char *) dma_buffer; + shm->samples = BUFFER_SIZE/(shm->samplebits/8); + + GUS_StartDMA(DmaChannel,dma_buffer,BUFFER_SIZE); + GUS_StartCODEC(BUFFER_SIZE,FSVal); + } + else + { + // do 19khz sampling rate unless command line parameter wants different + shm->speed = 19293; + Voices=32; + rc = COM_CheckParm("-sspeed"); + if (rc) + { + shm->speed = Q_atoi(com_argv[rc+1]); + + // Make sure rate not too high + if (shm->speed>44100) + shm->speed=44100; + + // Adjust speed to match one of the possible GF1 rates + for (Gf1Rate=Gf1Rates;Gf1Rate->Rate!=0;Gf1Rate++) + { + if (shm->speed <= Gf1Rate->Rate) + { + shm->speed=Gf1Rate->Rate; + Voices=Gf1Rate->Voices; + break; + } + } + } + + // Always do 16 bit stereo + shm->channels = 2; + shm->samplebits = 16; + + // allocate buffer twice the size we need so we can get aligned buffer + dma_buffer = dos_getmemory(BUFFER_SIZE*2); + if (dma_buffer==NULL) + { + Con_Printf("Couldn't allocate sound dma buffer"); + return false; + } + + RealAddr = ptr2real(dma_buffer); + RealAddr = (RealAddr + BUFFER_SIZE) & ~(BUFFER_SIZE-1); + dma_buffer = (short *) real2ptr(RealAddr); + + // Zero off DMA buffer + memset(dma_buffer, 0, BUFFER_SIZE); + + shm->soundalive = true; + shm->splitbuffer = false; + + shm->samplepos = 0; + shm->submission_chunk = 1; + shm->buffer = (unsigned char *) dma_buffer; + shm->samples = BUFFER_SIZE/(shm->samplebits/8); + + GUS_StartDMA(DmaChannel,dma_buffer,BUFFER_SIZE); + SetGf116(SET_DMA_ADDRESS,0x0000); + if (DmaChannel<=3) + SetGf18(DMA_CONTROL,0x41); + else + SetGf18(DMA_CONTROL,0x45); + GUS_StartGf1(BUFFER_SIZE,Voices); + } + return(true); +} + +//============================================================================= +// Returns the current playback position +//============================================================================= +int GUS_GetDMAPos(void) +{ + int count; + + if (HaveCodec) + { + // clear 16-bit reg flip-flop + // load the current dma count register + if (DmaChannel < 4) + { + dos_outportb(0x0C, 0); + count = dos_inportb(CountReg); + count += dos_inportb(CountReg) << 8; + if (shm->samplebits == 16) + count /= 2; + count = shm->samples - (count+1); + } + else + { + dos_outportb(0xD8, 0); + count = dos_inportb(CountReg); + count += dos_inportb(CountReg) << 8; + if (shm->samplebits == 8) + count *= 2; + count = shm->samples - (count+1); + } + + } + else + { + // Read current position from GF1 + dos_outportb(Gf1PageRegister,0); + count=(GetGf116(GET_ACC_HIGH)<<7) & 0xFFFF; + // See which half of buffer we are in. Note that since this is 16 bit + // data we are playing, position is in 16 bit samples + if (GetGf18(DMA_CONTROL) & 0x40) + { + GUS_StartDMA(DmaChannel,dma_buffer,BUFFER_SIZE); + SetGf116(SET_DMA_ADDRESS,0x0000); + if (DmaChannel<=3) + SetGf18(DMA_CONTROL,0x41); + else + SetGf18(DMA_CONTROL,0x45); + } + } + + shm->samplepos = count & (shm->samples-1); + return(shm->samplepos); +} + +//============================================================================= +// Stops the UltraSound playback +//============================================================================= +void GUS_Shutdown (void) +{ + if (HaveCodec) + { + // Stop CODEC + dos_outportb(CodecRegisterSelect,CODEC_INTERFACE_CONFIG); + dos_outportb(CodecData,0x01); + } + else + { + // Stop Voices + dos_outportb(Gf1PageRegister,0); + SetGf18(SET_CONTROL,0x03); + dos_outportb(Gf1PageRegister,1); + SetGf18(SET_CONTROL,0x03); + Gf1Delay(); + dos_outportb(Gf1PageRegister,0); + SetGf18(SET_CONTROL,0x03); + dos_outportb(Gf1PageRegister,1); + SetGf18(SET_CONTROL,0x03); + + // Stop any DMA + SetGf18(DMA_CONTROL,0x00); + GetGf18(DMA_CONTROL); + } + + dos_outportb(DisableReg, DmaChannel | 4); // disable dma channel +} diff --git a/contrib/other/sdlquake-1.0.9/snd_linux.c b/contrib/other/sdlquake-1.0.9/snd_linux.c new file mode 100644 index 000000000..4579e40d6 --- /dev/null +++ b/contrib/other/sdlquake-1.0.9/snd_linux.c @@ -0,0 +1,269 @@ +/* +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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "quakedef.h" + +int audio_fd; +int snd_inited; + +static int tryrates[] = { 11025, 22051, 44100, 8000 }; + +qboolean SNDDMA_Init(void) +{ + + int rc; + int fmt; + int tmp; + int i; + char *s; + struct audio_buf_info info; + int caps; + + snd_inited = 0; + +// open /dev/dsp, confirm capability to mmap, and get size of dma buffer + + audio_fd = open("/dev/dsp", O_RDWR); + if (audio_fd < 0) + { + perror("/dev/dsp"); + Con_Printf("Could not open /dev/dsp\n"); + return 0; + } + + rc = ioctl(audio_fd, SNDCTL_DSP_RESET, 0); + if (rc < 0) + { + perror("/dev/dsp"); + Con_Printf("Could not reset /dev/dsp\n"); + close(audio_fd); + return 0; + } + + if (ioctl(audio_fd, SNDCTL_DSP_GETCAPS, &caps)==-1) + { + perror("/dev/dsp"); + Con_Printf("Sound driver too old\n"); + close(audio_fd); + return 0; + } + + if (!(caps & DSP_CAP_TRIGGER) || !(caps & DSP_CAP_MMAP)) + { + Con_Printf("Sorry but your soundcard can't do this\n"); + close(audio_fd); + return 0; + } + + if (ioctl(audio_fd, SNDCTL_DSP_GETOSPACE, &info)==-1) + { + perror("GETOSPACE"); + Con_Printf("Um, can't do GETOSPACE?\n"); + close(audio_fd); + return 0; + } + + shm = &sn; + shm->splitbuffer = 0; + +// set sample bits & speed + + s = getenv("QUAKE_SOUND_SAMPLEBITS"); + if (s) shm->samplebits = atoi(s); + else if ((i = COM_CheckParm("-sndbits")) != 0) + shm->samplebits = atoi(com_argv[i+1]); + if (shm->samplebits != 16 && shm->samplebits != 8) + { + ioctl(audio_fd, SNDCTL_DSP_GETFMTS, &fmt); + if (fmt & AFMT_S16_LE) shm->samplebits = 16; + else if (fmt & AFMT_U8) shm->samplebits = 8; + } + + s = getenv("QUAKE_SOUND_SPEED"); + if (s) shm->speed = atoi(s); + else if ((i = COM_CheckParm("-sndspeed")) != 0) + shm->speed = atoi(com_argv[i+1]); + else + { + for (i=0 ; ispeed = tryrates[i]; + } + + s = getenv("QUAKE_SOUND_CHANNELS"); + if (s) shm->channels = atoi(s); + else if ((i = COM_CheckParm("-sndmono")) != 0) + shm->channels = 1; + else if ((i = COM_CheckParm("-sndstereo")) != 0) + shm->channels = 2; + else shm->channels = 2; + + shm->samples = info.fragstotal * info.fragsize / (shm->samplebits/8); + shm->submission_chunk = 1; + +// memory map the dma buffer + + shm->buffer = (unsigned char *) mmap(NULL, info.fragstotal + * info.fragsize, PROT_WRITE, MAP_FILE|MAP_SHARED, audio_fd, 0); + if (!shm->buffer || shm->buffer == (unsigned char *)-1) + { + perror("/dev/dsp"); + Con_Printf("Could not mmap /dev/dsp\n"); + close(audio_fd); + return 0; + } + + tmp = 0; + if (shm->channels == 2) + tmp = 1; + rc = ioctl(audio_fd, SNDCTL_DSP_STEREO, &tmp); + if (rc < 0) + { + perror("/dev/dsp"); + Con_Printf("Could not set /dev/dsp to stereo=%d", shm->channels); + close(audio_fd); + return 0; + } + if (tmp) + shm->channels = 2; + else + shm->channels = 1; + + rc = ioctl(audio_fd, SNDCTL_DSP_SPEED, &shm->speed); + if (rc < 0) + { + perror("/dev/dsp"); + Con_Printf("Could not set /dev/dsp speed to %d", shm->speed); + close(audio_fd); + return 0; + } + + if (shm->samplebits == 16) + { + rc = AFMT_S16_LE; + rc = ioctl(audio_fd, SNDCTL_DSP_SETFMT, &rc); + if (rc < 0) + { + perror("/dev/dsp"); + Con_Printf("Could not support 16-bit data. Try 8-bit.\n"); + close(audio_fd); + return 0; + } + } + else if (shm->samplebits == 8) + { + rc = AFMT_U8; + rc = ioctl(audio_fd, SNDCTL_DSP_SETFMT, &rc); + if (rc < 0) + { + perror("/dev/dsp"); + Con_Printf("Could not support 8-bit data.\n"); + close(audio_fd); + return 0; + } + } + else + { + perror("/dev/dsp"); + Con_Printf("%d-bit sound not supported.", shm->samplebits); + close(audio_fd); + return 0; + } + +// toggle the trigger & start her up + + tmp = 0; + rc = ioctl(audio_fd, SNDCTL_DSP_SETTRIGGER, &tmp); + if (rc < 0) + { + perror("/dev/dsp"); + Con_Printf("Could not toggle.\n"); + close(audio_fd); + return 0; + } + tmp = PCM_ENABLE_OUTPUT; + rc = ioctl(audio_fd, SNDCTL_DSP_SETTRIGGER, &tmp); + if (rc < 0) + { + perror("/dev/dsp"); + Con_Printf("Could not toggle.\n"); + close(audio_fd); + return 0; + } + + shm->samplepos = 0; + + snd_inited = 1; + return 1; + +} + +int SNDDMA_GetDMAPos(void) +{ + + struct count_info count; + + if (!snd_inited) return 0; + + if (ioctl(audio_fd, SNDCTL_DSP_GETOPTR, &count)==-1) + { + perror("/dev/dsp"); + Con_Printf("Uh, sound dead.\n"); + close(audio_fd); + snd_inited = 0; + return 0; + } +// shm->samplepos = (count.bytes / (shm->samplebits / 8)) & (shm->samples-1); +// fprintf(stderr, "%d \r", count.ptr); + shm->samplepos = count.ptr / (shm->samplebits / 8); + + return shm->samplepos; + +} + +void SNDDMA_Shutdown(void) +{ + if (snd_inited) + { + close(audio_fd); + snd_inited = 0; + } +} + +/* +============== +SNDDMA_Submit + +Send sound to device if buffer isn't really the dma buffer +=============== +*/ +void SNDDMA_Submit(void) +{ +} + diff --git a/contrib/other/sdlquake-1.0.9/snd_mem.c b/contrib/other/sdlquake-1.0.9/snd_mem.c new file mode 100644 index 000000000..71e32aa05 --- /dev/null +++ b/contrib/other/sdlquake-1.0.9/snd_mem.c @@ -0,0 +1,341 @@ +/* +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_mem.c: sound caching + +#include "quakedef.h" + +int cache_full_cycle; + +byte *S_Alloc (int size); + +/* +================ +ResampleSfx +================ +*/ +void ResampleSfx (sfx_t *sfx, int inrate, int inwidth, byte *data) +{ + int outcount; + int srcsample; + float stepscale; + int i; + int sample, samplefrac, fracstep; + sfxcache_t *sc; + + sc = Cache_Check (&sfx->cache); + if (!sc) + return; + + stepscale = (float)inrate / shm->speed; // this is usually 0.5, 1, or 2 + + outcount = sc->length / stepscale; + sc->length = outcount; + if (sc->loopstart != -1) + sc->loopstart = sc->loopstart / stepscale; + + sc->speed = shm->speed; + if (loadas8bit.value) + sc->width = 1; + else + sc->width = inwidth; + sc->stereo = 0; + +// resample / decimate to the current source rate + + if (stepscale == 1 && inwidth == 1 && sc->width == 1) + { +// fast special case + for (i=0 ; idata)[i] + = (int)( (unsigned char)(data[i]) - 128); + } + else + { +// general case + samplefrac = 0; + fracstep = stepscale*256; + for (i=0 ; i> 8; + samplefrac += fracstep; + if (inwidth == 2) + sample = LittleShort ( ((short *)data)[srcsample] ); + else + sample = (int)( (unsigned char)(data[srcsample]) - 128) << 8; + if (sc->width == 2) + ((short *)sc->data)[i] = sample; + else + ((signed char *)sc->data)[i] = sample >> 8; + } + } +} + +//============================================================================= + +/* +============== +S_LoadSound +============== +*/ +sfxcache_t *S_LoadSound (sfx_t *s) +{ + char namebuffer[256]; + byte *data; + wavinfo_t info; + int len; + float stepscale; + sfxcache_t *sc; + byte stackbuf[1*1024]; // avoid dirtying the cache heap + +// see if still in memory + sc = Cache_Check (&s->cache); + if (sc) + return sc; + +//Con_Printf ("S_LoadSound: %x\n", (int)stackbuf); +// load it in + Q_strcpy(namebuffer, "sound/"); + Q_strcat(namebuffer, s->name); + +// Con_Printf ("loading %s\n",namebuffer); + + data = COM_LoadStackFile(namebuffer, stackbuf, sizeof(stackbuf)); + + if (!data) + { + Con_Printf ("Couldn't load %s\n", namebuffer); + return NULL; + } + + info = GetWavinfo (s->name, data, com_filesize); + if (info.channels != 1) + { + Con_Printf ("%s is a stereo sample\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 (!sc) + return NULL; + + sc->length = info.samples; + sc->loopstart = info.loopstart; + sc->speed = info.rate; + sc->width = info.width; + sc->stereo = info.channels; + + ResampleSfx (s, sc->speed, sc->width, data + info.dataofs); + + return sc; +} + + + +/* +=============================================================================== + +WAV loading + +=============================================================================== +*/ + + +byte *data_p; +byte *iff_end; +byte *last_chunk; +byte *iff_data; +int iff_chunk_len; + + +short GetLittleShort(void) +{ + short val = 0; + val = *data_p; + val = val + (*(data_p+1)<<8); + data_p += 2; + return val; +} + +int GetLittleLong(void) +{ + int val = 0; + val = *data_p; + val = val + (*(data_p+1)<<8); + val = val + (*(data_p+2)<<16); + val = val + (*(data_p+3)<<24); + data_p += 4; + return val; +} + +void FindNextChunk(char *name) +{ + while (1) + { + data_p=last_chunk; + + if (data_p >= iff_end) + { // didn't find the chunk + data_p = NULL; + return; + } + + data_p += 4; + iff_chunk_len = GetLittleLong(); + if (iff_chunk_len < 0) + { + data_p = NULL; + return; + } +// if (iff_chunk_len > 1024*1024) +// Sys_Error ("FindNextChunk: %i length is past the 1 meg sanity limit", iff_chunk_len); + data_p -= 8; + last_chunk = data_p + 8 + ( (iff_chunk_len + 1) & ~1 ); + if (!Q_strncmp(data_p, name, 4)) + return; + } +} + +void FindChunk(char *name) +{ + last_chunk = iff_data; + FindNextChunk (name); +} + + +void DumpChunks(void) +{ + char str[5]; + + str[4] = 0; + data_p=iff_data; + do + { + memcpy (str, data_p, 4); + data_p += 4; + iff_chunk_len = GetLittleLong(); + 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); +} + +/* +============ +GetWavinfo +============ +*/ +wavinfo_t GetWavinfo (char *name, byte *wav, int wavlength) +{ + wavinfo_t info; + 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))) + { + Con_Printf("Missing RIFF/WAVE chunks\n"); + return info; + } + +// get "fmt " chunk + iff_data = data_p + 12; +// DumpChunks (); + + FindChunk("fmt "); + if (!data_p) + { + Con_Printf("Missing fmt chunk\n"); + return info; + } + data_p += 8; + format = GetLittleShort(); + if (format != 1) + { + Con_Printf("Microsoft PCM format only\n"); + return info; + } + + info.channels = GetLittleShort(); + info.rate = GetLittleLong(); + data_p += 4+2; + info.width = GetLittleShort() / 8; + +// get cue chunk + FindChunk("cue "); + if (data_p) + { + data_p += 32; + info.loopstart = GetLittleLong(); +// 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)) + { // this is not a proper parse, but it works with cooledit... + data_p += 24; + i = GetLittleLong (); // samples in loop + info.samples = info.loopstart + i; +// Con_Printf("looped length: %i\n", i); + } + } + } + else + info.loopstart = -1; + +// find data chunk + FindChunk("data"); + if (!data_p) + { + Con_Printf("Missing data chunk\n"); + return info; + } + + data_p += 4; + samples = GetLittleLong () / info.width; + + if (info.samples) + { + if (samples < info.samples) + Sys_Error ("Sound %s has a bad loop length", name); + } + else + info.samples = samples; + + info.dataofs = data_p - wav; + + return info; +} + diff --git a/contrib/other/sdlquake-1.0.9/snd_mix.c b/contrib/other/sdlquake-1.0.9/snd_mix.c new file mode 100644 index 000000000..d31f6c992 --- /dev/null +++ b/contrib/other/sdlquake-1.0.9/snd_mix.c @@ -0,0 +1,398 @@ +/* +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/contrib/other/sdlquake-1.0.9/snd_mixa.S b/contrib/other/sdlquake-1.0.9/snd_mixa.S new file mode 100644 index 000000000..7fa190b32 --- /dev/null +++ b/contrib/other/sdlquake-1.0.9/snd_mixa.S @@ -0,0 +1,218 @@ +/* +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_mixa.s +// x86 assembly-language sound code +// + +#include "asm_i386.h" +#include "quakeasm.h" + +#if id386 + + .text + +//---------------------------------------------------------------------- +// 8-bit sound-mixing code +//---------------------------------------------------------------------- + +#define ch 4+16 +#define sc 8+16 +#define count 12+16 + +.globl C(SND_PaintChannelFrom8) +C(SND_PaintChannelFrom8): + pushl %esi // preserve register variables + pushl %edi + pushl %ebx + pushl %ebp + +// int data; +// short *lscale, *rscale; +// unsigned char *sfx; +// int i; + + movl ch(%esp),%ebx + movl sc(%esp),%esi + +// if (ch->leftvol > 255) +// ch->leftvol = 255; +// if (ch->rightvol > 255) +// ch->rightvol = 255; + movl ch_leftvol(%ebx),%eax + movl ch_rightvol(%ebx),%edx + cmpl $255,%eax + jna LLeftSet + movl $255,%eax +LLeftSet: + cmpl $255,%edx + jna LRightSet + movl $255,%edx +LRightSet: + +// lscale = snd_scaletable[ch->leftvol >> 3]; +// rscale = snd_scaletable[ch->rightvol >> 3]; +// sfx = (signed char *)sc->data + ch->pos; +// ch->pos += count; + andl $0xF8,%eax + addl $(sfxc_data),%esi + andl $0xF8,%edx + movl ch_pos(%ebx),%edi + movl count(%esp),%ecx + addl %edi,%esi + shll $7,%eax + addl %ecx,%edi + shll $7,%edx + movl %edi,ch_pos(%ebx) + addl $(C(snd_scaletable)),%eax + addl $(C(snd_scaletable)),%edx + subl %ebx,%ebx + movb -1(%esi,%ecx,1),%bl + + testl $1,%ecx + jz LMix8Loop + + movl (%eax,%ebx,4),%edi + movl (%edx,%ebx,4),%ebp + addl C(paintbuffer)+psp_left-psp_size(,%ecx,psp_size),%edi + addl C(paintbuffer)+psp_right-psp_size(,%ecx,psp_size),%ebp + movl %edi,C(paintbuffer)+psp_left-psp_size(,%ecx,psp_size) + movl %ebp,C(paintbuffer)+psp_right-psp_size(,%ecx,psp_size) + movb -2(%esi,%ecx,1),%bl + + decl %ecx + jz LDone + +// 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; + movl -8(%ebx,%ecx,4),%eax + imull %esi,%eax + sarl $8,%eax + cmpl $0x7FFF,%eax + jg LClampHigh + cmpl $0xFFFF8000,%eax + jnl LClampDone + movl $0xFFFF8000,%eax + jmp LClampDone +LClampHigh: + movl $0x7FFF,%eax +LClampDone: + +// 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; + movl -4(%ebx,%ecx,4),%edx + imull %esi,%edx + sarl $8,%edx + cmpl $0x7FFF,%edx + jg LClampHigh2 + cmpl $0xFFFF8000,%edx + jnl LClampDone2 + movl $0xFFFF8000,%edx + jmp LClampDone2 +LClampHigh2: + movl $0x7FFF,%edx +LClampDone2: + shll $16,%edx + andl $0xFFFF,%eax + orl %eax,%edx + movl %edx,-4(%edi,%ecx,2) + +// } + subl $2,%ecx + jnz LWLBLoopTop + +// snd_p += snd_linear_count; + + popl %ebx + popl %edi + popl %esi + + ret + + +#endif // id386 + diff --git a/contrib/other/sdlquake-1.0.9/snd_next.c b/contrib/other/sdlquake-1.0.9/snd_next.c new file mode 100644 index 000000000..e732da342 --- /dev/null +++ b/contrib/other/sdlquake-1.0.9/snd_next.c @@ -0,0 +1,55 @@ +/* +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 int desired_speed; +extern int desired_bits; + +qboolean SNDDMA_Init(void) +{ + int size; + + size = 16384 + sizeof(dma_t); + shm = malloc (size); + memset((void*)shm, 0, size); + + shm->buffer = (char*)shm + sizeof(dma_t); + shm->channels = 2; + shm->speed = desired_speed; + shm->samplebits = desired_bits; + shm->samples = 16384 / (desired_bits / 8); + shm->submission_chunk = 1; + + return true; +} + +// return the current sample position (in mono samples read) +// inside the recirculating dma buffer +int SNDDMA_GetDMAPos(void) +{ + shm->samplepos = (int)(realtime*shm->speed*shm->channels) & (shm->samples-1); + + return shm->samplepos; +} + +void SNDDMA_Shutdown(void) +{ +} diff --git a/contrib/other/sdlquake-1.0.9/snd_null.c b/contrib/other/sdlquake-1.0.9/snd_null.c new file mode 100644 index 000000000..9db2ebcea --- /dev/null +++ b/contrib/other/sdlquake-1.0.9/snd_null.c @@ -0,0 +1,97 @@ +/* +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_null.c -- include this instead of all the other snd_* files to have +// no sound code whatsoever + +#include "quakedef.h" + +cvar_t bgmvolume = {"bgmvolume", "1", true}; +cvar_t volume = {"volume", "0.7", true}; + + +void S_Init (void) +{ +} + +void S_AmbientOff (void) +{ +} + +void S_AmbientOn (void) +{ +} + +void S_Shutdown (void) +{ +} + +void S_TouchSound (char *sample) +{ +} + +void S_ClearBuffer (void) +{ +} + +void S_StaticSound (sfx_t *sfx, vec3_t origin, float vol, float attenuation) +{ +} + +void S_StartSound (int entnum, int entchannel, sfx_t *sfx, vec3_t origin, float fvol, float attenuation) +{ +} + +void S_StopSound (int entnum, int entchannel) +{ +} + +sfx_t *S_PrecacheSound (char *sample) +{ + return NULL; +} + +void S_ClearPrecache (void) +{ +} + +void S_Update (vec3_t origin, vec3_t v_forward, vec3_t v_right, vec3_t v_up) +{ +} + +void S_StopAllSounds (qboolean clear) +{ +} + +void S_BeginPrecaching (void) +{ +} + +void S_EndPrecaching (void) +{ +} + +void S_ExtraUpdate (void) +{ +} + +void S_LocalSound (char *s) +{ +} + diff --git a/contrib/other/sdlquake-1.0.9/snd_sdl.c b/contrib/other/sdlquake-1.0.9/snd_sdl.c new file mode 100644 index 000000000..85405547b --- /dev/null +++ b/contrib/other/sdlquake-1.0.9/snd_sdl.c @@ -0,0 +1,112 @@ + +#include +#include "SDL_audio.h" +#include "SDL_byteorder.h" +#include "quakedef.h" + +static dma_t the_shm; +static int snd_inited; + +extern int desired_speed; +extern int desired_bits; + +static void paint_audio(void *unused, Uint8 *stream, int len) +{ + if ( shm ) { + shm->buffer = stream; + shm->samplepos += len/(shm->samplebits/8)/2; + // Check for samplepos overflow? + S_PaintChannels (shm->samplepos); + } +} + +qboolean SNDDMA_Init(void) +{ + SDL_AudioSpec desired, obtained; + + snd_inited = 0; + + /* Set up the desired format */ + desired.freq = desired_speed; + switch (desired_bits) { + case 8: + desired.format = AUDIO_U8; + break; + case 16: + if ( SDL_BYTEORDER == SDL_BIG_ENDIAN ) + desired.format = AUDIO_S16MSB; + else + desired.format = AUDIO_S16LSB; + break; + default: + Con_Printf("Unknown number of audio bits: %d\n", + desired_bits); + return 0; + } + desired.channels = 2; + desired.samples = 512; + desired.callback = paint_audio; + + /* Open the audio device */ + if ( SDL_OpenAudio(&desired, &obtained) < 0 ) { + Con_Printf("Couldn't open SDL audio: %s\n", SDL_GetError()); + return 0; + } + + /* Make sure we can support the audio format */ + switch (obtained.format) { + case AUDIO_U8: + /* Supported */ + break; + case AUDIO_S16LSB: + case AUDIO_S16MSB: + if ( ((obtained.format == AUDIO_S16LSB) && + (SDL_BYTEORDER == SDL_LIL_ENDIAN)) || + ((obtained.format == AUDIO_S16MSB) && + (SDL_BYTEORDER == SDL_BIG_ENDIAN)) ) { + /* Supported */ + break; + } + /* Unsupported, fall through */; + default: + /* Not supported -- force SDL to do our bidding */ + SDL_CloseAudio(); + if ( SDL_OpenAudio(&desired, NULL) < 0 ) { + Con_Printf("Couldn't open SDL audio: %s\n", + SDL_GetError()); + return 0; + } + memcpy(&obtained, &desired, sizeof(desired)); + break; + } + SDL_PauseAudio(0); + + /* Fill the audio DMA information block */ + shm = &the_shm; + shm->splitbuffer = 0; + shm->samplebits = (obtained.format & 0xFF); + shm->speed = obtained.freq; + shm->channels = obtained.channels; + shm->samples = obtained.samples*shm->channels; + shm->samplepos = 0; + shm->submission_chunk = 1; + shm->buffer = NULL; + + snd_inited = 1; + return 1; +} + +int SNDDMA_GetDMAPos(void) +{ + return shm->samplepos; +} + +void SNDDMA_Shutdown(void) +{ + if (snd_inited) + { + SDL_CloseAudio(); + snd_inited = 0; + } +} + diff --git a/contrib/other/sdlquake-1.0.9/snd_sun.c b/contrib/other/sdlquake-1.0.9/snd_sun.c new file mode 100644 index 000000000..fe9f8bbc9 --- /dev/null +++ b/contrib/other/sdlquake-1.0.9/snd_sun.c @@ -0,0 +1,218 @@ +/* +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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "quakedef.h" + +int audio_fd; +int snd_inited; + +static int bufpos; +static int wbufp; +static audio_info_t info; + +#define BUFFER_SIZE 8192 + +unsigned char dma_buffer[BUFFER_SIZE]; +unsigned char pend_buffer[BUFFER_SIZE]; +int pending; + +static int lastwrite = 0; + +qboolean SNDDMA_Init(void) +{ + int rc; + int fmt; + int tmp; + int i; + char *s; + int caps; + + if (snd_inited) { + printf("Sound already init'd\n"); + return; + } + + shm = &sn; + shm->splitbuffer = 0; + + audio_fd = open("/dev/audio", O_WRONLY|O_NDELAY); + + if (audio_fd < 0) { + if (errno == EBUSY) { + Con_Printf("Audio device is being used by another process\n"); + } + perror("/dev/audio"); + Con_Printf("Could not open /dev/audio\n"); + return (0); + } + + if (ioctl(audio_fd, AUDIO_GETINFO, &info) < 0) { + perror("/dev/audio"); + Con_Printf("Could not communicate with audio device.\n"); + close(audio_fd); + return 0; + } + + // + // set to nonblock + // + if (fcntl(audio_fd, F_SETFL, O_NONBLOCK) < 0) { + perror("/dev/audio"); + close(audio_fd); + return 0; + } + + AUDIO_INITINFO(&info); + + shm->speed = 11025; + + // try 16 bit stereo + info.play.encoding = AUDIO_ENCODING_LINEAR; + info.play.sample_rate = 11025; + info.play.channels = 2; + info.play.precision = 16; + + if (ioctl(audio_fd, AUDIO_SETINFO, &info) < 0) { + info.play.encoding = AUDIO_ENCODING_LINEAR; + info.play.sample_rate = 11025; + info.play.channels = 1; + info.play.precision = 16; + if (ioctl(audio_fd, AUDIO_SETINFO, &info) < 0) { + Con_Printf("Incapable sound hardware.\n"); + close(audio_fd); + return 0; + } + Con_Printf("16 bit mono sound initialized\n"); + shm->samplebits = 16; + shm->channels = 1; + } else { // 16 bit stereo + Con_Printf("16 bit stereo sound initialized\n"); + shm->samplebits = 16; + shm->channels = 2; + } + + shm->soundalive = true; + shm->samples = sizeof(dma_buffer) / (shm->samplebits/8); + shm->samplepos = 0; + shm->submission_chunk = 1; + shm->buffer = (unsigned char *)dma_buffer; + + snd_inited = 1; + + return 1; +} + +int SNDDMA_GetDMAPos(void) +{ + if (!snd_inited) + return (0); + + if (ioctl(audio_fd, AUDIO_GETINFO, &info) < 0) { + perror("/dev/audio"); + Con_Printf("Could not communicate with audio device.\n"); + close(audio_fd); + snd_inited = 0; + return (0); + } + + return ((info.play.samples*shm->channels) % shm->samples); +} + +int SNDDMA_GetSamples(void) +{ + if (!snd_inited) + return (0); + + if (ioctl(audio_fd, AUDIO_GETINFO, &info) < 0) { + perror("/dev/audio"); + Con_Printf("Could not communicate with audio device.\n"); + close(audio_fd); + snd_inited = 0; + return (0); + } + + return info.play.samples; +} + +void SNDDMA_Shutdown(void) +{ + if (snd_inited) { + close(audio_fd); + snd_inited = 0; + } +} + +/* +============== +SNDDMA_Submit + +Send sound to device if buffer isn't really the dma buffer +=============== +*/ +void SNDDMA_Submit(void) +{ + int samps; + int bsize; + int bytes, b; + static unsigned char writebuf[1024]; + unsigned char *p; + int idx; + int stop = paintedtime; + extern int soundtime; + + if (paintedtime < wbufp) + wbufp = 0; // reset + + bsize = shm->channels * (shm->samplebits/8); + bytes = (paintedtime - wbufp) * bsize; + + if (!bytes) + return; + + if (bytes > sizeof(writebuf)) { + bytes = sizeof(writebuf); + stop = wbufp + bytes/bsize; + } + + p = writebuf; + idx = (wbufp*bsize) & (BUFFER_SIZE - 1); + + for (b = bytes; b; b--) { + *p++ = dma_buffer[idx]; + idx = (idx + 1) & (BUFFER_SIZE - 1); + } + + wbufp = stop; + + if (write(audio_fd, writebuf, bytes) < bytes) + printf("audio can't keep up!\n"); + +} + diff --git a/contrib/other/sdlquake-1.0.9/snd_win.c b/contrib/other/sdlquake-1.0.9/snd_win.c new file mode 100644 index 000000000..11028c4cc --- /dev/null +++ b/contrib/other/sdlquake-1.0.9/snd_win.c @@ -0,0 +1,729 @@ +/* +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; + shm->speed = 11025; + + 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; + shm->speed = 11025; + + 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/contrib/other/sdlquake-1.0.9/sound.h b/contrib/other/sdlquake-1.0.9/sound.h new file mode 100644 index 000000000..1ba08d3f6 --- /dev/null +++ b/contrib/other/sdlquake-1.0.9/sound.h @@ -0,0 +1,177 @@ +/* +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/contrib/other/sdlquake-1.0.9/spritegn.h b/contrib/other/sdlquake-1.0.9/spritegn.h new file mode 100644 index 000000000..b192b540e --- /dev/null +++ b/contrib/other/sdlquake-1.0.9/spritegn.h @@ -0,0 +1,110 @@ +/* +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. + +*/ +// +// spritegn.h: header file for sprite generation program +// + +// ********************************************************** +// * This file must be identical in the spritegen directory * +// * and in the Quake directory, because it's used to * +// * pass data from one to the other via .spr files. * +// ********************************************************** + +//------------------------------------------------------- +// This program generates .spr sprite package files. +// The format of the files is as follows: +// +// dsprite_t file header structure +// +// +// dspriteframe_t frame header structure +// sprite bitmap +// +// dspriteframe_t frame header structure +// sprite bitmap +// +//------------------------------------------------------- + +#ifdef INCLUDELIBS + +#include +#include +#include +#include + +#include "cmdlib.h" +#include "scriplib.h" +#include "dictlib.h" +#include "trilib.h" +#include "lbmlib.h" +#include "mathlib.h" + +#endif + +#define SPRITE_VERSION 1 + +// must match definition in modelgen.h +#ifndef SYNCTYPE_T +#define SYNCTYPE_T +typedef enum {ST_SYNC=0, ST_RAND } synctype_t; +#endif + +// TODO: shorten these? +typedef struct { + int ident; + int version; + int type; + float boundingradius; + int width; + int height; + int numframes; + float beamlength; + synctype_t synctype; +} dsprite_t; + +#define SPR_VP_PARALLEL_UPRIGHT 0 +#define SPR_FACING_UPRIGHT 1 +#define SPR_VP_PARALLEL 2 +#define SPR_ORIENTED 3 +#define SPR_VP_PARALLEL_ORIENTED 4 + +typedef struct { + int origin[2]; + int width; + int height; +} dspriteframe_t; + +typedef struct { + int numframes; +} dspritegroup_t; + +typedef struct { + float interval; +} dspriteinterval_t; + +typedef enum { SPR_SINGLE=0, SPR_GROUP } spriteframetype_t; + +typedef struct { + spriteframetype_t type; +} dspriteframetype_t; + +#define IDSPRITEHEADER (('P'<<24)+('S'<<16)+('D'<<8)+'I') + // little-endian "IDSP" + diff --git a/contrib/other/sdlquake-1.0.9/surf16.S b/contrib/other/sdlquake-1.0.9/surf16.S new file mode 100644 index 000000000..c0812a3b3 --- /dev/null +++ b/contrib/other/sdlquake-1.0.9/surf16.S @@ -0,0 +1,172 @@ +/* +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. + +*/ +// +// surf16.s +// x86 assembly-language 16 bpp surface block drawing code. +// + +#include "asm_i386.h" +#include "quakeasm.h" +#include "asm_draw.h" + +#if id386 + +//---------------------------------------------------------------------- +// Surface block drawer +//---------------------------------------------------------------------- + + .data + +k: .long 0 +loopentry: .long 0 + + .align 4 +blockjumptable16: + .long LEnter2_16 + .long LEnter4_16 + .long 0, LEnter8_16 + .long 0, 0, 0, LEnter16_16 + + + .text + + .align 4 +.globl C(R_Surf16Start) +C(R_Surf16Start): + + .align 4 +.globl C(R_DrawSurfaceBlock16) +C(R_DrawSurfaceBlock16): + pushl %ebp // preserve caller's stack frame + pushl %edi + pushl %esi // preserve register variables + pushl %ebx + + movl C(blocksize),%eax + movl C(prowdestbase),%edi + movl C(pbasesource),%esi + movl C(sourcesstep),%ebx + movl blockjumptable16-4(,%eax,2),%ecx + movl %eax,k + movl %ecx,loopentry + movl C(lightleft),%edx + movl C(lightright),%ebp + +Lblockloop16: + + subl %edx,%ebp + movb C(blockdivshift),%cl + sarl %cl,%ebp + jns Lp1_16 + testl C(blockdivmask),%ebp + jz Lp1_16 + incl %ebp +Lp1_16: + + subl %eax,%eax + subl %ecx,%ecx // high words must be 0 in loop for addressing + + jmp *loopentry + + .align 4 + +#include "block16.h" + + movl C(pbasesource),%esi + movl C(lightleft),%edx + movl C(lightright),%ebp + movl C(sourcetstep),%eax + movl C(lightrightstep),%ecx + movl C(prowdestbase),%edi + + addl %eax,%esi + addl %ecx,%ebp + + movl C(lightleftstep),%eax + movl C(surfrowbytes),%ecx + + addl %eax,%edx + addl %ecx,%edi + + movl %esi,C(pbasesource) + movl %ebp,C(lightright) + movl k,%eax + movl %edx,C(lightleft) + decl %eax + movl %edi,C(prowdestbase) + movl %eax,k + jnz Lblockloop16 + + popl %ebx // restore register variables + popl %esi + popl %edi + popl %ebp // restore the caller's stack frame + ret + +.globl C(R_Surf16End) +C(R_Surf16End): + +//---------------------------------------------------------------------- +// Code patching routines +//---------------------------------------------------------------------- + .data + + .align 4 +LPatchTable16: + .long LBPatch0-4 + .long LBPatch1-4 + .long LBPatch2-4 + .long LBPatch3-4 + .long LBPatch4-4 + .long LBPatch5-4 + .long LBPatch6-4 + .long LBPatch7-4 + .long LBPatch8-4 + .long LBPatch9-4 + .long LBPatch10-4 + .long LBPatch11-4 + .long LBPatch12-4 + .long LBPatch13-4 + .long LBPatch14-4 + .long LBPatch15-4 + + .text + + .align 4 +.globl C(R_Surf16Patch) +C(R_Surf16Patch): + pushl %ebx + + movl C(colormap),%eax + movl $LPatchTable16,%ebx + movl $16,%ecx +LPatchLoop16: + movl (%ebx),%edx + addl $4,%ebx + movl %eax,(%edx) + decl %ecx + jnz LPatchLoop16 + + popl %ebx + + ret + + +#endif // id386 diff --git a/contrib/other/sdlquake-1.0.9/surf8.S b/contrib/other/sdlquake-1.0.9/surf8.S new file mode 100644 index 000000000..a079f1d00 --- /dev/null +++ b/contrib/other/sdlquake-1.0.9/surf8.S @@ -0,0 +1,783 @@ +/* +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. + +*/ +// +// surf8.s +// x86 assembly-language 8 bpp surface block drawing code. +// + +#include "asm_i386.h" +#include "quakeasm.h" +#include "asm_draw.h" + +#if id386 + + .data + +sb_v: .long 0 + + .text + + .align 4 +.globl C(R_Surf8Start) +C(R_Surf8Start): + +//---------------------------------------------------------------------- +// Surface block drawer for mip level 0 +//---------------------------------------------------------------------- + + .align 4 +.globl C(R_DrawSurfaceBlock8_mip0) +C(R_DrawSurfaceBlock8_mip0): + pushl %ebp // preserve caller's stack frame + pushl %edi + pushl %esi // preserve register variables + pushl %ebx + +// for (v=0 ; v> blockdivshift; +// lightrightstep = (lightptr[1] - lightright) >> blockdivshift; +// lightdeltastep = ((lightleftstep - lightrightstep) & 0xFFFFF) | +// 0xF0000000; + movl 4(%ebx),%ecx // lightptr[1] + movl (%ebx),%ebx // lightptr[0] + + subl %eax,%ebx + subl %edx,%ecx + + sarl $4,%ecx + orl $0xF0000000,%ebp + + sarl $4,%ebx + movl %ecx,C(lightrightstep) + + subl %ecx,%ebx + andl $0xFFFFF,%ebx + + orl $0xF0000000,%ebx + subl %ecx,%ecx // high word must be 0 in loop for addressing + + movl %ebx,C(lightdeltastep) + subl %ebx,%ebx // high word must be 0 in loop for addressing + +Lblockloop8_mip0: + movl %ebp,C(lightdelta) + movb 14(%esi),%cl + + sarl $4,%ebp + movb %dh,%bh + + movb 15(%esi),%bl + addl %ebp,%edx + + movb %dh,%ch + addl %ebp,%edx + + movb 0x12345678(%ebx),%ah +LBPatch0: + movb 13(%esi),%bl + + movb 0x12345678(%ecx),%al +LBPatch1: + movb 12(%esi),%cl + + movb %dh,%bh + addl %ebp,%edx + + rorl $16,%eax + movb %dh,%ch + + addl %ebp,%edx + movb 0x12345678(%ebx),%ah +LBPatch2: + + movb 11(%esi),%bl + movb 0x12345678(%ecx),%al +LBPatch3: + + movb 10(%esi),%cl + movl %eax,12(%edi) + + movb %dh,%bh + addl %ebp,%edx + + movb %dh,%ch + addl %ebp,%edx + + movb 0x12345678(%ebx),%ah +LBPatch4: + movb 9(%esi),%bl + + movb 0x12345678(%ecx),%al +LBPatch5: + movb 8(%esi),%cl + + movb %dh,%bh + addl %ebp,%edx + + rorl $16,%eax + movb %dh,%ch + + addl %ebp,%edx + movb 0x12345678(%ebx),%ah +LBPatch6: + + movb 7(%esi),%bl + movb 0x12345678(%ecx),%al +LBPatch7: + + movb 6(%esi),%cl + movl %eax,8(%edi) + + movb %dh,%bh + addl %ebp,%edx + + movb %dh,%ch + addl %ebp,%edx + + movb 0x12345678(%ebx),%ah +LBPatch8: + movb 5(%esi),%bl + + movb 0x12345678(%ecx),%al +LBPatch9: + movb 4(%esi),%cl + + movb %dh,%bh + addl %ebp,%edx + + rorl $16,%eax + movb %dh,%ch + + addl %ebp,%edx + movb 0x12345678(%ebx),%ah +LBPatch10: + + movb 3(%esi),%bl + movb 0x12345678(%ecx),%al +LBPatch11: + + movb 2(%esi),%cl + movl %eax,4(%edi) + + movb %dh,%bh + addl %ebp,%edx + + movb %dh,%ch + addl %ebp,%edx + + movb 0x12345678(%ebx),%ah +LBPatch12: + movb 1(%esi),%bl + + movb 0x12345678(%ecx),%al +LBPatch13: + movb (%esi),%cl + + movb %dh,%bh + addl %ebp,%edx + + rorl $16,%eax + movb %dh,%ch + + movb 0x12345678(%ebx),%ah +LBPatch14: + movl C(lightright),%edx + + movb 0x12345678(%ecx),%al +LBPatch15: + movl C(lightdelta),%ebp + + movl %eax,(%edi) + + addl C(sourcetstep),%esi + addl C(surfrowbytes),%edi + + addl C(lightrightstep),%edx + addl C(lightdeltastep),%ebp + + movl %edx,C(lightright) + jc Lblockloop8_mip0 + +// if (pbasesource >= r_sourcemax) +// pbasesource -= stepback; + + cmpl C(r_sourcemax),%esi + jb LSkip_mip0 + subl C(r_stepback),%esi +LSkip_mip0: + + movl C(r_lightptr),%ebx + decl sb_v + + jnz Lv_loop_mip0 + + popl %ebx // restore register variables + popl %esi + popl %edi + popl %ebp // restore the caller's stack frame + ret + + +//---------------------------------------------------------------------- +// Surface block drawer for mip level 1 +//---------------------------------------------------------------------- + + .align 4 +.globl C(R_DrawSurfaceBlock8_mip1) +C(R_DrawSurfaceBlock8_mip1): + pushl %ebp // preserve caller's stack frame + pushl %edi + pushl %esi // preserve register variables + pushl %ebx + +// for (v=0 ; v> blockdivshift; +// lightrightstep = (lightptr[1] - lightright) >> blockdivshift; +// lightdeltastep = ((lightleftstep - lightrightstep) & 0xFFFFF) | +// 0xF0000000; + movl 4(%ebx),%ecx // lightptr[1] + movl (%ebx),%ebx // lightptr[0] + + subl %eax,%ebx + subl %edx,%ecx + + sarl $3,%ecx + orl $0x70000000,%ebp + + sarl $3,%ebx + movl %ecx,C(lightrightstep) + + subl %ecx,%ebx + andl $0xFFFFF,%ebx + + orl $0xF0000000,%ebx + subl %ecx,%ecx // high word must be 0 in loop for addressing + + movl %ebx,C(lightdeltastep) + subl %ebx,%ebx // high word must be 0 in loop for addressing + +Lblockloop8_mip1: + movl %ebp,C(lightdelta) + movb 6(%esi),%cl + + sarl $3,%ebp + movb %dh,%bh + + movb 7(%esi),%bl + addl %ebp,%edx + + movb %dh,%ch + addl %ebp,%edx + + movb 0x12345678(%ebx),%ah +LBPatch22: + movb 5(%esi),%bl + + movb 0x12345678(%ecx),%al +LBPatch23: + movb 4(%esi),%cl + + movb %dh,%bh + addl %ebp,%edx + + rorl $16,%eax + movb %dh,%ch + + addl %ebp,%edx + movb 0x12345678(%ebx),%ah +LBPatch24: + + movb 3(%esi),%bl + movb 0x12345678(%ecx),%al +LBPatch25: + + movb 2(%esi),%cl + movl %eax,4(%edi) + + movb %dh,%bh + addl %ebp,%edx + + movb %dh,%ch + addl %ebp,%edx + + movb 0x12345678(%ebx),%ah +LBPatch26: + movb 1(%esi),%bl + + movb 0x12345678(%ecx),%al +LBPatch27: + movb (%esi),%cl + + movb %dh,%bh + addl %ebp,%edx + + rorl $16,%eax + movb %dh,%ch + + movb 0x12345678(%ebx),%ah +LBPatch28: + movl C(lightright),%edx + + movb 0x12345678(%ecx),%al +LBPatch29: + movl C(lightdelta),%ebp + + movl %eax,(%edi) + movl C(sourcetstep),%eax + + addl %eax,%esi + movl C(surfrowbytes),%eax + + addl %eax,%edi + movl C(lightrightstep),%eax + + addl %eax,%edx + movl C(lightdeltastep),%eax + + addl %eax,%ebp + movl %edx,C(lightright) + + jc Lblockloop8_mip1 + +// if (pbasesource >= r_sourcemax) +// pbasesource -= stepback; + + cmpl C(r_sourcemax),%esi + jb LSkip_mip1 + subl C(r_stepback),%esi +LSkip_mip1: + + movl C(r_lightptr),%ebx + decl sb_v + + jnz Lv_loop_mip1 + + popl %ebx // restore register variables + popl %esi + popl %edi + popl %ebp // restore the caller's stack frame + ret + + +//---------------------------------------------------------------------- +// Surface block drawer for mip level 2 +//---------------------------------------------------------------------- + + .align 4 +.globl C(R_DrawSurfaceBlock8_mip2) +C(R_DrawSurfaceBlock8_mip2): + pushl %ebp // preserve caller's stack frame + pushl %edi + pushl %esi // preserve register variables + pushl %ebx + +// for (v=0 ; v> blockdivshift; +// lightrightstep = (lightptr[1] - lightright) >> blockdivshift; +// lightdeltastep = ((lightleftstep - lightrightstep) & 0xFFFFF) | +// 0xF0000000; + movl 4(%ebx),%ecx // lightptr[1] + movl (%ebx),%ebx // lightptr[0] + + subl %eax,%ebx + subl %edx,%ecx + + sarl $2,%ecx + orl $0x30000000,%ebp + + sarl $2,%ebx + movl %ecx,C(lightrightstep) + + subl %ecx,%ebx + + andl $0xFFFFF,%ebx + + orl $0xF0000000,%ebx + subl %ecx,%ecx // high word must be 0 in loop for addressing + + movl %ebx,C(lightdeltastep) + subl %ebx,%ebx // high word must be 0 in loop for addressing + +Lblockloop8_mip2: + movl %ebp,C(lightdelta) + movb 2(%esi),%cl + + sarl $2,%ebp + movb %dh,%bh + + movb 3(%esi),%bl + addl %ebp,%edx + + movb %dh,%ch + addl %ebp,%edx + + movb 0x12345678(%ebx),%ah +LBPatch18: + movb 1(%esi),%bl + + movb 0x12345678(%ecx),%al +LBPatch19: + movb (%esi),%cl + + movb %dh,%bh + addl %ebp,%edx + + rorl $16,%eax + movb %dh,%ch + + movb 0x12345678(%ebx),%ah +LBPatch20: + movl C(lightright),%edx + + movb 0x12345678(%ecx),%al +LBPatch21: + movl C(lightdelta),%ebp + + movl %eax,(%edi) + movl C(sourcetstep),%eax + + addl %eax,%esi + movl C(surfrowbytes),%eax + + addl %eax,%edi + movl C(lightrightstep),%eax + + addl %eax,%edx + movl C(lightdeltastep),%eax + + addl %eax,%ebp + movl %edx,C(lightright) + + jc Lblockloop8_mip2 + +// if (pbasesource >= r_sourcemax) +// pbasesource -= stepback; + + cmpl C(r_sourcemax),%esi + jb LSkip_mip2 + subl C(r_stepback),%esi +LSkip_mip2: + + movl C(r_lightptr),%ebx + decl sb_v + + jnz Lv_loop_mip2 + + popl %ebx // restore register variables + popl %esi + popl %edi + popl %ebp // restore the caller's stack frame + ret + + +//---------------------------------------------------------------------- +// Surface block drawer for mip level 3 +//---------------------------------------------------------------------- + + .align 4 +.globl C(R_DrawSurfaceBlock8_mip3) +C(R_DrawSurfaceBlock8_mip3): + pushl %ebp // preserve caller's stack frame + pushl %edi + pushl %esi // preserve register variables + pushl %ebx + +// for (v=0 ; v> blockdivshift; +// lightrightstep = (lightptr[1] - lightright) >> blockdivshift; +// lightdeltastep = ((lightleftstep - lightrightstep) & 0xFFFFF) | +// 0xF0000000; + movl 4(%ebx),%ecx // lightptr[1] + movl (%ebx),%ebx // lightptr[0] + + subl %eax,%ebx + subl %edx,%ecx + + sarl $1,%ecx + + sarl $1,%ebx + movl %ecx,C(lightrightstep) + + subl %ecx,%ebx + andl $0xFFFFF,%ebx + + sarl $1,%ebp + orl $0xF0000000,%ebx + + movl %ebx,C(lightdeltastep) + subl %ebx,%ebx // high word must be 0 in loop for addressing + + movb 1(%esi),%bl + subl %ecx,%ecx // high word must be 0 in loop for addressing + + movb %dh,%bh + movb (%esi),%cl + + addl %ebp,%edx + movb %dh,%ch + + movb 0x12345678(%ebx),%al +LBPatch16: + movl C(lightright),%edx + + movb %al,1(%edi) + movb 0x12345678(%ecx),%al +LBPatch17: + + movb %al,(%edi) + movl C(sourcetstep),%eax + + addl %eax,%esi + movl C(surfrowbytes),%eax + + addl %eax,%edi + movl C(lightdeltastep),%eax + + movl C(lightdelta),%ebp + movb (%esi),%cl + + addl %eax,%ebp + movl C(lightrightstep),%eax + + sarl $1,%ebp + addl %eax,%edx + + movb %dh,%bh + movb 1(%esi),%bl + + addl %ebp,%edx + movb %dh,%ch + + movb 0x12345678(%ebx),%al +LBPatch30: + movl C(sourcetstep),%edx + + movb %al,1(%edi) + movb 0x12345678(%ecx),%al +LBPatch31: + + movb %al,(%edi) + movl C(surfrowbytes),%ebp + + addl %edx,%esi + addl %ebp,%edi + +// if (pbasesource >= r_sourcemax) +// pbasesource -= stepback; + + cmpl C(r_sourcemax),%esi + jb LSkip_mip3 + subl C(r_stepback),%esi +LSkip_mip3: + + movl C(r_lightptr),%ebx + decl sb_v + + jnz Lv_loop_mip3 + + popl %ebx // restore register variables + popl %esi + popl %edi + popl %ebp // restore the caller's stack frame + ret + + +.globl C(R_Surf8End) +C(R_Surf8End): + +//---------------------------------------------------------------------- +// Code patching routines +//---------------------------------------------------------------------- + .data + + .align 4 +LPatchTable8: + .long LBPatch0-4 + .long LBPatch1-4 + .long LBPatch2-4 + .long LBPatch3-4 + .long LBPatch4-4 + .long LBPatch5-4 + .long LBPatch6-4 + .long LBPatch7-4 + .long LBPatch8-4 + .long LBPatch9-4 + .long LBPatch10-4 + .long LBPatch11-4 + .long LBPatch12-4 + .long LBPatch13-4 + .long LBPatch14-4 + .long LBPatch15-4 + .long LBPatch16-4 + .long LBPatch17-4 + .long LBPatch18-4 + .long LBPatch19-4 + .long LBPatch20-4 + .long LBPatch21-4 + .long LBPatch22-4 + .long LBPatch23-4 + .long LBPatch24-4 + .long LBPatch25-4 + .long LBPatch26-4 + .long LBPatch27-4 + .long LBPatch28-4 + .long LBPatch29-4 + .long LBPatch30-4 + .long LBPatch31-4 + + .text + + .align 4 +.globl C(R_Surf8Patch) +C(R_Surf8Patch): + pushl %ebx + + movl C(colormap),%eax + movl $LPatchTable8,%ebx + movl $32,%ecx +LPatchLoop8: + movl (%ebx),%edx + addl $4,%ebx + movl %eax,(%edx) + decl %ecx + jnz LPatchLoop8 + + popl %ebx + + ret + +#endif // id386 diff --git a/contrib/other/sdlquake-1.0.9/sv_main.c b/contrib/other/sdlquake-1.0.9/sv_main.c new file mode 100644 index 000000000..deda690c2 --- /dev/null +++ b/contrib/other/sdlquake-1.0.9/sv_main.c @@ -0,0 +1,1200 @@ +/* +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. + +*/ +// sv_main.c -- server main program + +#include "quakedef.h" + +server_t sv; +server_static_t svs; + +char localmodels[MAX_MODELS][5]; // inline model names for precache + +//============================================================================ + +/* +=============== +SV_Init +=============== +*/ +void SV_Init (void) +{ + int i; + extern cvar_t sv_maxvelocity; + extern cvar_t sv_gravity; + extern cvar_t sv_nostep; + extern cvar_t sv_friction; + extern cvar_t sv_edgefriction; + extern cvar_t sv_stopspeed; + extern cvar_t sv_maxspeed; + extern cvar_t sv_accelerate; + extern cvar_t sv_idealpitchscale; + extern cvar_t sv_aim; + + Cvar_RegisterVariable (&sv_maxvelocity); + Cvar_RegisterVariable (&sv_gravity); + Cvar_RegisterVariable (&sv_friction); + Cvar_RegisterVariable (&sv_edgefriction); + Cvar_RegisterVariable (&sv_stopspeed); + Cvar_RegisterVariable (&sv_maxspeed); + Cvar_RegisterVariable (&sv_accelerate); + Cvar_RegisterVariable (&sv_idealpitchscale); + Cvar_RegisterVariable (&sv_aim); + Cvar_RegisterVariable (&sv_nostep); + + for (i=0 ; i MAX_DATAGRAM-16) + 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]); + for (i=0 ; i<3 ; i++) + { + v = dir[i]*16; + if (v > 127) + v = 127; + else if (v < -128) + v = -128; + MSG_WriteChar (&sv.datagram, v); + } + MSG_WriteByte (&sv.datagram, count); + MSG_WriteByte (&sv.datagram, color); +} + +/* +================== +SV_StartSound + +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. + +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; + + if (volume < 0 || volume > 255) + Sys_Error ("SV_StartSound: volume = %i", volume); + + if (attenuation < 0 || attenuation > 4) + Sys_Error ("SV_StartSound: attenuation = %f", attenuation); + + if (channel < 0 || channel > 7) + Sys_Error ("SV_StartSound: channel = %i", channel); + + if (sv.datagram.cursize > MAX_DATAGRAM-16) + return; + +// find precache number for sound + for (sound_num=1 ; sound_numv.origin[i]+0.5*(entity->v.mins[i]+entity->v.maxs[i])); +} + +/* +============================================================================== + +CLIENT SPAWNING + +============================================================================== +*/ + +/* +================ +SV_SendServerinfo + +Sends the first message from the server to a connected client. +This will be sent on the initial connection and upon each server load. +================ +*/ +void SV_SendServerinfo (client_t *client) +{ + char **s; + char message[2048]; + + MSG_WriteByte (&client->message, svc_print); + sprintf (message, "%c\nVERSION %4.2f SERVER (%i CRC)", 2, VERSION, pr_crc); + MSG_WriteString (&client->message,message); + + MSG_WriteByte (&client->message, svc_serverinfo); + MSG_WriteLong (&client->message, PROTOCOL_VERSION); + MSG_WriteByte (&client->message, svs.maxclients); + + if (!coop.value && deathmatch.value) + MSG_WriteByte (&client->message, GAME_DEATHMATCH); + else + MSG_WriteByte (&client->message, GAME_COOP); + + sprintf (message, pr_strings+sv.edicts->v.message); + + MSG_WriteString (&client->message,message); + + for (s = sv.model_precache+1 ; *s ; s++) + MSG_WriteString (&client->message, *s); + MSG_WriteByte (&client->message, 0); + + for (s = sv.sound_precache+1 ; *s ; s++) + MSG_WriteString (&client->message, *s); + MSG_WriteByte (&client->message, 0); + +// send music + MSG_WriteByte (&client->message, svc_cdtrack); + MSG_WriteByte (&client->message, sv.edicts->v.sounds); + MSG_WriteByte (&client->message, sv.edicts->v.sounds); + +// set view + MSG_WriteByte (&client->message, svc_setview); + MSG_WriteShort (&client->message, NUM_FOR_EDICT(client->edict)); + + MSG_WriteByte (&client->message, svc_signonnum); + MSG_WriteByte (&client->message, 1); + + client->sendsignon = true; + client->spawned = false; // need prespawn, spawn, etc +} + +/* +================ +SV_ConnectClient + +Initializes a client_t for a new net connection. This will only be called +once for a player each game, not once for each level change. +================ +*/ +void SV_ConnectClient (int clientnum) +{ + edict_t *ent; + client_t *client; + int edictnum; + struct qsocket_s *netconnection; + int i; + float spawn_parms[NUM_SPAWN_PARMS]; + + client = svs.clients + clientnum; + + Con_DPrintf ("Client %s connected\n", client->netconnection->address); + + 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)); + client->netconnection = netconnection; + + strcpy (client->name, "unconnected"); + client->active = true; + client->spawned = false; + client->edict = ent; + client->message.data = client->msgbuf; + 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 + { + // call the progs to get default spawn parms for the new client + PR_ExecuteProgram (pr_global_struct->SetNewParms); + for (i=0 ; ispawn_parms[i] = (&pr_global_struct->parm1)[i]; + } + + SV_SendServerinfo (client); +} + + +/* +=================== +SV_CheckForNewClients + +=================== +*/ +void SV_CheckForNewClients (void) +{ + struct qsocket_s *ret; + int i; + +// +// check for new connections +// + while (1) + { + ret = NET_CheckNewConnections (); + if (!ret) + break; + + // + // init a new client structure + // + for (i=0 ; icontents < 0) + { + if (node->contents != CONTENTS_SOLID) + { + pvs = Mod_LeafPVS ( (mleaf_t *)node, sv.worldmodel); + for (i=0 ; iplane; + d = DotProduct (org, plane->normal) - plane->dist; + if (d > 8) + node = node->children[0]; + else if (d < -8) + node = node->children[1]; + else + { // go down both + SV_AddToFatPVS (org, node->children[0]); + node = node->children[1]; + } + } +} + +/* +============= +SV_FatPVS + +Calculates a PVS that is the inclusive or of all leafs within 8 pixels of the +given point. +============= +*/ +byte *SV_FatPVS (vec3_t org) +{ + fatbytes = (sv.worldmodel->numleafs+31)>>3; + Q_memset (fatpvs, 0, fatbytes); + SV_AddToFatPVS (org, sv.worldmodel->nodes); + return fatpvs; +} + +//============================================================================= + + +/* +============= +SV_WriteEntitiesToClient + +============= +*/ +void SV_WriteEntitiesToClient (edict_t *clent, sizebuf_t *msg) +{ + int e, i; + int bits; + byte *pvs; + vec3_t org; + float miss; + edict_t *ent; + +// find the client's PVS + VectorAdd (clent->v.origin, clent->v.view_ofs, org); + pvs = SV_FatPVS (org); + +// 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 + if (!ent->v.modelindex || !pr_strings[ent->v.model]) + continue; + + 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) + continue; // not visible + } + + if (msg->maxsize - msg->cursize < 16) + { + Con_Printf ("packet overflow\n"); + return; + } + +// send an update + bits = 0; + + for (i=0 ; i<3 ; i++) + { + miss = ent->v.origin[i] - ent->baseline.origin[i]; + if ( miss < -0.1 || miss > 0.1 ) + bits |= U_ORIGIN1<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 + + 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; + + if (e >= 256) + bits |= U_LONGENTITY; + + if (bits >= 256) + bits |= U_MOREBITS; + + // + // write the message + // + MSG_WriteByte (msg,bits | U_SIGNAL); + + if (bits & U_MOREBITS) + MSG_WriteByte (msg, bits>>8); + if (bits & U_LONGENTITY) + MSG_WriteShort (msg,e); + else + MSG_WriteByte (msg,e); + + if (bits & U_MODEL) + MSG_WriteByte (msg, ent->v.modelindex); + if (bits & U_FRAME) + MSG_WriteByte (msg, ent->v.frame); + if (bits & U_COLORMAP) + MSG_WriteByte (msg, ent->v.colormap); + if (bits & U_SKIN) + MSG_WriteByte (msg, ent->v.skin); + if (bits & U_EFFECTS) + MSG_WriteByte (msg, ent->v.effects); + if (bits & U_ORIGIN1) + MSG_WriteCoord (msg, ent->v.origin[0]); + if (bits & U_ANGLE1) + MSG_WriteAngle(msg, ent->v.angles[0]); + if (bits & U_ORIGIN2) + MSG_WriteCoord (msg, ent->v.origin[1]); + if (bits & U_ANGLE2) + MSG_WriteAngle(msg, ent->v.angles[1]); + if (bits & U_ORIGIN3) + MSG_WriteCoord (msg, ent->v.origin[2]); + if (bits & U_ANGLE3) + MSG_WriteAngle(msg, ent->v.angles[2]); + } +} + +/* +============= +SV_CleanupEnts + +============= +*/ +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; + } + +} + +/* +================== +SV_WriteClientdataToMessage + +================== +*/ +void SV_WriteClientdataToMessage (edict_t *ent, sizebuf_t *msg) +{ + int bits; + int i; + edict_t *other; + int items; +#ifndef QUAKE2 + eval_t *val; +#endif + +// +// send a damage message +// + if (ent->v.dmg_take || ent->v.dmg_save) + { + other = PROG_TO_EDICT(ent->v.dmg_inflictor); + MSG_WriteByte (msg, svc_damage); + 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])); + + ent->v.dmg_take = 0; + ent->v.dmg_save = 0; + } + +// +// send the current viewpos offset from the view entity +// + SV_SetIdealPitch (); // how much to look up / down ideally + +// a fixangle might get lost in a dropped packet. Oh well. + if ( ent->v.fixangle ) + { + MSG_WriteByte (msg, svc_setangle); + for (i=0 ; i < 3 ; i++) + MSG_WriteAngle (msg, ent->v.angles[i] ); + 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]) + bits |= (SU_PUNCH1<v.velocity[i]) + bits |= (SU_VELOCITY1<v.weaponframe) + bits |= SU_WEAPONFRAME; + + if (ent->v.armorvalue) + bits |= SU_ARMOR; + +// if (ent->v.weapon) + bits |= SU_WEAPON; + +// send the data + + MSG_WriteByte (msg, svc_clientdata); + MSG_WriteShort (msg, bits); + + if (bits & SU_VIEWHEIGHT) + MSG_WriteChar (msg, ent->v.view_ofs[2]); + + if (bits & SU_IDEALPITCH) + MSG_WriteChar (msg, ent->v.idealpitch); + + for (i=0 ; i<3 ; i++) + { + if (bits & (SU_PUNCH1<v.punchangle[i]); + if (bits & (SU_VELOCITY1<v.velocity[i]/16); + } + +// [always sent] if (bits & SU_ITEMS) + MSG_WriteLong (msg, items); + + if (bits & SU_WEAPONFRAME) + MSG_WriteByte (msg, ent->v.weaponframe); + if (bits & SU_ARMOR) + MSG_WriteByte (msg, ent->v.armorvalue); + if (bits & SU_WEAPON) + MSG_WriteByte (msg, SV_ModelIndex(pr_strings+ent->v.weaponmodel)); + + MSG_WriteShort (msg, ent->v.health); + MSG_WriteByte (msg, ent->v.currentammo); + MSG_WriteByte (msg, ent->v.ammo_shells); + MSG_WriteByte (msg, ent->v.ammo_nails); + MSG_WriteByte (msg, ent->v.ammo_rockets); + MSG_WriteByte (msg, ent->v.ammo_cells); + + if (standard_quake) + { + MSG_WriteByte (msg, ent->v.weapon); + } + else + { + for(i=0;i<32;i++) + { + if ( ((int)ent->v.weapon) & (1<edict, &msg); + + SV_WriteEntitiesToClient (client->edict, &msg); + +// copy the server datagram if there is space + if (msg.cursize + sv.datagram.cursize < msg.maxsize) + SZ_Write (&msg, sv.datagram.data, sv.datagram.cursize); + +// send the datagram + if (NET_SendUnreliableMessage (client->netconnection, &msg) == -1) + { + SV_DropClient (true);// if the message couldn't send, kick off + return false; + } + + return true; +} + +/* +======================= +SV_UpdateToReliableMessages +======================= +*/ +void SV_UpdateToReliableMessages (void) +{ + int i, j; + client_t *client; + +// check for changes to be sent over the reliable streams + for (i=0, host_client = svs.clients ; iold_frags != host_client->edict->v.frags) + { + for (j=0, client = svs.clients ; jactive) + continue; + MSG_WriteByte (&client->message, svc_updatefrags); + MSG_WriteByte (&client->message, i); + MSG_WriteShort (&client->message, host_client->edict->v.frags); + } + + host_client->old_frags = host_client->edict->v.frags; + } + } + + for (j=0, client = svs.clients ; jactive) + continue; + SZ_Write (&client->message, sv.reliable_datagram.data, sv.reliable_datagram.cursize); + } + + SZ_Clear (&sv.reliable_datagram); +} + + +/* +======================= +SV_SendNop + +Send a nop message without trashing or sending the accumulated client +message buffer +======================= +*/ +void SV_SendNop (client_t *client) +{ + sizebuf_t msg; + byte buf[4]; + + msg.data = buf; + msg.maxsize = sizeof(buf); + msg.cursize = 0; + + MSG_WriteChar (&msg, svc_nop); + + if (NET_SendUnreliableMessage (client->netconnection, &msg) == -1) + SV_DropClient (true); // if the message couldn't send, kick off + client->last_message = realtime; +} + +/* +======================= +SV_SendClientMessages +======================= +*/ +void SV_SendClientMessages (void) +{ + int i; + +// update frags, names, etc + SV_UpdateToReliableMessages (); + +// build individual updates + for (i=0, host_client = svs.clients ; iactive) + continue; + + if (host_client->spawned) + { + if (!SV_SendClientDatagram (host_client)) + continue; + } + else + { + // 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 + // between signon stages + if (!host_client->sendsignon) + { + if (realtime - host_client->last_message > 5) + SV_SendNop (host_client); + continue; // don't send out non-signon messages + } + } + + // check for an overflowed message. Should only happen + // on a very fucked up connection that backs up a lot, then + // changes level + if (host_client->message.overflowed) + { + SV_DropClient (true); + host_client->message.overflowed = false; + continue; + } + + if (host_client->message.cursize || host_client->dropasap) + { + if (!NET_CanSendMessage (host_client->netconnection)) + { +// I_Printf ("can't write\n"); + continue; + } + + if (host_client->dropasap) + SV_DropClient (false); // went to another level + else + { + if (NET_SendMessage (host_client->netconnection + , &host_client->message) == -1) + SV_DropClient (true); // if the message couldn't send, kick off + SZ_Clear (&host_client->message); + host_client->last_message = realtime; + host_client->sendsignon = false; + } + } + } + + +// clear muzzle flashes + SV_CleanupEnts (); +} + + +/* +============================================================================== + +SERVER SPAWNING + +============================================================================== +*/ + +/* +================ +SV_ModelIndex + +================ +*/ +int SV_ModelIndex (char *name) +{ + int i; + + if (!name || !name[0]) + return 0; + + for (i=0 ; ifree) + continue; + if (entnum > svs.maxclients && !svent->v.modelindex) + continue; + + // + // create entity baseline + // + VectorCopy (svent->v.origin, svent->baseline.origin); + VectorCopy (svent->v.angles, svent->baseline.angles); + svent->baseline.frame = svent->v.frame; + svent->baseline.skin = svent->v.skin; + if (entnum > 0 && entnum <= svs.maxclients) + { + svent->baseline.colormap = entnum; + svent->baseline.modelindex = SV_ModelIndex("progs/player.mdl"); + } + else + { + svent->baseline.colormap = 0; + svent->baseline.modelindex = + SV_ModelIndex(pr_strings + svent->v.model); + } + + // + // add to the message + // + MSG_WriteByte (&sv.signon,svc_spawnbaseline); + MSG_WriteShort (&sv.signon,entnum); + + MSG_WriteByte (&sv.signon, svent->baseline.modelindex); + MSG_WriteByte (&sv.signon, svent->baseline.frame); + 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]); + } + } +} + + +/* +================ +SV_SendReconnect + +Tell all the clients that the server is changing levels +================ +*/ +void SV_SendReconnect (void) +{ + char data[128]; + sizebuf_t msg; + + msg.data = data; + msg.cursize = 0; + msg.maxsize = sizeof(data); + + 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 + Cmd_ExecuteString ("reconnect\n", src_command); +#endif +} + + +/* +================ +SV_SaveSpawnparms + +Grabs the current state of each client for saving across the +transition to another level +================ +*/ +void SV_SaveSpawnparms (void) +{ + int i, j; + + svs.serverflags = pr_global_struct->serverflags; + + for (i=0, host_client = svs.clients ; iactive) + continue; + + // call the progs to get default spawn parms for the new client + pr_global_struct->self = EDICT_TO_PROG(host_client->edict); + PR_ExecuteProgram (pr_global_struct->SetChangeParms); + for (j=0 ; jspawn_parms[j] = (&pr_global_struct->parm1)[j]; + } +} + + +/* +================ +SV_SpawnServer + +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 +{ + edict_t *ent; + int i; + + // let's not have any servers with no name + if (hostname.string[0] == 0) + Cvar_Set ("hostname", "UNNAMED"); + scr_centertime_off = 0; + + Con_DPrintf ("SpawnServer: %s\n",server); + svs.changelevel_issued = false; // now safe to issue another + +// +// tell all connected clients that we are going to a new level +// + if (sv.active) + { + SV_SendReconnect (); + } + +// +// make cvars consistant +// + if (coop.value) + Cvar_SetValue ("deathmatch", 0); + current_skill = (int)(skill.value + 0.5); + if (current_skill < 0) + current_skill = 0; + if (current_skill > 3) + current_skill = 3; + + Cvar_SetValue ("skill", (float)current_skill); + +// +// set up the new server +// + Host_ClearMemory (); + + memset (&sv, 0, sizeof(sv)); + + strcpy (sv.name, server); +#ifdef QUAKE2 + if (startspot) + strcpy(sv.startspot, startspot); +#endif + +// 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"); + + 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; + for (i=0 ; inumsubmodels ; i++) + { + sv.model_precache[1+i] = localmodels[i]; + sv.models[i+1] = Mod_ForName (localmodels[i], false); + } + +// +// load the rest of the entities +// + ent = EDICT_NUM(0); + memset (&ent->v, 0, progs->entityfields * 4); + ent->free = false; + ent->v.model = sv.worldmodel->name - pr_strings; + ent->v.modelindex = 1; // world model + ent->v.solid = SOLID_BSP; + ent->v.movetype = MOVETYPE_PUSH; + + if (coop.value) + pr_global_struct->coop = coop.value; + else + pr_global_struct->deathmatch = deathmatch.value; + + pr_global_struct->mapname = sv.name - pr_strings; +#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 (); + SV_Physics (); + +// create a baseline for more efficient communications + SV_CreateBaseline (); + +// 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/contrib/other/sdlquake-1.0.9/sv_move.c b/contrib/other/sdlquake-1.0.9/sv_move.c new file mode 100644 index 000000000..a0078b941 --- /dev/null +++ b/contrib/other/sdlquake-1.0.9/sv_move.c @@ -0,0 +1,427 @@ +/* +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. + +*/ +// sv_move.c -- monster movement + +#include "quakedef.h" + +#define STEPSIZE 18 + +/* +============= +SV_CheckBottom + +Returns false if any part of the bottom of the entity is off an edge that +is not a staircase. + +============= +*/ +int c_yes, c_no; + +qboolean SV_CheckBottom (edict_t *ent) +{ + vec3_t mins, maxs, start, stop; + 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); + +// if all of the points under the corners are solid world, don't bother +// with the tougher checks +// the corners must be within 16 of the midpoint + start[2] = mins[2] - 1; + for (x=0 ; x<=1 ; x++) + for (y=0 ; y<=1 ; y++) + { + start[0] = x ? maxs[0] : mins[0]; + start[1] = y ? maxs[1] : mins[1]; + if (SV_PointContents (start) != CONTENTS_SOLID) + goto realcheck; + } + + c_yes++; + return true; // we got out easy + +realcheck: + c_no++; +// +// 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; + stop[2] = start[2] - 2*STEPSIZE; + trace = SV_Move (start, vec3_origin, vec3_origin, stop, true, ent); + + if (trace.fraction == 1.0) + return false; + mid = bottom = trace.endpos[2]; + +// 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) + return false; + } + + c_yes++; + return true; +} + + +/* +============= +SV_movestep + +Called by monster program code. +The move will be adjusted for slopes and stairs, but if the move isn't +possible, no move is done, false is returned, and +pr_global_struct->trace_normal is set to the normal of the blocking wall +============= +*/ +qboolean SV_movestep (edict_t *ent, vec3_t move, qboolean relink) +{ + float dz; + vec3_t oldorg, neworg, end; + trace_t trace; + int i; + edict_t *enemy; + +// try the move + VectorCopy (ent->v.origin, oldorg); + VectorAdd (ent->v.origin, move, neworg); + +// flying monsters don't step up + if ( (int)ent->v.flags & (FL_SWIM | FL_FLY) ) + { + // try one move with vertical motion, then one without + for (i=0 ; i<2 ; i++) + { + VectorAdd (ent->v.origin, move, neworg); + enemy = PROG_TO_EDICT(ent->v.enemy); + if (i == 0 && enemy != sv.edicts) + { + dz = ent->v.origin[2] - PROG_TO_EDICT(ent->v.enemy)->v.origin[2]; + if (dz > 40) + neworg[2] -= 8; + if (dz < 30) + 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; + } + +// push down from a step height above the wished position + neworg[2] += STEPSIZE; + VectorCopy (neworg, end); + end[2] -= STEPSIZE*2; + + trace = SV_Move (neworg, ent->v.mins, ent->v.maxs, end, false, ent); + + if (trace.allsolid) + return false; + + if (trace.startsolid) + { + neworg[2] -= STEPSIZE; + trace = SV_Move (neworg, ent->v.mins, ent->v.maxs, end, false, ent); + if (trace.allsolid || trace.startsolid) + return false; + } + if (trace.fraction == 1) + { + // if monster had the ground pulled out, go ahead and fall + if ( (int)ent->v.flags & FL_PARTIALGROUND ) + { + VectorAdd (ent->v.origin, move, ent->v.origin); + if (relink) + SV_LinkEdict (ent, true); + ent->v.flags = (int)ent->v.flags & ~FL_ONGROUND; +// 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 ) + { // entity had floor mostly pulled out from underneath it + // and is trying to correct + if (relink) + SV_LinkEdict (ent, true); + return true; + } + VectorCopy (oldorg, ent->v.origin); + return false; + } + + if ( (int)ent->v.flags & FL_PARTIALGROUND ) + { +// Con_Printf ("back on ground\n"); + ent->v.flags = (int)ent->v.flags & ~FL_PARTIALGROUND; + } + ent->v.groundentity = EDICT_TO_PROG(trace.ent); + +// the move is ok + if (relink) + SV_LinkEdict (ent, true); + return true; +} + + +//============================================================================ + +/* +====================== +SV_StepDirection + +Turns to the movement direction, and walks the current distance if +facing it. + +====================== +*/ +void PF_changeyaw (void); +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; + move[2] = 0; + + VectorCopy (ent->v.origin, oldorigin); + if (SV_movestep (ent, move, false)) + { + delta = ent->v.angles[YAW] - ent->v.ideal_yaw; + if (delta > 45 && delta < 315) + { // not turned far enough, so don't take the step + VectorCopy (oldorigin, ent->v.origin); + } + SV_LinkEdict (ent, true); + return true; + } + SV_LinkEdict (ent, true); + + return false; +} + +/* +====================== +SV_FixCheckBottom + +====================== +*/ +void SV_FixCheckBottom (edict_t *ent) +{ +// Con_Printf ("SV_FixCheckBottom\n"); + + ent->v.flags = (int)ent->v.flags | FL_PARTIALGROUND; +} + + + +/* +================ +SV_NewChaseDir + +================ +*/ +#define DI_NODIR -1 +void SV_NewChaseDir (edict_t *actor, edict_t *enemy, float dist) +{ + float deltax,deltay; + float d[3]; + float tdir, olddir, turnaround; + + olddir = anglemod( (int)(actor->v.ideal_yaw/45)*45 ); + turnaround = anglemod(olddir - 180); + + deltax = enemy->v.origin[0] - actor->v.origin[0]; + deltay = enemy->v.origin[1] - actor->v.origin[1]; + if (deltax>10) + d[1]= 0; + else if (deltax<-10) + d[1]= 180; + else + d[1]= DI_NODIR; + if (deltay<-10) + d[2]= 270; + else if (deltay>10) + d[2]= 90; + else + d[2]= DI_NODIR; + +// try direct route + if (d[1] != DI_NODIR && d[2] != DI_NODIR) + { + if (d[1] == 0) + 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)) + { + tdir=d[1]; + d[1]=d[2]; + d[2]=tdir; + } + + if (d[1]!=DI_NODIR && d[1]!=turnaround + && SV_StepDirection(actor, d[1], dist)) + return; + + if (d[2]!=DI_NODIR && d[2]!=turnaround + && SV_StepDirection(actor, d[2], dist)) + return; + +/* there is no direct path to the player, so pick another direction */ + + if (olddir!=DI_NODIR && SV_StepDirection(actor, olddir, dist)) + return; + + if (rand()&1) /*randomly determine direction of search*/ + { + for (tdir=0 ; tdir<=315 ; tdir += 45) + if (tdir!=turnaround && SV_StepDirection(actor, tdir, dist) ) + return; + } + else + { + for (tdir=315 ; tdir >=0 ; tdir -= 45) + if (tdir!=turnaround && SV_StepDirection(actor, tdir, dist) ) + return; + } + + if (turnaround != DI_NODIR && SV_StepDirection(actor, turnaround, dist) ) + return; + + actor->v.ideal_yaw = olddir; // can't move + +// if a bridge was pulled out from underneath a monster, it may not have +// a valid standing position at all + + if (!SV_CheckBottom (actor)) + SV_FixCheckBottom (actor); + +} + +/* +====================== +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) + return false; + if (goal->v.absmax[i] < ent->v.absmin[i] - dist) + return false; + } + return true; +} + +/* +====================== +SV_MoveToGoal + +====================== +*/ +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); + dist = G_FLOAT(OFS_PARM0); + + if ( !( (int)ent->v.flags & (FL_ONGROUND|FL_FLY|FL_SWIM) ) ) + { + G_FLOAT(OFS_RETURN) = 0; + return; + } + +// 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... + if ( (rand()&3)==1 || + !SV_StepDirection (ent, ent->v.ideal_yaw, dist)) + { + SV_NewChaseDir (ent, goal, dist); + } +} + diff --git a/contrib/other/sdlquake-1.0.9/sv_phys.c b/contrib/other/sdlquake-1.0.9/sv_phys.c new file mode 100644 index 000000000..e13c0e443 --- /dev/null +++ b/contrib/other/sdlquake-1.0.9/sv_phys.c @@ -0,0 +1,1617 @@ +/* +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. + +*/ +// sv_phys.c + +#include "quakedef.h" + +/* + + +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 + +doors, plats, etc are SOLID_BSP, and MOVETYPE_PUSH +bonus items are SOLID_TRIGGER touch, and MOVETYPE_TOSS +corpses are SOLID_NOT and MOVETYPE_TOSS +crates are SOLID_BBOX and MOVETYPE_TOSS +walking monsters are SOLID_SLIDEBOX and MOVETYPE_STEP +flying/floating monsters are SOLID_SLIDEBOX and MOVETYPE_FLY + +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"}; + +#ifdef QUAKE2 +static vec3_t vec_origin = {0.0, 0.0, 0.0}; +#endif + +#define MOVE_EPSILON 0.01 + +void SV_Physics_Toss (edict_t *ent); + +/* +================ +SV_CheckAllEnts +================ +*/ +void SV_CheckAllEnts (void) +{ + int e; + edict_t *check; + +// see if any solid entities are inside the final position + check = NEXT_EDICT(sv.edicts); + for (e=1 ; efree) + 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; + + if (SV_TestEntityPosition (check)) + Con_Printf ("entity in invalid position\n"); + } +} + +/* +================ +SV_CheckVelocity +================ +*/ +void SV_CheckVelocity (edict_t *ent) +{ + int i; + +// +// bound velocity +// + for (i=0 ; i<3 ; i++) + { + if (IS_NAN(ent->v.velocity[i])) + { + Con_Printf ("Got a NaN velocity on %s\n", pr_strings + 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_strings + ent->v.classname); + ent->v.origin[i] = 0; + } + 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; + } +} + +/* +============= +SV_RunThink + +Runs thinking code if time. There is some play in the exact time the think +function will be called, because it is called before any movement is done +in a frame. Not used for pushmove objects, because they must be exact. +Returns false if the entity removed itself. +============= +*/ +qboolean SV_RunThink (edict_t *ent) +{ + float thinktime; + + 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. + 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); + return !ent->free; +} + +/* +================== +SV_Impact + +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) + { + pr_global_struct->self = EDICT_TO_PROG(e1); + 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); + pr_global_struct->other = EDICT_TO_PROG(e1); + PR_ExecuteProgram (e2->v.touch); + } + + pr_global_struct->self = old_self; + pr_global_struct->other = old_other; +} + + +/* +================== +ClipVelocity + +Slide off of the impacting object +returns the blocked flags (1 = floor, 2 = step / wall) +================== +*/ +#define STOP_EPSILON 0.1 + +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++) + { + change = normal[i]*backoff; + out[i] = in[i] - change; + if (out[i] > -STOP_EPSILON && out[i] < STOP_EPSILON) + out[i] = 0; + } + + return blocked; +} + + +/* +============ +SV_FlyMove + +The basic solid body movement clip that slides along multiple planes +Returns the clipflags if the velocity was modified (hit something solid) +1 = floor +2 = wall / step +4 = dead stop +If steptrace is not NULL, the trace of any vertical wall hit will be stored +============ +*/ +#define MAX_CLIP_PLANES 5 +int SV_FlyMove (edict_t *ent, float time, trace_t *steptrace) +{ + int bumpcount, numbumps; + vec3_t dir; + float d; + int numplanes; + vec3_t planes[MAX_CLIP_PLANES]; + vec3_t primal_velocity, original_velocity, new_velocity; + int i, j; + trace_t trace; + 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 ; bumpcountv.velocity[0] && !ent->v.velocity[1] && !ent->v.velocity[2]) + break; + + for (i=0 ; i<3 ; i++) + end[i] = ent->v.origin[i] + time_left * ent->v.velocity[i]; + + trace = SV_Move (ent->v.origin, ent->v.mins, ent->v.maxs, end, false, ent); + + if (trace.allsolid) + { // entity is trapped in another solid + VectorCopy (vec3_origin, ent->v.velocity); + return 3; + } + + if (trace.fraction > 0) + { // actually covered some distance + VectorCopy (trace.endpos, ent->v.origin); + VectorCopy (ent->v.velocity, original_velocity); + numplanes = 0; + } + + if (trace.fraction == 1) + break; // moved the entire distance + + if (!trace.ent) + Sys_Error ("SV_FlyMove: !trace.ent"); + + if (trace.plane.normal[2] > 0.7) + { + blocked |= 1; // floor + if (trace.ent->v.solid == SOLID_BSP) + { + ent->v.flags = (int)ent->v.flags | FL_ONGROUND; + ent->v.groundentity = EDICT_TO_PROG(trace.ent); + } + } + if (!trace.plane.normal[2]) + { + blocked |= 2; // step + if (steptrace) + *steptrace = trace; // save for player extrafriction + } + +// +// run the impact function +// + SV_Impact (ent, trace.ent); + if (ent->free) + 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 + VectorCopy (vec3_origin, ent->v.velocity); + return 3; + } + + VectorCopy (trace.plane.normal, planes[numplanes]); + numplanes++; + +// +// modify original_velocity so it parallels all of the clip planes +// + for (i=0 ; iv.velocity); + } + else + { // go along the crease + if (numplanes != 2) + { +// Con_Printf ("clip velocity, numplanes == %i\n",numplanes); + VectorCopy (vec3_origin, ent->v.velocity); + return 7; + } + CrossProduct (planes[0], planes[1], dir); + d = DotProduct (dir, ent->v.velocity); + VectorScale (dir, d, ent->v.velocity); + } + +// +// if original velocity is against the original velocity, stop dead +// to avoid tiny occilations in sloping corners +// + if (DotProduct (ent->v.velocity, primal_velocity) <= 0) + { + VectorCopy (vec3_origin, ent->v.velocity); + return blocked; + } + } + + return blocked; +} + + +/* +============ +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"); + if (val && val->_float) + ent_gravity = val->_float; + else + ent_gravity = 1.0; +#endif + ent->v.velocity[2] -= ent_gravity * sv_gravity.value * host_frametime; +} + + +/* +=============================================================================== + +PUSHMOVE + +=============================================================================== +*/ + +/* +============ +SV_PushEntity + +Does not change the entities velocity at all +============ +*/ +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) + trace = SV_Move (ent->v.origin, ent->v.mins, ent->v.maxs, end, MOVE_MISSILE, ent); + else if (ent->v.solid == SOLID_TRIGGER || ent->v.solid == SOLID_NOT) + // 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); + + VectorCopy (trace.endpos, ent->v.origin); + SV_LinkEdict (ent, true); + + if (trace.ent) + SV_Impact (ent, trace.ent); + + return trace; +} + + +/* +============ +SV_PushMove + +============ +*/ +void SV_PushMove (edict_t *pusher, float movetime) +{ + int i, e; + edict_t *check, *block; + vec3_t mins, maxs, move; + vec3_t entorig, pushorig; + int num_moved; + edict_t *moved_edict[MAX_EDICTS]; + vec3_t moved_from[MAX_EDICTS]; + + if (!pusher->v.velocity[0] && !pusher->v.velocity[1] && !pusher->v.velocity[2]) + { + pusher->v.ltime += movetime; + return; + } + + for (i=0 ; i<3 ; i++) + { + move[i] = pusher->v.velocity[i] * movetime; + mins[i] = pusher->v.absmin[i] + move[i]; + maxs[i] = pusher->v.absmax[i] + move[i]; + } + + 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); + + +// 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 +#ifdef QUAKE2 + || check->v.movetype == MOVETYPE_FOLLOW +#endif + || 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] >= 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] ) + 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++; + + // 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); + 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 + 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); + 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.angles); + 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); + VectorSubtract (moved_edict[i]->v.angles, amove, moved_edict[i]->v.angles); + SV_LinkEdict (moved_edict[i], false); + } + return; + } + else + { + VectorAdd (check->v.angles, amove, check->v.angles); + } + } + + +} +#endif + +/* +================ +SV_Physics_Pusher + +================ +*/ +void SV_Physics_Pusher (edict_t *ent) +{ + float thinktime; + float oldltime; + float movetime; + + oldltime = ent->v.ltime; + + thinktime = ent->v.nextthink; + if (thinktime < ent->v.ltime + host_frametime) + { + movetime = thinktime - ent->v.ltime; + if (movetime < 0) + movetime = 0; + } + else + movetime = host_frametime; + + if (movetime) + { +#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 (thinktime > oldltime && thinktime <= ent->v.ltime) + { + ent->v.nextthink = 0; + pr_global_struct->time = sv.time; + pr_global_struct->self = EDICT_TO_PROG(ent); + pr_global_struct->other = EDICT_TO_PROG(sv.edicts); + PR_ExecuteProgram (ent->v.think); + if (ent->free) + return; + } + +} + + +/* +=============================================================================== + +CLIENT MOVEMENT + +=============================================================================== +*/ + +/* +============= +SV_CheckStuck + +This is a big hack to try and fix the rare case of getting stuck in the world +clipping hull. +============= +*/ +void SV_CheckStuck (edict_t *ent) +{ + int i, j; + int z; + vec3_t org; + + if (!SV_TestEntityPosition(ent)) + { + VectorCopy (ent->v.origin, ent->v.oldorigin); + return; + } + + VectorCopy (ent->v.origin, org); + VectorCopy (ent->v.oldorigin, ent->v.origin); + if (!SV_TestEntityPosition(ent)) + { + Con_DPrintf ("Unstuck.\n"); + SV_LinkEdict (ent, true); + return; + } + + for (z=0 ; z< 18 ; z++) + for (i=-1 ; i <= 1 ; i++) + for (j=-1 ; j <= 1 ; j++) + { + ent->v.origin[0] = org[0] + i; + ent->v.origin[1] = org[1] + j; + ent->v.origin[2] = org[2] + z; + if (!SV_TestEntityPosition(ent)) + { + Con_DPrintf ("Unstuck.\n"); + SV_LinkEdict (ent, true); + return; + } + } + + VectorCopy (org, ent->v.origin); + Con_DPrintf ("player is stuck.\n"); +} + + +/* +============= +SV_CheckWater +============= +*/ +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; + + 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; + cont = SV_PointContents (point); + if (cont <= CONTENTS_WATER) + { + ent->v.waterlevel = 2; + point[2] = ent->v.origin[2] + ent->v.view_ofs[2]; + cont = SV_PointContents (point); + 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; +} + +/* +============ +SV_WallFriction + +============ +*/ +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); +} + +/* +===================== +SV_TryUnstick + +Player has come to a dead stop, possibly due to the problem with limited +float precision at some angle joins in the BSP hull. + +Try fixing by pushing one pixel in each direction. + +This is a hack, but in the interest of good gameplay... +====================== +*/ +int SV_TryUnstick (edict_t *ent, vec3_t oldvel) +{ + int i; + vec3_t oldorg; + vec3_t dir; + int clip; + trace_t steptrace; + + VectorCopy (ent->v.origin, oldorg); + VectorCopy (vec3_origin, dir); + + for (i=0 ; i<8 ; i++) + { +// try pushing a little in an axial direction + switch (i) + { + case 0: dir[0] = 2; dir[1] = 0; break; + case 1: dir[0] = 0; dir[1] = 2; break; + case 2: dir[0] = -2; dir[1] = 0; break; + case 3: dir[0] = 0; dir[1] = -2; break; + case 4: dir[0] = 2; dir[1] = 2; break; + case 5: dir[0] = -2; dir[1] = 2; break; + 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 + ent->v.velocity[0] = oldvel[0]; + ent->v. velocity[1] = oldvel[1]; + ent->v. velocity[2] = 0; + clip = SV_FlyMove (ent, 0.1, &steptrace); + + if ( fabs(oldorg[1] - ent->v.origin[1]) > 4 + || fabs(oldorg[0] - ent->v.origin[0]) > 4 ) + { +//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 +} + +/* +===================== +SV_WalkMove + +Only used by players +====================== +*/ +#define STEPSIZE 18 +void SV_WalkMove (edict_t *ent) +{ + vec3_t upmove, downmove; + vec3_t oldorg, oldvel; + vec3_t nosteporg, nostepvel; + 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) ) + return; // move didn't block on a step + + 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; + + VectorCopy (ent->v.origin, nosteporg); + VectorCopy (ent->v.velocity, nostepvel); + +// +// try moving up and forward to go up a step +// + VectorCopy (oldorg, ent->v.origin); // back to start pos + + VectorCopy (vec3_origin, upmove); + VectorCopy (vec3_origin, downmove); + upmove[2] = STEPSIZE; + downmove[2] = -STEPSIZE + oldvel[2]*host_frametime; + +// move up + SV_PushEntity (ent, upmove); // FIXME: don't link? + +// move forward + ent->v.velocity[0] = oldvel[0]; + ent->v. velocity[1] = oldvel[1]; + ent->v. velocity[2] = 0; + clip = SV_FlyMove (ent, host_frametime, &steptrace); + +// check for stuckness, possibly due to the limited precision of floats +// in the clipping hulls + if (clip) + { + if ( fabs(oldorg[1] - ent->v.origin[1]) < 0.03125 + && fabs(oldorg[0] - ent->v.origin[0]) < 0.03125 ) + { // stepping up didn't make any progress + clip = SV_TryUnstick (ent, oldvel); + } + } + +// extra friction based on view angle + if ( clip & 2 ) + SV_WallFriction (ent, &steptrace); + +// move down + downtrace = SV_PushEntity (ent, downmove); // FIXME: don't link? + + if (downtrace.plane.normal[2] > 0.7) + { + if (ent->v.solid == SOLID_BSP) + { + ent->v.flags = (int)ent->v.flags | FL_ONGROUND; + ent->v.groundentity = EDICT_TO_PROG(downtrace.ent); + } + } + else + { +// 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 + VectorCopy (nosteporg, ent->v.origin); + VectorCopy (nostepvel, ent->v.velocity); + } +} + + +/* +================ +SV_Physics_Client + +Player character actions +================ +*/ +void SV_Physics_Client (edict_t *ent, int num) +{ + if ( ! svs.clients[num-1].active ) + return; // unconnected slot + +// +// 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 +// + SV_CheckVelocity (ent); + +// +// decide which move function to call +// + switch ((int)ent->v.movetype) + { + case MOVETYPE_NONE: + if (!SV_RunThink (ent)) + return; + break; + + case MOVETYPE_WALK: + if (!SV_RunThink (ent)) + return; + 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); + break; + + case MOVETYPE_FLY: + if (!SV_RunThink (ent)) + 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; + pr_global_struct->self = EDICT_TO_PROG(ent); + PR_ExecuteProgram (pr_global_struct->PlayerPostThink); +} + +//============================================================================ + +/* +============= +SV_Physics_None + +Non moving objects can only think +============= +*/ +void SV_Physics_None (edict_t *ent) +{ +// regular thinking + 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 + +A moving object that doesn't obey physics +============= +*/ +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); + + SV_LinkEdict (ent, false); +} + +/* +============================================================================== + +TOSS / BOUNCE + +============================================================================== +*/ + +/* +============= +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; + } + else + { + 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; + } +} + +/* +============= +SV_Physics_Toss + +Toss, bounce, and fly movement. When onground, do nothing. +============= +*/ +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; + + SV_CheckVelocity (ent); + +// add gravity + 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; + + ClipVelocity (ent->v.velocity, trace.plane.normal, ent->v.velocity, backoff); + +// 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); + VectorCopy (vec3_origin, ent->v.velocity); + VectorCopy (vec3_origin, ent->v.avelocity); + } + } + +// check for in water + SV_CheckWaterTransition (ent); +} + +/* +=============================================================================== + +STEPPING MOVEMENT + +=============================================================================== +*/ + +/* +============= +SV_Physics_Step + +Monsters freefall when they don't have a ground entity, otherwise +all movement is done with discrete steps. + +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; + +// freefall if not onground + if ( ! ((int)ent->v.flags & (FL_ONGROUND | FL_FLY | FL_SWIM) ) ) + { + if (ent->v.velocity[2] < sv_gravity.value*-0.1) + hitsound = true; + else + hitsound = false; + + SV_AddGravity (ent); + SV_CheckVelocity (ent); + SV_FlyMove (ent, host_frametime, NULL); + SV_LinkEdict (ent, true); + + if ( (int)ent->v.flags & FL_ONGROUND ) // just hit ground + { + if (hitsound) + SV_StartSound (ent, 0, "demon/dland2.wav", 255, 1); + } + } + +// regular thinking + SV_RunThink (ent); + + SV_CheckWaterTransition (ent); +} +#endif + +//============================================================================ + +/* +================ +SV_Physics + +================ +*/ +void SV_Physics (void) +{ + int i; + edict_t *ent; + +// let the progs know that a new frame has started + pr_global_struct->self = EDICT_TO_PROG(sv.edicts); + pr_global_struct->other = EDICT_TO_PROG(sv.edicts); + pr_global_struct->time = sv.time; + PR_ExecuteProgram (pr_global_struct->StartFrame); + +//SV_CheckAllEnts (); + +// +// treat each object in turn +// + ent = sv.edicts; + for (i=0 ; ifree) + continue; + + if (pr_global_struct->force_retouch) + { + SV_LinkEdict (ent, true); // force retouch even for stationary + } + + if (i > 0 && i <= svs.maxclients) + SV_Physics_Client (ent, i); + else if (ent->v.movetype == MOVETYPE_PUSH) + 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 + || 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); + } + + 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; + + 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; +} +#endif diff --git a/contrib/other/sdlquake-1.0.9/sv_user.c b/contrib/other/sdlquake-1.0.9/sv_user.c new file mode 100644 index 000000000..11639497a --- /dev/null +++ b/contrib/other/sdlquake-1.0.9/sv_user.c @@ -0,0 +1,629 @@ +/* +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. + +*/ +// sv_user.c -- server code for moving users + +#include "quakedef.h" + +edict_t *sv_player; + +extern cvar_t sv_friction; +cvar_t sv_edgefriction = {"edgefriction", "2"}; +extern cvar_t sv_stopspeed; + +static vec3_t forward, right, up; + +vec3_t wishdir; +float wishspeed; + +// world +float *angles; +float *origin; +float *velocity; + +qboolean onground; + +usercmd_t cmd; + +cvar_t sv_idealpitchscale = {"sv_idealpitchscale","0.8"}; + + +/* +=============== +SV_SetIdealPitch +=============== +*/ +#define MAX_FORWARD 6 +void SV_SetIdealPitch (void) +{ + float angleval, sinval, cosval; + trace_t tr; + vec3_t top, bottom; + float z[MAX_FORWARD]; + int i, j; + int step, dir, steps; + + 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); + + for (i=0 ; iv.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 < ON_EPSILON) + continue; + + if (dir && ( step-dir > ON_EPSILON || step-dir < -ON_EPSILON ) ) + return; // mixed changes + + steps++; + dir = step; + } + + if (!dir) + { + sv_player->v.idealpitch = 0; + return; + } + + if (steps < 2) + return; + sv_player->v.idealpitch = -dir * sv_idealpitchscale.value; +} + + +/* +================== +SV_UserFriction + +================== +*/ +void SV_UserFriction (void) +{ + float *vel; + float speed, newspeed, control; + vec3_t start, stop; + float friction; + trace_t trace; + + vel = velocity; + + speed = sqrt(vel[0]*vel[0] +vel[1]*vel[1]); + if (!speed) + return; + +// if the leading edge is over a dropoff, increase friction + start[0] = stop[0] = origin[0] + vel[0]/speed*16; + start[1] = stop[1] = origin[1] + vel[1]/speed*16; + start[2] = origin[2] + sv_player->v.mins[2]; + stop[2] = start[2] - 34; + + trace = SV_Move (start, vec3_origin, vec3_origin, stop, true, sv_player); + + if (trace.fraction == 1.0) + friction = sv_friction.value*sv_edgefriction.value; + else + friction = sv_friction.value; + +// apply friction + 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; + vel[2] = vel[2] * newspeed; +} + +/* +============== +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) +{ + int i; + float addspeed, accelspeed, currentspeed; + + currentspeed = DotProduct (velocity, wishdir); + addspeed = wishspeed - currentspeed; + if (addspeed <= 0) + return; + accelspeed = sv_accelerate.value*host_frametime*wishspeed; + if (accelspeed > addspeed) + accelspeed = addspeed; + + for (i=0 ; i<3 ; i++) + velocity[i] += accelspeed*wishdir[i]; +} + +void SV_AirAccelerate (vec3_t wishveloc) +{ + int i; + float addspeed, wishspd, accelspeed, currentspeed; + + wishspd = VectorNormalize (wishveloc); + if (wishspd > 30) + wishspd = 30; + currentspeed = DotProduct (velocity, wishveloc); + addspeed = wishspd - currentspeed; + if (addspeed <= 0) + return; +// accelspeed = sv_accelerate.value * host_frametime; + accelspeed = sv_accelerate.value*wishspeed * host_frametime; + if (accelspeed > addspeed) + accelspeed = addspeed; + + for (i=0 ; i<3 ; 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; + VectorScale (sv_player->v.punchangle, len, sv_player->v.punchangle); +} + +/* +=================== +SV_WaterMove + +=================== +*/ +void SV_WaterMove (void) +{ + int i; + vec3_t wishvel; + float speed, newspeed, wishspeed, addspeed, accelspeed; + +// +// user intentions +// + AngleVectors (sv_player->v.v_angle, forward, right, up); + + for (i=0 ; i<3 ; i++) + wishvel[i] = forward[i]*cmd.forwardmove + right[i]*cmd.sidemove; + + if (!cmd.forwardmove && !cmd.sidemove && !cmd.upmove) + wishvel[2] -= 60; // drift towards bottom + else + wishvel[2] += cmd.upmove; + + wishspeed = Length(wishvel); + if (wishspeed > sv_maxspeed.value) + { + VectorScale (wishvel, sv_maxspeed.value/wishspeed, wishvel); + wishspeed = sv_maxspeed.value; + } + wishspeed *= 0.7; + +// +// water friction +// + speed = Length (velocity); + if (speed) + { + newspeed = speed - host_frametime * speed * sv_friction.value; + if (newspeed < 0) + newspeed = 0; + VectorScale (velocity, newspeed/speed, velocity); + } + else + newspeed = 0; + +// +// water acceleration +// + if (!wishspeed) + return; + + addspeed = wishspeed - newspeed; + if (addspeed <= 0) + return; + + VectorNormalize (wishvel); + accelspeed = sv_accelerate.value * wishspeed * host_frametime; + if (accelspeed > addspeed) + accelspeed = addspeed; + + for (i=0 ; i<3 ; i++) + velocity[i] += accelspeed * wishvel[i]; +} + +void SV_WaterJump (void) +{ + if (sv.time > sv_player->v.teleport_time + || !sv_player->v.waterlevel) + { + sv_player->v.flags = (int)sv_player->v.flags & ~FL_WATERJUMP; + sv_player->v.teleport_time = 0; + } + sv_player->v.velocity[0] = sv_player->v.movedir[0]; + sv_player->v.velocity[1] = sv_player->v.movedir[1]; +} + + +/* +=================== +SV_AirMove + +=================== +*/ +void SV_AirMove (void) +{ + int i; + vec3_t wishvel; + 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; + + if ( (int)sv_player->v.movetype != MOVETYPE_WALK) + wishvel[2] = cmd.upmove; + else + wishvel[2] = 0; + + VectorCopy (wishvel, wishdir); + wishspeed = VectorNormalize(wishdir); + if (wishspeed > sv_maxspeed.value) + { + VectorScale (wishvel, sv_maxspeed.value/wishspeed, wishvel); + wishspeed = sv_maxspeed.value; + } + + if ( sv_player->v.movetype == MOVETYPE_NOCLIP) + { // noclip + VectorCopy (wishvel, velocity); + } + else if ( onground ) + { + SV_UserFriction (); + SV_Accelerate (); + } + else + { // not on ground, so little effect on velocity + SV_AirAccelerate (wishvel); + } +} + +/* +=================== +SV_ClientThink + +the move fields specify an intended velocity in pix/sec +the angle fields specify an exact angular motion in degrees +=================== +*/ +void SV_ClientThink (void) +{ + vec3_t v_angle; + + 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 +// + if (sv_player->v.health <= 0) + return; + +// +// angles +// 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) + { + angles[PITCH] = -v_angle[PITCH]/3; + angles[YAW] = v_angle[YAW]; + } + + if ( (int)sv_player->v.flags & FL_WATERJUMP ) + { + SV_WaterJump (); + return; + } +// +// walk +// + if ( (sv_player->v.waterlevel >= 2) + && (sv_player->v.movetype != MOVETYPE_NOCLIP) ) + { + SV_WaterMove (); + return; + } + + SV_AirMove (); +} + + +/* +=================== +SV_ReadClientMove +=================== +*/ +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 + for (i=0 ; i<3 ; i++) + angle[i] = MSG_ReadAngle (); + + 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; + host_client->edict->v.button2 = (bits & 2)>>1; + + 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 +} + +/* +=================== +SV_ReadClientMessage + +Returns false if the client should be killed +=================== +*/ +qboolean SV_ReadClientMessage (void) +{ + int ret; + int cmd; + char *s; + + do + { +nextmsg: + ret = NET_GetMessage (host_client->netconnection); + if (ret == -1) + { + Sys_Printf ("SV_ReadClientMessage: NET_GetMessage failed\n"); + return false; + } + if (!ret) + return true; + + MSG_BeginReading (); + + while (1) + { + if (!host_client->active) + return false; // a command caused an error + + if (msg_badread) + { + Sys_Printf ("SV_ReadClientMessage: badread\n"); + return false; + } + + cmd = MSG_ReadChar (); + + switch (cmd) + { + 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: + s = MSG_ReadString (); + if (host_client->privileged) + ret = 2; + else + 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, "notarget", 8) == 0) + ret = 1; + else if (Q_strncasecmp(s, "fly", 3) == 0) + ret = 1; + else if (Q_strncasecmp(s, "name", 4) == 0) + ret = 1; + else if (Q_strncasecmp(s, "noclip", 6) == 0) + ret = 1; + else if (Q_strncasecmp(s, "say", 3) == 0) + ret = 1; + else if (Q_strncasecmp(s, "say_team", 8) == 0) + ret = 1; + else if (Q_strncasecmp(s, "tell", 4) == 0) + ret = 1; + else if (Q_strncasecmp(s, "color", 5) == 0) + ret = 1; + else if (Q_strncasecmp(s, "kill", 4) == 0) + ret = 1; + else if (Q_strncasecmp(s, "pause", 5) == 0) + ret = 1; + else if (Q_strncasecmp(s, "spawn", 5) == 0) + ret = 1; + else if (Q_strncasecmp(s, "begin", 5) == 0) + ret = 1; + else if (Q_strncasecmp(s, "prespawn", 8) == 0) + ret = 1; + else if (Q_strncasecmp(s, "kick", 4) == 0) + ret = 1; + else if (Q_strncasecmp(s, "ping", 4) == 0) + ret = 1; + else if (Q_strncasecmp(s, "give", 4) == 0) + ret = 1; + else if (Q_strncasecmp(s, "ban", 3) == 0) + ret = 1; + if (ret == 2) + Cbuf_InsertText (s); + else 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; +} + + +/* +================== +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 ()) + { + SV_DropClient (false); // client misbehaved... + continue; + } + + if (!host_client->spawned) + { + // clear client movement until a new packet is received + memset (&host_client->cmd, 0, sizeof(host_client->cmd)); + continue; + } + +// always pause in single player if in console or menus + if (!sv.paused && (svs.maxclients > 1 || key_dest == key_game) ) + SV_ClientThink (); + } +} + diff --git a/contrib/other/sdlquake-1.0.9/sys.h b/contrib/other/sdlquake-1.0.9/sys.h new file mode 100644 index 000000000..c5d61a7f7 --- /dev/null +++ b/contrib/other/sdlquake-1.0.9/sys.h @@ -0,0 +1,71 @@ +/* +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); +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 (unsigned long startaddr, unsigned long 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 + +void Sys_SendKeyEvents (void); +// Perform Key_Event () callbacks until the input que is empty + +void Sys_LowFPPrecision (void); +void Sys_HighFPPrecision (void); +void Sys_SetFPCW (void); + diff --git a/contrib/other/sdlquake-1.0.9/sys_dos.c b/contrib/other/sdlquake-1.0.9/sys_dos.c new file mode 100644 index 000000000..0a9bc4adc --- /dev/null +++ b/contrib/other/sdlquake-1.0.9/sys_dos.c @@ -0,0 +1,953 @@ +/* +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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "quakedef.h" +#include "dosisms.h" + +#define MINIMUM_WIN_MEMORY 0x800000 +#define MINIMUM_WIN_MEMORY_LEVELPAK (MINIMUM_WIN_MEMORY + 0x100000) + +int end_of_memory; +qboolean lockmem, lockunlockmem, unlockmem; +static int win95; + +#define STDOUT 1 + +#define KEYBUF_SIZE 256 +static unsigned char keybuf[KEYBUF_SIZE]; +static int keybuf_head=0; +static int keybuf_tail=0; + +static quakeparms_t quakeparms; +int sys_checksum; +static double curtime = 0.0; +static double lastcurtime = 0.0; +static double oldtime = 0.0; + +static qboolean isDedicated; + +static int minmem; + +float fptest_temp; + +extern char start_of_memory __asm__("start"); + +//============================================================================= + +// this is totally dependent on cwsdpmi putting the stack right after tge +// global data + +// This does evil things in a Win95 DOS box!!! +#if 0 +extern byte end; +#define CHECKBYTE 0xed +void Sys_InitStackCheck (void) +{ + int i; + + for (i=0 ; i<128*1024 ; i++) + (&end)[i] = CHECKBYTE; +} + +void Sys_StackCheck (void) +{ + int i; + + for (i=0 ; i<128*1024 ; i++) + if ( (&end)[i] != CHECKBYTE ) + break; + + Con_Printf ("%i undisturbed stack bytes\n", i); + if (end != CHECKBYTE) + Sys_Error ("System stack overflow!"); +} +#endif + +//============================================================================= + +byte scantokey[128] = + { +// 0 1 2 3 4 5 6 7 +// 8 9 A B C D E F + 0 , 27, '1', '2', '3', '4', '5', '6', + '7', '8', '9', '0', '-', '=', K_BACKSPACE, 9, // 0 + 'q', 'w', 'e', 'r', 't', 'y', 'u', 'i', + 'o', 'p', '[', ']', 13 , K_CTRL,'a', 's', // 1 + 'd', 'f', 'g', 'h', 'j', 'k', 'l', ';', + '\'' , '`', K_SHIFT,'\\', 'z', 'x', 'c', 'v', // 2 + 'b', 'n', 'm', ',', '.', '/', 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,0 , 0 , K_HOME, + K_UPARROW,K_PGUP,'-',K_LEFTARROW,'5',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 + }; + +byte shiftscantokey[128] = + { +// 0 1 2 3 4 5 6 7 +// 8 9 A B C D E F + 0 , 27, '!', '@', '#', '$', '%', '^', + '&', '*', '(', ')', '_', '+', K_BACKSPACE, 9, // 0 + 'Q', 'W', 'E', 'R', 'T', 'Y', 'U', 'I', + 'O', 'P', '{', '}', 13 , K_CTRL,'A', 'S', // 1 + 'D', 'F', 'G', 'H', 'J', 'K', 'L', ':', + '"' , '~', K_SHIFT,'|', 'Z', 'X', 'C', 'V', // 2 + 'B', 'N', 'M', '<', '>', '?', 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,0 , 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 + }; + +void TrapKey(void) +{ +// static int ctrl=0; + keybuf[keybuf_head] = dos_inportb(0x60); + dos_outportb(0x20, 0x20); + /* + if (scantokey[keybuf[keybuf_head]&0x7f] == K_CTRL) + ctrl=keybuf[keybuf_head]&0x80; + if (ctrl && scantokey[keybuf[keybuf_head]&0x7f] == 'c') + Sys_Error("ctrl-c hit\n"); + */ + keybuf_head = (keybuf_head + 1) & (KEYBUF_SIZE-1); +} + +#define SC_UPARROW 0x48 +#define SC_DOWNARROW 0x50 +#define SC_LEFTARROW 0x4b +#define SC_RIGHTARROW 0x4d +#define SC_LEFTSHIFT 0x2a +#define SC_RIGHTSHIFT 0x36 +#define SC_RIGHTARROW 0x4d + +void MaskExceptions (void); +void Sys_InitFloatTime (void); +void Sys_PushFPCW_SetHigh (void); +void Sys_PopFPCW (void); + +#define LEAVE_FOR_CACHE (512*1024) //FIXME: tune +#define LOCKED_FOR_MALLOC (128*1024) //FIXME: tune + + +void Sys_DetectWin95 (void) +{ + __dpmi_regs r; + + r.x.ax = 0x160a; /* Get Windows Version */ + __dpmi_int(0x2f, &r); + + if(r.x.ax || r.h.bh < 4) /* Not windows or earlier than Win95 */ + { + win95 = 0; + lockmem = true; + lockunlockmem = false; + unlockmem = true; + } + else + { + win95 = 1; + lockunlockmem = COM_CheckParm ("-winlockunlock"); + + if (lockunlockmem) + lockmem = true; + else + lockmem = COM_CheckParm ("-winlock"); + + unlockmem = lockmem && !lockunlockmem; + } +} + + +void *dos_getmaxlockedmem(int *size) +{ + __dpmi_free_mem_info meminfo; + __dpmi_meminfo info; + int working_size; + void *working_memory; + int last_locked; + int extra, i, j, allocsize; + static char *msg = "Locking data..."; + int m, n; + byte *x; + +// first lock all the current executing image so the locked count will +// be accurate. It doesn't hurt to lock the memory multiple times + last_locked = __djgpp_selector_limit + 1; + info.size = last_locked - 4096; + info.address = __djgpp_base_address + 4096; + + if (lockmem) + { + if(__dpmi_lock_linear_region(&info)) + { + Sys_Error ("Lock of current memory at 0x%lx for %ldKb failed!\n", + info.address, info.size/1024); + } + } + + __dpmi_get_free_memory_information(&meminfo); + + if (!win95) /* Not windows or earlier than Win95 */ + { + working_size = meminfo.maximum_locked_page_allocation_in_pages * 4096; + } + else + { + working_size = meminfo.largest_available_free_block_in_bytes - + LEAVE_FOR_CACHE; + } + + working_size &= ~0xffff; /* Round down to 64K */ + working_size += 0x10000; + + do + { + working_size -= 0x10000; /* Decrease 64K and try again */ + working_memory = sbrk(working_size); + } while (working_memory == (void *)-1); + + extra = 0xfffc - ((unsigned)sbrk(0) & 0xffff); + + if (extra > 0) + { + sbrk(extra); + working_size += extra; + } + +// now grab the memory + info.address = last_locked + __djgpp_base_address; + + if (!win95) + { + info.size = __djgpp_selector_limit + 1 - last_locked; + + while (info.size > 0 && __dpmi_lock_linear_region(&info)) + { + info.size -= 0x1000; + working_size -= 0x1000; + sbrk(-0x1000); + } + } + else + { /* Win95 section */ + j = COM_CheckParm("-winmem"); + + if (standard_quake) + minmem = MINIMUM_WIN_MEMORY; + else + minmem = MINIMUM_WIN_MEMORY_LEVELPAK; + + if (j) + { + allocsize = ((int)(Q_atoi(com_argv[j+1]))) * 0x100000 + + LOCKED_FOR_MALLOC; + + if (allocsize < (minmem + LOCKED_FOR_MALLOC)) + allocsize = minmem + LOCKED_FOR_MALLOC; + } + else + { + allocsize = minmem + LOCKED_FOR_MALLOC; + } + + if (!lockmem) + { + // we won't lock, just sbrk the memory + info.size = allocsize; + goto UpdateSbrk; + } + + // lock the memory down + write (STDOUT, msg, strlen (msg)); + + for (j=allocsize ; j>(minmem + LOCKED_FOR_MALLOC) ; + j -= 0x100000) + { + info.size = j; + + if (!__dpmi_lock_linear_region(&info)) + goto Locked; + + write (STDOUT, ".", 1); + } + + // finally, try with the absolute minimum amount + for (i=0 ; i<10 ; i++) + { + info.size = minmem + LOCKED_FOR_MALLOC; + + if (!__dpmi_lock_linear_region(&info)) + goto Locked; + } + + Sys_Error ("Can't lock memory; %d Mb lockable RAM required. " + "Try shrinking smartdrv.", info.size / 0x100000); + +Locked: + +UpdateSbrk: + + info.address += info.size; + info.address -= __djgpp_base_address + 4; // ending point, malloc align + working_size = info.address - (int)working_memory; + sbrk(info.address-(int)sbrk(0)); // negative adjustment + } + + + if (lockunlockmem) + { + __dpmi_unlock_linear_region (&info); + printf ("Locked and unlocked %d Mb data\n", working_size / 0x100000); + } + else if (lockmem) + { + printf ("Locked %d Mb data\n", working_size / 0x100000); + } + else + { + printf ("Allocated %d Mb data\n", working_size / 0x100000); + } + +// 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 *)working_memory; + + for (n=0 ; n<4 ; n++) + { + for (m=0 ; m<(working_size - 16 * 0x1000) ; m += 4) + { + sys_checksum += *(int *)&x[m]; + sys_checksum += *(int *)&x[m + 16 * 0x1000]; + } + } + +// give some of what we locked back for malloc before returning. Done +// by cheating and passing a negative value to sbrk + working_size -= LOCKED_FOR_MALLOC; + sbrk( -(LOCKED_FOR_MALLOC)); + *size = working_size; + return working_memory; +} + + +/* +============ +Sys_FileTime + +returns -1 if not present +============ +*/ +int Sys_FileTime (char *path) +{ + struct stat buf; + + if (stat (path,&buf) == -1) + return -1; + + return buf.st_mtime; +} + +void Sys_mkdir (char *path) +{ + mkdir (path, 0777); +} + + +void Sys_Sleep(void) +{ +} + + +char *Sys_ConsoleInput(void) +{ + static char text[256]; + static int len = 0; + char ch; + + if (!isDedicated) + return NULL; + + if (! kbhit()) + return NULL; + + ch = getche(); + + switch (ch) + { + case '\r': + putch('\n'); + if (len) + { + text[len] = 0; + len = 0; + return text; + } + break; + + case '\b': + putch(' '); + if (len) + { + len--; + putch('\b'); + } + break; + + default: + text[len] = ch; + len = (len + 1) & 0xff; + break; + } + + return NULL; +} + +void Sys_Init(void) +{ + + MaskExceptions (); + + Sys_SetFPCW (); + + dos_outportb(0x43, 0x34); // set system timer to mode 2 + dos_outportb(0x40, 0); // for the Sys_FloatTime() function + dos_outportb(0x40, 0); + + Sys_InitFloatTime (); + + _go32_interrupt_stack_size = 4 * 1024;; + _go32_rmcb_stack_size = 4 * 1024; +} + +void Sys_Shutdown(void) +{ + if (!isDedicated) + dos_restoreintr(9); + + if (unlockmem) + { + dos_unlockmem (&start_of_memory, + end_of_memory - (int)&start_of_memory); + dos_unlockmem (quakeparms.membase, quakeparms.memsize); + } +} + + +#define SC_RSHIFT 0x36 +#define SC_LSHIFT 0x2a +void Sys_SendKeyEvents (void) +{ + int k, next; + int outkey; + +// get key events + + while (keybuf_head != keybuf_tail) + { + + k = keybuf[keybuf_tail++]; + keybuf_tail &= (KEYBUF_SIZE-1); + + if (k==0xe0) + continue; // special / pause keys + next = keybuf[(keybuf_tail-2)&(KEYBUF_SIZE-1)]; + if (next == 0xe1) + continue; // pause key bullshit + if (k==0xc5 && next == 0x9d) + { + Key_Event (K_PAUSE, true); + continue; + } + + // extended keyboard shift key bullshit + if ( (k&0x7f)==SC_LSHIFT || (k&0x7f)==SC_RSHIFT ) + { + if ( keybuf[(keybuf_tail-2)&(KEYBUF_SIZE-1)]==0xe0 ) + continue; + k &= 0x80; + k |= SC_RSHIFT; + } + + if (k==0xc5 && keybuf[(keybuf_tail-2)&(KEYBUF_SIZE-1)] == 0x9d) + continue; // more pause bullshit + + outkey = scantokey[k & 0x7f]; + + if (k & 0x80) + Key_Event (outkey, false); + else + Key_Event (outkey, true); + + } + +} + + +// ======================================================================= +// General routines +// ======================================================================= + +/* +================ +Sys_Printf +================ +*/ + +void Sys_Printf (char *fmt, ...) +{ + va_list argptr; + char text[1024]; + + va_start (argptr,fmt); + vsprintf (text,fmt,argptr); + va_end (argptr); + + if (cls.state == ca_dedicated) + fprintf(stderr, "%s", text); +} + +void Sys_AtExit (void) +{ + +// shutdown only once (so Sys_Error can call this function to shutdown, then +// print the error message, then call exit without exit calling this function +// again) + Sys_Shutdown(); +} + + +void Sys_Quit (void) +{ + byte screen[80*25*2]; + byte *d; + char ver[6]; + int i; + + +// load the sell screen before shuting everything down + if (registered.value) + d = COM_LoadHunkFile ("end2.bin"); + else + d = COM_LoadHunkFile ("end1.bin"); + if (d) + memcpy (screen, d, sizeof(screen)); + +// write the version number directly to the end screen + sprintf (ver, " v%4.2f", VERSION); + for (i=0 ; i<6 ; i++) + screen[0*80*2 + 72*2 + i*2] = ver[i]; + + Host_Shutdown(); + +// do the text mode sell screen + if (d) + { + memcpy ((void *)real2ptr(0xb8000), screen,80*25*2); + + // set text pos + regs.x.ax = 0x0200; + regs.h.bh = 0; + regs.h.dl = 0; + regs.h.dh = 22; + dos_int86 (0x10); + } + else + printf ("couldn't load endscreen.\n"); + + exit(0); +} + +void Sys_Error (char *error, ...) +{ + va_list argptr; + char string[1024]; + + va_start (argptr,error); + vsprintf (string,error,argptr); + va_end (argptr); + + Host_Shutdown(); + fprintf(stderr, "Error: %s\n", string); +// Sys_AtExit is called by exit to shutdown the system + exit(0); +} + + +int Sys_FileOpenRead (char *path, int *handle) +{ + int h; + struct stat fileinfo; + + h = open (path, O_RDONLY|O_BINARY, 0666); + *handle = h; + if (h == -1) + return -1; + + if (fstat (h,&fileinfo) == -1) + Sys_Error ("Error fstating %s", path); + + return fileinfo.st_size; +} + +int Sys_FileOpenWrite (char *path) +{ + int handle; + + umask (0); + + handle = open(path,O_RDWR | O_BINARY | O_CREAT | O_TRUNC + , 0666); + + if (handle == -1) + Sys_Error ("Error opening %s: %s", path,strerror(errno)); + + return handle; +} + +void Sys_FileClose (int handle) +{ + close (handle); +} + +void Sys_FileSeek (int handle, int position) +{ + lseek (handle, position, SEEK_SET); +} + +int Sys_FileRead (int handle, void *dest, int count) +{ + return read (handle, dest, count); +} + +int Sys_FileWrite (int handle, void *data, int count) +{ + return write (handle, data, count); +} + +/* +================ +Sys_MakeCodeWriteable +================ +*/ +void Sys_MakeCodeWriteable (unsigned long startaddr, unsigned long length) +{ + // it's always writeable +} + + +/* +================ +Sys_FloatTime +================ +*/ +double Sys_FloatTime (void) +{ + int r; + unsigned t, tick; + double ft, time; + static int sametimecount; + + Sys_PushFPCW_SetHigh (); + +//{static float t = 0; t=t+0.05; return t;} // DEBUG + + t = *(unsigned short*)real2ptr(0x46c) * 65536; + + dos_outportb(0x43, 0); // latch time + r = dos_inportb(0x40); + r |= dos_inportb(0x40) << 8; + r = (r-1) & 0xffff; + + tick = *(unsigned short*)real2ptr(0x46c) * 65536; + if ((tick != t) && (r & 0x8000)) + t = tick; + + ft = (double) (t+(65536-r)) / 1193200.0; + time = ft - oldtime; + oldtime = ft; + + if (time < 0) + { + if (time > -3000.0) + time = 0.0; + else + time += 3600.0; + } + + curtime += time; + + if (curtime == lastcurtime) + { + sametimecount++; + + if (sametimecount > 100000) + { + curtime += 1.0; + sametimecount = 0; + } + } + else + { + sametimecount = 0; + } + + lastcurtime = curtime; + + Sys_PopFPCW (); + + return curtime; +} + + +/* +================ +Sys_InitFloatTime +================ +*/ +void Sys_InitFloatTime (void) +{ + int j; + + Sys_FloatTime (); + + oldtime = curtime; + + j = COM_CheckParm("-starttime"); + + if (j) + { + curtime = (double) (Q_atof(com_argv[j+1])); + } + else + { + curtime = 0.0; + } + lastcurtime = curtime; +} + + +/* +================ +Sys_GetMemory +================ +*/ +void Sys_GetMemory(void) +{ + int j, tsize; + + j = COM_CheckParm("-mem"); + if (j) + { + quakeparms.memsize = (int) (Q_atof(com_argv[j+1]) * 1024 * 1024); + quakeparms.membase = malloc (quakeparms.memsize); + } + else + { + quakeparms.membase = dos_getmaxlockedmem (&quakeparms.memsize); + } + + fprintf(stderr, "malloc'd: %d\n", quakeparms.memsize); + + if (COM_CheckParm ("-heapsize")) + { + tsize = Q_atoi (com_argv[COM_CheckParm("-heapsize") + 1]) * 1024; + + if (tsize < quakeparms.memsize) + quakeparms.memsize = tsize; + } +} + + +/* +================ +Sys_PageInProgram + +walks the text, data, and bss to make sure it's all paged in so that the +actual physical memory detected by Sys_GetMemory is correct. +================ +*/ +void Sys_PageInProgram(void) +{ + int i, j; + + end_of_memory = (int)sbrk(0); + + if (lockmem) + { + if (dos_lockmem ((void *)&start_of_memory, + end_of_memory - (int)&start_of_memory)) + Sys_Error ("Couldn't lock text and data"); + } + + if (lockunlockmem) + { + dos_unlockmem((void *)&start_of_memory, + end_of_memory - (int)&start_of_memory); + printf ("Locked and unlocked %d Mb image\n", + (end_of_memory - (int)&start_of_memory) / 0x100000); + } + else if (lockmem) + { + printf ("Locked %d Mb image\n", + (end_of_memory - (int)&start_of_memory) / 0x100000); + } + else + { + printf ("Loaded %d Mb image\n", + (end_of_memory - (int)&start_of_memory) / 0x100000); + } + +// touch the entire image, doing the 16-page skip so Win95 doesn't think we're +// trying to page ourselves in + for (j=0 ; j<4 ; j++) + { + for(i=(int)&start_of_memory ; i<(end_of_memory - 16 * 0x1000) ; i += 4) + { + sys_checksum += *(int *)i; + sys_checksum += *(int *)(i + 16 * 0x1000); + } + } +} + + +/* +================ +Sys_NoFPUExceptionHandler +================ +*/ +void Sys_NoFPUExceptionHandler(int whatever) +{ + printf ("\nError: Quake requires a floating-point processor\n"); + exit (0); +} + + +/* +================ +Sys_DefaultExceptionHandler +================ +*/ +void Sys_DefaultExceptionHandler(int whatever) +{ +} + + +/* +================ +main +================ +*/ +int main (int c, char **v) +{ + double time, oldtime, newtime; + extern void (*dos_error_func)(char *, ...); + static char cwd[1024]; + + printf ("Quake v%4.2f\n", VERSION); + +// make sure there's an FPU + signal(SIGNOFP, Sys_NoFPUExceptionHandler); + signal(SIGABRT, Sys_DefaultExceptionHandler); + signal(SIGALRM, Sys_DefaultExceptionHandler); + signal(SIGKILL, Sys_DefaultExceptionHandler); + signal(SIGQUIT, Sys_DefaultExceptionHandler); + signal(SIGINT, Sys_DefaultExceptionHandler); + + if (fptest_temp >= 0.0) + fptest_temp += 0.1; + + COM_InitArgv (c, v); + + quakeparms.argc = com_argc; + quakeparms.argv = com_argv; + + dos_error_func = Sys_Error; + + Sys_DetectWin95 (); + Sys_PageInProgram (); + Sys_GetMemory (); + + atexit (Sys_AtExit); // in case we crash + + getwd (cwd); + if (cwd[Q_strlen(cwd)-1] == '/') cwd[Q_strlen(cwd)-1] = 0; + quakeparms.basedir = cwd; //"f:/quake"; + + isDedicated = (COM_CheckParm ("-dedicated") != 0); + + Sys_Init (); + + if (!isDedicated) + dos_registerintr(9, TrapKey); + +//Sys_InitStackCheck (); + + Host_Init(&quakeparms); + +//Sys_StackCheck (); + +//Con_Printf ("Top of stack: 0x%x\n", &time); + oldtime = Sys_FloatTime (); + while (1) + { + newtime = Sys_FloatTime (); + time = newtime - oldtime; + + if (cls.state == ca_dedicated && (time +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "quakedef.h" + +qboolean isDedicated; + +int nostdout = 0; + +char *basedir = "."; +char *cachedir = "/tmp"; + +cvar_t sys_linerefresh = {"sys_linerefresh","0"};// set for entity display + +// ======================================================================= +// General routines +// ======================================================================= + +void Sys_DebugNumber(int y, int val) +{ +} + +/* +void Sys_Printf (char *fmt, ...) +{ + va_list argptr; + char text[1024]; + + va_start (argptr,fmt); + vsprintf (text,fmt,argptr); + va_end (argptr); + fprintf(stderr, "%s", text); + + Con_Print (text); +} + +void Sys_Printf (char *fmt, ...) +{ + + va_list argptr; + char text[1024], *t_p; + int l, r; + + if (nostdout) + return; + + va_start (argptr,fmt); + vsprintf (text,fmt,argptr); + va_end (argptr); + + l = strlen(text); + t_p = text; + +// make sure everything goes through, even though we are non-blocking + while (l) + { + r = write (1, text, l); + if (r != l) + sleep (0); + if (r > 0) + { + t_p += r; + l -= r; + } + } + +} +*/ + +void Sys_Printf (char *fmt, ...) +{ + va_list argptr; + char text[1024]; + unsigned char *p; + + va_start (argptr,fmt); + vsprintf (text,fmt,argptr); + va_end (argptr); + + if (strlen(text) > sizeof(text)) + Sys_Error("memory overwrite in Sys_Printf"); + + if (nostdout) + return; + + for (p = (unsigned char *)text; *p; p++) { + *p &= 0x7f; + if ((*p > 128 || *p < 32) && *p != 10 && *p != 13 && *p != 9) + printf("[%02x]", *p); + else + putc(*p, stdout); + } +} + +#if 0 +static char end1[] = +"\x1b[?7h\x1b[40m\x1b[2J\x1b[0;1;41m\x1b[1;1H QUAKE: The Doomed Dimension \x1b[33mby \x1b[44mid\x1b[41m Software \x1b[2;1H ---------------------------------------------------------------------------- \x1b[3;1H CALL 1-800-IDGAMES TO ORDER OR FOR TECHNICAL SUPPORT \x1b[4;1H PRICE: $45.00 (PRICES MAY VARY OUTSIDE THE US.) \x1b[5;1H \x1b[6;1H \x1b[37mYes! You only have one fourth of this incredible epic. That is because most \x1b[7;1H of you have paid us nothing or at most, very little. You could steal the \x1b[8;1H game from a friend. But we both know you'll be punished by God if you do. \x1b[9;1H \x1b[33mWHY RISK ETERNAL DAMNATION? CALL 1-800-IDGAMES AND BUY NOW! \x1b[10;1H \x1b[37mRemember, we love you almost as much as He does. \x1b[11;1H \x1b[12;1H \x1b[33mProgramming: \x1b[37mJohn Carmack, Michael Abrash, John Cash \x1b[13;1H \x1b[33mDesign: \x1b[37mJohn Romero, Sandy Petersen, American McGee, Tim Willits \x1b[14;1H \x1b[33mArt: \x1b[37mAdrian Carmack, Kevin Cloud \x1b[15;1H \x1b[33mBiz: \x1b[37mJay Wilbur, Mike Wilson, Donna Jackson \x1b[16;1H \x1b[33mProjects: \x1b[37mShawn Green \x1b[33mSupport: \x1b[37mBarrett Alexander \x1b[17;1H \x1b[33mSound Effects: \x1b[37mTrent Reznor and Nine Inch Nails \x1b[18;1H For other information or details on ordering outside the US, check out the \x1b[19;1H files accompanying QUAKE or our website at http://www.idsoftware.com. \x1b[20;1H \x1b[0;41mQuake is a trademark of Id Software, inc., (c)1996 Id Software, inc. \x1b[21;1H All rights reserved. NIN logo is a registered trademark licensed to \x1b[22;1H Nothing Interactive, Inc. All rights reserved. \x1b[40m\x1b[23;1H\x1b[0m"; +static char end2[] = +"\x1b[?7h\x1b[40m\x1b[2J\x1b[0;1;41m\x1b[1;1H QUAKE \x1b[33mby \x1b[44mid\x1b[41m Software \x1b[2;1H ----------------------------------------------------------------------------- \x1b[3;1H \x1b[37mWhy did you quit from the registered version of QUAKE? Did the \x1b[4;1H scary monsters frighten you? Or did Mr. Sandman tug at your \x1b[5;1H little lids? No matter! What is important is you love our \x1b[6;1H game, and gave us your money. Congratulations, you are probably \x1b[7;1H not a thief. \x1b[8;1H Thank You. \x1b[9;1H \x1b[33;44mid\x1b[41m Software is: \x1b[10;1H PROGRAMMING: \x1b[37mJohn Carmack, Michael Abrash, John Cash \x1b[11;1H \x1b[33mDESIGN: \x1b[37mJohn Romero, Sandy Petersen, American McGee, Tim Willits \x1b[12;1H \x1b[33mART: \x1b[37mAdrian Carmack, Kevin Cloud \x1b[13;1H \x1b[33mBIZ: \x1b[37mJay Wilbur, Mike Wilson \x1b[33mPROJECTS MAN: \x1b[37mShawn Green \x1b[14;1H \x1b[33mBIZ ASSIST: \x1b[37mDonna Jackson \x1b[33mSUPPORT: \x1b[37mBarrett Alexander \x1b[15;1H \x1b[33mSOUND EFFECTS AND MUSIC: \x1b[37mTrent Reznor and Nine Inch Nails \x1b[16;1H \x1b[17;1H If you need help running QUAKE refer to the text files in the \x1b[18;1H QUAKE directory, or our website at http://www.idsoftware.com. \x1b[19;1H If all else fails, call our technical support at 1-800-IDGAMES. \x1b[20;1H \x1b[0;41mQuake is a trademark of Id Software, inc., (c)1996 Id Software, inc. \x1b[21;1H All rights reserved. NIN logo is a registered trademark licensed \x1b[22;1H to Nothing Interactive, Inc. All rights reserved. \x1b[23;1H\x1b[40m\x1b[0m"; + +#endif +void Sys_Quit (void) +{ + Host_Shutdown(); + fcntl (0, F_SETFL, fcntl (0, F_GETFL, 0) & ~FNDELAY); +#if 0 + if (registered.value) + printf("%s", end2); + else + printf("%s", end1); +#endif + fflush(stdout); + exit(0); +} + +void Sys_Init(void) +{ +#if id386 + Sys_SetFPCW(); +#endif +} + +void Sys_Error (char *error, ...) +{ + va_list argptr; + char string[1024]; + +// change stdin to non blocking + fcntl (0, F_SETFL, fcntl (0, F_GETFL, 0) & ~FNDELAY); + + va_start (argptr,error); + vsprintf (string,error,argptr); + va_end (argptr); + fprintf(stderr, "Error: %s\n", string); + + Host_Shutdown (); + exit (1); + +} + +void Sys_Warn (char *warning, ...) +{ + va_list argptr; + char string[1024]; + + va_start (argptr,warning); + vsprintf (string,warning,argptr); + va_end (argptr); + fprintf(stderr, "Warning: %s", string); +} + +/* +============ +Sys_FileTime + +returns -1 if not present +============ +*/ +int Sys_FileTime (char *path) +{ + struct stat buf; + + if (stat (path,&buf) == -1) + return -1; + + return buf.st_mtime; +} + + +void Sys_mkdir (char *path) +{ + mkdir (path, 0777); +} + +int Sys_FileOpenRead (char *path, int *handle) +{ + int h; + struct stat fileinfo; + + + h = open (path, O_RDONLY, 0666); + *handle = h; + if (h == -1) + return -1; + + if (fstat (h,&fileinfo) == -1) + Sys_Error ("Error fstating %s", path); + + return fileinfo.st_size; +} + +int Sys_FileOpenWrite (char *path) +{ + int handle; + + umask (0); + + handle = open(path,O_RDWR | O_CREAT | O_TRUNC + , 0666); + + if (handle == -1) + Sys_Error ("Error opening %s: %s", path,strerror(errno)); + + return handle; +} + +int Sys_FileWrite (int handle, void *src, int count) +{ + return write (handle, src, count); +} + +void Sys_FileClose (int handle) +{ + close (handle); +} + +void Sys_FileSeek (int handle, int position) +{ + lseek (handle, position, SEEK_SET); +} + +int Sys_FileRead (int handle, void *dest, int count) +{ + return read (handle, dest, count); +} + +void Sys_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_BINARY | O_CREAT | O_APPEND, 0666); + fd = open(file, O_WRONLY | O_CREAT | O_APPEND, 0666); + write(fd, data, strlen(data)); + close(fd); +} + +void Sys_EditFile(char *filename) +{ + + char cmd[256]; + char *term; + char *editor; + + term = getenv("TERM"); + if (term && !strcmp(term, "xterm")) + { + editor = getenv("VISUAL"); + if (!editor) + editor = getenv("EDITOR"); + if (!editor) + editor = getenv("EDIT"); + if (!editor) + editor = "vi"; + sprintf(cmd, "xterm -e %s %s", editor, filename); + system(cmd); + } + +} + +double Sys_FloatTime (void) +{ + struct timeval tp; + struct timezone tzp; + static int secbase; + + gettimeofday(&tp, &tzp); + + if (!secbase) + { + secbase = tp.tv_sec; + return tp.tv_usec/1000000.0; + } + + return (tp.tv_sec - secbase) + tp.tv_usec/1000000.0; +} + +// ======================================================================= +// Sleeps for microseconds +// ======================================================================= + +static volatile int oktogo; + +void alarm_handler(int x) +{ + oktogo=1; +} + +void Sys_LineRefresh(void) +{ +} + +void floating_point_exception_handler(int whatever) +{ +// Sys_Warn("floating point exception\n"); + signal(SIGFPE, floating_point_exception_handler); +} + +char *Sys_ConsoleInput(void) +{ + static char text[256]; + int len; + fd_set fdset; + struct timeval timeout; + + if (cls.state == ca_dedicated) { + FD_ZERO(&fdset); + FD_SET(0, &fdset); // stdin + timeout.tv_sec = 0; + timeout.tv_usec = 0; + if (select (1, &fdset, NULL, NULL, &timeout) == -1 || !FD_ISSET(0, &fdset)) + return NULL; + + len = read (0, text, sizeof(text)); + if (len < 1) + return NULL; + text[len-1] = 0; // rip off the /n and terminate + + return text; + } + return NULL; +} + +#if !id386 +void Sys_HighFPPrecision (void) +{ +} + +void Sys_LowFPPrecision (void) +{ +} +#endif + +int main (int c, char **v) +{ + + double time, oldtime, newtime; + quakeparms_t parms; + extern int vcrFile; + extern int recording; + int j; + +// static char cwd[1024]; + +// signal(SIGFPE, floating_point_exception_handler); + signal(SIGFPE, SIG_IGN); + + memset(&parms, 0, sizeof(parms)); + + COM_InitArgv(c, v); + parms.argc = com_argc; + parms.argv = com_argv; + +#ifdef GLQUAKE + parms.memsize = 16*1024*1024; +#else + parms.memsize = 8*1024*1024; +#endif + + j = COM_CheckParm("-mem"); + if (j) + parms.memsize = (int) (Q_atof(com_argv[j+1]) * 1024 * 1024); + parms.membase = malloc (parms.memsize); + + parms.basedir = basedir; +// caching is disabled by default, use -cachedir to enable +// parms.cachedir = cachedir; + + fcntl(0, F_SETFL, fcntl (0, F_GETFL, 0) | FNDELAY); + + Host_Init(&parms); + + Sys_Init(); + + if (COM_CheckParm("-nostdout")) + nostdout = 1; + else { + fcntl(0, F_SETFL, fcntl (0, F_GETFL, 0) | FNDELAY); + printf ("Linux Quake -- Version %0.3f\n", LINUX_VERSION); + } + + oldtime = Sys_FloatTime () - 0.1; + while (1) + { +// find time spent rendering last frame + newtime = Sys_FloatTime (); + time = newtime - oldtime; + + if (cls.state == ca_dedicated) + { // play vcrfiles at max speed + if (time < sys_ticrate.value && (vcrFile == -1 || recording) ) + { + usleep(1); + continue; // not time to run a server only tic yet + } + time = sys_ticrate.value; + } + + if (time > sys_ticrate.value*2) + oldtime = newtime; + else + oldtime += time; + + Host_Frame (time); + +// graphic debugging aids + if (sys_linerefresh.value) + Sys_LineRefresh (); + } + +} + + +/* +================ +Sys_MakeCodeWriteable +================ +*/ +void Sys_MakeCodeWriteable (unsigned long startaddr, unsigned long length) +{ + + int r; + unsigned long addr; + int psize = getpagesize(); + + addr = (startaddr & ~(psize-1)) - psize; + +// fprintf(stderr, "writable code %lx(%lx)-%lx, length=%lx\n", startaddr, +// addr, startaddr+length, length); + + r = mprotect((char*)addr, length + startaddr - addr + psize, 7); + + if (r < 0) + Sys_Error("Protection change failed\n"); + +} + diff --git a/contrib/other/sdlquake-1.0.9/sys_null.c b/contrib/other/sdlquake-1.0.9/sys_null.c new file mode 100644 index 000000000..057d61de7 --- /dev/null +++ b/contrib/other/sdlquake-1.0.9/sys_null.c @@ -0,0 +1,232 @@ +/* +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_null.h -- null system driver to aid porting efforts + +#include "quakedef.h" +#include "errno.h" + +/* +=============================================================================== + +FILE IO + +=============================================================================== +*/ + +#define MAX_HANDLES 10 +FILE *sys_handles[MAX_HANDLES]; + +int findhandle (void) +{ + int i; + + for (i=1 ; i +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#if !defined(__WIN32__) && !defined(_KOLIBRI) +#include +#include +#include +#include +#include +#endif + +#include "quakedef.h" + +qboolean isDedicated; + +int noconinput = 0; + +char *basedir = "."; + +cvar_t sys_linerefresh = {"sys_linerefresh","0"};// set for entity display +cvar_t sys_nostdout = {"sys_nostdout","0"}; + +// ======================================================================= +// General routines +// ======================================================================= + +void Sys_DebugNumber(int y, int val) +{ +} + +void Sys_Printf (char *fmt, ...) +{ + va_list argptr; + char text[1024]; + + va_start (argptr,fmt); + vsprintf (text,fmt,argptr); + va_end (argptr); +#ifdef _KOLIBRI + __menuet__debug_out(text); +#else + fprintf(stderr, "%s", text); +#endif + + //Con_Print (text); +} + +void Sys_Quit (void) +{ + Host_Shutdown(); + exit(0); +} + +void Sys_Init(void) +{ +#if id386 + Sys_SetFPCW(); +#endif +} + +#if !id386 + +/* +================ +Sys_LowFPPrecision +================ +*/ +void Sys_LowFPPrecision (void) +{ +// causes weird problems on Nextstep +} + + +/* +================ +Sys_HighFPPrecision +================ +*/ +void Sys_HighFPPrecision (void) +{ +// causes weird problems on Nextstep +} + +#endif // !id386 + + +void Sys_Error (char *error, ...) +{ + va_list argptr; + char string[1024]; + + va_start (argptr,error); + vsprintf (string,error,argptr); + va_end (argptr); +#ifdef _KOLIBRI + __menuet__debug_out("Error: "); + __menuet__debug_out(string); + __menuet__debug_out("\n"); +#else + fprintf(stderr, "Error: %s\n", string); +#endif + + Host_Shutdown (); + exit (1); + +} + +void Sys_Warn (char *warning, ...) +{ + va_list argptr; + char string[1024]; + + va_start (argptr,warning); + vsprintf (string,warning,argptr); + va_end (argptr); +#ifdef _KOLIBRI + __menuet__debug_out("Warning: "); + __menuet__debug_out(string); +#else + fprintf(stderr, "Warning: %s", string); +#endif +} + +/* +=============================================================================== + +FILE IO + +=============================================================================== +*/ + +#define MAX_HANDLES 10 +FILE *sys_handles[MAX_HANDLES]; + +int findhandle (void) +{ + int i; + + for (i=1 ; i= 0 ) { + fclose (sys_handles[handle]); + sys_handles[handle] = NULL; + } +} + +void Sys_FileSeek (int handle, int position) +{ + if ( handle >= 0 ) { + fseek (sys_handles[handle], position, SEEK_SET); + } +} + +int Sys_FileRead (int handle, void *dst, int count) +{ + char *data; + int size, done; + + size = 0; + if ( handle >= 0 ) { + data = dst; + while ( count > 0 ) { + done = fread (data, 1, count, sys_handles[handle]); + if ( done == 0 ) { + break; + } + data += done; + count -= done; + size += done; + } + } + return size; + +} + +int Sys_FileWrite (int handle, void *src, int count) +{ + char *data; + int size, done; + + size = 0; + if ( handle >= 0 ) { + data = src; + while ( count > 0 ) { + done = fread (data, 1, count, sys_handles[handle]); + if ( done == 0 ) { + break; + } + data += done; + count -= done; + size += done; + } + } + return size; +} + +int Sys_FileTime (char *path) +{ + FILE *f; + + f = fopen(path, "rb"); + if (f) + { + fclose(f); + return 1; + } + + return -1; +} + +void Sys_mkdir (char *path) +{ +#ifdef __WIN32__ + mkdir (path); +#else + mkdir (path, 0777); +#endif +} + +void Sys_DebugLog(char *file, char *fmt, ...) +{ + va_list argptr; + static char data[1024]; + FILE *fp; + + va_start(argptr, fmt); + vsprintf(data, fmt, argptr); + va_end(argptr); + fp = fopen(file, "a"); + fwrite(data, strlen(data), 1, fp); + fclose(fp); +} + +double Sys_FloatTime (void) +{ +#if defined(_KOLIBRI) + static int starttime = 0; + + if ( ! starttime ) + __asm__ __volatile__("int $0x40" : "=a"(starttime) : "a"(26), "b"(9)); + + int curtime; + __asm__ __volatile__("int $0x40" : "=a"(curtime) : "a"(26), "b"(9)); + return (curtime-starttime)*0.01; +#elif defined(__WIN32__) + + static int starttime = 0; + + if ( ! starttime ) + starttime = clock(); + + return (clock()-starttime)*1.0/1024; + +#else + + struct timeval tp; + struct timezone tzp; + static int secbase; + + gettimeofday(&tp, &tzp); + + if (!secbase) + { + secbase = tp.tv_sec; + return tp.tv_usec/1000000.0; + } + + return (tp.tv_sec - secbase) + tp.tv_usec/1000000.0; + +#endif +} + +// ======================================================================= +// Sleeps for microseconds +// ======================================================================= + +static volatile int oktogo; + +void alarm_handler(int x) +{ + oktogo=1; +} + +byte *Sys_ZoneBase (int *size) +{ + + char *QUAKEOPT = getenv("QUAKEOPT"); + + *size = 0xc00000; + if (QUAKEOPT) + { + while (*QUAKEOPT) + if (tolower(*QUAKEOPT++) == 'm') + { + *size = atof(QUAKEOPT) * 1024*1024; + break; + } + } + return malloc (*size); + +} + +void Sys_LineRefresh(void) +{ +} + +void Sys_Sleep(void) +{ +#ifdef _KOLIBRI + __menuet__delay100(1); +#else + SDL_Delay(1); +#endif +} + +#ifndef _KOLIBRI +void floating_point_exception_handler(int whatever) +{ +// Sys_Warn("floating point exception\n"); + signal(SIGFPE, floating_point_exception_handler); +} +#endif + +void moncontrol(int x) +{ +} + +int main (int c, char **v) +{ + + double time, oldtime, newtime; + quakeparms_t parms; + extern int vcrFile; + extern qboolean recording; + static int frame; + + moncontrol(0); + +#ifndef _KOLIBRI +// signal(SIGFPE, floating_point_exception_handler); + signal(SIGFPE, SIG_IGN); +#endif + + parms.memsize = 8*1024*1024; + parms.membase = malloc (parms.memsize); + parms.basedir = basedir; + parms.cachedir = NULL; + + COM_InitArgv(c, v); + parms.argc = com_argc; + parms.argv = com_argv; + + Sys_Init(); + + Host_Init(&parms); + + Cvar_RegisterVariable (&sys_nostdout); + + oldtime = Sys_FloatTime () - 0.1; + while (1) + { +// find time spent rendering last frame + newtime = Sys_FloatTime (); + time = newtime - oldtime; + + if (cls.state == ca_dedicated) + { // play vcrfiles at max speed + if (time < sys_ticrate.value && (vcrFile == -1 || recording) ) + { +#ifdef _KOLIBRI + __menuet__delay100(1); +#else + SDL_Delay (1); +#endif + continue; // not time to run a server only tic yet + } + time = sys_ticrate.value; + } + + if (time > sys_ticrate.value*2) + oldtime = newtime; + else + oldtime += time; + + if (++frame > 10) + moncontrol(1); // profile only while we do each Quake frame + Host_Frame (time); + moncontrol(0); + +// graphic debugging aids + if (sys_linerefresh.value) + Sys_LineRefresh (); + } + +} + + +/* +================ +Sys_MakeCodeWriteable +================ +*/ +void Sys_MakeCodeWriteable (unsigned long startaddr, unsigned long length) +{ +#ifndef _KOLIBRI + int r; + unsigned long addr; + int psize = getpagesize(); + + fprintf(stderr, "writable code %lx-%lx\n", startaddr, startaddr+length); + + addr = startaddr & ~(psize-1); + + r = mprotect((char*)addr, length + startaddr - addr, 7); + + if (r < 0) + Sys_Error("Protection change failed\n"); +#endif +} + diff --git a/contrib/other/sdlquake-1.0.9/sys_sun.c b/contrib/other/sdlquake-1.0.9/sys_sun.c new file mode 100644 index 000000000..48cf8281d --- /dev/null +++ b/contrib/other/sdlquake-1.0.9/sys_sun.c @@ -0,0 +1,352 @@ +/* +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_sun.h -- Sun system driver + +#include "quakedef.h" +#include "errno.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +qboolean isDedicated; + +/* +=============================================================================== + +FILE IO + +=============================================================================== +*/ + +#define MAX_HANDLES 10 + +typedef struct +{ + FILE *hFile; + char *pMap; + int nLen; + int nPos; +} MEMFILE; + +MEMFILE sys_handles[MAX_HANDLES]; + +int findhandle (void) +{ + int i; + + for (i=1 ; i sys_handles[handle].nLen) + count = sys_handles[handle].nLen - nPos; + memcpy( dest, &sys_handles[handle].pMap[nPos], count ); + sys_handles[handle].nPos = nPos + count; + return( count ); + } + else return fread (dest, 1, count, sys_handles[handle].hFile); +} + +int Sys_FileWrite (int handle, void *data, int count) +{ + if (sys_handles[handle].pMap) + Sys_Error( "Attempted to write to read-only file %d!\n", handle ); + return fwrite (data, 1, count, sys_handles[handle].hFile); +} + +int Sys_FileTime (char *path) +{ + FILE *f; + + f = fopen(path, "rb"); + if (f) + { + fclose(f); + return 1; + } + + return -1; +} + +void Sys_mkdir (char *path) +{ + mkdir( path, 0777 ); +} + +/* +=============================================================================== + +SYSTEM IO + +=============================================================================== +*/ + +void Sys_MakeCodeWriteable (unsigned long startaddr, unsigned long length) +{ + + int r; + unsigned long addr; + int psize = getpagesize(); + + addr = (startaddr & ~(psize-1)) - psize; + +// fprintf(stderr, "writable code %lx(%lx)-%lx, length=%lx\n", startaddr, +// addr, startaddr+length, length); + + r = mprotect((char*)addr, length + startaddr - addr + psize, 7); + + if (r < 0) + Sys_Error("Protection change failed\n"); + +} + + +void Sys_Error (char *error, ...) +{ + va_list argptr; + + printf ("Sys_Error: "); + va_start (argptr,error); + vprintf (error,argptr); + va_end (argptr); + printf ("\n"); + Host_Shutdown(); + exit (1); +} + +void Sys_Printf (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_FloatTime (void) +{ + struct timeval tp; + struct timezone tzp; + static int secbase; + + gettimeofday(&tp, &tzp); + + if (!secbase) + { + secbase = tp.tv_sec; + return tp.tv_usec/1000000.0; + } + + return (tp.tv_sec - secbase) + tp.tv_usec/1000000.0; +} + +char *Sys_ConsoleInput (void) +{ + static char text[256]; + int len; + fd_set readfds; + int ready; + struct timeval timeout; + + timeout.tv_sec = 0; + timeout.tv_usec = 0; + FD_ZERO(&readfds); + FD_SET(0, &readfds); + ready = select(1, &readfds, 0, 0, &timeout); + + if (ready>0) + { + len = read (0, text, sizeof(text)); + if (len >= 1) + { + text[len-1] = 0; // rip off the /n and terminate + return text; + } + } + + return 0; +} + +void Sys_Sleep (void) +{ +} + +#if !id386 +void Sys_HighFPPrecision (void) +{ +} + +void Sys_LowFPPrecision (void) +{ +} +#endif + +void Sys_Init(void) +{ +#if id386 + Sys_SetFPCW(); +#endif +} + +//============================================================================= + +int main (int argc, char **argv) +{ + static quakeparms_t parms; + float time, oldtime, newtime; + + parms.memsize = 16*1024*1024; + parms.membase = malloc (parms.memsize); + parms.basedir = "."; + parms.cachedir = NULL; + + COM_InitArgv (argc, argv); + + parms.argc = com_argc; + parms.argv = com_argv; + + printf ("Host_Init\n"); + Host_Init (&parms); + + Sys_Init(); + + // unroll the simulation loop to give the video side a chance to see _vid_default_mode + Host_Frame( 0.1 ); + VID_SetDefaultMode(); + + oldtime = Sys_FloatTime(); + while (1) + { + newtime = Sys_FloatTime(); + Host_Frame (newtime - oldtime); + oldtime = newtime; + } + return 0; +} + + + + diff --git a/contrib/other/sdlquake-1.0.9/sys_win.c b/contrib/other/sdlquake-1.0.9/sys_win.c new file mode 100644 index 000000000..bd9d94b87 --- /dev/null +++ b/contrib/other/sdlquake-1.0.9/sys_win.c @@ -0,0 +1,893 @@ +/* +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 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; + +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 MaskExceptions (void); +void Sys_InitFloatTime (void); +void Sys_PushFPCW_SetHigh (void); +void Sys_PopFPCW (void); + +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 + +=============================================================================== +*/ + +#define MAX_HANDLES 10 +FILE *sys_handles[MAX_HANDLES]; + +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 (); + + 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; +} + + +void Sys_Error (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 (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 (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 (void) +{ + static int sametimecount; + static unsigned int oldtime; + static int first = 1; + LARGE_INTEGER PerformanceCount; + unsigned int temp, t2; + double time; + + Sys_PushFPCW_SetHigh (); + + 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; + } + } + + Sys_PopFPCW (); + + 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/contrib/other/sdlquake-1.0.9/sys_wina.S b/contrib/other/sdlquake-1.0.9/sys_wina.S new file mode 100644 index 000000000..e9ba61894 --- /dev/null +++ b/contrib/other/sdlquake-1.0.9/sys_wina.S @@ -0,0 +1,116 @@ +/* +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_wina.s +// x86 assembly-language Win-dependent routines. + +#define GLQUAKE 1 // don't include unneeded defs +#include "asm_i386.h" +#include "quakeasm.h" + +// LATER should be id386-dependent, and have an equivalent C path + + .data + + .align 4 +fpenv: + .long 0, 0, 0, 0, 0, 0, 0, 0 + + .text + +.globl C(MaskExceptions) +C(MaskExceptions): + fnstenv fpenv + orl $0x3F,fpenv + fldenv fpenv + + ret + +#if 0 +.globl C(unmaskexceptions) +C(unmaskexceptions): + fnstenv fpenv + andl $0xFFFFFFE0,fpenv + fldenv fpenv + + ret +#endif + + .data + + .align 4 +.globl ceil_cw, single_cw, full_cw, cw, pushed_cw +ceil_cw: .long 0 +single_cw: .long 0 +full_cw: .long 0 +cw: .long 0 +pushed_cw: .long 0 + + .text + +.globl C(Sys_LowFPPrecision) +C(Sys_LowFPPrecision): + fldcw single_cw + + ret + +.globl C(Sys_HighFPPrecision) +C(Sys_HighFPPrecision): + fldcw full_cw + + ret + +.globl C(Sys_PushFPCW_SetHigh) +C(Sys_PushFPCW_SetHigh): + fnstcw pushed_cw + fldcw full_cw + + ret + +.globl C(Sys_PopFPCW) +C(Sys_PopFPCW): + fldcw pushed_cw + + ret + +.globl C(Sys_SetFPCW) +C(Sys_SetFPCW): + fnstcw cw + movl cw,%eax +#if id386 + andb $0xF0,%ah + orb $0x03,%ah // round mode, 64-bit precision +#endif + movl %eax,full_cw + +#if id386 + andb $0xF0,%ah + orb $0x0C,%ah // chop mode, single precision +#endif + movl %eax,single_cw + +#if id386 + andb $0xF0,%ah + orb $0x08,%ah // ceil mode, single precision +#endif + movl %eax,ceil_cw + + ret + diff --git a/contrib/other/sdlquake-1.0.9/sys_wind.c b/contrib/other/sdlquake-1.0.9/sys_wind.c new file mode 100644 index 000000000..ccce22b40 --- /dev/null +++ b/contrib/other/sdlquake-1.0.9/sys_wind.c @@ -0,0 +1,325 @@ +/* +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_null.h -- null system driver to aid porting efforts + +#include "quakedef.h" +#include "winquake.h" +#include "errno.h" +#include +#include + + +/* +=============================================================================== + +FILE IO + +=============================================================================== +*/ + +#define MAX_HANDLES 10 +FILE *sys_handles[MAX_HANDLES]; + +int findhandle (void) +{ + int i; + + for (i=1 ; i 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/contrib/other/sdlquake-1.0.9/vid_dos.c b/contrib/other/sdlquake-1.0.9/vid_dos.c new file mode 100644 index 000000000..bf4293ffc --- /dev/null +++ b/contrib/other/sdlquake-1.0.9/vid_dos.c @@ -0,0 +1,778 @@ +/* +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_dos.c: DOS-specific video routines +// + +#include +#include +#include +#include +#include +#include +#include + +#include "quakedef.h" +#include "d_local.h" +#include "dosisms.h" +#include "vid_dos.h" + +int vid_modenum; +vmode_t *pcurrentmode = NULL; +int vid_testingmode, vid_realmode; +double vid_testendtime; + +cvar_t vid_mode = {"vid_mode","0", false}; +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_default_mode = {"_vid_default_mode","0", true}; +cvar_t _vid_default_mode_win = {"_vid_default_mode_win","1", 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","0", true}; +cvar_t vid_fullscreen_mode = {"vid_fullscreen_mode","3", true}; +cvar_t vid_windowed_mode = {"vid_windowed_mode","0", true}; +cvar_t block_switch = {"block_switch","0", true}; +cvar_t vid_window_x = {"vid_window_x", "0", true}; +cvar_t vid_window_y = {"vid_window_y", "0", true}; + +int d_con_indirect = 0; + +int numvidmodes; +vmode_t *pvidmodes; + +static int firstupdate = 1; + +extern regs_t regs; + +void VID_TestMode_f (void); +void VID_NumModes_f (void); +void VID_DescribeCurrentMode_f (void); +void VID_DescribeMode_f (void); +void VID_DescribeModes_f (void); + +byte vid_current_palette[768]; // save for mode changes + + +static qboolean nomodecheck = false; + +unsigned short d_8to16table[256]; // not used in 8 bpp mode +unsigned d_8to24table[256]; // not used in 8 bpp mode + +void VID_MenuDraw (void); +void VID_MenuKey (int key); + + +/* +================ +VID_Init +================ +*/ +void VID_Init (unsigned char *palette) +{ + 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 (&vid_fullscreen_mode); + Cvar_RegisterVariable (&vid_windowed_mode); + Cvar_RegisterVariable (&block_switch); + + Cmd_AddCommand ("vid_testmode", VID_TestMode_f); + 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); + +// set up the mode list; note that later inits link in their modes ahead of +// earlier ones, so the standard VGA modes are always first in the list. This +// is important because mode 0 must always be VGA mode 0x13 + if (!COM_CheckParm ("-stdvid")) + VID_InitExtra (); + VGA_Init (); + + vid_testingmode = 0; + + vid_modenum = vid_mode.value; + + VID_SetMode (vid_modenum, palette); + + vid_realmode = vid_modenum; + + vid_menudrawfn = VID_MenuDraw; + vid_menukeyfn = VID_MenuKey; +} + + +/* +================= +VID_GetModePtr +================= +*/ +vmode_t *VID_GetModePtr (int modenum) +{ + vmode_t *pv; + + pv = pvidmodes; + if (!pv) + Sys_Error ("VID_GetModePtr: empty vid mode list"); + + while (modenum--) + { + pv = pv->pnext; + if (!pv) + Sys_Error ("VID_GetModePtr: corrupt vid mode list"); + } + + return pv; +} + +/* +================ +VID_NumModes +================ +*/ +int VID_NumModes () +{ + return (numvidmodes); +} + + +/* +================ +VID_ModeInfo +================ +*/ +char *VID_ModeInfo (int modenum, char **ppheader) +{ + static char *badmodestr = "Bad mode number"; + vmode_t *pv; + + pv = VID_GetModePtr (modenum); + + if (!pv) + { + if (ppheader) + *ppheader = NULL; + return badmodestr; + } + else + { + if (ppheader) + *ppheader = pv->header; + return pv->name; + } +} + + +/* +================ +VID_SetMode +================ +*/ +int VID_SetMode (int modenum, unsigned char *palette) +{ + int stat; + vmode_t *pnewmode, *poldmode; + + if ((modenum >= numvidmodes) || (modenum < 0)) + { + Cvar_SetValue ("vid_mode", (float)vid_modenum); + + nomodecheck = true; + Con_Printf ("No such video mode: %d\n", modenum); + nomodecheck = false; + + if (pcurrentmode == NULL) + { + modenum = 0; // mode hasn't been set yet, so initialize to base + // mode since they gave us an invalid initial mode + } + else + { + return 0; + } + } + + pnewmode = VID_GetModePtr (modenum); + + if (pnewmode == pcurrentmode) + return 1; // already in the desired mode + +// initialize the new mode + poldmode = pcurrentmode; + pcurrentmode = pnewmode; + + vid.width = pcurrentmode->width; + vid.height = pcurrentmode->height; + vid.aspect = pcurrentmode->aspect; + vid.rowbytes = pcurrentmode->rowbytes; + + stat = (*pcurrentmode->setmode) (&vid, pcurrentmode); + + if (stat < 1) + { + if (stat == 0) + { + // real, hard failure that requires resetting the mode + if (!VID_SetMode (vid_modenum, palette)) // restore prior mode + Sys_Error ("VID_SetMode: Unable to set any mode, probably " + "because there's not enough memory available"); + Con_Printf ("Failed to set mode %d\n", modenum); + return 0; + } + else if (stat == -1) + { + // not enough memory; just put things back the way they were + pcurrentmode = poldmode; + vid.width = pcurrentmode->width; + vid.height = pcurrentmode->height; + vid.aspect = pcurrentmode->aspect; + vid.rowbytes = pcurrentmode->rowbytes; + return 0; + } + else + { + Sys_Error ("VID_SetMode: invalid setmode return code %d"); + } + } + + (*pcurrentmode->setpalette) (&vid, pcurrentmode, palette); + + vid_modenum = modenum; + Cvar_SetValue ("vid_mode", (float)vid_modenum); + + nomodecheck = true; + Con_Printf ("%s\n", VID_ModeInfo (vid_modenum, NULL)); + nomodecheck = false; + + vid.recalc_refdef = 1; + + return 1; +} + + +/* +================ +VID_SetPalette +================ +*/ +void VID_SetPalette (unsigned char *palette) +{ + if (palette != vid_current_palette) + Q_memcpy(vid_current_palette, palette, 768); + (*pcurrentmode->setpalette)(&vid, pcurrentmode, vid_current_palette); +} + + +/* +================ +VID_ShiftPalette +================ +*/ +void VID_ShiftPalette (unsigned char *palette) +{ + + VID_SetPalette (palette); +} + + +/* +================ +VID_Shutdown +================ +*/ +void VID_Shutdown (void) +{ + + regs.h.ah = 0; + regs.h.al = 0x3; + dos_int86(0x10); + + vid_testingmode = 0; +} + + +/* +================ +VID_Update +================ +*/ +void VID_Update (vrect_t *rects) +{ + if (firstupdate && _vid_default_mode.value) + { + if(_vid_default_mode.value >= numvidmodes) + Cvar_SetValue ("_vid_default_mode", 0); + + firstupdate = 0; + Cvar_SetValue ("vid_mode", _vid_default_mode.value); + } + + (*pcurrentmode->swapbuffers)(&vid, pcurrentmode, rects); + + if (!nomodecheck) + { + if (vid_testingmode) + { + if (realtime >= vid_testendtime) + { + VID_SetMode (vid_realmode, vid_current_palette); + vid_testingmode = 0; + } + } + else + { + if (vid_mode.value != vid_realmode) + { + VID_SetMode ((int)vid_mode.value, vid_current_palette); + Cvar_SetValue ("vid_mode", (float)vid_modenum); + // so if mode set fails, we don't keep on + // trying to set that mode + vid_realmode = vid_modenum; + } + } + } +} + + +/* +================= +VID_NumModes_f +================= +*/ +void VID_NumModes_f (void) +{ + int nummodes; + + nummodes = VID_NumModes (); + if (nummodes == 1) + Con_Printf ("%d video mode is available\n", VID_NumModes ()); + else + Con_Printf ("%d video modes are available\n", VID_NumModes ()); +} + + +/* +================= +VID_DescribeCurrentMode_f +================= +*/ +void VID_DescribeCurrentMode_f (void) +{ + Con_Printf ("%s\n", VID_ModeInfo (vid_modenum, NULL)); +} + + +/* +================= +VID_DescribeMode_f +================= +*/ +void VID_DescribeMode_f (void) +{ + int modenum; + + modenum = Q_atoi (Cmd_Argv(1)); + + Con_Printf ("%s\n", VID_ModeInfo (modenum, NULL)); +} + + +/* +================= +VID_DescribeModes_f +================= +*/ +void VID_DescribeModes_f (void) +{ + int i, nummodes; + char *pinfo, *pheader; + vmode_t *pv; + qboolean na; + + na = false; + + nummodes = VID_NumModes (); + for (i=0 ; iwidth, pv->height, pv->rowbytes, + (pv->numpages == 1) || vid_nopageflip.value)) + { + Con_Printf ("%2d: %s\n", i, pinfo); + } + else + { + Con_Printf ("**: %s\n", pinfo); + na = true; + } + } + + if (na) + { + Con_Printf ("\n[**: not enough system RAM for mode]\n"); + } +} + + +/* +================= +VID_GetModeDescription +================= +*/ +char *VID_GetModeDescription (int mode) +{ + char *pinfo, *pheader; + vmode_t *pv; + + pv = VID_GetModePtr (mode); + pinfo = VID_ModeInfo (mode, &pheader); + + if (VGA_CheckAdequateMem (pv->width, pv->height, pv->rowbytes, + (pv->numpages == 1) || vid_nopageflip.value)) + { + return pinfo; + } + else + { + return NULL; + } +} + + +/* +================= +VID_TestMode_f +================= +*/ +void VID_TestMode_f (void) +{ + int modenum; + double testduration; + + if (!vid_testingmode) + { + modenum = Q_atoi (Cmd_Argv(1)); + + if (VID_SetMode (modenum, vid_current_palette)) + { + vid_testingmode = 1; + testduration = Q_atof (Cmd_Argv(2)); + if (testduration == 0) + testduration = 5.0; + vid_testendtime = realtime + testduration; + } + } +} + + +/* +================ +D_BeginDirectRect +================ +*/ +void D_BeginDirectRect (int x, int y, byte *pbitmap, int width, int height) +{ + + if (!vid.direct || !pcurrentmode) + return; + + if ((width > 24) || (height > 24) || (width < 1) || (height < 1)) + return; + + if (width & 0x03) + return; + + (*pcurrentmode->begindirectrect) (&vid, pcurrentmode, x, y, pbitmap, width, + height); +} + + +/* +================ +D_EndDirectRect +================ +*/ +void D_EndDirectRect (int x, int y, int width, int height) +{ + + if (!vid.direct || !pcurrentmode) + return; + + if ((width > 24) || (height > 24) || (width < 1) || (height < 1)) + return; + + if ((width & 0x03) || (height & 0x03)) + return; + + (*pcurrentmode->enddirectrect) (&vid, pcurrentmode, x, y, width, height); +} + + +//=========================================================================== + +extern void M_Menu_Options_f (void); +extern void M_Print (int cx, int cy, char *str); +extern void M_PrintWhite (int cx, int cy, char *str); +extern void M_DrawCharacter (int cx, int line, int num); +extern void M_DrawTransPic (int x, int y, qpic_t *pic); +extern void M_DrawPic (int x, int y, qpic_t *pic); + +static int vid_line, vid_wmodes, vid_column_size; + +typedef struct +{ + int modenum; + char *desc; + int iscur; +} modedesc_t; + +#define MAX_COLUMN_SIZE 11 + +#define MAX_MODEDESCS (MAX_COLUMN_SIZE*3) + +static modedesc_t modedescs[MAX_MODEDESCS]; + +/* +================ +VID_MenuDraw +================ +*/ +void VID_MenuDraw (void) +{ + qpic_t *p; + char *ptr; + int nummodes, i, j, column, row, dup; + char temp[100]; + + vid_wmodes = 0; + nummodes = VID_NumModes (); + + p = Draw_CachePic ("gfx/vidmodes.lmp"); + M_DrawPic ( (320-p->width)/2, 4, p); + + for (i=0 ; i= vid_wmodes) + vid_line = 0; + break; + + case K_LEFTARROW: + S_LocalSound ("misc/menu1.wav"); + vid_line -= vid_column_size; + + if (vid_line < 0) + { + vid_line += ((vid_wmodes + (vid_column_size - 1)) / + vid_column_size) * vid_column_size; + + while (vid_line >= vid_wmodes) + vid_line -= vid_column_size; + } + break; + + case K_RIGHTARROW: + S_LocalSound ("misc/menu1.wav"); + vid_line += vid_column_size; + + if (vid_line >= vid_wmodes) + { + vid_line -= ((vid_wmodes + (vid_column_size - 1)) / + vid_column_size) * vid_column_size; + + while (vid_line < 0) + vid_line += vid_column_size; + } + break; + + case K_ENTER: + S_LocalSound ("misc/menu1.wav"); + VID_SetMode (modedescs[vid_line].modenum, vid_current_palette); + break; + + case 'T': + case 't': + S_LocalSound ("misc/menu1.wav"); + if (VID_SetMode (modedescs[vid_line].modenum, vid_current_palette)) + { + vid_testingmode = 1; + vid_testendtime = realtime + 5.0; + } + break; + + case 'D': + case 'd': + S_LocalSound ("misc/menu1.wav"); + firstupdate = 0; + Cvar_SetValue ("_vid_default_mode", vid_modenum); + break; + + default: + break; + } +} + diff --git a/contrib/other/sdlquake-1.0.9/vid_dos.h b/contrib/other/sdlquake-1.0.9/vid_dos.h new file mode 100644 index 000000000..4740e5984 --- /dev/null +++ b/contrib/other/sdlquake-1.0.9/vid_dos.h @@ -0,0 +1,83 @@ +/* +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_dos.h: header file for DOS-specific video stuff + +typedef struct vmode_s { + struct vmode_s *pnext; + char *name; + char *header; + unsigned width; + unsigned height; + float aspect; + unsigned rowbytes; + int planar; + int numpages; + void *pextradata; + int (*setmode)(viddef_t *vid, struct vmode_s *pcurrentmode); + void (*swapbuffers)(viddef_t *vid, struct vmode_s *pcurrentmode, + vrect_t *rects); + void (*setpalette)(viddef_t *vid, struct vmode_s *pcurrentmode, + unsigned char *palette); + void (*begindirectrect)(viddef_t *vid, struct vmode_s *pcurrentmode, + int x, int y, byte *pbitmap, int width, + int height); + void (*enddirectrect)(viddef_t *vid, struct vmode_s *pcurrentmode, + int x, int y, int width, int height); +} vmode_t; + +// vid_wait settings +#define VID_WAIT_NONE 0 +#define VID_WAIT_VSYNC 1 +#define VID_WAIT_DISPLAY_ENABLE 2 + +extern int numvidmodes; +extern vmode_t *pvidmodes; + +extern int VGA_width, VGA_height, VGA_rowbytes, VGA_bufferrowbytes; +extern byte *VGA_pagebase; +extern vmode_t *VGA_pcurmode; + +extern cvar_t vid_wait; +extern cvar_t vid_nopageflip; +extern cvar_t _vid_wait_override; + +extern unsigned char colormap256[32][256]; + +extern void *vid_surfcache; +extern int vid_surfcachesize; + +void VGA_Init (void); +void VID_InitVESA (void); +void VID_InitExtra (void); +void VGA_WaitVsync (void); +void VGA_ClearVideoMem (int planar); +void VGA_SetPalette(viddef_t *vid, vmode_t *pcurrentmode, unsigned char *pal); +void VGA_SwapBuffersCopy (viddef_t *vid, vmode_t *pcurrentmode, + vrect_t *rects); +qboolean VGA_FreeAndAllocVidbuffer (viddef_t *vid, int allocnewbuffer); +qboolean VGA_CheckAdequateMem (int width, int height, int rowbytes, + int allocnewbuffer); +void VGA_BeginDirectRect (viddef_t *vid, struct vmode_s *pcurrentmode, int x, + int y, byte *pbitmap, int width, int height); +void VGA_EndDirectRect (viddef_t *vid, struct vmode_s *pcurrentmode, int x, + int y, int width, int height); +void VGA_UpdateLinearScreen (void *srcptr, void *destptr, int width, + int height, int srcrowbytes, int destrowbytes); + diff --git a/contrib/other/sdlquake-1.0.9/vid_ext.c b/contrib/other/sdlquake-1.0.9/vid_ext.c new file mode 100644 index 000000000..4188e2b9c --- /dev/null +++ b/contrib/other/sdlquake-1.0.9/vid_ext.c @@ -0,0 +1,795 @@ +/* +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_ext.c: extended video modes +// in this implementation, VESA-specific DOS video stuff +// + +// TODO: make dependencies on vid_vga.c explicit or eliminate them + +#include +#include + +#include "quakedef.h" +#include "d_local.h" +#include "dosisms.h" +#include "vid_dos.h" +#include + +#define MODE_SUPPORTED_IN_HW 0x0001 +#define COLOR_MODE 0x0008 +#define GRAPHICS_MODE 0x0010 +#define VGA_INCOMPATIBLE 0x0020 +#define LINEAR_FRAME_BUFFER 0x0080 + +#define LINEAR_MODE 0x4000 + +#define VESA_DONT_WAIT_VSYNC 0 // when page flipping +#define VESA_WAIT_VSYNC 0x80 + +#define MAX_VESA_MODES 30 // we'll just take the first 30 if there + // are more +typedef struct { + int pages[3]; // either 2 or 3 is valid + int vesamode; // LINEAR_MODE set if linear mode + void *plinearmem; // linear address of start of frame buffer + qboolean vga_incompatible; +} vesa_extra_t; + +static vmode_t vesa_modes[MAX_VESA_MODES] = + {{NULL, NULL, " ********* VESA modes ********* "}}; +static vesa_extra_t vesa_extra[MAX_VESA_MODES]; +static char names[MAX_VESA_MODES][10]; + +extern regs_t regs; + +static int VID_currentpage; +static int VID_displayedpage; +static int *VID_pagelist; +static byte *VID_membase; +static int VID_banked; + +typedef struct +{ + int modenum; + int mode_attributes; + int winasegment; + int winbsegment; + int bytes_per_scanline; // bytes per logical scanline (+16) + int win; // window number (A=0, B=1) + int win_size; // window size (+6) + int granularity; // how finely i can set the window in vid mem (+4) + int width, height; // displayed width and height (+18, +20) + int bits_per_pixel; // er, better be 8, 15, 16, 24, or 32 (+25) + int bytes_per_pixel; // er, better be 1, 2, or 4 + int memory_model; // and better be 4 or 6, packed or direct color (+27) + int num_pages; // number of complete frame buffer pages (+29) + int red_width; // the # of bits in the red component (+31) + int red_pos; // the bit position of the red component (+32) + int green_width; // etc.. (+33) + int green_pos; // (+34) + int blue_width; // (+35) + int blue_pos; // (+36) + int pptr; + int pagesize; + int numpages; +} modeinfo_t; + +static modeinfo_t modeinfo; + +// all bytes to avoid problems with compiler field packing +typedef struct vbeinfoblock_s { + byte VbeSignature[4]; + byte VbeVersion[2]; + byte OemStringPtr[4]; + byte Capabilities[4]; + byte VideoModePtr[4]; + byte TotalMemory[2]; + byte OemSoftwareRev[2]; + byte OemVendorNamePtr[4]; + byte OemProductNamePtr[4]; + byte OemProductRevPtr[4]; + byte Reserved[222]; + byte OemData[256]; +} vbeinfoblock_t; + +static int totalvidmem; +static byte *ppal; +qboolean vsync_exists, de_exists; + +qboolean VID_ExtraGetModeInfo(int modenum); +int VID_ExtraInitMode (viddef_t *vid, vmode_t *pcurrentmode); +void VID_ExtraSwapBuffers (viddef_t *vid, vmode_t *pcurrentmode, + vrect_t *rects); + + +/* +================ +VGA_BankedBeginDirectRect +================ +*/ +void VGA_BankedBeginDirectRect (viddef_t *lvid, struct vmode_s *pcurrentmode, + int x, int y, byte *pbitmap, int width, int height) +{ + + if (!lvid->direct) + return; + + regs.x.ax = 0x4f05; + regs.x.bx = 0; + regs.x.dx = VID_displayedpage; + dos_int86(0x10); + + VGA_BeginDirectRect (lvid, pcurrentmode, x, y, pbitmap, width, height); + + regs.x.ax = 0x4f05; + regs.x.bx = 0; + regs.x.dx = VID_currentpage; + dos_int86(0x10); +} + + +/* +================ +VGA_BankedEndDirectRect +================ +*/ +void VGA_BankedEndDirectRect (viddef_t *lvid, struct vmode_s *pcurrentmode, + int x, int y, int width, int height) +{ + + if (!lvid->direct) + return; + + regs.x.ax = 0x4f05; + regs.x.bx = 0; + regs.x.dx = VID_displayedpage; + dos_int86(0x10); + + VGA_EndDirectRect (lvid, pcurrentmode, x, y, width, height); + + regs.x.ax = 0x4f05; + regs.x.bx = 0; + regs.x.dx = VID_currentpage; + dos_int86(0x10); +} + + +/* +================ +VID_SetVESAPalette +================ +*/ +void VID_SetVESAPalette (viddef_t *lvid, vmode_t *pcurrentmode, + unsigned char *pal) +{ + int i; + byte *pp; + + UNUSED(lvid); + UNUSED(pcurrentmode); + + pp = ppal; + + for (i=0 ; i<256 ; i++) + { + pp[2] = pal[0] >> 2; + pp[1] = pal[1] >> 2; + pp[0] = pal[2] >> 2; + pp += 4; + pal += 3; + } + + regs.x.ax = 0x4F09; + regs.x.bx = 0; + regs.x.cx = 256; + regs.x.dx = 0; + regs.x.es = ptr2real(ppal) >> 4; + regs.x.di = ptr2real(ppal) & 0xf; + dos_int86(0x10); + + if (regs.x.ax != 0x4f) + Sys_Error ("Unable to load VESA palette\n"); +} + + + + +/* +================ +VID_ExtraFarToLinear +================ +*/ +void *VID_ExtraFarToLinear (void *ptr) +{ + int temp; + + temp = (int)ptr; + return real2ptr(((temp & 0xFFFF0000) >> 12) + (temp & 0xFFFF)); +} + + +/* +================ +VID_ExtraWaitDisplayEnable +================ +*/ +void VID_ExtraWaitDisplayEnable () +{ + while ((inportb (0x3DA) & 0x01) == 1) + ; +} + + +/* +================ +VID_ExtraVidLookForState +================ +*/ +qboolean VID_ExtraVidLookForState (unsigned state, unsigned mask) +{ + int i; + double starttime, time; + + starttime = Sys_FloatTime (); + + do + { + for (i=0 ; i<100000 ; i++) + { + if ((inportb (0x3DA) & mask) == state) + return true; + } + + time = Sys_FloatTime (); + } while ((time - starttime) < 0.1); + + return false; +} + + +/* +================ +VID_ExtraStateFound +================ +*/ +qboolean VID_ExtraStateFound (unsigned state) +{ + int i, workingstate; + + workingstate = 0; + + for (i=0 ; i<10 ; i++) + { + if (!VID_ExtraVidLookForState(workingstate, state)) + { + return false; + } + + workingstate ^= state; + } + + return true; +} + + +/* +================ +VID_InitExtra +================ +*/ +void VID_InitExtra (void) +{ + int nummodes; + short *pmodenums; + vbeinfoblock_t *pinfoblock; + __dpmi_meminfo phys_mem_info; + + pinfoblock = dos_getmemory(sizeof(vbeinfoblock_t)); + + *(long *)pinfoblock->VbeSignature = 'V' + ('B'<<8) + ('E'<<16) + ('2'<<24); + +// see if VESA support is available + regs.x.ax = 0x4f00; + regs.x.es = ptr2real(pinfoblock) >> 4; + regs.x.di = ptr2real(pinfoblock) & 0xf; + dos_int86(0x10); + + if (regs.x.ax != 0x4f) + return; // no VESA support + + if (pinfoblock->VbeVersion[1] < 0x02) + return; // not VESA 2.0 or greater + + Con_Printf ("VESA 2.0 compliant adapter:\n%s\n", + VID_ExtraFarToLinear (*(byte **)&pinfoblock->OemStringPtr[0])); + + totalvidmem = *(unsigned short *)&pinfoblock->TotalMemory[0] << 16; + + pmodenums = (short *) + VID_ExtraFarToLinear (*(byte **)&pinfoblock->VideoModePtr[0]); + +// find 8 bit modes until we either run out of space or run out of modes + nummodes = 0; + + while ((*pmodenums != -1) && (nummodes < MAX_VESA_MODES)) + { + if (VID_ExtraGetModeInfo (*pmodenums)) + { + vesa_modes[nummodes].pnext = &vesa_modes[nummodes+1]; + if (modeinfo.width > 999) + { + if (modeinfo.height > 999) + { + sprintf (&names[nummodes][0], "%4dx%4d", modeinfo.width, + modeinfo.height); + names[nummodes][9] = 0; + } + else + { + sprintf (&names[nummodes][0], "%4dx%3d", modeinfo.width, + modeinfo.height); + names[nummodes][8] = 0; + } + } + else + { + if (modeinfo.height > 999) + { + sprintf (&names[nummodes][0], "%3dx%4d", modeinfo.width, + modeinfo.height); + names[nummodes][8] = 0; + } + else + { + sprintf (&names[nummodes][0], "%3dx%3d", modeinfo.width, + modeinfo.height); + names[nummodes][7] = 0; + } + } + + vesa_modes[nummodes].name = &names[nummodes][0]; + vesa_modes[nummodes].width = modeinfo.width; + vesa_modes[nummodes].height = modeinfo.height; + vesa_modes[nummodes].aspect = + ((float)modeinfo.height / (float)modeinfo.width) * + (320.0 / 240.0); + vesa_modes[nummodes].rowbytes = modeinfo.bytes_per_scanline; + vesa_modes[nummodes].planar = 0; + vesa_modes[nummodes].pextradata = &vesa_extra[nummodes]; + vesa_modes[nummodes].setmode = VID_ExtraInitMode; + vesa_modes[nummodes].swapbuffers = VID_ExtraSwapBuffers; + vesa_modes[nummodes].setpalette = VID_SetVESAPalette; + + if (modeinfo.mode_attributes & LINEAR_FRAME_BUFFER) + { + // add linear bit to mode for linear modes + vesa_extra[nummodes].vesamode = modeinfo.modenum | LINEAR_MODE; + vesa_extra[nummodes].pages[0] = 0; + vesa_extra[nummodes].pages[1] = modeinfo.pagesize; + vesa_extra[nummodes].pages[2] = modeinfo.pagesize * 2; + vesa_modes[nummodes].numpages = modeinfo.numpages; + + vesa_modes[nummodes].begindirectrect = VGA_BeginDirectRect; + vesa_modes[nummodes].enddirectrect = VGA_EndDirectRect; + + phys_mem_info.address = (int)modeinfo.pptr; + phys_mem_info.size = 0x400000; + + if (__dpmi_physical_address_mapping(&phys_mem_info)) + goto NextMode; + + vesa_extra[nummodes].plinearmem = + real2ptr (phys_mem_info.address); + } + else + { + // banked at 0xA0000 + vesa_extra[nummodes].vesamode = modeinfo.modenum; + vesa_extra[nummodes].pages[0] = 0; + vesa_extra[nummodes].plinearmem = + real2ptr(modeinfo.winasegment<<4); + + vesa_modes[nummodes].begindirectrect = + VGA_BankedBeginDirectRect; + vesa_modes[nummodes].enddirectrect = VGA_BankedEndDirectRect; + vesa_extra[nummodes].pages[1] = modeinfo.pagesize; + vesa_extra[nummodes].pages[2] = modeinfo.pagesize * 2; + vesa_modes[nummodes].numpages = modeinfo.numpages; + } + + vesa_extra[nummodes].vga_incompatible = + modeinfo.mode_attributes & VGA_INCOMPATIBLE; + + nummodes++; + } +NextMode: + pmodenums++; + } + +// add the VESA modes at the start of the mode list (if there are any) + if (nummodes) + { + vesa_modes[nummodes-1].pnext = pvidmodes; + pvidmodes = &vesa_modes[0]; + numvidmodes += nummodes; + ppal = dos_getmemory(256*4); + } + + dos_freememory(pinfoblock); +} + + +/* +================ +VID_ExtraGetModeInfo +================ +*/ +qboolean VID_ExtraGetModeInfo(int modenum) +{ + char *infobuf; + int numimagepages; + + infobuf = dos_getmemory(256); + + regs.x.ax = 0x4f01; + regs.x.cx = modenum; + regs.x.es = ptr2real(infobuf) >> 4; + regs.x.di = ptr2real(infobuf) & 0xf; + dos_int86(0x10); + if (regs.x.ax != 0x4f) + { + return false; + } + else + { + modeinfo.modenum = modenum; + modeinfo.bits_per_pixel = *(char*)(infobuf+25); + modeinfo.bytes_per_pixel = (modeinfo.bits_per_pixel+1)/8; + modeinfo.width = *(short*)(infobuf+18); + modeinfo.height = *(short*)(infobuf+20); + + // we do only 8-bpp in software + if ((modeinfo.bits_per_pixel != 8) || + (modeinfo.bytes_per_pixel != 1) || + (modeinfo.width > MAXWIDTH) || + (modeinfo.height > MAXHEIGHT)) + { + return false; + } + + modeinfo.mode_attributes = *(short*)infobuf; + + // we only want color graphics modes that are supported by the hardware + if ((modeinfo.mode_attributes & + (MODE_SUPPORTED_IN_HW | COLOR_MODE | GRAPHICS_MODE)) != + (MODE_SUPPORTED_IN_HW | COLOR_MODE | GRAPHICS_MODE)) + { + return false; + } + + // we only work with linear frame buffers, except for 320x200, which can + // effectively be linear when banked at 0xA000 + if (!(modeinfo.mode_attributes & LINEAR_FRAME_BUFFER)) + { + if ((modeinfo.width != 320) || (modeinfo.height != 200)) + return false; + } + + modeinfo.bytes_per_scanline = *(short*)(infobuf+16); + + modeinfo.pagesize = modeinfo.bytes_per_scanline * modeinfo.height; + + if (modeinfo.pagesize > totalvidmem) + return false; + + // force to one page if the adapter reports it doesn't support more pages + // than that, no matter how much memory it has--it may not have hardware + // support for page flipping + numimagepages = *(unsigned char *)(infobuf+29); + + if (numimagepages <= 0) + { + // wrong, but there seems to be an ATI VESA driver that reports 0 + modeinfo.numpages = 1; + } + else if (numimagepages < 3) + { + modeinfo.numpages = numimagepages; + } + else + { + modeinfo.numpages = 3; + } + + if (*(char*)(infobuf+2) & 5) + { + modeinfo.winasegment = *(unsigned short*)(infobuf+8); + modeinfo.win = 0; + } + else if (*(char*)(infobuf+3) & 5) + { + modeinfo.winbsegment = *(unsigned short*)(infobuf+8); + modeinfo.win = 1; + } + modeinfo.granularity = *(short*)(infobuf+4) * 1024; + modeinfo.win_size = *(short*)(infobuf+6) * 1024; + modeinfo.bits_per_pixel = *(char*)(infobuf+25); + modeinfo.bytes_per_pixel = (modeinfo.bits_per_pixel+1)/8; + modeinfo.memory_model = *(unsigned char*)(infobuf+27); + modeinfo.num_pages = *(char*)(infobuf+29) + 1; + + modeinfo.red_width = *(char*)(infobuf+31); + modeinfo.red_pos = *(char*)(infobuf+32); + modeinfo.green_width = *(char*)(infobuf+33); + modeinfo.green_pos = *(char*)(infobuf+34); + modeinfo.blue_width = *(char*)(infobuf+35); + modeinfo.blue_pos = *(char*)(infobuf+36); + + modeinfo.pptr = *(long *)(infobuf+40); + +#if 0 + printf("VID: (VESA) info for mode 0x%x\n", modeinfo.modenum); + printf(" mode attrib = 0x%0x\n", modeinfo.mode_attributes); + printf(" win a attrib = 0x%0x\n", *(unsigned char*)(infobuf+2)); + printf(" win b attrib = 0x%0x\n", *(unsigned char*)(infobuf+3)); + printf(" win a seg 0x%0x\n", (int) modeinfo.winasegment); + printf(" win b seg 0x%0x\n", (int) modeinfo.winbsegment); + printf(" bytes per scanline = %d\n", + modeinfo.bytes_per_scanline); + printf(" width = %d, height = %d\n", modeinfo.width, + modeinfo.height); + printf(" win = %c\n", 'A' + modeinfo.win); + printf(" win granularity = %d\n", modeinfo.granularity); + printf(" win size = %d\n", modeinfo.win_size); + printf(" bits per pixel = %d\n", modeinfo.bits_per_pixel); + printf(" bytes per pixel = %d\n", modeinfo.bytes_per_pixel); + printf(" memory model = 0x%x\n", modeinfo.memory_model); + printf(" num pages = %d\n", modeinfo.num_pages); + printf(" red width = %d\n", modeinfo.red_width); + printf(" red pos = %d\n", modeinfo.red_pos); + printf(" green width = %d\n", modeinfo.green_width); + printf(" green pos = %d\n", modeinfo.green_pos); + printf(" blue width = %d\n", modeinfo.blue_width); + printf(" blue pos = %d\n", modeinfo.blue_pos); + printf(" phys mem = %x\n", modeinfo.pptr); +#endif + } + + dos_freememory(infobuf); + + return true; +} + + +/* +================ +VID_ExtraInitMode +================ +*/ +int VID_ExtraInitMode (viddef_t *lvid, vmode_t *pcurrentmode) +{ + vesa_extra_t *pextra; + int pageoffset; + + pextra = pcurrentmode->pextradata; + + if (vid_nopageflip.value) + lvid->numpages = 1; + else + lvid->numpages = pcurrentmode->numpages; + +// clean up any old vid buffer lying around, alloc new if needed + if (!VGA_FreeAndAllocVidbuffer (lvid, lvid->numpages == 1)) + return -1; // memory alloc failed + +// clear the screen and wait for the next frame. VGA_pcurmode, which +// VGA_ClearVideoMem relies on, is guaranteed to be set because mode 0 is +// always the first mode set in a session + if (VGA_pcurmode) + VGA_ClearVideoMem (VGA_pcurmode->planar); + +// set the mode + regs.x.ax = 0x4f02; + regs.x.bx = pextra->vesamode; + dos_int86(0x10); + + if (regs.x.ax != 0x4f) + return 0; + + VID_banked = !(pextra->vesamode & LINEAR_MODE); + VID_membase = pextra->plinearmem; + VGA_width = lvid->width; + VGA_height = lvid->height; + VGA_rowbytes = lvid->rowbytes; + + lvid->colormap = host_colormap; + + VID_pagelist = &pextra->pages[0]; + +// wait for display enable by default only when triple-buffering on a VGA- +// compatible machine that actually has a functioning display enable status + vsync_exists = VID_ExtraStateFound (0x08); + de_exists = VID_ExtraStateFound (0x01); + + if (!pextra->vga_incompatible && + (lvid->numpages == 3) && + de_exists && + (_vid_wait_override.value == 0.0)) + { + Cvar_SetValue ("vid_wait", (float)VID_WAIT_DISPLAY_ENABLE); + + VID_displayedpage = 0; + VID_currentpage = 1; + } + else + { + if ((lvid->numpages == 1) && (_vid_wait_override.value == 0.0)) + { + Cvar_SetValue ("vid_wait", (float)VID_WAIT_NONE); + VID_displayedpage = VID_currentpage = 0; + } + else + { + Cvar_SetValue ("vid_wait", (float)VID_WAIT_VSYNC); + + VID_displayedpage = 0; + + if (lvid->numpages > 1) + VID_currentpage = 1; + else + VID_currentpage = 0; + } + } + +// TODO: really should be a call to a function + pageoffset = VID_pagelist[VID_displayedpage]; + + regs.x.ax = 0x4f07; + regs.x.bx = 0x80; // wait for vsync so we know page 0 is visible + regs.x.cx = pageoffset % VGA_rowbytes; + regs.x.dx = pageoffset / VGA_rowbytes; + dos_int86(0x10); + + if (VID_banked) + { + regs.x.ax = 0x4f05; + regs.x.bx = 0; + regs.x.dx = VID_currentpage; + dos_int86(0x10); + + VGA_pagebase = VID_membase; + } + else + { + VGA_pagebase = VID_membase + VID_pagelist[VID_currentpage]; + } + + if (lvid->numpages > 1) + { + lvid->buffer = VGA_pagebase; + lvid->conbuffer = lvid->buffer; + } + else + { + lvid->rowbytes = lvid->width; + } + + lvid->direct = VGA_pagebase; + lvid->conrowbytes = lvid->rowbytes; + lvid->conwidth = lvid->width; + lvid->conheight = lvid->height; + + lvid->maxwarpwidth = WARP_WIDTH; + lvid->maxwarpheight = WARP_HEIGHT; + + VGA_pcurmode = pcurrentmode; + + D_InitCaches (vid_surfcache, vid_surfcachesize); + + return 1; +} + + +/* +================ +VID_ExtraSwapBuffers +================ +*/ +void VID_ExtraSwapBuffers (viddef_t *lvid, vmode_t *pcurrentmode, + vrect_t *rects) +{ + int pageoffset; + + UNUSED(rects); + UNUSED(pcurrentmode); + + pageoffset = VID_pagelist[VID_currentpage]; + +// display the newly finished page + if (lvid->numpages > 1) + { + // page flipped + regs.x.ax = 0x4f07; + + if (vid_wait.value != VID_WAIT_VSYNC) + { + if ((vid_wait.value == VID_WAIT_DISPLAY_ENABLE) && de_exists) + VID_ExtraWaitDisplayEnable (); + + regs.x.bx = VESA_DONT_WAIT_VSYNC; + } + else + { + regs.x.bx = VESA_WAIT_VSYNC; // double buffered has to wait + } + + regs.x.cx = pageoffset % VGA_rowbytes; + regs.x.dx = pageoffset / VGA_rowbytes; + dos_int86(0x10); + + VID_displayedpage = VID_currentpage; + if (++VID_currentpage >= lvid->numpages) + VID_currentpage = 0; + + // + // set the new write window if this is a banked mode; otherwise, set the + // new address to which to write + // + if (VID_banked) + { + regs.x.ax = 0x4f05; + regs.x.bx = 0; + regs.x.dx = VID_currentpage; + dos_int86(0x10); + } + else + { + lvid->direct = lvid->buffer; // direct drawing goes to the + // currently displayed page + lvid->buffer = VID_membase + VID_pagelist[VID_currentpage]; + lvid->conbuffer = lvid->buffer; + } + + VGA_pagebase = lvid->buffer; + } + else + { + // non-page-flipped + if (vsync_exists && (vid_wait.value == VID_WAIT_VSYNC)) + { + VGA_WaitVsync (); + } + + while (rects) + { + VGA_UpdateLinearScreen ( + lvid->buffer + rects->x + (rects->y * lvid->rowbytes), + VGA_pagebase + rects->x + (rects->y * VGA_rowbytes), + rects->width, + rects->height, + lvid->rowbytes, + VGA_rowbytes); + + rects = rects->pnext; + } + } +} + diff --git a/contrib/other/sdlquake-1.0.9/vid_null.c b/contrib/other/sdlquake-1.0.9/vid_null.c new file mode 100644 index 000000000..225691b29 --- /dev/null +++ b/contrib/other/sdlquake-1.0.9/vid_null.c @@ -0,0 +1,87 @@ +/* +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_null.c -- null video driver to aid porting efforts + +#include "quakedef.h" +#include "d_local.h" + +viddef_t vid; // global video state + +#define BASEWIDTH 320 +#define BASEHEIGHT 200 + +byte vid_buffer[BASEWIDTH*BASEHEIGHT]; +short zbuffer[BASEWIDTH*BASEHEIGHT]; +byte surfcache[256*1024]; + +unsigned short d_8to16table[256]; +unsigned d_8to24table[256]; + +void VID_SetPalette (unsigned char *palette) +{ +} + +void VID_ShiftPalette (unsigned char *palette) +{ +} + +void VID_Init (unsigned char *palette) +{ + vid.maxwarpwidth = vid.width = vid.conwidth = BASEWIDTH; + vid.maxwarpheight = vid.height = vid.conheight = BASEHEIGHT; + vid.aspect = 1.0; + vid.numpages = 1; + vid.colormap = host_colormap; + vid.fullbright = 256 - LittleLong (*((int *)vid.colormap + 2048)); + vid.buffer = vid.conbuffer = vid_buffer; + vid.rowbytes = vid.conrowbytes = BASEWIDTH; + + d_pzbuffer = zbuffer; + D_InitCaches (surfcache, sizeof(surfcache)); +} + +void VID_Shutdown (void) +{ +} + +void VID_Update (vrect_t *rects) +{ +} + +/* +================ +D_BeginDirectRect +================ +*/ +void D_BeginDirectRect (int x, int y, byte *pbitmap, int width, int height) +{ +} + + +/* +================ +D_EndDirectRect +================ +*/ +void D_EndDirectRect (int x, int y, int width, int height) +{ +} + + diff --git a/contrib/other/sdlquake-1.0.9/vid_sdl.c b/contrib/other/sdlquake-1.0.9/vid_sdl.c new file mode 100644 index 000000000..0898e5cd9 --- /dev/null +++ b/contrib/other/sdlquake-1.0.9/vid_sdl.c @@ -0,0 +1,393 @@ +// vid_sdl.h -- sdl video driver + +#include "SDL.h" +#include "quakedef.h" +#include "d_local.h" + +viddef_t vid; // global video state +unsigned short d_8to16table[256]; + +// The original defaults +//#define BASEWIDTH 320 +//#define BASEHEIGHT 200 +// Much better for high resolution displays +#define BASEWIDTH (320*2) +#define BASEHEIGHT (200*2) + +int VGA_width, VGA_height, VGA_rowbytes, VGA_bufferrowbytes = 0; +byte *VGA_pagebase; + +static SDL_Surface *screen = NULL; + +static qboolean mouse_avail; +static float mouse_x, mouse_y; +static int mouse_oldbuttonstate = 0; + +// No support for option menus +void (*vid_menudrawfn)(void) = NULL; +void (*vid_menukeyfn)(int key) = NULL; + +void VID_SetPalette (unsigned char *palette) +{ + int i; + SDL_Color colors[256]; + + for ( i=0; i<256; ++i ) + { + colors[i].r = *palette++; + colors[i].g = *palette++; + colors[i].b = *palette++; + } + SDL_SetColors(screen, colors, 0, 256); +} + +void VID_ShiftPalette (unsigned char *palette) +{ + VID_SetPalette(palette); +} + +void VID_Init (unsigned char *palette) +{ + int pnum, chunk; + byte *cache; + int cachesize; + Uint8 video_bpp; + Uint16 video_w, video_h; + Uint32 flags; + + // Load the SDL library +#ifdef _KOLIBRI + if (SDL_Init(SDL_INIT_VIDEO|SDL_INIT_AUDIO) < 0) +#else + if (SDL_Init(SDL_INIT_VIDEO|SDL_INIT_AUDIO|SDL_INIT_CDROM) < 0) +#endif + Sys_Error("VID: Couldn't load SDL: %s", SDL_GetError()); + + // Set up display mode (width and height) + vid.width = BASEWIDTH; + vid.height = BASEHEIGHT; + vid.maxwarpwidth = WARP_WIDTH; + vid.maxwarpheight = WARP_HEIGHT; + if ((pnum=COM_CheckParm("-winsize"))) + { + if (pnum >= com_argc-2) + Sys_Error("VID: -winsize \n"); + vid.width = Q_atoi(com_argv[pnum+1]); + vid.height = Q_atoi(com_argv[pnum+2]); + if (!vid.width || !vid.height) + Sys_Error("VID: Bad window width/height\n"); + } + + // Set video width, height and flags + flags = (SDL_SWSURFACE|SDL_HWPALETTE); + if ( COM_CheckParm ("-fullscreen") ) + flags |= SDL_FULLSCREEN; + + // Initialize display + if (!(screen = SDL_SetVideoMode(vid.width, vid.height, 8, flags))) + Sys_Error("VID: Couldn't set video mode: %s\n", SDL_GetError()); + VID_SetPalette(palette); + SDL_WM_SetCaption("sdlquake","sdlquake"); + // now know everything we need to know about the buffer + VGA_width = vid.conwidth = vid.width; + VGA_height = vid.conheight = vid.height; + vid.aspect = ((float)vid.height / (float)vid.width) * (320.0 / 240.0); + vid.numpages = 1; + vid.colormap = host_colormap; + vid.fullbright = 256 - LittleLong (*((int *)vid.colormap + 2048)); + VGA_pagebase = vid.buffer = screen->pixels; + VGA_rowbytes = vid.rowbytes = screen->pitch; + vid.conbuffer = vid.buffer; + vid.conrowbytes = vid.rowbytes; + vid.direct = 0; + + // allocate z buffer and surface cache + chunk = vid.width * vid.height * sizeof (*d_pzbuffer); + cachesize = D_SurfaceCacheForRes (vid.width, vid.height); + chunk += cachesize; + d_pzbuffer = Hunk_HighAllocName(chunk, "video"); + if (d_pzbuffer == NULL) + Sys_Error ("Not enough memory for video mode\n"); + + // initialize the cache memory + cache = (byte *) d_pzbuffer + + vid.width * vid.height * sizeof (*d_pzbuffer); + D_InitCaches (cache, cachesize); + + // initialize the mouse + SDL_ShowCursor(0); +} + +void VID_Shutdown (void) +{ + SDL_Quit(); +} + +void VID_Update (vrect_t *rects) +{ + SDL_Rect *sdlrects; + int n, i; + vrect_t *rect; + + // Two-pass system, since Quake doesn't do it the SDL way... + + // First, count the number of rectangles + n = 0; + for (rect = rects; rect; rect = rect->pnext) + ++n; + + // Second, copy them to SDL rectangles and update + if (!(sdlrects = (SDL_Rect *)alloca(n*sizeof(*sdlrects)))) + Sys_Error("Out of memory"); + i = 0; + for (rect = rects; rect; rect = rect->pnext) + { + sdlrects[i].x = rect->x; + sdlrects[i].y = rect->y; + sdlrects[i].w = rect->width; + sdlrects[i].h = rect->height; + ++i; + } + SDL_UpdateRects(screen, n, sdlrects); +} + +/* +================ +D_BeginDirectRect +================ +*/ +void D_BeginDirectRect (int x, int y, byte *pbitmap, int width, int height) +{ + Uint8 *offset; + + + if (!screen) return; + if ( x < 0 ) x = screen->w+x-1; + offset = (Uint8 *)screen->pixels + y*screen->pitch + x; + while ( height-- ) + { + memcpy(offset, pbitmap, width); + offset += screen->pitch; + pbitmap += width; + } +} + + +/* +================ +D_EndDirectRect +================ +*/ +void D_EndDirectRect (int x, int y, int width, int height) +{ + if (!screen) return; + if (x < 0) x = screen->w+x-1; + SDL_UpdateRect(screen, x, y, width, height); +} + + +/* +================ +Sys_SendKeyEvents +================ +*/ + +void Sys_SendKeyEvents(void) +{ + SDL_Event event; + int sym, state; + int modstate; + + while (SDL_PollEvent(&event)) + { + switch (event.type) { + + case SDL_KEYDOWN: + case SDL_KEYUP: + sym = event.key.keysym.sym; + state = event.key.state; + modstate = SDL_GetModState(); + switch(sym) + { + case SDLK_DELETE: sym = K_DEL; break; + case SDLK_BACKSPACE: sym = K_BACKSPACE; break; + case SDLK_F1: sym = K_F1; break; + case SDLK_F2: sym = K_F2; break; + case SDLK_F3: sym = K_F3; break; + case SDLK_F4: sym = K_F4; break; + case SDLK_F5: sym = K_F5; break; + case SDLK_F6: sym = K_F6; break; + case SDLK_F7: sym = K_F7; break; + case SDLK_F8: sym = K_F8; break; + case SDLK_F9: sym = K_F9; break; + case SDLK_F10: sym = K_F10; break; + case SDLK_F11: sym = K_F11; break; + case SDLK_F12: sym = K_F12; break; + case SDLK_BREAK: + case SDLK_PAUSE: sym = K_PAUSE; break; + case SDLK_UP: sym = K_UPARROW; break; + case SDLK_DOWN: sym = K_DOWNARROW; break; + case SDLK_RIGHT: sym = K_RIGHTARROW; break; + case SDLK_LEFT: sym = K_LEFTARROW; break; + case SDLK_INSERT: sym = K_INS; break; + case SDLK_HOME: sym = K_HOME; break; + case SDLK_END: sym = K_END; break; + case SDLK_PAGEUP: sym = K_PGUP; break; + case SDLK_PAGEDOWN: sym = K_PGDN; break; + case SDLK_RSHIFT: + case SDLK_LSHIFT: sym = K_SHIFT; break; + case SDLK_RCTRL: + case SDLK_LCTRL: sym = K_CTRL; break; + case SDLK_RALT: + case SDLK_LALT: sym = K_ALT; break; + case SDLK_KP0: + if(modstate & KMOD_NUM) sym = K_INS; + else sym = SDLK_0; + break; + case SDLK_KP1: + if(modstate & KMOD_NUM) sym = K_END; + else sym = SDLK_1; + break; + case SDLK_KP2: + if(modstate & KMOD_NUM) sym = K_DOWNARROW; + else sym = SDLK_2; + break; + case SDLK_KP3: + if(modstate & KMOD_NUM) sym = K_PGDN; + else sym = SDLK_3; + break; + case SDLK_KP4: + if(modstate & KMOD_NUM) sym = K_LEFTARROW; + else sym = SDLK_4; + break; + case SDLK_KP5: sym = SDLK_5; break; + case SDLK_KP6: + if(modstate & KMOD_NUM) sym = K_RIGHTARROW; + else sym = SDLK_6; + break; + case SDLK_KP7: + if(modstate & KMOD_NUM) sym = K_HOME; + else sym = SDLK_7; + break; + case SDLK_KP8: + if(modstate & KMOD_NUM) sym = K_UPARROW; + else sym = SDLK_8; + break; + case SDLK_KP9: + if(modstate & KMOD_NUM) sym = K_PGUP; + else sym = SDLK_9; + break; + case SDLK_KP_PERIOD: + if(modstate & KMOD_NUM) sym = K_DEL; + else sym = SDLK_PERIOD; + break; + case SDLK_KP_DIVIDE: sym = SDLK_SLASH; break; + case SDLK_KP_MULTIPLY: sym = SDLK_ASTERISK; break; + case SDLK_KP_MINUS: sym = SDLK_MINUS; break; + case SDLK_KP_PLUS: sym = SDLK_PLUS; break; + case SDLK_KP_ENTER: sym = SDLK_RETURN; break; + case SDLK_KP_EQUALS: sym = SDLK_EQUALS; break; + } + // If we're not directly handled and still above 255 + // just force it to 0 + if(sym > 255) sym = 0; + Key_Event(sym, state); + break; + + case SDL_MOUSEMOTION: + if ( (event.motion.x != (vid.width/2)) || + (event.motion.y != (vid.height/2)) ) { + mouse_x = event.motion.xrel*10; + mouse_y = event.motion.yrel*10; + if ( (event.motion.x < ((vid.width/2)-(vid.width/4))) || + (event.motion.x > ((vid.width/2)+(vid.width/4))) || + (event.motion.y < ((vid.height/2)-(vid.height/4))) || + (event.motion.y > ((vid.height/2)+(vid.height/4))) ) { + SDL_WarpMouse(vid.width/2, vid.height/2); + } + } + break; + + case SDL_QUIT: + CL_Disconnect (); + Host_ShutdownServer(false); + Sys_Quit (); + break; + default: + break; + } + } +} + +void IN_Init (void) +{ + if ( COM_CheckParm ("-nomouse") ) + return; + mouse_x = mouse_y = 0.0; + mouse_avail = 1; +} + +void IN_Shutdown (void) +{ + mouse_avail = 0; +} + +void IN_Commands (void) +{ + int i; + int mouse_buttonstate; + + if (!mouse_avail) return; + + i = SDL_GetMouseState(NULL, NULL); + /* Quake swaps the second and third buttons */ + mouse_buttonstate = (i & ~0x06) | ((i & 0x02)<<1) | ((i & 0x04)>>1); + for (i=0 ; i<3 ; i++) { + if ( (mouse_buttonstate & (1<sidemove += m_side.value * mouse_x; + else + cl.viewangles[YAW] -= m_yaw.value * mouse_x; + if (in_mlook.state & 1) + V_StopPitchDrift (); + + if ( (in_mlook.state & 1) && !(in_strafe.state & 1)) { + 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; + } + mouse_x = mouse_y = 0.0; +} + +/* +================ +Sys_ConsoleInput +================ +*/ +char *Sys_ConsoleInput (void) +{ + return 0; +} diff --git a/contrib/other/sdlquake-1.0.9/vid_sunx.c b/contrib/other/sdlquake-1.0.9/vid_sunx.c new file mode 100644 index 000000000..4e27c8dad --- /dev/null +++ b/contrib/other/sdlquake-1.0.9/vid_sunx.c @@ -0,0 +1,1257 @@ +/* +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_x.c -- general x video driver + +#define _BSD + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "quakedef.h" +#include "d_local.h" + +cvar_t m_filter = {"m_filter","0", true}; + +qboolean mouse_avail; +int mouse_buttons=3; +int mouse_oldbuttonstate; +int mouse_buttonstate; +float mouse_x, mouse_y; +float old_mouse_x, old_mouse_y; +int p_mouse_x; +int p_mouse_y; +qboolean mouse_grabbed = false; // we grab it when console is up + +int VGA_width, VGA_height, VGA_rowbytes, VGA_bufferrowbytes, VGA_planar; +byte *VGA_pagebase; + +// The following X property format is defined in Motif 1.1's +// Xm/MwmUtils.h, but QUAKE should not depend on that header +// file. Note: Motif 1.2 expanded this structure with +// uninteresting fields (to QUAKE) so just stick with the +// smaller Motif 1.1 structure. + +#define MWM_HINTS_DECORATIONS 2 +typedef struct +{ + long flags; + long functions; + long decorations; + long input_mode; +} MotifWmHints; + +#define MAX_COLUMN_SIZE 11 + +#define MAX_MODEDESCS (MAX_COLUMN_SIZE*3) + +typedef struct +{ + int modenum; + int iscur; + char desc[256]; +} modedesc_t; + +extern void M_Menu_Options_f (void); +extern void M_Print (int cx, int cy, char *str); +extern void M_PrintWhite (int cx, int cy, char *str); +extern void M_DrawCharacter (int cx, int line, int num); +extern void M_DrawTransPic (int x, int y, qpic_t *pic); +extern void M_DrawPic (int x, int y, qpic_t *pic); + +extern int sb_updates; +extern int x_root, y_root; // root window relative mouse coords + +typedef struct +{ + int input; + int output; +} keymap_t; + +viddef_t vid; // global video state +unsigned short d_8to16table[256]; + +int num_shades=32; + +int d_con_indirect = 0; + +int vid_buffersize; + +#define STD_EVENT_MASK \ +( KeyPressMask | KeyReleaseMask | ButtonPressMask | ButtonReleaseMask | \ +PointerMotionMask | EnterWindowMask | LeaveWindowMask | VisibilityChangeMask | \ +ExposureMask | StructureNotifyMask ) + +qboolean x_fullscreen = true; +Display *x_disp = NULL; +int x_screen, x_screen_width, x_screen_height; +int x_center_width, x_center_height; +int x_std_event_mask = STD_EVENT_MASK; +Window x_win, x_root_win; +qboolean mouse_in_window = false; +int global_dx, global_dy; + +static qboolean doShm; +static Colormap x_cmap; +static GC x_gc; +static Visual *x_vis; +static XVisualInfo *x_visinfo; +static Atom aHints = 0; +static Atom aWMDelete = 0; + +static int x_shmeventtype; +//static XShmSegmentInfo x_shminfo; + +static qboolean oktodraw = false; + +int XShmQueryExtension(Display *); +int XShmGetEventBase(Display *); + +int current_framebuffer; +static XImage *x_framebuffer[2] = { 0, 0 }; +static XShmSegmentInfo x_shminfo[2]; + +static int verbose=1; + +static byte current_palette[768]; + +typedef unsigned short PIXEL16; +typedef unsigned long PIXEL24; +static PIXEL16 st2d_8to16table[256]; +static PIXEL24 st2d_8to24table[256]; +static int shiftmask_fl=0; +static long r_shift,g_shift,b_shift; +static unsigned long r_mask,g_mask,b_mask; + +void shiftmask_init() +{ + unsigned int x; + r_mask=x_vis->red_mask; + g_mask=x_vis->green_mask; + b_mask=x_vis->blue_mask; + for(r_shift=-8,x=1;x0) { + p=(r<<(r_shift))&r_mask; + } else if(r_shift<0) { + p=(r>>(-r_shift))&r_mask; + } else p|=(r&r_mask); + + if(g_shift>0) { + p|=(g<<(g_shift))&g_mask; + } else if(g_shift<0) { + p|=(g>>(-g_shift))&g_mask; + } else p|=(g&g_mask); + + if(b_shift>0) { + p|=(b<<(b_shift))&b_mask; + } else if(b_shift<0) { + p|=(b>>(-b_shift))&b_mask; + } else p|=(b&b_mask); + + return p; +} + +PIXEL24 xlib_rgb24(int r,int g,int b) +{ + PIXEL24 p; + if(shiftmask_fl==0) shiftmask_init(); + p=0; + + if(r_shift>0) { + p=(r<<(r_shift))&r_mask; + } else if(r_shift<0) { + p=(r>>(-r_shift))&r_mask; + } else p|=(r&r_mask); + + if(g_shift>0) { + p|=(g<<(g_shift))&g_mask; + } else if(g_shift<0) { + p|=(g>>(-g_shift))&g_mask; + } else p|=(g&g_mask); + + if(b_shift>0) { + p|=(b<<(b_shift))&b_mask; + } else if(b_shift<0) { + p|=(b>>(-b_shift))&b_mask; + } else p|=(b&b_mask); + + return p; +} + +void st2_fixup( XImage *framebuf, int x, int y, int width, int height) +{ + int xi,yi; + unsigned char *src; + PIXEL16 *dest; + register int count, n; + + if( (x<0)||(y<0) )return; + + for (yi = y; yi < (y+height); yi++) { + src = &framebuf->data [yi * framebuf->bytes_per_line]; + + // Duff's Device + count = width; + n = (count + 7) / 8; + dest = ((PIXEL16 *)src) + x+width - 1; + src += x+width - 1; + + switch (count % 8) { + case 0: do { *dest-- = st2d_8to16table[*src--]; + case 7: *dest-- = st2d_8to16table[*src--]; + case 6: *dest-- = st2d_8to16table[*src--]; + case 5: *dest-- = st2d_8to16table[*src--]; + case 4: *dest-- = st2d_8to16table[*src--]; + case 3: *dest-- = st2d_8to16table[*src--]; + case 2: *dest-- = st2d_8to16table[*src--]; + case 1: *dest-- = st2d_8to16table[*src--]; + } while (--n > 0); + } + +// for(xi = (x+width-1); xi >= x; xi--) { +// dest[xi] = st2d_8to16table[src[xi]]; +// } + } +} + +void st3_fixup( XImage *framebuf, int x, int y, int width, int height) +{ + int xi,yi; + unsigned char *src; + PIXEL24 *dest; + register int count, n; + + if( (x<0)||(y<0) )return; + + for (yi = y; yi < (y+height); yi++) { + src = &framebuf->data [yi * framebuf->bytes_per_line]; + + // Duff's Device + count = width; + n = (count + 7) / 8; + dest = ((PIXEL24 *)src) + x+width - 1; + src += x+width - 1; + + switch (count % 8) { + case 0: do { *dest-- = st2d_8to24table[*src--]; + case 7: *dest-- = st2d_8to24table[*src--]; + case 6: *dest-- = st2d_8to24table[*src--]; + case 5: *dest-- = st2d_8to24table[*src--]; + case 4: *dest-- = st2d_8to24table[*src--]; + case 3: *dest-- = st2d_8to24table[*src--]; + case 2: *dest-- = st2d_8to24table[*src--]; + case 1: *dest-- = st2d_8to24table[*src--]; + } while (--n > 0); + } + +// for(xi = (x+width-1); xi >= x; xi--) { +// dest[xi] = st2d_8to16table[src[xi]]; +// } + } +} + +/* +================ +D_BeginDirectRect +================ +*/ +void D_BeginDirectRect (int x, int y, byte *pbitmap, int width, int height) +{ +// direct drawing of the "accessing disk" icon isn't supported under Nextstep +} + + +/* +================ +D_EndDirectRect +================ +*/ +void D_EndDirectRect (int x, int y, int width, int height) +{ +// direct drawing of the "accessing disk" icon isn't supported under Nextstep +} + + +/* +================= +VID_Gamma_f + +Keybinding command +================= +*/ + +byte vid_gamma[256]; + +void VID_Gamma_f (void) +{ + + float g, f, inf; + int i; + + if (Cmd_Argc () == 2) + { + g = Q_atof (Cmd_Argv(1)); + + for (i=0 ; i<255 ; i++) + { + f = pow ((i+1)/256.0, g); + inf = f*255 + 0.5; + if (inf < 0) + inf = 0; + if (inf > 255) + inf = 255; + vid_gamma[i] = inf; + } + + VID_SetPalette (current_palette); + + vid.recalc_refdef = 1; // force a surface cache flush + } + +} + +// ======================================================================== +// Tragic death handler +// ======================================================================== + +void TragicDeath(int signal_num) +{ + //XAutoRepeatOn(x_disp); + VID_Shutdown(); + Sys_Error("This death brought to you by the number %d\n", signal_num); +} + +// ======================================================================== +// makes a null cursor +// ======================================================================== + +static Cursor CreateNullCursor(Display *display, Window root) +{ + Pixmap cursormask; + XGCValues xgc; + GC gc; + XColor dummycolour; + Cursor cursor; + + cursormask = XCreatePixmap(display, root, 1, 1, 1/*depth*/); + xgc.function = GXclear; + gc = XCreateGC(display, cursormask, GCFunction, &xgc); + XFillRectangle(display, cursormask, gc, 0, 0, 1, 1); + dummycolour.pixel = 0; + dummycolour.red = 0; + dummycolour.flags = 04; + cursor = XCreatePixmapCursor(display, cursormask, cursormask, + &dummycolour,&dummycolour, 0,0); + XFreePixmap(display,cursormask); + XFreeGC(display,gc); + return cursor; +} + +void ResetFrameBuffer(void) +{ + + int mem; + int pwidth; + + if (x_framebuffer[0]) + { + Z_Free(x_framebuffer[0]->data); +// Z_Free(d_pzbuffer); + free(x_framebuffer[0]); + } + + pwidth = x_visinfo->depth / 8; + if (pwidth == 3) pwidth = 4; + mem = ((vid.width*pwidth+3)&~3) * vid.height; + +// d_pzbuffer = (unsigned short *) Z_Malloc(vid.width*vid.height* +// sizeof(*d_pzbuffer)); + d_pzbuffer = (short *) Hunk_HighAllocName(vid.width*vid.height* + sizeof(*d_pzbuffer), "zbuff"); + + x_framebuffer[0] = XCreateImage( x_disp, + x_vis, + x_visinfo->depth, + ZPixmap, + 0, + Z_Malloc(mem), + vid.width, vid.height, + 32, + 0); + + if (!x_framebuffer[0]) + Sys_Error("VID: XCreateImage failed\n"); + +} + +void ResetSharedFrameBuffers(void) +{ + + int size; + int key; + int minsize = getpagesize(); + int frm; + +// if (d_pzbuffer) +// Z_Free(d_pzbuffer); + d_pzbuffer = Hunk_HighAllocName(vid.width*vid.height*sizeof(*d_pzbuffer),"zbuff"); + + for (frm=0 ; frm<2 ; frm++) + { + + // free up old frame buffer memory + + if (x_framebuffer[frm]) + { + XShmDetach(x_disp, &x_shminfo[frm]); + free(x_framebuffer[frm]); + shmdt(x_shminfo[frm].shmaddr); + } + + // create the image + + x_framebuffer[frm] = XShmCreateImage( x_disp, + x_vis, + x_visinfo->depth, + ZPixmap, + 0, + &x_shminfo[frm], + vid.width, + vid.height ); + + // grab shared memory + + size = x_framebuffer[frm]->bytes_per_line + * x_framebuffer[frm]->height; + if (size < minsize) + Sys_Error("VID: Window must use at least %d bytes\n", minsize); + + key = random(); + x_shminfo[frm].shmid = shmget((key_t)key, size, IPC_CREAT|0777); + if (x_shminfo[frm].shmid==-1) + Sys_Error("VID: Could not get any shared memory\n"); + + // attach to the shared memory segment + x_shminfo[frm].shmaddr = + (void *) shmat(x_shminfo[frm].shmid, 0, 0); + + printf("VID: shared memory id=%d, addr=0x%x\n", x_shminfo[frm].shmid, + (int) x_shminfo[frm].shmaddr); + + x_framebuffer[frm]->data = x_shminfo[frm].shmaddr; + + // get the X server to attach to it + + if (!XShmAttach(x_disp, &x_shminfo[frm])) + Sys_Error("VID: XShmAttach() failed\n"); + XSync(x_disp, 0); + shmctl(x_shminfo[frm].shmid, IPC_RMID, 0); + + } + +} + +void VID_MenuDraw( void ) +{ + qpic_t *p; + char *ptr; + int i, j, column, row, dup; + char temp[100]; + + p = Draw_CachePic ("gfx/vidmodes.lmp"); + M_DrawPic ( (320-p->width)/2, 4, p); + M_Print (4*8, 36 + MAX_COLUMN_SIZE * 8 + 8, "Video mode switching unavailable"); + M_Print (9*8, 36 + MAX_COLUMN_SIZE * 8 + 8*6, "Press any key..."); +} + +void VID_MenuKey( int key ) { M_Menu_Options_f (); } + +// 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 + +byte surfcache[1024*1024]; + +// +// VID_SetWindowTitle - set the window and icon titles +// + +void VID_SetWindowTitle( Window win, char *pszName ) +{ + XTextProperty textprop; + XWMHints *wmHints; + + // Setup ICCCM properties + textprop.value = (unsigned char *)pszName; + textprop.encoding = XA_STRING; + textprop.format = 8; + textprop.nitems = strlen(pszName); + wmHints = XAllocWMHints(); + wmHints->initial_state = NormalState; + wmHints->flags = StateHint; + XSetWMProperties( x_disp, win, &textprop, &textprop, + // Only put WM_COMMAND property on first window. + com_argv, com_argc, NULL, NULL, NULL ); + XFree( wmHints ); + + aWMDelete = XInternAtom( x_disp, "WM_DELETE_WINDOW", False ); + XSetWMProtocols( x_disp, win, &aWMDelete, 1 ); +} + +// +// VID_FullScreen - open the window in full screen mode +// + +qboolean VID_FullScreen( Window win ) +{ + MotifWmHints hints; + XWindowChanges changes; + + aHints = XInternAtom( x_disp, "_MOTIF_WM_HINTS", 0 ); + if (aHints == None) + { + Con_Printf( "Could not intern X atom for _MOTIF_WM_HINTS." ); + return( false ); + } + + hints.flags = MWM_HINTS_DECORATIONS; + hints.decorations = 0; // Absolutely no decorations. + XChangeProperty( x_disp, win, aHints, aHints, 32, PropModeReplace, (unsigned char *)&hints, 4 ); + + changes.x = 0; + changes.y = 0; + changes.width = x_screen_width; + changes.height = x_screen_height; + changes.stack_mode = TopIf; + XConfigureWindow( x_disp, win, CWX | CWY | CWWidth | CWHeight | CWStackMode, &changes); + return( true ); +} + +void VID_Init (unsigned char *palette) +{ + + int pnum, i; + XVisualInfo template; + int num_visuals; + int template_mask; + + Cmd_AddCommand ("gamma", VID_Gamma_f); + for (i=0 ; i<256 ; i++) + vid_gamma[i] = i; + + vid.width = 320; + vid.height = 200; + vid.aspect = 1.0; + vid.numpages = 2; + vid.colormap = host_colormap; + vid.fullbright = 256 - LittleLong (*((int *)vid.colormap + 2048)); + //vid.cbits = VID_CBITS; + //vid.grades = VID_GRADES; + + srandom(getpid()); + + verbose=COM_CheckParm("-verbose"); + +// open the display + x_disp = XOpenDisplay(0); + if (!x_disp) + { + if (getenv("DISPLAY")) + Sys_Error("VID: Could not open display [%s]\n", + getenv("DISPLAY")); + else + Sys_Error("VID: Could not open local display\n"); + } + + x_screen = XDefaultScreen( x_disp ); + x_screen_width = WidthOfScreen( ScreenOfDisplay( x_disp, x_screen ) ); + x_screen_height = HeightOfScreen( ScreenOfDisplay( x_disp, x_screen ) ); + + x_center_width = x_screen_width/2; + + x_center_height = x_screen_height/2; + + Con_Printf( "Using screen %d: %dx%d\n", x_screen, x_screen_width, x_screen_height ); + + x_root_win = XRootWindow( x_disp, x_screen ); + +// catch signals so i can turn on auto-repeat +// we never run full-screen, so no auto-repeat nukage + if (0) + { + struct sigaction sa; + sigaction(SIGINT, 0, &sa); + sa.sa_handler = TragicDeath; + sigaction(SIGINT, &sa, 0); + sigaction(SIGTERM, &sa, 0); + } + + //XAutoRepeatOff(x_disp); + +// for debugging only +// XSynchronize(x_disp, True); + +// check for command-line window size + if ((pnum=COM_CheckParm("-winsize"))) + { + if (pnum >= com_argc-2) + Sys_Error("VID: -winsize \n"); + vid.width = Q_atoi(com_argv[pnum+1]); + vid.height = Q_atoi(com_argv[pnum+2]); + if (!vid.width || !vid.height) + Sys_Error("VID: Bad window width/height\n"); + } + + template_mask = 0; + +// specify a visual id + if ((pnum=COM_CheckParm("-visualid"))) + { + if (pnum >= com_argc-1) + Sys_Error("VID: -visualid \n"); + template.visualid = Q_atoi(com_argv[pnum+1]); + template_mask = VisualIDMask; + } + +// If not specified, use default visual + else + { + int screen; + screen = XDefaultScreen(x_disp); + template.visualid = + XVisualIDFromVisual(XDefaultVisual(x_disp, screen)); + template_mask = VisualIDMask; + } + +// pick a visual- warn if more than one was available + x_visinfo = XGetVisualInfo(x_disp, template_mask, &template, &num_visuals); + if (num_visuals > 1) + { + printf("Found more than one visual id at depth %d:\n", template.depth); + for (i=0 ; ivisualid)); + printf(" class %d\n", x_visinfo->class); + printf(" screen %d\n", x_visinfo->screen); + printf(" depth %d\n", x_visinfo->depth); + printf(" red_mask 0x%x\n", (int)(x_visinfo->red_mask)); + printf(" green_mask 0x%x\n", (int)(x_visinfo->green_mask)); + printf(" blue_mask 0x%x\n", (int)(x_visinfo->blue_mask)); + printf(" colormap_size %d\n", x_visinfo->colormap_size); + printf(" bits_per_rgb %d\n", x_visinfo->bits_per_rgb); + } + + x_vis = x_visinfo->visual; + +// setup attributes for main window + { + int attribmask = CWEventMask | CWColormap | CWBorderPixel; + XSetWindowAttributes attribs; + Colormap tmpcmap; + + tmpcmap = XCreateColormap(x_disp, XRootWindow(x_disp, + x_visinfo->screen), x_vis, AllocNone); + + attribs.event_mask = x_std_event_mask; + attribs.border_pixel = 0; + attribs.colormap = tmpcmap; + +// create the main window + x_win = XCreateWindow( x_disp, + XRootWindow(x_disp, x_visinfo->screen), + 0, 0, // x, y + vid.width, vid.height, + 0, // borderwidth + x_visinfo->depth, + InputOutput, + x_vis, + attribmask, + &attribs ); + + if (x_visinfo->class != TrueColor) + XFreeColormap(x_disp, tmpcmap); + + } + + if (x_visinfo->depth == 8) + { + + // create and upload the palette + if (x_visinfo->class == PseudoColor) + { + x_cmap = XCreateColormap(x_disp, x_win, x_vis, AllocAll); + VID_SetPalette(palette); + XSetWindowColormap(x_disp, x_win, x_cmap); + } + + } + + VID_SetWindowTitle( x_win, "Quake" ); + +// create the GC + { + XGCValues xgcvalues; + int valuemask = GCGraphicsExposures; + xgcvalues.graphics_exposures = False; + x_gc = XCreateGC(x_disp, x_win, valuemask, &xgcvalues ); + } + +// map the window + XMapWindow(x_disp, x_win); + +// wait for first exposure event + { + XEvent event; + do + { + XNextEvent(x_disp, &event); + if (event.type == Expose && !event.xexpose.count) + oktodraw = true; + } while (!oktodraw); + } +// now safe to draw + +// even if MITSHM is available, make sure it's a local connection + if (XShmQueryExtension(x_disp)) + { + char *displayname; + doShm = true; + displayname = (char *) getenv("DISPLAY"); + if (displayname) + { + char *d = displayname; + while (*d && (*d != ':')) d++; + if (*d) *d = 0; + if (!(!strcasecmp(displayname, "unix") || !*displayname)) + doShm = false; + } + } + + if (doShm) + { + x_shmeventtype = XShmGetEventBase(x_disp) + ShmCompletion; + ResetSharedFrameBuffers(); + } + else + ResetFrameBuffer(); + + current_framebuffer = 0; + vid.rowbytes = x_framebuffer[0]->bytes_per_line; + vid.buffer = x_framebuffer[0]->data; + vid.conbuffer = x_framebuffer[0]->data; + vid.conrowbytes = vid.rowbytes; + vid.conwidth = vid.width; + vid.conheight = vid.height; + + vid.maxwarpwidth = WARP_WIDTH; + vid.maxwarpheight = WARP_HEIGHT; + + D_InitCaches (surfcache, sizeof(surfcache)); + +// XSynchronize(x_disp, False); + + vid_menudrawfn = VID_MenuDraw; + vid_menukeyfn = VID_MenuKey; + +} + +void VID_ShiftPalette(unsigned char *p) +{ + VID_SetPalette(p); +} + +void VID_SetPalette(unsigned char *palette) +{ + + int i; + XColor colors[256]; + + for(i=0;i<256;i++) { + st2d_8to16table[i]= xlib_rgb16(palette[i*3], palette[i*3+1],palette[i*3+2]); + st2d_8to24table[i]= xlib_rgb24(palette[i*3], palette[i*3+1],palette[i*3+2]); + } + + if (x_visinfo->class == PseudoColor && x_visinfo->depth == 8) + { + if (palette != current_palette) + memcpy(current_palette, palette, 768); + for (i=0 ; i<256 ; i++) + { + colors[i].pixel = i; + colors[i].flags = DoRed|DoGreen|DoBlue; + colors[i].red = vid_gamma[palette[i*3]] * 257; + colors[i].green = vid_gamma[palette[i*3+1]] * 257; + colors[i].blue = vid_gamma[palette[i*3+2]] * 257; + } + XStoreColors(x_disp, x_cmap, colors, 256); + } + +} + +// Called at shutdown + +void VID_Shutdown (void) +{ + Con_Printf("VID_Shutdown\n"); + //XAutoRepeatOn(x_disp); + if (mouse_grabbed) { + /* ungrab the pointer */ + XUngrabPointer(x_disp, CurrentTime); + XUndefineCursor(x_disp, x_win); + } + XCloseDisplay(x_disp); +} + +int XLateKey(XKeyEvent *ev) +{ + + int key; + char buf[64]; + KeySym keysym; + + XLookupString(ev, buf, sizeof buf, &keysym, 0); + + switch(keysym) + { + case XK_Page_Up: key = K_PGUP; break; + case XK_Page_Down: key = K_PGDN; break; + case XK_Home: key = K_HOME; break; + case XK_End: key = K_END; break; + case XK_Left: key = K_LEFTARROW; break; + case XK_Right: key = K_RIGHTARROW; break; + case XK_Down: key = K_DOWNARROW; break; + case XK_Up: key = K_UPARROW; break; + case XK_Escape: key = K_ESCAPE; break; + case XK_Return: key = K_ENTER; break; + case XK_Tab: key = K_TAB; break; + case XK_F1: key = K_F1; break; + case XK_F2: key = K_F2; break; + case XK_F3: key = K_F3; break; + case XK_F4: key = K_F4; break; + case XK_F5: key = K_F5; break; + case XK_F6: key = K_F6; break; + case XK_F7: key = K_F7; break; + case XK_F8: key = K_F8; break; + case XK_F9: key = K_F9; break; + case XK_F10: key = K_F10; break; + case XK_F11: key = K_F11; break; + case XK_F12: key = K_F12; break; + case XK_BackSpace: + case XK_Delete: key = K_BACKSPACE; break; + case XK_Pause: key = K_PAUSE; break; + case XK_Shift_L: + case XK_Shift_R: key = K_SHIFT; break; + case XK_Control_L: + case XK_Control_R: key = K_CTRL; break; + case XK_Alt_L: + case XK_Meta_L: + case XK_Alt_R: + case XK_Meta_R: key = K_ALT; break; +// various other keys on the keyboard + case XK_F27: key = K_HOME; break; + case XK_F29: key = K_PGUP; break; + case XK_F33: key = K_END; break; + case XK_F35: key = K_PGDN; break; + case XK_KP_Insert: key = K_INS; break; + + default: + key = *buf; + break; + } + + return key; + +} + +struct +{ + int key; + int down; +} keyq[64]; +int keyq_head=0; +int keyq_tail=0; + +int config_notify=0; +int config_notify_width; +int config_notify_height; + +void GetEvent(void) +{ + XEvent x_event; + + XNextEvent(x_disp, &x_event); + switch(x_event.type) + { + case KeyPress: + Key_Event(XLateKey(&x_event.xkey), true); + break; + case KeyRelease: + Key_Event(XLateKey(&x_event.xkey), false); + break; + case ButtonPress: + //printf( "button %d down\n", x_event.xbutton.button ); + Key_Event( K_MOUSE1 + x_event.xbutton.button - 1, true ); + break; + case ButtonRelease: + //printf( "button %d up\n", x_event.xbutton.button ); + Key_Event( K_MOUSE1 + x_event.xbutton.button - 1, false ); + break; + case MotionNotify: + if (mouse_avail && mouse_grabbed) { + mouse_x = (float) ((int)x_event.xmotion.x - (int)(vid.width/2)); + mouse_y = (float) ((int)x_event.xmotion.y - (int)(vid.height/2)); + //printf("m: x=%d,y=%d, mx=%3.2f,my=%3.2f\n", + // x_event.xmotion.x, x_event.xmotion.y, mouse_x, mouse_y); + + /* move the mouse to the window center again */ + XSelectInput(x_disp,x_win, STD_EVENT_MASK & ~PointerMotionMask); + XWarpPointer(x_disp,None,x_win,0,0,0,0, (vid.width/2),(vid.height/2)); + XSelectInput(x_disp,x_win, STD_EVENT_MASK); + } else { + mouse_x = (float) (x_event.xmotion.x-p_mouse_x); + mouse_y = (float) (x_event.xmotion.y-p_mouse_y); + p_mouse_x=x_event.xmotion.x; + p_mouse_y=x_event.xmotion.y; + } + break; + + case ConfigureNotify: +// printf("config notify\n"); + config_notify_width = x_event.xconfigure.width; + config_notify_height = x_event.xconfigure.height; + config_notify = 1; + sb_updates = 0; + break; + case Expose: + sb_updates = 0; + break; + case ClientMessage: + if (x_event.xclient.data.l[0] == aWMDelete) Host_Quit_f(); + break; + case EnterNotify: + mouse_in_window = true; + break; + case LeaveNotify: + mouse_in_window = false; + break; + + default: + if (doShm && x_event.type == x_shmeventtype) + oktodraw = true; + } + + if (mouse_avail) { + if (key_dest == key_game && !mouse_grabbed && mouse_in_window) { + mouse_grabbed = true; + /* grab the pointer */ + XGrabPointer(x_disp,x_win,True,0,GrabModeAsync, + GrabModeAsync,x_win,None,CurrentTime); + // inviso cursor + XDefineCursor(x_disp, x_win, CreateNullCursor(x_disp, x_win)); + } else if ((key_dest != key_game || !mouse_in_window) && mouse_grabbed) { + mouse_grabbed = false; + /* ungrab the pointer */ + XUngrabPointer(x_disp, CurrentTime); + XUndefineCursor(x_disp, x_win); + } + } +} + +// flushes the given rectangles from the view buffer to the screen + +void VID_Update (vrect_t *rects) +{ +#if 0 + static int count; + static long long s; + long long gethrtime(); + + if (count == 0) + s = gethrtime(); + + if (count++ == 50) { + count = 1; + printf("%lf frames/secs\n", 50.0/((double)(gethrtime()-s) / 1e9)); + s = gethrtime(); + } +#endif + +// if the window changes dimension, skip this frame + + if (config_notify) + { + printf("config notify\n"); + config_notify = 0; + vid.width = config_notify_width & ~3; + vid.height = config_notify_height; + + printf("w = %d, h = %d\n", vid.width, vid.height); + + if (doShm) + ResetSharedFrameBuffers(); + else + ResetFrameBuffer(); + vid.rowbytes = x_framebuffer[0]->bytes_per_line; + vid.buffer = x_framebuffer[current_framebuffer]->data; + vid.conbuffer = vid.buffer; + vid.conwidth = vid.width; + vid.conheight = vid.height; + vid.conrowbytes = vid.rowbytes; + vid.recalc_refdef = 1; // force a surface cache flush + return; + } + + if (doShm) + { +// long long s, gethrtime(); +// s = gethrtime(); + + while (rects) + { +printf("update: %d,%d (%d,%d)\n", rects->x, rects->y, rects->width, rects->height); + if (x_visinfo->depth == 16) + st2_fixup( x_framebuffer[current_framebuffer], + rects->x, rects->y, rects->width, + rects->height); + else if (x_visinfo->depth == 24) + st3_fixup( x_framebuffer[current_framebuffer], + rects->x, rects->y, rects->width, + rects->height); + if (!XShmPutImage(x_disp, x_win, x_gc, + x_framebuffer[current_framebuffer], rects->x, rects->y, + rects->x, rects->y, rects->width, rects->height, True)) + Sys_Error("VID_Update: XShmPutImage failed\n"); + oktodraw = false; + while (!oktodraw) GetEvent(); + rects = rects->pnext; + } +// printf("%lf\n", (double)(gethrtime()-s)/1.0e9); + current_framebuffer = !current_framebuffer; + vid.buffer = x_framebuffer[current_framebuffer]->data; + vid.conbuffer = vid.buffer; + XSync(x_disp, False); + + } + else + { + while (rects) + { + if (x_visinfo->depth == 16) + st2_fixup( x_framebuffer[current_framebuffer], + rects->x, rects->y, rects->width, + rects->height); + else if (x_visinfo->depth == 24) + st3_fixup( x_framebuffer[current_framebuffer], + rects->x, rects->y, rects->width, + rects->height); + XPutImage(x_disp, x_win, x_gc, x_framebuffer[0], rects->x, + rects->y, rects->x, rects->y, rects->width, rects->height); + rects = rects->pnext; + } + XSync(x_disp, False); + } +} + +static int dither; + +void VID_DitherOn(void) +{ + if (dither == 0) + { + vid.recalc_refdef = 1; + dither = 1; + } +} + +void VID_DitherOff(void) +{ + if (dither) + { + vid.recalc_refdef = 1; + dither = 0; + } +} + +void VID_SetDefaultMode( void ) +{ +} + +int I_OpenWindow(void) +{ + return 0; +} + +void I_EraseWindow(int window) +{ +} + +void I_DrawCircle(int window, int x, int y, int r) +{ +} + +void I_DisplayWindow(int window) +{ +} + +void Sys_SendKeyEvents(void) +{ +// get events from x server + if (x_disp) + { + while (XPending(x_disp)) GetEvent(); + while (keyq_head != keyq_tail) + { + Key_Event(keyq[keyq_tail].key, keyq[keyq_tail].down); + keyq_tail = (keyq_tail + 1) & 63; + } + } +} + +#if 0 +char *Sys_ConsoleInput (void) +{ + + static char text[256]; + int len; + fd_set readfds; + int ready; + struct timeval timeout; + + timeout.tv_sec = 0; + timeout.tv_usec = 0; + FD_ZERO(&readfds); + FD_SET(0, &readfds); + ready = select(1, &readfds, 0, 0, &timeout); + + if (ready>0) + { + len = read (0, text, sizeof(text)); + if (len >= 1) + { + text[len-1] = 0; // rip off the /n and terminate + return text; + } + } + + return 0; + +} +#endif + +void IN_Init (void) +{ + Cvar_RegisterVariable (&m_filter); + if ( COM_CheckParm ("-nomouse") ) + return; + mouse_x = mouse_y = 0.0; + mouse_avail = 1; +} + +void IN_Shutdown (void) +{ + mouse_avail = 0; +} + +void IN_Commands (void) +{ + int i; + + if (!mouse_avail) return; + + for (i=0 ; isidemove += m_side.value * mouse_x; + else + cl.viewangles[YAW] -= m_yaw.value * mouse_x; + if (in_mlook.state & 1) + V_StopPitchDrift (); + + if ( (in_mlook.state & 1) && !(in_strafe.state & 1)) { + 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; + } + mouse_x = mouse_y = 0.0; +} diff --git a/contrib/other/sdlquake-1.0.9/vid_sunxil.c b/contrib/other/sdlquake-1.0.9/vid_sunxil.c new file mode 100644 index 000000000..31f301e10 --- /dev/null +++ b/contrib/other/sdlquake-1.0.9/vid_sunxil.c @@ -0,0 +1,1288 @@ +/* +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_sunxil.c -- uses X to setup windows and XIL to copy images (scaled as needed) +// to screen + +#define _BSD +#define BYTE_DEFINED 1 + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "quakedef.h" +#include "d_local.h" + +#define MIN_WIDTH 320 +#define MIN_HEIGHT 200 + +cvar_t _windowed_mouse = {"_windowed_mouse","0", true}; +cvar_t m_filter = {"m_filter","0", true}; +float old_windowed_mouse; + +// The following X property format is defined in Motif 1.1's +// Xm/MwmUtils.h, but QUAKE should not depend on that header +// file. Note: Motif 1.2 expanded this structure with +// uninteresting fields (to QUAKE) so just stick with the +// smaller Motif 1.1 structure. + +#define MWM_HINTS_DECORATIONS 2 +typedef struct +{ + long flags; + long functions; + long decorations; + long input_mode; +} MotifWmHints; + +#define MAX_COLUMN_SIZE 11 + +#define MAX_MODEDESCS (MAX_COLUMN_SIZE*3) + +typedef struct +{ + int modenum; + int iscur; + char desc[256]; +} modedesc_t; + +extern void M_Menu_Options_f (void); +extern void M_Print (int cx, int cy, char *str); +extern void M_PrintWhite (int cx, int cy, char *str); +extern void M_DrawCharacter (int cx, int line, int num); +extern void M_DrawTransPic (int x, int y, qpic_t *pic); +extern void M_DrawPic (int x, int y, qpic_t *pic); + +extern int sb_updates; + +qboolean mouse_avail; +int mouse_buttons=3; +int mouse_oldbuttonstate; +int mouse_buttonstate; +float mouse_x, mouse_y; +float old_mouse_x, old_mouse_y; +int p_mouse_x; +int p_mouse_y; + +typedef struct +{ + int input; + int output; +} keymap_t; + +viddef_t vid; // global video state +unsigned short d_8to16table[256]; + +int num_shades=32; + +int d_con_indirect = 0; + +int vid_buffersize; + +#define STD_EVENT_MASK \ +( \ + StructureNotifyMask | \ + KeyPressMask | \ + KeyReleaseMask | \ + ButtonPressMask | \ + ButtonReleaseMask | \ + ExposureMask | \ + PointerMotionMask | \ + FocusChangeMask \ +) + +int VGA_width, VGA_height, VGA_rowbytes, VGA_bufferrowbytes, VGA_planar; +byte *VGA_pagebase; + +qboolean x_fullscreen = true; +Display *x_disp = NULL; +int x_screen, x_screen_width, x_screen_height; +int x_center_width, x_center_height; +int x_std_event_mask = STD_EVENT_MASK; +Window x_win, x_root_win; +qboolean x_focus = true; +int global_dx, global_dy; + + +static Colormap x_cmap; +static GC x_gc; +static Visual *x_vis; +static XVisualInfo *x_visinfo; +static Atom aHints = NULL; +static Atom aWMDelete = NULL; + +static qboolean oktodraw = false; +static qboolean X11_active = false; + + +static int verbose=1; + +static byte current_palette[768]; + +cvar_t pixel_multiply = {"pixel_multiply", "2", true}; +int current_pixel_multiply = 2; + +#define PM(a) (int)((current_pixel_multiply)?((a)*current_pixel_multiply):(a)) +#define MP(a) (int)((current_pixel_multiply)?((a)/current_pixel_multiply):(a)) + +static int render_pipeline[2]; +static XilSystemState state; +static XilImage display_image = NULL; +static XilImage quake_image = NULL; +static int use_mt = 0; +static int count_frames = 0; + +/* +================ +D_BeginDirectRect +================ +*/ +void D_BeginDirectRect (int x, int y, byte *pbitmap, int width, int height) +{ +// direct drawing of the "accessing disk" icon isn't supported under Nextstep +} + + +/* +================ +D_EndDirectRect +================ +*/ +void D_EndDirectRect (int x, int y, int width, int height) +{ +// direct drawing of the "accessing disk" icon isnt supported under Nextstep +} + + +/* +================= +VID_Gamma_f + +Keybinding command +================= +*/ + +byte vid_gamma[256]; + +void VID_Gamma_f (void) +{ + + float g, f, inf; + int i; + + if (Cmd_Argc () == 2) { + g = Q_atof (Cmd_Argv(1)); + + for (i=0 ; i<255 ; i++) { + f = pow ((i+1)/256.0, g); + inf = f*255 + 0.5; + if (inf < 0) + inf = 0; + if (inf > 255) + inf = 255; + vid_gamma[i] = inf; + } + + VID_SetPalette (current_palette); + + vid.recalc_refdef = 1; // force a surface cache flush + } + +} + +qboolean CheckPixelMultiply (void) +{ + int m; + int w, h; + XWindowAttributes wattr; + XWindowChanges chg; + unsigned int value_mask; + int old_pixel; + + if ((m = (int)pixel_multiply.value) != current_pixel_multiply) { + if (m < 1) + m = 1; + if (m > 4) + m = 4; + + old_pixel = current_pixel_multiply; + current_pixel_multiply = m; + Cvar_SetValue("pixel_multiply", m); + + if(XGetWindowAttributes(x_disp, x_win, & wattr) == 0) + return true; // ??? + + memset(&chg, 0, sizeof(chg)); + chg.width = wattr.width/old_pixel * current_pixel_multiply; + chg.height = wattr.height/old_pixel * current_pixel_multiply; + + if (chg.width < MIN_WIDTH*current_pixel_multiply) + chg.width = MIN_WIDTH*current_pixel_multiply; + if (chg.height < MIN_HEIGHT*current_pixel_multiply) + chg.height = MIN_HEIGHT*current_pixel_multiply; + + XConfigureWindow(x_disp, x_win, CWWidth | CWHeight, &chg); + + vid.width = MP(wattr.width) & ~3; + vid.height = MP(wattr.height); + + if (vid.width < 320) + vid.width = 320; + if (vid.height < 200) + vid.height = 200; + VID_ResetFramebuffer(); + + return true; + } + return false; +} + +// ======================================================================== +// Tragic death handler +// ======================================================================== + +void TragicDeath(int signal_num) +{ + //XAutoRepeatOn(x_disp); + XCloseDisplay(x_disp); + Sys_Error("This death brought to you by the number %d\n", signal_num); +} + +// ======================================================================== +// makes a null cursor +// ======================================================================== + +static Cursor CreateNullCursor(Display *display, Window root) +{ + Pixmap cursormask; + XGCValues xgc; + GC gc; + XColor dummycolour; + Cursor cursor; + + cursormask = XCreatePixmap(display, root, 1, 1, 1/*depth*/); + xgc.function = GXclear; + gc = XCreateGC(display, cursormask, GCFunction, &xgc); + XFillRectangle(display, cursormask, gc, 0, 0, 1, 1); + dummycolour.pixel = 0; + dummycolour.red = 0; + dummycolour.flags = 04; + cursor = XCreatePixmapCursor(display, cursormask, cursormask, + &dummycolour,&dummycolour, 0,0); + XFreePixmap(display,cursormask); + XFreeGC(display,gc); + return cursor; +} + + +void VID_MenuDraw( void ) +{ + qpic_t *p; + char *ptr; + int i, j, column, row, dup; + char temp[100]; + + p = Draw_CachePic ("gfx/vidmodes.lmp"); + M_DrawPic ( (320-p->width)/2, 4, p); + M_Print (4*8, 36 + MAX_COLUMN_SIZE * 8 + 8, "Video mode switching unavailable"); + M_Print (9*8, 36 + MAX_COLUMN_SIZE * 8 + 8*6, "Press any key..."); +} + +void VID_MenuKey( int key ) { M_Menu_Options_f (); } + +// 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 + +byte surfcache[1024*1024]; + +// +// VID_SetWindowTitle - set the window and icon titles +// + +void VID_SetWindowTitle( Window win, char *pszName ) +{ + XTextProperty textprop; + XWMHints *wmHints; + + // Setup ICCCM properties + textprop.value = (unsigned char *)pszName; + textprop.encoding = XA_STRING; + textprop.format = 8; + textprop.nitems = strlen(pszName); + wmHints = XAllocWMHints(); + wmHints->initial_state = NormalState; + wmHints->flags = StateHint; + XSetWMProperties( x_disp, win, &textprop, &textprop, + // Only put WM_COMMAND property on first window. + com_argv, com_argc, NULL, NULL, NULL ); + XFree( wmHints ); + + aWMDelete = XInternAtom( x_disp, "WM_DELETE_WINDOW", False ); + XSetWMProtocols( x_disp, win, &aWMDelete, 1 ); +} + +// +// VID_FullScreen - open the window in full screen mode +// + +qboolean VID_FullScreen( Window win ) +{ + MotifWmHints hints; + XWindowChanges changes; + + aHints = XInternAtom( x_disp, "_MOTIF_WM_HINTS", 0 ); + if (aHints == None) { + Con_Printf( "Could not intern X atom for _MOTIF_WM_HINTS." ); + return( false ); + } + + hints.flags = MWM_HINTS_DECORATIONS; + hints.decorations = 0; // Absolutely no decorations. + XChangeProperty( x_disp, win, aHints, aHints, 32, PropModeReplace, (unsigned char *)&hints, 4 ); + + changes.x = 0; + changes.y = 0; + changes.width = x_screen_width; + changes.height = x_screen_height; + changes.stack_mode = TopIf; + XConfigureWindow( x_disp, win, CWX | CWY | CWWidth | CWHeight | CWStackMode, &changes); + return( true ); +} + +void VID_Init (unsigned char *palette) +{ + + int pnum, i; + XVisualInfo template; + int num_visuals; + int template_mask; + int w, h; + + int desired_width=320, desired_height=200; + + Cmd_AddCommand ("gamma", VID_Gamma_f); + + Cvar_RegisterVariable (&pixel_multiply); + + if (pipe(render_pipeline) < 0) + Sys_Error("VID_Init: pipe"); + + for (i=0 ; i<256 ; i++) + vid_gamma[i] = i; + + vid.width = 320; + vid.height = 200; + vid.aspect = 1.0; + vid.numpages = 2; + vid.colormap = host_colormap; + vid.fullbright = 256 - LittleLong (*((int *)vid.colormap + 2048)); + //vid.cbits = VID_CBITS; + //vid.grades = VID_GRADES; + + srandom(getpid()); + + verbose = COM_CheckParm("-verbose"); + count_frames = COM_CheckParm("-count_frames"); + +// +// open the display +// + x_disp = XOpenDisplay(0); + + if (!x_disp) { + if (getenv("DISPLAY")) + Sys_Error("VID: Could not open display [%s]\n", + getenv("DISPLAY")); + else + Sys_Error("VID: Could not open local display\n"); + } + + x_screen = DefaultScreen( x_disp ); + x_screen_width = WidthOfScreen( ScreenOfDisplay( x_disp, x_screen ) ); + x_screen_height = HeightOfScreen( ScreenOfDisplay( x_disp, x_screen ) ); + + x_center_width = x_screen_width/2; + + x_center_height = x_screen_height/2; + + Con_Printf( "Using screen %d: %dx%d\n", x_screen, x_screen_width, x_screen_height ); + + x_root_win = DefaultRootWindow( x_disp); + + //XAutoRepeatOff(x_disp); + +// for debugging only + if (verbose) + XSynchronize(x_disp, True); + +// +// check for command-line window size +// + if ((pnum=COM_CheckParm("-winsize"))) { + if (pnum >= com_argc-2) + Sys_Error("VID: -winsize \n"); + desired_width = Q_atoi(com_argv[pnum+1]); + desired_height = Q_atoi(com_argv[pnum+2]); + if (desired_width < 1 || desired_height < 1) + Sys_Error("VID: Bad window width/height\n"); + } + + template_mask = VisualScreenMask; // make sure we get the right one + template.screen = x_screen; +// +// specify a visual id +// + if ((pnum=COM_CheckParm("-visualid"))) { + if (pnum >= com_argc-1) + Sys_Error("VID: -visualid \n"); + template.visualid = Q_atoi(com_argv[pnum+1]); + template_mask |= VisualIDMask; + } else { + // If not specified, find an 8 bit visual since others don't work +// template.depth = 8; +// template_mask |= VisualDepthMask; + int screen; + screen = XDefaultScreen(x_disp); + template.visualid = + XVisualIDFromVisual(XDefaultVisual(x_disp, screen)); + template_mask = VisualIDMask; + } +// +// pick a visual- warn if more than one was available +// + x_visinfo = XGetVisualInfo(x_disp, template_mask, &template, &num_visuals); + if (num_visuals > 1) { + printf("Found more than one visual id at depth %d:\n", template.depth); + for (i=0 ; ivisualid)); + printf(" screen %d\n", x_visinfo->screen); + printf(" red_mask 0x%x\n", (int)(x_visinfo->red_mask)); + printf(" green_mask 0x%x\n", (int)(x_visinfo->green_mask)); + printf(" blue_mask 0x%x\n", (int)(x_visinfo->blue_mask)); + printf(" colormap_size %d\n", x_visinfo->colormap_size); + printf(" bits_per_rgb %d\n", x_visinfo->bits_per_rgb); + } + + x_vis = x_visinfo->visual; +// +// See if we're going to do pixel multiply +// + if (pixel_multiply.value < 1 || pixel_multiply.value > 4) + Cvar_SetValue("pixel_multiply", 2); + current_pixel_multiply = pixel_multiply.value; + + w = 320*current_pixel_multiply; // minimum width + h = 200*current_pixel_multiply; // minimum height + if (desired_width < w) + desired_width = w; + if (desired_height < h) + desired_height = h; + + vid.width = MP(desired_width); + vid.height = MP(desired_height); + + // + // patch things up so game doesn't fail if window is too small + // + + if (vid.width < 320) + vid.width = 320; + if (vid.height < 200) + vid.height = 200; + +// +// see if we're going to use threads +// + if(((sysconf(_SC_NPROCESSORS_ONLN) > 1) || COM_CheckParm("-mt")) && + (COM_CheckParm("-no_mt") == 0)) { + use_mt = 1; + printf("VID: Using multiple threads!\n"); + } + +// setup attributes for main window + { + int attribmask = CWEventMask | CWColormap | CWBorderPixel; + XSetWindowAttributes attribs; + Colormap tmpcmap; + + tmpcmap = XCreateColormap(x_disp, XRootWindow(x_disp, + x_visinfo->screen), x_vis, AllocNone); + + attribs.event_mask = x_std_event_mask; + attribs.border_pixel = 0; + attribs.colormap = tmpcmap; + +// create the main window + x_win = XCreateWindow( x_disp, + XRootWindow(x_disp, x_visinfo->screen), + 0, 0, // x, y + desired_width, desired_height, + 0, // borderwidth + x_visinfo->depth, + InputOutput, + x_vis, + attribmask, + &attribs ); + + if (x_visinfo->class != TrueColor) + XFreeColormap(x_disp, tmpcmap); + + } + + if (x_visinfo->depth == 8) { + + // create and upload the palette + if (x_visinfo->class == PseudoColor) { + x_cmap = XCreateColormap(x_disp, x_win, x_vis, AllocAll); + VID_SetPalette(palette); + XSetWindowColormap(x_disp, x_win, x_cmap); + } + + } + + VID_SetWindowTitle( x_win, "Quake" ); + +// inviso cursor + XDefineCursor(x_disp, x_win, CreateNullCursor(x_disp, x_win)); + +// create the GC + { + XGCValues xgcvalues; + int valuemask = GCGraphicsExposures; + xgcvalues.graphics_exposures = False; + x_gc = XCreateGC(x_disp, x_win, valuemask, &xgcvalues ); + } + +// map the window + XMapWindow(x_disp, x_win); + XSync(x_disp, True) ; /* wait for map */ +// +// wait for first exposure event +// + { + XEvent event; + do{ + XNextEvent(x_disp, &event); + if (event.type == Expose && !event.xexpose.count) + oktodraw = true; + } while (!oktodraw); + } +// +// initialize XIL +// + + state = xil_open(); + + if(state == NULL) { + // + // XIL's default error handler will print an error msg on stderr + // + Sys_Error("xil_open failed\n"); + } + + X11_active = true; + + VID_ResetFramebuffer(); + + D_InitCaches (surfcache, sizeof(surfcache)); + + vid_menudrawfn = VID_MenuDraw; + vid_menukeyfn = VID_MenuKey; +} + +VID_ResetFramebuffer() +{ + XilMemoryStorage storage; + + if (use_mt) { + VID_ResetFramebuffer_MT(); + return; + } + +//printf("VID_ResetFramebuffer: vid.width %d, vid.height %d\n", vid.width, vid.height); + + xil_destroy(display_image); + + xil_destroy(quake_image); + + display_image = xil_create_from_window(state, x_disp, x_win); + quake_image = xil_create(state, vid.width, vid.height, 1, XIL_BYTE); + + xil_export(quake_image); + + if (xil_get_memory_storage(quake_image, &storage) == FALSE) + Sys_Error("xil_get_memory_storage"); + + xil_import(quake_image, TRUE); + xil_export(quake_image); + + if (xil_get_memory_storage(quake_image, &storage) == FALSE) + Sys_Error("xil_get_memory_storage"); + + vid.rowbytes = storage.byte.scanline_stride; + vid.buffer = storage.byte.data; + vid.conbuffer = vid.buffer; + vid.conrowbytes = vid.rowbytes; + vid.conwidth = vid.width; + vid.conheight = vid.height; + + vid.maxwarpwidth = WARP_WIDTH; + vid.maxwarpheight = WARP_HEIGHT; + vid.recalc_refdef = 1; // force a surface cache flush + + free(d_pzbuffer); + + d_pzbuffer = malloc(PM(vid.width)*PM(vid.height)*sizeof(*d_pzbuffer)); + //Hunk_HighAllocName(PM(vid.width)*PM(vid.height)*sizeof(*d_pzbuffer),"zbuff"); +} + +VID_ResetFramebuffer_MT() +{ + XilMemoryStorage storage; + XilImage drain_renderpipeline(); + XilImage old_display_image; + + void * update_thread(); + + printf("VID_ResetFramebuffer: vid.width %d, vid.height %d\n", vid.width, vid.height); + + old_display_image = display_image; + + display_image = xil_create_from_window(state, x_disp, x_win); + + if (quake_image == NULL) + if (thr_create(NULL, NULL, update_thread, NULL, THR_NEW_LWP, NULL) != 0) + Sys_Error("VID: thr_create"); + + quake_image = drain_renderpipeline(quake_image); + + xil_destroy(old_display_image); + + free(d_pzbuffer); + + d_pzbuffer = malloc(PM(vid.width)*PM(vid.height)*sizeof(*d_pzbuffer)); +} + +void VID_ShiftPalette(unsigned char *p) +{ + VID_SetPalette(p); +} + +void VID_SetPalette(unsigned char *palette) +{ + + int i; + XColor colors[256]; + + if (x_visinfo->class == PseudoColor && x_visinfo->depth == 8) { + if (palette != current_palette) + memcpy(current_palette, palette, 768); + for (i=0 ; i<256 ; i++) + { + colors[i].pixel = i; + colors[i].flags = DoRed|DoGreen|DoBlue; + colors[i].red = vid_gamma[palette[i*3]] * 257; + colors[i].green = vid_gamma[palette[i*3+1]] * 257; + colors[i].blue = vid_gamma[palette[i*3+2]] * 257; + } + XStoreColors(x_disp, x_cmap, colors, 256); + } + +} + +// Called at shutdown + +void VID_Shutdown (void) +{ + X11_active = false; + Con_Printf("VID_Shutdown\n"); + //XAutoRepeatOn(x_disp); + xil_destroy(display_image); + xil_destroy(quake_image); + display_image = NULL; + quake_image = NULL; + XCloseDisplay(x_disp); +} + +int XLateKey(XKeyEvent *ev) +{ + + int key; + char buf[64]; + KeySym keysym; + + XLookupString(ev, buf, sizeof buf, &keysym, 0); + + switch(keysym) { + case XK_Page_Up: key = K_PGUP; break; + case XK_Page_Down: key = K_PGDN; break; + case XK_Home: key = K_HOME; break; + case XK_End: key = K_END; break; + case XK_Left: key = K_LEFTARROW; break; + case XK_Right: key = K_RIGHTARROW; break; + case XK_Down: key = K_DOWNARROW; break; + case XK_Up: key = K_UPARROW; break; + case XK_Escape: key = K_ESCAPE; break; + case XK_Return: key = K_ENTER; break; + case XK_Tab: key = K_TAB; break; + case XK_Help: + case XK_F1: key = K_F1; break; + case XK_F2: key = K_F2; break; + case XK_F3: key = K_F3; break; + case XK_F4: key = K_F4; break; + case XK_F5: key = K_F5; break; + case XK_F6: key = K_F6; break; + case XK_F7: key = K_F7; break; + case XK_F8: key = K_F8; break; + case XK_F9: key = K_F9; break; + case XK_F10: key = K_F10; break; + case XK_F11: key = K_F11; break; + case XK_F12: key = K_F12; break; + case XK_BackSpace: + case XK_Delete: key = K_BACKSPACE; break; + case XK_Pause: key = K_PAUSE; break; + case XK_Shift_L: + case XK_Shift_R: key = K_SHIFT; break; + case XK_Control_L: + case XK_Control_R: key = K_CTRL; break; + case XK_Alt_L: + case XK_Meta_L: + case XK_Alt_R: + case XK_Meta_R: key = K_ALT; break; + // various other keys on the keyboard + case XK_F27: key = K_HOME; break; + case XK_F29: key = K_PGUP; break; + case XK_F33: key = K_END; break; + case XK_F35: key = K_PGDN; break; + case XK_Insert: + case XK_KP_Insert: key = K_INS; break; + case XK_F24: key = '-'; break; + case XK_KP_Add: key = '+'; break; + case XK_KP_Subtract: key = '-'; break; + case XK_F25: key = '/'; break; + case XK_F26: key = '*'; break; + + default: + key = (unsigned char)*buf; + break; + } + + return key; + +} + +struct { + int key; + int down; +} keyq[64]; + +int keyq_head=0; +int keyq_tail=0; + +int config_notify=0; +int config_notify_width; +int config_notify_height; + +void GetEvent(void) +{ + XEvent x_event; + int b; + + XNextEvent(x_disp, &x_event); + switch(x_event.type) { + case KeyPress: + Key_Event(XLateKey(&x_event.xkey), true); + break; + case KeyRelease: + Key_Event(XLateKey(&x_event.xkey), false); + break; + + case MotionNotify: + + if (_windowed_mouse.value) { + mouse_x = (float) ((int)x_event.xmotion.x - (int)(vid.width/2)); + mouse_y = (float) ((int)x_event.xmotion.y - (int)(vid.height/2)); + //printf("m: x=%d,y=%d, mx=%3.2f,my=%3.2f\n", + // x_event.xmotion.x, x_event.xmotion.y, mouse_x, mouse_y); + + /* move the mouse to the window center again */ + XSelectInput( x_disp, x_win, x_std_event_mask & ~PointerMotionMask ); + XWarpPointer(x_disp,None,x_win,0,0,0,0, + (vid.width/2),(vid.height/2)); + XSelectInput( x_disp, x_win, x_std_event_mask ); + } else { + mouse_x = (float) (x_event.xmotion.x-p_mouse_x); + mouse_y = (float) (x_event.xmotion.y-p_mouse_y); + p_mouse_x=x_event.xmotion.x; + p_mouse_y=x_event.xmotion.y; + } + break; + + case ButtonPress: + b=-1; + if (x_event.xbutton.button == 1) + b = 0; + else if (x_event.xbutton.button == 2) + b = 2; + else if (x_event.xbutton.button == 3) + b = 1; + if (b>=0) + mouse_buttonstate |= 1<=0) + mouse_buttonstate &= ~(1<pnext; + } +} + +void +VID_Update_MT (vrect_t *rects) +{ + XilImage sched_update(); + + // if the window changes dimension, skip this frame + + if (config_notify) { + int w, h; + XWindowChanges chg; + unsigned int value_mask; + + w = 320*current_pixel_multiply; // minimum width + h = 200*current_pixel_multiply; // minimum height + + if (config_notify_width < w || config_notify_height < h) { + // We must resize the window + memset(&chg, 0, sizeof(chg)); + value_mask = 0; + if (config_notify_width < w) { + config_notify_width = chg.width = w; + value_mask |= CWWidth; + } + if (config_notify_height < h) { + config_notify_height = chg.height = h; + value_mask |= CWHeight; + } + if (value_mask) + XConfigureWindow(x_disp, x_win, value_mask, &chg); + } + + config_notify = 0; + + vid.width = MP(config_notify_width) & ~3; + vid.height = MP(config_notify_height); + + if (vid.width < 320) + vid.width = 320; + if (vid.height < 200) + vid.height = 200; + + VID_ResetFramebuffer_MT(); + + return; + } + // if pixel multiply changed, skip this frame + if (CheckPixelMultiply()) + return; + + quake_image = sched_update(quake_image); +} + +XilImage +drain_renderpipeline(XilImage old) +{ + XilImage new; + + XilMemoryStorage storage; + + if (old) + if (read(render_pipeline[1], &new, sizeof(new)) != sizeof (new)) { + Sys_Error("drain_renderpipeline: read"); + xil_destroy(new); + } + + xil_destroy(old); + + + new = xil_create(state, vid.width, vid.height, 1, XIL_BYTE); + + if (write(render_pipeline[0], &new, sizeof (new)) != sizeof(new)) + Sys_Error("drain_renderpipeline: write"); + + new = xil_create(state, vid.width, vid.height, 1, XIL_BYTE); + + xil_export(new); + + if (xil_get_memory_storage(new, &storage) == FALSE) + Sys_Error("xil_get_memory_storage"); + + vid.rowbytes = storage.byte.scanline_stride; + vid.buffer = storage.byte.data; + vid.conbuffer = vid.buffer; + vid.conrowbytes = vid.rowbytes; + vid.conwidth = vid.width; + vid.conheight = vid.height; + + vid.maxwarpwidth = WARP_WIDTH; + vid.maxwarpheight = WARP_HEIGHT; + vid.recalc_refdef = 1; // force a surface cache flush + + return(new); + +} + +XilImage +sched_update(XilImage image) +{ + XilImage new; + XilMemoryStorage storage; + + if (write(render_pipeline[1], &image, sizeof(image)) != sizeof (image)) + Sys_Error("sched_update:write"); + + if (read(render_pipeline[1], &new, sizeof(new)) != sizeof (new)) + Sys_Error("sched_update:read"); + + xil_export(new); + + if (xil_get_memory_storage(new, &storage) == FALSE) + Sys_Error("xil_get_memory_storage"); + + vid.buffer = storage.byte.data; + vid.conbuffer = vid.buffer; + + return (new); +} + +void *update_thread() +{ + XilImage image; + + if (!X11_active) + return; + + while (read(render_pipeline[0], &image, sizeof (image)) == sizeof(image)) { + + xil_import(image, TRUE); // let xil control the image + + if (!display_image) + return; + + if (current_pixel_multiply < 2) + xil_copy(image, display_image); + else + xil_scale(image, display_image, "nearest", + (float)current_pixel_multiply, (float)current_pixel_multiply); + + if (write(render_pipeline[0], &image, sizeof (image)) != sizeof(image)) + Sys_Error("update_thread: write"); + } +} + + +static int dither; + +void VID_DitherOn(void) +{ + if (dither == 0) { + vid.recalc_refdef = 1; + dither = 1; + } +} + +void VID_DitherOff(void) +{ + if (dither) { + vid.recalc_refdef = 1; + dither = 0; + } +} + +void VID_SetDefaultMode( void ) +{ +} + +int I_OpenWindow(void) +{ + return 0; +} + +void I_EraseWindow(int window) +{ + +} + +void I_DrawCircle(int window, int x, int y, int r) +{ +} + +void I_DisplayWindow(int window) +{ +} + +void Sys_SendKeyEvents(void) +{ + // get events from x server + if (x_disp) { + while (XPending(x_disp)) GetEvent(); + while (keyq_head != keyq_tail) { + Key_Event(keyq[keyq_tail].key, keyq[keyq_tail].down); + keyq_tail = (keyq_tail + 1) & 63; + } + } +} + +void IN_Init (void) +{ + Cvar_RegisterVariable (&_windowed_mouse); + Cvar_RegisterVariable (&m_filter); + if ( COM_CheckParm ("-nomouse") ) + return; + mouse_x = mouse_y = 0.0; + mouse_avail = 1; +} + +void IN_Shutdown (void) +{ + mouse_avail = 0; +} + +void IN_Commands (void) +{ + int i; + + if (!mouse_avail) return; + + for (i=0 ; isidemove += m_side.value * mouse_x; + else + cl.viewangles[YAW] -= m_yaw.value * mouse_x; + if (in_mlook.state & 1) + V_StopPitchDrift (); + + if ( (in_mlook.state & 1) && !(in_strafe.state & 1)) { + 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; + } + mouse_x = mouse_y = 0.0; +} + +//void VID_UnlockBuffer(void) { } +//void VID_LockBuffer(void) { } + diff --git a/contrib/other/sdlquake-1.0.9/vid_svgalib.c b/contrib/other/sdlquake-1.0.9/vid_svgalib.c new file mode 100644 index 000000000..e0fea3af0 --- /dev/null +++ b/contrib/other/sdlquake-1.0.9/vid_svgalib.c @@ -0,0 +1,1003 @@ +/* +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 +#include +#include +#include +#include +#include +#include + +#include + +#include "vga.h" +#include "vgakeyboard.h" +#include "vgamouse.h" + +#include "quakedef.h" +#include "d_local.h" + +#define stringify(m) { #m, m } + +unsigned short d_8to16table[256]; +static byte *vid_surfcache; +static int VID_highhunkmark; + +int num_modes; +vga_modeinfo *modes; +int current_mode; + +int num_shades=32; + +struct +{ + char *name; + int num; +} mice[] = +{ + stringify(MOUSE_MICROSOFT), + stringify(MOUSE_MOUSESYSTEMS), + stringify(MOUSE_MMSERIES), + stringify(MOUSE_LOGITECH), + stringify(MOUSE_BUSMOUSE), + stringify(MOUSE_PS2), +}; + +static unsigned char scantokey[128]; +static byte vid_current_palette[768]; + +int num_mice = sizeof (mice) / sizeof(mice[0]); + +int d_con_indirect = 0; + +int svgalib_inited=0; +int UseMouse = 1; +int UseDisplay = 1; +int UseKeyboard = 1; + +int mouserate = MOUSE_DEFAULTSAMPLERATE; + +cvar_t vid_mode = {"vid_mode","5",false}; +cvar_t vid_redrawfull = {"vid_redrawfull","0",false}; +cvar_t vid_waitforrefresh = {"vid_waitforrefresh","0",true}; + +char *framebuffer_ptr; + +cvar_t mouse_button_commands[3] = +{ + {"mouse1","+attack"}, + {"mouse2","+strafe"}, + {"mouse3","+forward"}, +}; + +int mouse_buttons; +int mouse_buttonstate; +int mouse_oldbuttonstate; +float mouse_x, mouse_y; +float old_mouse_x, old_mouse_y; +int mx, my; + +cvar_t m_filter = {"m_filter","0"}; + +static byte backingbuf[48*24]; + +int VGA_width, VGA_height, VGA_rowbytes, VGA_bufferrowbytes, VGA_planar; +byte *VGA_pagebase; + +void VGA_UpdatePlanarScreen (void *srcbuffer); + +void D_BeginDirectRect (int x, int y, byte *pbitmap, int width, int height) +{ + int i, j, k, plane, reps, repshift, offset, vidpage, off; + + if (!svgalib_inited || !vid.direct || !vga_oktowrite()) return; + + if (vid.aspect > 1.5) + { + reps = 2; + repshift = 1; + } else { + reps = 1; + repshift = 0; + } + + vidpage = 0; + vga_setpage(0); + + if (VGA_planar) + { + for (plane=0 ; plane<4 ; plane++) + { + // select the correct plane for reading and writing + outb(0x02, 0x3C4); + outb(1 << plane, 0x3C5); + outb(4, 0x3CE); + outb(plane, 0x3CF); + + for (i=0 ; i<(height << repshift) ; i += reps) + { + for (k=0 ; k> 2) ; j++) + { + backingbuf[(i + k) * 24 + (j << 2) + plane] = + vid.direct[(y + i + k) * VGA_rowbytes + + (x >> 2) + j]; + vid.direct[(y + i + k) * VGA_rowbytes + (x>>2) + j] = + pbitmap[(i >> repshift) * 24 + + (j << 2) + plane]; + } + } + } + } + } else { + for (i=0 ; i<(height << repshift) ; i += reps) + { + for (j=0 ; j> repshift)*width], width); + } + } + } +} + +void D_EndDirectRect (int x, int y, int width, int height) +{ + int i, j, k, plane, reps, repshift, offset, vidpage, off; + + if (!svgalib_inited || !vid.direct || !vga_oktowrite()) return; + + if (vid.aspect > 1.5) + { + reps = 2; + repshift = 1; + } else { + reps = 1; + repshift = 0; + } + + vidpage = 0; + vga_setpage(0); + + if (VGA_planar) + { + for (plane=0 ; plane<4 ; plane++) + { + // select the correct plane for writing + outb(2, 0x3C4); + outb(1 << plane, 0x3C5); + outb(4, 0x3CE); + outb(plane, 0x3CF); + + for (i=0 ; i<(height << repshift) ; i += reps) + { + for (k=0 ; k> 2) ; j++) + { + vid.direct[(y + i + k) * VGA_rowbytes + (x>>2) + j] = + backingbuf[(i + k) * 24 + (j << 2) + plane]; + } + } + } + } + } else { + for (i=0 ; i<(height << repshift) ; i += reps) + { + for (j=0 ; j 255) + inf = 255; + palette[i] = inf; + } + + VID_SetPalette (palette); + + vid.recalc_refdef = 1; // force a surface cache flush + } +} + +void VID_DescribeMode_f (void) +{ + int modenum; + + modenum = Q_atoi (Cmd_Argv(1)); + if ((modenum >= num_modes) || (modenum < 0 ) || !modes[modenum].width) + Con_Printf("Invalid video mode: %d!\n",modenum); + Con_Printf("%d: %d x %d - ",modenum,modes[modenum].width,modes[modenum].height); + if (modes[modenum].bytesperpixel == 0) + Con_Printf("ModeX\n"); + else + Con_Printf("%d bpp\n", modes[modenum].bytesperpixel<<3); +} + +void VID_DescribeModes_f (void) +{ + int i; + + for (i=0;i> 2; + + if (UseDisplay && vga_oktowrite()) + vga_setpalvec(0, 256, tmppal); + + } +} + +int VID_SetMode (int modenum, unsigned char *palette) +{ + int bsize, zsize, tsize; + + if ((modenum >= num_modes) || (modenum < 0) || !modes[modenum].width) + { + Cvar_SetValue ("vid_mode", (float)current_mode); + + Con_Printf("No such video mode: %d\n",modenum); + + return 0; + } + + Cvar_SetValue ("vid_mode", (float)modenum); + + current_mode=modenum; + + vid.width = modes[current_mode].width; + vid.height = modes[current_mode].height; + + VGA_width = modes[current_mode].width; + VGA_height = modes[current_mode].height; + VGA_planar = modes[current_mode].bytesperpixel == 0; + VGA_rowbytes = modes[current_mode].linewidth; + vid.rowbytes = modes[current_mode].linewidth; + if (VGA_planar) { + VGA_bufferrowbytes = modes[current_mode].linewidth * 4; + vid.rowbytes = modes[current_mode].linewidth*4; + } + + vid.aspect = ((float)vid.height / (float)vid.width) * (320.0 / 240.0); + vid.colormap = (pixel_t *) host_colormap; + vid.fullbright = 256 - LittleLong (*((int *)vid.colormap + 2048)); + vid.conrowbytes = vid.rowbytes; + vid.conwidth = vid.width; + vid.conheight = vid.height; + vid.numpages = 1; + + vid.maxwarpwidth = WARP_WIDTH; + vid.maxwarpheight = WARP_HEIGHT; + + // alloc zbuffer and surface cache + if (d_pzbuffer) { + D_FlushCaches(); + Hunk_FreeToHighMark (VID_highhunkmark); + d_pzbuffer = NULL; + vid_surfcache = NULL; + } + + bsize = vid.rowbytes * vid.height; + tsize = D_SurfaceCacheForRes (vid.width, vid.height); + zsize = vid.width * vid.height * sizeof(*d_pzbuffer); + + VID_highhunkmark = Hunk_HighMark (); + + d_pzbuffer = Hunk_HighAllocName (bsize+tsize+zsize, "video"); + + vid_surfcache = ((byte *)d_pzbuffer) + zsize; + + vid.conbuffer = vid.buffer = (pixel_t *)(((byte *)d_pzbuffer) + zsize + tsize); + + D_InitCaches (vid_surfcache, tsize); + +// get goin' + + vga_setmode(current_mode); + VID_SetPalette(palette); + + VGA_pagebase = vid.direct = framebuffer_ptr = (char *) vga_getgraphmem(); +// if (vga_setlinearaddressing()>0) +// framebuffer_ptr = (char *) vga_getgraphmem(); + if (!framebuffer_ptr) + Sys_Error("This mode isn't hapnin'\n"); + + vga_setpage(0); + + svgalib_inited=1; + + vid.recalc_refdef = 1; // force a surface cache flush + + return 0; +} + +void VID_Init(unsigned char *palette) +{ + + int i; + int w, h, d; + + if (svgalib_inited) + return; + +// Cmd_AddCommand ("gamma", VID_Gamma_f); + + if (UseDisplay) + { + vga_init(); + + VID_InitModes(); + + Cvar_RegisterVariable (&vid_mode); + Cvar_RegisterVariable (&vid_redrawfull); + Cvar_RegisterVariable (&vid_waitforrefresh); + + Cmd_AddCommand("vid_nummodes", VID_NumModes_f); + Cmd_AddCommand("vid_describemode", VID_DescribeMode_f); + Cmd_AddCommand("vid_describemodes", VID_DescribeModes_f); + Cmd_AddCommand("vid_debug", VID_Debug_f); + + // interpret command-line params + + w = h = d = 0; + if (getenv("GSVGAMODE")) + current_mode = get_mode(getenv("GSVGAMODE"), w, h, d); + else if (COM_CheckParm("-mode")) + current_mode = get_mode(com_argv[COM_CheckParm("-mode")+1], w, h, d); + else if (COM_CheckParm("-w") || COM_CheckParm("-h") + || COM_CheckParm("-d")) + { + if (COM_CheckParm("-w")) + w = Q_atoi(com_argv[COM_CheckParm("-w")+1]); + if (COM_CheckParm("-h")) + h = Q_atoi(com_argv[COM_CheckParm("-h")+1]); + if (COM_CheckParm("-d")) + d = Q_atoi(com_argv[COM_CheckParm("-d")+1]); + current_mode = get_mode(0, w, h, d); + } + else + current_mode = G320x200x256; + + // set vid parameters + VID_SetMode(current_mode, palette); + + VID_SetPalette(palette); + + // we do want to run in the background when switched away + vga_runinbackground(1); + } + + if (COM_CheckParm("-nokbd")) UseKeyboard = 0; + + if (UseKeyboard) + { + for (i=0 ; i<128 ; i++) + scantokey[i] = ' '; + + scantokey[42] = K_SHIFT; + scantokey[54] = K_SHIFT; + scantokey[72] = K_UPARROW; + scantokey[103] = K_UPARROW; + scantokey[80] = K_DOWNARROW; + scantokey[108] = K_DOWNARROW; + scantokey[75] = K_LEFTARROW; + scantokey[105] = K_LEFTARROW; + scantokey[77] = K_RIGHTARROW; + scantokey[106] = K_RIGHTARROW; + scantokey[29] = K_CTRL; + scantokey[97] = K_CTRL; + scantokey[56] = K_ALT; + scantokey[100] = K_ALT; +// scantokey[58] = JK_CAPS; +// scantokey[69] = JK_NUM_LOCK; + scantokey[71] = K_HOME; + scantokey[73] = K_PGUP; + scantokey[79] = K_END; + scantokey[81] = K_PGDN; + scantokey[82] = K_INS; + scantokey[83] = K_DEL; + scantokey[1 ] = K_ESCAPE; + scantokey[28] = K_ENTER; + scantokey[15] = K_TAB; + scantokey[14] = K_BACKSPACE; + scantokey[119] = K_PAUSE; + scantokey[57] = ' '; + + scantokey[102] = K_HOME; + scantokey[104] = K_PGUP; + scantokey[107] = K_END; + scantokey[109] = K_PGDN; + scantokey[110] = K_INS; + scantokey[111] = K_DEL; + + scantokey[2] = '1'; + scantokey[3] = '2'; + scantokey[4] = '3'; + scantokey[5] = '4'; + scantokey[6] = '5'; + scantokey[7] = '6'; + scantokey[8] = '7'; + scantokey[9] = '8'; + scantokey[10] = '9'; + scantokey[11] = '0'; + scantokey[12] = '-'; + scantokey[13] = '='; + scantokey[41] = '`'; + scantokey[26] = '['; + scantokey[27] = ']'; + scantokey[39] = ';'; + scantokey[40] = '\''; + scantokey[51] = ','; + scantokey[52] = '.'; + scantokey[53] = '/'; + scantokey[43] = '\\'; + + scantokey[59] = K_F1; + scantokey[60] = K_F2; + scantokey[61] = K_F3; + scantokey[62] = K_F4; + scantokey[63] = K_F5; + scantokey[64] = K_F6; + scantokey[65] = K_F7; + scantokey[66] = K_F8; + scantokey[67] = K_F9; + scantokey[68] = K_F10; + scantokey[87] = K_F11; + scantokey[88] = K_F12; + scantokey[30] = 'a'; + scantokey[48] = 'b'; + scantokey[46] = 'c'; + scantokey[32] = 'd'; + scantokey[18] = 'e'; + scantokey[33] = 'f'; + scantokey[34] = 'g'; + scantokey[35] = 'h'; + scantokey[23] = 'i'; + scantokey[36] = 'j'; + scantokey[37] = 'k'; + scantokey[38] = 'l'; + scantokey[50] = 'm'; + scantokey[49] = 'n'; + scantokey[24] = 'o'; + scantokey[25] = 'p'; + scantokey[16] = 'q'; + scantokey[19] = 'r'; + scantokey[31] = 's'; + scantokey[20] = 't'; + scantokey[22] = 'u'; + scantokey[47] = 'v'; + scantokey[17] = 'w'; + scantokey[45] = 'x'; + scantokey[21] = 'y'; + scantokey[44] = 'z'; + + if (keyboard_init()) + Sys_Error("keyboard_init() failed"); + keyboard_seteventhandler(keyhandler); + } + +} + +void VID_Update(vrect_t *rects) +{ + if (!svgalib_inited) + return; + + if (!vga_oktowrite()) + return; // can't update screen if it's not active + + if (vid_waitforrefresh.value) + vga_waitretrace(); + + if (VGA_planar) + VGA_UpdatePlanarScreen (vid.buffer); + + else if (vid_redrawfull.value) { + int total = vid.rowbytes * vid.height; + int offset; + + for (offset=0;offset0x10000)?0x10000:(total-offset))); + } + } else { + int ycount; + int offset; + int vidpage=0; + + vga_setpage(0); + + while (rects) + { + ycount = rects->height; + offset = rects->y * vid.rowbytes + rects->x; + while (ycount--) + { + register int i = offset % 0x10000; + + if ((offset / 0x10000) != vidpage) { + vidpage=offset / 0x10000; + vga_setpage(vidpage); + } + if (rects->width + i > 0x10000) { + memcpy(framebuffer_ptr + i, + vid.buffer + offset, + 0x10000 - i); + vga_setpage(++vidpage); + memcpy(framebuffer_ptr, + vid.buffer + offset + 0x10000 - i, + rects->width - 0x10000 + i); + } else + memcpy(framebuffer_ptr + i, + vid.buffer + offset, + rects->width); + offset += vid.rowbytes; + } + + rects = rects->pnext; + } + } + + if (vid_mode.value != current_mode) + VID_SetMode ((int)vid_mode.value, vid_current_palette); +} + +static int dither; + +void VID_DitherOn(void) +{ + if (dither == 0) + { +// R_ViewChanged (&vrect, sb_lines, vid.aspect); + dither = 1; + } +} + +void VID_DitherOff(void) +{ + if (dither) + { +// R_ViewChanged (&vrect, sb_lines, vid.aspect); + dither = 0; + } +} + +void Sys_SendKeyEvents(void) +{ + if (!svgalib_inited) + return; + + if (UseKeyboard) + while (keyboard_update()); +} + +void Force_CenterView_f (void) +{ + cl.viewangles[PITCH] = 0; +} + + +void mousehandler(int buttonstate, int dx, int dy) +{ + mouse_buttonstate = buttonstate; + mx += dx; + my += dy; +} + +void IN_Init(void) +{ + + int mtype; + char *mousedev; + int mouserate; + + if (UseMouse) + { + + Cvar_RegisterVariable (&mouse_button_commands[0]); + Cvar_RegisterVariable (&mouse_button_commands[1]); + Cvar_RegisterVariable (&mouse_button_commands[2]); + Cvar_RegisterVariable (&m_filter); + Cmd_AddCommand ("force_centerview", Force_CenterView_f); + + mouse_buttons = 3; + + mtype = vga_getmousetype(); + + mousedev = "/dev/mouse"; + if (getenv("MOUSEDEV")) mousedev = getenv("MOUSEDEV"); + if (COM_CheckParm("-mdev")) + mousedev = com_argv[COM_CheckParm("-mdev")+1]; + + mouserate = 1200; + if (getenv("MOUSERATE")) mouserate = atoi(getenv("MOUSERATE")); + if (COM_CheckParm("-mrate")) + mouserate = atoi(com_argv[COM_CheckParm("-mrate")+1]); + +// printf("Mouse: dev=%s,type=%s,speed=%d\n", +// mousedev, mice[mtype].name, mouserate); + if (mouse_init(mousedev, mtype, mouserate)) + { + Con_Printf("No mouse found\n"); + UseMouse = 0; + } + else + mouse_seteventhandler(mousehandler); + + } + +} + +void IN_Shutdown(void) +{ + if (UseMouse) + mouse_close(); +} + +/* +=========== +IN_Commands +=========== +*/ +void IN_Commands (void) +{ + if (UseMouse && cls.state != ca_dedicated) + { + // poll mouse values + while (mouse_update()) + ; + + // perform button actions + if ((mouse_buttonstate & MOUSE_LEFTBUTTON) && + !(mouse_oldbuttonstate & MOUSE_LEFTBUTTON)) + Key_Event (K_MOUSE1, true); + else if (!(mouse_buttonstate & MOUSE_LEFTBUTTON) && + (mouse_oldbuttonstate & MOUSE_LEFTBUTTON)) + Key_Event (K_MOUSE1, false); + + if ((mouse_buttonstate & MOUSE_RIGHTBUTTON) && + !(mouse_oldbuttonstate & MOUSE_RIGHTBUTTON)) + Key_Event (K_MOUSE2, true); + else if (!(mouse_buttonstate & MOUSE_RIGHTBUTTON) && + (mouse_oldbuttonstate & MOUSE_RIGHTBUTTON)) + Key_Event (K_MOUSE2, false); + + if ((mouse_buttonstate & MOUSE_MIDDLEBUTTON) && + !(mouse_oldbuttonstate & MOUSE_MIDDLEBUTTON)) + Key_Event (K_MOUSE3, true); + else if (!(mouse_buttonstate & MOUSE_MIDDLEBUTTON) && + (mouse_oldbuttonstate & MOUSE_MIDDLEBUTTON)) + Key_Event (K_MOUSE3, false); + + mouse_oldbuttonstate = mouse_buttonstate; + } +} + +/* +=========== +IN_Move +=========== +*/ +void IN_MouseMove (usercmd_t *cmd) +{ + if (!UseMouse) + return; + + // poll mouse values + while (mouse_update()) + ; + + if (m_filter.value) + { + mouse_x = (mx + old_mouse_x) * 0.5; + mouse_y = (my + old_mouse_y) * 0.5; + } + else + { + mouse_x = mx; + mouse_y = my; + } + old_mouse_x = mx; + old_mouse_y = my; + mx = my = 0; // clear for next update + + mouse_x *= sensitivity.value; + mouse_y *= sensitivity.value; + +// add mouse X/Y movement to cmd + if ( (in_strafe.state & 1) || (lookstrafe.value && (in_mlook.state & 1) )) + cmd->sidemove += m_side.value * mouse_x; + else + cl.viewangles[YAW] -= m_yaw.value * mouse_x; + + if (in_mlook.state & 1) + V_StopPitchDrift (); + + if ( (in_mlook.state & 1) && !(in_strafe.state & 1)) + { + 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; + } +} + +void IN_Move (usercmd_t *cmd) +{ + IN_MouseMove(cmd); +} + + +/* +================ +VID_ModeInfo +================ +*/ +char *VID_ModeInfo (int modenum) +{ + static char *badmodestr = "Bad mode number"; + static char modestr[40]; + + if (modenum == 0) + { + sprintf (modestr, "%d x %d, %d bpp", + vid.width, vid.height, modes[current_mode].bytesperpixel*8); + return (modestr); + } + else + { + return (badmodestr); + } +} + diff --git a/contrib/other/sdlquake-1.0.9/vid_vga.c b/contrib/other/sdlquake-1.0.9/vid_vga.c new file mode 100644 index 000000000..6fbec9de5 --- /dev/null +++ b/contrib/other/sdlquake-1.0.9/vid_vga.c @@ -0,0 +1,478 @@ +/* +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_vga.c: VGA-specific DOS video stuff +// + +// TODO: proper handling of page-swap failure + +#include + +#include "quakedef.h" +#include "d_local.h" +#include "dosisms.h" +#include "vid_dos.h" +#include + +extern regs_t regs; + +int VGA_width, VGA_height, VGA_rowbytes, VGA_bufferrowbytes; +byte *VGA_pagebase; +vmode_t *VGA_pcurmode; + +static int VGA_planar; +static int VGA_numpages; +static int VGA_buffersize; + +void *vid_surfcache; +int vid_surfcachesize; + +int VGA_highhunkmark; + +#include "vgamodes.h" + +#define NUMVIDMODES (sizeof(vgavidmodes) / sizeof(vgavidmodes[0])) + +void VGA_UpdatePlanarScreen (void *srcbuffer); + +static byte backingbuf[48*24]; + +/* +================ +VGA_BeginDirectRect +================ +*/ +void VGA_BeginDirectRect (viddef_t *lvid, struct vmode_s *pcurrentmode, int x, + int y, byte *pbitmap, int width, int height) +{ + int i, j, k, plane, reps, repshift; + + if (!lvid->direct) + return; + + if (lvid->aspect > 1.5) + { + reps = 2; + repshift = 1; + } + else + { + reps = 1; + repshift = 0; + } + + if (pcurrentmode->planar) + { + for (plane=0 ; plane<4 ; plane++) + { + // select the correct plane for reading and writing + outportb (SC_INDEX, MAP_MASK); + outportb (SC_DATA, 1 << plane); + outportb (GC_INDEX, READ_MAP); + outportb (GC_DATA, plane); + + for (i=0 ; i<(height << repshift) ; i += reps) + { + for (k=0 ; k> 2) ; j++) + { + backingbuf[(i + k) * 24 + (j << 2) + plane] = + lvid->direct[(y + i + k) * VGA_rowbytes + + (x >> 2) + j]; + lvid->direct[(y + i + k) * VGA_rowbytes + (x>>2) + j] = + pbitmap[(i >> repshift) * 24 + + (j << 2) + plane]; + } + } + } + } + } + else + { + for (i=0 ; i<(height << repshift) ; i += reps) + { + for (j=0 ; jdirect + x + ((y << repshift) + i + j) * + VGA_rowbytes, + width); + memcpy (lvid->direct + x + ((y << repshift) + i + j) * + VGA_rowbytes, + &pbitmap[(i >> repshift) * width], + width); + } + } + } +} + + +/* +================ +VGA_EndDirectRect +================ +*/ +void VGA_EndDirectRect (viddef_t *lvid, struct vmode_s *pcurrentmode, int x, + int y, int width, int height) +{ + int i, j, k, plane, reps, repshift; + + if (!lvid->direct) + return; + + if (lvid->aspect > 1.5) + { + reps = 2; + repshift = 1; + } + else + { + reps = 1; + repshift = 0; + } + + if (pcurrentmode->planar) + { + for (plane=0 ; plane<4 ; plane++) + { + // select the correct plane for writing + outportb (SC_INDEX, MAP_MASK); + outportb (SC_DATA, 1 << plane); + + for (i=0 ; i<(height << repshift) ; i += reps) + { + for (k=0 ; k> 2) ; j++) + { + lvid->direct[(y + i + k) * VGA_rowbytes + (x>>2) + j] = + backingbuf[(i + k) * 24 + (j << 2) + plane]; + } + } + } + } + } + else + { + for (i=0 ; i<(height << repshift) ; i += reps) + { + for (j=0 ; jdirect + x + ((y << repshift) + i + j) * + VGA_rowbytes, + &backingbuf[(i + j) * 24], + width); + } + } + } +} + + +/* +================ +VGA_Init +================ +*/ +void VGA_Init (void) +{ + int i; + +// link together all the VGA modes + for (i=0 ; i<(NUMVIDMODES - 1) ; i++) + { + vgavidmodes[i].pnext = &vgavidmodes[i+1]; + } + +// add the VGA modes at the start of the mode list + vgavidmodes[NUMVIDMODES-1].pnext = pvidmodes; + pvidmodes = &vgavidmodes[0]; + + numvidmodes += NUMVIDMODES; +} + + +/* +================ +VGA_WaitVsync +================ +*/ +void VGA_WaitVsync (void) +{ + while ((inportb (0x3DA) & 0x08) == 0) + ; +} + + +/* +================ +VGA_ClearVideoMem +================ +*/ +void VGA_ClearVideoMem (int planar) +{ + + if (planar) + { + // enable all planes for writing + outportb (SC_INDEX, MAP_MASK); + outportb (SC_DATA, 0x0F); + } + + Q_memset (VGA_pagebase, 0, VGA_rowbytes * VGA_height); +} + +/* +================ +VGA_FreeAndAllocVidbuffer +================ +*/ +qboolean VGA_FreeAndAllocVidbuffer (viddef_t *lvid, int allocnewbuffer) +{ + int tsize, tbuffersize; + + if (allocnewbuffer) + { + // alloc an extra line in case we want to wrap, and allocate the z-buffer + tbuffersize = (lvid->rowbytes * (lvid->height + 1)) + + (lvid->width * lvid->height * sizeof (*d_pzbuffer)); + } + else + { + // just allocate the z-buffer + tbuffersize = lvid->width * lvid->height * sizeof (*d_pzbuffer); + } + + tsize = D_SurfaceCacheForRes (lvid->width, lvid->height); + + tbuffersize += tsize; + +// see if there's enough memory, allowing for the normal mode 0x13 pixel, +// z, and surface buffers + if ((host_parms.memsize - tbuffersize + SURFCACHE_SIZE_AT_320X200 + + 0x10000 * 3) < minimum_memory) + { + Con_Printf ("Not enough memory for video mode\n"); + VGA_pcurmode = NULL; // so no further accesses to the buffer are + // attempted, particularly when clearing + return false; // not enough memory for mode + } + + VGA_buffersize = tbuffersize; + vid_surfcachesize = tsize; + + if (d_pzbuffer) + { + D_FlushCaches (); + Hunk_FreeToHighMark (VGA_highhunkmark); + d_pzbuffer = NULL; + } + + VGA_highhunkmark = Hunk_HighMark (); + + d_pzbuffer = Hunk_HighAllocName (VGA_buffersize, "video"); + + vid_surfcache = (byte *)d_pzbuffer + + lvid->width * lvid->height * sizeof (*d_pzbuffer); + + if (allocnewbuffer) + { + lvid->buffer = (void *)( (byte *)vid_surfcache + vid_surfcachesize); + lvid->conbuffer = lvid->buffer; + } + + return true; +} + + +/* +================ +VGA_CheckAdequateMem +================ +*/ +qboolean VGA_CheckAdequateMem (int width, int height, int rowbytes, + int allocnewbuffer) +{ + int tbuffersize; + + tbuffersize = width * height * sizeof (*d_pzbuffer); + + if (allocnewbuffer) + { + // alloc an extra line in case we want to wrap, and allocate the z-buffer + tbuffersize += (rowbytes * (height + 1)); + } + + tbuffersize += D_SurfaceCacheForRes (width, height); + +// see if there's enough memory, allowing for the normal mode 0x13 pixel, +// z, and surface buffers + if ((host_parms.memsize - tbuffersize + SURFCACHE_SIZE_AT_320X200 + + 0x10000 * 3) < minimum_memory) + { + return false; // not enough memory for mode + } + + return true; +} + + +/* +================ +VGA_InitMode +================ +*/ +int VGA_InitMode (viddef_t *lvid, vmode_t *pcurrentmode) +{ + vextra_t *pextra; + + pextra = pcurrentmode->pextradata; + + if (!VGA_FreeAndAllocVidbuffer (lvid, pextra->vidbuffer)) + return -1; // memory alloc failed + + if (VGA_pcurmode) + VGA_ClearVideoMem (VGA_pcurmode->planar); + +// mode 0x13 is the base for all the Mode X-class mode sets + regs.h.ah = 0; + regs.h.al = 0x13; + dos_int86(0x10); + + VGA_pagebase = (void *)real2ptr(0xa0000); + lvid->direct = (pixel_t *)VGA_pagebase; + +// set additional registers as needed + VideoRegisterSet (pextra->pregset); + + VGA_numpages = 1; + lvid->numpages = VGA_numpages; + + VGA_width = (lvid->width + 0x1F) & ~0x1F; + VGA_height = lvid->height; + VGA_planar = pcurrentmode->planar; + if (VGA_planar) + VGA_rowbytes = lvid->rowbytes / 4; + else + VGA_rowbytes = lvid->rowbytes; + VGA_bufferrowbytes = lvid->rowbytes; + lvid->colormap = host_colormap; + lvid->fullbright = 256 - LittleLong (*((int *)lvid->colormap + 2048)); + + lvid->maxwarpwidth = WARP_WIDTH; + lvid->maxwarpheight = WARP_HEIGHT; + + lvid->conbuffer = lvid->buffer; + lvid->conrowbytes = lvid->rowbytes; + lvid->conwidth = lvid->width; + lvid->conheight = lvid->height; + + VGA_pcurmode = pcurrentmode; + + VGA_ClearVideoMem (pcurrentmode->planar); + + if (_vid_wait_override.value) + { + Cvar_SetValue ("vid_wait", (float)VID_WAIT_VSYNC); + } + else + { + Cvar_SetValue ("vid_wait", (float)VID_WAIT_NONE); + } + + D_InitCaches (vid_surfcache, vid_surfcachesize); + + return 1; +} + + +/* +================ +VGA_SetPalette +================ +*/ +void VGA_SetPalette(viddef_t *lvid, vmode_t *pcurrentmode, unsigned char *pal) +{ + int shiftcomponents=2; + int i; + + UNUSED(lvid); + UNUSED(pcurrentmode); + + dos_outportb(0x3c8, 0); + for (i=0 ; i<768 ; i++) + outportb(0x3c9, pal[i]>>shiftcomponents); +} + + +/* +================ +VGA_SwapBuffersCopy +================ +*/ +void VGA_SwapBuffersCopy (viddef_t *lvid, vmode_t *pcurrentmode, + vrect_t *rects) +{ + + UNUSED(pcurrentmode); + +// TODO: can write a dword at a time +// TODO: put in ASM +// TODO: copy only specified rectangles + if (VGA_planar) + { + + // TODO: copy only specified rectangles + + VGA_UpdatePlanarScreen (lvid->buffer); + } + else + { + while (rects) + { + VGA_UpdateLinearScreen ( + lvid->buffer + rects->x + (rects->y * lvid->rowbytes), + VGA_pagebase + rects->x + (rects->y * VGA_rowbytes), + rects->width, + rects->height, + lvid->rowbytes, + VGA_rowbytes); + + rects = rects->pnext; + } + } +} + + +/* +================ +VGA_SwapBuffers +================ +*/ +void VGA_SwapBuffers (viddef_t *lvid, vmode_t *pcurrentmode, vrect_t *rects) +{ + UNUSED(lvid); + + if (vid_wait.value == VID_WAIT_VSYNC) + VGA_WaitVsync (); + + VGA_SwapBuffersCopy (lvid, pcurrentmode, rects); +} + diff --git a/contrib/other/sdlquake-1.0.9/vid_win.c b/contrib/other/sdlquake-1.0.9/vid_win.c new file mode 100644 index 000000000..db90689c6 --- /dev/null +++ b/contrib/other/sdlquake-1.0.9/vid_win.c @@ -0,0 +1,3343 @@ +/* +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_win.c -- Win32 video driver + +#include "quakedef.h" +#include "winquake.h" +#include "d_local.h" +#include "resource.h" + +#define MAX_MODE_LIST 30 +#define VID_ROW_SIZE 3 + +qboolean dibonly; + +extern int Minimized; + +HWND mainwindow; + +HWND WINAPI InitializeWindow (HINSTANCE hInstance, int nCmdShow); + +int DIBWidth, DIBHeight; +qboolean DDActive; +RECT WindowRect; +DWORD WindowStyle, ExWindowStyle; + +int window_center_x, window_center_y, window_x, window_y, window_width, window_height; +RECT window_rect; + +static DEVMODE gdevmode; +static qboolean startwindowed = 0, windowed_mode_set; +static int firstupdate = 1; +static qboolean vid_initialized = false, vid_palettized; +static int lockcount; +static int vid_fulldib_on_focus_mode; +static qboolean force_minimized, in_mode_set, is_mode0x13, force_mode_set; +static int vid_stretched, windowed_mouse; +static qboolean palette_changed, syscolchg, vid_mode_set, hide_window, pal_is_nostatic; +static HICON hIcon; + +viddef_t vid; // global video state + +#define MODE_WINDOWED 0 +#define MODE_SETTABLE_WINDOW 2 +#define NO_MODE (MODE_WINDOWED - 1) +#define MODE_FULLSCREEN_DEFAULT (MODE_WINDOWED + 3) + +// Note that 0 is MODE_WINDOWED +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","0", true}; +cvar_t vid_fullscreen_mode = {"vid_fullscreen_mode","3", true}; +cvar_t vid_windowed_mode = {"vid_windowed_mode","0", true}; +cvar_t block_switch = {"block_switch","0", true}; +cvar_t vid_window_x = {"vid_window_x", "0", true}; +cvar_t vid_window_y = {"vid_window_y", "0", true}; + +typedef struct { + int width; + int height; +} lmode_t; + +lmode_t lowresmodes[] = { + {320, 200}, + {320, 240}, + {400, 300}, + {512, 384}, +}; + +int vid_modenum = NO_MODE; +int vid_testingmode, vid_realmode; +double vid_testendtime; +int vid_default = MODE_WINDOWED; +static int windowed_default; + +modestate_t modestate = MS_UNINIT; + +static byte *vid_surfcache; +static int vid_surfcachesize; +static int VID_highhunkmark; + +unsigned char vid_curpal[256*3]; + +unsigned short d_8to16table[256]; +unsigned d_8to24table[256]; + +int driver = grDETECT,mode; +bool useWinDirect = true, useDirectDraw = true; +MGLDC *mgldc = NULL,*memdc = NULL,*dibdc = NULL,*windc = NULL; + +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; + +static vmode_t modelist[MAX_MODE_LIST]; +static int nummodes; +static vmode_t *pcurrentmode; + +int aPage; // Current active display page +int vPage; // Current visible display page +int waitVRT = true; // True to wait for retrace on flip + +static vmode_t badmode; + +static byte backingbuf[48*24]; + +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); + + +/* +================ +VID_RememberWindowPos +================ +*/ +void VID_RememberWindowPos (void) +{ + RECT rect; + + if (GetWindowRect (mainwindow, &rect)) + { + if ((rect.left < GetSystemMetrics (SM_CXSCREEN)) && + (rect.top < GetSystemMetrics (SM_CYSCREEN)) && + (rect.right > 0) && + (rect.bottom > 0)) + { + Cvar_SetValue ("vid_window_x", (float)rect.left); + Cvar_SetValue ("vid_window_y", (float)rect.top); + } + } +} + + +/* +================ +VID_CheckWindowXY +================ +*/ +void VID_CheckWindowXY (void) +{ + + if (((int)vid_window_x.value > (GetSystemMetrics (SM_CXSCREEN) - 160)) || + ((int)vid_window_y.value > (GetSystemMetrics (SM_CYSCREEN) - 120)) || + ((int)vid_window_x.value < 0) || + ((int)vid_window_y.value < 0)) + { + Cvar_SetValue ("vid_window_x", 0.0); + Cvar_SetValue ("vid_window_y", 0.0 ); + } +} + + +/* +================ +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 (); +} + + +/* +================ +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 (); +} + + +/* +================ +VID_CheckAdequateMem +================ +*/ +qboolean VID_CheckAdequateMem (int width, int height) +{ + int tbuffersize; + + tbuffersize = width * height * sizeof (*d_pzbuffer); + + tbuffersize += D_SurfaceCacheForRes (width, height); + +// see if there's enough memory, allowing for the normal mode 0x13 pixel, +// z, and surface buffers + if ((host_parms.memsize - tbuffersize + SURFCACHE_SIZE_AT_320X200 + + 0x10000 * 3) < minimum_memory) + { + return false; // not enough memory for mode + } + + return true; +} + + +/* +================ +VID_AllocBuffers +================ +*/ +qboolean VID_AllocBuffers (int width, int height) +{ + int tsize, tbuffersize; + + tbuffersize = width * height * sizeof (*d_pzbuffer); + + tsize = D_SurfaceCacheForRes (width, height); + + tbuffersize += tsize; + +// see if there's enough memory, allowing for the normal mode 0x13 pixel, +// z, and surface buffers + if ((host_parms.memsize - tbuffersize + SURFCACHE_SIZE_AT_320X200 + + 0x10000 * 3) < minimum_memory) + { + Con_SafePrintf ("Not enough memory for video mode\n"); + return false; // not enough memory for mode + } + + vid_surfcachesize = tsize; + + if (d_pzbuffer) + { + D_FlushCaches (); + Hunk_FreeToHighMark (VID_highhunkmark); + d_pzbuffer = NULL; + } + + VID_highhunkmark = Hunk_HighMark (); + + d_pzbuffer = Hunk_HighAllocName (tbuffersize, "video"); + + vid_surfcache = (byte *)d_pzbuffer + + width * height * sizeof (*d_pzbuffer); + + return true; +} + + +void initFatalError(void) +{ + MGL_exit(); + MGL_fatalError(MGL_errorMsg(MGL_result())); + exit(EXIT_FAILURE); +} + + +int VID_Suspend (MGLDC *dc,m_int flags) +{ + + if (flags & MGL_DEACTIVATE) + { + // FIXME: this doesn't currently work on NT + if (block_switch.value && !WinNT) + { + return MGL_NO_DEACTIVATE; + } + + S_BlockSound (); + S_ClearBuffer (); + + IN_RestoreOriginalMouseState (); + CDAudio_Pause (); + + // keep WM_PAINT from trying to redraw + in_mode_set = true; + + block_drawing = true; // so we don't try to draw while switched away + + return MGL_NO_SUSPEND_APP; + } + else if (flags & MGL_REACTIVATE) + { + IN_SetQuakeMouseState (); + // fix the leftover Alt from any Alt-Tab or the like that switched us away + ClearAllStates (); + CDAudio_Resume (); + S_UnblockSound (); + + in_mode_set = false; + + vid.recalc_refdef = 1; + + block_drawing = false; + + return MGL_NO_SUSPEND_APP; + } + +} + + +void registerAllDispDrivers(void) +{ + /* Event though these driver require WinDirect, we register + * them so that they will still be available even if DirectDraw + * is present and the user has disable the high performance + * WinDirect modes. + */ + MGL_registerDriver(MGL_VGA8NAME,VGA8_driver); +// MGL_registerDriver(MGL_VGAXNAME,VGAX_driver); + + /* Register display drivers */ + if (useWinDirect) + { +//we don't want VESA 1.X drivers MGL_registerDriver(MGL_SVGA8NAME,SVGA8_driver); + MGL_registerDriver(MGL_LINEAR8NAME,LINEAR8_driver); + + if (!COM_CheckParm ("-novbeaf")) + MGL_registerDriver(MGL_ACCEL8NAME,ACCEL8_driver); + } + + if (useDirectDraw) + { + MGL_registerDriver(MGL_DDRAW8NAME,DDRAW8_driver); + } +} + + +void registerAllMemDrivers(void) +{ + /* Register memory context drivers */ + MGL_registerDriver(MGL_PACKED8NAME,PACKED8_driver); +} + + +void VID_InitMGLFull (HINSTANCE hInstance) +{ + int i, xRes, yRes, bits, vMode, lowres, curmode, temp; + int lowstretchedres, stretchedmode, lowstretched; + uchar *m; + +// FIXME: NT is checked for because MGL currently has a bug that causes it +// to try to use WinDirect modes even on NT + if (COM_CheckParm("-nowindirect") || + COM_CheckParm("-nowd") || + COM_CheckParm("-novesa") || + WinNT) + { + useWinDirect = false; + } + + if (COM_CheckParm("-nodirectdraw") || COM_CheckParm("-noddraw") || COM_CheckParm("-nodd")) + useDirectDraw = false; + + // Initialise the MGL + MGL_unregisterAllDrivers(); + registerAllDispDrivers(); + registerAllMemDrivers(); + MGL_detectGraph(&driver,&mode); + m = MGL_availableModes(); + + if (m[0] != 0xFF) + { + lowres = lowstretchedres = 99999; + lowstretched = 0; + curmode = 0; + + // find the lowest-res mode, or a mode we can stretch up to and get + // lowest-res that way + for (i = 0; m[i] != 0xFF; i++) + { + MGL_modeResolution(m[i], &xRes, &yRes,&bits); + + if ((bits == 8) && + (xRes <= MAXWIDTH) && + (yRes <= MAXHEIGHT) && + (curmode < MAX_MODE_LIST)) + { + if (m[i] == grVGA_320x200x256) + is_mode0x13 = true; + + if (!COM_CheckParm("-noforcevga")) + { + if (m[i] == grVGA_320x200x256) + { + mode = i; + break; + } + } + + if (xRes < lowres) + { + lowres = xRes; + mode = i; + } + + if ((xRes < lowstretchedres) && ((xRes >> 1) >= 320)) + { + lowstretchedres = xRes >> 1; + stretchedmode = i; + } + } + + curmode++; + } + + // if there's a mode we can stretch by 2 up to, thereby effectively getting + // a lower-res mode than the lowest-res real but still at least 320x200, that + // will be our default mode + if (lowstretchedres < lowres) + { + mode = stretchedmode; + lowres = lowstretchedres; + lowstretched = 1; + } + + // build the mode list, leaving room for the low-res stretched mode, if any + nummodes++; // leave room for default mode + + for (i = 0; m[i] != 0xFF; i++) + { + MGL_modeResolution(m[i], &xRes, &yRes,&bits); + + if ((bits == 8) && + (xRes <= MAXWIDTH) && + (yRes <= MAXHEIGHT) && + (nummodes < MAX_MODE_LIST)) + { + if (i == mode) + { + if (lowstretched) + { + stretchedmode = nummodes; + curmode = nummodes++; + } + else + { + curmode = MODE_FULLSCREEN_DEFAULT; + } + } + else + { + curmode = nummodes++; + } + + modelist[curmode].type = MS_FULLSCREEN; + modelist[curmode].width = xRes; + modelist[curmode].height = yRes; + sprintf (modelist[curmode].modedesc, "%dx%d", xRes, yRes); + + if (m[i] == grVGA_320x200x256) + modelist[curmode].mode13 = 1; + else + modelist[curmode].mode13 = 0; + + modelist[curmode].modenum = m[i]; + modelist[curmode].stretched = 0; + modelist[curmode].dib = 0; + modelist[curmode].fullscreen = 1; + modelist[curmode].halfscreen = 0; + modelist[curmode].bpp = 8; + } + } + + if (lowstretched) + { + modelist[MODE_FULLSCREEN_DEFAULT] = modelist[stretchedmode]; + modelist[MODE_FULLSCREEN_DEFAULT].stretched = 1; + modelist[MODE_FULLSCREEN_DEFAULT].width >>= 1; + modelist[MODE_FULLSCREEN_DEFAULT].height >>= 1; + sprintf (modelist[MODE_FULLSCREEN_DEFAULT].modedesc, "%dx%d", + modelist[MODE_FULLSCREEN_DEFAULT].width, + modelist[MODE_FULLSCREEN_DEFAULT].height); + } + + vid_default = MODE_FULLSCREEN_DEFAULT; + + temp = m[0]; + + if (!MGL_init(&driver, &temp, "")) + { + initFatalError(); + } + } + + MGL_setSuspendAppCallback(VID_Suspend); +} + + +MGLDC *createDisplayDC(int forcemem) +/**************************************************************************** +* +* Function: createDisplayDC +* Returns: Pointer to the MGL device context to use for the application +* +* Description: Initialises the MGL and creates an appropriate display +* device context to be used by the GUI. This creates and +* apropriate device context depending on the system being +* compile for, and should be the only place where system +* specific code is required. +* +****************************************************************************/ +{ + MGLDC *dc; + pixel_format_t pf; + int npages; + + // Start the specified video mode + if (!MGL_changeDisplayMode(mode)) + initFatalError(); + + npages = MGL_availablePages(mode); + + if (npages > 3) + npages = 3; + + if (!COM_CheckParm ("-notriplebuf")) + { + if (npages > 2) + { + npages = 2; + } + } + + if ((dc = MGL_createDisplayDC(npages)) == NULL) + return NULL; + + if (!forcemem && (MGL_surfaceAccessType(dc)) == MGL_LINEAR_ACCESS && (dc->mi.maxPage > 0)) + { + MGL_makeCurrentDC(dc); + memdc = NULL; + } + else + { + // Set up for blitting from a memory buffer + memdc = MGL_createMemoryDC(MGL_sizex(dc)+1,MGL_sizey(dc)+1,8,&pf); + MGL_makeCurrentDC(memdc); + } + + // Enable page flipping even for even for blitted surfaces + if (forcemem) + { + vid.numpages = 1; + } + else + { + vid.numpages = dc->mi.maxPage + 1; + + if (vid.numpages > 1) + { + // Set up for page flipping + MGL_setActivePage(dc, aPage = 1); + MGL_setVisualPage(dc, vPage = 0, false); + } + + if (vid.numpages > 3) + vid.numpages = 3; + } + + if (vid.numpages == 2) + waitVRT = true; + else + waitVRT = false; + + return dc; +} + + +void VID_InitMGLDIB (HINSTANCE hInstance) +{ + WNDCLASS wc; + HDC hdc; + int i; + + hIcon = LoadIcon (hInstance, MAKEINTRESOURCE (IDI_ICON2)); + + /* Register the frame class */ + wc.style = 0; + wc.lpfnWndProc = (WNDPROC)MainWndProc; + wc.cbClsExtra = 0; + wc.cbWndExtra = 0; + wc.hInstance = hInstance; + wc.hIcon = 0; + wc.hCursor = LoadCursor (NULL,IDC_ARROW); + wc.hbrBackground = NULL; + wc.lpszMenuName = 0; + wc.lpszClassName = "WinQuake"; + + if (!RegisterClass (&wc) ) + Sys_Error ("Couldn't register window class"); + + /* Find the size for the DIB window */ + /* Initialise the MGL for windowed operation */ + MGL_setAppInstance(hInstance); + registerAllMemDrivers(); + MGL_initWindowed(""); + + modelist[0].type = MS_WINDOWED; + modelist[0].width = 320; + modelist[0].height = 240; + strcpy (modelist[0].modedesc, "320x240"); + modelist[0].mode13 = 0; + modelist[0].modenum = MODE_WINDOWED; + modelist[0].stretched = 0; + modelist[0].dib = 1; + modelist[0].fullscreen = 0; + modelist[0].halfscreen = 0; + modelist[0].bpp = 8; + + modelist[1].type = MS_WINDOWED; + modelist[1].width = 640; + modelist[1].height = 480; + strcpy (modelist[1].modedesc, "640x480"); + modelist[1].mode13 = 0; + modelist[1].modenum = MODE_WINDOWED + 1; + modelist[1].stretched = 1; + modelist[1].dib = 1; + modelist[1].fullscreen = 0; + modelist[1].halfscreen = 0; + modelist[1].bpp = 8; + + modelist[2].type = MS_WINDOWED; + modelist[2].width = 800; + modelist[2].height = 600; + strcpy (modelist[2].modedesc, "800x600"); + modelist[2].mode13 = 0; + modelist[2].modenum = MODE_WINDOWED + 2; + modelist[2].stretched = 1; + modelist[2].dib = 1; + modelist[2].fullscreen = 0; + modelist[2].halfscreen = 0; + modelist[2].bpp = 8; + +// automatically stretch the default mode up if > 640x480 desktop resolution + hdc = GetDC(NULL); + + if ((GetDeviceCaps(hdc, HORZRES) > 640) && !COM_CheckParm("-noautostretch")) + { + vid_default = MODE_WINDOWED + 1; + } + else + { + vid_default = MODE_WINDOWED; + } + + windowed_default = vid_default; + + ReleaseDC(NULL,hdc); + + nummodes = 3; // reserve space for windowed mode + + DDActive = 0; +} + + +/* +================= +VID_InitFullDIB +================= +*/ +void VID_InitFullDIB (HINSTANCE hInstance) +{ + DEVMODE devmode; + int i, j, modenum, cmodes, existingmode, originalnummodes, lowestres; + int numlowresmodes, bpp, done; + int cstretch, istretch, mstretch; + BOOL stat; + +// enumerate 8 bpp modes + originalnummodes = nummodes; + modenum = 0; + lowestres = 99999; + + do + { + stat = EnumDisplaySettings (NULL, modenum, &devmode); + + if ((devmode.dmBitsPerPel == 8) && + (devmode.dmPelsWidth <= MAXWIDTH) && + (devmode.dmPelsHeight <= MAXHEIGHT) && + (nummodes < MAX_MODE_LIST)) + { + 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].mode13 = 0; + modelist[nummodes].stretched = 0; + modelist[nummodes].halfscreen = 0; + modelist[nummodes].dib = 1; + modelist[nummodes].fullscreen = 1; + modelist[nummodes].bpp = devmode.dmBitsPerPel; + sprintf (modelist[nummodes].modedesc, "%dx%d", + devmode.dmPelsWidth, devmode.dmPelsHeight); + + // 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; + sprintf (modelist[nummodes].modedesc, "%dx%d", + modelist[nummodes].width, + modelist[nummodes].height); + } + } + + for (i=originalnummodes, existingmode = 0 ; i 8 bpp + if (nummodes == originalnummodes) + { + modenum = 0; + lowestres = 99999; + + Con_SafePrintf ("No 8-bpp fullscreen DIB modes found\n"); + + do + { + stat = EnumDisplaySettings (NULL, modenum, &devmode); + + if ((((devmode.dmPelsWidth <= MAXWIDTH) && + (devmode.dmPelsHeight <= MAXHEIGHT)) || + (!COM_CheckParm("-noadjustaspect") && + (devmode.dmPelsWidth <= (MAXWIDTH*2)) && + (devmode.dmPelsWidth > (devmode.dmPelsHeight*2)))) && + (nummodes < MAX_MODE_LIST) && + (devmode.dmBitsPerPel > 8)) + { + 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].mode13 = 0; + modelist[nummodes].stretched = 0; + modelist[nummodes].halfscreen = 0; + modelist[nummodes].dib = 1; + modelist[nummodes].fullscreen = 1; + modelist[nummodes].bpp = devmode.dmBitsPerPel; + sprintf (modelist[nummodes].modedesc, "%dx%d", + devmode.dmPelsWidth, devmode.dmPelsHeight); + + // 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*2)) + { + modelist[nummodes].width >>= 1; + modelist[nummodes].halfscreen = 1; + sprintf (modelist[nummodes].modedesc, "%dx%d", + modelist[nummodes].width, + modelist[nummodes].height); + } + } + + for (i=originalnummodes, existingmode = 0 ; i= modelist[i].bpp)) + { + existingmode = 1; + break; + } + } + + if (!existingmode) + { + if (modelist[nummodes].width < lowestres) + lowestres = modelist[nummodes].width; + + nummodes++; + } + } + } + + switch (bpp) + { + case 8: + bpp = 16; + break; + + case 16: + bpp = 32; + break; + + case 32: + done = 1; + break; + } + } + +// now add the lowest stretch-by-2 pseudo-modes between 320-wide +// (inclusive) and lowest real res (not inclusive) +// don't bother if we have a real VGA mode 0x13 mode + if (!is_mode0x13) + { + for (i=originalnummodes, cstretch=0 ; i> 1) < lowestres) && + ((modelist[i].width >> 1) >= 320)) + { + lowestres = modelist[i].width >> 1; + cstretch = 1; + mstretch = i; + } + } + + if ((nummodes + cstretch) > MAX_MODE_LIST) + cstretch = MAX_MODE_LIST - nummodes; + + if (cstretch > 0) + { + for (i=(nummodes-1) ; i>=originalnummodes ; i--) + modelist[i+cstretch] = modelist[i]; + + nummodes += cstretch; + istretch = originalnummodes; + + modelist[istretch] = modelist[mstretch]; + modelist[istretch].width >>= 1; + modelist[istretch].height >>= 1; + modelist[istretch].stretched = 1; + sprintf (modelist[istretch].modedesc, "%dx%d", + modelist[istretch].width, modelist[istretch].height); + } + } + + if (nummodes != originalnummodes) + vid_default = MODE_FULLSCREEN_DEFAULT; + else + Con_SafePrintf ("No fullscreen DIB modes found\n"); +} + + +/* +================= +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_CheckModedescFixup +================= +*/ +void VID_CheckModedescFixup (int mode) +{ + int x, y, stretch; + + if (mode == MODE_SETTABLE_WINDOW) + { + modelist[mode].stretched = (int)vid_stretch_by_2.value; + stretch = modelist[mode].stretched; + + if (vid_config_x.value < (320 << stretch)) + vid_config_x.value = 320 << stretch; + + if (vid_config_y.value < (200 << stretch)) + vid_config_y.value = 200 << stretch; + + x = (int)vid_config_x.value; + y = (int)vid_config_y.value; + sprintf (modelist[mode].modedesc, "%dx%d", x, y); + modelist[mode].width = x; + modelist[mode].height = y; + } +} + + +/* +================= +VID_GetModeDescriptionMemCheck +================= +*/ +char *VID_GetModeDescriptionMemCheck (int mode) +{ + char *pinfo; + vmode_t *pv; + + if ((mode < 0) || (mode >= nummodes)) + return NULL; + + VID_CheckModedescFixup (mode); + + pv = VID_GetModePtr (mode); + pinfo = pv->modedesc; + + if (VID_CheckAdequateMem (pv->width, pv->height)) + { + return pinfo; + } + else + { + return NULL; + } +} + + +/* +================= +VID_GetModeDescription +================= +*/ +char *VID_GetModeDescription (int mode) +{ + char *pinfo; + vmode_t *pv; + + if ((mode < 0) || (mode >= nummodes)) + return NULL; + + VID_CheckModedescFixup (mode); + + pv = VID_GetModePtr (mode); + pinfo = pv->modedesc; + return pinfo; +} + + +/* +================= +VID_GetModeDescription2 + +Tacks on "windowed" or "fullscreen" +================= +*/ +char *VID_GetModeDescription2 (int mode) +{ + static char pinfo[40]; + vmode_t *pv; + + if ((mode < 0) || (mode >= nummodes)) + return NULL; + + VID_CheckModedescFixup (mode); + + pv = VID_GetModePtr (mode); + + if (modelist[mode].type == MS_FULLSCREEN) + { + sprintf(pinfo,"%s fullscreen", pv->modedesc); + } + else if (modelist[mode].type == MS_FULLDIB) + { + sprintf(pinfo,"%s fullscreen", pv->modedesc); + } + else + { + sprintf(pinfo, "%s windowed", pv->modedesc); + } + + return pinfo; +} + + +// KJB: Added this to return the mode driver name in description for console + +char *VID_GetExtModeDescription (int mode) +{ + static char pinfo[40]; + vmode_t *pv; + + if ((mode < 0) || (mode >= nummodes)) + return NULL; + + VID_CheckModedescFixup (mode); + + pv = VID_GetModePtr (mode); + if (modelist[mode].type == MS_FULLSCREEN) + { + sprintf(pinfo,"%s fullscreen %s",pv->modedesc, + MGL_modeDriverName(pv->modenum)); + } + else if (modelist[mode].type == MS_FULLDIB) + { + sprintf(pinfo,"%s fullscreen DIB", pv->modedesc); + } + else + { + sprintf(pinfo, "%s windowed", pv->modedesc); + } + + return pinfo; +} + + +void DestroyDIBWindow (void) +{ + + if (modestate == MS_WINDOWED) + { + // destroy the associated MGL DC's; the window gets reused + if (windc) + MGL_destroyDC(windc); + if (dibdc) + MGL_destroyDC(dibdc); + windc = dibdc = NULL; + } +} + + +void DestroyFullscreenWindow (void) +{ + + if (modestate == MS_FULLSCREEN) + { + // destroy the existing fullscreen mode and DC's + if (mgldc) + MGL_destroyDC (mgldc); + if (memdc) + MGL_destroyDC (memdc); + mgldc = memdc = NULL; + } +} + + + +void DestroyFullDIBWindow (void) +{ + if (modestate == MS_FULLDIB) + { + ChangeDisplaySettings (NULL, CDS_FULLSCREEN); + + // Destroy the fullscreen DIB window and associated MGL DC's + if (windc) + MGL_destroyDC(windc); + if (dibdc) + MGL_destroyDC(dibdc); + windc = dibdc = NULL; + } +} + + +qboolean VID_SetWindowedMode (int modenum) +{ + HDC hdc; + pixel_format_t pf; + qboolean stretched; + int lastmodestate; + LONG wlong; + + if (!windowed_mode_set) + { + if (COM_CheckParm ("-resetwinpos")) + { + Cvar_SetValue ("vid_window_x", 0.0); + Cvar_SetValue ("vid_window_y", 0.0); + } + + windowed_mode_set; + } + + VID_CheckModedescFixup (modenum); + + DDActive = 0; + lastmodestate = modestate; + + DestroyFullscreenWindow (); + DestroyFullDIBWindow (); + + if (windc) + MGL_destroyDC(windc); + if (dibdc) + MGL_destroyDC(dibdc); + windc = dibdc = NULL; + +// KJB: Signal to the MGL that we are going back to windowed mode + if (!MGL_changeDisplayMode(grWINDOWED)) + initFatalError(); + + WindowRect.top = WindowRect.left = 0; + + WindowRect.right = modelist[modenum].width; + WindowRect.bottom = modelist[modenum].height; + stretched = modelist[modenum].stretched; + + DIBWidth = modelist[modenum].width; + DIBHeight = modelist[modenum].height; + + if (stretched) + { + DIBWidth >>= 1; + DIBHeight >>= 1; + } + + WindowStyle = WS_OVERLAPPED | WS_BORDER | WS_CAPTION | WS_SYSMENU | + WS_MINIMIZEBOX | WS_MAXIMIZEBOX | WS_CLIPSIBLINGS | + WS_CLIPCHILDREN; + ExWindowStyle = 0; + AdjustWindowRectEx(&WindowRect, WindowStyle, FALSE, 0); + +// the first time we're called to set the mode, create the window we'll use +// for the rest of the session + if (!vid_mode_set) + { + mainwindow = CreateWindowEx ( + ExWindowStyle, + "WinQuake", + "WinQuake", + WindowStyle, + 0, 0, + WindowRect.right - WindowRect.left, + WindowRect.bottom - WindowRect.top, + NULL, + NULL, + global_hInstance, + NULL); + + if (!mainwindow) + Sys_Error ("Couldn't create DIB window"); + + // tell MGL to use this window for fullscreen modes + MGL_registerFullScreenWindow (mainwindow); + + vid_mode_set = true; + } + else + { + SetWindowLong(mainwindow, GWL_STYLE, WindowStyle | WS_VISIBLE); + SetWindowLong(mainwindow, GWL_EXSTYLE, ExWindowStyle); + } + + if (!SetWindowPos (mainwindow, + NULL, + 0, 0, + WindowRect.right - WindowRect.left, + WindowRect.bottom - WindowRect.top, + SWP_NOCOPYBITS | SWP_NOZORDER | + SWP_HIDEWINDOW)) + { + Sys_Error ("Couldn't resize DIB window"); + } + + if (hide_window) + return true; + +// position and show the DIB window + VID_CheckWindowXY (); + SetWindowPos (mainwindow, NULL, (int)vid_window_x.value, + (int)vid_window_y.value, 0, 0, + SWP_NOSIZE | SWP_NOZORDER | SWP_SHOWWINDOW | SWP_DRAWFRAME); + + if (force_minimized) + ShowWindow (mainwindow, SW_MINIMIZE); + else + ShowWindow (mainwindow, SW_SHOWDEFAULT); + + UpdateWindow (mainwindow); + + modestate = MS_WINDOWED; + vid_fulldib_on_focus_mode = 0; + +// 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(mainwindow); + PatBlt(hdc,0,0,WindowRect.right,WindowRect.bottom,BLACKNESS); + ReleaseDC(mainwindow, hdc); + + /* Create the MGL window DC and the MGL memory DC */ + if ((windc = MGL_createWindowedDC(mainwindow)) == NULL) + MGL_fatalError("Unable to create Windowed DC!"); + + if ((dibdc = MGL_createMemoryDC(DIBWidth,DIBHeight,8,&pf)) == NULL) + MGL_fatalError("Unable to create Memory DC!"); + + MGL_makeCurrentDC(dibdc); + + vid.buffer = vid.conbuffer = vid.direct = dibdc->surface; + vid.rowbytes = vid.conrowbytes = dibdc->mi.bytesPerLine; + vid.numpages = 1; + vid.maxwarpwidth = WARP_WIDTH; + vid.maxwarpheight = WARP_HEIGHT; + vid.height = vid.conheight = DIBHeight; + vid.width = vid.conwidth = DIBWidth; + vid.aspect = ((float)vid.height / (float)vid.width) * + (320.0 / 240.0); + + vid_stretched = stretched; + + SendMessage (mainwindow, WM_SETICON, (WPARAM)TRUE, (LPARAM)hIcon); + SendMessage (mainwindow, WM_SETICON, (WPARAM)FALSE, (LPARAM)hIcon); + + return true; +} + + +qboolean VID_SetFullscreenMode (int modenum) +{ + + DDActive = 1; + + DestroyDIBWindow (); + DestroyFullDIBWindow (); + + mode = modelist[modenum].modenum; + + // Destroy old DC's, resetting back to fullscreen mode + if (mgldc) + MGL_destroyDC (mgldc); + if (memdc) + MGL_destroyDC (memdc); + mgldc = memdc = NULL; + + if ((mgldc = createDisplayDC (modelist[modenum].stretched || + (int)vid_nopageflip.value)) == NULL) + { + return false; + } + + modestate = MS_FULLSCREEN; + vid_fulldib_on_focus_mode = 0; + + vid.buffer = vid.conbuffer = vid.direct = NULL; + vid.maxwarpwidth = WARP_WIDTH; + vid.maxwarpheight = WARP_HEIGHT; + DIBHeight = vid.height = vid.conheight = modelist[modenum].height; + DIBWidth = vid.width = vid.conwidth = modelist[modenum].width; + vid.aspect = ((float)vid.height / (float)vid.width) * + (320.0 / 240.0); + + vid_stretched = modelist[modenum].stretched; + +// needed because we're not getting WM_MOVE messages fullscreen on NT + window_x = 0; + window_y = 0; + +// set the large icon, so the Quake icon will show up in the taskbar + SendMessage (mainwindow, WM_SETICON, (WPARAM)1, (LPARAM)hIcon); + SendMessage (mainwindow, WM_SETICON, (WPARAM)0, (LPARAM)hIcon); + +// shouldn't be needed, but Kendall needs to let us get the activation +// message for this not to be needed on NT + AppActivate (true, false); + + return true; +} + + +qboolean VID_SetFullDIBMode (int modenum) +{ + HDC hdc; + pixel_format_t pf; + int lastmodestate; + + DDActive = 0; + + DestroyFullscreenWindow (); + DestroyDIBWindow (); + + if (windc) + MGL_destroyDC(windc); + if (dibdc) + MGL_destroyDC(dibdc); + windc = dibdc = NULL; + +// KJB: Signal to the MGL that we are going back to windowed mode + if (!MGL_changeDisplayMode(grWINDOWED)) + initFatalError(); + + gdevmode.dmFields = DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT; + gdevmode.dmBitsPerPel = modelist[modenum].bpp; + gdevmode.dmPelsWidth = modelist[modenum].width << modelist[modenum].stretched << + modelist[modenum].halfscreen; + gdevmode.dmPelsHeight = modelist[modenum].height << modelist[modenum].stretched; + 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; + vid_fulldib_on_focus_mode = modenum; + + WindowRect.top = WindowRect.left = 0; + + hdc = GetDC(NULL); + + WindowRect.right = modelist[modenum].width << modelist[modenum].stretched; + WindowRect.bottom = modelist[modenum].height << modelist[modenum].stretched; + + ReleaseDC(NULL,hdc); + + DIBWidth = modelist[modenum].width; + DIBHeight = modelist[modenum].height; + + WindowStyle = WS_POPUP | WS_SYSMENU | WS_CLIPSIBLINGS | WS_CLIPCHILDREN; + ExWindowStyle = 0; + AdjustWindowRectEx(&WindowRect, WindowStyle, FALSE, 0); + + SetWindowLong(mainwindow, GWL_STYLE, WindowStyle | WS_VISIBLE); + SetWindowLong(mainwindow, GWL_EXSTYLE, ExWindowStyle); + + if (!SetWindowPos (mainwindow, + NULL, + 0, 0, + WindowRect.right - WindowRect.left, + WindowRect.bottom - WindowRect.top, + SWP_NOCOPYBITS | SWP_NOZORDER)) + { + Sys_Error ("Couldn't resize DIB window"); + } + +// position and show the DIB window + SetWindowPos (mainwindow, HWND_TOPMOST, 0, 0, 0, 0, + SWP_NOSIZE | SWP_SHOWWINDOW | SWP_DRAWFRAME); + ShowWindow (mainwindow, SW_SHOWDEFAULT); + UpdateWindow (mainwindow); + + // 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(mainwindow); + PatBlt(hdc,0,0,WindowRect.right,WindowRect.bottom,BLACKNESS); + ReleaseDC(mainwindow, hdc); + + /* Create the MGL window DC and the MGL memory DC */ + if ((windc = MGL_createWindowedDC(mainwindow)) == NULL) + MGL_fatalError("Unable to create Fullscreen DIB DC!"); + + if ((dibdc = MGL_createMemoryDC(DIBWidth,DIBHeight,8,&pf)) == NULL) + MGL_fatalError("Unable to create Memory DC!"); + + MGL_makeCurrentDC(dibdc); + + vid.buffer = vid.conbuffer = vid.direct = dibdc->surface; + vid.rowbytes = vid.conrowbytes = dibdc->mi.bytesPerLine; + vid.numpages = 1; + vid.maxwarpwidth = WARP_WIDTH; + vid.maxwarpheight = WARP_HEIGHT; + vid.height = vid.conheight = DIBHeight; + vid.width = vid.conwidth = DIBWidth; + vid.aspect = ((float)vid.height / (float)vid.width) * + (320.0 / 240.0); + + vid_stretched = modelist[modenum].stretched; + +// needed because we're not getting WM_MOVE messages fullscreen on NT + window_x = 0; + window_y = 0; + + return true; +} + + +void VID_RestoreOldMode (int original_mode) +{ + static qboolean inerror = false; + + if (inerror) + return; + + in_mode_set = false; + inerror = true; + +// make sure mode set happens (video mode changes) + vid_modenum = original_mode - 1; + + if (!VID_SetMode (original_mode, vid_curpal)) + { + vid_modenum = MODE_WINDOWED - 1; + + if (!VID_SetMode (windowed_default, vid_curpal)) + Sys_Error ("Can't set any video mode"); + } + + inerror = false; +} + + +void VID_SetDefaultMode (void) +{ + + if (vid_initialized) + VID_SetMode (0, vid_curpal); + + IN_DeactivateMouse (); +} + + +int VID_SetMode (int modenum, unsigned char *palette) +{ + int original_mode, temp, dummy; + qboolean stat; + MSG msg; + HDC hdc; + + while ((modenum >= nummodes) || (modenum < 0)) + { + if (vid_modenum == NO_MODE) + { + if (modenum == vid_default) + { + modenum = windowed_default; + } + else + { + modenum = vid_default; + } + + Cvar_SetValue ("vid_mode", (float)modenum); + } + else + { + Cvar_SetValue ("vid_mode", (float)vid_modenum); + return 0; + } + } + + if (!force_mode_set && (modenum == vid_modenum)) + return true; + +// so Con_Printfs don't mess us up by forcing vid and snd updates + temp = scr_disabled_for_loading; + scr_disabled_for_loading = true; + in_mode_set = true; + + CDAudio_Pause (); + S_ClearBuffer (); + + 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) + { + 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 + { + stat = VID_SetFullscreenMode(modenum); + IN_ActivateMouse (); + IN_HideMouse (); + } + + window_width = vid.width << vid_stretched; + window_height = vid.height << vid_stretched; + VID_UpdateWindowStatus (); + + CDAudio_Resume (); + scr_disabled_for_loading = temp; + + if (!stat) + { + VID_RestoreOldMode (original_mode); + return false; + } + + if (hide_window) + return true; + +// 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 + if (!force_minimized) + SetForegroundWindow (mainwindow); + + hdc = GetDC(NULL); + + if (GetDeviceCaps(hdc, RASTERCAPS) & RC_PALETTE) + vid_palettized = true; + else + vid_palettized = false; + + VID_SetPalette (palette); + + ReleaseDC(NULL,hdc); + + vid_modenum = modenum; + Cvar_SetValue ("vid_mode", (float)vid_modenum); + + if (!VID_AllocBuffers (vid.width, vid.height)) + { + // couldn't get memory for this mode; try to fall back to previous mode + VID_RestoreOldMode (original_mode); + return false; + } + + D_InitCaches (vid_surfcache, vid_surfcachesize); + + while (PeekMessage (&msg, NULL, 0, 0, PM_REMOVE)) + { + TranslateMessage (&msg); + DispatchMessage (&msg); + } + + Sleep (100); + + if (!force_minimized) + { + 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 ("%s\n", VID_GetModeDescription (vid_modenum)); + + VID_SetPalette (palette); + + in_mode_set = false; + vid.recalc_refdef = 1; + + return true; +} + +void VID_LockBuffer (void) +{ + + if (dibdc) + return; + + lockcount++; + + if (lockcount > 1) + return; + + MGL_beginDirectAccess(); + + if (memdc) + { + // Update surface pointer for linear access modes + vid.buffer = vid.conbuffer = vid.direct = memdc->surface; + vid.rowbytes = vid.conrowbytes = memdc->mi.bytesPerLine; + } + else if (mgldc) + { + // Update surface pointer for linear access modes + vid.buffer = vid.conbuffer = vid.direct = mgldc->surface; + vid.rowbytes = vid.conrowbytes = mgldc->mi.bytesPerLine; + } + + if (r_dowarp) + d_viewbuffer = r_warpbuffer; + else + d_viewbuffer = (void *)(byte *)vid.buffer; + + if (r_dowarp) + screenwidth = WARP_WIDTH; + else + screenwidth = vid.rowbytes; + + if (lcd_x.value) + screenwidth <<= 1; +} + + +void VID_UnlockBuffer (void) +{ + if (dibdc) + return; + + lockcount--; + + if (lockcount > 0) + return; + + if (lockcount < 0) + Sys_Error ("Unbalanced unlock"); + + MGL_endDirectAccess(); + +// to turn up any unlocked accesses + vid.buffer = vid.conbuffer = vid.direct = d_viewbuffer = NULL; + +} + + +int VID_ForceUnlockedAndReturnState (void) +{ + int lk; + + if (!lockcount) + return 0; + + lk = lockcount; + + if (dibdc) + { + lockcount = 0; + } + else + { + lockcount = 1; + VID_UnlockBuffer (); + } + + return lk; +} + + +void VID_ForceLockState (int lk) +{ + + if (!dibdc && lk) + { + lockcount = 0; + VID_LockBuffer (); + } + + lockcount = lk; +} + + +void VID_SetPalette (unsigned char *palette) +{ + INT i; + palette_t pal[256]; + HDC hdc; + + if (!Minimized) + { + palette_changed = true; + + // make sure we have the static colors if we're the active app + hdc = GetDC(NULL); + + if (vid_palettized && ActiveApp) + { + if (GetSystemPaletteUse(hdc) == SYSPAL_STATIC) + { + // switch to SYSPAL_NOSTATIC and remap the colors + SetSystemPaletteUse(hdc, SYSPAL_NOSTATIC); + syscolchg = true; + pal_is_nostatic = true; + } + } + + ReleaseDC(NULL,hdc); + + // Translate the palette values to an MGL palette array and + // set the values. + for (i = 0; i < 256; i++) + { + pal[i].red = palette[i*3]; + pal[i].green = palette[i*3+1]; + pal[i].blue = palette[i*3+2]; + } + + if (DDActive) + { + if (!mgldc) + return; + + MGL_setPalette(mgldc,pal,256,0); + MGL_realizePalette(mgldc,256,0,false); + if (memdc) + MGL_setPalette(memdc,pal,256,0); + } + else + { + if (!windc) + return; + + MGL_setPalette(windc,pal,256,0); + MGL_realizePalette(windc,256,0,false); + if (dibdc) + { + MGL_setPalette(dibdc,pal,256,0); + MGL_realizePalette(dibdc,256,0,false); + } + } + } + + memcpy (vid_curpal, palette, sizeof(vid_curpal)); + + if (syscolchg) + { + PostMessage (HWND_BROADCAST, WM_SYSCOLORCHANGE, (WPARAM)0, (LPARAM)0); + syscolchg = false; + } +} + + +void VID_ShiftPalette (unsigned char *palette) +{ + VID_SetPalette (palette); +} + + +/* +================= +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 modenum; + + modenum = Q_atoi (Cmd_Argv(1)); + + Con_Printf ("%s\n", VID_GetExtModeDescription (modenum)); +} + + +/* +================= +VID_DescribeModes_f +================= +*/ +void VID_DescribeModes_f (void) +{ + int i, lnummodes; + char *pinfo; + qboolean na; + vmode_t *pv; + + na = false; + + lnummodes = VID_NumModes (); + + for (i=0 ; iwidth, pv->height)) + { + Con_Printf ("%2d: %s\n", i, pinfo); + } + else + { + Con_Printf ("**: %s\n", pinfo); + na = true; + } + } + + if (na) + { + Con_Printf ("\n[**: not enough system RAM for mode]\n"); + } +} + + +/* +================= +VID_TestMode_f +================= +*/ +void VID_TestMode_f (void) +{ + int modenum; + double testduration; + + if (!vid_testingmode) + { + modenum = Q_atoi (Cmd_Argv(1)); + + if (VID_SetMode (modenum, vid_curpal)) + { + vid_testingmode = 1; + testduration = Q_atof (Cmd_Argv(2)); + if (testduration == 0) + testduration = 5.0; + vid_testendtime = realtime + testduration; + } + } +} + + +/* +================= +VID_Windowed_f +================= +*/ +void VID_Windowed_f (void) +{ + + VID_SetMode ((int)vid_windowed_mode.value, vid_curpal); +} + + +/* +================= +VID_Fullscreen_f +================= +*/ +void VID_Fullscreen_f (void) +{ + + VID_SetMode ((int)vid_fullscreen_mode.value, vid_curpal); +} + + +/* +================= +VID_Minimize_f +================= +*/ +void VID_Minimize_f (void) +{ + +// we only support minimizing windows; if you're fullscreen, +// switch to windowed first + if (modestate == MS_WINDOWED) + ShowWindow (mainwindow, SW_MINIMIZE); +} + + + +/* +================= +VID_ForceMode_f +================= +*/ +void VID_ForceMode_f (void) +{ + int modenum; + double testduration; + + if (!vid_testingmode) + { + modenum = Q_atoi (Cmd_Argv(1)); + + force_mode_set = 1; + VID_SetMode (modenum, vid_curpal); + force_mode_set = 0; + } +} + + +void VID_Init (unsigned char *palette) +{ + int i, bestmatch, bestmatchmetric, t, dr, dg, db; + int basenummodes; + byte *ptmp; + + 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 (&vid_fullscreen_mode); + Cvar_RegisterVariable (&vid_windowed_mode); + Cvar_RegisterVariable (&block_switch); + Cvar_RegisterVariable (&vid_window_x); + Cvar_RegisterVariable (&vid_window_y); + + Cmd_AddCommand ("vid_testmode", VID_TestMode_f); + 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); + Cmd_AddCommand ("vid_forcemode", VID_ForceMode_f); + Cmd_AddCommand ("vid_windowed", VID_Windowed_f); + Cmd_AddCommand ("vid_fullscreen", VID_Fullscreen_f); + Cmd_AddCommand ("vid_minimize", VID_Minimize_f); + + if (COM_CheckParm ("-dibonly")) + dibonly = true; + + VID_InitMGLDIB (global_hInstance); + + basenummodes = nummodes; + + if (!dibonly) + VID_InitMGLFull (global_hInstance); + +// if there are no non-windowed modes, or only windowed and mode 0x13, then use +// fullscreen DIBs as well + if (((nummodes == basenummodes) || + ((nummodes == (basenummodes + 1)) && is_mode0x13)) && + !COM_CheckParm ("-nofulldib")) + + { + VID_InitFullDIB (global_hInstance); + } + + vid.maxwarpwidth = WARP_WIDTH; + vid.maxwarpheight = WARP_HEIGHT; + vid.colormap = host_colormap; + vid.fullbright = 256 - LittleLong (*((int *)vid.colormap + 2048)); + vid_testingmode = 0; + +// GDI doesn't let us remap palette index 0, so we'll remap color +// mappings from that black to another one + bestmatchmetric = 256*256*3; + + for (i=1 ; i<256 ; i++) + { + dr = palette[0] - palette[i*3]; + dg = palette[1] - palette[i*3+1]; + db = palette[2] - palette[i*3+2]; + + t = (dr * dr) + (dg * dg) + (db * db); + + if (t < bestmatchmetric) + { + bestmatchmetric = t; + bestmatch = i; + + if (t == 0) + break; + } + } + + for (i=0, ptmp = vid.colormap ; i<(1<<(VID_CBITS+8)) ; i++, ptmp++) + { + if (*ptmp == 0) + *ptmp = bestmatch; + } + + if (COM_CheckParm("-startwindowed")) + { + startwindowed = 1; + vid_default = windowed_default; + } + + if (hwnd_dialog) + DestroyWindow (hwnd_dialog); + +// sound initialization has to go here, preceded by a windowed mode set, +// so there's a window for DirectSound to work with but we're not yet +// fullscreen so the "hardware already in use" dialog is visible if it +// gets displayed + +// keep the window minimized until we're ready for the first real mode set + hide_window = true; + VID_SetMode (MODE_WINDOWED, palette); + hide_window = false; + S_Init (); + + vid_initialized = true; + + force_mode_set = true; + VID_SetMode (vid_default, palette); + force_mode_set = false; + + vid_realmode = vid_modenum; + + VID_SetPalette (palette); + + vid_menudrawfn = VID_MenuDraw; + vid_menukeyfn = VID_MenuKey; + + strcpy (badmode.modedesc, "Bad mode"); +} + + +void VID_Shutdown (void) +{ + HDC hdc; + int dummy; + + if (vid_initialized) + { + if (modestate == MS_FULLDIB) + ChangeDisplaySettings (NULL, CDS_FULLSCREEN); + + PostMessage (HWND_BROADCAST, WM_PALETTECHANGED, (WPARAM)mainwindow, (LPARAM)0); + PostMessage (HWND_BROADCAST, WM_SYSCOLORCHANGE, (WPARAM)0, (LPARAM)0); + + AppActivate(false, false); + DestroyDIBWindow (); + DestroyFullscreenWindow (); + DestroyFullDIBWindow (); + + if (hwnd_dialog) + DestroyWindow (hwnd_dialog); + + if (mainwindow) + DestroyWindow(mainwindow); + + MGL_exit(); + + vid_testingmode = 0; + vid_initialized = 0; + } +} + + +/* +================ +FlipScreen +================ +*/ +void FlipScreen(vrect_t *rects) +{ + HRESULT ddrval; + + // Flip the surfaces + + if (DDActive) + { + if (mgldc) + { + if (memdc) + { + while (rects) + { + if (vid_stretched) + { + MGL_stretchBltCoord(mgldc, memdc, + rects->x, + rects->y, + rects->x + rects->width, + rects->y + rects->height, + rects->x << 1, + rects->y << 1, + (rects->x + rects->width) << 1, + (rects->y + rects->height) << 1); + } + else + { + MGL_bitBltCoord(mgldc, memdc, + rects->x, rects->y, + (rects->x + rects->width), + (rects->y + rects->height), + rects->x, rects->y, MGL_REPLACE_MODE); + } + + rects = rects->pnext; + } + } + + if (vid.numpages > 1) + { + // We have a flipping surface, so do a hard page flip + aPage = (aPage+1) % vid.numpages; + vPage = (vPage+1) % vid.numpages; + MGL_setActivePage(mgldc,aPage); + MGL_setVisualPage(mgldc,vPage,waitVRT); + } + } + } + else + { + HDC hdcScreen; + + hdcScreen = GetDC(mainwindow); + + if (windc && dibdc) + { + MGL_setWinDC(windc,hdcScreen); + + while (rects) + { + if (vid_stretched) + { + MGL_stretchBltCoord(windc,dibdc, + rects->x, rects->y, + rects->x + rects->width, rects->y + rects->height, + rects->x << 1, rects->y << 1, + (rects->x + rects->width) << 1, + (rects->y + rects->height) << 1); + } + else + { + MGL_bitBltCoord(windc,dibdc, + rects->x, rects->y, + rects->x + rects->width, rects->y + rects->height, + rects->x, rects->y, MGL_REPLACE_MODE); + } + + rects = rects->pnext; + } + } + + ReleaseDC(mainwindow, hdcScreen); + } +} + + +void VID_Update (vrect_t *rects) +{ + vrect_t rect; + RECT trect; + + if (!vid_palettized && palette_changed) + { + palette_changed = false; + rect.x = 0; + rect.y = 0; + rect.width = vid.width; + rect.height = vid.height; + rect.pnext = NULL; + rects = ▭ + } + + if (firstupdate) + { + if (modestate == MS_WINDOWED) + { + GetWindowRect (mainwindow, &trect); + + if ((trect.left != (int)vid_window_x.value) || + (trect.top != (int)vid_window_y.value)) + { + if (COM_CheckParm ("-resetwinpos")) + { + Cvar_SetValue ("vid_window_x", 0.0); + Cvar_SetValue ("vid_window_y", 0.0); + } + + VID_CheckWindowXY (); + SetWindowPos (mainwindow, NULL, (int)vid_window_x.value, + (int)vid_window_y.value, 0, 0, + SWP_NOSIZE | SWP_NOZORDER | SWP_SHOWWINDOW | SWP_DRAWFRAME); + } + } + + if ((_vid_default_mode_win.value != vid_default) && + (!startwindowed || (_vid_default_mode_win.value < MODE_FULLSCREEN_DEFAULT))) + { + firstupdate = 0; + + if (COM_CheckParm ("-resetwinpos")) + { + Cvar_SetValue ("vid_window_x", 0.0); + Cvar_SetValue ("vid_window_y", 0.0); + } + + if ((_vid_default_mode_win.value < 0) || + (_vid_default_mode_win.value >= nummodes)) + { + Cvar_SetValue ("_vid_default_mode_win", windowed_default); + } + + Cvar_SetValue ("vid_mode", _vid_default_mode_win.value); + } + } + + // We've drawn the frame; copy it to the screen + FlipScreen (rects); + + if (vid_testingmode) + { + if (realtime >= vid_testendtime) + { + VID_SetMode (vid_realmode, vid_curpal); + vid_testingmode = 0; + } + } + else + { + if ((int)vid_mode.value != vid_realmode) + { + VID_SetMode ((int)vid_mode.value, vid_curpal); + Cvar_SetValue ("vid_mode", (float)vid_modenum); + // so if mode set fails, we don't keep on + // trying to set that mode + vid_realmode = vid_modenum; + } + } + +// handle the mouse state when windowed if that's changed + if (modestate == MS_WINDOWED) + { + if ((int)_windowed_mouse.value != windowed_mouse) + { + if (_windowed_mouse.value) + { + IN_ActivateMouse (); + IN_HideMouse (); + } + else + { + IN_DeactivateMouse (); + IN_ShowMouse (); + } + + windowed_mouse = (int)_windowed_mouse.value; + } + } +} + + +/* +================ +D_BeginDirectRect +================ +*/ +void D_BeginDirectRect (int x, int y, byte *pbitmap, int width, int height) +{ + int i, j, reps, repshift; + vrect_t rect; + + if (!vid_initialized) + return; + + if (vid.aspect > 1.5) + { + reps = 2; + repshift = 1; + } + else + { + reps = 1; + repshift = 0; + } + + if (vid.numpages == 1) + { + VID_LockBuffer (); + + if (!vid.direct) + Sys_Error ("NULL vid.direct pointer"); + + for (i=0 ; i<(height << repshift) ; i += reps) + { + for (j=0 ; j> repshift) * width], + width); + } + } + + VID_UnlockBuffer (); + + rect.x = x; + rect.y = y; + rect.width = width; + rect.height = height << repshift; + rect.pnext = NULL; + + FlipScreen (&rect); + } + else + { + // unlock if locked + if (lockcount > 0) + MGL_endDirectAccess(); + + // set the active page to the displayed page + MGL_setActivePage (mgldc, vPage); + + // lock the screen + MGL_beginDirectAccess (); + + // save from and draw to screen + for (i=0 ; i<(height << repshift) ; i += reps) + { + for (j=0 ; jsurface + x + + ((y << repshift) + i + j) * mgldc->mi.bytesPerLine, + width); + memcpy ((byte *)mgldc->surface + x + + ((y << repshift) + i + j) * mgldc->mi.bytesPerLine, + &pbitmap[(i >> repshift) * width], + width); + } + } + + // unlock the screen + MGL_endDirectAccess (); + + // restore the original active page + MGL_setActivePage (mgldc, aPage); + + // relock the screen if it was locked + if (lockcount > 0) + MGL_beginDirectAccess(); + } +} + + +/* +================ +D_EndDirectRect +================ +*/ +void D_EndDirectRect (int x, int y, int width, int height) +{ + int i, j, reps, repshift; + vrect_t rect; + + if (!vid_initialized) + return; + + if (vid.aspect > 1.5) + { + reps = 2; + repshift = 1; + } + else + { + reps = 1; + repshift = 0; + } + + if (vid.numpages == 1) + { + VID_LockBuffer (); + + if (!vid.direct) + Sys_Error ("NULL vid.direct pointer"); + + for (i=0 ; i<(height << repshift) ; i += reps) + { + for (j=0 ; j 0) + MGL_endDirectAccess(); + + // set the active page to the displayed page + MGL_setActivePage (mgldc, vPage); + + // lock the screen + MGL_beginDirectAccess (); + + // restore to the screen + for (i=0 ; i<(height << repshift) ; i += reps) + { + for (j=0 ; jsurface + x + + ((y << repshift) + i + j) * mgldc->mi.bytesPerLine, + &backingbuf[(i + j) * 24], + width); + } + } + + // unlock the screen + MGL_endDirectAccess (); + + // restore the original active page + MGL_setActivePage (mgldc, aPage); + + // relock the screen if it was locked + if (lockcount > 0) + MGL_beginDirectAccess(); + } +} + + +//========================================================================== + +byte scantokey[128] = + { +// 0 1 2 3 4 5 6 7 +// 8 9 A B C D E F + 0 , 27, '1', '2', '3', '4', '5', '6', + '7', '8', '9', '0', '-', '=', K_BACKSPACE, 9, // 0 + 'q', 'w', 'e', 'r', 't', 'y', 'u', 'i', + 'o', 'p', '[', ']', 13 , K_CTRL,'a', 's', // 1 + 'd', 'f', 'g', 'h', 'j', 'k', 'l', ';', + '\'' , '`', K_SHIFT,'\\', 'z', 'x', 'c', 'v', // 2 + 'b', 'n', 'm', ',', '.', '/', 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,'5',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 +}; + +/* +======= +MapKey + +Map from windows to quake keynums +======= +*/ +int MapKey (int key) +{ + key = (key>>16)&255; + if (key > 127) + return 0; + + return scantokey[key]; +} + +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. +* +****************************************************************************/ +{ + HDC hdc; + int i, t; + static BOOL sound_active; + + ActiveApp = fActive; + +// messy, but it seems to work + if (vid_fulldib_on_focus_mode) + { + Minimized = minimize; + + if (Minimized) + ActiveApp = false; + } + + MGL_appActivate(windc, ActiveApp); + + if (vid_initialized) + { + // yield the palette if we're losing the focus + hdc = GetDC(NULL); + + if (GetDeviceCaps(hdc, RASTERCAPS) & RC_PALETTE) + { + if (ActiveApp) + { + if ((modestate == MS_WINDOWED) || (modestate == MS_FULLDIB)) + { + if (GetSystemPaletteUse(hdc) == SYSPAL_STATIC) + { + // switch to SYSPAL_NOSTATIC and remap the colors + SetSystemPaletteUse(hdc, SYSPAL_NOSTATIC); + syscolchg = true; + pal_is_nostatic = true; + } + } + } + else if (pal_is_nostatic) + { + if (GetSystemPaletteUse(hdc) == SYSPAL_NOSTATIC) + { + // switch back to SYSPAL_STATIC and the old mapping + SetSystemPaletteUse(hdc, SYSPAL_STATIC); + syscolchg = true; + } + + pal_is_nostatic = false; + } + } + + if (!Minimized) + VID_SetPalette (vid_curpal); + + scr_fullupdate = 0; + + ReleaseDC(NULL,hdc); + } + +// enable/disable sound on focus gain/loss + if (!ActiveApp && sound_active) + { + S_BlockSound (); + S_ClearBuffer (); + sound_active = false; + } + else if (ActiveApp && !sound_active) + { + S_UnblockSound (); + S_ClearBuffer (); + sound_active = true; + } + +// minimize/restore fulldib windows/mouse-capture normal windows on demand + if (!in_mode_set) + { + if (ActiveApp) + { + if (vid_fulldib_on_focus_mode) + { + if (vid_initialized) + { + msg_suppress_1 = true; // don't want to see normal mode set message + VID_SetMode (vid_fulldib_on_focus_mode, vid_curpal); + msg_suppress_1 = false; + + t = in_mode_set; + in_mode_set = true; + AppActivate (true, false); + in_mode_set = t; + } + + IN_ActivateMouse (); + IN_HideMouse (); + } + else if ((modestate == MS_WINDOWED) && _windowed_mouse.value) + { + IN_ActivateMouse (); + IN_HideMouse (); + } + } + + if (!ActiveApp) + { + if (modestate == MS_FULLDIB) + { + if (vid_initialized) + { + force_minimized = true; + i = vid_fulldib_on_focus_mode; + msg_suppress_1 = true; // don't want to see normal mode set message + VID_SetMode (windowed_default, vid_curpal); + msg_suppress_1 = false; + vid_fulldib_on_focus_mode = i; + force_minimized = false; + + // we never seem to get WM_ACTIVATE inactive from this mode set, so we'll + // do it manually + t = in_mode_set; + in_mode_set = true; + AppActivate (false, true); + in_mode_set = t; + } + + IN_DeactivateMouse (); + IN_ShowMouse (); + } + else if ((modestate == MS_WINDOWED) && _windowed_mouse.value) + { + IN_DeactivateMouse (); + IN_ShowMouse (); + } + } + } +} + + +/* +================ +VID_HandlePause +================ +*/ +void VID_HandlePause (qboolean pause) +{ + + if ((modestate == MS_WINDOWED) && _windowed_mouse.value) + { + if (pause) + { + IN_DeactivateMouse (); + IN_ShowMouse (); + } + else + { + IN_ActivateMouse (); + IN_HideMouse (); + } + } +} + + +/* +=================================================================== + +MAIN WINDOW + +=================================================================== +*/ + +LONG CDAudio_MessageHandler(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam); + +/* main window procedure */ +LONG WINAPI MainWndProc ( + HWND hWnd, + UINT uMsg, + WPARAM wParam, + LPARAM lParam) +{ + LONG lRet = 0; + int fwKeys, xPos, yPos, fActive, fMinimized, temp; + HDC hdc; + PAINTSTRUCT ps; + static int recursiveflag; + + switch (uMsg) + { + case WM_CREATE: + break; + + case WM_SYSCOMMAND: + + // Check for maximize being hit + switch (wParam & ~0x0F) + { + case SC_MAXIMIZE: + // if minimized, bring up as a window before going fullscreen, + // so MGL will have the right state to restore + if (Minimized) + { + force_mode_set = true; + VID_SetMode (vid_modenum, vid_curpal); + force_mode_set = false; + } + + VID_SetMode ((int)vid_fullscreen_mode.value, vid_curpal); + break; + + case SC_SCREENSAVE: + case SC_MONITORPOWER: + if (modestate != MS_WINDOWED) + { + // don't call DefWindowProc() because we don't want to start + // the screen saver fullscreen + break; + } + + // fall through windowed and allow the screen saver to start + + default: + if (!in_mode_set) + { + S_BlockSound (); + S_ClearBuffer (); + } + + lRet = DefWindowProc (hWnd, uMsg, wParam, lParam); + + if (!in_mode_set) + { + S_UnblockSound (); + } + } + break; + + case WM_MOVE: + window_x = (int) LOWORD(lParam); + window_y = (int) HIWORD(lParam); + VID_UpdateWindowStatus (); + + if ((modestate == MS_WINDOWED) && !in_mode_set && !Minimized) + VID_RememberWindowPos (); + + break; + + case WM_SIZE: + Minimized = false; + + if (!(wParam & SIZE_RESTORED)) + { + if (wParam & SIZE_MINIMIZED) + Minimized = true; + } + break; + + case WM_SYSCHAR: + // keep Alt-Space from happening + 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 (); + + if (!in_mode_set) + { + if (windc) + MGL_activatePalette(windc,true); + + VID_SetPalette(vid_curpal); + } + + break; + + case WM_PAINT: + hdc = BeginPaint(hWnd, &ps); + + if (!in_mode_set && host_initialized) + SCR_UpdateWholeScreen (); + + EndPaint(hWnd, &ps); + break; + + case WM_KEYDOWN: + case WM_SYSKEYDOWN: + if (!in_mode_set) + Key_Event (MapKey(lParam), true); + break; + + case WM_KEYUP: + case WM_SYSKEYUP: + if (!in_mode_set) + Key_Event (MapKey(lParam), false); + 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_MOUSEMOVE: + if (!in_mode_set) + { + temp = 0; + + if (wParam & MK_LBUTTON) + temp |= 1; + + if (wParam & MK_RBUTTON) + temp |= 2; + + if (wParam & MK_MBUTTON) + temp |= 4; + + 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; + // KJB: Added these new palette functions + case WM_PALETTECHANGED: + if ((HWND)wParam == hWnd) + break; + /* Fall through to WM_QUERYNEWPALETTE */ + case WM_QUERYNEWPALETTE: + hdc = GetDC(NULL); + + if (GetDeviceCaps(hdc, RASTERCAPS) & RC_PALETTE) + vid_palettized = true; + else + vid_palettized = false; + + ReleaseDC(NULL,hdc); + + scr_fullupdate = 0; + + if (vid_initialized && !in_mode_set && windc && MGL_activatePalette(windc,false) && !Minimized) + { + VID_SetPalette (vid_curpal); + InvalidateRect (mainwindow, NULL, false); + + // specifically required if WM_QUERYNEWPALETTE realizes a new palette + lRet = TRUE; + } + break; + + case WM_DISPLAYCHANGE: + if (!in_mode_set && (modestate == MS_WINDOWED) && !vid_fulldib_on_focus_mode) + { + force_mode_set = true; + VID_SetMode (vid_modenum, vid_curpal); + force_mode_set = false; + } + break; + + case WM_CLOSE: + // this causes Close in the right-click task bar menu not to work, but right + // now bad things happen if Close is handled in that case (garbage and a + // crash on Win95) + if (!in_mode_set) + { + if (MessageBox (mainwindow, "Are you sure you want to quit?", "Confirm Exit", + MB_YESNO | MB_SETFOREGROUND | MB_ICONQUESTION) == IDYES) + { + Sys_Quit (); + } + } + break; + + case MM_MCINOTIFY: + lRet = CDAudio_MessageHandler (hWnd, uMsg, wParam, lParam); + break; + + default: + /* pass all unhandled messages to DefWindowProc */ + lRet = DefWindowProc (hWnd, uMsg, wParam, lParam); + break; + } + + /* return 0 if handled message, 1 if not */ + return lRet; +} + + +extern void M_Menu_Options_f (void); +extern void M_Print (int cx, int cy, char *str); +extern void M_PrintWhite (int cx, int cy, char *str); +extern void M_DrawCharacter (int cx, int line, int num); +extern void M_DrawTransPic (int x, int y, qpic_t *pic); +extern void M_DrawPic (int x, int y, qpic_t *pic); + +static int vid_line, vid_wmodes; + +typedef struct +{ + int modenum; + char *desc; + int iscur; + int ismode13; + int width; +} modedesc_t; + +#define MAX_COLUMN_SIZE 5 +#define MODE_AREA_HEIGHT (MAX_COLUMN_SIZE + 6) +#define MAX_MODEDESCS (MAX_COLUMN_SIZE*3) + +static modedesc_t modedescs[MAX_MODEDESCS]; + +/* +================ +VID_MenuDraw +================ +*/ +void VID_MenuDraw (void) +{ + qpic_t *p; + char *ptr; + int lnummodes, i, j, k, column, row, dup, dupmode; + char temp[100]; + vmode_t *pv; + modedesc_t tmodedesc; + + p = Draw_CachePic ("gfx/vidmodes.lmp"); + M_DrawPic ( (320-p->width)/2, 4, p); + + for (i=0 ; i<3 ; i++) + { + ptr = VID_GetModeDescriptionMemCheck (i); + modedescs[i].modenum = modelist[i].modenum; + modedescs[i].desc = ptr; + modedescs[i].ismode13 = 0; + modedescs[i].iscur = 0; + + if (vid_modenum == i) + modedescs[i].iscur = 1; + } + + vid_wmodes = 3; + lnummodes = VID_NumModes (); + + for (i=3 ; iwidth != 360) || COM_CheckParm("-allow360"))) + { + dup = 0; + + for (j=3 ; jmode13; + modedescs[k].iscur = 0; + modedescs[k].width = pv->width; + + if (i == vid_modenum) + modedescs[k].iscur = 1; + + if (!dup) + vid_wmodes++; + } + } + } + } + +// sort the modes on width (to handle picking up oddball dibonly modes +// after all the others) + for (i=3 ; i<(vid_wmodes-1) ; i++) + { + for (j=(i+1) ; j modedescs[j].width) + { + tmodedesc = modedescs[i]; + modedescs[i] = modedescs[j]; + modedescs[j] = tmodedesc; + } + } + } + + + M_Print (13*8, 36, "Windowed Modes"); + + column = 16; + row = 36+2*8; + + for (i=0 ; i<3; i++) + { + if (modedescs[i].iscur) + M_PrintWhite (column, row, modedescs[i].desc); + else + M_Print (column, row, modedescs[i].desc); + + column += 13*8; + } + + if (vid_wmodes > 3) + { + M_Print (12*8, 36+4*8, "Fullscreen Modes"); + + column = 16; + row = 36+6*8; + + for (i=3 ; i= 3) + row += 3*8; + + M_DrawCharacter (column, row, 12+((int)(realtime*4)&1)); + } +} + + +/* +================ +VID_MenuKey +================ +*/ +void VID_MenuKey (int key) +{ + if (vid_testingmode) + return; + + switch (key) + { + case K_ESCAPE: + S_LocalSound ("misc/menu1.wav"); + M_Menu_Options_f (); + break; + + case K_LEFTARROW: + S_LocalSound ("misc/menu1.wav"); + vid_line = ((vid_line / VID_ROW_SIZE) * VID_ROW_SIZE) + + ((vid_line + 2) % VID_ROW_SIZE); + + if (vid_line >= vid_wmodes) + vid_line = vid_wmodes - 1; + break; + + case K_RIGHTARROW: + S_LocalSound ("misc/menu1.wav"); + vid_line = ((vid_line / VID_ROW_SIZE) * VID_ROW_SIZE) + + ((vid_line + 4) % VID_ROW_SIZE); + + if (vid_line >= vid_wmodes) + vid_line = (vid_line / VID_ROW_SIZE) * VID_ROW_SIZE; + break; + + case K_UPARROW: + S_LocalSound ("misc/menu1.wav"); + vid_line -= VID_ROW_SIZE; + + if (vid_line < 0) + { + vid_line += ((vid_wmodes + (VID_ROW_SIZE - 1)) / + VID_ROW_SIZE) * VID_ROW_SIZE; + + while (vid_line >= vid_wmodes) + vid_line -= VID_ROW_SIZE; + } + break; + + case K_DOWNARROW: + S_LocalSound ("misc/menu1.wav"); + vid_line += VID_ROW_SIZE; + + if (vid_line >= vid_wmodes) + { + vid_line -= ((vid_wmodes + (VID_ROW_SIZE - 1)) / + VID_ROW_SIZE) * VID_ROW_SIZE; + + while (vid_line < 0) + vid_line += VID_ROW_SIZE; + } + break; + + case K_ENTER: + S_LocalSound ("misc/menu1.wav"); + VID_SetMode (modedescs[vid_line].modenum, vid_curpal); + break; + + case 'T': + case 't': + S_LocalSound ("misc/menu1.wav"); + // have to set this before setting the mode because WM_PAINT + // happens during the mode set and does a VID_Update, which + // checks vid_testingmode + vid_testingmode = 1; + vid_testendtime = realtime + 5.0; + + if (!VID_SetMode (modedescs[vid_line].modenum, vid_curpal)) + { + vid_testingmode = 0; + } + break; + + case 'D': + case 'd': + S_LocalSound ("misc/menu1.wav"); + firstupdate = 0; + Cvar_SetValue ("_vid_default_mode_win", vid_modenum); + break; + + default: + break; + } +} diff --git a/contrib/other/sdlquake-1.0.9/vid_x.c b/contrib/other/sdlquake-1.0.9/vid_x.c new file mode 100644 index 000000000..5987b6c8f --- /dev/null +++ b/contrib/other/sdlquake-1.0.9/vid_x.c @@ -0,0 +1,1199 @@ +/* +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_x.c -- general x video driver + +#define _BSD + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "quakedef.h" +#include "d_local.h" + +cvar_t _windowed_mouse = {"_windowed_mouse","0", true}; +cvar_t m_filter = {"m_filter","0", true}; +float old_windowed_mouse; + +qboolean mouse_avail; +int mouse_buttons=3; +int mouse_oldbuttonstate; +int mouse_buttonstate; +float mouse_x, mouse_y; +float old_mouse_x, old_mouse_y; +int p_mouse_x; +int p_mouse_y; +int ignorenext; +int bits_per_pixel; + +typedef struct +{ + int input; + int output; +} keymap_t; + +viddef_t vid; // global video state +unsigned short d_8to16table[256]; + +int num_shades=32; + +int d_con_indirect = 0; + +int vid_buffersize; + +static qboolean doShm; +static Display *x_disp; +static Colormap x_cmap; +static Window x_win; +static GC x_gc; +static Visual *x_vis; +static XVisualInfo *x_visinfo; +//static XImage *x_image; + +static int x_shmeventtype; +//static XShmSegmentInfo x_shminfo; + +static qboolean oktodraw = false; + +int XShmQueryExtension(Display *); +int XShmGetEventBase(Display *); + +int current_framebuffer; +static XImage *x_framebuffer[2] = { 0, 0 }; +static XShmSegmentInfo x_shminfo[2]; + +static int verbose=0; + +static byte current_palette[768]; + +static long X11_highhunkmark; +static long X11_buffersize; + +int vid_surfcachesize; +void *vid_surfcache; + +void (*vid_menudrawfn)(void); +void (*vid_menukeyfn)(int key); +void VID_MenuKey (int key); + +typedef unsigned short PIXEL16; +typedef unsigned long PIXEL24; +static PIXEL16 st2d_8to16table[256]; +static PIXEL24 st2d_8to24table[256]; +static int shiftmask_fl=0; +static long r_shift,g_shift,b_shift; +static unsigned long r_mask,g_mask,b_mask; + +void shiftmask_init() +{ + unsigned int x; + r_mask=x_vis->red_mask; + g_mask=x_vis->green_mask; + b_mask=x_vis->blue_mask; + for(r_shift=-8,x=1;x0) { + p=(r<<(r_shift))&r_mask; + } else if(r_shift<0) { + p=(r>>(-r_shift))&r_mask; + } else p|=(r&r_mask); + + if(g_shift>0) { + p|=(g<<(g_shift))&g_mask; + } else if(g_shift<0) { + p|=(g>>(-g_shift))&g_mask; + } else p|=(g&g_mask); + + if(b_shift>0) { + p|=(b<<(b_shift))&b_mask; + } else if(b_shift<0) { + p|=(b>>(-b_shift))&b_mask; + } else p|=(b&b_mask); + + return p; +} + +PIXEL24 xlib_rgb24(int r,int g,int b) +{ + PIXEL24 p; + if(shiftmask_fl==0) shiftmask_init(); + p=0; + + if(r_shift>0) { + p=(r<<(r_shift))&r_mask; + } else if(r_shift<0) { + p=(r>>(-r_shift))&r_mask; + } else p|=(r&r_mask); + + if(g_shift>0) { + p|=(g<<(g_shift))&g_mask; + } else if(g_shift<0) { + p|=(g>>(-g_shift))&g_mask; + } else p|=(g&g_mask); + + if(b_shift>0) { + p|=(b<<(b_shift))&b_mask; + } else if(b_shift<0) { + p|=(b>>(-b_shift))&b_mask; + } else p|=(b&b_mask); + + return p; +} + +void st2_fixup( XImage *framebuf, int x, int y, int width, int height) +{ + int xi,yi; + unsigned char *src; + PIXEL16 *dest; + register int count, n; + + if( (x<0)||(y<0) )return; + + for (yi = y; yi < (y+height); yi++) { + src = &framebuf->data [yi * framebuf->bytes_per_line]; + + // Duff's Device + count = width; + n = (count + 7) / 8; + dest = ((PIXEL16 *)src) + x+width - 1; + src += x+width - 1; + + switch (count % 8) { + case 0: do { *dest-- = st2d_8to16table[*src--]; + case 7: *dest-- = st2d_8to16table[*src--]; + case 6: *dest-- = st2d_8to16table[*src--]; + case 5: *dest-- = st2d_8to16table[*src--]; + case 4: *dest-- = st2d_8to16table[*src--]; + case 3: *dest-- = st2d_8to16table[*src--]; + case 2: *dest-- = st2d_8to16table[*src--]; + case 1: *dest-- = st2d_8to16table[*src--]; + } while (--n > 0); + } + +// for(xi = (x+width-1); xi >= x; xi--) { +// dest[xi] = st2d_8to16table[src[xi]]; +// } + } +} + +void st3_fixup( XImage *framebuf, int x, int y, int width, int height) +{ + int xi,yi; + unsigned char *src; + PIXEL24 *dest; + register int count, n; + + if( (x<0)||(y<0) )return; + + for (yi = y; yi < (y+height); yi++) { + src = &framebuf->data [yi * framebuf->bytes_per_line]; + + // Duff's Device + count = width; + n = (count + 7) / 8; + dest = ((PIXEL24 *)src) + x+width - 1; + src += x+width - 1; + + switch (count % 8) { + case 0: do { *dest-- = st2d_8to24table[*src--]; + case 7: *dest-- = st2d_8to24table[*src--]; + case 6: *dest-- = st2d_8to24table[*src--]; + case 5: *dest-- = st2d_8to24table[*src--]; + case 4: *dest-- = st2d_8to24table[*src--]; + case 3: *dest-- = st2d_8to24table[*src--]; + case 2: *dest-- = st2d_8to24table[*src--]; + case 1: *dest-- = st2d_8to24table[*src--]; + } while (--n > 0); + } + +// for(xi = (x+width-1); xi >= x; xi--) { +// dest[xi] = st2d_8to16table[src[xi]]; +// } + } +} + + +// ======================================================================== +// Tragic death handler +// ======================================================================== + +void TragicDeath(int signal_num) +{ + XAutoRepeatOn(x_disp); + XCloseDisplay(x_disp); + Sys_Error("This death brought to you by the number %d\n", signal_num); +} + +// ======================================================================== +// makes a null cursor +// ======================================================================== + +static Cursor CreateNullCursor(Display *display, Window root) +{ + Pixmap cursormask; + XGCValues xgc; + GC gc; + XColor dummycolour; + Cursor cursor; + + cursormask = XCreatePixmap(display, root, 1, 1, 1/*depth*/); + xgc.function = GXclear; + gc = XCreateGC(display, cursormask, GCFunction, &xgc); + XFillRectangle(display, cursormask, gc, 0, 0, 1, 1); + dummycolour.pixel = 0; + dummycolour.red = 0; + dummycolour.flags = 04; + cursor = XCreatePixmapCursor(display, cursormask, cursormask, + &dummycolour,&dummycolour, 0,0); + XFreePixmap(display,cursormask); + XFreeGC(display,gc); + return cursor; +} + +void ResetFrameBuffer(void) +{ + int mem; + int pwidth; + + if (x_framebuffer[0]) + { + free(x_framebuffer[0]->data); + free(x_framebuffer[0]); + } + + if (d_pzbuffer) + { + D_FlushCaches (); + Hunk_FreeToHighMark (X11_highhunkmark); + d_pzbuffer = NULL; + } + X11_highhunkmark = Hunk_HighMark (); + +// alloc an extra line in case we want to wrap, and allocate the z-buffer + X11_buffersize = vid.width * vid.height * sizeof (*d_pzbuffer); + + vid_surfcachesize = D_SurfaceCacheForRes (vid.width, vid.height); + + X11_buffersize += vid_surfcachesize; + + d_pzbuffer = Hunk_HighAllocName (X11_buffersize, "video"); + if (d_pzbuffer == NULL) + Sys_Error ("Not enough memory for video mode\n"); + + vid_surfcache = (byte *) d_pzbuffer + + vid.width * vid.height * sizeof (*d_pzbuffer); + + D_InitCaches(vid_surfcache, vid_surfcachesize); + + pwidth = x_visinfo->depth / 8; + if (pwidth == 3) pwidth = 4; + mem = ((vid.width*pwidth+7)&~7) * vid.height; + + x_framebuffer[0] = XCreateImage( x_disp, + x_vis, + x_visinfo->depth, + ZPixmap, + 0, + malloc(mem), + vid.width, vid.height, + 32, + 0); + + if (!x_framebuffer[0]) + Sys_Error("VID: XCreateImage failed\n"); + + vid.buffer = (byte*) (x_framebuffer[0]); + vid.conbuffer = vid.buffer; + +} + +void ResetSharedFrameBuffers(void) +{ + + int size; + int key; + int minsize = getpagesize(); + int frm; + + if (d_pzbuffer) + { + D_FlushCaches (); + Hunk_FreeToHighMark (X11_highhunkmark); + d_pzbuffer = NULL; + } + + X11_highhunkmark = Hunk_HighMark (); + +// alloc an extra line in case we want to wrap, and allocate the z-buffer + X11_buffersize = vid.width * vid.height * sizeof (*d_pzbuffer); + + vid_surfcachesize = D_SurfaceCacheForRes (vid.width, vid.height); + + X11_buffersize += vid_surfcachesize; + + d_pzbuffer = Hunk_HighAllocName (X11_buffersize, "video"); + if (d_pzbuffer == NULL) + Sys_Error ("Not enough memory for video mode\n"); + + vid_surfcache = (byte *) d_pzbuffer + + vid.width * vid.height * sizeof (*d_pzbuffer); + + D_InitCaches(vid_surfcache, vid_surfcachesize); + + for (frm=0 ; frm<2 ; frm++) + { + + // free up old frame buffer memory + + if (x_framebuffer[frm]) + { + XShmDetach(x_disp, &x_shminfo[frm]); + free(x_framebuffer[frm]); + shmdt(x_shminfo[frm].shmaddr); + } + + // create the image + + x_framebuffer[frm] = XShmCreateImage( x_disp, + x_vis, + x_visinfo->depth, + ZPixmap, + 0, + &x_shminfo[frm], + vid.width, + vid.height ); + + // grab shared memory + + size = x_framebuffer[frm]->bytes_per_line + * x_framebuffer[frm]->height; + if (size < minsize) + Sys_Error("VID: Window must use at least %d bytes\n", minsize); + + key = random(); + x_shminfo[frm].shmid = shmget((key_t)key, size, IPC_CREAT|0777); + if (x_shminfo[frm].shmid==-1) + Sys_Error("VID: Could not get any shared memory\n"); + + // attach to the shared memory segment + x_shminfo[frm].shmaddr = + (void *) shmat(x_shminfo[frm].shmid, 0, 0); + + printf("VID: shared memory id=%d, addr=0x%lx\n", x_shminfo[frm].shmid, + (long) x_shminfo[frm].shmaddr); + + x_framebuffer[frm]->data = x_shminfo[frm].shmaddr; + + // get the X server to attach to it + + if (!XShmAttach(x_disp, &x_shminfo[frm])) + Sys_Error("VID: XShmAttach() failed\n"); + XSync(x_disp, 0); + shmctl(x_shminfo[frm].shmid, IPC_RMID, 0); + + } + +} + +// 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_Init (unsigned char *palette) +{ + + int pnum, i; + XVisualInfo template; + int num_visuals; + int template_mask; + + ignorenext=0; + vid.width = 320; + vid.height = 200; + vid.maxwarpwidth = WARP_WIDTH; + vid.maxwarpheight = WARP_HEIGHT; + vid.numpages = 2; + vid.colormap = host_colormap; + // vid.cbits = VID_CBITS; + // vid.grades = VID_GRADES; + vid.fullbright = 256 - LittleLong (*((int *)vid.colormap + 2048)); + + srandom(getpid()); + + verbose=COM_CheckParm("-verbose"); + +// open the display + x_disp = XOpenDisplay(0); + if (!x_disp) + { + if (getenv("DISPLAY")) + Sys_Error("VID: Could not open display [%s]\n", + getenv("DISPLAY")); + else + Sys_Error("VID: Could not open local display\n"); + } + +// catch signals so i can turn on auto-repeat + + { + struct sigaction sa; + sigaction(SIGINT, 0, &sa); + sa.sa_handler = TragicDeath; + sigaction(SIGINT, &sa, 0); + sigaction(SIGTERM, &sa, 0); + } + + XAutoRepeatOff(x_disp); + +// for debugging only + XSynchronize(x_disp, True); + +// check for command-line window size + if ((pnum=COM_CheckParm("-winsize"))) + { + if (pnum >= com_argc-2) + Sys_Error("VID: -winsize \n"); + vid.width = Q_atoi(com_argv[pnum+1]); + vid.height = Q_atoi(com_argv[pnum+2]); + if (!vid.width || !vid.height) + Sys_Error("VID: Bad window width/height\n"); + } + if ((pnum=COM_CheckParm("-width"))) { + if (pnum >= com_argc-1) + Sys_Error("VID: -width \n"); + vid.width = Q_atoi(com_argv[pnum+1]); + if (!vid.width) + Sys_Error("VID: Bad window width\n"); + } + if ((pnum=COM_CheckParm("-height"))) { + if (pnum >= com_argc-1) + Sys_Error("VID: -height \n"); + vid.height = Q_atoi(com_argv[pnum+1]); + if (!vid.height) + Sys_Error("VID: Bad window height\n"); + } + + template_mask = 0; + +// specify a visual id + if ((pnum=COM_CheckParm("-visualid"))) + { + if (pnum >= com_argc-1) + Sys_Error("VID: -visualid \n"); + template.visualid = Q_atoi(com_argv[pnum+1]); + template_mask = VisualIDMask; + } + +// If not specified, use default visual + else + { + int screen; + screen = XDefaultScreen(x_disp); + template.visualid = + XVisualIDFromVisual(XDefaultVisual(x_disp, screen)); + template_mask = VisualIDMask; + } + +// pick a visual- warn if more than one was available + x_visinfo = XGetVisualInfo(x_disp, template_mask, &template, &num_visuals); + if (num_visuals > 1) + { + printf("Found more than one visual id at depth %d:\n", template.depth); + for (i=0 ; ivisualid)); + printf(" screen %d\n", x_visinfo->screen); + printf(" red_mask 0x%x\n", (int)(x_visinfo->red_mask)); + printf(" green_mask 0x%x\n", (int)(x_visinfo->green_mask)); + printf(" blue_mask 0x%x\n", (int)(x_visinfo->blue_mask)); + printf(" colormap_size %d\n", x_visinfo->colormap_size); + printf(" bits_per_rgb %d\n", x_visinfo->bits_per_rgb); + } + + x_vis = x_visinfo->visual; + +// setup attributes for main window + { + int attribmask = CWEventMask | CWColormap | CWBorderPixel; + XSetWindowAttributes attribs; + Colormap tmpcmap; + + tmpcmap = XCreateColormap(x_disp, XRootWindow(x_disp, + x_visinfo->screen), x_vis, AllocNone); + + attribs.event_mask = StructureNotifyMask | KeyPressMask + | KeyReleaseMask | ExposureMask | PointerMotionMask | + ButtonPressMask | ButtonReleaseMask; + attribs.border_pixel = 0; + attribs.colormap = tmpcmap; + +// create the main window + x_win = XCreateWindow( x_disp, + XRootWindow(x_disp, x_visinfo->screen), + 0, 0, // x, y + vid.width, vid.height, + 0, // borderwidth + x_visinfo->depth, + InputOutput, + x_vis, + attribmask, + &attribs ); + XStoreName( x_disp,x_win,"xquake"); + + + if (x_visinfo->class != TrueColor) + XFreeColormap(x_disp, tmpcmap); + } + + if (x_visinfo->depth == 8) + { + // create and upload the palette + if (x_visinfo->class == PseudoColor) + { + x_cmap = XCreateColormap(x_disp, x_win, x_vis, AllocAll); + VID_SetPalette(palette); + XSetWindowColormap(x_disp, x_win, x_cmap); + } + } + +// inviso cursor + XDefineCursor(x_disp, x_win, CreateNullCursor(x_disp, x_win)); + +// create the GC + { + XGCValues xgcvalues; + int valuemask = GCGraphicsExposures; + xgcvalues.graphics_exposures = False; + x_gc = XCreateGC(x_disp, x_win, valuemask, &xgcvalues ); + } + +// map the window + XMapWindow(x_disp, x_win); + +// wait for first exposure event + { + XEvent event; + do + { + XNextEvent(x_disp, &event); + if (event.type == Expose && !event.xexpose.count) + oktodraw = true; + } while (!oktodraw); + } +// now safe to draw + +// even if MITSHM is available, make sure it's a local connection + if (XShmQueryExtension(x_disp)) + { + char *displayname; + doShm = true; + displayname = (char *) getenv("DISPLAY"); + if (displayname) + { + char *d = displayname; + while (*d && (*d != ':')) d++; + if (*d) *d = 0; + if (!(!strcasecmp(displayname, "unix") || !*displayname)) + doShm = false; + } + } + + if (doShm) + { + x_shmeventtype = XShmGetEventBase(x_disp) + ShmCompletion; + ResetSharedFrameBuffers(); + } + else + ResetFrameBuffer(); + + current_framebuffer = 0; + vid.rowbytes = x_framebuffer[0]->bytes_per_line; + vid.buffer = x_framebuffer[0]->data; + vid.direct = 0; + vid.conbuffer = x_framebuffer[0]->data; + vid.conrowbytes = vid.rowbytes; + vid.conwidth = vid.width; + vid.conheight = vid.height; + vid.aspect = ((float)vid.height / (float)vid.width) * (320.0 / 240.0); + +// XSynchronize(x_disp, False); + +} + +void VID_ShiftPalette(unsigned char *p) +{ + VID_SetPalette(p); +} + + + +void VID_SetPalette(unsigned char *palette) +{ + + int i; + XColor colors[256]; + + for(i=0;i<256;i++) { + st2d_8to16table[i]= xlib_rgb16(palette[i*3], palette[i*3+1],palette[i*3+2]); + st2d_8to24table[i]= xlib_rgb24(palette[i*3], palette[i*3+1],palette[i*3+2]); + } + + if (x_visinfo->class == PseudoColor && x_visinfo->depth == 8) + { + if (palette != current_palette) + memcpy(current_palette, palette, 768); + for (i=0 ; i<256 ; i++) + { + colors[i].pixel = i; + colors[i].flags = DoRed|DoGreen|DoBlue; + colors[i].red = palette[i*3] * 257; + colors[i].green = palette[i*3+1] * 257; + colors[i].blue = palette[i*3+2] * 257; + } + XStoreColors(x_disp, x_cmap, colors, 256); + } + +} + +// Called at shutdown + +void VID_Shutdown (void) +{ + Con_Printf("VID_Shutdown\n"); + XAutoRepeatOn(x_disp); + XCloseDisplay(x_disp); +} + +int XLateKey(XKeyEvent *ev) +{ + + int key; + char buf[64]; + KeySym keysym; + + key = 0; + + XLookupString(ev, buf, sizeof buf, &keysym, 0); + + switch(keysym) + { + case XK_KP_Page_Up: + case XK_Page_Up: key = K_PGUP; break; + + case XK_KP_Page_Down: + case XK_Page_Down: key = K_PGDN; break; + + case XK_KP_Home: + case XK_Home: key = K_HOME; break; + + case XK_KP_End: + case XK_End: key = K_END; break; + + case XK_KP_Left: + case XK_Left: key = K_LEFTARROW; break; + + case XK_KP_Right: + case XK_Right: key = K_RIGHTARROW; break; + + case XK_KP_Down: + case XK_Down: key = K_DOWNARROW; break; + + case XK_KP_Up: + case XK_Up: key = K_UPARROW; break; + + case XK_Escape: key = K_ESCAPE; break; + + case XK_KP_Enter: + case XK_Return: key = K_ENTER; break; + + case XK_Tab: key = K_TAB; break; + + case XK_F1: key = K_F1; break; + + case XK_F2: key = K_F2; break; + + case XK_F3: key = K_F3; break; + + case XK_F4: key = K_F4; break; + + case XK_F5: key = K_F5; break; + + case XK_F6: key = K_F6; break; + + case XK_F7: key = K_F7; break; + + case XK_F8: key = K_F8; break; + + case XK_F9: key = K_F9; break; + + case XK_F10: key = K_F10; break; + + case XK_F11: key = K_F11; break; + + case XK_F12: key = K_F12; break; + + case XK_BackSpace: key = K_BACKSPACE; break; + + case XK_KP_Delete: + case XK_Delete: key = K_DEL; break; + + case XK_Pause: key = K_PAUSE; break; + + case XK_Shift_L: + case XK_Shift_R: key = K_SHIFT; break; + + case XK_Execute: + case XK_Control_L: + case XK_Control_R: key = K_CTRL; break; + + case XK_Alt_L: + case XK_Meta_L: + case XK_Alt_R: + case XK_Meta_R: key = K_ALT; break; + + case XK_KP_Begin: key = K_AUX30; break; + + case XK_Insert: + case XK_KP_Insert: key = K_INS; break; + + case XK_KP_Multiply: key = '*'; break; + case XK_KP_Add: key = '+'; break; + case XK_KP_Subtract: key = '-'; break; + case XK_KP_Divide: key = '/'; break; + +#if 0 + case 0x021: key = '1';break;/* [!] */ + case 0x040: key = '2';break;/* [@] */ + case 0x023: key = '3';break;/* [#] */ + case 0x024: key = '4';break;/* [$] */ + case 0x025: key = '5';break;/* [%] */ + case 0x05e: key = '6';break;/* [^] */ + case 0x026: key = '7';break;/* [&] */ + case 0x02a: key = '8';break;/* [*] */ + case 0x028: key = '9';;break;/* [(] */ + case 0x029: key = '0';break;/* [)] */ + case 0x05f: key = '-';break;/* [_] */ + case 0x02b: key = '=';break;/* [+] */ + case 0x07c: key = '\'';break;/* [|] */ + case 0x07d: key = '[';break;/* [}] */ + case 0x07b: key = ']';break;/* [{] */ + case 0x022: key = '\'';break;/* ["] */ + case 0x03a: key = ';';break;/* [:] */ + case 0x03f: key = '/';break;/* [?] */ + case 0x03e: key = '.';break;/* [>] */ + case 0x03c: key = ',';break;/* [<] */ +#endif + + default: + key = *(unsigned char*)buf; + if (key >= 'A' && key <= 'Z') + key = key - 'A' + 'a'; +// fprintf(stdout, "case 0x0%x: key = ___;break;/* [%c] */\n", keysym); + break; + } + + return key; +} + +struct +{ + int key; + int down; +} keyq[64]; +int keyq_head=0; +int keyq_tail=0; + +int config_notify=0; +int config_notify_width; +int config_notify_height; + +void GetEvent(void) +{ + XEvent x_event; + int b; + + XNextEvent(x_disp, &x_event); + switch(x_event.type) { + case KeyPress: + keyq[keyq_head].key = XLateKey(&x_event.xkey); + keyq[keyq_head].down = true; + keyq_head = (keyq_head + 1) & 63; + break; + case KeyRelease: + keyq[keyq_head].key = XLateKey(&x_event.xkey); + keyq[keyq_head].down = false; + keyq_head = (keyq_head + 1) & 63; + break; + + case MotionNotify: + if (_windowed_mouse.value) { + mouse_x = (float) ((int)x_event.xmotion.x - (int)(vid.width/2)); + mouse_y = (float) ((int)x_event.xmotion.y - (int)(vid.height/2)); +//printf("m: x=%d,y=%d, mx=%3.2f,my=%3.2f\n", +// x_event.xmotion.x, x_event.xmotion.y, mouse_x, mouse_y); + + /* move the mouse to the window center again */ + XSelectInput(x_disp,x_win,StructureNotifyMask|KeyPressMask + |KeyReleaseMask|ExposureMask + |ButtonPressMask + |ButtonReleaseMask); + XWarpPointer(x_disp,None,x_win,0,0,0,0, + (vid.width/2),(vid.height/2)); + XSelectInput(x_disp,x_win,StructureNotifyMask|KeyPressMask + |KeyReleaseMask|ExposureMask + |PointerMotionMask|ButtonPressMask + |ButtonReleaseMask); + } else { + mouse_x = (float) (x_event.xmotion.x-p_mouse_x); + mouse_y = (float) (x_event.xmotion.y-p_mouse_y); + p_mouse_x=x_event.xmotion.x; + p_mouse_y=x_event.xmotion.y; + } + break; + + case ButtonPress: + b=-1; + if (x_event.xbutton.button == 1) + b = 0; + else if (x_event.xbutton.button == 2) + b = 2; + else if (x_event.xbutton.button == 3) + b = 1; + if (b>=0) + mouse_buttonstate |= 1<=0) + mouse_buttonstate &= ~(1<bytes_per_line; + vid.buffer = x_framebuffer[current_framebuffer]->data; + vid.conbuffer = vid.buffer; + vid.conwidth = vid.width; + vid.conheight = vid.height; + vid.conrowbytes = vid.rowbytes; + vid.recalc_refdef = 1; // force a surface cache flush + Con_CheckResize(); + Con_Clear_f(); + return; + } + + // force full update if not 8bit + if (x_visinfo->depth != 8) { + extern int scr_fullupdate; + + scr_fullupdate = 0; + } + + + if (doShm) + { + + while (rects) + { + if (x_visinfo->depth == 16) + st2_fixup( x_framebuffer[current_framebuffer], + rects->x, rects->y, rects->width, + rects->height); + else if (x_visinfo->depth == 24) + st3_fixup( x_framebuffer[current_framebuffer], + rects->x, rects->y, rects->width, + rects->height); + if (!XShmPutImage(x_disp, x_win, x_gc, + x_framebuffer[current_framebuffer], rects->x, rects->y, + rects->x, rects->y, rects->width, rects->height, True)) + Sys_Error("VID_Update: XShmPutImage failed\n"); + oktodraw = false; + while (!oktodraw) GetEvent(); + rects = rects->pnext; + } + current_framebuffer = !current_framebuffer; + vid.buffer = x_framebuffer[current_framebuffer]->data; + vid.conbuffer = vid.buffer; + XSync(x_disp, False); + } + else + { + while (rects) + { + if (x_visinfo->depth == 16) + st2_fixup( x_framebuffer[current_framebuffer], + rects->x, rects->y, rects->width, + rects->height); + else if (x_visinfo->depth == 24) + st3_fixup( x_framebuffer[current_framebuffer], + rects->x, rects->y, rects->width, + rects->height); + XPutImage(x_disp, x_win, x_gc, x_framebuffer[0], rects->x, + rects->y, rects->x, rects->y, rects->width, rects->height); + rects = rects->pnext; + } + XSync(x_disp, False); + } + +} + +static int dither; + +void VID_DitherOn(void) +{ + if (dither == 0) + { + vid.recalc_refdef = 1; + dither = 1; + } +} + +void VID_DitherOff(void) +{ + if (dither) + { + vid.recalc_refdef = 1; + dither = 0; + } +} + +int Sys_OpenWindow(void) +{ + return 0; +} + +void Sys_EraseWindow(int window) +{ +} + +void Sys_DrawCircle(int window, int x, int y, int r) +{ +} + +void Sys_DisplayWindow(int window) +{ +} + +void Sys_SendKeyEvents(void) +{ +// get events from x server + if (x_disp) + { + while (XPending(x_disp)) GetEvent(); + while (keyq_head != keyq_tail) + { + Key_Event(keyq[keyq_tail].key, keyq[keyq_tail].down); + keyq_tail = (keyq_tail + 1) & 63; + } + } +} + +#if 0 +char *Sys_ConsoleInput (void) +{ + + static char text[256]; + int len; + fd_set readfds; + int ready; + struct timeval timeout; + + timeout.tv_sec = 0; + timeout.tv_usec = 0; + FD_ZERO(&readfds); + FD_SET(0, &readfds); + ready = select(1, &readfds, 0, 0, &timeout); + + if (ready>0) + { + len = read (0, text, sizeof(text)); + if (len >= 1) + { + text[len-1] = 0; // rip off the /n and terminate + return text; + } + } + + return 0; + +} +#endif + +void D_BeginDirectRect (int x, int y, byte *pbitmap, int width, int height) +{ +// direct drawing of the "accessing disk" icon isn't supported under Linux +} + +void D_EndDirectRect (int x, int y, int width, int height) +{ +// direct drawing of the "accessing disk" icon isn't supported under Linux +} + +void IN_Init (void) +{ + Cvar_RegisterVariable (&_windowed_mouse); + Cvar_RegisterVariable (&m_filter); + if ( COM_CheckParm ("-nomouse") ) + return; + mouse_x = mouse_y = 0.0; + mouse_avail = 1; +} + +void IN_Shutdown (void) +{ + mouse_avail = 0; +} + +void IN_Commands (void) +{ + int i; + + if (!mouse_avail) return; + + for (i=0 ; isidemove += m_side.value * mouse_x; + else + cl.viewangles[YAW] -= m_yaw.value * mouse_x; + if (in_mlook.state & 1) + V_StopPitchDrift (); + + if ( (in_mlook.state & 1) && !(in_strafe.state & 1)) { + 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; + } + mouse_x = mouse_y = 0.0; +} diff --git a/contrib/other/sdlquake-1.0.9/view.c b/contrib/other/sdlquake-1.0.9/view.c new file mode 100644 index 000000000..ececf8c54 --- /dev/null +++ b/contrib/other/sdlquake-1.0.9/view.c @@ -0,0 +1,1113 @@ +/* +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. + +*/ +// view.c -- player eye positioning + +#include "quakedef.h" +#include "r_local.h" + +/* + +The view is allowed to move slightly from it's true position for bobbing, +but if it exceeds 8 pixels linear distance (spherical, not box), the list of +entities sent from the server may not include everything in the pvs, especially +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", 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_t cl_rollangle = {"cl_rollangle", "2.0"}; + +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", 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", 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", false}; + +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", false}; + +float v_dmg_time, v_dmg_roll, v_dmg_pitch; + +extern int in_forward, in_forward2, in_back; + + +/* +=============== +V_CalcRoll + +Used by view and sv_user +=============== +*/ +vec3_t forward, right, up; + +float V_CalcRoll (vec3_t angles, vec3_t velocity) +{ + 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; + + if (side < cl_rollspeed.value) + side = side * value / cl_rollspeed.value; + else + side = value; + + return side*sign; + +} + + +/* +=============== +V_CalcBob + +=============== +*/ +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) + cycle = M_PI * cycle / cl_bobup.value; + else + cycle = M_PI + M_PI*(cycle-cl_bobup.value)/(1.0 - cl_bobup.value); + +// bob is proportional to velocity in the xy plane +// (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)); + bob = bob*0.3 + bob*0.7*sin(cycle); + if (bob > 4) + bob = 4; + else if (bob < -7) + bob = -7; + return bob; + +} + + +//============================================================================= + + +cvar_t v_centermove = {"v_centermove", "0.15", false}; +cvar_t v_centerspeed = {"v_centerspeed","500"}; + + +void V_StartPitchDrift (void) +{ +#if 1 + if (cl.laststop == cl.time) + { + return; // something else is keeping it from drifting + } +#endif + if (cl.nodrift || !cl.pitchvel) + { + cl.pitchvel = v_centerspeed.value; + cl.nodrift = false; + cl.driftmove = 0; + } +} + +void V_StopPitchDrift (void) +{ + cl.laststop = cl.time; + cl.nodrift = true; + cl.pitchvel = 0; +} + +/* +=============== +V_DriftPitch + +Moves the client pitch angle towards cl.idealpitch sent by the server. + +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 +=============== +*/ +void V_DriftPitch (void) +{ + float delta, move; + + if (noclip_anglehack || !cl.onground || cls.demoplayback ) + { + cl.driftmove = 0; + cl.pitchvel = 0; + return; + } + +// don't count small mouse motion + if (cl.nodrift) + { + if ( fabs(cl.cmd.forwardmove) < cl_forwardspeed.value) + cl.driftmove = 0; + else + cl.driftmove += host_frametime; + + if ( cl.driftmove > v_centermove.value) + { + V_StartPitchDrift (); + } + return; + } + + delta = cl.idealpitch - cl.viewangles[PITCH]; + + if (!delta) + { + cl.pitchvel = 0; + return; + } + + move = host_frametime * cl.pitchvel; + cl.pitchvel += host_frametime * v_centerspeed.value; + +//Con_Printf ("move: %f (%f)\n", move, host_frametime); + + if (delta > 0) + { + if (move > delta) + { + cl.pitchvel = 0; + move = delta; + } + cl.viewangles[PITCH] += move; + } + else if (delta < 0) + { + if (move > -delta) + { + cl.pitchvel = 0; + move = -delta; + } + cl.viewangles[PITCH] -= move; + } +} + + + + + +/* +============================================================================== + + 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 }; + +cvar_t v_gamma = {"gamma", "1", true}; + +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 +================= +*/ +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; +} + + + +/* +=============== +V_ParseDamage +=============== +*/ +void V_ParseDamage (void) +{ + int armor, blood; + vec3_t from; + int i; + vec3_t forward, right, up; + entity_t *ent; + float side; + float count; + + armor = MSG_ReadByte (); + blood = MSG_ReadByte (); + for (i=0 ; i<3 ; i++) + from[i] = MSG_ReadCoord (); + + count = blood*0.5 + armor*0.5; + if (count < 10) + count = 10; + + cl.faceanimtime = cl.time + 0.2; // but sbar face into pain frame + + cl.cshifts[CSHIFT_DAMAGE].percent += 3*count; + if (cl.cshifts[CSHIFT_DAMAGE].percent < 0) + cl.cshifts[CSHIFT_DAMAGE].percent = 0; + if (cl.cshifts[CSHIFT_DAMAGE].percent > 150) + cl.cshifts[CSHIFT_DAMAGE].percent = 150; + + if (armor > blood) + { + cl.cshifts[CSHIFT_DAMAGE].destcolor[0] = 200; + cl.cshifts[CSHIFT_DAMAGE].destcolor[1] = 100; + cl.cshifts[CSHIFT_DAMAGE].destcolor[2] = 100; + } + else if (armor) + { + cl.cshifts[CSHIFT_DAMAGE].destcolor[0] = 220; + cl.cshifts[CSHIFT_DAMAGE].destcolor[1] = 50; + cl.cshifts[CSHIFT_DAMAGE].destcolor[2] = 50; + } + else + { + cl.cshifts[CSHIFT_DAMAGE].destcolor[0] = 255; + cl.cshifts[CSHIFT_DAMAGE].destcolor[1] = 0; + cl.cshifts[CSHIFT_DAMAGE].destcolor[2] = 0; + } + +// +// 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; + + v_dmg_time = v_kicktime.value; +} + + +/* +================== +V_cshift_f +================== +*/ +void V_cshift_f (void) +{ + cshift_empty.destcolor[0] = atoi(Cmd_Argv(1)); + cshift_empty.destcolor[1] = atoi(Cmd_Argv(2)); + cshift_empty.destcolor[2] = atoi(Cmd_Argv(3)); + cshift_empty.percent = atoi(Cmd_Argv(4)); +} + + +/* +================== +V_BonusFlash_f + +When you run over an item, the server sends this command +================== +*/ +void V_BonusFlash_f (void) +{ + cl.cshifts[CSHIFT_BONUS].destcolor[0] = 215; + cl.cshifts[CSHIFT_BONUS].destcolor[1] = 186; + cl.cshifts[CSHIFT_BONUS].destcolor[2] = 69; + cl.cshifts[CSHIFT_BONUS].percent = 50; +} + +/* +============= +V_SetContentsColor + +Underwater, lava, etc each has a color shift +============= +*/ +void V_SetContentsColor (int contents) +{ + switch (contents) + { + case CONTENTS_EMPTY: + case CONTENTS_SOLID: + cl.cshifts[CSHIFT_CONTENTS] = cshift_empty; + break; + case CONTENTS_LAVA: + cl.cshifts[CSHIFT_CONTENTS] = cshift_lava; + break; + case CONTENTS_SLIME: + cl.cshifts[CSHIFT_CONTENTS] = cshift_slime; + break; + default: + cl.cshifts[CSHIFT_CONTENTS] = cshift_water; + } +} + +/* +============= +V_CalcPowerupCshift +============= +*/ +void V_CalcPowerupCshift (void) +{ + if (cl.items & IT_QUAD) + { + cl.cshifts[CSHIFT_POWERUP].destcolor[0] = 0; + cl.cshifts[CSHIFT_POWERUP].destcolor[1] = 0; + cl.cshifts[CSHIFT_POWERUP].destcolor[2] = 255; + cl.cshifts[CSHIFT_POWERUP].percent = 30; + } + else if (cl.items & IT_SUIT) + { + cl.cshifts[CSHIFT_POWERUP].destcolor[0] = 0; + cl.cshifts[CSHIFT_POWERUP].destcolor[1] = 255; + cl.cshifts[CSHIFT_POWERUP].destcolor[2] = 0; + cl.cshifts[CSHIFT_POWERUP].percent = 20; + } + else if (cl.items & IT_INVISIBILITY) + { + cl.cshifts[CSHIFT_POWERUP].destcolor[0] = 100; + cl.cshifts[CSHIFT_POWERUP].destcolor[1] = 100; + cl.cshifts[CSHIFT_POWERUP].destcolor[2] = 100; + cl.cshifts[CSHIFT_POWERUP].percent = 100; + } + else if (cl.items & IT_INVULNERABILITY) + { + cl.cshifts[CSHIFT_POWERUP].destcolor[0] = 255; + cl.cshifts[CSHIFT_POWERUP].destcolor[1] = 255; + cl.cshifts[CSHIFT_POWERUP].destcolor[2] = 0; + cl.cshifts[CSHIFT_POWERUP].percent = 30; + } + else + cl.cshifts[CSHIFT_POWERUP].percent = 0; +} + +/* +============= +V_CalcBlend +============= +*/ +#ifdef GLQUAKE +void V_CalcBlend (void) +{ + float r, g, b, a, a2; + int j; + + r = 0; + g = 0; + b = 0; + a = 0; + + for (j=0 ; j 1) + v_blend[3] = 1; + if (v_blend[3] < 0) + v_blend[3] = 0; +} +#endif + +/* +============= +V_UpdatePalette +============= +*/ +#ifdef GLQUAKE +void V_UpdatePalette (void) +{ + int i, j; + qboolean new; + byte *basepal, *newpal; + byte pal[768]; + float r,g,b,a; + int ir, ig, ib; + qboolean force; + + V_CalcPowerupCshift (); + + new = 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]; + } + + 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; + } + + 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; + + 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); +} +#endif // !GLQUAKE + + +/* +============================================================================== + + VIEW RENDERING + +============================================================================== +*/ + +float angledelta (float a) +{ + a = anglemod(a); + if (a > 180) + a -= 360; + return a; +} + +/* +================== +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]; + + yaw = angledelta(yaw - r_refdef.viewangles[YAW]) * 0.4; + if (yaw > 10) + yaw = 10; + if (yaw < -10) + yaw = -10; + pitch = angledelta(-pitch - r_refdef.viewangles[PITCH]) * 0.4; + if (pitch > 10) + pitch = 10; + if (pitch < -10) + pitch = -10; + move = host_frametime*20; + if (yaw > oldyaw) + { + if (oldyaw + move < yaw) + yaw = oldyaw + move; + } + else + { + if (oldyaw - move > yaw) + yaw = oldyaw - move; + } + + if (pitch > oldpitch) + { + if (oldpitch + move < pitch) + pitch = oldpitch + move; + } + else + { + if (oldpitch - move > pitch) + pitch = oldpitch - move; + } + + oldyaw = yaw; + oldpitch = pitch; + + cl.viewent.angles[YAW] = r_refdef.viewangles[YAW] + yaw; + cl.viewent.angles[PITCH] = - (r_refdef.viewangles[PITCH] + pitch); + + cl.viewent.angles[ROLL] -= v_idlescale.value * sin(cl.time*v_iroll_cycle.value) * v_iroll_level.value; + cl.viewent.angles[PITCH] -= v_idlescale.value * sin(cl.time*v_ipitch_cycle.value) * v_ipitch_level.value; + cl.viewent.angles[YAW] -= v_idlescale.value * sin(cl.time*v_iyaw_cycle.value) * v_iyaw_level.value; +} + +/* +============== +V_BoundOffsets +============== +*/ +void V_BoundOffsets (void) +{ + entity_t *ent; + + ent = &cl_entities[cl.viewentity]; + +// absolutely bound refresh reletive to entity clipping hull +// so the view can never be inside a solid wall + + if (r_refdef.vieworg[0] < ent->origin[0] - 14) + 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) + r_refdef.vieworg[2] = ent->origin[2] + 30; +} + +/* +============== +V_AddIdle + +Idle swaying +============== +*/ +void V_AddIdle (void) +{ + r_refdef.viewangles[ROLL] += v_idlescale.value * sin(cl.time*v_iroll_cycle.value) * v_iroll_level.value; + r_refdef.viewangles[PITCH] += v_idlescale.value * sin(cl.time*v_ipitch_cycle.value) * v_ipitch_level.value; + r_refdef.viewangles[YAW] += v_idlescale.value * sin(cl.time*v_iyaw_cycle.value) * v_iyaw_level.value; +} + + +/* +============== +V_CalcViewRoll + +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; + + if (v_dmg_time > 0) + { + r_refdef.viewangles[ROLL] += v_dmg_time/v_kicktime.value*v_dmg_roll; + r_refdef.viewangles[PITCH] += v_dmg_time/v_kicktime.value*v_dmg_pitch; + v_dmg_time -= host_frametime; + } + + if (cl.stats[STAT_HEALTH] <= 0) + { + r_refdef.viewangles[ROLL] = 80; // dead view angle + return; + } + +} + + +/* +================== +V_CalcIntermissionRefdef + +================== +*/ +void V_CalcIntermissionRefdef (void) +{ + entity_t *ent, *view; + float old; + +// ent is the player model (visible when out of body) + ent = &cl_entities[cl.viewentity]; +// view is the weapon model (only visible from inside body) + view = &cl.viewent; + + VectorCopy (ent->origin, r_refdef.vieworg); + VectorCopy (ent->angles, r_refdef.viewangles); + view->model = NULL; + +// allways idle in intermission + old = v_idlescale.value; + v_idlescale.value = 1; + V_AddIdle (); + v_idlescale.value = old; +} + +/* +================== +V_CalcRefdef + +================== +*/ +void V_CalcRefdef (void) +{ + entity_t *ent, *view; + int i; + vec3_t forward, right, up; + vec3_t angles; + float bob; + static float oldz = 0; + + V_DriftPitch (); + +// ent is the player model (visible when out of body) + 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 + + + bob = V_CalcBob (); + +// refresh position + VectorCopy (ent->origin, r_refdef.vieworg); + r_refdef.vieworg[2] += cl.viewheight + bob; + +// never let it sit exactly on a node line, because a water plane can +// dissapear when viewed with the eye exactly on it. +// the server protocol only specifies to 1/16 pixel, so add 1/32 in each axis + r_refdef.vieworg[0] += 1.0/32; + r_refdef.vieworg[1] += 1.0/32; + r_refdef.vieworg[2] += 1.0/32; + + VectorCopy (cl.viewangles, r_refdef.viewangles); + V_CalcViewRoll (); + V_AddIdle (); + +// offsets + 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]; + + + 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++) + { + view->origin[i] += forward[i]*bob*0.4; +// view->origin[i] += right[i]*bob*0.4; +// view->origin[i] += up[i]*bob*0.8; + } + 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 + 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); + +// smooth out stair step ups +if (cl.onground && ent->origin[2] - oldz > 0) +{ + float steptime; + + steptime = cl.time - cl.oldtime; + if (steptime < 0) +//FIXME I_Error ("steptime < 0"); + steptime = 0; + + oldz += steptime * 80; + if (oldz > ent->origin[2]) + oldz = ent->origin[2]; + if (ent->origin[2] - oldz > 12) + oldz = ent->origin[2] - 12; + r_refdef.vieworg[2] += oldz - ent->origin[2]; + view->origin[2] += oldz - ent->origin[2]; +} +else + oldz = ent->origin[2]; + + if (chase_active.value) + Chase_Update (); +} + +/* +================== +V_RenderView + +The player's clipping box goes from (-16 -16 -24) to (16 16 32) from +the entity origin, so any view position inside that will be valid +================== +*/ +extern vrect_t scr_vrect; + +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 (); + + 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 (); + + vid.buffer -= vid.rowbytes>>1; + + r_refdef.vrect.height <<= 1; + + 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 + +} + +//============================================================================ + +/* +============= +V_Init +============= +*/ +void V_Init (void) +{ + 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); + + Cvar_RegisterVariable (&v_iyaw_cycle); + Cvar_RegisterVariable (&v_iroll_cycle); + Cvar_RegisterVariable (&v_ipitch_cycle); + Cvar_RegisterVariable (&v_iyaw_level); + Cvar_RegisterVariable (&v_iroll_level); + Cvar_RegisterVariable (&v_ipitch_level); + + Cvar_RegisterVariable (&v_idlescale); + Cvar_RegisterVariable (&crosshair); + Cvar_RegisterVariable (&cl_crossx); + Cvar_RegisterVariable (&cl_crossy); + Cvar_RegisterVariable (&gl_cshiftpercent); + + Cvar_RegisterVariable (&scr_ofsx); + Cvar_RegisterVariable (&scr_ofsy); + Cvar_RegisterVariable (&scr_ofsz); + Cvar_RegisterVariable (&cl_rollspeed); + Cvar_RegisterVariable (&cl_rollangle); + Cvar_RegisterVariable (&cl_bob); + Cvar_RegisterVariable (&cl_bobcycle); + Cvar_RegisterVariable (&cl_bobup); + + Cvar_RegisterVariable (&v_kicktime); + Cvar_RegisterVariable (&v_kickroll); + Cvar_RegisterVariable (&v_kickpitch); + + BuildGammaTable (1.0); // no gamma yet + Cvar_RegisterVariable (&v_gamma); +} + + diff --git a/contrib/other/sdlquake-1.0.9/view.h b/contrib/other/sdlquake-1.0.9/view.h new file mode 100644 index 000000000..82123a1c1 --- /dev/null +++ b/contrib/other/sdlquake-1.0.9/view.h @@ -0,0 +1,35 @@ +/* +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. + +*/ +// view.h + +extern cvar_t v_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; + + +void V_Init (void); +void V_RenderView (void); +float V_CalcRoll (vec3_t angles, vec3_t velocity); +void V_UpdatePalette (void); + diff --git a/contrib/other/sdlquake-1.0.9/vregset.c b/contrib/other/sdlquake-1.0.9/vregset.c new file mode 100644 index 000000000..ce009c8be --- /dev/null +++ b/contrib/other/sdlquake-1.0.9/vregset.c @@ -0,0 +1,81 @@ +/* +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. + +*/ +// +// vregset.c: video register-setting interpreter +// + +#include +#include + +#include "quakedef.h" +#include "vregset.h" + +//#define outportb loutportb + +void loutportb (int port, int val) +{ + printf ("port, val: %x %x\n", port, val); + getch (); +} + +/* +================ +VideoRegisterSet +================ +*/ +void VideoRegisterSet (int *pregset) +{ + int port, temp0, temp1, temp2; + + for ( ;; ) + { + switch (*pregset++) + { + case VRS_END: + return; + + case VRS_BYTE_OUT: + port = *pregset++; + outportb (port, *pregset++); + break; + + case VRS_BYTE_RMW: + port = *pregset++; + temp0 = *pregset++; + temp1 = *pregset++; + temp2 = inportb (port); + temp2 &= temp0; + temp2 |= temp1; + outportb (port, temp2); + break; + + case VRS_WORD_OUT: + port = *pregset++; + outportb (port, *pregset & 0xFF); + outportb (port+1, *pregset >> 8); + pregset++; + break; + + default: + Sys_Error ("VideoRegisterSet: Invalid command\n"); + } + } +} + diff --git a/contrib/other/sdlquake-1.0.9/vregset.h b/contrib/other/sdlquake-1.0.9/vregset.h new file mode 100644 index 000000000..822c76c20 --- /dev/null +++ b/contrib/other/sdlquake-1.0.9/vregset.h @@ -0,0 +1,56 @@ +/* +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. + +*/ +// +// vregset.h: header file for video register-setting interpreter +// + +// +// registers & subregisters +// +#define MISC_OUTPUT 0x3C2 + +#define SC_INDEX 0x3C4 +#define SC_DATA 0x3C5 +#define SYNC_RESET 0 +#define MAP_MASK 2 +#define MEMORY_MODE 4 + +#define GC_INDEX 0x3CE +#define GC_DATA 0x3CF +#define READ_MAP 4 +#define GRAPHICS_MODE 5 +#define MISCELLANOUS 6 + +#define CRTC_INDEX 0x3D4 +#define CRTC_DATA 0x3D5 +#define MAX_SCAN_LINE 9 +#define UNDERLINE 0x14 +#define MODE_CONTROL 0x17 + +// +// register-set commands +// +#define VRS_END 0 +#define VRS_BYTE_OUT 1 +#define VRS_BYTE_RMW 2 +#define VRS_WORD_OUT 3 + +void VideoRegisterSet (int *pregset); + diff --git a/contrib/other/sdlquake-1.0.9/wad.c b/contrib/other/sdlquake-1.0.9/wad.c new file mode 100644 index 000000000..c84f72c6d --- /dev/null +++ b/contrib/other/sdlquake-1.0.9/wad.c @@ -0,0 +1,158 @@ +/* +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. + +*/ +// wad.c + +#include "quakedef.h" + +int wad_numlumps; +lumpinfo_t *wad_lumps; +byte *wad_base; + +void SwapPic (qpic_t *pic); + +/* +================== +W_CleanupName + +Lowercases name and pads with spaces and a terminating 0 to the length of +lumpinfo_t->name. +Used so lumpname lookups can proceed rapidly by comparing 4 chars at a time +Space padding is so names can be printed nicely in tables. +Can safely be performed in place. +================== +*/ +void W_CleanupName (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) +{ + lumpinfo_t *lump_p; + wadinfo_t *header; + unsigned i; + int infotableofs; + + wad_base = COM_LoadHunkFile (filename); + if (!wad_base) + Sys_Error ("W_LoadWadFile: couldn't load %s", filename); + + header = (wadinfo_t *)wad_base; + + 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); + if (lump_p->type == TYP_QPIC) + SwapPic ( (qpic_t *)(wad_base + lump_p->filepos)); + } +} + + +/* +============= +W_GetLumpinfo +============= +*/ +lumpinfo_t *W_GetLumpinfo (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); + return NULL; +} + +void *W_GetLumpName (char *name) +{ + lumpinfo_t *lump; + + lump = W_GetLumpinfo (name); + + 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); +} + +/* +============================================================================= + +automatic byte swapping + +============================================================================= +*/ + +void SwapPic (qpic_t *pic) +{ + pic->width = LittleLong(pic->width); + pic->height = LittleLong(pic->height); +} diff --git a/contrib/other/sdlquake-1.0.9/wad.h b/contrib/other/sdlquake-1.0.9/wad.h new file mode 100644 index 000000000..9a740d9a7 --- /dev/null +++ b/contrib/other/sdlquake-1.0.9/wad.h @@ -0,0 +1,75 @@ +/* +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. + +*/ +// wad.h + +//=============== +// TYPES +//=============== + +#define CMP_NONE 0 +#define CMP_LZSS 1 + +#define TYP_NONE 0 +#define TYP_LABEL 1 + +#define TYP_LUMPY 64 // 64 + grab command number +#define TYP_PALETTE 64 +#define TYP_QTEX 65 +#define TYP_QPIC 66 +#define TYP_SOUND 67 +#define TYP_MIPTEX 68 + +typedef struct +{ + int width, height; + byte data[4]; // variably sized +} qpic_t; + + + +typedef struct +{ + char identification[4]; // should be WAD2 or 2DAW + int numlumps; + int infotableofs; +} wadinfo_t; + +typedef struct +{ + int filepos; + int disksize; + int size; // uncompressed + char type; + char compression; + char pad1, pad2; + char name[16]; // must be null terminated +} lumpinfo_t; + +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_GetLumpNum (int num); + +void SwapPic (qpic_t *pic); diff --git a/contrib/other/sdlquake-1.0.9/winquake.h b/contrib/other/sdlquake-1.0.9/winquake.h new file mode 100644 index 000000000..57bc7793b --- /dev/null +++ b/contrib/other/sdlquake-1.0.9/winquake.h @@ -0,0 +1,114 @@ +/* +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; + +extern modestate_t modestate; + +extern HWND mainwindow; +extern qboolean ActiveApp, Minimized; + +extern qboolean WinNT; + +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; + +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/contrib/other/sdlquake-1.0.9/winquake.rc b/contrib/other/sdlquake-1.0.9/winquake.rc new file mode 100644 index 000000000..5fb0a244d --- /dev/null +++ b/contrib/other/sdlquake-1.0.9/winquake.rc @@ -0,0 +1,131 @@ +//Microsoft Developer Studio generated resource script. +// +#include "resource.h" + +#define APSTUDIO_READONLY_SYMBOLS +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 2 resource. +// +#include "afxres.h" + +///////////////////////////////////////////////////////////////////////////// +#undef APSTUDIO_READONLY_SYMBOLS + +///////////////////////////////////////////////////////////////////////////// +// English (U.S.) resources + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) +#ifdef _WIN32 +LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US +#pragma code_page(1252) +#endif //_WIN32 + +#ifdef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// TEXTINCLUDE +// + +1 TEXTINCLUDE DISCARDABLE +BEGIN + "resource.h\0" +END + +2 TEXTINCLUDE DISCARDABLE +BEGIN + "#include ""afxres.h""\r\n" + "\0" +END + +3 TEXTINCLUDE DISCARDABLE +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 DISCARDABLE "quake.ico" + +///////////////////////////////////////////////////////////////////////////// +// +// Dialog +// + +IDD_DIALOG1 DIALOGEX 0, 0, 62, 21 +STYLE DS_MODALFRAME | DS_SETFOREGROUND | DS_3DLOOK | DS_CENTER | WS_POPUP +EXSTYLE WS_EX_TOOLWINDOW | WS_EX_CLIENTEDGE +FONT 16, "Times New Roman", 0, 0, 0x1 +BEGIN + CTEXT "Starting Quake...",IDC_STATIC,4,6,54,8 +END + +IDD_PROGRESS DIALOGEX 0, 0, 333, 45 +STYLE DS_MODALFRAME | DS_SETFOREGROUND | DS_3DLOOK | DS_CENTER | WS_POPUP | + WS_VISIBLE +EXSTYLE WS_EX_TOOLWINDOW | WS_EX_CLIENTEDGE +FONT 8, "MS Sans Serif" +BEGIN + LTEXT "Creating 15 bit inverse palette. This is only done once, so just be patient for the next 30-60 seconds.", + IDC_STATIC,7,19,319,10 + CONTROL "Progress1",IDC_PROGRESS,"msctls_progress32",0x0,7,29, + 319,11 + LTEXT "Starting Quake...",IDC_STATIC,7,4,54,8 +END + + +///////////////////////////////////////////////////////////////////////////// +// +// DESIGNINFO +// + +#ifdef APSTUDIO_INVOKED +GUIDELINES DESIGNINFO DISCARDABLE +BEGIN + IDD_DIALOG1, DIALOG + BEGIN + LEFTMARGIN, 4 + RIGHTMARGIN, 58 + TOPMARGIN, 6 + BOTTOMMARGIN, 16 + HORZGUIDE, 6 + HORZGUIDE, 16 + END +END +#endif // APSTUDIO_INVOKED + + +///////////////////////////////////////////////////////////////////////////// +// +// String Table +// + +STRINGTABLE DISCARDABLE +BEGIN + IDS_STRING1 "WinQuake" +END + +#endif // English (U.S.) resources +///////////////////////////////////////////////////////////////////////////// + + + +#ifndef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 3 resource. +// + + +///////////////////////////////////////////////////////////////////////////// +#endif // not APSTUDIO_INVOKED + diff --git a/contrib/other/sdlquake-1.0.9/world.c b/contrib/other/sdlquake-1.0.9/world.c new file mode 100644 index 000000000..e1acfea50 --- /dev/null +++ b/contrib/other/sdlquake-1.0.9/world.c @@ -0,0 +1,962 @@ +/* +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. + +*/ +// world.c -- world query functions + +#include "quakedef.h" + +/* + +entities never clip against themselves, or their owner + +line of sight checks trace->crosscontent, but bullets don't + +*/ + + +typedef struct +{ + vec3_t boxmins, boxmaxs;// enclose the test object along entire move + float *mins, *maxs; // size of the moving object + vec3_t mins2, maxs2; // size when clipping against mosnters + float *start, *end; + trace_t trace; + int type; + edict_t *passedict; +} moveclip_t; + + +int SV_HullPointContents (hull_t *hull, int num, vec3_t p); + +/* +=============================================================================== + +HULL BOXES + +=============================================================================== +*/ + + +static hull_t box_hull; +static dclipnode_t box_clipnodes[6]; +static mplane_t box_planes[6]; + +/* +=================== +SV_InitBoxHull + +Set up the planes and clipnodes so that the six floats of a bounding box +can just be stored out and get a proper hull_t structure. +=================== +*/ +void SV_InitBoxHull (void) +{ + int i; + int side; + + box_hull.clipnodes = box_clipnodes; + box_hull.planes = box_planes; + box_hull.firstclipnode = 0; + box_hull.lastclipnode = 5; + + 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; + } + +} + + +/* +=================== +SV_HullForBox + +To keep everything totally uniform, bounding boxes are turned into small +BSP trees instead of being compared directly. +=================== +*/ +hull_t *SV_HullForBox (vec3_t mins, vec3_t maxs) +{ + box_planes[0].dist = maxs[0]; + box_planes[1].dist = mins[0]; + box_planes[2].dist = maxs[1]; + box_planes[3].dist = mins[1]; + box_planes[4].dist = maxs[2]; + box_planes[5].dist = mins[2]; + + return &box_hull; +} + + + +/* +================ +SV_HullForEntity + +Returns a hull that can be used for testing or clipping an object of mins/maxs +size. +Offset is filled in to contain the adjustment that must be added to the +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; + vec3_t size; + vec3_t hullmins, hullmaxs; + hull_t *hull; + +// decide which clipping hull to use, based on the size + 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"); + + model = sv.models[ (int)ent->v.modelindex ]; + + if (!model || model->type != mod_brush) + Sys_Error ("MOVETYPE_PUSH with a non bsp model"); + + VectorSubtract (maxs, mins, size); + if (size[0] < 3) + hull = &model->hulls[0]; + else if (size[0] <= 32) + hull = &model->hulls[1]; + else + hull = &model->hulls[2]; + +// calculate an offset value to center the origin + VectorSubtract (hull->clip_mins, mins, offset); + VectorAdd (offset, ent->v.origin, offset); + } + else + { // create a temp hull from bounding box sizes + + VectorSubtract (ent->v.mins, maxs, hullmins); + VectorSubtract (ent->v.maxs, mins, hullmaxs); + hull = SV_HullForBox (hullmins, hullmaxs); + + VectorCopy (ent->v.origin, offset); + } + + + return hull; +} + +/* +=============================================================================== + +ENTITY AREA CHECKING + +=============================================================================== +*/ + +typedef struct areanode_s +{ + int axis; // -1 = leaf node + float dist; + struct areanode_s *children[2]; + link_t trigger_edicts; + link_t solid_edicts; +} areanode_t; + +#define AREA_DEPTH 4 +#define AREA_NODES 32 + +static areanode_t sv_areanodes[AREA_NODES]; +static int sv_numareanodes; + +/* +=============== +SV_CreateAreaNode + +=============== +*/ +areanode_t *SV_CreateAreaNode (int depth, vec3_t mins, vec3_t maxs) +{ + areanode_t *anode; + vec3_t size; + vec3_t mins1, maxs1, mins2, maxs2; + + anode = &sv_areanodes[sv_numareanodes]; + sv_numareanodes++; + + 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); + + 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); + + return anode; +} + +/* +=============== +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); +} + + +/* +=============== +SV_UnlinkEdict + +=============== +*/ +void SV_UnlinkEdict (edict_t *ent) +{ + if (!ent->area.prev) + return; // not linked in anywhere + RemoveLink (&ent->area); + ent->area.prev = ent->area.next = NULL; +} + + +/* +==================== +SV_TouchLinks +==================== +*/ +void SV_TouchLinks ( edict_t *ent, areanode_t *node ) +{ + 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; + old_self = pr_global_struct->self; + old_other = pr_global_struct->other; + + pr_global_struct->self = EDICT_TO_PROG(touch); + pr_global_struct->other = EDICT_TO_PROG(ent); + pr_global_struct->time = sv.time; + PR_ExecuteProgram (touch->v.touch); + + 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] ); +} + + +/* +=============== +SV_FindTouchedLeafs + +=============== +*/ +void SV_FindTouchedLeafs (edict_t *ent, mnode_t *node) +{ + mplane_t *splitplane; + mleaf_t *leaf; + int sides; + int leafnum; + + if (node->contents == CONTENTS_SOLID) + return; + +// add an efrag if the node is a leaf + + if ( node->contents < 0) + { + if (ent->num_leafs == MAX_ENT_LEAFS) + return; + + leaf = (mleaf_t *)node; + leafnum = leaf - sv.worldmodel->leafs - 1; + + ent->leafnums[ent->num_leafs] = leafnum; + 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]); +} + +/* +=============== +SV_LinkEdict + +=============== +*/ +void SV_LinkEdict (edict_t *ent, qboolean touch_triggers) +{ + areanode_t *node; + + if (ent->area.prev) + SV_UnlinkEdict (ent); // unlink from old position + + if (ent == sv.edicts) + return; // don't add the world + + if (ent->free) + 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); + } + +// +// to make items easier to pick up and allow them to be grabbed off +// of shelves, the abs sizes are expanded +// + if ((int)ent->v.flags & FL_ITEM) + { + ent->v.absmin[0] -= 15; + ent->v.absmin[1] -= 15; + ent->v.absmax[0] += 15; + ent->v.absmax[1] += 15; + } + else + { // because movement is clipped an epsilon away from an actual edge, + // we must fully check even when bounding boxes don't quite touch + ent->v.absmin[0] -= 1; + ent->v.absmin[1] -= 1; + ent->v.absmin[2] -= 1; + ent->v.absmax[0] += 1; + ent->v.absmax[1] += 1; + ent->v.absmax[2] += 1; + } + +// link to PVS leafs + ent->num_leafs = 0; + if (ent->v.modelindex) + SV_FindTouchedLeafs (ent, sv.worldmodel->nodes); + + if (ent->v.solid == SOLID_NOT) + return; + +// find the first node that the ent's box crosses + node = sv_areanodes; + while (1) + { + if (node->axis == -1) + break; + if (ent->v.absmin[node->axis] > node->dist) + node = node->children[0]; + else if (ent->v.absmax[node->axis] < node->dist) + node = node->children[1]; + else + break; // crosses the node + } + +// 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 ); +} + + + +/* +=============================================================================== + +POINT TESTING IN HULLS + +=============================================================================== +*/ + +#if !id386 + +/* +================== +SV_HullPointContents + +================== +*/ +int SV_HullPointContents (hull_t *hull, int num, vec3_t p) +{ + float d; + dclipnode_t *node; + 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; + if (d < 0) + num = node->children[1]; + else + num = node->children[0]; + } + + return num; +} + +#endif // !id386 + + +/* +================== +SV_PointContents + +================== +*/ +int SV_PointContents (vec3_t p) +{ + int cont; + + cont = SV_HullPointContents (&sv.worldmodel->hulls[0], 0, p); + if (cont <= CONTENTS_CURRENT_0 && cont >= CONTENTS_CURRENT_DOWN) + cont = CONTENTS_WATER; + return cont; +} + +int SV_TruePointContents (vec3_t p) +{ + return SV_HullPointContents (&sv.worldmodel->hulls[0], 0, p); +} + +//=========================================================================== + +/* +============ +SV_TestEntityPosition + +This could be a lot more efficient... +============ +*/ +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; +} + + +/* +=============================================================================== + +LINE TESTING IN HULLS + +=============================================================================== +*/ + +// 1/32 epsilon to keep floating point happy +#define DIST_EPSILON (0.03125) + +/* +================== +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; + mplane_t *plane; + float t1, t2; + float frac; + int i; + vec3_t mid; + int side; + float midf; + +// check for empty + if (num < 0) + { + if (num != CONTENTS_SOLID) + { + trace->allsolid = false; + if (num == CONTENTS_EMPTY) + trace->inopen = true; + else + trace->inwater = true; + } + else + trace->startsolid = true; + return true; // empty + } + + if (num < hull->firstclipnode || num > hull->lastclipnode) + Sys_Error ("SV_RecursiveHullCheck: bad node number"); + +// +// find the point distances +// + node = hull->clipnodes + num; + plane = hull->planes + node->planenum; + + if (plane->type < 3) + { + t1 = p1[plane->type] - plane->dist; + t2 = p2[plane->type] - plane->dist; + } + else + { + t1 = DotProduct (plane->normal, p1) - plane->dist; + t2 = DotProduct (plane->normal, p2) - plane->dist; + } + +#if 1 + if (t1 >= 0 && t2 >= 0) + return SV_RecursiveHullCheck (hull, node->children[0], p1f, p2f, p1, p2, trace); + if (t1 < 0 && t2 < 0) + return SV_RecursiveHullCheck (hull, node->children[1], p1f, p2f, p1, p2, trace); +#else + if ( (t1 >= DIST_EPSILON && t2 >= DIST_EPSILON) || (t2 > t1 && t1 >= 0) ) + return SV_RecursiveHullCheck (hull, node->children[0], p1f, p2f, p1, p2, trace); + if ( (t1 <= -DIST_EPSILON && t2 <= -DIST_EPSILON) || (t2 < t1 && t1 <= 0) ) + return SV_RecursiveHullCheck (hull, node->children[1], p1f, p2f, p1, p2, trace); +#endif + +// put the crosspoint DIST_EPSILON pixels on the near side + if (t1 < 0) + frac = (t1 + DIST_EPSILON)/(t1-t2); + else + frac = (t1 - DIST_EPSILON)/(t1-t2); + if (frac < 0) + 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]); + + side = (t1 < 0); + +// move up to the node + if (!SV_RecursiveHullCheck (hull, node->children[side], p1f, midf, p1, mid, trace) ) + return false; + +#ifdef PARANOID + if (SV_HullPointContents (sv_hullmodel, mid, node->children[side]) + == CONTENTS_SOLID) + { + Con_Printf ("mid PointInHullSolid\n"); + 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 +//================== + if (!side) + { + VectorCopy (plane->normal, trace->plane.normal); + trace->plane.dist = plane->dist; + } + else + { + VectorSubtract (vec3_origin, plane->normal, trace->plane.normal); + trace->plane.dist = -plane->dist; + } + + while (SV_HullPointContents (hull, hull->firstclipnode, mid) + == CONTENTS_SOLID) + { // shouldn't really happen, but does occasionally + frac -= 0.1; + if (frac < 0) + { + trace->fraction = midf; + VectorCopy (mid, trace->endpos); + Con_DPrintf ("backup past 0\n"); + return false; + } + midf = p1f + (p2f - p1f)*frac; + for (i=0 ; i<3 ; i++) + mid[i] = p1[i] + frac*(p2[i] - p1[i]); + } + + trace->fraction = midf; + VectorCopy (mid, trace->endpos); + + return false; +} + + +/* +================== +SV_ClipMoveToEntity + +Handles selection or creation of a clipping hull, and offseting (and +eventually rotation) of the end points +================== +*/ +trace_t SV_ClipMoveToEntity (edict_t *ent, vec3_t start, vec3_t mins, vec3_t maxs, vec3_t end) +{ + trace_t trace; + vec3_t offset; + vec3_t start_l, end_l; + hull_t *hull; + +// fill in a default trace + memset (&trace, 0, sizeof(trace_t)); + trace.fraction = 1; + trace.allsolid = true; + VectorCopy (end, trace.endpos); + +// get the clipping hull + hull = SV_HullForEntity (ent, mins, maxs, offset); + + VectorSubtract (start, offset, start_l); + VectorSubtract (end, offset, end_l); + +#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 + +// trace a line through the apropriate clipping hull + SV_RecursiveHullCheck (hull, hull->firstclipnode, 0, 1, start_l, end_l, &trace); + +#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 + +// fix trace up by the offset + if (trace.fraction != 1) + VectorAdd (trace.endpos, offset, trace.endpos); + +// did we clip the move? + if (trace.fraction < 1 || trace.startsolid ) + trace.ent = ent; + + return trace; +} + +//=========================================================================== + +/* +==================== +SV_ClipToLinks + +Mins and maxs enclose the entire area swept by the move +==================== +*/ +void SV_ClipToLinks ( areanode_t *node, moveclip_t *clip ) +{ + link_t *l, *next; + edict_t *touch; + trace_t trace; + +// touch linked edicts + for (l = node->solid_edicts.next ; l != &node->solid_edicts ; l = next) + { + next = l->next; + touch = EDICT_FROM_AREA(l); + if (touch->v.solid == SOLID_NOT) + continue; + if (touch == clip->passedict) + continue; + if (touch->v.solid == SOLID_TRIGGER) + Sys_Error ("Trigger in clipping list"); + + if (clip->type == MOVE_NOMONSTERS && touch->v.solid != SOLID_BSP) + continue; + + if (clip->boxmins[0] > touch->v.absmax[0] + || clip->boxmins[1] > touch->v.absmax[1] + || clip->boxmins[2] > touch->v.absmax[2] + || clip->boxmaxs[0] < touch->v.absmin[0] + || clip->boxmaxs[1] < touch->v.absmin[1] + || clip->boxmaxs[2] < touch->v.absmin[2] ) + continue; + + if (clip->passedict && clip->passedict->v.size[0] && !touch->v.size[0]) + continue; // points never interact + + // might intersect, so do an exact clip + if (clip->trace.allsolid) + return; + if (clip->passedict) + { + if (PROG_TO_EDICT(touch->v.owner) == clip->passedict) + continue; // don't clip against own missiles + if (PROG_TO_EDICT(clip->passedict->v.owner) == touch) + continue; // don't clip against owner + } + + if ((int)touch->v.flags & FL_MONSTER) + trace = SV_ClipMoveToEntity (touch, clip->start, clip->mins2, clip->maxs2, clip->end); + else + trace = SV_ClipMoveToEntity (touch, clip->start, clip->mins, clip->maxs, clip->end); + if (trace.allsolid || trace.startsolid || + trace.fraction < clip->trace.fraction) + { + trace.ent = touch; + if (clip->trace.startsolid) + { + clip->trace = trace; + clip->trace.startsolid = true; + } + else + clip->trace = trace; + } + else if (trace.startsolid) + clip->trace.startsolid = true; + } + +// recurse down both sides + if (node->axis == -1) + return; + + if ( clip->boxmaxs[node->axis] > node->dist ) + SV_ClipToLinks ( node->children[0], clip ); + if ( clip->boxmins[node->axis] < node->dist ) + SV_ClipToLinks ( node->children[1], clip ); +} + + +/* +================== +SV_MoveBounds +================== +*/ +void SV_MoveBounds (vec3_t start, vec3_t mins, vec3_t maxs, vec3_t end, vec3_t boxmins, vec3_t boxmaxs) +{ +#if 0 +// debug to test against everything +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]) + { + boxmins[i] = start[i] + mins[i] - 1; + boxmaxs[i] = end[i] + maxs[i] + 1; + } + else + { + boxmins[i] = end[i] + mins[i] - 1; + boxmaxs[i] = start[i] + maxs[i] + 1; + } + } +#endif +} + +/* +================== +SV_Move +================== +*/ +trace_t SV_Move (vec3_t start, vec3_t mins, vec3_t maxs, vec3_t end, int type, edict_t *passedict) +{ + moveclip_t clip; + int i; + + memset ( &clip, 0, sizeof ( moveclip_t ) ); + +// clip to world + clip.trace = SV_ClipMoveToEntity ( sv.edicts, start, mins, maxs, end ); + + clip.start = start; + clip.end = end; + clip.mins = mins; + clip.maxs = maxs; + clip.type = type; + clip.passedict = passedict; + + if (type == MOVE_MISSILE) + { + for (i=0 ; i<3 ; i++) + { + clip.mins2[i] = -15; + clip.maxs2[i] = 15; + } + } + else + { + 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 ); + +// clip to entities + SV_ClipToLinks ( sv_areanodes, &clip ); + + return clip.trace; +} + diff --git a/contrib/other/sdlquake-1.0.9/world.h b/contrib/other/sdlquake-1.0.9/world.h new file mode 100644 index 000000000..cddb94fca --- /dev/null +++ b/contrib/other/sdlquake-1.0.9/world.h @@ -0,0 +1,78 @@ +/* +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. + +*/ +// world.h + +typedef struct +{ + vec3_t normal; + float dist; +} plane_t; + +typedef struct +{ + qboolean allsolid; // if true, plane is not valid + qboolean startsolid; // if true, the initial point was in a solid area + qboolean inopen, inwater; + float fraction; // time completed, 1.0 = didn't hit anything + vec3_t endpos; // final position + plane_t plane; // surface normal at impact + edict_t *ent; // entity the surface is on +} trace_t; + + +#define MOVE_NORMAL 0 +#define MOVE_NOMONSTERS 1 +#define MOVE_MISSILE 2 + + +void SV_ClearWorld (void); +// called after the world model has been loaded, before linking any entities + +void SV_UnlinkEdict (edict_t *ent); +// call before removing an entity, and before trying to move one, +// so it doesn't clip against itself +// flags ent->v.modified + +void SV_LinkEdict (edict_t *ent, qboolean touch_triggers); +// Needs to be called any time an entity changes origin, mins, maxs, or solid +// flags ent->v.modified +// sets ent->v.absmin and ent->v.absmax +// if touchtriggers, calls prog functions for the intersected triggers + +int SV_PointContents (vec3_t p); +int SV_TruePointContents (vec3_t p); +// returns the CONTENTS_* value from the world at the given point. +// does not check any entities at all +// the non-true version remaps the water current contents to content_water + +edict_t *SV_TestEntityPosition (edict_t *ent); + +trace_t SV_Move (vec3_t start, vec3_t mins, vec3_t maxs, vec3_t end, int type, edict_t *passedict); +// mins and maxs are reletive + +// if the entire move stays in a solid volume, trace.allsolid will be set + +// if the starting point is in a solid, it will be allowed to move out +// to an open area + +// nomonsters is used for line of sight or edge testing, where mosnters +// shouldn't be considered solid objects + +// passedict is explicitly excluded from clipping checks (normally NULL) diff --git a/contrib/other/sdlquake-1.0.9/worlda.S b/contrib/other/sdlquake-1.0.9/worlda.S new file mode 100644 index 000000000..630902ad6 --- /dev/null +++ b/contrib/other/sdlquake-1.0.9/worlda.S @@ -0,0 +1,144 @@ +/* +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. + +*/ +// +// worlda.s +// x86 assembly-language server testing stuff +// + +#define GLQUAKE 1 // don't include unneeded defs +#include "asm_i386.h" +#include "quakeasm.h" +#include "d_ifacea.h" + +#if id386 + + .data + +Ltemp: .long 0 + + .text + +//---------------------------------------------------------------------- +// hull-point test +//---------------------------------------------------------------------- + +#define hull 4+8 // because only partially pushed +#define num 8+4 // because only partially pushed +#define p 12+12 // because only partially pushed + + .align 4 +.globl C(SV_HullPointContents) +C(SV_HullPointContents): + pushl %edi // preserve register variables + movl num(%esp),%eax + testl %eax,%eax + js Lhquickout + +// float d; +// dclipnode_t *node; +// mplane_t *plane; + + pushl %ebx + movl hull(%esp),%ebx + + pushl %ebp + movl p(%esp),%edx + + movl hu_clipnodes(%ebx),%edi + movl hu_planes(%ebx),%ebp + + subl %ebx,%ebx + pushl %esi + +// %ebx: 0 +// %eax: num +// %edx: p +// %edi: hull->clipnodes +// %ebp: hull->planes + +// while (num >= 0) +// { + +Lhloop: + +// node = hull->clipnodes + num; +// plane = hull->planes + node->planenum; +// !!! if the size of dclipnode_t changes, the scaling of %eax needs to be +// changed !!! + movl nd_planenum(%edi,%eax,8),%ecx + movl nd_children(%edi,%eax,8),%eax + movl %eax,%esi + rorl $16,%eax + leal (%ecx,%ecx,4),%ecx + +// if (plane->type < 3) +// d = p[plane->type] - plane->dist; + movb pl_type(%ebp,%ecx,4),%bl + cmpb $3,%bl + jb Lnodot + +// else +// d = DotProduct (plane->normal, p) - plane->dist; + flds pl_normal(%ebp,%ecx,4) + fmuls 0(%edx) + flds pl_normal+4(%ebp,%ecx,4) + fmuls 4(%edx) + flds pl_normal+8(%ebp,%ecx,4) + fmuls 8(%edx) + fxch %st(1) + faddp %st(0),%st(2) + faddp %st(0),%st(1) + fsubs pl_dist(%ebp,%ecx,4) + jmp Lsub + +Lnodot: + flds pl_dist(%ebp,%ecx,4) + fsubrs (%edx,%ebx,4) + +Lsub: + sarl $16,%eax + sarl $16,%esi + +// if (d < 0) +// num = node->children[1]; +// else +// num = node->children[0]; + fstps Ltemp + movl Ltemp,%ecx + sarl $31,%ecx + andl %ecx,%esi + xorl $0xFFFFFFFF,%ecx + andl %ecx,%eax + orl %esi,%eax + jns Lhloop + +// return num; +Lhdone: + popl %esi + popl %ebp + popl %ebx // restore register variables + +Lhquickout: + popl %edi + + ret + +#endif // id386 + diff --git a/contrib/other/sdlquake-1.0.9/wq.bat b/contrib/other/sdlquake-1.0.9/wq.bat new file mode 100644 index 000000000..90881fe4f --- /dev/null +++ b/contrib/other/sdlquake-1.0.9/wq.bat @@ -0,0 +1,42 @@ +@echo off +if x%1==xfast goto fast +if x%1==xsafe goto safe +if x%1==xverysafe goto verysafe +if x%1==xfastvid goto fastvid +if x%1==xfastsnd goto fastsnd +if x%1==xmax goto max + +echo ------------------------------------------------------------------- +echo Options for running WinQuake: +echo wq max: all features on, but doesn't work on all systems +echo wq fast: maximum speed, but doesn't work on all systems +echo wq fastvid: maximum video speed, but safer, probably slower sound +echo wq fastsnd: maximum sound speed, but safer, probably slower video +echo wq safe: very likely to run, but may be slower +echo wq verysafe: almost sure to run, but probably slower, and no sound +echo ------------------------------------------------------------------- +goto done + +:max +winquake -dinput %2 %3 %4 %5 %6 %7 %8 %9 +goto done + +:fast +winquake %2 %3 %4 %5 %6 %7 %8 %9 +goto done + +:fastvid +winquake -wavonly %2 %3 %4 %5 %6 %7 %8 %9 +goto done + +:fastsnd +winquake -nodirectdraw -nowindirect %2 %3 %4 %5 %6 %7 %8 %9 +goto done + +:safe +winquake -nodirectdraw -nowindirect -wavonly %2 %3 %4 %5 %6 %7 %8 %9 +goto done + +:verysafe +winquake -dibonly -nosound -nojoy %2 %3 %4 %5 %6 %7 %8 %9 +:done diff --git a/contrib/other/sdlquake-1.0.9/wqreadme.txt b/contrib/other/sdlquake-1.0.9/wqreadme.txt new file mode 100644 index 000000000..9ba2f1b67 --- /dev/null +++ b/contrib/other/sdlquake-1.0.9/wqreadme.txt @@ -0,0 +1,1119 @@ +-------------------------- +| 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/contrib/other/sdlquake-1.0.9/zone.c b/contrib/other/sdlquake-1.0.9/zone.c new file mode 100644 index 000000000..e30d7f847 --- /dev/null +++ b/contrib/other/sdlquake-1.0.9/zone.c @@ -0,0 +1,935 @@ +/* +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. + +*/ +// Z_zone.c + +#include "quakedef.h" + +#define DYNAMIC_SIZE 0xc000 + +#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 +} memblock_t; + +typedef struct +{ + int size; // total bytes malloced, including header + memblock_t blocklist; // start / end cap for linked list + memblock_t *rover; +} memzone_t; + +void Cache_FreeLow (int new_low_hunk); +void Cache_FreeHigh (int new_high_hunk); + + +/* +============================================================================== + + ZONE MEMORY ALLOCATION + +There is never any space between memblocks, and there will never be two +contiguous free memblocks. + +The rover can be left pointing at a non-empty block + +The zone calls are pretty much only used for small strings and structures, +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); +} + + +/* +======================== +Z_Free +======================== +*/ +void Z_Free (void *ptr) +{ + memblock_t *block, *other; + + if (!ptr) + Sys_Error ("Z_Free: NULL pointer"); + + block = (memblock_t *) ( (byte *)ptr - sizeof(memblock_t)); + if (block->id != ZONEID) + Sys_Error ("Z_Free: freed a pointer without ZONEID"); + if (block->tag == 0) + 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 + other->size += block->size; + other->next = block->next; + other->next->prev = other; + if (block == mainzone->rover) + mainzone->rover = other; + block = other; + } + + other = block->next; + if (!other->tag) + { // merge the next free block onto the end + block->size += other->size; + block->next = other->next; + block->next->prev = block; + if (other == mainzone->rover) + mainzone->rover = block; + } +} + + +/* +======================== +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) +{ + int extra; + memblock_t *start, *rover, *new, *base; + + if (!tag) + Sys_Error ("Z_TagMalloc: tried to use a 0 tag"); + +// +// scan through the block list looking for the first free block +// of sufficient size +// + 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 + return NULL; + if (rover->tag) + base = rover = rover->next; + 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; + 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 + *(int *)((byte *)base + base->size - 4) = ZONEID; + + return (void *) ((byte *)base + sizeof(memblock_t)); +} + + +/* +======================== +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 + 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) + Con_Printf ("ERROR: next block doesn't have proper back link\n"); + if (!block->tag && !block->next->tag) + Con_Printf ("ERROR: two consecutive free blocks\n"); + } +} + + +/* +======================== +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 + +typedef struct +{ + int sentinal; + int size; // including sizeof(hunk_t), -1 = not allocated + char name[8]; +} hunk_t; + +byte *hunk_base; +int hunk_size; + +int hunk_low_used; +int hunk_high_used; + +qboolean hunk_tempactive; +int hunk_tempmark; + +void R_FreeTextures (void); + +/* +============== +Hunk_Check + +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) + Sys_Error ("Hunk_Check: bad size"); + h = (hunk_t *)((byte *)h+h->size); + } +} + +/* +============== +Hunk_Print + +If "all" is specified, every single allocation is printed. +Otherwise, allocations with the same name will be totaled up before printing. +============== +*/ +void Hunk_Print (qboolean all) +{ + hunk_t *h, *next, *endlow, *starthigh, *endhigh; + int count, sum; + int totalblocks; + char name[9]; + + 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); + endhigh = (hunk_t *)(hunk_base + hunk_size); + + Con_Printf (" :%8i total hunk size\n", hunk_size); + Con_Printf ("-------------------------\n"); + + while (1) + { + // + // skip to the high hunk if done with low hunk + // + if ( h == endlow ) + { + Con_Printf ("-------------------------\n"); + Con_Printf (" :%8i REMAINING\n", hunk_size - hunk_low_used - hunk_high_used); + Con_Printf ("-------------------------\n"); + h = starthigh; + } + + // + // if totally done, break + // + if ( h == endhigh ) + break; + + // + // run consistancy checks + // + if (h->sentinal != HUNK_SENTINAL) + Sys_Error ("Hunk_Check: trahsed sentinal"); + if (h->size < 16 || h->size + (byte *)h - hunk_base > hunk_size) + Sys_Error ("Hunk_Check: bad size"); + + next = (hunk_t *)((byte *)h+h->size); + count++; + totalblocks++; + sum += h->size; + + // + // print the single block + // + memcpy (name, h->name, 8); + 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 (!all) + Con_Printf (" :%8i %8s (TOTAL)\n",sum, name); + count = 0; + sum = 0; + } + + h = next; + } + + Con_Printf ("-------------------------\n"); + Con_Printf ("%8i total blocks\n", totalblocks); + +} + +/* +=================== +Hunk_AllocName +=================== +*/ +void *Hunk_AllocName (int size, 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); + + return (void *)(h+1); +} + +/* +=================== +Hunk_Alloc +=================== +*/ +void *Hunk_Alloc (int size) +{ + return Hunk_AllocName (size, "unknown"); +} + +int Hunk_LowMark (void) +{ + return hunk_low_used; +} + +void Hunk_FreeToLowMark (int mark) +{ + if (mark < 0 || mark > hunk_low_used) + Sys_Error ("Hunk_FreeToLowMark: bad mark %i", mark); + memset (hunk_base + mark, 0, hunk_low_used - mark); + hunk_low_used = mark; +} + +int Hunk_HighMark (void) +{ + if (hunk_tempactive) + { + hunk_tempactive = false; + Hunk_FreeToHighMark (hunk_tempmark); + } + + return hunk_high_used; +} + +void Hunk_FreeToHighMark (int mark) +{ + if (hunk_tempactive) + { + hunk_tempactive = false; + Hunk_FreeToHighMark (hunk_tempmark); + } + if (mark < 0 || mark > hunk_high_used) + Sys_Error ("Hunk_FreeToHighMark: bad mark %i", mark); + memset (hunk_base + hunk_size - hunk_high_used, 0, hunk_high_used - mark); + hunk_high_used = mark; +} + + +/* +=================== +Hunk_HighAllocName +=================== +*/ +void *Hunk_HighAllocName (int size, char *name) +{ + hunk_t *h; + + if (size < 0) + Sys_Error ("Hunk_HighAllocName: bad size: %i", size); + + if (hunk_tempactive) + { + Hunk_FreeToHighMark (hunk_tempmark); + hunk_tempactive = false; + } + +#ifdef PARANOID + Hunk_Check (); +#endif + + size = sizeof(hunk_t) + ((size+15)&~15); + + if (hunk_size - hunk_low_used - hunk_high_used < size) + { + Con_Printf ("Hunk_HighAlloc: failed on %i bytes\n",size); + return NULL; + } + + hunk_high_used += size; + Cache_FreeHigh (hunk_high_used); + + h = (hunk_t *)(hunk_base + hunk_size - hunk_high_used); + + memset (h, 0, size); + h->size = size; + h->sentinal = HUNK_SENTINAL; + Q_strncpy (h->name, name, 8); + + return (void *)(h+1); +} + + +/* +================= +Hunk_TempAlloc + +Return space from the top of the hunk +================= +*/ +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"); + + hunk_tempactive = true; + + return buf; +} + +/* +=============================================================================== + +CACHE MEMORY + +=============================================================================== +*/ + +typedef struct cache_system_s +{ + int size; // including this header + cache_user_t *user; + char name[16]; + struct cache_system_s *prev, *next; + struct cache_system_s *lru_prev, *lru_next; // for LRU flushing +} cache_system_t; + +cache_system_t *Cache_TryAlloc (int size, qboolean nobottom); + +cache_system_t cache_head; + +/* +=========== +Cache_Move +=========== +*/ +void Cache_Move ( cache_system_t *c) +{ + cache_system_t *new; + +// we are clearing up space at the bottom, so only allocate it late + new = Cache_TryAlloc (c->size, true); + if (new) + { +// 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); + } + else + { +// Con_Printf ("cache_move failed\n"); + + Cache_Free (c->user); // tough luck... + } +} + +/* +============ +Cache_FreeLow + +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; + if (c == &cache_head) + return; // nothing in cache at all + if ((byte *)c >= hunk_base + new_low_hunk) + return; // there is space to grow the hunk + Cache_Move ( c ); // reclaim the space + } +} + +/* +============ +Cache_FreeHigh + +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) + { + c = cache_head.prev; + if (c == &cache_head) + return; // nothing in cache at all + 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 + else + { + Cache_Move (c); // try to move it + prev = c; + } + } +} + +void Cache_UnlinkLRU (cache_system_t *cs) +{ + if (!cs->lru_next || !cs->lru_prev) + Sys_Error ("Cache_UnlinkLRU: NULL link"); + + cs->lru_next->lru_prev = cs->lru_prev; + cs->lru_prev->lru_next = cs->lru_next; + + cs->lru_prev = cs->lru_next = NULL; +} + +void Cache_MakeLRU (cache_system_t *cs) +{ + if (cs->lru_next || cs->lru_prev) + Sys_Error ("Cache_MakeLRU: active link"); + + cache_head.lru_next->lru_prev = cs; + cs->lru_next = cache_head.lru_next; + cs->lru_prev = &cache_head; + cache_head.lru_next = cs; +} + +/* +============ +Cache_TryAlloc + +Looks for a free block of memory between the high and low hunk marks +Size should already include the header and padding +============ +*/ +cache_system_t *Cache_TryAlloc (int size, qboolean nobottom) +{ + cache_system_t *cs, *new; + +// is the cache completely empty? + + if (!nobottom && cache_head.prev == &cache_head) + { + 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; + + cache_head.prev = cache_head.next = new; + new->prev = new->next = &cache_head; + + Cache_MakeLRU (new); + return new; + } + +// search from the bottom up for space + + new = (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) + { // 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; + } + } + + // continue looking + new = (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) + { + 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; + } + + return NULL; // couldn't allocate +} + +/* +============ +Cache_Flush + +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_Print + +============ +*/ +void Cache_Print (void) +{ + cache_system_t *cd; + + for (cd = cache_head.next ; cd != &cache_head ; cd = cd->next) + { + Con_Printf ("%8i : %s\n", cd->size, cd->name); + } +} + +/* +============ +Cache_Report + +============ +*/ +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 + +============ +*/ +void Cache_Init (void) +{ + cache_head.next = cache_head.prev = &cache_head; + cache_head.lru_next = cache_head.lru_prev = &cache_head; + + Cmd_AddCommand ("flush", Cache_Flush); +} + +/* +============== +Cache_Free + +Frees the memory and removes it from the LRU list +============== +*/ +void Cache_Free (cache_user_t *c) +{ + cache_system_t *cs; + + if (!c->data) + Sys_Error ("Cache_Free: not allocated"); + + cs = ((cache_system_t *)c->data) - 1; + + cs->prev->next = cs->next; + cs->next->prev = cs->prev; + cs->next = cs->prev = NULL; + + c->data = NULL; + + Cache_UnlinkLRU (cs); +} + + + +/* +============== +Cache_Check +============== +*/ +void *Cache_Check (cache_user_t *c) +{ + cache_system_t *cs; + + if (!c->data) + return NULL; + + cs = ((cache_system_t *)c->data) - 1; + +// move to head of LRU + Cache_UnlinkLRU (cs); + Cache_MakeLRU (cs); + + return c->data; +} + + +/* +============== +Cache_Alloc +============== +*/ +void *Cache_Alloc (cache_user_t *c, int size, 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 + while (1) + { + cs = Cache_TryAlloc (size, false); + if (cs) + { + strncpy (cs->name, name, sizeof(cs->name)-1); + 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 ); + } + + return Cache_Check (c); +} + +//============================================================================ + + +/* +======================== +Memory_Init +======================== +*/ +void Memory_Init (void *buf, int size) +{ + int p; + int zonesize = DYNAMIC_SIZE; + + hunk_base = buf; + hunk_size = size; + hunk_low_used = 0; + hunk_high_used = 0; + + Cache_Init (); + p = COM_CheckParm ("-zone"); + if (p) + { + if (p < com_argc-1) + zonesize = Q_atoi (com_argv[p+1]) * 1024; + else + Sys_Error ("Memory_Init: you must specify a size in KB after -zone"); + } + mainzone = Hunk_AllocName (zonesize, "zone" ); + Z_ClearZone (mainzone, zonesize); +} + diff --git a/contrib/other/sdlquake-1.0.9/zone.h b/contrib/other/sdlquake-1.0.9/zone.h new file mode 100644 index 000000000..7655ad9c0 --- /dev/null +++ b/contrib/other/sdlquake-1.0.9/zone.h @@ -0,0 +1,131 @@ +/* +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. + +*/ +/* + memory allocation + + +H_??? The hunk manages the entire memory block given to quake. It must be +contiguous. Memory can be allocated from either the low or high end in a +stack fashion. The only way memory is released is by resetting one of the +pointers. + +Hunk allocations should be given a name, so the Hunk_Print () function +can display usage. + +Hunk allocations are guaranteed to be 16 byte aligned. + +The video buffers are allocated high to avoid leaving a hole underneath +server allocations when changing to a higher video mode. + + +Z_??? Zone memory functions used for small, dynamic allocations like text +strings from command input. There is only about 48K for it, allocated at +the very bottom of the hunk. + +Cache_??? Cache memory is for objects that can be dynamically loaded and +can usefully stay persistant between levels. The size of the cache +fluctuates from level to level. + +To allocate a cachable object + + +Temp_??? Temp memory is used for file loading and surface caching. The size +of the cache memory is adjusted so that there is a minimum of 512k remaining +for temp memory. + + +------ Top of Memory ------- + +high hunk allocations + +<--- high hunk reset point held by vid + +video buffer + +z buffer + +surface cache + +<--- high hunk used + +cachable memory + +<--- low hunk used + +client and server low hunk allocations + +<-- low hunk reset point held by host + +startup hunk allocations + +Zone block + +----- Bottom of Memory ----- + + + +*/ + +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_DumpHeap (void); +void Z_CheckHeap (void); +int Z_FreeMemory (void); + +void *Hunk_Alloc (int size); // returns 0 filled memory +void *Hunk_AllocName (int size, char *name); + +void *Hunk_HighAllocName (int size, char *name); + +int Hunk_LowMark (void); +void Hunk_FreeToLowMark (int mark); + +int Hunk_HighMark (void); +void Hunk_FreeToHighMark (int mark); + +void *Hunk_TempAlloc (int size); + +void Hunk_Check (void); + +typedef struct cache_user_s +{ + void *data; +} cache_user_t; + +void Cache_Flush (void); + +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_Alloc (cache_user_t *c, int size, char *name); +// Returns NULL if all purgable data was tossed and there still +// wasn't enough room. + +void Cache_Report (void); + + + diff --git a/contrib/sdk/sources/SDL-1.2.2/SDL_anim-0.2.1/LICENSE b/contrib/sdk/sources/SDL-1.2.2/SDL_anim-0.2.1/LICENSE new file mode 100644 index 000000000..b1e3f5a26 --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/SDL_anim-0.2.1/LICENSE @@ -0,0 +1,504 @@ + GNU LESSER GENERAL PUBLIC LICENSE + Version 2.1, February 1999 + + Copyright (C) 1991, 1999 Free Software Foundation, Inc. + 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + +[This is the first released version of the Lesser GPL. It also counts + as the successor of the GNU Library Public License, version 2, hence + the version number 2.1.] + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +Licenses are intended to guarantee your freedom to share and change +free software--to make sure the software is free for all its users. + + This license, the Lesser General Public License, applies to some +specially designated software packages--typically libraries--of the +Free Software Foundation and other authors who decide to use it. You +can use it too, but we suggest you first think carefully about whether +this license or the ordinary General Public License is the better +strategy to use in any particular case, based on the explanations below. + + When we speak of free software, we are referring to freedom of use, +not price. Our General Public Licenses are designed to make sure that +you have the freedom to distribute copies of free software (and charge +for this service if you wish); that you receive source code or can get +it if you want it; that you can change the software and use pieces of +it in new free programs; and that you are informed that you can do +these things. + + To protect your rights, we need to make restrictions that forbid +distributors to deny you these rights or to ask you to surrender these +rights. These restrictions translate to certain responsibilities for +you if you distribute copies of the library or if you modify it. + + For example, if you distribute copies of the library, whether gratis +or for a fee, you must give the recipients all the rights that we gave +you. You must make sure that they, too, receive or can get the source +code. If you link other code with the library, you must provide +complete object files to the recipients, so that they can relink them +with the library after making changes to the library and recompiling +it. And you must show them these terms so they know their rights. + + We protect your rights with a two-step method: (1) we copyright the +library, and (2) we offer you this license, which gives you legal +permission to copy, distribute and/or modify the library. + + To protect each distributor, we want to make it very clear that +there is no warranty for the free library. Also, if the library is +modified by someone else and passed on, the recipients should know +that what they have is not the original version, so that the original +author's reputation will not be affected by problems that might be +introduced by others. + + Finally, software patents pose a constant threat to the existence of +any free program. We wish to make sure that a company cannot +effectively restrict the users of a free program by obtaining a +restrictive license from a patent holder. Therefore, we insist that +any patent license obtained for a version of the library must be +consistent with the full freedom of use specified in this license. + + Most GNU software, including some libraries, is covered by the +ordinary GNU General Public License. This license, the GNU Lesser +General Public License, applies to certain designated libraries, and +is quite different from the ordinary General Public License. We use +this license for certain libraries in order to permit linking those +libraries into non-free programs. + + When a program is linked with a library, whether statically or using +a shared library, the combination of the two is legally speaking a +combined work, a derivative of the original library. The ordinary +General Public License therefore permits such linking only if the +entire combination fits its criteria of freedom. The Lesser General +Public License permits more lax criteria for linking other code with +the library. + + We call this license the "Lesser" General Public License because it +does Less to protect the user's freedom than the ordinary General +Public License. It also provides other free software developers Less +of an advantage over competing non-free programs. These disadvantages +are the reason we use the ordinary General Public License for many +libraries. However, the Lesser license provides advantages in certain +special circumstances. + + For example, on rare occasions, there may be a special need to +encourage the widest possible use of a certain library, so that it becomes +a de-facto standard. To achieve this, non-free programs must be +allowed to use the library. A more frequent case is that a free +library does the same job as widely used non-free libraries. In this +case, there is little to gain by limiting the free library to free +software only, so we use the Lesser General Public License. + + In other cases, permission to use a particular library in non-free +programs enables a greater number of people to use a large body of +free software. For example, permission to use the GNU C Library in +non-free programs enables many more people to use the whole GNU +operating system, as well as its variant, the GNU/Linux operating +system. + + Although the Lesser General Public License is Less protective of the +users' freedom, it does ensure that the user of a program that is +linked with the Library has the freedom and the wherewithal to run +that program using a modified version of the Library. + + The precise terms and conditions for copying, distribution and +modification follow. Pay close attention to the difference between a +"work based on the library" and a "work that uses the library". The +former contains code derived from the library, whereas the latter must +be combined with the library in order to run. + + GNU LESSER GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License Agreement applies to any software library or other +program which contains a notice placed by the copyright holder or +other authorized party saying it may be distributed under the terms of +this Lesser General Public License (also called "this License"). +Each licensee is addressed as "you". + + A "library" means a collection of software functions and/or data +prepared so as to be conveniently linked with application programs +(which use some of those functions and data) to form executables. + + The "Library", below, refers to any such software library or work +which has been distributed under these terms. A "work based on the +Library" means either the Library or any derivative work under +copyright law: that is to say, a work containing the Library or a +portion of it, either verbatim or with modifications and/or translated +straightforwardly into another language. (Hereinafter, translation is +included without limitation in the term "modification".) + + "Source code" for a work means the preferred form of the work for +making modifications to it. For a library, complete source code means +all the source code for all modules it contains, plus any associated +interface definition files, plus the scripts used to control compilation +and installation of the library. + + Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running a program using the Library is not restricted, and output from +such a program is covered only if its contents constitute a work based +on the Library (independent of the use of the Library in a tool for +writing it). Whether that is true depends on what the Library does +and what the program that uses the Library does. + + 1. You may copy and distribute verbatim copies of the Library's +complete source code as you receive it, in any medium, provided that +you conspicuously and appropriately publish on each copy an +appropriate copyright notice and disclaimer of warranty; keep intact +all the notices that refer to this License and to the absence of any +warranty; and distribute a copy of this License along with the +Library. + + You may charge a fee for the physical act of transferring a copy, +and you may at your option offer warranty protection in exchange for a +fee. + + 2. You may modify your copy or copies of the Library or any portion +of it, thus forming a work based on the Library, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) The modified work must itself be a software library. + + b) You must cause the files modified to carry prominent notices + stating that you changed the files and the date of any change. + + c) You must cause the whole of the work to be licensed at no + charge to all third parties under the terms of this License. + + d) If a facility in the modified Library refers to a function or a + table of data to be supplied by an application program that uses + the facility, other than as an argument passed when the facility + is invoked, then you must make a good faith effort to ensure that, + in the event an application does not supply such function or + table, the facility still operates, and performs whatever part of + its purpose remains meaningful. + + (For example, a function in a library to compute square roots has + a purpose that is entirely well-defined independent of the + application. Therefore, Subsection 2d requires that any + application-supplied function or table used by this function must + be optional: if the application does not supply it, the square + root function must still compute square roots.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Library, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Library, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote +it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Library. + +In addition, mere aggregation of another work not based on the Library +with the Library (or with a work based on the Library) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may opt to apply the terms of the ordinary GNU General Public +License instead of this License to a given copy of the Library. To do +this, you must alter all the notices that refer to this License, so +that they refer to the ordinary GNU General Public License, version 2, +instead of to this License. (If a newer version than version 2 of the +ordinary GNU General Public License has appeared, then you can specify +that version instead if you wish.) Do not make any other change in +these notices. + + Once this change is made in a given copy, it is irreversible for +that copy, so the ordinary GNU General Public License applies to all +subsequent copies and derivative works made from that copy. + + This option is useful when you wish to copy part of the code of +the Library into a program that is not a library. + + 4. You may copy and distribute the Library (or a portion or +derivative of it, under Section 2) in object code or executable form +under the terms of Sections 1 and 2 above provided that you accompany +it with the complete corresponding machine-readable source code, which +must be distributed under the terms of Sections 1 and 2 above on a +medium customarily used for software interchange. + + If distribution of object code is made by offering access to copy +from a designated place, then offering equivalent access to copy the +source code from the same place satisfies the requirement to +distribute the source code, even though third parties are not +compelled to copy the source along with the object code. + + 5. A program that contains no derivative of any portion of the +Library, but is designed to work with the Library by being compiled or +linked with it, is called a "work that uses the Library". Such a +work, in isolation, is not a derivative work of the Library, and +therefore falls outside the scope of this License. + + However, linking a "work that uses the Library" with the Library +creates an executable that is a derivative of the Library (because it +contains portions of the Library), rather than a "work that uses the +library". The executable is therefore covered by this License. +Section 6 states terms for distribution of such executables. + + When a "work that uses the Library" uses material from a header file +that is part of the Library, the object code for the work may be a +derivative work of the Library even though the source code is not. +Whether this is true is especially significant if the work can be +linked without the Library, or if the work is itself a library. The +threshold for this to be true is not precisely defined by law. + + If such an object file uses only numerical parameters, data +structure layouts and accessors, and small macros and small inline +functions (ten lines or less in length), then the use of the object +file is unrestricted, regardless of whether it is legally a derivative +work. (Executables containing this object code plus portions of the +Library will still fall under Section 6.) + + Otherwise, if the work is a derivative of the Library, you may +distribute the object code for the work under the terms of Section 6. +Any executables containing that work also fall under Section 6, +whether or not they are linked directly with the Library itself. + + 6. As an exception to the Sections above, you may also combine or +link a "work that uses the Library" with the Library to produce a +work containing portions of the Library, and distribute that work +under terms of your choice, provided that the terms permit +modification of the work for the customer's own use and reverse +engineering for debugging such modifications. + + You must give prominent notice with each copy of the work that the +Library is used in it and that the Library and its use are covered by +this License. You must supply a copy of this License. If the work +during execution displays copyright notices, you must include the +copyright notice for the Library among them, as well as a reference +directing the user to the copy of this License. Also, you must do one +of these things: + + a) Accompany the work with the complete corresponding + machine-readable source code for the Library including whatever + changes were used in the work (which must be distributed under + Sections 1 and 2 above); and, if the work is an executable linked + with the Library, with the complete machine-readable "work that + uses the Library", as object code and/or source code, so that the + user can modify the Library and then relink to produce a modified + executable containing the modified Library. (It is understood + that the user who changes the contents of definitions files in the + Library will not necessarily be able to recompile the application + to use the modified definitions.) + + b) Use a suitable shared library mechanism for linking with the + Library. A suitable mechanism is one that (1) uses at run time a + copy of the library already present on the user's computer system, + rather than copying library functions into the executable, and (2) + will operate properly with a modified version of the library, if + the user installs one, as long as the modified version is + interface-compatible with the version that the work was made with. + + c) Accompany the work with a written offer, valid for at + least three years, to give the same user the materials + specified in Subsection 6a, above, for a charge no more + than the cost of performing this distribution. + + d) If distribution of the work is made by offering access to copy + from a designated place, offer equivalent access to copy the above + specified materials from the same place. + + e) Verify that the user has already received a copy of these + materials or that you have already sent this user a copy. + + For an executable, the required form of the "work that uses the +Library" must include any data and utility programs needed for +reproducing the executable from it. However, as a special exception, +the materials to be distributed need not include anything that is +normally distributed (in either source or binary form) with the major +components (compiler, kernel, and so on) of the operating system on +which the executable runs, unless that component itself accompanies +the executable. + + It may happen that this requirement contradicts the license +restrictions of other proprietary libraries that do not normally +accompany the operating system. Such a contradiction means you cannot +use both them and the Library together in an executable that you +distribute. + + 7. You may place library facilities that are a work based on the +Library side-by-side in a single library together with other library +facilities not covered by this License, and distribute such a combined +library, provided that the separate distribution of the work based on +the Library and of the other library facilities is otherwise +permitted, and provided that you do these two things: + + a) Accompany the combined library with a copy of the same work + based on the Library, uncombined with any other library + facilities. This must be distributed under the terms of the + Sections above. + + b) Give prominent notice with the combined library of the fact + that part of it is a work based on the Library, and explaining + where to find the accompanying uncombined form of the same work. + + 8. You may not copy, modify, sublicense, link with, or distribute +the Library except as expressly provided under this License. Any +attempt otherwise to copy, modify, sublicense, link with, or +distribute the Library is void, and will automatically terminate your +rights under this License. However, parties who have received copies, +or rights, from you under this License will not have their licenses +terminated so long as such parties remain in full compliance. + + 9. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Library or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Library (or any work based on the +Library), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Library or works based on it. + + 10. Each time you redistribute the Library (or any work based on the +Library), the recipient automatically receives a license from the +original licensor to copy, distribute, link with or modify the Library +subject to these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties with +this License. + + 11. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Library at all. For example, if a patent +license would not permit royalty-free redistribution of the Library by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Library. + +If any portion of this section is held invalid or unenforceable under any +particular circumstance, the balance of the section is intended to apply, +and the section as a whole is intended to apply in other circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 12. If the distribution and/or use of the Library is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Library under this License may add +an explicit geographical distribution limitation excluding those countries, +so that distribution is permitted only in or among countries not thus +excluded. In such case, this License incorporates the limitation as if +written in the body of this License. + + 13. The Free Software Foundation may publish revised and/or new +versions of the Lesser General Public License from time to time. +Such new versions will be similar in spirit to the present version, +but may differ in detail to address new problems or concerns. + +Each version is given a distinguishing version number. If the Library +specifies a version number of this License which applies to it and +"any later version", you have the option of following the terms and +conditions either of that version or of any later version published by +the Free Software Foundation. If the Library does not specify a +license version number, you may choose any version ever published by +the Free Software Foundation. + + 14. If you wish to incorporate parts of the Library into other free +programs whose distribution conditions are incompatible with these, +write to the author to ask for permission. For software which is +copyrighted by the Free Software Foundation, write to the Free +Software Foundation; we sometimes make exceptions for this. Our +decision will be guided by the two goals of preserving the free status +of all derivatives of our free software and of promoting the sharing +and reuse of software generally. + + NO WARRANTY + + 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO +WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. +EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR +OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY +KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE +LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME +THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN +WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY +AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU +FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR +CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE +LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING +RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A +FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF +SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH +DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Libraries + + If you develop a new library, and you want it to be of the greatest +possible use to the public, we recommend making it free software that +everyone can redistribute and change. You can do so by permitting +redistribution under these terms (or, alternatively, under the terms of the +ordinary General Public License). + + To apply these terms, attach the following notices to the library. It is +safest to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least the +"copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +Also add information on how to contact you by electronic and paper mail. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the library, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the + library `Frob' (a library for tweaking knobs) written by James Random Hacker. + + , 1 April 1990 + Ty Coon, President of Vice + +That's all there is to it! + + diff --git a/contrib/sdk/sources/SDL-1.2.2/SDL_anim-0.2.1/Makefile b/contrib/sdk/sources/SDL-1.2.2/SDL_anim-0.2.1/Makefile new file mode 100644 index 000000000..9764d9e36 --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/SDL_anim-0.2.1/Makefile @@ -0,0 +1,5 @@ +OUTFILE = libSDL_anim.a +OBJS = anim.o +CFLAGS = -I$(MENUETDEV)/include/SDL + +include $(MENUETDEV)/makefiles/Makefile_for_lib diff --git a/contrib/sdk/sources/SDL-1.2.2/SDL_anim-0.2.1/Makefile.demo b/contrib/sdk/sources/SDL-1.2.2/SDL_anim-0.2.1/Makefile.demo new file mode 100644 index 000000000..947df8112 --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/SDL_anim-0.2.1/Makefile.demo @@ -0,0 +1,6 @@ +OUTFILE = showanim +OBJS = showanim.o +CFLAGS = -I. -I$(MENUETDEV)/include/SDL +LIBS = -L. -lSDL -lpng -lz -lSDL_anim -lpng -lz + +include $(MENUETDEV)/makefiles/Makefile_for_program diff --git a/contrib/sdk/sources/SDL-1.2.2/SDL_anim-0.2.1/README b/contrib/sdk/sources/SDL-1.2.2/SDL_anim-0.2.1/README new file mode 100644 index 000000000..ac973da09 --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/SDL_anim-0.2.1/README @@ -0,0 +1,35 @@ + +SDL_anim 0.2 + +The latest version of this library is available from: +http://tamale.net/SDL_anim/ + +This is a simple library to load animations and blit them to SDL surfaces. +This library supports PNG anim files. + +API: +#include "SDL_anim.h" + + SDL_Animation *Anim_Load( const char *file ); + int Anim_Free( SDL_Animation *anim ); + int Anim_GetFrameNum( float start, float now ); + int Anim_GetFrameRect( int frame, SDL_Rect *rect ); + int Anim_BlitFrame( SDL_Surface dest, float start, float now ); + int Anim_BlitFrameNum( SDL_Surface dest, int frame ); + int Anim_DisplayFormat( SDL_Animation *anim ); + +Two programs are included: + + `showanim' is an example program that uses SDL_anim. + `makeanim' creates PNG anim files. + +SDL_anim requires: + libpng http://www.cdrom.com/pub/png/ + zlib http://www.cdrom.com/pub/infozip/zlib/ + +This library is under the GNU Library General Public License, see the file +"LICENSE" for details. + +To build under unix: + +gcc -I/home/mike/include/SDL/ -L/home/mike/lib Anim.c makeanim.c -o makeanim -lpng -lz -lSDL -lSDLmain -lpthread diff --git a/contrib/sdk/sources/SDL-1.2.2/SDL_anim-0.2.1/SDL_anim.h b/contrib/sdk/sources/SDL-1.2.2/SDL_anim-0.2.1/SDL_anim.h new file mode 100644 index 000000000..6374b0b8d --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/SDL_anim-0.2.1/SDL_anim.h @@ -0,0 +1,60 @@ +/* + SDL_anim: an animation library for SDL + Copyright (C) 2001, 2002 Michael Leonhard + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the Free + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + Michael Leonhard + mike@tamale.net +*/ + +#ifndef _SDLanim_h +#define _SDLanim_h + +#include "SDL.h" +#include "begin_code.h" + +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +extern "C" { +#endif + +struct SDL_Animation; +typedef struct SDL_Animation { + SDL_Surface *surface; + int frames, w, h; + Uint32 duration; + } SDL_Animation; + +extern DECLSPEC struct SDL_Animation *Anim_Load( const char *file ); +extern DECLSPEC void Anim_Free( SDL_Animation *anim ); +extern DECLSPEC int Anim_GetFrameNum( SDL_Animation *anim, Uint32 start, Uint32 now ); +extern DECLSPEC int Anim_BlitFrame( SDL_Animation *anim, Uint32 start, Uint32 now, SDL_Surface *dest, SDL_Rect *dr ); +extern DECLSPEC void Anim_GetFrameRect( SDL_Animation *anim, int frame, SDL_Rect *rect ); +extern DECLSPEC int Anim_BlitFrameNum( SDL_Animation *anim, int frame, SDL_Surface *dest, SDL_Rect *dr ); +extern DECLSPEC int Anim_DisplayFormat( SDL_Animation *anim ); + +/* We'll use SDL for reporting errors */ +#define Anim_SetError SDL_SetError +#define Anim_GetError SDL_GetError + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +}; +#endif + +#include "SDL/close_code.h" + +#endif /* _SDL_anim_h */ diff --git a/contrib/sdk/sources/SDL-1.2.2/SDL_anim-0.2.1/anim.c b/contrib/sdk/sources/SDL-1.2.2/SDL_anim-0.2.1/anim.c new file mode 100644 index 000000000..34212b7b0 --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/SDL_anim-0.2.1/anim.c @@ -0,0 +1,362 @@ +/* + SDL_anim: an animation library for SDL + Copyright (C) 2001, 2002 Michael Leonhard + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the Free + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + Michael Leonhard + mike@tamale.net +*/ + +#include +#include +#include +#include +#include "SDL_anim.h" + +/* deal with MSVC++ crappiness */ +#ifdef WIN32UNDEFINED + #define strcasecmp _strcmpi + #endif + +void Anim_Free( SDL_Animation *anim ) { + SDL_FreeSurface( anim->surface ); + free( anim ); + } + +int Anim_GetFrameNum( SDL_Animation *anim, Uint32 start, Uint32 now ) { + int mspf, ms, frame; + if( now < start ) return 0; + + mspf = anim->duration / anim->frames; + ms = now - start; + if( mspf == 0 ) frame = 0; + else frame = ms / mspf; + + return frame; + } + +void Anim_GetFrameRect( SDL_Animation *anim, int frame, SDL_Rect *rect ) { + rect->x = anim->w * (frame % anim->frames); + rect->y = 0; + rect->w = anim->w; + rect->h = anim->h; + } + +int Anim_BlitFrame( SDL_Animation *anim, Uint32 start, Uint32 now, SDL_Surface *dest, SDL_Rect *dr ) { + int frame; + frame = Anim_GetFrameNum( anim, start, now ); + return Anim_BlitFrameNum( anim, frame, dest, dr ); + } + +int Anim_BlitFrameNum( SDL_Animation *anim, int frame, SDL_Surface *dest, SDL_Rect *dr ) { + SDL_Rect rect; + Anim_GetFrameRect( anim, frame, &rect ); + return SDL_BlitSurface( anim->surface, &rect, dest, dr ); + } + +int Anim_DisplayFormat( SDL_Animation *anim ) { + struct SDL_Surface *newsurface; + if( SDL_WasInit( SDL_INIT_VIDEO ) == 0 ) return 0;/*"Video is not initialized.\n"*/ + newsurface = SDL_DisplayFormatAlpha( anim->surface ); + if( !newsurface ) return 0; + anim->surface = newsurface; + return 1; + } + +int DoAnimFormat( char *text, int *duration, int *framewidth, int *numframes ) { + char *tok; + SDL_printf( "file is \"%s\"\n", text ); + + /* SDL_anim */ + tok = strtok( text, " " ); + if( !tok ) return 0; + if( strcasecmp( tok, "SDL_anim" ) != 0 ) { + SDL_printf( "no SDL_anim\n" ); + return 0; + } + + /* duration */ + tok = strtok( NULL, " " ); + if( !tok ) return 0; + *duration = atoi( tok ); + if( *duration < 1 ) { + SDL_printf( "no duration\n" ); + return 0; + } + + /* framewidth */ + tok = strtok( NULL, " " ); + if( !tok ) return 0; + *framewidth = atoi( tok ); + if( *framewidth < 1 ) { + SDL_printf( "no framewidth\n" ); + return 0; + } + + /* numframes */ + tok = strtok( NULL, " " ); + if( !tok ) return 0; + *numframes = atoi( tok ); + if( *numframes < 1 ) { + SDL_printf( "no numframes\n" ); + return 0; + } + + return 1; + } + +struct SDL_Animation *Anim_Load( const char *file ) { + int ckey = -1, i; + char buf[8]; + static FILE *fp; /* "static" prevents setjmp corruption */ + png_structp read_ptr; + png_infop read_info_ptr, end_info_ptr; + png_bytep *row_pointers; + png_textp text_ptr; + int num_text, t; + int interlace_type, compression_type, filter_type, bit_depth, color_type; + png_uint_32 width, height, row; + int duration, framewidth, numframes; + + png_color_16p background; + double white_x, white_y, red_x, red_y, green_x, green_y, blue_x, blue_y; + double gamma; + int intent; + png_uint_16p hist; + png_uint_32 offset_x, offset_y; + int unit_type; + png_charp purpose, units; + png_charpp params; + png_int_32 X0, X1; + int type, nparams; + png_uint_32 res_x, res_y; +/* png_colorp palette; + int num_palette; +*/ png_color_8p sig_bit; + png_bytep trans; + int num_trans; + png_color_16p trans_values; + + Uint32 Rmask; + Uint32 Gmask; + Uint32 Bmask; + Uint32 Amask; + + SDL_Animation *anim; + SDL_Surface *surface; + SDL_Palette *palette; + + if( !file ) return NULL; + +/* printf( "opening file \"%s\"\n", file ); +*/ + /* open the file handle */ + fp = fopen( file, "rb" ); + if( fp == NULL ) { + SDL_printf( "fopen() failed\n" ); + return NULL; + } + + /* check if it's PNG */ + if( fread( buf, 1, 8, fp ) != 8 ) { + SDL_printf( "fread() failed\n" ); + return NULL; + } + if( png_sig_cmp( buf, (png_size_t)0, 8 ) ) { + SDL_printf( "not a PNG file\n" ); + return NULL; + } + fseek( fp, 0, SEEK_SET ); + + /* allocate read structure */ + read_ptr = png_create_read_struct( PNG_LIBPNG_VER_STRING, (png_voidp)NULL, (png_error_ptr)NULL, (png_error_ptr)NULL ); + if( read_ptr == NULL ) { + SDL_printf( "png_create_read_struct() failed\n" ); + return NULL; + } + + /* allocate read info structure */ + read_info_ptr = png_create_info_struct( read_ptr ); + if( read_info_ptr == NULL ) { + SDL_printf( "png_create_info_struct() failed\n" ); + return NULL; + } + end_info_ptr = png_create_info_struct( read_ptr ); + if( end_info_ptr == NULL ) { + SDL_printf( "png_create_info_struct() failed\n" ); + return NULL; + } + + /* set error handler code */ + if( setjmp( read_ptr->jmpbuf ) ) { + SDL_printf( "libpng read error\n" ); + return NULL; + } + + /* initialize stream */ + png_init_io( read_ptr, fp ); + png_set_read_status_fn( read_ptr, NULL ); + + /* read png info struct */ + png_read_info( read_ptr, read_info_ptr ); + + /* get the info */ + if( !png_get_IHDR( read_ptr, read_info_ptr, &width, &height, &bit_depth, &color_type, &interlace_type, &compression_type, &filter_type ) ) { + SDL_printf( "png_get_IHDR() failed\n" ); + return NULL; + } + + /* background color */ + png_get_bKGD( read_ptr, read_info_ptr, &background ); + + png_get_cHRM( read_ptr, read_info_ptr, &white_x, &white_y, &red_x, &red_y, &green_x, &green_y, &blue_x, &blue_y ); + + /* gamma */ + png_get_gAMA( read_ptr, read_info_ptr, &gamma ); + + /* rendering intent */ + png_get_sRGB( read_ptr, read_info_ptr, &intent ); + + /* Histogram */ + png_get_hIST( read_ptr, read_info_ptr, &hist ); + + /* offsets */ + png_get_oFFs( read_ptr, read_info_ptr, &offset_x, &offset_y, &unit_type ); + + png_get_pCAL( read_ptr, read_info_ptr, &purpose, &X0, &X1, &type, &nparams, &units, ¶ms ); + + /* pixel density */ + png_get_pHYs( read_ptr, read_info_ptr, &res_x, &res_y, &unit_type ); + +/* png_get_PLTE( read_ptr, read_info_ptr, &palette, &num_palette ); +*/ + /* significant bits */ + png_get_sBIT( read_ptr, read_info_ptr, &sig_bit ); + + /* transparency */ + if( png_get_tRNS( read_ptr, read_info_ptr, &trans, &num_trans, &trans_values ) ) { + if( color_type == PNG_COLOR_TYPE_PALETTE ) { + if( num_trans == 1 ) ckey = trans[0]; + else png_set_expand( read_ptr ); + } + else ckey = 0; /* actual value will be set later */ + } + + /* text chunks */ + num_text = 0; + if( !png_get_text( read_ptr, read_info_ptr, &text_ptr, &num_text ) ) { + SDL_printf( "file has no text chunks\n" ); + return NULL; + } + for( t = 0; t < num_text; t++ ) { + if( strcasecmp( text_ptr[t].key, "format" ) == 0 ) { + if( DoAnimFormat( text_ptr[t].text, &duration, &framewidth, &numframes ) ) break; + } + } + if( t == num_text ) { + SDL_printf( "file is not an SDL_anim PNG\n" ); + return NULL; + } + + png_set_strip_16( read_ptr ); + png_set_packing( read_ptr ); + if(color_type == PNG_COLOR_TYPE_GRAY) + png_set_expand( read_ptr ); + + /* Allocate the SDL surface to hold the image */ + Rmask = Gmask = Bmask = Amask = 0; + if( color_type != PNG_COLOR_TYPE_PALETTE ) { + if( SDL_BYTEORDER == SDL_LIL_ENDIAN ) { + Rmask = 0x000000FF; + Gmask = 0x0000FF00; + Bmask = 0x00FF0000; + Amask = (read_info_ptr->channels == 4)? 0xFF000000 : 0; + } + else { + int s = (read_info_ptr->channels == 4) ? 0 : 8; + Rmask = 0xFF000000 >> s; + Gmask = 0x00FF0000 >> s; + Bmask = 0x0000FF00 >> s; + Amask = 0x000000FF >> s; + } + } + + surface = SDL_AllocSurface( SDL_SWSURFACE, width, height, bit_depth * read_info_ptr->channels, Rmask, Gmask, Bmask, Amask ); + if( surface == NULL ) { + Anim_SetError("Out of memory"); + return NULL; + } + + if(ckey != -1) { + if( color_type != PNG_COLOR_TYPE_PALETTE ) ckey = SDL_MapRGB( surface->format, (Uint8)trans_values->red, (Uint8)trans_values->green, (Uint8)trans_values->blue ); + SDL_SetColorKey( surface, SDL_SRCCOLORKEY, ckey ); + } + + /* allocate row pointers */ + row_pointers = (png_bytep *)malloc( sizeof( png_bytep ) * height ); + if( row_pointers == NULL ) { + SDL_printf( "malloc() failed\n" ); + return NULL; + } + for( row = 0; row < height; row++ ) { + row_pointers[row] = (Uint8 *)surface->pixels + row * surface->pitch; + } + + png_read_image( read_ptr, row_pointers ); + + /* end io */ +/* printf( "done\n" ); +*/ png_read_end( read_ptr, end_info_ptr ); + + /* cleanup */ + png_destroy_read_struct( &read_ptr, &read_info_ptr, &end_info_ptr); + fclose( fp ); + + /* Load the palette, if any */ + palette = surface->format->palette; + if( palette ) { + if(color_type == PNG_COLOR_TYPE_GRAY) { + palette->ncolors = 256; + for( i = 0; i < 256; i++ ) { + palette->colors[i].r = i; + palette->colors[i].g = i; + palette->colors[i].b = i; + } + } + else if( read_info_ptr->num_palette > 0 ) { + palette->ncolors = read_info_ptr->num_palette; + for( i = 0; i < read_info_ptr->num_palette; ++i ) { + palette->colors[i].b = read_info_ptr->palette[i].blue; + palette->colors[i].g = read_info_ptr->palette[i].green; + palette->colors[i].r = read_info_ptr->palette[i].red; + } + } + } + + anim = (struct SDL_Animation *)malloc( sizeof( struct SDL_Animation ) ); + if( !anim ) { + SDL_printf( "malloc() failed\n" ); + return NULL; + } + + anim->surface = surface; + anim->w = framewidth; + anim->h = height; + anim->frames = numframes; + anim->duration = duration; + + return anim; + } diff --git a/contrib/sdk/sources/SDL-1.2.2/SDL_anim-0.2.1/anim.c.BAK b/contrib/sdk/sources/SDL-1.2.2/SDL_anim-0.2.1/anim.c.BAK new file mode 100644 index 000000000..0f833a311 --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/SDL_anim-0.2.1/anim.c.BAK @@ -0,0 +1,362 @@ +/* + SDL_anim: an animation library for SDL + Copyright (C) 2001, 2002 Michael Leonhard + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the Free + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + Michael Leonhard + mike@tamale.net +*/ + +#include +#include +#include +#include +#include "SDL_anim.h" + +/* deal with MSVC++ crappiness */ +#ifdef WIN32 + #define strcasecmp _strcmpi + #endif + +void Anim_Free( SDL_Animation *anim ) { + SDL_FreeSurface( anim->surface ); + free( anim ); + } + +int Anim_GetFrameNum( SDL_Animation *anim, Uint32 start, Uint32 now ) { + int mspf, ms, frame; + if( now < start ) return 0; + + mspf = anim->duration / anim->frames; + ms = now - start; + if( mspf == 0 ) frame = 0; + else frame = ms / mspf; + + return frame; + } + +void Anim_GetFrameRect( SDL_Animation *anim, int frame, SDL_Rect *rect ) { + rect->x = anim->w * (frame % anim->frames); + rect->y = 0; + rect->w = anim->w; + rect->h = anim->h; + } + +int Anim_BlitFrame( SDL_Animation *anim, Uint32 start, Uint32 now, SDL_Surface *dest, SDL_Rect *dr ) { + int frame; + frame = Anim_GetFrameNum( anim, start, now ); + return Anim_BlitFrameNum( anim, frame, dest, dr ); + } + +int Anim_BlitFrameNum( SDL_Animation *anim, int frame, SDL_Surface *dest, SDL_Rect *dr ) { + SDL_Rect rect; + Anim_GetFrameRect( anim, frame, &rect ); + return SDL_BlitSurface( anim->surface, &rect, dest, dr ); + } + +int Anim_DisplayFormat( SDL_Animation *anim ) { + struct SDL_Surface *newsurface; + if( SDL_WasInit( SDL_INIT_VIDEO ) == 0 ) return 0;/*"Video is not initialized.\n"*/ + newsurface = SDL_DisplayFormatAlpha( anim->surface ); + if( !newsurface ) return 0; + anim->surface = newsurface; + return 1; + } + +int DoAnimFormat( char *text, int *duration, int *framewidth, int *numframes ) { + char *tok; + SDL_printf( "file is \"%s\"\n", text ); + + /* SDL_anim */ + tok = strtok( text, " " ); + if( !tok ) return 0; + if( strcasecmp( tok, "SDL_anim" ) != 0 ) { + SDL_printf( "no SDL_anim\n" ); + return 0; + } + + /* duration */ + tok = strtok( NULL, " " ); + if( !tok ) return 0; + *duration = atoi( tok ); + if( *duration < 1 ) { + SDL_printf( "no duration\n" ); + return 0; + } + + /* framewidth */ + tok = strtok( NULL, " " ); + if( !tok ) return 0; + *framewidth = atoi( tok ); + if( *framewidth < 1 ) { + SDL_printf( "no framewidth\n" ); + return 0; + } + + /* numframes */ + tok = strtok( NULL, " " ); + if( !tok ) return 0; + *numframes = atoi( tok ); + if( *numframes < 1 ) { + SDL_printf( "no numframes\n" ); + return 0; + } + + return 1; + } + +struct SDL_Animation *Anim_Load( const char *file ) { + int ckey = -1, i; + char buf[8]; + static FILE *fp; /* "static" prevents setjmp corruption */ + png_structp read_ptr; + png_infop read_info_ptr, end_info_ptr; + png_bytep *row_pointers; + png_textp text_ptr; + int num_text, t; + int interlace_type, compression_type, filter_type, bit_depth, color_type; + png_uint_32 width, height, row; + int duration, framewidth, numframes; + + png_color_16p background; + double white_x, white_y, red_x, red_y, green_x, green_y, blue_x, blue_y; + double gamma; + int intent; + png_uint_16p hist; + png_uint_32 offset_x, offset_y; + int unit_type; + png_charp purpose, units; + png_charpp params; + png_int_32 X0, X1; + int type, nparams; + png_uint_32 res_x, res_y; +/* png_colorp palette; + int num_palette; +*/ png_color_8p sig_bit; + png_bytep trans; + int num_trans; + png_color_16p trans_values; + + Uint32 Rmask; + Uint32 Gmask; + Uint32 Bmask; + Uint32 Amask; + + SDL_Animation *anim; + SDL_Surface *surface; + SDL_Palette *palette; + + if( !file ) return NULL; + +/* printf( "opening file \"%s\"\n", file ); +*/ + /* open the file handle */ + fp = fopen( file, "rb" ); + if( fp == NULL ) { + SDL_printf( "fopen() failed\n" ); + return NULL; + } + + /* check if it's PNG */ + if( fread( buf, 1, 8, fp ) != 8 ) { + SDL_printf( "fread() failed\n" ); + return NULL; + } + if( png_sig_cmp( buf, (png_size_t)0, 8 ) ) { + SDL_printf( "not a PNG file\n" ); + return NULL; + } + fseek( fp, 0, SEEK_SET ); + + /* allocate read structure */ + read_ptr = png_create_read_struct( PNG_LIBPNG_VER_STRING, (png_voidp)NULL, (png_error_ptr)NULL, (png_error_ptr)NULL ); + if( read_ptr == NULL ) { + SDL_printf( "png_create_read_struct() failed\n" ); + return NULL; + } + + /* allocate read info structure */ + read_info_ptr = png_create_info_struct( read_ptr ); + if( read_info_ptr == NULL ) { + SDL_printf( "png_create_info_struct() failed\n" ); + return NULL; + } + end_info_ptr = png_create_info_struct( read_ptr ); + if( end_info_ptr == NULL ) { + SDL_printf( "png_create_info_struct() failed\n" ); + return NULL; + } + + /* set error handler code */ + if( setjmp( read_ptr->jmpbuf ) ) { + SDL_printf( "libpng read error\n" ); + return NULL; + } + + /* initialize stream */ + png_init_io( read_ptr, fp ); + png_set_read_status_fn( read_ptr, NULL ); + + /* read png info struct */ + png_read_info( read_ptr, read_info_ptr ); + + /* get the info */ + if( !png_get_IHDR( read_ptr, read_info_ptr, &width, &height, &bit_depth, &color_type, &interlace_type, &compression_type, &filter_type ) ) { + SDL_printf( "png_get_IHDR() failed\n" ); + return NULL; + } + + /* background color */ + png_get_bKGD( read_ptr, read_info_ptr, &background ); + + png_get_cHRM( read_ptr, read_info_ptr, &white_x, &white_y, &red_x, &red_y, &green_x, &green_y, &blue_x, &blue_y ); + + /* gamma */ + png_get_gAMA( read_ptr, read_info_ptr, &gamma ); + + /* rendering intent */ + png_get_sRGB( read_ptr, read_info_ptr, &intent ); + + /* Histogram */ + png_get_hIST( read_ptr, read_info_ptr, &hist ); + + /* offsets */ + png_get_oFFs( read_ptr, read_info_ptr, &offset_x, &offset_y, &unit_type ); + + png_get_pCAL( read_ptr, read_info_ptr, &purpose, &X0, &X1, &type, &nparams, &units, ¶ms ); + + /* pixel density */ + png_get_pHYs( read_ptr, read_info_ptr, &res_x, &res_y, &unit_type ); + +/* png_get_PLTE( read_ptr, read_info_ptr, &palette, &num_palette ); +*/ + /* significant bits */ + png_get_sBIT( read_ptr, read_info_ptr, &sig_bit ); + + /* transparency */ + if( png_get_tRNS( read_ptr, read_info_ptr, &trans, &num_trans, &trans_values ) ) { + if( color_type == PNG_COLOR_TYPE_PALETTE ) { + if( num_trans == 1 ) ckey = trans[0]; + else png_set_expand( read_ptr ); + } + else ckey = 0; /* actual value will be set later */ + } + + /* text chunks */ + num_text = 0; + if( !png_get_text( read_ptr, read_info_ptr, &text_ptr, &num_text ) ) { + SDL_printf( "file has no text chunks\n" ); + return NULL; + } + for( t = 0; t < num_text; t++ ) { + if( strcasecmp( text_ptr[t].key, "format" ) == 0 ) { + if( DoAnimFormat( text_ptr[t].text, &duration, &framewidth, &numframes ) ) break; + } + } + if( t == num_text ) { + SDL_printf( "file is not an SDL_anim PNG\n" ); + return NULL; + } + + png_set_strip_16( read_ptr ); + png_set_packing( read_ptr ); + if(color_type == PNG_COLOR_TYPE_GRAY) + png_set_expand( read_ptr ); + + /* Allocate the SDL surface to hold the image */ + Rmask = Gmask = Bmask = Amask = 0; + if( color_type != PNG_COLOR_TYPE_PALETTE ) { + if( SDL_BYTEORDER == SDL_LIL_ENDIAN ) { + Rmask = 0x000000FF; + Gmask = 0x0000FF00; + Bmask = 0x00FF0000; + Amask = (read_info_ptr->channels == 4)? 0xFF000000 : 0; + } + else { + int s = (read_info_ptr->channels == 4) ? 0 : 8; + Rmask = 0xFF000000 >> s; + Gmask = 0x00FF0000 >> s; + Bmask = 0x0000FF00 >> s; + Amask = 0x000000FF >> s; + } + } + + surface = SDL_AllocSurface( SDL_SWSURFACE, width, height, bit_depth * read_info_ptr->channels, Rmask, Gmask, Bmask, Amask ); + if( surface == NULL ) { + Anim_SetError("Out of memory"); + return NULL; + } + + if(ckey != -1) { + if( color_type != PNG_COLOR_TYPE_PALETTE ) ckey = SDL_MapRGB( surface->format, (Uint8)trans_values->red, (Uint8)trans_values->green, (Uint8)trans_values->blue ); + SDL_SetColorKey( surface, SDL_SRCCOLORKEY, ckey ); + } + + /* allocate row pointers */ + row_pointers = (png_bytep *)malloc( sizeof( png_bytep ) * height ); + if( row_pointers == NULL ) { + SDL_printf( "malloc() failed\n" ); + return NULL; + } + for( row = 0; row < height; row++ ) { + row_pointers[row] = (Uint8 *)surface->pixels + row * surface->pitch; + } + + png_read_image( read_ptr, row_pointers ); + + /* end io */ +/* printf( "done\n" ); +*/ png_read_end( read_ptr, end_info_ptr ); + + /* cleanup */ + png_destroy_read_struct( &read_ptr, &read_info_ptr, &end_info_ptr); + fclose( fp ); + + /* Load the palette, if any */ + palette = surface->format->palette; + if( palette ) { + if(color_type == PNG_COLOR_TYPE_GRAY) { + palette->ncolors = 256; + for( i = 0; i < 256; i++ ) { + palette->colors[i].r = i; + palette->colors[i].g = i; + palette->colors[i].b = i; + } + } + else if( read_info_ptr->num_palette > 0 ) { + palette->ncolors = read_info_ptr->num_palette; + for( i = 0; i < read_info_ptr->num_palette; ++i ) { + palette->colors[i].b = read_info_ptr->palette[i].blue; + palette->colors[i].g = read_info_ptr->palette[i].green; + palette->colors[i].r = read_info_ptr->palette[i].red; + } + } + } + + anim = (struct SDL_Animation *)malloc( sizeof( struct SDL_Animation ) ); + if( !anim ) { + SDL_printf( "malloc() failed\n" ); + return NULL; + } + + anim->surface = surface; + anim->w = framewidth; + anim->h = height; + anim->frames = numframes; + anim->duration = duration; + + return anim; + } diff --git a/contrib/sdk/sources/SDL-1.2.2/SDL_anim-0.2.1/makeanim.c b/contrib/sdk/sources/SDL-1.2.2/SDL_anim-0.2.1/makeanim.c new file mode 100644 index 000000000..340a4dd43 --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/SDL_anim-0.2.1/makeanim.c @@ -0,0 +1,328 @@ +/* + SDL_anim: an animation library for SDL + Copyright (C) 2001, 2002 Michael Leonhard + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the Free + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + Michael Leonhard + mike@tamale.net +*/ + +#include +#include +#include + +/* deal with MSVC++ crappiness */ +#ifdef WIN32UNDEFINED + #define snprintf _snprintf + #endif + +typedef struct inputstruct { + FILE *file; + char *name; + png_structp read_ptr; + png_infop read_info_ptr; + }; + +int numfiles; +struct inputstruct *input; + +int main( int argc, char *argv[] ) { + int f, rowbytes; + char buf[256]; + static FILE *fpout; /* "static" prevents setjmp corruption */ + png_structp write_ptr; + png_infop write_info_ptr, end_info_ptr; + png_bytep row_buf, here; + png_uint_32 y; + png_textp text_ptr, new_text_ptr; + int num_text; + + int interlace_type, compression_type, filter_type, bit_depth, color_type; + int it, ct, ft, bd, clrt; + png_uint_32 width, height, w, h; + + int duration; + + if( argc < 4 ) { + printf( "makeanim v0.2\nusage: makeanim \n" ); + printf( "example: makeanim 1500 a00.png a01.png a02.png a03.png a04.png a.anim\n" ); + return 1; + } + + duration = atoi( argv[1] ); + if( duration < 1 ) { + printf( "duration is incorrect\n" ); + return 1; + } + + numfiles = argc - 3; + input = (struct inputstruct *)malloc( sizeof( struct inputstruct ) * numfiles ); + if( !input ) return 1; + + for( f = 0; f < numfiles; f++ ) { + input[f].name = argv[f + 2]; + printf( "opening file %d, \"%s\"\n", f, input[f].name ); + + /* open the file handle */ + input[f].file = fopen( input[f].name, "rb" ); + if( input[f].file == NULL ) { + printf( "fopen() failed\n" ); + return 1; + } + + /* check if it's PNG */ + if( fread( buf, 1, 8, input[f].file ) != 8 ) { + printf( "fread() failed for file \"%s\"\n", input[f].name ); + return 1; + } + if( png_sig_cmp( buf, (png_size_t)0, 8 ) ) { + printf( "not a PNG file\n" ); + return 1; + } + fseek( input[f].file, 0, SEEK_SET ); + + /* allocate read structure */ + input[f].read_ptr = png_create_read_struct( PNG_LIBPNG_VER_STRING, (png_voidp)NULL, (png_error_ptr)NULL, (png_error_ptr)NULL ); + if( input[f].read_ptr == NULL ) { + printf( "png_create_read_struct() failed\n" ); + return 1; + } + + /* allocate read info structure */ + input[f].read_info_ptr = png_create_info_struct( input[f].read_ptr ); + if( input[f].read_info_ptr == NULL ) { + printf( "png_create_info_struct() failed\n" ); + return 1; + } + + + /* set error handler code */ + if( setjmp( input[f].read_ptr->jmpbuf ) ) { + printf( "libpng read error\n" ); + return 1; + } + + /* initialize stream */ + png_init_io( input[f].read_ptr, input[f].file ); + png_set_read_status_fn( input[f].read_ptr, NULL ); + + /* read png info struct */ + png_read_info( input[f].read_ptr, input[f].read_info_ptr ); + + /* get the info */ + if( !png_get_IHDR( input[f].read_ptr, input[f].read_info_ptr, &w, &h, &bd, &clrt, &it, &ct, &ft ) ) { + printf( "png_get_IHDR() failed\n" ); + return 1; + } + + /* save the info of the first frame */ + if( f == 0 ) { + width = w; + height = h; + bit_depth = bd; + color_type = clrt; + interlace_type = it; + compression_type = ct; + filter_type = ft; + } + /* compare all other frames to first frame */ + else if( (w != width) || + (h != height) || + (bd != bit_depth) || + (clrt != color_type) || + (it != interlace_type) || + (ct != compression_type) || + (ft != filter_type) ) { + if( w != width ) printf( "width is different\n" ); + if( h != height ) printf( "height is different\n" ); + if( bd != bit_depth ) printf( "bit depth is different\n" ); + if( clrt != color_type ) printf( "color type is different\n" ); + if( it != interlace_type ) printf( "interlace type is different\n" ); + if( ct != compression_type ) printf( "compression type is different\n" ); + if( ft != filter_type ) printf( "filter type is different\n" ); + return 1; + } + } + + row_buf = (png_bytep)NULL; + + /* open output file */ + printf( "opening file \"%s\"\n", argv[numfiles + 2] ); + fpout = fopen( argv[numfiles + 2], "wb" ); + if( fpout == NULL ) { + printf( "fopen() failed\n" ); + return 1; + } + + /* allocate write structure */ + write_ptr = png_create_write_struct( PNG_LIBPNG_VER_STRING, (png_voidp)NULL, (png_error_ptr)NULL, (png_error_ptr)NULL ); + + /* allocate info structures */ + write_info_ptr = png_create_info_struct( write_ptr ); + end_info_ptr = png_create_info_struct( write_ptr ); + + /* error handling */ + if( setjmp( write_ptr->jmpbuf ) ) { + printf( "libpng write error\n" ); + return 1; + } + + /* initialize output stream */ + png_init_io( write_ptr, fpout ); + png_set_write_status_fn( write_ptr, NULL ); + + /* set info */ + png_set_IHDR( write_ptr, write_info_ptr, width * numfiles, height, bit_depth, color_type, PNG_INTERLACE_NONE, compression_type, filter_type); + + /* image characteristics */ + { + png_color_16p background; + double white_x, white_y, red_x, red_y, green_x, green_y, blue_x, blue_y; + double gamma; + int intent; + png_uint_16p hist; + png_uint_32 offset_x, offset_y; + int unit_type; + png_charp purpose, units; + png_charpp params; + png_int_32 X0, X1; + int type, nparams; + png_uint_32 res_x, res_y; + png_colorp palette; + int num_palette; + png_color_8p sig_bit; + png_bytep trans; + int num_trans; + png_color_16p trans_values; + + /* background color */ + if( png_get_bKGD( input[0].read_ptr, input[0].read_info_ptr, &background ) ) { + png_set_bKGD( write_ptr, write_info_ptr, background ); + } + + if( png_get_cHRM( input[0].read_ptr, input[0].read_info_ptr, &white_x, &white_y, &red_x, &red_y, &green_x, &green_y, &blue_x, &blue_y ) ) { + png_set_cHRM( write_ptr, write_info_ptr, white_x, white_y, red_x, red_y, green_x, green_y, blue_x, blue_y ); + } + + /* gamma */ + if( png_get_gAMA( input[0].read_ptr, input[0].read_info_ptr, &gamma ) ) { + png_set_gAMA( write_ptr, write_info_ptr, gamma ); + } + + /* rendering intent */ + if( png_get_sRGB( input[0].read_ptr, input[0].read_info_ptr, &intent ) ) { + png_set_sRGB( write_ptr, write_info_ptr, intent ); + } + + /* Histogram */ + if( png_get_hIST( input[0].read_ptr, input[0].read_info_ptr, &hist ) ) { + png_set_hIST( write_ptr, write_info_ptr, hist ); + } + + /* offsets */ + if( png_get_oFFs( input[0].read_ptr, input[0].read_info_ptr, &offset_x, &offset_y, &unit_type ) ) { + png_set_oFFs( write_ptr, write_info_ptr, offset_x, offset_y, unit_type ); + } + + if( png_get_pCAL( input[0].read_ptr, input[0].read_info_ptr, &purpose, &X0, &X1, &type, &nparams, &units, ¶ms ) ) { + png_set_pCAL( write_ptr, write_info_ptr, purpose, X0, X1, type, nparams, units, params ); + } + + /* pixel density */ + if( png_get_pHYs( input[0].read_ptr, input[0].read_info_ptr, &res_x, &res_y, &unit_type ) ) { + png_set_pHYs( write_ptr, write_info_ptr, res_x, res_y, unit_type ); + } + + /* text chunks */ +/* if( png_get_text( input[0].read_ptr, input[0].read_info_ptr, &text_ptr, &num_text ) > 0 ) { + printf( "Handling %d tEXt/zTXt chunks\n", num_text ); + png_set_text( write_ptr, write_info_ptr, text_ptr, num_text ); + } +*/ + /* palette */ + if( png_get_PLTE( input[0].read_ptr, input[0].read_info_ptr, &palette, &num_palette ) ) { + png_set_PLTE( write_ptr, write_info_ptr, palette, num_palette ); + } + + /* significant bits */ + if( png_get_sBIT( input[0].read_ptr, input[0].read_info_ptr, &sig_bit ) ) { + png_set_sBIT( write_ptr, write_info_ptr, sig_bit ); + } + + /* transparency */ + if( png_get_tRNS( input[0].read_ptr, input[0].read_info_ptr, &trans, &num_trans, &trans_values ) ) { + png_set_tRNS( write_ptr, write_info_ptr, trans, num_trans, trans_values ); + } + } + + /* text chunks */ + num_text = 0; + if( !png_get_text( input[0].read_ptr, input[0].read_info_ptr, &text_ptr, &num_text ) ) num_text = 0; + new_text_ptr = (struct png_text_struct *)malloc( sizeof( struct png_text_struct ) * num_text + 1 ); + if( !new_text_ptr ) { + printf( "malloc() failed\n" ); + return 1; + } + + memcpy( new_text_ptr, text_ptr, sizeof( struct png_text_struct ) * num_text ); + + snprintf( buf, 255, "SDL_anim %d %d %d", duration, width, numfiles ); + buf[255] = 0; + new_text_ptr[num_text].compression = PNG_TEXT_COMPRESSION_NONE; + new_text_ptr[num_text].key = "format"; + new_text_ptr[num_text].text = buf; + new_text_ptr[num_text].text_length = strlen( buf ); + num_text++; + png_set_text( write_ptr, write_info_ptr, new_text_ptr, num_text ); + + /* write info */ + png_write_info( write_ptr, write_info_ptr ); + + /* allocate buffer */ + rowbytes = png_get_rowbytes( input[0].read_ptr, input[0].read_info_ptr ); + row_buf = (png_bytep)png_malloc( write_ptr, rowbytes * numfiles ); + if( row_buf == NULL ) { + printf( "png_malloc() failed\n" ); + return 1; + } + + /* copy raw data */ + for( y = 0; y < height; y++ ) { + /* grab a scanline from each file */ + here = row_buf; + for( f = 0; f < numfiles; f++ ) { + png_read_rows( input[f].read_ptr, (png_bytepp)&here, (png_bytepp)NULL, 1 ); + here += rowbytes; + } + /* write the long scanline */ + png_write_rows( write_ptr, (png_bytepp)&row_buf, 1 ); + } + + /* end io */ + for( f = 0; f < numfiles; f++ ) png_read_end( input[f].read_ptr, end_info_ptr ); + png_write_end( write_ptr, end_info_ptr ); + + /* cleanup */ + png_free( write_ptr, row_buf ); + for( f = 0; f < numfiles; f++ ) { + png_destroy_read_struct( &input[f].read_ptr, &input[f].read_info_ptr, &end_info_ptr); + fclose( input[f].file ); + } + png_destroy_write_struct( &write_ptr, &write_info_ptr ); + fclose( fpout ); + + return 0; + } diff --git a/contrib/sdk/sources/SDL-1.2.2/SDL_anim-0.2.1/makeanim.c.BAK b/contrib/sdk/sources/SDL-1.2.2/SDL_anim-0.2.1/makeanim.c.BAK new file mode 100644 index 000000000..f6306c08b --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/SDL_anim-0.2.1/makeanim.c.BAK @@ -0,0 +1,328 @@ +/* + SDL_anim: an animation library for SDL + Copyright (C) 2001, 2002 Michael Leonhard + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the Free + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + Michael Leonhard + mike@tamale.net +*/ + +#include +#include +#include + +/* deal with MSVC++ crappiness */ +#ifdef WIN32 + #define snprintf _snprintf + #endif + +typedef struct inputstruct { + FILE *file; + char *name; + png_structp read_ptr; + png_infop read_info_ptr; + }; + +int numfiles; +struct inputstruct *input; + +int main( int argc, char *argv[] ) { + int f, rowbytes; + char buf[256]; + static FILE *fpout; /* "static" prevents setjmp corruption */ + png_structp write_ptr; + png_infop write_info_ptr, end_info_ptr; + png_bytep row_buf, here; + png_uint_32 y; + png_textp text_ptr, new_text_ptr; + int num_text; + + int interlace_type, compression_type, filter_type, bit_depth, color_type; + int it, ct, ft, bd, clrt; + png_uint_32 width, height, w, h; + + int duration; + + if( argc < 4 ) { + printf( "makeanim v0.2\nusage: makeanim \n" ); + printf( "example: makeanim 1500 a00.png a01.png a02.png a03.png a04.png a.anim\n" ); + return 1; + } + + duration = atoi( argv[1] ); + if( duration < 1 ) { + printf( "duration is incorrect\n" ); + return 1; + } + + numfiles = argc - 3; + input = (struct inputstruct *)malloc( sizeof( struct inputstruct ) * numfiles ); + if( !input ) return 1; + + for( f = 0; f < numfiles; f++ ) { + input[f].name = argv[f + 2]; + printf( "opening file %d, \"%s\"\n", f, input[f].name ); + + /* open the file handle */ + input[f].file = fopen( input[f].name, "rb" ); + if( input[f].file == NULL ) { + printf( "fopen() failed\n" ); + return 1; + } + + /* check if it's PNG */ + if( fread( buf, 1, 8, input[f].file ) != 8 ) { + printf( "fread() failed for file \"%s\"\n", input[f].name ); + return 1; + } + if( png_sig_cmp( buf, (png_size_t)0, 8 ) ) { + printf( "not a PNG file\n" ); + return 1; + } + fseek( input[f].file, 0, SEEK_SET ); + + /* allocate read structure */ + input[f].read_ptr = png_create_read_struct( PNG_LIBPNG_VER_STRING, (png_voidp)NULL, (png_error_ptr)NULL, (png_error_ptr)NULL ); + if( input[f].read_ptr == NULL ) { + printf( "png_create_read_struct() failed\n" ); + return 1; + } + + /* allocate read info structure */ + input[f].read_info_ptr = png_create_info_struct( input[f].read_ptr ); + if( input[f].read_info_ptr == NULL ) { + printf( "png_create_info_struct() failed\n" ); + return 1; + } + + + /* set error handler code */ + if( setjmp( input[f].read_ptr->jmpbuf ) ) { + printf( "libpng read error\n" ); + return 1; + } + + /* initialize stream */ + png_init_io( input[f].read_ptr, input[f].file ); + png_set_read_status_fn( input[f].read_ptr, NULL ); + + /* read png info struct */ + png_read_info( input[f].read_ptr, input[f].read_info_ptr ); + + /* get the info */ + if( !png_get_IHDR( input[f].read_ptr, input[f].read_info_ptr, &w, &h, &bd, &clrt, &it, &ct, &ft ) ) { + printf( "png_get_IHDR() failed\n" ); + return 1; + } + + /* save the info of the first frame */ + if( f == 0 ) { + width = w; + height = h; + bit_depth = bd; + color_type = clrt; + interlace_type = it; + compression_type = ct; + filter_type = ft; + } + /* compare all other frames to first frame */ + else if( (w != width) || + (h != height) || + (bd != bit_depth) || + (clrt != color_type) || + (it != interlace_type) || + (ct != compression_type) || + (ft != filter_type) ) { + if( w != width ) printf( "width is different\n" ); + if( h != height ) printf( "height is different\n" ); + if( bd != bit_depth ) printf( "bit depth is different\n" ); + if( clrt != color_type ) printf( "color type is different\n" ); + if( it != interlace_type ) printf( "interlace type is different\n" ); + if( ct != compression_type ) printf( "compression type is different\n" ); + if( ft != filter_type ) printf( "filter type is different\n" ); + return 1; + } + } + + row_buf = (png_bytep)NULL; + + /* open output file */ + printf( "opening file \"%s\"\n", argv[numfiles + 2] ); + fpout = fopen( argv[numfiles + 2], "wb" ); + if( fpout == NULL ) { + printf( "fopen() failed\n" ); + return 1; + } + + /* allocate write structure */ + write_ptr = png_create_write_struct( PNG_LIBPNG_VER_STRING, (png_voidp)NULL, (png_error_ptr)NULL, (png_error_ptr)NULL ); + + /* allocate info structures */ + write_info_ptr = png_create_info_struct( write_ptr ); + end_info_ptr = png_create_info_struct( write_ptr ); + + /* error handling */ + if( setjmp( write_ptr->jmpbuf ) ) { + printf( "libpng write error\n" ); + return 1; + } + + /* initialize output stream */ + png_init_io( write_ptr, fpout ); + png_set_write_status_fn( write_ptr, NULL ); + + /* set info */ + png_set_IHDR( write_ptr, write_info_ptr, width * numfiles, height, bit_depth, color_type, PNG_INTERLACE_NONE, compression_type, filter_type); + + /* image characteristics */ + { + png_color_16p background; + double white_x, white_y, red_x, red_y, green_x, green_y, blue_x, blue_y; + double gamma; + int intent; + png_uint_16p hist; + png_uint_32 offset_x, offset_y; + int unit_type; + png_charp purpose, units; + png_charpp params; + png_int_32 X0, X1; + int type, nparams; + png_uint_32 res_x, res_y; + png_colorp palette; + int num_palette; + png_color_8p sig_bit; + png_bytep trans; + int num_trans; + png_color_16p trans_values; + + /* background color */ + if( png_get_bKGD( input[0].read_ptr, input[0].read_info_ptr, &background ) ) { + png_set_bKGD( write_ptr, write_info_ptr, background ); + } + + if( png_get_cHRM( input[0].read_ptr, input[0].read_info_ptr, &white_x, &white_y, &red_x, &red_y, &green_x, &green_y, &blue_x, &blue_y ) ) { + png_set_cHRM( write_ptr, write_info_ptr, white_x, white_y, red_x, red_y, green_x, green_y, blue_x, blue_y ); + } + + /* gamma */ + if( png_get_gAMA( input[0].read_ptr, input[0].read_info_ptr, &gamma ) ) { + png_set_gAMA( write_ptr, write_info_ptr, gamma ); + } + + /* rendering intent */ + if( png_get_sRGB( input[0].read_ptr, input[0].read_info_ptr, &intent ) ) { + png_set_sRGB( write_ptr, write_info_ptr, intent ); + } + + /* Histogram */ + if( png_get_hIST( input[0].read_ptr, input[0].read_info_ptr, &hist ) ) { + png_set_hIST( write_ptr, write_info_ptr, hist ); + } + + /* offsets */ + if( png_get_oFFs( input[0].read_ptr, input[0].read_info_ptr, &offset_x, &offset_y, &unit_type ) ) { + png_set_oFFs( write_ptr, write_info_ptr, offset_x, offset_y, unit_type ); + } + + if( png_get_pCAL( input[0].read_ptr, input[0].read_info_ptr, &purpose, &X0, &X1, &type, &nparams, &units, ¶ms ) ) { + png_set_pCAL( write_ptr, write_info_ptr, purpose, X0, X1, type, nparams, units, params ); + } + + /* pixel density */ + if( png_get_pHYs( input[0].read_ptr, input[0].read_info_ptr, &res_x, &res_y, &unit_type ) ) { + png_set_pHYs( write_ptr, write_info_ptr, res_x, res_y, unit_type ); + } + + /* text chunks */ +/* if( png_get_text( input[0].read_ptr, input[0].read_info_ptr, &text_ptr, &num_text ) > 0 ) { + printf( "Handling %d tEXt/zTXt chunks\n", num_text ); + png_set_text( write_ptr, write_info_ptr, text_ptr, num_text ); + } +*/ + /* palette */ + if( png_get_PLTE( input[0].read_ptr, input[0].read_info_ptr, &palette, &num_palette ) ) { + png_set_PLTE( write_ptr, write_info_ptr, palette, num_palette ); + } + + /* significant bits */ + if( png_get_sBIT( input[0].read_ptr, input[0].read_info_ptr, &sig_bit ) ) { + png_set_sBIT( write_ptr, write_info_ptr, sig_bit ); + } + + /* transparency */ + if( png_get_tRNS( input[0].read_ptr, input[0].read_info_ptr, &trans, &num_trans, &trans_values ) ) { + png_set_tRNS( write_ptr, write_info_ptr, trans, num_trans, trans_values ); + } + } + + /* text chunks */ + num_text = 0; + if( !png_get_text( input[0].read_ptr, input[0].read_info_ptr, &text_ptr, &num_text ) ) num_text = 0; + new_text_ptr = (struct png_text_struct *)malloc( sizeof( struct png_text_struct ) * num_text + 1 ); + if( !new_text_ptr ) { + printf( "malloc() failed\n" ); + return 1; + } + + memcpy( new_text_ptr, text_ptr, sizeof( struct png_text_struct ) * num_text ); + + snprintf( buf, 255, "SDL_anim %d %d %d", duration, width, numfiles ); + buf[255] = 0; + new_text_ptr[num_text].compression = PNG_TEXT_COMPRESSION_NONE; + new_text_ptr[num_text].key = "format"; + new_text_ptr[num_text].text = buf; + new_text_ptr[num_text].text_length = strlen( buf ); + num_text++; + png_set_text( write_ptr, write_info_ptr, new_text_ptr, num_text ); + + /* write info */ + png_write_info( write_ptr, write_info_ptr ); + + /* allocate buffer */ + rowbytes = png_get_rowbytes( input[0].read_ptr, input[0].read_info_ptr ); + row_buf = (png_bytep)png_malloc( write_ptr, rowbytes * numfiles ); + if( row_buf == NULL ) { + printf( "png_malloc() failed\n" ); + return 1; + } + + /* copy raw data */ + for( y = 0; y < height; y++ ) { + /* grab a scanline from each file */ + here = row_buf; + for( f = 0; f < numfiles; f++ ) { + png_read_rows( input[f].read_ptr, (png_bytepp)&here, (png_bytepp)NULL, 1 ); + here += rowbytes; + } + /* write the long scanline */ + png_write_rows( write_ptr, (png_bytepp)&row_buf, 1 ); + } + + /* end io */ + for( f = 0; f < numfiles; f++ ) png_read_end( input[f].read_ptr, end_info_ptr ); + png_write_end( write_ptr, end_info_ptr ); + + /* cleanup */ + png_free( write_ptr, row_buf ); + for( f = 0; f < numfiles; f++ ) { + png_destroy_read_struct( &input[f].read_ptr, &input[f].read_info_ptr, &end_info_ptr); + fclose( input[f].file ); + } + png_destroy_write_struct( &write_ptr, &write_info_ptr ); + fclose( fpout ); + + return 0; + } diff --git a/contrib/sdk/sources/SDL-1.2.2/SDL_anim-0.2.1/ship.ani b/contrib/sdk/sources/SDL-1.2.2/SDL_anim-0.2.1/ship.ani new file mode 100644 index 000000000..778ecd624 Binary files /dev/null and b/contrib/sdk/sources/SDL-1.2.2/SDL_anim-0.2.1/ship.ani differ diff --git a/contrib/sdk/sources/SDL-1.2.2/SDL_anim-0.2.1/showanim.c b/contrib/sdk/sources/SDL-1.2.2/SDL_anim-0.2.1/showanim.c new file mode 100644 index 000000000..782a0bb62 --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/SDL_anim-0.2.1/showanim.c @@ -0,0 +1,149 @@ +/* + SDL_anim: an animation library for SDL + Copyright (C) 2001, 2002 Michael Leonhard + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the Free + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + Michael Leonhard + mike@tamale.net +*/ + +#include +#include +#include +#include +#include "SDL_anim.h" + +/* Draw a Gimpish background pattern to show transparency in the anim */ +void draw_background( SDL_Surface *screen ) { + Uint8 *dst = screen->pixels; + int x, y; + int bpp = screen->format->BytesPerPixel; + Uint32 col[2]; + col[0] = SDL_MapRGB(screen->format, 0x66, 0x66, 0x66); + col[1] = SDL_MapRGB(screen->format, 0x99, 0x99, 0x99); + for(y = 0; y < screen->h; y++) { + for(x = 0; x < screen->w; x++) { + /* use an 8x8 checkerboard pattern */ + Uint32 c = col[((x ^ y) >> 3) & 1]; + switch(bpp) { + case 1: + dst[x] = c; + break; + case 2: + ((Uint16 *)dst)[x] = c; + break; + case 3: + if(SDL_BYTEORDER == SDL_LIL_ENDIAN) { + dst[x * 3] = c; + dst[x * 3 + 1] = c >> 8; + dst[x * 3 + 2] = c >> 16; + } + else { + dst[x * 3] = c >> 16; + dst[x * 3 + 1] = c >> 8; + dst[x * 3 + 2] = c; + } + break; + case 4: + ((Uint32 *)dst)[x] = c; + break; + } + } + dst += screen->pitch; + } + } + +int app_main(int argc, char *argv[]) { + SDL_Surface *screen; + SDL_Animation *anim; + SDL_Rect rect; + SDL_Event event; + SDL_KeyboardEvent *key; + int depth, done; + Uint32 start; + + argv[1]="ship.ani"; + /* Initialize the SDL library */ + if( SDL_Init( SDL_INIT_VIDEO ) < 0 ) { + fprintf( stderr, "Couldn't initialize SDL: %s\n", SDL_GetError() ); + return 2; + } + + /* Open the anim file */ + anim = Anim_Load(argv[1]); + if( anim == NULL ) { + fprintf( stderr, "Couldn't load %s: %s\n", argv[1], SDL_GetError() ); + SDL_Quit(); + return 3; + } + + SDL_WM_SetCaption( argv[1], "showanim" ); + + /* Create a display for the anim */ + depth = SDL_VideoModeOK( anim->w + 1, anim->h, 32, SDL_HWPALETTE ); + /* Use the deepest native mode, except that we emulate 32bpp for */ + /* viewing non-indexed anims on 8bpp screens */ + if( (anim->surface->format->BytesPerPixel > 1) && (depth == 8) ) { + depth = 32; + } + screen = SDL_SetVideoMode( anim->w + 10, anim->h, 16, SDL_HWPALETTE ); + if( screen == NULL ) { + fprintf( stderr, "Couldn't set %dx%dx%d video mode: %s\n", + anim->w, anim->h, depth, SDL_GetError() ); + SDL_Quit(); + return 4; + } + + /* Set the palette, if one exists */ + if( anim->surface->format->palette ) { + SDL_SetColors( screen, anim->surface->format->palette->colors, + 0, anim->surface->format->palette->ncolors ); + } + + + if( !Anim_DisplayFormat( anim ) ) { + fprintf( stderr, "Anim_DisplayFormat() failed\n" ); + return 5; + } + + done = 0; + start = SDL_GetTicks(); + while( !done ) { + while( SDL_PollEvent( &event ) ) { + switch( event.type ) { + case SDL_QUIT: + done = 1; + break; + case SDL_KEYDOWN: + key = (SDL_KeyboardEvent *)&event; + if( key->keysym.sym == SDLK_ESCAPE ) done = 1; + start = SDL_GetTicks(); + break; + } + } + + draw_background( screen ); + rect.x = 0; + rect.y = 0; + Anim_BlitFrame( anim, start, SDL_GetTicks(), screen, &rect ); + SDL_UpdateRect( screen, 0, 0, 0, 0 ); + SDL_Delay( 100 ); + } + + Anim_Free( anim ); + SDL_Quit(); + return 0; + } diff --git a/contrib/sdk/sources/SDL-1.2.2/SDL_bdf-1.2/Makefile b/contrib/sdk/sources/SDL-1.2.2/SDL_bdf-1.2/Makefile new file mode 100644 index 000000000..e6606da12 --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/SDL_bdf-1.2/Makefile @@ -0,0 +1,5 @@ +CFLAGS = -DUSE_RWOPS=1 -I. -I$(MENUETDEV)/include/SDL +OUTFILE = libSDL_bdf.a +OBJS = SDL_bdf.o + +include $(MENUETDEV)/makefiles/Makefile_for_lib diff --git a/contrib/sdk/sources/SDL-1.2.2/SDL_bdf-1.2/README.txt b/contrib/sdk/sources/SDL-1.2.2/SDL_bdf-1.2/README.txt new file mode 100644 index 000000000..8f76797f0 --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/SDL_bdf-1.2/README.txt @@ -0,0 +1,46 @@ +SDL_bdf version 1.2 + +http://www.geocities.com/andre_leiradella/ + +For copyright information see the source files. + +SDL_bdf is a small library that renders BDF fonts. As of version 1.2, SDL_bdf +doesn't depend on SDL anymore, you can use it with any graphics library throgh +it's API, but the bundled exampled uses SDL to show a text with a BDF font on +the screen. + +The library has been tested with SDL under Windows but should work on any +platform/graphics library. The functions provided are: + +. BDF_Font *BDF_OpenFont(BDF_ReadByte getbyte, void *info, int *error): Opens a + BDF font, it receives the function that will produce the stream of bytes, the + user defined void pointer that will be passed to getbyte and a pointer to an + int that will receive the error code. Returns the BDF font. +. void BDF_CloseFont(BDF_Font *font): Closes the font and frees all associated + memory. +. void BDF_SizeH(BDF_Font *font, char *text, int *x0, int *y0, int *width, + int *height): Determines the size of the horizontal text, returns the width + and height of the smallest rectangle that can acomodate the rendered text and + the start position in x0 and y0 on where the text must be rendered to exactly + fit the rectangle. This is because the render functions take the y parameter + as the baseline of the text to allow different fonts (e.g. normal and italic) + to be mixed in the same line. It handles NULL pointers for pieces of + information you don't want. +. void BDF_SizeEntitiesH(BDF_Font *font, char *text, int *x0, int *y0, + int *width, int *height): Same as above but accepts entities in the + form &...; (e.g. André) +. int BDF_DrawH(void *surface, BDF_PutPixel putpixel, BDF_Font *font, + char *text, int x, int y, unsigned int color): Draws the text at the given + surface starting at position (x, y). It calls putpixel with the surface, + coordinates and color to draw the pixel (doesn't clip). Returns the next x + coordinate to continue to render more text. Only accepts characters in the + range [0..255]. +. int BDF_DrawEntitiesH(void *, BDF_PutPixel, BDF_Font *, char *, int, int, + unsigned int): Same as above but accepts entities in the form &...; + +TODO: + +. Handle vertical writing. +. Use a hash table instead of an ordered array to access the glyphs by name. +. What else? Tell me: leiradella@bigfoot.com + diff --git a/contrib/sdk/sources/SDL-1.2.2/SDL_bdf-1.2/SDL_bdf.c b/contrib/sdk/sources/SDL-1.2.2/SDL_bdf-1.2/SDL_bdf.c new file mode 100644 index 000000000..a5473c74f --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/SDL_bdf-1.2/SDL_bdf.c @@ -0,0 +1,588 @@ +/* +SDL_bdf - renders BDF fonts +Copyright (C) 2002-2003 Andre de Leiradella + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 2.1 of the License, or (at your option) any later version. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +For information about SDL_bdf contact leiradella@bigfoot.com + +Version 1.0: first public release. +Version 1.1: removed SDL dependecies, now SDL_bdf can be used with any graphics + library. +Version 1.2: fixed BDF_SizeH and BDF_SizeEntitiesH to return the correct sizes. +*/ +#include +#include +#include +#include +#include +#include +#include + +/* +BDF fonts are encoded in ascii. Each line of the file begins with a keyword, +has zero or more arguments which can be integers, numbers (floats), strings and +quoted string, and ends with an eol. Some keywords are optional or +user-defined, unquoted strings can begin with any character which means that it +can start with a minus sign making it hard to distinguish them from negative +integers or numbers (and it do happen in some places). Adobe's spec isn't clear +sometimes so we have to be cautious (eg it doesn't say how eols are encoded so +we have to accept MSDOS (cr lf), Unix (lf) and Mac (cr) styles. I implemented a +*very* relaxed parser which won't stop on some errors. The parser reads the +font line by line and for each one verifies which is the keyword (using a hash +table generated by gperf) and takes the appropriate action through a switch +statement. +*/ + +/* BDF keywords. */ +#define BBX 1 +#define BITMAP 2 +#define CHARS 3 +#define COMMENT 4 +#define CONTENTVERSION 5 +#define DWIDTH 6 +#define DWIDTH1 7 +#define ENCODING 8 +#define ENDCHAR 9 +#define ENDFONT 10 +#define ENDPROPERTIES 11 +#define FONT 12 +#define FONTBOUNDINGBOX 13 +#define METRICSSET 14 +#define SIZE 15 +#define STARTCHAR 16 +#define STARTFONT 17 +#define STARTPROPERTIES 18 +#define SWIDTH 19 +#define SWIDTH1 20 +#define VVECTOR 21 + +/* Include GPERF hash function generated from bdf.in. */ +#include "bdf.gperf" + +/* Reads a line from rwops up to 65536 characters. */ +static int readline(BDF_ReadByte getbyte, void *info, char *data) { + int k, i = 65536; + + for (;;) { + k = getbyte(info); + if (k == -1) + return 0; + switch (k) { + default: + *data++=k; + if (--i==0) { + case '\n': + *data='\0'; + return 1; + } + case '\r': + ; + } + } +} + +/* Parse an integer updating the pointer. */ +static int readinteger(char **data, int *integer) { + char *aux; + int i, signal; + + aux = *data; + signal = 1; + /* Adobe's spec doesn't say numbers can be preceeded by '+' but we never know. */ + switch (*aux) { + case '-': + signal = -1; + case '+': + aux++; + break; + } + /* Skip spaces between signal and first digit. */ + while (isspace(*aux)) aux++; + if (!isdigit(*aux)) return 0; + /* Now we start reading digits. */ + i = 0; + while (isdigit(*aux)) i = i * 10 + *aux++ - '0'; + /* We're done, update pointer and return value. */ + *data = aux; + if (integer != NULL) *integer = signal * i; + return 1; +} + +/* Parse a double updating the pointer. */ +static int readnumber(char **data, double *number) { + register char *aux; + double n, d; + int signal; + + aux = *data; + signal = 1; + /* Adobe's spec doesn't say numbers can be preceeded by '+' but we never know. */ + switch (*aux) { + case '-': + signal = -1; + case '+': + aux++; + break; + } + /* Skip spaces between signal and first digit. */ + while (isspace(*aux)) aux++; + if (!isdigit(*aux)) return 0; + /* Now we start reading digits */ + n = 0; + while (isdigit(*aux)) n = n * 10 + *aux++ - '0'; + d = 10; + /* If next character is a dot then we have a decimal part. */ + if (*aux == '.') { + aux++; + /* Decimal point must be succeeded by one or more digits. */ + if (!isdigit(*aux)) return 0; + while (isdigit(*aux)) n += (*aux++ - '0') / d, d /= 10; + } + /* We're done, update pointer and return value. */ + *data = aux; + if (number != NULL) *number = signal*n; + return 1; +} + +/* Parse a string updating the pointer. */ +static int readstring(char **data, char **string) { + int len; + + len = strlen(*data); + if (string != NULL) { + /* Malloc the required space. */ + *string=(char *)malloc(len + 1); + if (*string == NULL) + return 0; + /* Copy everything. */ + strcpy(*string, *data); + } + /* We're done, update pointer. */ + *data += len; + return 1; +} + +/* Scan the line (just after the keyword) for elements listed in format. */ +static int scan(char *data, char *format, ...) { + va_list args; + int *i; + double *n; + char **s; + + /* Keyword already skipped, skip spaces. */ + while (*data != '\0' && isspace(*data)) data++; + /* Scan the data for the pattern in format. */ + va_start(args, format); + while (*format != '\0') { + switch (*format++) { + case 'i': /* integer. */ + i = va_arg(args, int *); + if (!readinteger(&data, i)) { + va_end(args); + return 0; + } + break; + case 'n': /* number. */ + n = va_arg(args, double *); + if (!readnumber(&data, n)) { + va_end(args); + return 0; + } + break; + case 's': /* string. */ + s = va_arg(args, char **); + if (!readstring(&data, s)) { + va_end(args); + return 0; + } + break; + } + /* Skip spaces between elements. */ + while (*data != '\0' && isspace(*data)) data++; + } + va_end(args); + return *data == '\0'; +} + +/* Compare function to sort characters by their names. */ +static int compare(const void *c1, const void *c2) { + return strcmp(((BDF_Char *)c1)->name, ((BDF_Char *)c2)->name); +} + +#define XVAL(x) (isdigit((x)) ? (x) - '0' : toupper((x)) - 'A' + 10) + +BDF_Font *BDF_OpenFont(BDF_ReadByte getbyte, void *info, int *error) { + BDF_Font *font; + BDF_Char *chr; + char *data; + register char *aux; + struct bdfword *word; + unsigned char *bits; + double n; + int numChars; + int dwx0, dwy0; + int dwx1, dwy1; + int bbw, bbh, bbxoff0x, bbyoff0y, i; + + /* Malloc the font. */ + font = (BDF_Font *)malloc(sizeof(BDF_Font)); + if (font == NULL) { + if (error != NULL) *error = BDF_MEMORYERROR; + goto error; + } + /* Null array of characters. */ + font->chars = NULL; + /* Looks ugly but I'm lazy... */ + data = (char *)malloc(65537 * sizeof(char)); + if (data == NULL) { + if (error != NULL) *error = BDF_MEMORYERROR; + goto error; + } + /* Zero the structure. */ + font->metricsSet = font->numChars = 0; + dwx0 = dwy0 = 0; + dwx1 = dwy1 = 0; + bbw = bbh = 0; + bbxoff0x = bbyoff0y = 0; + /* chr holds the current character or NULL if we're not inside a character definition. */ + chr = NULL; + for (;;) { + /* Read one line at a time. */ + if (!readline(getbyte, info, data)) { + if (*error != NULL) *error = BDF_READERROR; + goto error; + } + /* Find end of keyword. */ + aux = data; + while (*aux != '\0' && !isspace(*aux)) aux++; + /* Find which keyword it is using gperf's hash function. */ + word = (struct bdfword *)in_word_set(data, aux - data); + switch (word == NULL ? 0 : word->code) { + case STARTFONT: + /* Issue an error on versions higher than 2.2. */ + if (!scan(aux, "n", &n)) { + if (error != NULL) *error = BDF_PARSEERROR; + goto error; + } + if (n > 2.2) { + if (error != NULL) *error = BDF_WRONGVERSION; + goto error; + } + break; + case FONTBOUNDINGBOX: + /* The FONTBOUNDINGBOX values seems to be defaults for BBX values. */ + if (!scan(aux, "iiii", &bbw, &bbh, &bbxoff0x, &bbyoff0y)) { + if (error != NULL) *error = BDF_PARSEERROR; + goto error; + } + break; + case METRICSSET: + /* We only handle horizontal writing by now. */ + if (!scan(aux, "i", &font->metricsSet)) { + if (error != NULL) *error = BDF_PARSEERROR; + goto error; + } + if (font->metricsSet != 0) { + if (error != NULL) *error = BDF_CANNOTHANDLEVERTICAL; + goto error; + } + break; + case DWIDTH: + /* This is the character's width in pixels. */ + if (chr != NULL) + if (!scan(aux, "ii", &chr->dwx0, &chr->dwy0)) { + if (error != NULL) *error = BDF_PARSEERROR; + goto error; + } + else + if (!scan(aux, "ii", &dwx0, &dwy0)) { + if (error != NULL) *error = BDF_PARSEERROR; + goto error; + } + break; + case DWIDTH1: + /* This is the character's width in pixels for vertical writing. */ + if (chr != NULL) + if (!scan(aux, "ii", &chr->dwx1, &chr->dwy1)) { + if (error != NULL) *error = BDF_PARSEERROR; + goto error; + } + else + if (!scan(aux, "ii", &dwx1, &dwy1)) { + if (error != NULL) *error = BDF_PARSEERROR; + goto error; + } + break; + case CHARS: + /* We read the number of chars in this font and malloc the required memory. */ + if (!scan(aux, "i", &font->numChars)) { + if (error != NULL) *error = BDF_PARSEERROR; + goto error; + } + font->chars = (BDF_Char *)malloc(font->numChars * sizeof(BDF_Char)); + if (font->chars == NULL) { + if (error != NULL) *error = BDF_MEMORYERROR; + goto error; + } + /* Zero all characters' info. */ + for (i = font->numChars, chr = font->chars; i != 0; i--, chr++) { + chr->name = NULL; + chr->code = -1; + chr->dwx0 = chr->dwy0 = 0; + chr->dwx1 = chr->dwy1 = 0; + chr->bbw = chr->bbh = 0; + chr->bbxoff0x = chr->bbyoff0y = 0; + chr->bits = NULL; + } + /* chr points to the current character. */ + chr = font->chars; + break; + case STARTCHAR: + /* If chr is NULL there are more characters in the font then expected. */ + if (chr == NULL) { + if (error != NULL) *error = BDF_TOOMANYCHARACTERS; + goto error; + } + if (!scan(aux, "s", &chr->name)) { + if (error != NULL) *error = BDF_PARSEERROR; + goto error; + } + /* Copy default values. */ + chr->code = -1; + chr->dwx0 = dwx0; + chr->dwy0 = dwy0; + chr->dwx1 = dwx1; + chr->dwy1 = dwy1; + chr->bbw = bbw; + chr->bbh = bbh; + chr->bbxoff0x = bbxoff0x; + chr->bbyoff0y = bbyoff0y; + break; + case ENCODING: + /* Read character's code, it can be -1. */ + if (chr != NULL) + if (!scan(aux, "i", &chr->code)) { + if (error != NULL) *error = BDF_PARSEERROR; + goto error; + } + break; + case BBX: + /* The bounding box around the character's black pixels. */ + if (chr != NULL) + if (!scan(aux, "iiii", &chr->bbw, &chr->bbh, &chr->bbxoff0x, &chr->bbyoff0y)) { + if (error != NULL) *error = BDF_PARSEERROR; + goto error; + } + break; + case BITMAP: + /* BITMAP signals the start of the hex data. */ + if (chr != NULL) { + /* wbytes is the width of the char in bytes. */ + chr->wbytes = (chr->bbw + 7) / 8; + /* Malloc the memory for the pixels. */ + chr->bits = (unsigned char *)malloc(chr->wbytes * chr->bbh); + if (chr->bits == NULL) { + if (error != NULL) *error = BDF_MEMORYERROR; + goto error; + } + /* Read all pixels from file. */ + for (i = chr->bbh, bits = chr->bits; i != 0; i--) { + if (!readline(getbyte, info, data)) { + if (error != NULL) *error = BDF_READERROR; + goto error; + } + aux = data; + while (aux[0] != '\0' && aux[1] != '\0') { + *bits++ = XVAL(aux[0]) * 16 + XVAL(aux[1]); + aux += 2; + } + } + } + break; + case ENDCHAR: + /* Skip to the next character, makes a bound check. */ + chr++; + if ((chr-font->chars) >= font->numChars) + chr = NULL; + break; + case ENDFONT: + /* Ends the font, if chr is not NULL then we are short on characters. */ + if (chr != NULL) { + if (error != NULL) *error = BDF_TOOFEWCHARACTERS; + goto error; + } + /* Sort font by character names, should be an hash table. */ + qsort(font->chars, font->numChars, sizeof(BDF_Char), compare); + /* Fast pointers to characters encoded between [0..255]. */ + for (i = 0; i < 256; i++) + font->code[i] = NULL; + for (i = font->numChars, chr = font->chars; i != 0; i--, chr++) + if (chr->code >= 0 && chr->code <= 255) + font->code[chr->code] = chr; + if (error != NULL) *error = BDF_OK; + free(data); + return font; + } + } + error: + /* Free everything. */ + free(data); + BDF_CloseFont(font); + return NULL; +} + +void BDF_CloseFont(BDF_Font *font) { + int i; + BDF_Char *chr; + + /* Free everything. */ + if (font != NULL) { + if (font->chars != NULL) { + for (i = font->numChars, chr = font->chars; i != 0; i--, chr++) { + free(chr->name); + free(chr->bits); + } + free(font->chars); + } + free(font); + } +} + +/* Finds a char in the font, if entities is not zero then handle entities. */ +static BDF_Char *findchar(BDF_Font *font, char **text, int entities) { + char *aux; + BDF_Char key, *chr; + + /* Handle entities. */ + if (entities != 0 && **text == '&') { + if ((*text)[1] != '&') { + key.name = *text + 1; + aux = strchr(*text, ';'); + if (aux == NULL) { + *text = *text + strlen(*text); + return NULL; + } + *aux = '\0'; + *text = aux + 1; + chr = (BDF_Char *)bsearch(&key, font->chars, font->numChars, sizeof(BDF_Char), compare); + *aux = ';'; + return chr; + } else + (*text)++; + } + /* Return the character in the range [0..255]. */ + return font->code[*(unsigned char *)(*text)++]; +} + +/* Determines the size of the horizontal text. */ +static void sizeh(BDF_Font *font, char *text, int entities, int *x0, int *y0, int *width, int *height) { + BDF_Char *chr; + int first, y, h, minh, maxh; + + first = 1; + minh = *y0 = INT_MAX; + maxh = INT_MIN; + y = 0; + while (*text != '\0') { + chr = findchar(font, &text, entities); + if (first != 0) { + first = 0; + *x0 = *width = -chr->bbxoff0x; + } + if (chr != NULL) { + h = y - (chr->bbyoff0y + chr->bbh); + if (h < minh) + minh = h; + h += chr->bbh - 1; + if (h > maxh) + maxh = h; + *width += chr->dwx0; + if (chr->bbyoff0y < *y0) + *y0 = chr->bbyoff0y; + y += chr->dwy0; + } + } + *height = maxh - minh + 1; + *y0 += *height; +} + +void BDF_SizeH(BDF_Font *font, char *text, int *x0, int *y0, int *width, int *height) { + int _x0, _y0, _width, _height; + + sizeh(font, text, 0, &_x0, &_y0, &_width, &_height); + if (x0 != NULL) *x0 = _x0; + if (y0 != NULL) *y0 = _y0; + if (width != NULL) *width = _width; + if (height != NULL) *height = _height; +} + +void BDF_SizeEntitiesH(BDF_Font *font, char *text, int *x0, int *y0, int *width, int *height) { + int _x0, _y0, _width, _height; + + sizeh(font, text, 1, &_x0, &_y0, &_width, &_height); + if (x0 != NULL) *x0 = _x0; + if (y0 != NULL) *y0 = _y0; + if (width != NULL) *width = _width; + if (height != NULL) *height = _height; +} + +/* Draws a char on the surface. */ +static void drawchar(void *surface, BDF_PutPixel putpixel, BDF_Char *chr, int x, int y, unsigned int color) { + int xx; + unsigned char *bits, *endfont, *endline; + + /* Calculate the position of the first pixel. */ + x += chr->bbxoff0x; + y -= (chr->bbyoff0y + chr->bbh); + bits = chr->bits; + /* Put them! */ + for (endfont = bits + chr->wbytes * chr->bbh; bits < endfont; y++) + for (endline = bits + chr->wbytes, xx = x; bits < endline; xx += 8, bits++) { + if ((*bits) & 0x80) putpixel(surface, xx, y, color); + if ((*bits) & 0x40) putpixel(surface, xx + 1, y, color); + if ((*bits) & 0x20) putpixel(surface, xx + 2, y, color); + if ((*bits) & 0x10) putpixel(surface, xx + 3, y, color); + if ((*bits) & 0x08) putpixel(surface, xx + 4, y, color); + if ((*bits) & 0x04) putpixel(surface, xx + 5, y, color); + if ((*bits) & 0x02) putpixel(surface, xx + 6, y, color); + if ((*bits) & 0x01) putpixel(surface, xx + 7, y, color); + } +} + +/* Draws an entire line of text. */ +static int drawh(void *surface, BDF_PutPixel putpixel, BDF_Font *font, char *text, int entities, int x, int y, unsigned int color) { + BDF_Char *chr; + + /* For each character... */ + while (*text != '\0') { + chr = findchar(font, &text, entities); + if (chr != NULL) { + /* ... draw it. */ + drawchar(surface, putpixel, chr, x, y, color); + x += chr->dwx0; + y += chr->dwy0; + } + } + return x; +} + +int BDF_DrawH(void *surface, BDF_PutPixel putpixel, BDF_Font *font, char *text, int x, int y, unsigned int color) { + return drawh(surface, putpixel, font, text, 0, x, y, color); +} + +int BDF_DrawEntitiesH(void *surface, BDF_PutPixel putpixel, BDF_Font *font, char *text, int x, int y,unsigned int color) { + return drawh(surface, putpixel, font, text, 1, x, y, color); +} diff --git a/contrib/sdk/sources/SDL-1.2.2/SDL_bdf-1.2/SDL_bdf.h b/contrib/sdk/sources/SDL-1.2.2/SDL_bdf-1.2/SDL_bdf.h new file mode 100644 index 000000000..d3422aa4a --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/SDL_bdf-1.2/SDL_bdf.h @@ -0,0 +1,120 @@ +/* +SDL_bdf - renders BDF fonts +Copyright (C) 2002-2003 Andre de Leiradella + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 2.1 of the License, or (at your option) any later version. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +For information about SDL_bdf contact leiradella@bigfoot.com + +Version 1.0: first public release. +Version 1.1: removed SDL dependecies, now SDL_bdf can be used with any graphics + library. +Version 1.2: fixed BDF_SizeH and BDF_SizeEntitiesH to return the correct sizes. +*/ +#ifndef __SDL_bdf_h__ +#define __SDL_bdf_h__ + +#ifdef __cplusplus +extern "C" { +#endif + +/* Error codes. */ + +/* No error. */ +#define BDF_OK 0 +/* Not enough memory reading BDF font. */ +#define BDF_MEMORYERROR 1 +/* Error reading BDF font. */ +#define BDF_READERROR 2 +/* Can only handle BDF font varsions up to 2.2. */ +#define BDF_WRONGVERSION 3 +/* Can only handle horizontal BDF fonts. */ +#define BDF_CANNOTHANDLEVERTICAL 4 +/* Character found past end of BDF font. */ +#define BDF_TOOMANYCHARACTERS 5 +/* BDF font is missing characters. */ +#define BDF_TOOFEWCHARACTERS 6 +/* Error parsing BDF font. */ +#define BDF_PARSEERROR 7 + +/* A BDF character. */ +typedef struct { + char *name; + int code; + int dwx0, dwy0; + int dwx1, dwy1; + int bbw, bbh, bbxoff0x, bbyoff0y, wbytes; + unsigned char *bits; +} BDF_Char; + +/* A BDF font. */ +typedef struct { + int metricsSet, numChars; + BDF_Char *chars; + BDF_Char *code[256]; +} BDF_Font; + +/* +Function to put a pixel on the surface, it receives a pointer to the surface +(whatever format it may be), the x and y coordinates and the color. +*/ +typedef void (*BDF_PutPixel)(void *, int, int, unsigned int); + +/* +Function to read a byte, it receives an user defined void pointer and must +return a value in the range [0..255] or -1 to indicate EOF. +*/ +typedef int (*BDF_ReadByte)(void *); + +/* +Opens a BDF font, it receives the function that will produce the stream of +bytes, the user defined void pointer that will be passed to getbyte and a +pointer to an int that will receive the error code. Returns the BDF font. +*/ +extern BDF_Font *BDF_OpenFont(BDF_ReadByte getbyte, void *info, int *error); +/* +Closes the font and frees all associated memory. +*/ +extern void BDF_CloseFont(BDF_Font *font); +/* +Determines the size of the horizontal text, returns the width and height of the +smallest rectangle that can acomodate the rendered text and the start position +in x0 and y0 on where the text must be rendered to exactly fit the rectangle. +This is because the render functions take the y parameter as the baseline of +the text to allow different fonts (e.g. normal and italic) to be mixed in the +same line. It handles NULL pointers for pieces of information you don't want. +*/ +extern void BDF_SizeH(BDF_Font *font, char *text, int *x0, int *y0, int *width, int *height); +/* +Same as above but accepts entities in the form &...; +*/ +extern void BDF_SizeEntitiesH(BDF_Font *font, char *text, int *x0, int *y0, int *width, int *height); +/* +Draws the text at the given surface starting at position (x, y). It calls +putpixel with the surface, coordinates and color to draw the pixel (doesn't +clip). Returns the next x coordinate to continue to render more text. Only +accepts characters in the range [0..255]. +*/ +extern int BDF_DrawH(void *surface, BDF_PutPixel putpixel, BDF_Font *font, char *text, int x, int y, unsigned int color); +/* +Same as above but accepts entities in the form &...; +*/ +extern int BDF_DrawEntitiesH(void *, BDF_PutPixel, BDF_Font *, char *, int, int, unsigned int); + +#ifdef __cplusplus +}; +#endif + +#endif diff --git a/contrib/sdk/sources/SDL-1.2.2/SDL_bdf-1.2/bdf.gperf b/contrib/sdk/sources/SDL-1.2.2/SDL_bdf-1.2/bdf.gperf new file mode 100644 index 000000000..e6ba8dbbd --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/SDL_bdf-1.2/bdf.gperf @@ -0,0 +1,112 @@ +/* ANSI-C code produced by gperf version 2.7 */ +/* Command-line: gperf -c -C -l -L ANSI-C -f 0 -G -t bdf.in */ +struct bdfword { char *name; int code; }; + +#define TOTAL_KEYWORDS 21 +#define MIN_WORD_LENGTH 3 +#define MAX_WORD_LENGTH 15 +#define MIN_HASH_VALUE 3 +#define MAX_HASH_VALUE 37 +/* maximum key range = 35, duplicates = 0 */ + +#ifdef __GNUC__ +__inline +#endif +static unsigned int +hash (register const char *str, register unsigned int len) +{ + static const unsigned char asso_values[] = + { + 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, + 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, + 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, + 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, + 38, 38, 38, 38, 38, 38, 38, 38, 38, 5, + 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, + 38, 38, 38, 38, 38, 38, 0, 20, 5, 0, + 15, 0, 0, 38, 38, 38, 38, 0, 0, 38, + 10, 38, 15, 0, 0, 38, 15, 38, 0, 38, + 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, + 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, + 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, + 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, + 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, + 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, + 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, + 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, + 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, + 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, + 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, + 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, + 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, + 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, + 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, + 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, + 38, 38, 38, 38, 38, 38 + }; + return len + asso_values[(unsigned char)str[len - 1]] + asso_values[(unsigned char)str[0]]; +} + +static const unsigned char lengthtable[] = + { + 0, 0, 0, 3, 4, 0, 6, 7, 8, 9, 10, 6, 7, 13, + 0, 15, 6, 7, 0, 4, 0, 0, 7, 0, 9, 5, 0, 7, + 0, 0, 15, 0, 0, 0, 14, 0, 0, 7 + }; + +static const struct bdfword wordlist[] = + { + {""}, {""}, {""}, + {"BBX",BBX}, + {"SIZE",SIZE}, + {""}, + {"SWIDTH",SWIDTH}, + {"ENDFONT",ENDFONT}, + {"ENCODING",ENCODING}, + {"STARTFONT",STARTFONT}, + {"METRICSSET",METRICSSET}, + {"DWIDTH",DWIDTH}, + {"SWIDTH1",SWIDTH1}, + {"ENDPROPERTIES",ENDPROPERTIES}, + {""}, + {"STARTPROPERTIES",STARTPROPERTIES}, + {"BITMAP",BITMAP}, + {"DWIDTH1",DWIDTH1}, + {""}, + {"FONT",FONT}, + {""}, {""}, + {"ENDCHAR",ENDCHAR}, + {""}, + {"STARTCHAR",STARTCHAR}, + {"CHARS",CHARS}, + {""}, + {"COMMENT",COMMENT}, + {""}, {""}, + {"FONTBOUNDINGBOX",FONTBOUNDINGBOX}, + {""}, {""}, {""}, + {"CONTENTVERSION",CONTENTVERSION}, + {""}, {""}, + {"VVECTOR",VVECTOR} + }; + +#ifdef __GNUC__ +__inline +#endif +const struct bdfword * +in_word_set (register const char *str, register unsigned int len) +{ + if (len <= MAX_WORD_LENGTH && len >= MIN_WORD_LENGTH) + { + register int key = hash (str, len); + + if (key <= MAX_HASH_VALUE && key >= 0) + if (len == lengthtable[key]) + { + register const char *s = wordlist[key].name; + + if (*str == *s && !strncmp (str + 1, s + 1, len - 1)) + return &wordlist[key]; + } + } + return 0; +} diff --git a/contrib/sdk/sources/SDL-1.2.2/SDL_bdf-1.2/bdf.in b/contrib/sdk/sources/SDL-1.2.2/SDL_bdf-1.2/bdf.in new file mode 100644 index 000000000..c87afcf84 --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/SDL_bdf-1.2/bdf.in @@ -0,0 +1,23 @@ +struct bdfword { char *name; int code; }; +%% +STARTFONT,STARTFONT +COMMENT,COMMENT +CONTENTVERSION,CONTENTVERSION +FONT,FONT +SIZE,SIZE +FONTBOUNDINGBOX,FONTBOUNDINGBOX +METRICSSET,METRICSSET +SWIDTH,SWIDTH +DWIDTH,DWIDTH +SWIDTH1,SWIDTH1 +DWIDTH1,DWIDTH1 +VVECTOR,VVECTOR +STARTPROPERTIES,STARTPROPERTIES +ENDPROPERTIES,ENDPROPERTIES +CHARS,CHARS +STARTCHAR,STARTCHAR +ENCODING,ENCODING +BBX,BBX +BITMAP,BITMAP +ENDCHAR,ENDCHAR +ENDFONT,ENDFONT diff --git a/contrib/sdk/sources/SDL-1.2.2/SDL_bdf-1.2/dustismo36.bdf b/contrib/sdk/sources/SDL-1.2.2/SDL_bdf-1.2/dustismo36.bdf new file mode 100644 index 000000000..226b49f3e --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/SDL_bdf-1.2/dustismo36.bdf @@ -0,0 +1,20131 @@ +STARTFONT 2.1 +COMMENT +COMMENT Converted from TrueType font "c:\windows\desktop\dustismo\dustismo_roman.ttf" by "TTF2BDF 2.6". +COMMENT +FONT -FreeType-Dustismo Roman-Medium-R-Normal--50-360-100-100-P-233-ISO10646-1 +SIZE 36 100 100 +FONTBOUNDINGBOX 53 66 -6 -13 +STARTPROPERTIES 20 +FOUNDRY "FreeType" +FAMILY_NAME "Dustismo Roman" +WEIGHT_NAME "Medium" +SLANT "R" +SETWIDTH_NAME "Normal" +ADD_STYLE_NAME "" +PIXEL_SIZE 50 +POINT_SIZE 360 +RESOLUTION_X 100 +RESOLUTION_Y 100 +SPACING "P" +AVERAGE_WIDTH 233 +CHARSET_REGISTRY "ISO10646" +CHARSET_ENCODING "1" +FONT_ASCENT 46 +FONT_DESCENT 12 +COPYRIGHT "Copyright (c) Dustin Norlander, 2003. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or any later " +_TTF_FONTFILE "c:\windows\desktop\dustismo\dustismo_roman.ttf" +_TTF_PSNAME "DustismoRoman" +_XFREE86_GLYPH_RANGES "32_126 160_172 174_271 274_289 292_305 308_310 313_314 317_324 327_341 344_369 372_382 402 461_476 482_483 486_487 508_512 562 710_711 713 728 730_733 894 902 904_906 908 910_911 913_929 931_942 945_974 8211_8212 8216_8218 8220_8222 8224_8226 8230 8240 8249_8250 8260 8364 8482 8706 8710 8719_8722 8725 8729_8730 8734_8735 8747 8776_8777 8800_8802 8804_8805 8814_8815 8976 9472 9474 9484 9488 9492 9496 9500 9508 9516 9524 9532 9552_9580 9786 9792_9794 9827 9829_9830 9833_9836 64257_64258" +ENDPROPERTIES +CHARS 496 +STARTCHAR 0020 +ENCODING 32 +SWIDTH 320 0 +DWIDTH 16 0 +BBX 1 1 0 0 +BITMAP +00 +ENDCHAR +STARTCHAR 0021 +ENCODING 33 +SWIDTH 180 0 +DWIDTH 9 0 +BBX 5 37 2 0 +BITMAP +F8 +F8 +F8 +F8 +F8 +F8 +F8 +F8 +F8 +F8 +F8 +F8 +F8 +F8 +F8 +F8 +F8 +F8 +F8 +F8 +F8 +70 +70 +70 +70 +70 +70 +70 +00 +00 +00 +00 +F8 +F8 +F8 +F8 +F8 +ENDCHAR +STARTCHAR 0022 +ENCODING 34 +SWIDTH 380 0 +DWIDTH 19 0 +BBX 15 9 2 27 +BITMAP +F83E +F83E +F83E +F83E +783E +783C +783C +703C +701C +ENDCHAR +STARTCHAR 0023 +ENCODING 35 +SWIDTH 520 0 +DWIDTH 26 0 +BBX 24 36 1 0 +BITMAP +003010 +003030 +003030 +002030 +002020 +006020 +006060 +006060 +004060 +004040 +3FFFFF +3FFFFF +00C0C0 +0080C0 +008080 +018080 +018180 +018180 +010180 +010100 +030100 +030300 +030300 +020300 +FFFFFC +FFFFFC +060200 +060600 +040600 +040400 +040400 +0C0400 +0C0C00 +080C00 +080C00 +080800 +ENDCHAR +STARTCHAR 0024 +ENCODING 36 +SWIDTH 500 0 +DWIDTH 25 0 +BBX 23 45 1 -5 +BITMAP +003000 +003000 +003000 +003000 +00FC00 +07FFE0 +1F31E0 +3E3060 +7C3060 +7C3060 +F83020 +F83000 +F83000 +F83000 +F83000 +FC3000 +FC3000 +7E3000 +7F3000 +3FF000 +1FFC00 +0FFF00 +03FFC0 +00FFE0 +001FF0 +0013F8 +0031FC +0030FC +00307E +00303E +00303E +C0303E +C0303E +C0303E +C0307C +C0307C +E030F8 +7031F0 +3C37E0 +0FFFC0 +03FE00 +003000 +003000 +003000 +001000 +ENDCHAR +STARTCHAR 0025 +ENCODING 37 +SWIDTH 500 0 +DWIDTH 25 0 +BBX 21 36 2 0 +BITMAP +1E00C0 +7F80C0 +738080 +E1C180 +E1C180 +E1C100 +E1C300 +E1C300 +E1C600 +738600 +7F8400 +1E0C00 +000C00 +001800 +001800 +001000 +003000 +003000 +006000 +006000 +004000 +00C000 +00C000 +018000 +018000 +0187E0 +030FF0 +030E70 +021C38 +061C38 +061C38 +0C1C38 +0C1C38 +080E70 +180FF0 +1807E0 +ENDCHAR +STARTCHAR 0026 +ENCODING 38 +SWIDTH 640 0 +DWIDTH 32 0 +BBX 29 37 2 0 +BITMAP +01F80000 +03FC0000 +0F860000 +0F030000 +1F030000 +1F010000 +1F010000 +1F010000 +0F030000 +0F830000 +0F870000 +07C60000 +07CC0000 +03FC0000 +03F80000 +01F00000 +01F00000 +01F80000 +03780000 +067C0000 +0C3E0000 +181F01F8 +381F01F8 +700F8060 +7007C040 +F007C0C0 +F003E0C0 +F001F180 +F000F900 +F000FB00 +F8007E00 +F8003E00 +7C003F00 +3F00EF80 +3FFF8FC0 +0FFF1FF8 +03F81FF8 +ENDCHAR +STARTCHAR 0027 +ENCODING 39 +SWIDTH 180 0 +DWIDTH 9 0 +BBX 5 9 2 27 +BITMAP +F8 +F8 +F8 +F8 +F8 +F0 +F0 +F0 +70 +ENDCHAR +STARTCHAR 0028 +ENCODING 40 +SWIDTH 300 0 +DWIDTH 15 0 +BBX 12 48 2 -12 +BITMAP +0010 +0070 +00E0 +01C0 +0380 +0780 +0F00 +0E00 +1E00 +1E00 +3C00 +3C00 +7C00 +7C00 +7800 +7800 +7800 +F800 +F800 +F800 +F800 +F800 +F800 +F800 +F800 +F800 +F800 +F800 +F800 +F800 +F800 +7800 +7800 +7800 +7C00 +7C00 +3C00 +3C00 +1E00 +1E00 +0E00 +0F00 +0780 +0380 +01C0 +00E0 +0070 +0010 +ENDCHAR +STARTCHAR 0029 +ENCODING 41 +SWIDTH 320 0 +DWIDTH 16 0 +BBX 12 48 2 -12 +BITMAP +8000 +C000 +7000 +3800 +1C00 +1E00 +0F00 +0700 +0780 +0780 +03C0 +03C0 +03C0 +03E0 +01E0 +01E0 +01E0 +01F0 +01F0 +01F0 +01F0 +01F0 +01F0 +01F0 +01F0 +01F0 +01F0 +01F0 +01F0 +01F0 +01F0 +01E0 +01E0 +03E0 +03E0 +03E0 +03C0 +03C0 +0780 +0780 +0700 +0F00 +1E00 +1C00 +3800 +7000 +E000 +8000 +ENDCHAR +STARTCHAR 002A +ENCODING 42 +SWIDTH 500 0 +DWIDTH 25 0 +BBX 22 21 1 10 +BITMAP +003800 +007C00 +007C00 +007C00 +007C00 +007C00 +70383C +FC38FC +FF11FC +7F83FC +1F83F0 +000000 +000000 +00C400 +01C700 +03C780 +0787C0 +0F83E0 +1F03E0 +1F01E0 +0E00C0 +ENDCHAR +STARTCHAR 002B +ENCODING 43 +SWIDTH 440 0 +DWIDTH 22 0 +BBX 21 21 0 3 +BITMAP +003000 +003000 +003000 +003000 +003000 +003000 +003000 +003000 +003000 +FFFFF8 +FFFFF8 +003000 +003000 +003000 +003000 +003000 +003000 +003000 +003000 +003000 +003000 +ENDCHAR +STARTCHAR 002C +ENCODING 44 +SWIDTH 180 0 +DWIDTH 9 0 +BBX 5 10 2 -5 +BITMAP +F8 +F8 +F8 +F8 +F8 +38 +18 +30 +60 +C0 +ENDCHAR +STARTCHAR 002D +ENCODING 45 +SWIDTH 420 0 +DWIDTH 21 0 +BBX 17 2 2 17 +BITMAP +FFFF80 +FFFF80 +ENDCHAR +STARTCHAR 002E +ENCODING 46 +SWIDTH 200 0 +DWIDTH 10 0 +BBX 5 5 2 0 +BITMAP +F8 +F8 +F8 +F8 +F8 +ENDCHAR +STARTCHAR 002F +ENCODING 47 +SWIDTH 340 0 +DWIDTH 17 0 +BBX 15 36 1 0 +BITMAP +0002 +0006 +0004 +000C +000C +0008 +0018 +0010 +0030 +0030 +0020 +0060 +0040 +00C0 +00C0 +0080 +0180 +0100 +0300 +0300 +0200 +0600 +0600 +0400 +0C00 +0800 +1800 +1800 +1000 +3000 +2000 +6000 +6000 +4000 +C000 +8000 +ENDCHAR +STARTCHAR 0030 +ENCODING 48 +SWIDTH 580 0 +DWIDTH 29 0 +BBX 25 37 2 -1 +BITMAP +007F0000 +03FFE000 +07C1F000 +0F80F800 +1F007C00 +1E007C00 +3E003E00 +3E003E00 +7C001F00 +7C001F00 +7C001F00 +7C001F00 +FC001F80 +F8000F80 +F8000F80 +F8000F80 +F8000F80 +F8000F80 +F8000F80 +F8000F80 +F8000F80 +F8000F80 +F8000F80 +F8000F80 +F8000F80 +78000F00 +7C001F00 +7C001F00 +7C001F00 +3C001E00 +3E003E00 +1E003C00 +1F007C00 +0F80F800 +07C1F000 +03FFE000 +007F0000 +ENDCHAR +STARTCHAR 0031 +ENCODING 49 +SWIDTH 240 0 +DWIDTH 12 0 +BBX 9 36 1 0 +BITMAP +FE00 +3E00 +3E00 +3E00 +3E00 +3E00 +3E00 +3E00 +3E00 +3E00 +3E00 +3E00 +3E00 +3E00 +3E00 +3E00 +3E00 +3E00 +3E00 +3E00 +3E00 +3E00 +3E00 +3E00 +3E00 +3E00 +3E00 +3E00 +3E00 +3E00 +3E00 +3E00 +3E00 +3E00 +FF80 +FF80 +ENDCHAR +STARTCHAR 0032 +ENCODING 50 +SWIDTH 500 0 +DWIDTH 25 0 +BBX 22 36 2 0 +BITMAP +00FE00 +03FF80 +0E0FC0 +1803E0 +3001F0 +2001F0 +6001F8 +4000F8 +4000F8 +0000F8 +0000F8 +0000F8 +0000F0 +0001F0 +0001E0 +0003E0 +0007C0 +000780 +000F00 +001E00 +003C00 +007800 +00F000 +01E000 +03C000 +078000 +0F0000 +1E0000 +3C0000 +7C0000 +780000 +F8000C +F8000C +F8000C +FFFFFC +FFFFFC +ENDCHAR +STARTCHAR 0033 +ENCODING 51 +SWIDTH 480 0 +DWIDTH 24 0 +BBX 21 37 1 -1 +BITMAP +01FC00 +07FF00 +0E1F80 +1807C0 +1003E0 +3003E0 +0003F0 +0001F0 +0001F0 +0001F0 +0001F0 +0001F0 +0001E0 +0003E0 +0003C0 +0007C0 +000F80 +00FE00 +00FF00 +000FC0 +0003E0 +0003E0 +0001F0 +0001F0 +0000F8 +0000F8 +0000F8 +0000F8 +0000F8 +0000F8 +C001F0 +C001F0 +E003E0 +F007E0 +F80FC0 +FFFF00 +01FC00 +ENDCHAR +STARTCHAR 0034 +ENCODING 52 +SWIDTH 460 0 +DWIDTH 23 0 +BBX 22 36 0 0 +BITMAP +0001C0 +0003C0 +0007C0 +0007C0 +000FC0 +000FC0 +001FC0 +0037C0 +0037C0 +0067C0 +0047C0 +00C7C0 +0187C0 +0187C0 +0307C0 +0207C0 +0607C0 +0C07C0 +0C07C0 +1807C0 +1007C0 +3007C0 +2007C0 +7FFFFC +FFFFFC +FFFFFC +FFFFFC +FFFFFC +0007C0 +0007C0 +0007C0 +0007C0 +0007C0 +0007C0 +0007C0 +0007C0 +ENDCHAR +STARTCHAR 0035 +ENCODING 53 +SWIDTH 500 0 +DWIDTH 25 0 +BBX 23 37 1 -1 +BITMAP +0FFFF8 +0FFFF8 +0F8000 +0F8000 +0F8000 +0F8000 +0F8000 +0F8000 +0F0000 +1F0000 +1F0000 +1F0000 +1F0000 +1F0000 +1FFE00 +1FFFC0 +1F07E0 +1C03F0 +0001F8 +0000F8 +00007C +00007C +00007E +00003E +00003E +40003E +C0003E +C0003E +E0003E +60007C +70007C +3000FC +1800F8 +1C01F0 +0F07E0 +03FF80 +00FE00 +ENDCHAR +STARTCHAR 0036 +ENCODING 54 +SWIDTH 520 0 +DWIDTH 26 0 +BBX 23 37 2 -1 +BITMAP +00FE00 +03FF00 +0FC180 +0F80C0 +1F0000 +3E0000 +3E0000 +3E0000 +7C0000 +7C0000 +7C0000 +7C0000 +780000 +780000 +F8FE00 +FBFFC0 +FE07E0 +F803F0 +F801F8 +F800F8 +F8007C +F8007C +F8003E +F8003E +F8003E +F8003E +F8003E +F8003E +7C003E +7C007C +7C007C +3E00FC +3E00F8 +1F01F0 +0F87E0 +07FFC0 +00FE00 +ENDCHAR +STARTCHAR 0037 +ENCODING 55 +SWIDTH 460 0 +DWIDTH 23 0 +BBX 21 36 1 0 +BITMAP +FFFFF8 +FFFFF8 +0000F8 +0001F0 +0001F0 +0003E0 +0003C0 +0007C0 +000F80 +000F80 +001F00 +001F00 +003E00 +003E00 +007C00 +007800 +00F800 +00F800 +01F000 +01F000 +03E000 +03E000 +03C000 +07C000 +07C000 +0F8000 +0F8000 +0F8000 +1F0000 +1F0000 +1F0000 +1F0000 +3E0000 +3E0000 +3E0000 +3E0000 +ENDCHAR +STARTCHAR 0038 +ENCODING 56 +SWIDTH 520 0 +DWIDTH 26 0 +BBX 22 37 2 -1 +BITMAP +01FE00 +07FF80 +0F87C0 +1F03E0 +3E01F0 +3E01F0 +7C00F8 +7C00F8 +7C00F8 +7C00F8 +7C00F8 +3E01F0 +3E01F0 +1F03E0 +0F87C0 +03FF00 +03FF00 +0F87C0 +1F03E0 +3E01F0 +7C00F8 +7C00F8 +7800F8 +F8007C +F8007C +F8007C +F8007C +F8007C +F8007C +FC00FC +7C00F8 +7C00F8 +3E01F0 +1F03E0 +0F87C0 +07FF80 +01FE00 +ENDCHAR +STARTCHAR 0039 +ENCODING 57 +SWIDTH 520 0 +DWIDTH 26 0 +BBX 23 37 1 -1 +BITMAP +01FE00 +07FFC0 +0FC3E0 +1F01F0 +3E00F8 +7E00F8 +7C007C +7C007C +F8003E +F8003E +F8003E +F8003E +F8003E +F8003E +F8003E +7C003E +7C003E +3E003E +3F007E +0FC1FE +07FFFC +01FE7C +00007C +00007C +000078 +0000F8 +0000F8 +0000F0 +0001F0 +0001E0 +0003E0 +0007C0 +000F80 +001F00 +007E00 +0FF000 +0F0000 +ENDCHAR +STARTCHAR 003A +ENCODING 58 +SWIDTH 160 0 +DWIDTH 8 0 +BBX 5 24 2 0 +BITMAP +F8 +F8 +F8 +F8 +F8 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +F8 +F8 +F8 +F8 +F8 +ENDCHAR +STARTCHAR 003B +ENCODING 59 +SWIDTH 180 0 +DWIDTH 9 0 +BBX 5 29 2 -5 +BITMAP +F8 +F8 +F8 +F8 +F8 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +F8 +F8 +F8 +F8 +F8 +38 +18 +30 +60 +C0 +ENDCHAR +STARTCHAR 003C +ENCODING 60 +SWIDTH 440 0 +DWIDTH 22 0 +BBX 19 24 1 6 +BITMAP +000020 +0000E0 +0001E0 +0007C0 +001F80 +003E00 +00F800 +03F000 +07C000 +1F8000 +3E0000 +F80000 +F80000 +7E0000 +1F0000 +0FC000 +03F000 +00F800 +007E00 +001F80 +0007C0 +0003E0 +0000E0 +000020 +ENDCHAR +STARTCHAR 003D +ENCODING 61 +SWIDTH 400 0 +DWIDTH 20 0 +BBX 18 13 1 13 +BITMAP +FFFFC0 +FFFFC0 +000000 +000000 +000000 +000000 +000000 +000000 +000000 +000000 +000000 +FFFFC0 +FFFFC0 +ENDCHAR +STARTCHAR 003E +ENCODING 62 +SWIDTH 440 0 +DWIDTH 22 0 +BBX 19 23 2 6 +BITMAP +800000 +E00000 +F80000 +7C0000 +3F0000 +0FC000 +03E000 +01F800 +007E00 +001F00 +000FC0 +0003E0 +0007C0 +001F80 +007E00 +00F800 +03E000 +0FC000 +1F0000 +7C0000 +F80000 +E00000 +800000 +ENDCHAR +STARTCHAR 003F +ENCODING 63 +SWIDTH 480 0 +DWIDTH 24 0 +BBX 23 36 1 0 +BITMAP +01FE00 +0FFFC0 +3F83E0 +7E00F8 +7C007C +FC007C +F8003E +F8003E +7C003E +7C007C +3C007C +0000F8 +0001F0 +0001E0 +0007C0 +000F80 +001E00 +001C00 +003800 +007000 +007000 +006000 +006000 +006000 +006000 +006000 +006000 +006000 +006000 +000000 +000000 +01F000 +01F000 +01F000 +01F000 +01F000 +ENDCHAR +STARTCHAR 0040 +ENCODING 64 +SWIDTH 720 0 +DWIDTH 36 0 +BBX 32 35 2 0 +BITMAP +0000FC00 +0007FF80 +001F03C0 +007800E0 +00F00030 +01C00018 +0380000C +0700000C +0E000006 +0C03F806 +180F07C7 +381E03C3 +303C03C3 +307C07C3 +60F80783 +60F80783 +60F00783 +C1F00783 +C1F00F87 +C1F00F86 +C1F00F06 +C1F00F0C +C1F00F0C +C1F81F18 +C0F83F38 +E07EFE70 +603FDFE0 +701F0F80 +70000000 +38000200 +1C000600 +1F001C00 +07C07800 +03FFE000 +007F8000 +ENDCHAR +STARTCHAR 0041 +ENCODING 65 +SWIDTH 600 0 +DWIDTH 30 0 +BBX 29 36 1 0 +BITMAP +00060000 +000F0000 +000F0000 +000F0000 +000F8000 +001F8000 +001F8000 +001FC000 +003FC000 +0037C000 +0037E000 +0077E000 +0063E000 +0063F000 +00E3F000 +00C1F000 +00C1F800 +01C1F800 +0180F800 +0180FC00 +0180FC00 +03807C00 +03FFFC00 +03FFFE00 +07007E00 +06003E00 +06003F00 +0E003F00 +0C001F00 +0C001F80 +1C001F80 +18000F80 +18000FC0 +38000FC0 +FE001FF8 +FE001FF8 +ENDCHAR +STARTCHAR 0042 +ENCODING 66 +SWIDTH 580 0 +DWIDTH 29 0 +BBX 26 36 1 0 +BITMAP +FFFFC000 +FFFFF000 +1F01F800 +1F007C00 +1F003E00 +1F003E00 +1F001F00 +1F001F00 +1F001F00 +1F001F00 +1F001F00 +1F001F00 +1F003E00 +1F003E00 +1F007C00 +1F01F800 +1FFFF000 +1FFFFC00 +1F007E00 +1F003F00 +1F001F80 +1F000F80 +1F000F80 +1F0007C0 +1F0007C0 +1F0007C0 +1F0007C0 +1F0007C0 +1F0007C0 +1F000F80 +1F000F80 +1F001F00 +1F003F00 +1F007E00 +FFFFF800 +FFFFE000 +ENDCHAR +STARTCHAR 0043 +ENCODING 67 +SWIDTH 560 0 +DWIDTH 28 0 +BBX 24 37 2 -1 +BITMAP +001FF0 +00FFFE +03F03F +07C00F +0F8007 +1F0003 +3E0003 +3E0000 +7C0000 +7C0000 +7C0000 +F80000 +F80000 +F80000 +F80000 +F80000 +F80000 +F80000 +F80000 +F80000 +F80000 +F80000 +F80000 +F80000 +F80000 +7C0000 +7C0000 +7C0000 +7C0000 +3E0000 +3E0003 +1F0003 +0F8007 +07C00F +03F03F +00FFFE +001FF0 +ENDCHAR +STARTCHAR 0044 +ENCODING 68 +SWIDTH 620 0 +DWIDTH 31 0 +BBX 28 36 1 0 +BITMAP +FFFFE000 +FFFFFC00 +1F00FE00 +1F003F00 +1F001F80 +1F000FC0 +1F0007C0 +1F0007E0 +1F0003E0 +1F0003E0 +1F0003E0 +1F0003F0 +1F0001F0 +1F0001F0 +1F0001F0 +1F0001F0 +1F0001F0 +1F0001F0 +1F0001F0 +1F0001F0 +1F0001F0 +1F0001F0 +1F0001F0 +1F0001F0 +1F0003F0 +1F0003E0 +1F0003E0 +1F0003E0 +1F0007E0 +1F0007C0 +1F000FC0 +1F001F80 +1F003F00 +1F007E00 +FFFFFC00 +FFFFE000 +ENDCHAR +STARTCHAR 0045 +ENCODING 69 +SWIDTH 520 0 +DWIDTH 26 0 +BBX 24 36 1 0 +BITMAP +FFFFFF +FFFFFF +1F0003 +1F0003 +1F0000 +1F0000 +1F0000 +1F0000 +1F0000 +1F0000 +1F0000 +1F0000 +1F0000 +1F0000 +1F0060 +1F0060 +1F0060 +1FFFE0 +1FFFE0 +1F0060 +1F0060 +1F0060 +1F0000 +1F0000 +1F0000 +1F0000 +1F0000 +1F0000 +1F0000 +1F0000 +1F0000 +1F0003 +1F0003 +1F0003 +FFFFFF +FFFFFF +ENDCHAR +STARTCHAR 0046 +ENCODING 70 +SWIDTH 500 0 +DWIDTH 25 0 +BBX 23 36 1 0 +BITMAP +FFFFFE +FFFFFE +1F0006 +1F0006 +1F0000 +1F0000 +1F0000 +1F0000 +1F0000 +1F0000 +1F0000 +1F0000 +1F0000 +1F0000 +1F0060 +1F0060 +1F0060 +1FFFE0 +1FFFE0 +1F0060 +1F0060 +1F0060 +1F0000 +1F0000 +1F0000 +1F0000 +1F0000 +1F0000 +1F0000 +1F0000 +1F0000 +1F0000 +1F0000 +1F0000 +FFE000 +FFE000 +ENDCHAR +STARTCHAR 0047 +ENCODING 71 +SWIDTH 640 0 +DWIDTH 32 0 +BBX 29 37 2 -1 +BITMAP +007F8000 +03FFF000 +07E07C00 +0F801E00 +1F000F00 +3F000700 +3E000700 +7E000300 +7C000300 +7C000300 +7C000300 +FC000000 +F8000000 +F8000000 +F8000000 +F8000000 +F8000000 +F8000000 +F8000000 +F8000000 +F800FFF8 +F800FFF8 +F80007C0 +F80007C0 +F80007C0 +7C0007C0 +7C0007C0 +7C0007C0 +7C0007C0 +3E000FC0 +3E000F80 +1F000F80 +1F801F00 +0FC03E00 +07E07C00 +01FFF000 +007FC000 +ENDCHAR +STARTCHAR 0048 +ENCODING 72 +SWIDTH 660 0 +DWIDTH 33 0 +BBX 31 36 1 0 +BITMAP +FFE007FE +FFE007FE +1F0001F0 +1F0001F0 +1F0001F0 +1F0001F0 +1F0001F0 +1F0001F0 +1F0001F0 +1F0001F0 +1F0001F0 +1F0001F0 +1F0001F0 +1F0001F0 +1F0001F0 +1F0001F0 +1F0001F0 +1FFFFFF0 +1FFFFFF0 +1F0001F0 +1F0001F0 +1F0001F0 +1F0001F0 +1F0001F0 +1F0001F0 +1F0001F0 +1F0001F0 +1F0001F0 +1F0001F0 +1F0001F0 +1F0001F0 +1F0001F0 +1F0001F0 +1F0001F0 +FFE007FE +FFE007FE +ENDCHAR +STARTCHAR 0049 +ENCODING 73 +SWIDTH 280 0 +DWIDTH 14 0 +BBX 11 36 1 0 +BITMAP +FFE0 +FFE0 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +FFE0 +FFE0 +ENDCHAR +STARTCHAR 004A +ENCODING 74 +SWIDTH 480 0 +DWIDTH 24 0 +BBX 22 37 1 -1 +BITMAP +000FFC +000FFC +0003E0 +0003E0 +0003E0 +0003E0 +0003E0 +0003E0 +0003E0 +0003E0 +0003E0 +0003E0 +0003E0 +0003E0 +0003E0 +0003E0 +0003E0 +0003E0 +0003E0 +0003E0 +0003E0 +0003E0 +0003E0 +0003E0 +0003E0 +0003E0 +0003E0 +0003E0 +3003E0 +F003E0 +F003E0 +7007E0 +7807C0 +3C0FC0 +1E1F80 +0FFF00 +01F800 +ENDCHAR +STARTCHAR 004B +ENCODING 75 +SWIDTH 680 0 +DWIDTH 34 0 +BBX 30 36 1 0 +BITMAP +FFE003F0 +FFE003F0 +1F000180 +1F000700 +1F000E00 +1F001C00 +1F003000 +1F006000 +1F00C000 +1F038000 +1F070000 +1F0E0000 +1F1C0000 +1F300000 +1F600000 +1FE00000 +1FF00000 +1FF80000 +1FFC0000 +1FFE0000 +1F7F0000 +1F3F8000 +1F1F8000 +1F1FC000 +1F0FE000 +1F07F000 +1F03F800 +1F01FC00 +1F00FE00 +1F007F00 +1F003F80 +1F001FC0 +1F000FC0 +1F000FE0 +FFE00FFC +FFE00FFC +ENDCHAR +STARTCHAR 004C +ENCODING 76 +SWIDTH 500 0 +DWIDTH 25 0 +BBX 23 36 1 0 +BITMAP +FFC000 +FFC000 +1F0000 +1F0000 +1F0000 +1F0000 +1F0000 +1F0000 +1F0000 +1F0000 +1F0000 +1F0000 +1F0000 +1F0000 +1F0000 +1F0000 +1F0000 +1F0000 +1F0000 +1F0000 +1F0000 +1F0000 +1F0000 +1F0000 +1F0000 +1F0000 +1F0000 +1F0000 +1F0000 +1F0000 +1F0000 +1F0006 +1F0006 +1F0006 +FFFFFE +FFFFFE +ENDCHAR +STARTCHAR 004D +ENCODING 77 +SWIDTH 740 0 +DWIDTH 37 0 +BBX 35 36 1 0 +BITMAP +FF80003FE0 +FF80003FE0 +1F80003F00 +1FC0007F00 +1FC0007F00 +1FC0007F00 +1FE000FF00 +1FE000FF00 +1BE000FF00 +1BF001DF00 +1BF001DF00 +19F001DF00 +19F8039F00 +19F8039F00 +18F8039F00 +18FC071F00 +18FC071F00 +187C071F00 +187E0E1F00 +187E0E1F00 +183E0E1F00 +183F1C1F00 +183F1C1F00 +181F1C1F00 +181FB81F00 +181FB81F00 +180FB01F00 +180FF01F00 +180FF01F00 +1807E01F00 +1807E01F00 +1807E01F00 +1803C01F00 +1803C01F00 +FF03C07FE0 +FF01807FE0 +ENDCHAR +STARTCHAR 004E +ENCODING 78 +SWIDTH 620 0 +DWIDTH 31 0 +BBX 29 36 1 0 +BITMAP +FF8007F8 +FF8007F8 +1FC000C0 +1FC000C0 +1FE000C0 +1BF000C0 +1BF000C0 +19F800C0 +19F800C0 +18FC00C0 +187E00C0 +187E00C0 +183F00C0 +183F00C0 +181F80C0 +180FC0C0 +180FC0C0 +1807E0C0 +1807E0C0 +1803F0C0 +1801F8C0 +1801F8C0 +1800FCC0 +1800FEC0 +18007EC0 +18003FC0 +18003FC0 +18001FC0 +18001FC0 +18000FC0 +180007C0 +180007C0 +180003C0 +180003C0 +FE0001C0 +FE0000C0 +ENDCHAR +STARTCHAR 004F +ENCODING 79 +SWIDTH 640 0 +DWIDTH 32 0 +BBX 27 37 2 -1 +BITMAP +007F8000 +01FFF000 +07E0FC00 +0F807E00 +1F003F00 +1F001F00 +3E000F80 +7E000F80 +7C000FC0 +7C0007C0 +FC0007C0 +FC0007E0 +FC0007E0 +FC0007E0 +F80007E0 +F80003E0 +F80003E0 +F80003E0 +F80003E0 +F80003E0 +F80003E0 +F80003E0 +F80007E0 +F80007E0 +FC0007E0 +FC0007E0 +FC0007C0 +7C0007C0 +7C000FC0 +7E000F80 +3E000F80 +1F001F00 +1F003F00 +0F807E00 +07E0FC00 +01FFF000 +007FC000 +ENDCHAR +STARTCHAR 0050 +ENCODING 80 +SWIDTH 600 0 +DWIDTH 30 0 +BBX 27 36 1 0 +BITMAP +FFFFE000 +FFFFFC00 +1F007E00 +1F001F80 +1F000F80 +1F0007C0 +1F0007C0 +1F0003E0 +1F0003E0 +1F0003E0 +1F0003E0 +1F0003E0 +1F0007C0 +1F0007C0 +1F000F80 +1F001F80 +1F007E00 +1FFFFC00 +1FFFE000 +1F000000 +1F000000 +1F000000 +1F000000 +1F000000 +1F000000 +1F000000 +1F000000 +1F000000 +1F000000 +1F000000 +1F000000 +1F000000 +1F000000 +1F000000 +FFE00000 +FFE00000 +ENDCHAR +STARTCHAR 0051 +ENCODING 81 +SWIDTH 620 0 +DWIDTH 31 0 +BBX 32 43 1 -7 +BITMAP +007FC000 +03FFF800 +0FF0FE00 +1FC03F00 +1F801F00 +3F000F80 +3F000FC0 +7E0007C0 +7E0007E0 +7C0003E0 +7C0003E0 +FC0003E0 +FC0003F0 +F80001F0 +F80001F0 +F80001F0 +F80001F0 +F80001F0 +F80001F0 +F80001F0 +F80001F0 +F80001F0 +F80001F0 +F80001F0 +FC0003F0 +7C0003E0 +7C0003E0 +7C0003E0 +7E0007E0 +3E0007C0 +3F000FC0 +1F000F80 +1F801F00 +0FC03F00 +03F0FC00 +00FFF000 +000FF800 +0000FE00 +00003F00 +00001F80 +00000FE0 +000007FF +000001FC +ENDCHAR +STARTCHAR 0052 +ENCODING 82 +SWIDTH 640 0 +DWIDTH 32 0 +BBX 31 36 1 0 +BITMAP +FFFFE000 +FFFFFC00 +1F007E00 +1F001F00 +1F000F80 +1F0007C0 +1F0007C0 +1F0003E0 +1F0003E0 +1F0003E0 +1F0003E0 +1F0003E0 +1F0007C0 +1F0007C0 +1F000F80 +1F001F80 +1F007F00 +1FFFFC00 +1FFFF000 +1F07E000 +1F03E000 +1F03F000 +1F03F000 +1F01F800 +1F00F800 +1F00FC00 +1F007C00 +1F007E00 +1F003F00 +1F003F80 +1F001F80 +1F000FC0 +1F000FE0 +1F0007F0 +FFE003FE +FFE001FE +ENDCHAR +STARTCHAR 0053 +ENCODING 83 +SWIDTH 520 0 +DWIDTH 26 0 +BBX 23 37 2 -1 +BITMAP +01FE00 +0FFFE0 +1F83F0 +3F00F0 +7E0070 +7C0070 +F80030 +F80000 +F80000 +F80000 +F80000 +FC0000 +FC0000 +7E0000 +7F0000 +3FC000 +1FF800 +0FFF00 +03FFC0 +00FFE0 +001FF0 +0003F8 +0000FC +00007C +00007E +00003E +00003E +C0003E +C0003E +E0003E +E0007C +E0007C +F000F8 +7801F0 +3E07E0 +0FFFC0 +03FE00 +ENDCHAR +STARTCHAR 0054 +ENCODING 84 +SWIDTH 540 0 +DWIDTH 27 0 +BBX 25 36 1 0 +BITMAP +FFFFFF80 +FFFFFF80 +C03E0380 +C03E0380 +C03E0380 +003E0000 +003E0000 +003E0000 +003E0000 +003E0000 +003E0000 +003E0000 +003E0000 +003E0000 +003E0000 +003E0000 +003E0000 +003E0000 +003E0000 +003E0000 +003E0000 +003E0000 +003E0000 +003E0000 +003E0000 +003E0000 +003E0000 +003E0000 +003E0000 +003E0000 +003E0000 +003E0000 +003E0000 +003E0000 +01FF8000 +01FF8000 +ENDCHAR +STARTCHAR 0055 +ENCODING 85 +SWIDTH 720 0 +DWIDTH 36 0 +BBX 34 37 1 -1 +BITMAP +FFC001FFC0 +FFC001FFC0 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F80003E00 +0F80007C00 +0F80007C00 +0F80007C00 +07C0007800 +07C000F800 +03E000F800 +03E001F000 +01F003E000 +00FC0FC000 +003FFF8000 +0007FC0000 +ENDCHAR +STARTCHAR 0056 +ENCODING 86 +SWIDTH 600 0 +DWIDTH 30 0 +BBX 29 36 1 0 +BITMAP +FFC003F8 +FFC003F8 +3F0000C0 +1F0001C0 +1F800180 +1F800180 +0F800380 +0FC00300 +0FC00300 +07C00700 +07E00600 +07E00600 +03E00600 +03F00E00 +03F00C00 +01F00C00 +01F81C00 +01F81800 +00F81800 +00F83800 +00FC3000 +007C3000 +007C7000 +007E6000 +007E6000 +003EE000 +003FC000 +003FC000 +001FC000 +001FC000 +001F8000 +000F8000 +000F8000 +000F0000 +00070000 +00070000 +ENDCHAR +STARTCHAR 0057 +ENCODING 87 +SWIDTH 860 0 +DWIDTH 43 0 +BBX 41 36 1 0 +BITMAP +FFCFFFF83F80 +FFCFFFF83F80 +1F03F0C00C00 +1F81F0C01C00 +1F81F9C01800 +0F81F9801800 +0FC0F9803800 +0FC0FF803000 +07C0FF003000 +07E07F007000 +07E07F006000 +03E07F006000 +03F03E00E000 +03F03E00C000 +01F03F00C000 +01F83F01C000 +01F81F018000 +00F81F818000 +00FC1F818000 +00FC1F838000 +007C3FC30000 +007C3FC30000 +007E37C70000 +003E77E60000 +003E67E60000 +003F63EE0000 +003FE3FC0000 +001FC3FC0000 +001FC1FC0000 +001FC1F80000 +000FC1F80000 +000F80F80000 +000F80F00000 +000780F00000 +000700700000 +000700700000 +ENDCHAR +STARTCHAR 0058 +ENCODING 88 +SWIDTH 660 0 +DWIDTH 33 0 +BBX 29 36 2 0 +BITMAP +FFC01FC0 +FFC01FC0 +1F000600 +1F800E00 +0F800C00 +0FC01800 +07C03800 +07E03000 +03F07000 +01F06000 +01F8E000 +00F9C000 +00FD8000 +007F8000 +003F0000 +003F0000 +001F0000 +001F8000 +001F8000 +001FC000 +003FE000 +0033E000 +0063F000 +00E1F000 +00C1F800 +01C0FC00 +01807C00 +03007E00 +03003E00 +06003F00 +0E001F00 +0C000F80 +1C000FC0 +180007C0 +FC001FF8 +FC001FF8 +ENDCHAR +STARTCHAR 0059 +ENCODING 89 +SWIDTH 620 0 +DWIDTH 31 0 +BBX 29 36 1 0 +BITMAP +FFC001F8 +FFC001F8 +1F0000C0 +0F8001C0 +0FC00180 +07C00300 +07E00700 +03E00600 +03F00E00 +01F00C00 +00F81800 +00F81800 +007C3000 +007C7000 +003E6000 +001FE000 +001FC000 +000F8000 +000F8000 +000F8000 +000F8000 +000F8000 +000F8000 +000F8000 +000F8000 +000F8000 +000F8000 +000F8000 +000F8000 +000F8000 +000F8000 +000F8000 +000F8000 +000F8000 +007FE000 +007FE000 +ENDCHAR +STARTCHAR 005A +ENCODING 90 +SWIDTH 580 0 +DWIDTH 29 0 +BBX 26 36 1 0 +BITMAP +7FFFFFC0 +7FFFFF80 +60001F80 +60001F00 +60003F00 +00003E00 +00007C00 +0000FC00 +0000F800 +0001F800 +0001F000 +0003F000 +0007E000 +0007C000 +000FC000 +000F8000 +001F8000 +001F0000 +003E0000 +007E0000 +007C0000 +00FC0000 +00F80000 +01F80000 +03F00000 +03E00000 +07E00000 +07C00000 +0FC00000 +0F800000 +1F000000 +3F0000C0 +3E0000C0 +7E0000C0 +7FFFFFC0 +FFFFFFC0 +ENDCHAR +STARTCHAR 005B +ENCODING 91 +SWIDTH 280 0 +DWIDTH 14 0 +BBX 11 48 2 -12 +BITMAP +FFE0 +FFE0 +F800 +F800 +F800 +F800 +F800 +F800 +F800 +F800 +F800 +F800 +F800 +F800 +F800 +F800 +F800 +F800 +F800 +F800 +F800 +F800 +F800 +F800 +F800 +F800 +F800 +F800 +F800 +F800 +F800 +F800 +F800 +F800 +F800 +F800 +F800 +F800 +F800 +F800 +F800 +F800 +F800 +F800 +F800 +F800 +FFE0 +FFE0 +ENDCHAR +STARTCHAR 005C +ENCODING 92 +SWIDTH 340 0 +DWIDTH 17 0 +BBX 15 36 1 0 +BITMAP +8000 +C000 +4000 +4000 +6000 +2000 +3000 +1000 +1000 +1800 +0800 +0C00 +0400 +0400 +0600 +0200 +0300 +0300 +0100 +0180 +0080 +00C0 +00C0 +0040 +0060 +0020 +0030 +0030 +0010 +0018 +0008 +000C +000C +0004 +0006 +0002 +ENDCHAR +STARTCHAR 005D +ENCODING 93 +SWIDTH 280 0 +DWIDTH 14 0 +BBX 12 48 0 -12 +BITMAP +FFF0 +FFF0 +01F0 +01F0 +01F0 +01F0 +01F0 +01F0 +01F0 +01F0 +01F0 +01F0 +01F0 +01F0 +01F0 +01F0 +01F0 +01F0 +01F0 +01F0 +01F0 +01F0 +01F0 +01F0 +01F0 +01F0 +01F0 +01F0 +01F0 +01F0 +01F0 +01F0 +01F0 +01F0 +01F0 +01F0 +01F0 +01F0 +01F0 +01F0 +01F0 +01F0 +01F0 +01F0 +01F0 +01F0 +FFF0 +FFF0 +ENDCHAR +STARTCHAR 005E +ENCODING 94 +SWIDTH 500 0 +DWIDTH 25 0 +BBX 20 17 3 19 +BITMAP +006000 +00F000 +01F000 +019800 +031800 +030C00 +060C00 +060600 +0C0300 +0C0300 +180180 +180180 +3000C0 +6000C0 +600060 +C00060 +C00030 +ENDCHAR +STARTCHAR 005F +ENCODING 95 +SWIDTH 540 0 +DWIDTH 27 0 +BBX 22 2 2 -10 +BITMAP +FFFFFC +FFFFFC +ENDCHAR +STARTCHAR 0060 +ENCODING 96 +SWIDTH 220 0 +DWIDTH 11 0 +BBX 8 8 1 27 +BITMAP +F8 +7C +7C +3E +1E +0F +07 +06 +ENDCHAR +STARTCHAR 0061 +ENCODING 97 +SWIDTH 540 0 +DWIDTH 27 0 +BBX 23 25 2 -1 +BITMAP +03FE00 +1FFF80 +3C0FC0 +3807E0 +3003E0 +3001F0 +2001F0 +0001F0 +0001F0 +0001F0 +0003F0 +001DF0 +03E1F0 +1F01F0 +3C01F0 +7C01F0 +F801F0 +F801F0 +F803F0 +F803F0 +F807F0 +FC0DF0 +7E39F8 +3FF0FE +0FC000 +ENDCHAR +STARTCHAR 0062 +ENCODING 98 +SWIDTH 520 0 +DWIDTH 26 0 +BBX 24 37 1 -1 +BITMAP +FF0000 +1F0000 +1F0000 +1F0000 +1F0000 +1F0000 +1F0000 +1F0000 +1F0000 +1F0000 +1F0000 +1F0000 +1F3F80 +1FFFF0 +1FE1F8 +1F80FC +1F007C +1F007E +1F003E +1F003E +1F001F +1F001F +1F001F +1F001F +1F001F +1F001F +1F001F +1F001F +1F001F +1F001E +1F003E +1F003E +1F003C +1F007C +1F80F8 +FF61F0 +001F80 +ENDCHAR +STARTCHAR 0063 +ENCODING 99 +SWIDTH 460 0 +DWIDTH 23 0 +BBX 19 25 2 -1 +BITMAP +01F820 +07FE60 +1FC3E0 +3F00E0 +3E0060 +7C0060 +7C0020 +7C0000 +F80000 +F80000 +F80000 +F80000 +F80000 +F80000 +F80000 +F80000 +F80000 +7C0000 +7C0020 +7E0020 +3E0060 +3F00C0 +1F8380 +0FFF00 +01FC00 +ENDCHAR +STARTCHAR 0064 +ENCODING 100 +SWIDTH 520 0 +DWIDTH 26 0 +BBX 24 37 1 -1 +BITMAP +0007F8 +0000F8 +0000F8 +0000F8 +0000F8 +0000F8 +0000F8 +0000F8 +0000F8 +0000F8 +0000F8 +0000F8 +01FCF8 +0FFFF8 +1F87F8 +3F01F8 +3E00F8 +7E00F8 +7C00F8 +7C00F8 +F800F8 +F800F8 +F800F8 +F800F8 +F800F8 +F800F8 +F800F8 +F800F8 +F800F8 +7800F8 +7C00F8 +7C00F8 +3C00F8 +3E00F8 +1F01F8 +0F86FF +01F800 +ENDCHAR +STARTCHAR 0065 +ENCODING 101 +SWIDTH 500 0 +DWIDTH 25 0 +BBX 21 25 2 -1 +BITMAP +01FC00 +07FF00 +1F07C0 +3E03C0 +3C01E0 +7C01F0 +7800F0 +7800F0 +F800F8 +FFFFF8 +FFFFF8 +F80000 +F80000 +F80000 +F80000 +F80000 +F80000 +7C0000 +7C0010 +3C0018 +3E0030 +1F0060 +0F81C0 +07FF80 +01FC00 +ENDCHAR +STARTCHAR 0066 +ENCODING 102 +SWIDTH 320 0 +DWIDTH 16 0 +BBX 13 36 1 0 +BITMAP +03E0 +0FF8 +0F98 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +FFE0 +FFE0 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +FFE0 +FFE0 +ENDCHAR +STARTCHAR 0067 +ENCODING 103 +SWIDTH 520 0 +DWIDTH 26 0 +BBX 24 36 0 -12 +BITMAP +003FFF +01FFFF +03E1F0 +07C0F8 +0F807C +0F807C +1F003C +1F003E +1F003E +1F003E +1F003E +1F003E +1F003C +0F807C +0F807C +07C0F8 +03E1F0 +01FFC0 +003F80 +000700 +00FC00 +03E000 +07C000 +03F000 +00EF80 +0780F0 +1E003C +3C003E +78001F +F8001F +F8001F +F8001F +FC003E +7E00FE +3FFFF8 +07FFC0 +ENDCHAR +STARTCHAR 0068 +ENCODING 104 +SWIDTH 580 0 +DWIDTH 29 0 +BBX 27 36 1 0 +BITMAP +FF000000 +1F000000 +1F000000 +1F000000 +1F000000 +1F000000 +1F000000 +1F000000 +1F000000 +1F000000 +1F000000 +1F000000 +1F1FC000 +1F7FF000 +1FE0F800 +1FC07C00 +1F003E00 +1F003E00 +1F001F00 +1F001F00 +1F001F00 +1F001F00 +1F001F00 +1F001F00 +1F001F00 +1F001F00 +1F001F00 +1F001F00 +1F001F00 +1F001F00 +1F001F00 +1F001F00 +1F001F00 +1F001F00 +FFE0FFE0 +FFE0FFE0 +ENDCHAR +STARTCHAR 0069 +ENCODING 105 +SWIDTH 280 0 +DWIDTH 14 0 +BBX 10 35 2 0 +BITMAP +1F00 +1F00 +1F00 +1F00 +1F00 +0000 +0000 +0000 +0000 +0000 +0000 +FF00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +FFC0 +FFC0 +ENDCHAR +STARTCHAR 006A +ENCODING 106 +SWIDTH 220 0 +DWIDTH 11 0 +BBX 8 47 1 -12 +BITMAP +1F +1F +1F +1F +1F +00 +00 +00 +00 +00 +00 +FF +1F +1F +1F +1F +1F +1F +1F +1F +1F +1F +1F +1F +1F +1F +1F +1F +1F +1F +1F +1F +1F +1F +1F +1F +1F +1F +1F +1F +1F +1F +1F +1F +3E +FC +F0 +ENDCHAR +STARTCHAR 006B +ENCODING 107 +SWIDTH 500 0 +DWIDTH 25 0 +BBX 22 36 1 0 +BITMAP +FF0000 +1F0000 +1F0000 +1F0000 +1F0000 +1F0000 +1F0000 +1F0000 +1F0000 +1F0000 +1F0000 +1F0000 +1F01F0 +1F01F0 +1F0180 +1F0300 +1F0600 +1F0C00 +1F1800 +1F1000 +1F2000 +1F4000 +1FC000 +1FE000 +1FE000 +1FF000 +1FF800 +1F7C00 +1F3E00 +1F1F00 +1F0F80 +1F07C0 +1F03E0 +1F03F0 +FFE3FC +FFE3FC +ENDCHAR +STARTCHAR 006C +ENCODING 108 +SWIDTH 260 0 +DWIDTH 13 0 +BBX 11 36 1 0 +BITMAP +FF00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +FFE0 +FFE0 +ENDCHAR +STARTCHAR 006D +ENCODING 109 +SWIDTH 820 0 +DWIDTH 41 0 +BBX 38 25 2 0 +BITMAP +000C003000 +FF77C1FE00 +1FC3E60F00 +1F81FC0780 +1F00F807C0 +1F00F803C0 +1F00F803E0 +1F00F803E0 +1F00F803E0 +1F00F803E0 +1F00F803E0 +1F00F803E0 +1F00F803E0 +1F00F803E0 +1F00F803E0 +1F00F803E0 +1F00F803E0 +1F00F803E0 +1F00F803E0 +1F00F803E0 +1F00F803E0 +1F00F803E0 +1F00F803E0 +FFE7FF1FFC +FFE7FF1FFC +ENDCHAR +STARTCHAR 006E +ENCODING 110 +SWIDTH 600 0 +DWIDTH 30 0 +BBX 26 24 2 0 +BITMAP +FF1F8000 +1F7FE000 +1FE1F800 +1F80F800 +1F007C00 +1F007C00 +1F003E00 +1F003E00 +1F003E00 +1F003E00 +1F003E00 +1F003E00 +1F003E00 +1F003E00 +1F003E00 +1F003E00 +1F003E00 +1F003E00 +1F003E00 +1F003E00 +1F003E00 +1F003E00 +FFE1FFC0 +FFE1FFC0 +ENDCHAR +STARTCHAR 006F +ENCODING 111 +SWIDTH 520 0 +DWIDTH 26 0 +BBX 22 25 2 -1 +BITMAP +01FE00 +07FF80 +1F87E0 +3F03F0 +3E01F0 +7C00F8 +7C00F8 +7C00F8 +F8007C +F8007C +F8007C +F8007C +F8007C +F8007C +F8007C +F8007C +F8007C +7C00F8 +7C00F8 +7C00F8 +3E01F0 +3F03F0 +1F87E0 +0FFFC0 +01FE00 +ENDCHAR +STARTCHAR 0070 +ENCODING 112 +SWIDTH 520 0 +DWIDTH 26 0 +BBX 24 36 1 -12 +BITMAP +FF1F80 +1FE1F0 +1F80F8 +1F007C +1F003C +1F003E +1F003E +1F001E +1F001F +1F001F +1F001F +1F001F +1F001F +1F001F +1F001F +1F001F +1F001F +1F003E +1F003E +1F007E +1F007C +1F80FC +1FE1F8 +1F7FF0 +1F1FC0 +1F0000 +1F0000 +1F0000 +1F0000 +1F0000 +1F0000 +1F0000 +1F0000 +1F0000 +FFE000 +FFE000 +ENDCHAR +STARTCHAR 0071 +ENCODING 113 +SWIDTH 520 0 +DWIDTH 26 0 +BBX 24 36 1 -12 +BITMAP +01F8F8 +0F86F8 +1F01F8 +3E00F8 +3C00F8 +7C00F8 +7C00F8 +F800F8 +F800F8 +F800F8 +F800F8 +F800F8 +F800F8 +F800F8 +F800F8 +F800F8 +F800F8 +7C00F8 +7C00F8 +7C00F8 +3E00F8 +3F01F8 +1F87F8 +0FFEF8 +01F8F8 +0000F8 +0000F8 +0000F8 +0000F8 +0000F8 +0000F8 +0000F8 +0000F8 +0000F8 +0007FF +0007FF +ENDCHAR +STARTCHAR 0072 +ENCODING 114 +SWIDTH 440 0 +DWIDTH 22 0 +BBX 20 24 1 0 +BITMAP +FF1F80 +1F7FE0 +1FE1F0 +1F8060 +1F0000 +1F0000 +1F0000 +1F0000 +1F0000 +1F0000 +1F0000 +1F0000 +1F0000 +1F0000 +1F0000 +1F0000 +1F0000 +1F0000 +1F0000 +1F0000 +1F0000 +1F0000 +FFE000 +FFE000 +ENDCHAR +STARTCHAR 0073 +ENCODING 115 +SWIDTH 440 0 +DWIDTH 22 0 +BBX 17 25 3 -1 +BITMAP +07FF00 +1FFF00 +3E1F00 +7C0F00 +F80700 +F80300 +F80300 +F80000 +FC0000 +7E0000 +7FC000 +3FF000 +0FFC00 +03FE00 +007F00 +001F00 +001F80 +000F80 +800F80 +C00F80 +C01F80 +E01F00 +F87E00 +CFFC00 +03F000 +ENDCHAR +STARTCHAR 0074 +ENCODING 116 +SWIDTH 320 0 +DWIDTH 16 0 +BBX 13 35 1 0 +BITMAP +0080 +0180 +0380 +0780 +0F80 +0F80 +0F80 +0F80 +0F80 +0F80 +0F80 +FFF8 +FFF8 +0F80 +0F80 +0F80 +0F80 +0F80 +0F80 +0F80 +0F80 +0F80 +0F80 +0F80 +0F80 +0F80 +0F80 +0F80 +0F80 +0F80 +0F80 +0F80 +0FC0 +07F8 +00F8 +ENDCHAR +STARTCHAR 0075 +ENCODING 117 +SWIDTH 580 0 +DWIDTH 29 0 +BBX 27 25 1 -1 +BITMAP +FF00FF00 +FF00FF00 +1F001F00 +1F001F00 +1F001F00 +1F001F00 +1F001F00 +1F001F00 +1F001F00 +1F001F00 +1F001F00 +1F001F00 +1F001F00 +1F001F00 +1F001F00 +1F001F00 +1F001F00 +1F001F00 +1F001F00 +0F801F00 +0F803F00 +07C07F00 +03E0FF00 +01FFDFE0 +007F0000 +ENDCHAR +STARTCHAR 0076 +ENCODING 118 +SWIDTH 520 0 +DWIDTH 26 0 +BBX 24 24 1 0 +BITMAP +FF803F +FF803F +1F0008 +1F0018 +0F0018 +0F8010 +0F8030 +07C020 +07C060 +03C060 +03E040 +03E0C0 +01F080 +01F180 +01F180 +00F900 +00FB00 +007E00 +007E00 +007E00 +003C00 +003C00 +001800 +001800 +ENDCHAR +STARTCHAR 0077 +ENCODING 119 +SWIDTH 740 0 +DWIDTH 37 0 +BBX 35 24 1 0 +BITMAP +FFDFFF07E0 +FFDFFF07E0 +1F03EC0100 +0F03E80300 +0F83F80200 +0F81F00600 +07C1F00600 +07C0F80400 +07C0F80C00 +03E0F80800 +03E07C1800 +01F0FC1800 +01F0FE1000 +01F0BE3000 +00F9BE3000 +00F91F6000 +007D1F6000 +007F0FC000 +007E0FC000 +003E0FC000 +003E078000 +001C078000 +001C030000 +0018030000 +ENDCHAR +STARTCHAR 0078 +ENCODING 120 +SWIDTH 540 0 +DWIDTH 27 0 +BBX 23 24 2 0 +BITMAP +FFC07C +FFC07C +1F0020 +1F8060 +0FC0C0 +0FC180 +07E300 +03F300 +03F600 +01FC00 +00F800 +00FC00 +007E00 +007E00 +00FF00 +00DF80 +019F80 +030FC0 +0607E0 +0407E0 +0C03F0 +1801F0 +FC07FE +FC07FE +ENDCHAR +STARTCHAR 0079 +ENCODING 121 +SWIDTH 500 0 +DWIDTH 25 0 +BBX 23 36 1 -12 +BITMAP +FFC07E +FFC07E +1F0018 +1F0010 +0F8030 +0F8030 +078020 +07C060 +07C060 +03E040 +03E0C0 +01E080 +01F180 +01F180 +00F900 +00FB00 +00FB00 +007E00 +007E00 +003C00 +003C00 +003C00 +001800 +001800 +001000 +003000 +003000 +002000 +006000 +006000 +004000 +00C000 +008000 +018000 +070000 +0E0000 +ENDCHAR +STARTCHAR 007A +ENCODING 122 +SWIDTH 500 0 +DWIDTH 25 0 +BBX 21 24 2 0 +BITMAP +FFFFF8 +FFFFF0 +C001E0 +C003E0 +C007C0 +000780 +000F80 +001F00 +003E00 +003C00 +007C00 +00F800 +00F000 +01F000 +03E000 +03C000 +07C000 +0F8000 +1F0000 +1E0008 +3E0008 +7C0008 +7FFFF8 +FFFFF8 +ENDCHAR +STARTCHAR 007B +ENCODING 123 +SWIDTH 300 0 +DWIDTH 15 0 +BBX 12 48 1 -12 +BITMAP +0030 +01F0 +03C0 +0780 +0F00 +0F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1E00 +1E00 +3C00 +F000 +E000 +7800 +3C00 +1E00 +1E00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +0F00 +0F80 +0780 +03E0 +0070 +ENDCHAR +STARTCHAR 007C +ENCODING 124 +SWIDTH 140 0 +DWIDTH 7 0 +BBX 2 48 2 -12 +BITMAP +C0 +C0 +C0 +C0 +C0 +C0 +C0 +C0 +C0 +C0 +C0 +C0 +C0 +C0 +C0 +C0 +C0 +C0 +C0 +C0 +C0 +C0 +C0 +C0 +C0 +C0 +C0 +C0 +C0 +C0 +C0 +C0 +C0 +C0 +C0 +C0 +C0 +C0 +C0 +C0 +C0 +C0 +C0 +C0 +C0 +C0 +C0 +C0 +ENDCHAR +STARTCHAR 007D +ENCODING 125 +SWIDTH 300 0 +DWIDTH 15 0 +BBX 12 48 1 -12 +BITMAP +C000 +F800 +3C00 +1E00 +0F00 +0F00 +0F80 +0F80 +0F80 +0F80 +0F80 +0F80 +0F80 +0F80 +0F80 +0F80 +0F80 +0F80 +0F80 +0F80 +0780 +0780 +03C0 +00F0 +0070 +01E0 +03C0 +0780 +0780 +0F80 +0F80 +0F80 +0F80 +0F80 +0F80 +0F80 +0F80 +0F80 +0F80 +0F80 +0F80 +0F80 +0F80 +0F00 +1F00 +1E00 +7C00 +E000 +ENDCHAR +STARTCHAR 007E +ENCODING 126 +SWIDTH 580 0 +DWIDTH 29 0 +BBX 25 8 2 23 +BITMAP +07C00000 +1FF00100 +3FF80180 +787C0300 +603F0F00 +C00FFE00 +4007FC00 +0001F000 +ENDCHAR +STARTCHAR 00A0 +ENCODING 160 +SWIDTH 320 0 +DWIDTH 16 0 +BBX 1 1 0 0 +BITMAP +00 +ENDCHAR +STARTCHAR 00A1 +ENCODING 161 +SWIDTH 180 0 +DWIDTH 9 0 +BBX 5 37 2 -12 +BITMAP +F8 +F8 +F8 +F8 +F8 +00 +00 +00 +00 +70 +70 +70 +70 +70 +70 +70 +F8 +F8 +F8 +F8 +F8 +F8 +F8 +F8 +F8 +F8 +F8 +F8 +F8 +F8 +F8 +F8 +F8 +F8 +F8 +F8 +F8 +ENDCHAR +STARTCHAR 00A2 +ENCODING 162 +SWIDTH 440 0 +DWIDTH 22 0 +BBX 19 36 1 -6 +BITMAP +0000C0 +000080 +000180 +000180 +000300 +000300 +01FE20 +0787E0 +1F04E0 +3E0460 +3C0C60 +7C0820 +7C1800 +781800 +F81000 +F83000 +F82000 +F86000 +F86000 +F84000 +F8C000 +F88000 +FD8000 +7D8000 +7D0020 +7F0020 +3E0060 +3F00C0 +1F8380 +07FF00 +0DF800 +0C0000 +180000 +180000 +100000 +300000 +ENDCHAR +STARTCHAR 00A3 +ENCODING 163 +SWIDTH 540 0 +DWIDTH 27 0 +BBX 23 37 3 -1 +BITMAP +01FC00 +0FFF80 +1F87C0 +3E03E0 +7C01E0 +FC01F0 +F801F0 +F801F0 +F80080 +F80000 +F80000 +F80000 +7C0000 +7C0000 +7E0000 +3E0000 +3E0000 +1F0000 +1F0000 +1F8000 +FFF800 +FFF800 +07C000 +07C000 +07C000 +07C000 +07C000 +07C000 +0F8000 +0F8000 +1F0000 +3E0000 +7E0000 +FFC000 +FEF87E +301FF8 +0007E0 +ENDCHAR +STARTCHAR 00A4 +ENCODING 164 +SWIDTH 560 0 +DWIDTH 28 0 +BBX 22 23 3 6 +BITMAP +800004 +C0FC0C +63FF38 +3787F0 +1E01E0 +0C00C0 +180060 +180060 +300030 +300030 +300030 +300030 +300030 +380070 +180060 +1C00E0 +0E01C0 +070780 +0FFFC0 +18FC60 +300030 +600018 +400008 +ENDCHAR +STARTCHAR 00A5 +ENCODING 165 +SWIDTH 620 0 +DWIDTH 31 0 +BBX 29 36 1 0 +BITMAP +FF8001F8 +FF8001F8 +1F000040 +1F0000C0 +0F800180 +07C00180 +07C00300 +03E00200 +03E00600 +01F00C00 +01F00C00 +00F81800 +007C1800 +007C3000 +003E6000 +003E6000 +001FC000 +000FC000 +000F8000 +000F8000 +07FFFF00 +07FFFF00 +000F8000 +000F8000 +000F8000 +000F8000 +000F8000 +07FFFF00 +07FFFF00 +000F8000 +000F8000 +000F8000 +000F8000 +000F8000 +007FF000 +007FF000 +ENDCHAR +STARTCHAR 00A6 +ENCODING 166 +SWIDTH 180 0 +DWIDTH 9 0 +BBX 2 48 3 -12 +BITMAP +C0 +C0 +C0 +C0 +C0 +C0 +C0 +C0 +C0 +C0 +C0 +C0 +C0 +C0 +C0 +C0 +C0 +C0 +C0 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +C0 +C0 +C0 +C0 +C0 +C0 +C0 +C0 +C0 +C0 +C0 +C0 +C0 +C0 +C0 +C0 +C0 +C0 +C0 +ENDCHAR +STARTCHAR 00A7 +ENCODING 167 +SWIDTH 440 0 +DWIDTH 22 0 +BBX 18 38 2 -1 +BITMAP +03F000 +1FFFC0 +3F07C0 +7C03C0 +FC01C0 +F800C0 +F800C0 +F80000 +FC0000 +7E0000 +7F8000 +3FF000 +1FFC00 +0FFE00 +3FFF00 +7C3F80 +781F80 +F80FC0 +F807C0 +F807C0 +F807C0 +FE07C0 +7F8F80 +3FFF00 +1FFE00 +07FE00 +00FF00 +003F80 +000F80 +000FC0 +0007C0 +8007C0 +C007C0 +C00FC0 +E00F80 +F83F00 +CFFE00 +03F000 +ENDCHAR +STARTCHAR 00A8 +ENCODING 168 +SWIDTH 380 0 +DWIDTH 19 0 +BBX 15 5 2 31 +BITMAP +F83E +F83E +F83E +F83E +F83E +ENDCHAR +STARTCHAR 00A9 +ENCODING 169 +SWIDTH 700 0 +DWIDTH 35 0 +BBX 31 31 2 1 +BITMAP +00038000 +003FF800 +00E01E00 +03800780 +060001C0 +0C0FC0E0 +187FF070 +10FC1F38 +21F80718 +23F0031C +43E0030C +43E0000C +47C00006 +87C00006 +87C00006 +87C00006 +87C00006 +87C00006 +87C00006 +47C0000E +43E0000C +43E0030C +23F00318 +31F80618 +10FC1C30 +087FF070 +040FC0E0 +030003C0 +01800700 +00787E00 +001FF000 +ENDCHAR +STARTCHAR 00AA +ENCODING 170 +SWIDTH 320 0 +DWIDTH 16 0 +BBX 14 16 1 20 +BITMAP +1FC0 +30E0 +2070 +2030 +0030 +0030 +0070 +07B0 +3830 +7030 +E030 +E030 +E070 +E0F0 +71B0 +3E3C +ENDCHAR +STARTCHAR 00AB +ENCODING 171 +SWIDTH 440 0 +DWIDTH 22 0 +BBX 19 21 1 7 +BITMAP +004000 +00C020 +01C060 +03C0E0 +03C1E0 +0783E0 +0F07C0 +1F0F80 +3E1F00 +7C1E00 +F83E00 +7C1E00 +3E1F00 +1F0F80 +0F07C0 +0783E0 +03C1E0 +03C0E0 +01C060 +00C020 +004000 +ENDCHAR +STARTCHAR 00AC +ENCODING 172 +SWIDTH 540 0 +DWIDTH 27 0 +BBX 25 12 0 12 +BITMAP +FFFFFF80 +FFFFFF80 +00000180 +00000180 +00000180 +00000180 +00000180 +00000180 +00000180 +00000180 +00000180 +00000180 +ENDCHAR +STARTCHAR 00AE +ENCODING 174 +SWIDTH 700 0 +DWIDTH 35 0 +BBX 31 31 2 0 +BITMAP +000FE000 +007FFC00 +01C00F00 +03000380 +060001C0 +08FFE060 +18FFF030 +30703838 +20701C18 +60700C0C +40700C0C +40700C0C +80701806 +80703006 +807FC006 +8071C006 +8071E006 +8070E006 +8070F006 +4070700C +4070780C +60703C0C +20F83F18 +30F81F38 +10000030 +08000060 +060001C0 +03000380 +01C00F00 +007FFC00 +000FE000 +ENDCHAR +STARTCHAR 00AF +ENCODING 175 +SWIDTH 400 0 +DWIDTH 20 0 +BBX 16 2 2 34 +BITMAP +FFFF +FFFF +ENDCHAR +STARTCHAR 00B0 +ENCODING 176 +SWIDTH 280 0 +DWIDTH 14 0 +BBX 10 12 2 24 +BITMAP +1E00 +7F80 +7380 +E1C0 +E1C0 +E1C0 +E1C0 +E1C0 +E1C0 +7380 +7F80 +1E00 +ENDCHAR +STARTCHAR 00B1 +ENCODING 177 +SWIDTH 440 0 +DWIDTH 22 0 +BBX 21 22 1 4 +BITMAP +003000 +003000 +003000 +003000 +003000 +003000 +003000 +003000 +003000 +FFFFF8 +FFFFF8 +003000 +003000 +003000 +003000 +003000 +003000 +003000 +003000 +003000 +FFFFF8 +FFFFF8 +ENDCHAR +STARTCHAR 00B2 +ENCODING 178 +SWIDTH 500 0 +DWIDTH 25 0 +BBX 14 19 2 17 +BITMAP +07C0 +1FF0 +30F8 +607C +403C +C03C +003C +0078 +0070 +00E0 +01C0 +0700 +0E00 +1C00 +3800 +7000 +F004 +FFFC +FFFC +ENDCHAR +STARTCHAR 00B3 +ENCODING 179 +SWIDTH 320 0 +DWIDTH 16 0 +BBX 12 19 1 17 +BITMAP +1F00 +3FC0 +61C0 +01E0 +00E0 +00E0 +00E0 +01C0 +0180 +0F80 +03E0 +00E0 +00F0 +0070 +0070 +0070 +C0E0 +E1C0 +FF80 +ENDCHAR +STARTCHAR 00B4 +ENCODING 180 +SWIDTH 220 0 +DWIDTH 11 0 +BBX 9 8 1 27 +BITMAP +0F80 +1F00 +1E00 +3E00 +3C00 +7800 +F000 +3000 +ENDCHAR +STARTCHAR 00B5 +ENCODING 181 +SWIDTH 540 0 +DWIDTH 27 0 +BBX 26 34 0 -10 +BITMAP +1F007C00 +1F007C00 +1F007C00 +1F007C00 +1F007C00 +1F007C00 +1F007C00 +1F007C00 +1F007C00 +1F007C00 +1F007C00 +1F007C00 +1F007C00 +1F007C00 +1F007C00 +1F007C00 +1F007C00 +1F807C00 +1F807E00 +1F807E00 +1F80FE00 +1FE1FE00 +1F7FDFC0 +1F7F9FC0 +1F0E0000 +1F000000 +3F000000 +3E000000 +3E000000 +3E000000 +7C000000 +7C000000 +F8000000 +70000000 +ENDCHAR +STARTCHAR 00B6 +ENCODING 182 +SWIDTH 460 0 +DWIDTH 23 0 +BBX 20 36 1 0 +BITMAP +01FFF0 +07FFF0 +1FE180 +3FE180 +7FE180 +7FE180 +7FE180 +FFE180 +FFE180 +FFE180 +FFE180 +FFE180 +7FE180 +7FE180 +3FE180 +1FE180 +0FE180 +07E180 +006180 +006180 +006180 +006180 +006180 +006180 +006180 +006180 +006180 +006180 +006180 +006180 +006180 +006180 +006180 +006180 +006180 +006180 +ENDCHAR +STARTCHAR 00B7 +ENCODING 183 +SWIDTH 200 0 +DWIDTH 10 0 +BBX 5 5 2 19 +BITMAP +F8 +F8 +F8 +F8 +F8 +ENDCHAR +STARTCHAR 00B8 +ENCODING 184 +SWIDTH 220 0 +DWIDTH 11 0 +BBX 8 13 1 -12 +BITMAP +0C +18 +10 +30 +38 +7E +1F +0F +0F +0F +1F +FE +FC +ENDCHAR +STARTCHAR 00B9 +ENCODING 185 +SWIDTH 240 0 +DWIDTH 12 0 +BBX 5 19 2 17 +BITMAP +F0 +70 +70 +70 +70 +70 +70 +70 +70 +70 +70 +70 +70 +70 +70 +70 +70 +70 +F8 +ENDCHAR +STARTCHAR 00BA +ENCODING 186 +SWIDTH 380 0 +DWIDTH 19 0 +BBX 15 19 2 17 +BITMAP +0FC0 +1FF0 +3C78 +783C +701C +F01E +E00E +E00E +E00E +E00E +E00E +E00E +E00E +E00E +701C +701C +3C78 +1FF0 +0FE0 +ENDCHAR +STARTCHAR 00BB +ENCODING 187 +SWIDTH 460 0 +DWIDTH 23 0 +BBX 20 21 2 7 +BITMAP +800000 +C02000 +E03000 +F03800 +F83C00 +783E00 +3C1F00 +1E0F80 +1F07C0 +0F83E0 +07C1F0 +0F83E0 +1F07C0 +3E0F80 +3C1F00 +783E00 +F83C00 +F03800 +E03000 +C02000 +800000 +ENDCHAR +STARTCHAR 00BC +ENCODING 188 +SWIDTH 620 0 +DWIDTH 31 0 +BBX 29 36 1 0 +BITMAP +F0000020 +70000060 +700000C0 +70000180 +70000100 +70000300 +70000600 +70000C00 +70000800 +70001800 +70003000 +70006000 +70004000 +7000C000 +70018000 +70030000 +70020000 +F80601C0 +000C03C0 +001807C0 +00180FC0 +00301BC0 +006013C0 +004023C0 +00C043C0 +0180C3C0 +030183C0 +020303C0 +060203C0 +0C07FFF8 +1807FFF8 +100003C0 +300003C0 +600003C0 +C00003C0 +800003C0 +ENDCHAR +STARTCHAR 00BD +ENCODING 189 +SWIDTH 600 0 +DWIDTH 30 0 +BBX 29 36 1 0 +BITMAP +1E000060 +0E000040 +0E0000C0 +0E000180 +0E000300 +0E000200 +0E000600 +0E000C00 +0E000800 +0E001000 +0E003000 +0E006000 +0E004000 +0E00C000 +0E018000 +0E030000 +0E020000 +0E060F80 +1F0C3FE0 +001861F0 +0010C0F8 +00308078 +00618078 +00400078 +00C000F0 +018000E0 +030001C0 +02000380 +06000E00 +0C001C00 +18003800 +10007000 +3000E000 +6001E008 +C001FFF8 +C001FFF8 +ENDCHAR +STARTCHAR 00BE +ENCODING 190 +SWIDTH 620 0 +DWIDTH 31 0 +BBX 27 36 1 0 +BITMAP +1F000060 +3FC00060 +61C000C0 +00E00180 +00E00300 +00E00300 +00E00600 +01C00C00 +03800800 +0F801800 +01E03000 +00E06000 +00706000 +0070C000 +00718000 +C0730000 +C0E30000 +F1C60700 +DF8C0F00 +00181F00 +00183F00 +00306F00 +00604F00 +00408F00 +00C10F00 +01830F00 +03060F00 +020C0F00 +06080F00 +0C1FFFE0 +181FFFE0 +18000F00 +30000F00 +60000F00 +C0000F00 +C0000F00 +ENDCHAR +STARTCHAR 00BF +ENCODING 191 +SWIDTH 500 0 +DWIDTH 25 0 +BBX 22 37 2 -13 +BITMAP +007C00 +007C00 +007C00 +007C00 +007C00 +000000 +000000 +000000 +001800 +001800 +001800 +001800 +001800 +001800 +001800 +001800 +001800 +003000 +007000 +00F000 +01E000 +03C000 +078000 +1F0000 +3E0000 +3C01F0 +7800F8 +F800F8 +F800F8 +F80078 +F8007C +F800F8 +7C00F8 +3E01F0 +1F87E0 +07FF80 +01FE00 +ENDCHAR +STARTCHAR 00C0 +ENCODING 192 +SWIDTH 620 0 +DWIDTH 31 0 +BBX 29 46 1 0 +BITMAP +00F80000 +007C0000 +003C0000 +003E0000 +001E0000 +000F0000 +00070000 +00060000 +00000000 +00000000 +00060000 +000F0000 +000F0000 +000F0000 +000F8000 +001F8000 +001F8000 +001FC000 +003FC000 +0037C000 +0037E000 +0077E000 +0063E000 +0063F000 +00E3F000 +00C1F000 +00C1F800 +01C1F800 +0180F800 +0180FC00 +0180FC00 +03807C00 +03FFFC00 +03FFFE00 +07007E00 +06003E00 +06003F00 +0E003F00 +0C001F00 +0C001F80 +1C001F80 +18000F80 +18000FC0 +38000FC0 +FE001FF8 +FE001FF8 +ENDCHAR +STARTCHAR 00C1 +ENCODING 193 +SWIDTH 620 0 +DWIDTH 31 0 +BBX 29 46 1 0 +BITMAP +0000F800 +0001F000 +0001E000 +0003E000 +0003C000 +00078000 +000F0000 +00030000 +00000000 +00000000 +00060000 +000F0000 +000F0000 +000F0000 +000F8000 +001F8000 +001F8000 +001FC000 +003FC000 +0037C000 +0037E000 +0077E000 +0063E000 +0063F000 +00E3F000 +00C1F000 +00C1F800 +01C1F800 +0180F800 +0180FC00 +0180FC00 +03807C00 +03FFFC00 +03FFFE00 +07007E00 +06003E00 +06003F00 +0E003F00 +0C001F00 +0C001F80 +1C001F80 +18000F80 +18000FC0 +38000FC0 +FE001FF8 +FE001FF8 +ENDCHAR +STARTCHAR 00C2 +ENCODING 194 +SWIDTH 640 0 +DWIDTH 32 0 +BBX 29 45 1 0 +BITMAP +00070000 +000F8000 +000FC000 +001DC000 +0038E000 +00307000 +00603000 +00000000 +00000000 +00060000 +000F0000 +000F0000 +000F0000 +000F8000 +001F8000 +001F8000 +001FC000 +003FC000 +0037C000 +0037E000 +0077E000 +0063E000 +0063F000 +00E3F000 +00C1F000 +00C1F800 +01C1F800 +0180F800 +0180FC00 +0180FC00 +03807C00 +03FFFC00 +03FFFE00 +07007E00 +06003E00 +06003F00 +0E003F00 +0C001F00 +0C001F80 +1C001F80 +18000F80 +18000FC0 +38000FC0 +FE001FF8 +FE001FF8 +ENDCHAR +STARTCHAR 00C3 +ENCODING 195 +SWIDTH 640 0 +DWIDTH 32 0 +BBX 29 46 1 0 +BITMAP +00300000 +00780400 +00FE0400 +00FF0C00 +00CF9800 +0183F800 +0101F000 +0100E000 +00000000 +00000000 +00060000 +000F0000 +000F0000 +000F0000 +000F8000 +001F8000 +001F8000 +001FC000 +003FC000 +0037C000 +0037E000 +0077E000 +0063E000 +0063F000 +00E3F000 +00C1F000 +00C1F800 +01C1F800 +0180F800 +0180FC00 +0180FC00 +03807C00 +03FFFC00 +03FFFE00 +07007E00 +06003E00 +06003F00 +0E003F00 +0C001F00 +0C001F80 +1C001F80 +18000F80 +18000FC0 +38000FC0 +FE001FF8 +FE001FF8 +ENDCHAR +STARTCHAR 00C4 +ENCODING 196 +SWIDTH 620 0 +DWIDTH 31 0 +BBX 29 44 1 0 +BITMAP +01F07C00 +01F07C00 +01F07C00 +01F07C00 +01F07C00 +00000000 +00000000 +00000000 +00060000 +000F0000 +000F0000 +000F0000 +000F8000 +001F8000 +001F8000 +001FC000 +003FC000 +0037C000 +0037E000 +0077E000 +0063E000 +0063F000 +00E3F000 +00C1F000 +00C1F800 +01C1F800 +0180F800 +0180FC00 +0180FC00 +03807C00 +03FFFC00 +03FFFE00 +07007E00 +06003E00 +06003F00 +0E003F00 +0C001F00 +0C001F80 +1C001F80 +18000F80 +18000FC0 +38000FC0 +FE001FF8 +FE001FF8 +ENDCHAR +STARTCHAR 00C5 +ENCODING 197 +SWIDTH 580 0 +DWIDTH 29 0 +BBX 29 45 1 0 +BITMAP +000F0000 +001FC000 +0018C000 +00306000 +00306000 +00306000 +00306000 +0018C000 +001FC000 +00070000 +000F0000 +000F0000 +000F0000 +000F8000 +001F8000 +001F8000 +001FC000 +003FC000 +0037C000 +0037E000 +0077E000 +0063E000 +0063F000 +00E3F000 +00C1F000 +00C1F800 +01C1F800 +0180F800 +0180FC00 +0180FC00 +03807C00 +03FFFC00 +03FFFE00 +07007E00 +06003E00 +06003F00 +0E003F00 +0C001F00 +0C001F80 +1C001F80 +18000F80 +18000FC0 +38000FC0 +FE001FF8 +FE001FF8 +ENDCHAR +STARTCHAR 00C6 +ENCODING 198 +SWIDTH 920 0 +DWIDTH 46 0 +BBX 45 36 0 0 +BITMAP +000007FFFFF8 +000007FFFFF8 +000003F80018 +000002F80018 +000006F80018 +00000CF80000 +000008F80000 +000018F80000 +000030F80000 +000030F80000 +000060F80000 +000040F80000 +0000C0F80000 +000180F80000 +000180F80300 +000300F80300 +000200F80300 +000600FFFF00 +000C00FFFF00 +000C00F80300 +001800F80300 +003FFFF80300 +003FFFF80000 +007000F80000 +006000F80000 +00C000F80000 +01C000F80000 +018000F80000 +030000F80000 +030000F80000 +060000F80000 +0C0000F80018 +0C0000F80018 +180000F80018 +FC0007FFFFF8 +FC0007FFFFF8 +ENDCHAR +STARTCHAR 00C7 +ENCODING 199 +SWIDTH 560 0 +DWIDTH 28 0 +BBX 24 48 2 -12 +BITMAP +001FF0 +00FFFE +03F03F +07C00F +0F8007 +1F0003 +3E0003 +3E0000 +7C0000 +7C0000 +7C0000 +F80000 +F80000 +F80000 +F80000 +F80000 +F80000 +F80000 +F80000 +F80000 +F80000 +F80000 +F80000 +F80000 +F80000 +7C0000 +7C0000 +7C0000 +7C0000 +3E0000 +3E0003 +1F0003 +0F8007 +07C00F +03F03F +00FFFE +001FF0 +001000 +003000 +003800 +007E00 +001F00 +000F00 +000F00 +000F00 +001F00 +00FE00 +00FC00 +ENDCHAR +STARTCHAR 00C8 +ENCODING 200 +SWIDTH 520 0 +DWIDTH 26 0 +BBX 24 46 1 0 +BITMAP +01F000 +00F800 +007800 +007C00 +003C00 +001E00 +000E00 +000C00 +000000 +000000 +FFFFFF +FFFFFF +1F0003 +1F0003 +1F0000 +1F0000 +1F0000 +1F0000 +1F0000 +1F0000 +1F0000 +1F0000 +1F0000 +1F0000 +1F0060 +1F0060 +1F0060 +1FFFE0 +1FFFE0 +1F0060 +1F0060 +1F0060 +1F0000 +1F0000 +1F0000 +1F0000 +1F0000 +1F0000 +1F0000 +1F0000 +1F0000 +1F0003 +1F0003 +1F0003 +FFFFFF +FFFFFF +ENDCHAR +STARTCHAR 00C9 +ENCODING 201 +SWIDTH 520 0 +DWIDTH 26 0 +BBX 24 45 1 0 +BITMAP +000F80 +001F00 +001E00 +003E00 +003C00 +007800 +00F000 +003000 +000000 +FFFFFF +FFFFFF +1F0003 +1F0003 +1F0000 +1F0000 +1F0000 +1F0000 +1F0000 +1F0000 +1F0000 +1F0000 +1F0000 +1F0000 +1F0060 +1F0060 +1F0060 +1FFFE0 +1FFFE0 +1F0060 +1F0060 +1F0060 +1F0000 +1F0000 +1F0000 +1F0000 +1F0000 +1F0000 +1F0000 +1F0000 +1F0000 +1F0003 +1F0003 +1F0003 +FFFFFF +FFFFFF +ENDCHAR +STARTCHAR 00CA +ENCODING 202 +SWIDTH 520 0 +DWIDTH 26 0 +BBX 24 45 1 0 +BITMAP +000E00 +001F00 +001F80 +003B80 +0071C0 +0060E0 +00C060 +000000 +000000 +FFFFFF +FFFFFF +1F0003 +1F0003 +1F0000 +1F0000 +1F0000 +1F0000 +1F0000 +1F0000 +1F0000 +1F0000 +1F0000 +1F0000 +1F0060 +1F0060 +1F0060 +1FFFE0 +1FFFE0 +1F0060 +1F0060 +1F0060 +1F0000 +1F0000 +1F0000 +1F0000 +1F0000 +1F0000 +1F0000 +1F0000 +1F0000 +1F0003 +1F0003 +1F0003 +FFFFFF +FFFFFF +ENDCHAR +STARTCHAR 00CB +ENCODING 203 +SWIDTH 520 0 +DWIDTH 26 0 +BBX 24 44 1 0 +BITMAP +03E0F8 +03E0F8 +03E0F8 +03E0F8 +03E0F8 +000000 +000000 +000000 +FFFFFF +FFFFFF +1F0003 +1F0003 +1F0000 +1F0000 +1F0000 +1F0000 +1F0000 +1F0000 +1F0000 +1F0000 +1F0000 +1F0000 +1F0060 +1F0060 +1F0060 +1FFFE0 +1FFFE0 +1F0060 +1F0060 +1F0060 +1F0000 +1F0000 +1F0000 +1F0000 +1F0000 +1F0000 +1F0000 +1F0000 +1F0000 +1F0003 +1F0003 +1F0003 +FFFFFF +FFFFFF +ENDCHAR +STARTCHAR 00CC +ENCODING 204 +SWIDTH 300 0 +DWIDTH 15 0 +BBX 11 46 1 0 +BITMAP +3E00 +1F00 +0F00 +0F80 +0780 +03C0 +01C0 +0180 +0000 +0000 +FFE0 +FFE0 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +FFE0 +FFE0 +ENDCHAR +STARTCHAR 00CD +ENCODING 205 +SWIDTH 300 0 +DWIDTH 15 0 +BBX 12 46 1 0 +BITMAP +01F0 +03E0 +03C0 +07C0 +0780 +0F00 +1E00 +0600 +0000 +0000 +FFE0 +FFE0 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +FFE0 +FFE0 +ENDCHAR +STARTCHAR 00CE +ENCODING 206 +SWIDTH 280 0 +DWIDTH 14 0 +BBX 12 45 1 0 +BITMAP +0700 +0F80 +0FC0 +1DC0 +38E0 +3070 +6030 +0000 +0000 +FFE0 +FFE0 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +FFE0 +FFE0 +ENDCHAR +STARTCHAR 00CF +ENCODING 207 +SWIDTH 300 0 +DWIDTH 15 0 +BBX 15 44 0 0 +BITMAP +F83E +F83E +F83E +F83E +F83E +0000 +0000 +0000 +7FF0 +7FF0 +0F80 +0F80 +0F80 +0F80 +0F80 +0F80 +0F80 +0F80 +0F80 +0F80 +0F80 +0F80 +0F80 +0F80 +0F80 +0F80 +0F80 +0F80 +0F80 +0F80 +0F80 +0F80 +0F80 +0F80 +0F80 +0F80 +0F80 +0F80 +0F80 +0F80 +0F80 +0F80 +7FF0 +7FF0 +ENDCHAR +STARTCHAR 00D0 +ENCODING 208 +SWIDTH 620 0 +DWIDTH 31 0 +BBX 28 36 1 0 +BITMAP +FFFFE000 +FFFFFC00 +1F00FE00 +1F003F00 +1F001F80 +1F000FC0 +1F0007C0 +1F0007E0 +1F0003E0 +1F0003E0 +1F0003E0 +1F0003F0 +1F0001F0 +1F0001F0 +1F0001F0 +1F0001F0 +1F0001F0 +FFFF01F0 +FFFF01F0 +1F0001F0 +1F0001F0 +1F0001F0 +1F0001F0 +1F0001F0 +1F0003F0 +1F0003E0 +1F0003E0 +1F0003E0 +1F0007E0 +1F0007C0 +1F000FC0 +1F001F80 +1F003F00 +1F007E00 +FFFFFC00 +FFFFE000 +ENDCHAR +STARTCHAR 00D1 +ENCODING 209 +SWIDTH 600 0 +DWIDTH 30 0 +BBX 29 46 1 0 +BITMAP +00180000 +003C0200 +007F0200 +007F8600 +0067CC00 +00C1FC00 +0080F800 +00807000 +00000000 +00000000 +FF8007F8 +FF8007F8 +1FC000C0 +1FC000C0 +1FE000C0 +1BF000C0 +1BF000C0 +19F800C0 +19F800C0 +18FC00C0 +187E00C0 +187E00C0 +183F00C0 +183F00C0 +181F80C0 +180FC0C0 +180FC0C0 +1807E0C0 +1807E0C0 +1803F0C0 +1801F8C0 +1801F8C0 +1800FCC0 +1800FEC0 +18007EC0 +18003FC0 +18003FC0 +18001FC0 +18001FC0 +18000FC0 +180007C0 +180007C0 +180003C0 +180003C0 +FE0001C0 +FE0000C0 +ENDCHAR +STARTCHAR 00D2 +ENCODING 210 +SWIDTH 600 0 +DWIDTH 30 0 +BBX 27 47 2 -1 +BITMAP +00F80000 +007C0000 +003C0000 +003E0000 +001E0000 +000F0000 +00070000 +00060000 +00000000 +00000000 +007F8000 +01FFF000 +07E0FC00 +0F807E00 +1F003F00 +1F001F00 +3E000F80 +7E000F80 +7C000FC0 +7C0007C0 +FC0007C0 +FC0007E0 +FC0007E0 +FC0007E0 +F80007E0 +F80003E0 +F80003E0 +F80003E0 +F80003E0 +F80003E0 +F80003E0 +F80003E0 +F80007E0 +F80007E0 +FC0007E0 +FC0007E0 +FC0007C0 +7C0007C0 +7C000FC0 +7E000F80 +3E000F80 +1F001F00 +1F003F00 +0F807E00 +07E0FC00 +01FFF000 +007FC000 +ENDCHAR +STARTCHAR 00D3 +ENCODING 211 +SWIDTH 620 0 +DWIDTH 31 0 +BBX 27 47 2 -1 +BITMAP +0003E000 +0007C000 +00078000 +000F8000 +000F0000 +001E0000 +003C0000 +000C0000 +00000000 +00000000 +007F8000 +01FFF000 +07E0FC00 +0F807E00 +1F003F00 +1F001F00 +3E000F80 +7E000F80 +7C000FC0 +7C0007C0 +FC0007C0 +FC0007E0 +FC0007E0 +FC0007E0 +F80007E0 +F80003E0 +F80003E0 +F80003E0 +F80003E0 +F80003E0 +F80003E0 +F80003E0 +F80007E0 +F80007E0 +FC0007E0 +FC0007E0 +FC0007C0 +7C0007C0 +7C000FC0 +7E000F80 +3E000F80 +1F001F00 +1F003F00 +0F807E00 +07E0FC00 +01FFF000 +007FC000 +ENDCHAR +STARTCHAR 00D4 +ENCODING 212 +SWIDTH 600 0 +DWIDTH 30 0 +BBX 27 47 2 -1 +BITMAP +000E0000 +001F0000 +001F8000 +003B8000 +0071C000 +0060E000 +00C06000 +00000000 +00000000 +00000000 +007F8000 +01FFF000 +07E0FC00 +0F807E00 +1F003F00 +1F001F00 +3E000F80 +7E000F80 +7C000FC0 +7C0007C0 +FC0007C0 +FC0007E0 +FC0007E0 +FC0007E0 +F80007E0 +F80003E0 +F80003E0 +F80003E0 +F80003E0 +F80003E0 +F80003E0 +F80003E0 +F80007E0 +F80007E0 +FC0007E0 +FC0007E0 +FC0007C0 +7C0007C0 +7C000FC0 +7E000F80 +3E000F80 +1F001F00 +1F003F00 +0F807E00 +07E0FC00 +01FFF000 +007FC000 +ENDCHAR +STARTCHAR 00D5 +ENCODING 213 +SWIDTH 600 0 +DWIDTH 30 0 +BBX 27 47 2 -1 +BITMAP +00600000 +00F00800 +01FC0800 +01FE1800 +019F3000 +0307F000 +0203E000 +0201C000 +00000000 +00000000 +007F8000 +01FFF000 +07E0FC00 +0F807E00 +1F003F00 +1F001F00 +3E000F80 +7E000F80 +7C000FC0 +7C0007C0 +FC0007C0 +FC0007E0 +FC0007E0 +FC0007E0 +F80007E0 +F80003E0 +F80003E0 +F80003E0 +F80003E0 +F80003E0 +F80003E0 +F80003E0 +F80007E0 +F80007E0 +FC0007E0 +FC0007E0 +FC0007C0 +7C0007C0 +7C000FC0 +7E000F80 +3E000F80 +1F001F00 +1F003F00 +0F807E00 +07E0FC00 +01FFF000 +007FC000 +ENDCHAR +STARTCHAR 00D6 +ENCODING 214 +SWIDTH 600 0 +DWIDTH 30 0 +BBX 27 45 2 -1 +BITMAP +03E0F800 +03E0F800 +03E0F800 +03E0F800 +03E0F800 +00000000 +00000000 +00000000 +007F8000 +01FFF000 +07E0FC00 +0F807E00 +1F003F00 +1F001F00 +3E000F80 +7E000F80 +7C000FC0 +7C0007C0 +FC0007C0 +FC0007E0 +FC0007E0 +FC0007E0 +F80007E0 +F80003E0 +F80003E0 +F80003E0 +F80003E0 +F80003E0 +F80003E0 +F80003E0 +F80007E0 +F80007E0 +FC0007E0 +FC0007E0 +FC0007C0 +7C0007C0 +7C000FC0 +7E000F80 +3E000F80 +1F001F00 +1F003F00 +0F807E00 +07E0FC00 +01FFF000 +007FC000 +ENDCHAR +STARTCHAR 00D7 +ENCODING 215 +SWIDTH 600 0 +DWIDTH 30 0 +BBX 26 24 2 0 +BITMAP +E00001C0 +70000380 +38000700 +1C000E00 +0E001C00 +07003800 +03007000 +0180E000 +00C1C000 +00638000 +00370000 +001E0000 +000C0000 +001E0000 +00330000 +00618000 +00C0C000 +01806000 +03003000 +06001800 +0C000C00 +18000600 +30000300 +60000180 +ENDCHAR +STARTCHAR 00D8 +ENCODING 216 +SWIDTH 660 0 +DWIDTH 33 0 +BBX 29 37 2 -1 +BITMAP +003FF818 +00FFFC38 +03F07F30 +07C01FE0 +0F800FE0 +1F800FC0 +1F0007C0 +1F0007C0 +3E0007E0 +3E0007E0 +3E000FE0 +7E0019E0 +7C0031F0 +7C0061F0 +7C0041F0 +7C00C1F0 +7C0181F0 +7C0301F0 +7C0601F0 +7C0401F0 +7C0801F0 +7C1801F0 +7C3001F0 +7C6001F0 +7C4001F0 +7C8001F0 +3F8003E0 +3F0003E0 +3E0003E0 +3F0003C0 +1F0007C0 +1F8007C0 +3F800F80 +67C01F00 +C3F07E00 +C1FFFC00 +003FE000 +ENDCHAR +STARTCHAR 00D9 +ENCODING 217 +SWIDTH 700 0 +DWIDTH 35 0 +BBX 34 47 1 -1 +BITMAP +000F800000 +0007C00000 +0003C00000 +0003E00000 +0001E00000 +0000F00000 +0000700000 +0000600000 +0000000000 +0000000000 +FFC001FFC0 +FFC001FFC0 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F80003E00 +0F80007C00 +0F80007C00 +0F80007C00 +07C0007800 +07C000F800 +03E000F800 +03E001F000 +01F003E000 +00FC0FC000 +003FFF8000 +0007FC0000 +ENDCHAR +STARTCHAR 00DA +ENCODING 218 +SWIDTH 700 0 +DWIDTH 35 0 +BBX 34 46 1 -1 +BITMAP +0000F80000 +0001F00000 +0001E00000 +0003E00000 +0003C00000 +0007800000 +000F000000 +0003000000 +0000000000 +FFC001FFC0 +FFC001FFC0 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F80003E00 +0F80007C00 +0F80007C00 +0F80007C00 +07C0007800 +07C000F800 +03E000F800 +03E001F000 +01F003E000 +00FC0FC000 +003FFF8000 +0007FC0000 +ENDCHAR +STARTCHAR 00DB +ENCODING 219 +SWIDTH 700 0 +DWIDTH 35 0 +BBX 34 46 1 -1 +BITMAP +0001C00000 +0003E00000 +0003F00000 +0007700000 +000E380000 +000C1C0000 +00180C0000 +0000000000 +0000000000 +FFC001FFC0 +FFC001FFC0 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F80003E00 +0F80007C00 +0F80007C00 +0F80007C00 +07C0007800 +07C000F800 +03E000F800 +03E001F000 +01F003E000 +00FC0FC000 +003FFF8000 +0007FC0000 +ENDCHAR +STARTCHAR 00DC +ENCODING 220 +SWIDTH 700 0 +DWIDTH 35 0 +BBX 34 44 1 -1 +BITMAP +007C1F0000 +007C1F0000 +007C1F0000 +007C1F0000 +007C1F0000 +0000000000 +0000000000 +FFC001FFC0 +FFC001FFC0 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F80003E00 +0F80007C00 +0F80007C00 +0F80007C00 +07C0007800 +07C000F800 +03E000F800 +03E001F000 +01F003E000 +00FC0FC000 +003FFF8000 +0007FC0000 +ENDCHAR +STARTCHAR 00DD +ENCODING 221 +SWIDTH 640 0 +DWIDTH 32 0 +BBX 29 45 1 0 +BITMAP +0000F800 +0001F000 +0001E000 +0003E000 +0003C000 +00078000 +000F0000 +00030000 +00000000 +FFC001F8 +FFC001F8 +1F0000C0 +0F8001C0 +0FC00180 +07C00300 +07E00700 +03E00600 +03F00E00 +01F00C00 +00F81800 +00F81800 +007C3000 +007C7000 +003E6000 +001FE000 +001FC000 +000F8000 +000F8000 +000F8000 +000F8000 +000F8000 +000F8000 +000F8000 +000F8000 +000F8000 +000F8000 +000F8000 +000F8000 +000F8000 +000F8000 +000F8000 +000F8000 +000F8000 +007FE000 +007FE000 +ENDCHAR +STARTCHAR 00DE +ENCODING 222 +SWIDTH 580 0 +DWIDTH 29 0 +BBX 27 36 1 0 +BITMAP +FFC00000 +FFC00000 +1F000000 +1F000000 +1F000000 +1F000000 +1F000000 +1F000000 +1FFFF800 +1FFFFC00 +1F001F00 +1F000F80 +1F000780 +1F0007C0 +1F0003C0 +1F0003E0 +1F0003E0 +1F0003E0 +1F0003E0 +1F0003E0 +1F0003E0 +1F0007C0 +1F0007C0 +1F000780 +1F000F80 +1F001F00 +1FFFFE00 +1FFFF000 +1F000000 +1F000000 +1F000000 +1F000000 +1F000000 +1F000000 +FFC00000 +FFC00000 +ENDCHAR +STARTCHAR 00DF +ENCODING 223 +SWIDTH 520 0 +DWIDTH 26 0 +BBX 26 36 -1 0 +BITMAP +00FF0000 +03FFC000 +07C3E000 +0781F000 +0F01F000 +0F00F800 +1F00F800 +1F00F800 +1F00F800 +1F00F000 +1F01F000 +1F03E000 +1F07C000 +1F0F8000 +1F1F0000 +1F1F0000 +1F1F0000 +1F0F8000 +1F07E000 +1F01F000 +1F007C00 +1F003E00 +1F001F00 +1F000F80 +1F000F80 +1F0007C0 +1F0007C0 +1F0007C0 +1F0007C0 +1F0007C0 +1F0007C0 +1F200780 +1FF00F80 +1FFC1F00 +1F3FFE00 +FF07F800 +ENDCHAR +STARTCHAR 00E0 +ENCODING 224 +SWIDTH 520 0 +DWIDTH 26 0 +BBX 23 35 2 -1 +BITMAP +0F8000 +07C000 +03C000 +03E000 +01E000 +00F000 +007000 +006000 +000000 +000000 +03FE00 +1FFF80 +3C0FC0 +3807E0 +3003E0 +3001F0 +2001F0 +0001F0 +0001F0 +0001F0 +0003F0 +001DF0 +03E1F0 +1F01F0 +3C01F0 +7C01F0 +F801F0 +F801F0 +F803F0 +F803F0 +F807F0 +FC0DF0 +7E39F8 +3FF0FE +0FC000 +ENDCHAR +STARTCHAR 00E1 +ENCODING 225 +SWIDTH 520 0 +DWIDTH 26 0 +BBX 23 35 2 -1 +BITMAP +003E00 +007C00 +007800 +00F800 +00F000 +01E000 +03C000 +00C000 +000000 +000000 +03FE00 +1FFF80 +3C0FC0 +3807E0 +3003E0 +3001F0 +2001F0 +0001F0 +0001F0 +0001F0 +0003F0 +001DF0 +03E1F0 +1F01F0 +3C01F0 +7C01F0 +F801F0 +F801F0 +F803F0 +F803F0 +F807F0 +FC0DF0 +7E39F8 +3FF0FE +0FC000 +ENDCHAR +STARTCHAR 00E2 +ENCODING 226 +SWIDTH 520 0 +DWIDTH 26 0 +BBX 23 35 2 -1 +BITMAP +007000 +00F800 +00FC00 +01DC00 +038E00 +030700 +060300 +000000 +000000 +000000 +03FE00 +1FFF80 +3C0FC0 +3807E0 +3003E0 +3001F0 +2001F0 +0001F0 +0001F0 +0001F0 +0003F0 +001DF0 +03E1F0 +1F01F0 +3C01F0 +7C01F0 +F801F0 +F801F0 +F803F0 +F803F0 +F807F0 +FC0DF0 +7E39F8 +3FF0FE +0FC000 +ENDCHAR +STARTCHAR 00E3 +ENCODING 227 +SWIDTH 520 0 +DWIDTH 26 0 +BBX 23 35 2 -1 +BITMAP +030000 +078040 +0FE040 +0FF0C0 +0CF980 +183F80 +101F00 +100E00 +000000 +000000 +03FE00 +1FFF80 +3C0FC0 +3807E0 +3003E0 +3001F0 +2001F0 +0001F0 +0001F0 +0001F0 +0003F0 +001DF0 +03E1F0 +1F01F0 +3C01F0 +7C01F0 +F801F0 +F801F0 +F803F0 +F803F0 +F807F0 +FC0DF0 +7E39F8 +3FF0FE +0FC000 +ENDCHAR +STARTCHAR 00E4 +ENCODING 228 +SWIDTH 520 0 +DWIDTH 26 0 +BBX 23 33 2 -1 +BITMAP +1F07C0 +1F07C0 +1F07C0 +1F07C0 +1F07C0 +000000 +000000 +000000 +03FE00 +1FFF80 +3C0FC0 +3807E0 +3003E0 +3001F0 +2001F0 +0001F0 +0001F0 +0001F0 +0003F0 +001DF0 +03E1F0 +1F01F0 +3C01F0 +7C01F0 +F801F0 +F801F0 +F803F0 +F803F0 +F807F0 +FC0DF0 +7E39F8 +3FF0FE +0FC000 +ENDCHAR +STARTCHAR 00E5 +ENCODING 229 +SWIDTH 520 0 +DWIDTH 26 0 +BBX 23 35 2 -1 +BITMAP +01E000 +03F800 +031800 +060C00 +060C00 +060C00 +060C00 +031800 +03F800 +00E000 +03FE00 +1FFF80 +3C0FC0 +3807E0 +3003E0 +3001F0 +2001F0 +0001F0 +0001F0 +0001F0 +0003F0 +001DF0 +03E1F0 +1F01F0 +3C01F0 +7C01F0 +F801F0 +F801F0 +F803F0 +F803F0 +F807F0 +FC0DF0 +7E39F8 +3FF0FE +0FC000 +ENDCHAR +STARTCHAR 00E6 +ENCODING 230 +SWIDTH 800 0 +DWIDTH 40 0 +BBX 37 25 1 -1 +BITMAP +01FE01FC00 +1FFFC7FF00 +1E07FF07C0 +1C03FE03C0 +1801FC01E0 +1800FC01F0 +1000F800F0 +0000F800F0 +0000F800F8 +0000FFFFF8 +0003FFFFF8 +001CF80000 +03E0F80000 +1E00F80000 +3C00F80000 +7800F80000 +F800F80000 +F800FC0000 +F801FC0008 +F803FC0018 +F8073E0030 +FC0E1F0070 +7E3C0FE3C0 +3FF807FF80 +0FC000FE00 +ENDCHAR +STARTCHAR 00E7 +ENCODING 231 +SWIDTH 440 0 +DWIDTH 22 0 +BBX 19 36 2 -12 +BITMAP +01F820 +07FE60 +1FC3E0 +3F00E0 +3E0060 +7C0060 +7C0020 +7C0000 +F80000 +F80000 +F80000 +F80000 +F80000 +F80000 +F80000 +F80000 +F80000 +7C0000 +7C0020 +7E0020 +3E0060 +3F00C0 +1F8380 +0FFF00 +01FC00 +010000 +030000 +038000 +07E000 +01F000 +00F000 +00F000 +00F000 +01F000 +0FE000 +0FC000 +ENDCHAR +STARTCHAR 00E8 +ENCODING 232 +SWIDTH 480 0 +DWIDTH 24 0 +BBX 21 35 2 -1 +BITMAP +0F8000 +07C000 +03C000 +03E000 +01E000 +00F000 +007000 +006000 +000000 +000000 +01FC00 +07FF00 +1F07C0 +3E03C0 +3C01E0 +7C01F0 +7800F0 +7800F0 +F800F8 +FFFFF8 +FFFFF8 +F80000 +F80000 +F80000 +F80000 +F80000 +F80000 +7C0000 +7C0010 +3C0018 +3E0030 +1F0060 +0F81C0 +07FF80 +01FC00 +ENDCHAR +STARTCHAR 00E9 +ENCODING 233 +SWIDTH 480 0 +DWIDTH 24 0 +BBX 21 35 2 -1 +BITMAP +001F00 +003E00 +003C00 +007C00 +007800 +00F000 +01E000 +006000 +000000 +000000 +01FC00 +07FF00 +1F07C0 +3E03C0 +3C01E0 +7C01F0 +7800F0 +7800F0 +F800F8 +FFFFF8 +FFFFF8 +F80000 +F80000 +F80000 +F80000 +F80000 +F80000 +7C0000 +7C0010 +3C0018 +3E0030 +1F0060 +0F81C0 +07FF80 +01FC00 +ENDCHAR +STARTCHAR 00EA +ENCODING 234 +SWIDTH 480 0 +DWIDTH 24 0 +BBX 21 35 2 -1 +BITMAP +007000 +00F800 +00FC00 +01DC00 +038E00 +030700 +060300 +000000 +000000 +000000 +01FC00 +07FF00 +1F07C0 +3E03C0 +3C01E0 +7C01F0 +7800F0 +7800F0 +F800F8 +FFFFF8 +FFFFF8 +F80000 +F80000 +F80000 +F80000 +F80000 +F80000 +7C0000 +7C0010 +3C0018 +3E0030 +1F0060 +0F81C0 +07FF80 +01FC00 +ENDCHAR +STARTCHAR 00EB +ENCODING 235 +SWIDTH 480 0 +DWIDTH 24 0 +BBX 21 33 2 -1 +BITMAP +1F07C0 +1F07C0 +1F07C0 +1F07C0 +1F07C0 +000000 +000000 +000000 +01FC00 +07FF00 +1F07C0 +3E03C0 +3C01E0 +7C01F0 +7800F0 +7800F0 +F800F8 +FFFFF8 +FFFFF8 +F80000 +F80000 +F80000 +F80000 +F80000 +F80000 +7C0000 +7C0010 +3C0018 +3E0030 +1F0060 +0F81C0 +07FF80 +01FC00 +ENDCHAR +STARTCHAR 00EC +ENCODING 236 +SWIDTH 240 0 +DWIDTH 12 0 +BBX 10 34 1 0 +BITMAP +F800 +7C00 +3C00 +3E00 +1E00 +0F00 +0700 +0600 +0000 +0000 +FF00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +FFC0 +FFC0 +ENDCHAR +STARTCHAR 00ED +ENCODING 237 +SWIDTH 240 0 +DWIDTH 12 0 +BBX 12 34 0 0 +BITMAP +01F0 +03E0 +03C0 +07C0 +0780 +0F00 +1E00 +0600 +0000 +0000 +FF00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +FFC0 +FFC0 +ENDCHAR +STARTCHAR 00EE +ENCODING 238 +SWIDTH 260 0 +DWIDTH 13 0 +BBX 11 34 0 0 +BITMAP +0E00 +1F00 +1F80 +3B80 +71C0 +60E0 +C060 +0000 +0000 +0000 +7F80 +0F80 +0F80 +0F80 +0F80 +0F80 +0F80 +0F80 +0F80 +0F80 +0F80 +0F80 +0F80 +0F80 +0F80 +0F80 +0F80 +0F80 +0F80 +0F80 +0F80 +0F80 +7FE0 +7FE0 +ENDCHAR +STARTCHAR 00EF +ENCODING 239 +SWIDTH 280 0 +DWIDTH 14 0 +BBX 15 32 -1 0 +BITMAP +F83E +F83E +F83E +F83E +F83E +0000 +0000 +0000 +3FC0 +07C0 +07C0 +07C0 +07C0 +07C0 +07C0 +07C0 +07C0 +07C0 +07C0 +07C0 +07C0 +07C0 +07C0 +07C0 +07C0 +07C0 +07C0 +07C0 +07C0 +07C0 +3FF0 +3FF0 +ENDCHAR +STARTCHAR 00F0 +ENCODING 240 +SWIDTH 500 0 +DWIDTH 25 0 +BBX 23 37 1 -1 +BITMAP +0F0000 +1FE000 +01F9F8 +007FE0 +003F80 +003F00 +00FF80 +03F7C0 +0047C0 +0003E0 +0003E0 +0001F0 +0001F0 +0000F8 +00FEF8 +03EFF8 +0F83FC +1F007C +3E007C +3C003C +7C003E +7C003E +F8003E +F8003E +F8003E +F8003E +F8003E +F8003E +F8007E +7C007C +7C007C +7E00F8 +3E01F8 +1F01F0 +0FC7E0 +07FFC0 +00FE00 +ENDCHAR +STARTCHAR 00F1 +ENCODING 241 +SWIDTH 580 0 +DWIDTH 29 0 +BBX 26 35 1 0 +BITMAP +00300000 +00780400 +00FE0400 +00FF0C00 +00CF9800 +0183F800 +0101F000 +0100E000 +00000000 +00000000 +00000000 +FF1F8000 +1F7FE000 +1FE1F800 +1F80F800 +1F007C00 +1F007C00 +1F003E00 +1F003E00 +1F003E00 +1F003E00 +1F003E00 +1F003E00 +1F003E00 +1F003E00 +1F003E00 +1F003E00 +1F003E00 +1F003E00 +1F003E00 +1F003E00 +1F003E00 +1F003E00 +FFE1FFC0 +FFE1FFC0 +ENDCHAR +STARTCHAR 00F2 +ENCODING 242 +SWIDTH 500 0 +DWIDTH 25 0 +BBX 22 35 2 -1 +BITMAP +03E000 +01F000 +00F000 +00F800 +007800 +003C00 +001C00 +001800 +000000 +000000 +01FE00 +07FF80 +1F87E0 +3F03F0 +3E01F0 +7C00F8 +7C00F8 +7C00F8 +F8007C +F8007C +F8007C +F8007C +F8007C +F8007C +F8007C +F8007C +F8007C +7C00F8 +7C00F8 +7C00F8 +3E01F0 +3F03F0 +1F87E0 +0FFFC0 +01FE00 +ENDCHAR +STARTCHAR 00F3 +ENCODING 243 +SWIDTH 500 0 +DWIDTH 25 0 +BBX 22 35 1 -1 +BITMAP +000F80 +001F00 +001E00 +003E00 +003C00 +007800 +00F000 +003000 +000000 +000000 +01FE00 +07FF80 +1F87E0 +3F03F0 +3E01F0 +7C00F8 +7C00F8 +7C00F8 +F8007C +F8007C +F8007C +F8007C +F8007C +F8007C +F8007C +F8007C +F8007C +7C00F8 +7C00F8 +7C00F8 +3E01F0 +3F03F0 +1F87E0 +0FFFC0 +01FE00 +ENDCHAR +STARTCHAR 00F4 +ENCODING 244 +SWIDTH 500 0 +DWIDTH 25 0 +BBX 22 35 1 -1 +BITMAP +003800 +007C00 +007E00 +00EE00 +01C700 +018380 +030180 +000000 +000000 +000000 +01FE00 +07FF80 +1F87E0 +3F03F0 +3E01F0 +7C00F8 +7C00F8 +7C00F8 +F8007C +F8007C +F8007C +F8007C +F8007C +F8007C +F8007C +F8007C +F8007C +7C00F8 +7C00F8 +7C00F8 +3E01F0 +3F03F0 +1F87E0 +0FFFC0 +01FE00 +ENDCHAR +STARTCHAR 00F5 +ENCODING 245 +SWIDTH 500 0 +DWIDTH 25 0 +BBX 22 36 1 -1 +BITMAP +018000 +03C020 +07F020 +07F860 +067CC0 +0C1FC0 +080F80 +080700 +000000 +000000 +000000 +01FE00 +07FF80 +1F87E0 +3F03F0 +3E01F0 +7C00F8 +7C00F8 +7C00F8 +F8007C +F8007C +F8007C +F8007C +F8007C +F8007C +F8007C +F8007C +F8007C +7C00F8 +7C00F8 +7C00F8 +3E01F0 +3F03F0 +1F87E0 +0FFFC0 +01FE00 +ENDCHAR +STARTCHAR 00F6 +ENCODING 246 +SWIDTH 500 0 +DWIDTH 25 0 +BBX 22 33 2 -1 +BITMAP +1F07C0 +1F07C0 +1F07C0 +1F07C0 +1F07C0 +000000 +000000 +000000 +01FE00 +07FF80 +1F87E0 +3F03F0 +3E01F0 +7C00F8 +7C00F8 +7C00F8 +F8007C +F8007C +F8007C +F8007C +F8007C +F8007C +F8007C +F8007C +F8007C +7C00F8 +7C00F8 +7C00F8 +3E01F0 +3F03F0 +1F87E0 +0FFFC0 +01FE00 +ENDCHAR +STARTCHAR 00F7 +ENCODING 247 +SWIDTH 540 0 +DWIDTH 27 0 +BBX 27 24 0 1 +BITMAP +003E0000 +003E0000 +003E0000 +003E0000 +003E0000 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +FFFFFFE0 +FFFFFFE0 +00000000 +00000000 +00000000 +00000000 +00000000 +00000000 +003E0000 +003E0000 +003E0000 +003E0000 +003E0000 +ENDCHAR +STARTCHAR 00F8 +ENCODING 248 +SWIDTH 520 0 +DWIDTH 26 0 +BBX 22 25 2 -1 +BITMAP +01FF8C +07FFDC +1F87F8 +3E01F0 +3E01F0 +7C00F8 +7C00F8 +7801F8 +F8037C +F8067C +F8047C +F8087C +F8107C +F8207C +F8407C +F8807C +F9807C +7B0078 +7E00F8 +7C00F8 +3C01F0 +3E01F0 +3F87E0 +47FFC0 +01FE00 +ENDCHAR +STARTCHAR 00F9 +ENCODING 249 +SWIDTH 560 0 +DWIDTH 28 0 +BBX 27 35 1 -1 +BITMAP +01F00000 +00F80000 +00780000 +007C0000 +003C0000 +001E0000 +000E0000 +000C0000 +00000000 +00000000 +FF00FF00 +FF00FF00 +1F001F00 +1F001F00 +1F001F00 +1F001F00 +1F001F00 +1F001F00 +1F001F00 +1F001F00 +1F001F00 +1F001F00 +1F001F00 +1F001F00 +1F001F00 +1F001F00 +1F001F00 +1F001F00 +1F001F00 +0F801F00 +0F803F00 +07C07F00 +03E0FF00 +01FFDFE0 +007F0000 +ENDCHAR +STARTCHAR 00FA +ENCODING 250 +SWIDTH 580 0 +DWIDTH 29 0 +BBX 27 35 1 -1 +BITMAP +000F8000 +001F0000 +001E0000 +003E0000 +003C0000 +00780000 +00F00000 +00300000 +00000000 +00000000 +FF00FF00 +FF00FF00 +1F001F00 +1F001F00 +1F001F00 +1F001F00 +1F001F00 +1F001F00 +1F001F00 +1F001F00 +1F001F00 +1F001F00 +1F001F00 +1F001F00 +1F001F00 +1F001F00 +1F001F00 +1F001F00 +1F001F00 +0F801F00 +0F803F00 +07C07F00 +03E0FF00 +01FFDFE0 +007F0000 +ENDCHAR +STARTCHAR 00FB +ENCODING 251 +SWIDTH 560 0 +DWIDTH 28 0 +BBX 27 35 1 -1 +BITMAP +001C0000 +003E0000 +003F0000 +00770000 +00E38000 +00C1C000 +0180C000 +00000000 +00000000 +00000000 +FF00FF00 +FF00FF00 +1F001F00 +1F001F00 +1F001F00 +1F001F00 +1F001F00 +1F001F00 +1F001F00 +1F001F00 +1F001F00 +1F001F00 +1F001F00 +1F001F00 +1F001F00 +1F001F00 +1F001F00 +1F001F00 +1F001F00 +0F801F00 +0F803F00 +07C07F00 +03E0FF00 +01FFDFE0 +007F0000 +ENDCHAR +STARTCHAR 00FC +ENCODING 252 +SWIDTH 560 0 +DWIDTH 28 0 +BBX 27 33 1 -1 +BITMAP +07C1F000 +07C1F000 +07C1F000 +07C1F000 +07C1F000 +00000000 +00000000 +00000000 +FF00FF00 +FF00FF00 +1F001F00 +1F001F00 +1F001F00 +1F001F00 +1F001F00 +1F001F00 +1F001F00 +1F001F00 +1F001F00 +1F001F00 +1F001F00 +1F001F00 +1F001F00 +1F001F00 +1F001F00 +1F001F00 +1F001F00 +0F801F00 +0F803F00 +07C07F00 +03E0FF00 +01FFDFE0 +007F0000 +ENDCHAR +STARTCHAR 00FD +ENCODING 253 +SWIDTH 520 0 +DWIDTH 26 0 +BBX 23 46 1 -12 +BITMAP +000F80 +001F00 +001E00 +003E00 +003C00 +007800 +00F000 +003000 +000000 +000000 +FFC07E +FFC07E +1F0018 +1F0010 +0F8030 +0F8030 +078020 +07C060 +07C060 +03E040 +03E0C0 +01E080 +01F180 +01F180 +00F900 +00FB00 +00FB00 +007E00 +007E00 +003C00 +003C00 +003C00 +001800 +001800 +001000 +003000 +003000 +002000 +006000 +006000 +004000 +00C000 +008000 +018000 +070000 +0E0000 +ENDCHAR +STARTCHAR 00FE +ENCODING 254 +SWIDTH 520 0 +DWIDTH 26 0 +BBX 24 48 1 -12 +BITMAP +FF0000 +1F0000 +1F0000 +1F0000 +1F0000 +1F0000 +1F0000 +1F0000 +1F0000 +1F0000 +1F0000 +1F0000 +1F3F80 +1FFFF0 +1FE1F8 +1F80FC +1F007C +1F007E +1F003E +1F003E +1F001F +1F001F +1F001F +1F001F +1F001F +1F001F +1F001F +1F001F +1F001F +1F001E +1F003E +1F003E +1F003C +1F007C +1F80F8 +1F61F0 +1F1F80 +1F0000 +1F0000 +1F0000 +1F0000 +1F0000 +1F0000 +1F0000 +1F0000 +1F0000 +FFE000 +FFE000 +ENDCHAR +STARTCHAR 00FF +ENCODING 255 +SWIDTH 520 0 +DWIDTH 26 0 +BBX 23 44 1 -12 +BITMAP +03E0F8 +03E0F8 +03E0F8 +03E0F8 +03E0F8 +000000 +000000 +000000 +FFC07E +FFC07E +1F0018 +1F0010 +0F8030 +0F8030 +078020 +07C060 +07C060 +03E040 +03E0C0 +01E080 +01F180 +01F180 +00F900 +00FB00 +00FB00 +007E00 +007E00 +003C00 +003C00 +003C00 +001800 +001800 +001000 +003000 +003000 +002000 +006000 +006000 +004000 +00C000 +008000 +018000 +070000 +0E0000 +ENDCHAR +STARTCHAR 0100 +ENCODING 256 +SWIDTH 620 0 +DWIDTH 31 0 +BBX 29 40 1 0 +BITMAP +03FFFC00 +03FFFC00 +00000000 +00000000 +00060000 +000F0000 +000F0000 +000F0000 +000F8000 +001F8000 +001F8000 +001FC000 +003FC000 +0037C000 +0037E000 +0077E000 +0063E000 +0063F000 +00E3F000 +00C1F000 +00C1F800 +01C1F800 +0180F800 +0180FC00 +0180FC00 +03807C00 +03FFFC00 +03FFFE00 +07007E00 +06003E00 +06003F00 +0E003F00 +0C001F00 +0C001F80 +1C001F80 +18000F80 +18000FC0 +38000FC0 +FE001FF8 +FE001FF8 +ENDCHAR +STARTCHAR 0101 +ENCODING 257 +SWIDTH 520 0 +DWIDTH 26 0 +BBX 23 30 2 -1 +BITMAP +3FFFC0 +3FFFC0 +000000 +000000 +000000 +03FE00 +1FFF80 +3C0FC0 +3807E0 +3003E0 +3001F0 +2001F0 +0001F0 +0001F0 +0001F0 +0003F0 +001DF0 +03E1F0 +1F01F0 +3C01F0 +7C01F0 +F801F0 +F801F0 +F803F0 +F803F0 +F807F0 +FC0DF0 +7E39F8 +3FF0FE +0FC000 +ENDCHAR +STARTCHAR 0102 +ENCODING 258 +SWIDTH 640 0 +DWIDTH 32 0 +BBX 29 43 1 0 +BITMAP +03E03E00 +03E03C00 +01F0F800 +007FF000 +001FC000 +00000000 +00000000 +00060000 +000F0000 +000F0000 +000F0000 +000F8000 +001F8000 +001F8000 +001FC000 +003FC000 +0037C000 +0037E000 +0077E000 +0063E000 +0063F000 +00E3F000 +00C1F000 +00C1F800 +01C1F800 +0180F800 +0180FC00 +0180FC00 +03807C00 +03FFFC00 +03FFFE00 +07007E00 +06003E00 +06003F00 +0E003F00 +0C001F00 +0C001F80 +1C001F80 +18000F80 +18000FC0 +38000FC0 +FE001FF8 +FE001FF8 +ENDCHAR +STARTCHAR 0103 +ENCODING 259 +SWIDTH 520 0 +DWIDTH 26 0 +BBX 23 32 2 -1 +BITMAP +7C07C0 +7C0780 +3E1F00 +0FFE00 +03F800 +000000 +000000 +03FE00 +1FFF80 +3C0FC0 +3807E0 +3003E0 +3001F0 +2001F0 +0001F0 +0001F0 +0001F0 +0003F0 +001DF0 +03E1F0 +1F01F0 +3C01F0 +7C01F0 +F801F0 +F801F0 +F803F0 +F803F0 +F807F0 +FC0DF0 +7E39F8 +3FF0FE +0FC000 +ENDCHAR +STARTCHAR 0104 +ENCODING 260 +SWIDTH 620 0 +DWIDTH 31 0 +BBX 31 45 1 -9 +BITMAP +00060000 +000F0000 +000F0000 +000F0000 +000F8000 +001F8000 +001F8000 +001FC000 +003FC000 +0037C000 +0037E000 +0077E000 +0063E000 +0063F000 +00E3F000 +00C1F000 +00C1F800 +01C1F800 +0180F800 +0180FC00 +0180FC00 +03807C00 +03FFFC00 +03FFFE00 +07007E00 +06003E00 +06003F00 +0E003F00 +0C001F00 +0C001F80 +1C001F80 +18000F80 +18000FC0 +38000FC0 +FE001FF8 +FE001FF8 +000001F0 +000001F0 +000001F0 +000001F0 +000001F0 +000000F8 +000000F8 +0000007E +0000001E +ENDCHAR +STARTCHAR 0105 +ENCODING 261 +SWIDTH 500 0 +DWIDTH 25 0 +BBX 23 32 2 -8 +BITMAP +03FE00 +1FFF80 +3C0FC0 +3807E0 +3003E0 +3001F0 +2001F0 +0001F0 +0001F0 +0001F0 +0003F0 +001DF0 +03E1F0 +1F01F0 +3C01F0 +7C01F0 +F801F0 +F801F0 +F803F0 +F803F0 +F807F0 +FC0DF0 +7E39F8 +3FF0FE +0FE000 +03E000 +03E000 +03E000 +01F000 +01F000 +00FC00 +003C00 +ENDCHAR +STARTCHAR 0106 +ENCODING 262 +SWIDTH 540 0 +DWIDTH 27 0 +BBX 24 46 2 -1 +BITMAP +0003E0 +0007C0 +000780 +000F80 +000F00 +001E00 +003C00 +000C00 +000000 +001FF0 +00FFFE +03F03F +07C00F +0F8007 +1F0003 +3E0003 +3E0000 +7C0000 +7C0000 +7C0000 +F80000 +F80000 +F80000 +F80000 +F80000 +F80000 +F80000 +F80000 +F80000 +F80000 +F80000 +F80000 +F80000 +F80000 +7C0000 +7C0000 +7C0000 +7C0000 +3E0000 +3E0003 +1F0003 +0F8007 +07C00F +03F03F +00FFFE +001FF0 +ENDCHAR +STARTCHAR 0107 +ENCODING 263 +SWIDTH 440 0 +DWIDTH 22 0 +BBX 19 35 2 -1 +BITMAP +003E00 +007C00 +007800 +00F800 +00F000 +01E000 +03C000 +00C000 +000000 +000000 +01F820 +07FE60 +1FC3E0 +3F00E0 +3E0060 +7C0060 +7C0020 +7C0000 +F80000 +F80000 +F80000 +F80000 +F80000 +F80000 +F80000 +F80000 +F80000 +7C0000 +7C0020 +7E0020 +3E0060 +3F00C0 +1F8380 +0FFF00 +01FC00 +ENDCHAR +STARTCHAR 0108 +ENCODING 264 +SWIDTH 540 0 +DWIDTH 27 0 +BBX 24 46 2 -1 +BITMAP +000E00 +001F00 +001F80 +003B80 +0071C0 +0060E0 +00C060 +000000 +000000 +001FF0 +00FFFE +03F03F +07C00F +0F8007 +1F0003 +3E0003 +3E0000 +7C0000 +7C0000 +7C0000 +F80000 +F80000 +F80000 +F80000 +F80000 +F80000 +F80000 +F80000 +F80000 +F80000 +F80000 +F80000 +F80000 +F80000 +7C0000 +7C0000 +7C0000 +7C0000 +3E0000 +3E0003 +1F0003 +0F8007 +07C00F +03F03F +00FFFE +001FF0 +ENDCHAR +STARTCHAR 0109 +ENCODING 265 +SWIDTH 440 0 +DWIDTH 22 0 +BBX 19 35 2 -1 +BITMAP +007000 +00F800 +00FC00 +01DC00 +038E00 +030700 +060300 +000000 +000000 +000000 +01F820 +07FE60 +1FC3E0 +3F00E0 +3E0060 +7C0060 +7C0020 +7C0000 +F80000 +F80000 +F80000 +F80000 +F80000 +F80000 +F80000 +F80000 +F80000 +7C0000 +7C0020 +7E0020 +3E0060 +3F00C0 +1F8380 +0FFF00 +01FC00 +ENDCHAR +STARTCHAR 010A +ENCODING 266 +SWIDTH 540 0 +DWIDTH 27 0 +BBX 24 44 2 -1 +BITMAP +0007C0 +0007C0 +0007C0 +0007C0 +0007C0 +000000 +000000 +001FF0 +00FFFE +03F03F +07C00F +0F8007 +1F0003 +3E0003 +3E0000 +7C0000 +7C0000 +7C0000 +F80000 +F80000 +F80000 +F80000 +F80000 +F80000 +F80000 +F80000 +F80000 +F80000 +F80000 +F80000 +F80000 +F80000 +7C0000 +7C0000 +7C0000 +7C0000 +3E0000 +3E0003 +1F0003 +0F8007 +07C00F +03F03F +00FFFE +001FF0 +ENDCHAR +STARTCHAR 010B +ENCODING 267 +SWIDTH 440 0 +DWIDTH 22 0 +BBX 19 33 1 -1 +BITMAP +007C00 +007C00 +007C00 +007C00 +007C00 +000000 +000000 +000000 +01F820 +07FE60 +1FC3E0 +3F00E0 +3E0060 +7C0060 +7C0020 +7C0000 +F80000 +F80000 +F80000 +F80000 +F80000 +F80000 +F80000 +F80000 +F80000 +7C0000 +7C0020 +7E0020 +3E0060 +3F00C0 +1F8380 +0FFF00 +01FC00 +ENDCHAR +STARTCHAR 010C +ENCODING 268 +SWIDTH 560 0 +DWIDTH 28 0 +BBX 24 45 2 -1 +BITMAP +00E030 +007060 +0038C0 +001DC0 +000F80 +000F00 +000000 +000000 +001FF0 +00FFFE +03F03F +07C00F +0F8007 +1F0003 +3E0003 +3E0000 +7C0000 +7C0000 +7C0000 +F80000 +F80000 +F80000 +F80000 +F80000 +F80000 +F80000 +F80000 +F80000 +F80000 +F80000 +F80000 +F80000 +F80000 +7C0000 +7C0000 +7C0000 +7C0000 +3E0000 +3E0003 +1F0003 +0F8007 +07C00F +03F03F +00FFFE +001FF0 +ENDCHAR +STARTCHAR 010D +ENCODING 269 +SWIDTH 440 0 +DWIDTH 22 0 +BBX 19 34 2 -1 +BITMAP +0E0300 +070600 +038C00 +01DC00 +00F800 +00F000 +000000 +000000 +000000 +01F820 +07FE60 +1FC3E0 +3F00E0 +3E0060 +7C0060 +7C0020 +7C0000 +F80000 +F80000 +F80000 +F80000 +F80000 +F80000 +F80000 +F80000 +F80000 +7C0000 +7C0020 +7E0020 +3E0060 +3F00C0 +1F8380 +0FFF00 +01FC00 +ENDCHAR +STARTCHAR 010E +ENCODING 270 +SWIDTH 600 0 +DWIDTH 30 0 +BBX 28 45 1 0 +BITMAP +07018000 +03830000 +01C60000 +00EE0000 +007C0000 +00780000 +00000000 +00000000 +00000000 +FFFFE000 +FFFFFC00 +1F00FE00 +1F003F00 +1F001F80 +1F000FC0 +1F0007C0 +1F0007E0 +1F0003E0 +1F0003E0 +1F0003E0 +1F0003F0 +1F0001F0 +1F0001F0 +1F0001F0 +1F0001F0 +1F0001F0 +1F0001F0 +1F0001F0 +1F0001F0 +1F0001F0 +1F0001F0 +1F0001F0 +1F0001F0 +1F0003F0 +1F0003E0 +1F0003E0 +1F0003E0 +1F0007E0 +1F0007C0 +1F000FC0 +1F001F80 +1F003F00 +1F007E00 +FFFFFC00 +FFFFE000 +ENDCHAR +STARTCHAR 010F +ENCODING 271 +SWIDTH 580 0 +DWIDTH 29 0 +BBX 27 37 1 -1 +BITMAP +0007FBE0 +0000FBE0 +0000FBE0 +0000FBE0 +0000FBE0 +0000F8E0 +0000F860 +0000F8C0 +0000F980 +0000FB00 +0000F800 +0000F800 +01FCF800 +0FFFF800 +1F87F800 +3F01F800 +3E00F800 +7E00F800 +7C00F800 +7C00F800 +F800F800 +F800F800 +F800F800 +F800F800 +F800F800 +F800F800 +F800F800 +F800F800 +F800F800 +7800F800 +7C00F800 +7C00F800 +3C00F800 +3E00F800 +1F01F800 +0F86FF00 +01F80000 +ENDCHAR +STARTCHAR 0112 +ENCODING 274 +SWIDTH 520 0 +DWIDTH 26 0 +BBX 24 40 1 0 +BITMAP +0FFFF0 +0FFFF0 +000000 +000000 +FFFFFF +FFFFFF +1F0003 +1F0003 +1F0000 +1F0000 +1F0000 +1F0000 +1F0000 +1F0000 +1F0000 +1F0000 +1F0000 +1F0000 +1F0060 +1F0060 +1F0060 +1FFFE0 +1FFFE0 +1F0060 +1F0060 +1F0060 +1F0000 +1F0000 +1F0000 +1F0000 +1F0000 +1F0000 +1F0000 +1F0000 +1F0000 +1F0003 +1F0003 +1F0003 +FFFFFF +FFFFFF +ENDCHAR +STARTCHAR 0113 +ENCODING 275 +SWIDTH 480 0 +DWIDTH 24 0 +BBX 21 30 2 -1 +BITMAP +3FFFC0 +3FFFC0 +000000 +000000 +000000 +01FC00 +07FF00 +1F07C0 +3E03C0 +3C01E0 +7C01F0 +7800F0 +7800F0 +F800F8 +FFFFF8 +FFFFF8 +F80000 +F80000 +F80000 +F80000 +F80000 +F80000 +7C0000 +7C0010 +3C0018 +3E0030 +1F0060 +0F81C0 +07FF80 +01FC00 +ENDCHAR +STARTCHAR 0114 +ENCODING 276 +SWIDTH 520 0 +DWIDTH 26 0 +BBX 24 43 1 0 +BITMAP +07C07C +07C078 +03E1F0 +00FFE0 +003F80 +000000 +000000 +FFFFFF +FFFFFF +1F0003 +1F0003 +1F0000 +1F0000 +1F0000 +1F0000 +1F0000 +1F0000 +1F0000 +1F0000 +1F0000 +1F0000 +1F0060 +1F0060 +1F0060 +1FFFE0 +1FFFE0 +1F0060 +1F0060 +1F0060 +1F0000 +1F0000 +1F0000 +1F0000 +1F0000 +1F0000 +1F0000 +1F0000 +1F0000 +1F0003 +1F0003 +1F0003 +FFFFFF +FFFFFF +ENDCHAR +STARTCHAR 0115 +ENCODING 277 +SWIDTH 480 0 +DWIDTH 24 0 +BBX 21 32 2 -1 +BITMAP +3E03E0 +3E03C0 +1F0F80 +07FF00 +01FC00 +000000 +000000 +01FC00 +07FF00 +1F07C0 +3E03C0 +3C01E0 +7C01F0 +7800F0 +7800F0 +F800F8 +FFFFF8 +FFFFF8 +F80000 +F80000 +F80000 +F80000 +F80000 +F80000 +7C0000 +7C0010 +3C0018 +3E0030 +1F0060 +0F81C0 +07FF80 +01FC00 +ENDCHAR +STARTCHAR 0116 +ENCODING 278 +SWIDTH 520 0 +DWIDTH 26 0 +BBX 24 43 1 0 +BITMAP +001F00 +001F00 +001F00 +001F00 +001F00 +000000 +000000 +FFFFFF +FFFFFF +1F0003 +1F0003 +1F0000 +1F0000 +1F0000 +1F0000 +1F0000 +1F0000 +1F0000 +1F0000 +1F0000 +1F0000 +1F0060 +1F0060 +1F0060 +1FFFE0 +1FFFE0 +1F0060 +1F0060 +1F0060 +1F0000 +1F0000 +1F0000 +1F0000 +1F0000 +1F0000 +1F0000 +1F0000 +1F0000 +1F0003 +1F0003 +1F0003 +FFFFFF +FFFFFF +ENDCHAR +STARTCHAR 0117 +ENCODING 279 +SWIDTH 480 0 +DWIDTH 24 0 +BBX 21 33 2 -1 +BITMAP +01F000 +01F000 +01F000 +01F000 +01F000 +000000 +000000 +000000 +01FC00 +07FF00 +1F07C0 +3E03C0 +3C01E0 +7C01F0 +7800F0 +7800F0 +F800F8 +FFFFF8 +FFFFF8 +F80000 +F80000 +F80000 +F80000 +F80000 +F80000 +7C0000 +7C0010 +3C0018 +3E0030 +1F0060 +0F81C0 +07FF80 +01FC00 +ENDCHAR +STARTCHAR 0118 +ENCODING 280 +SWIDTH 520 0 +DWIDTH 26 0 +BBX 24 44 1 -8 +BITMAP +FFFFFF +FFFFFF +1F0003 +1F0003 +1F0000 +1F0000 +1F0000 +1F0000 +1F0000 +1F0000 +1F0000 +1F0000 +1F0000 +1F0000 +1F0060 +1F0060 +1F0060 +1FFFE0 +1FFFE0 +1F0060 +1F0060 +1F0060 +1F0000 +1F0000 +1F0000 +1F0000 +1F0000 +1F0000 +1F0000 +1F0000 +1F0000 +1F0003 +1F0003 +1F0003 +FFFFFF +FFFFFF +007C00 +007C00 +007C00 +007C00 +003E00 +003E00 +001F80 +000780 +ENDCHAR +STARTCHAR 0119 +ENCODING 281 +SWIDTH 480 0 +DWIDTH 24 0 +BBX 21 32 1 -8 +BITMAP +01FC00 +07FF00 +1F07C0 +3E03C0 +3C01E0 +7C01F0 +7800F0 +7800F0 +F800F8 +FFFFF8 +FFFFF8 +F80000 +F80000 +F80000 +F80000 +F80000 +F80000 +7C0000 +7C0010 +3C0018 +3E0030 +1F0060 +0F81C0 +07FF80 +01FC00 +00F800 +00F800 +00F800 +007C00 +007C00 +003F00 +000F00 +ENDCHAR +STARTCHAR 011A +ENCODING 282 +SWIDTH 520 0 +DWIDTH 26 0 +BBX 24 44 1 0 +BITMAP +01C060 +00E0C0 +007180 +003B80 +001F00 +001E00 +000000 +000000 +FFFFFF +FFFFFF +1F0003 +1F0003 +1F0000 +1F0000 +1F0000 +1F0000 +1F0000 +1F0000 +1F0000 +1F0000 +1F0000 +1F0000 +1F0060 +1F0060 +1F0060 +1FFFE0 +1FFFE0 +1F0060 +1F0060 +1F0060 +1F0000 +1F0000 +1F0000 +1F0000 +1F0000 +1F0000 +1F0000 +1F0000 +1F0000 +1F0003 +1F0003 +1F0003 +FFFFFF +FFFFFF +ENDCHAR +STARTCHAR 011B +ENCODING 283 +SWIDTH 480 0 +DWIDTH 24 0 +BBX 21 34 2 -1 +BITMAP +0E0300 +070600 +038C00 +01DC00 +00F800 +00F000 +000000 +000000 +000000 +01FC00 +07FF00 +1F07C0 +3E03C0 +3C01E0 +7C01F0 +7800F0 +7800F0 +F800F8 +FFFFF8 +FFFFF8 +F80000 +F80000 +F80000 +F80000 +F80000 +F80000 +7C0000 +7C0010 +3C0018 +3E0030 +1F0060 +0F81C0 +07FF80 +01FC00 +ENDCHAR +STARTCHAR 011C +ENCODING 284 +SWIDTH 600 0 +DWIDTH 30 0 +BBX 29 46 2 -1 +BITMAP +001C0000 +003E0000 +003F0000 +00770000 +00E38000 +00C1C000 +0180C000 +00000000 +00000000 +007F8000 +03FFF000 +07E07C00 +0F801E00 +1F000F00 +3F000700 +3E000700 +7E000300 +7C000300 +7C000300 +7C000300 +FC000000 +F8000000 +F8000000 +F8000000 +F8000000 +F8000000 +F8000000 +F8000000 +F8000000 +F800FFF8 +F800FFF8 +F80007C0 +F80007C0 +F80007C0 +7C0007C0 +7C0007C0 +7C0007C0 +7C0007C0 +3E000FC0 +3E000F80 +1F000F80 +1F801F00 +0FC03E00 +07E07C00 +01FFF000 +007FC000 +ENDCHAR +STARTCHAR 011D +ENCODING 285 +SWIDTH 500 0 +DWIDTH 25 0 +BBX 24 46 -1 -12 +BITMAP +001C00 +003E00 +003F00 +007700 +00E380 +00C1C0 +0180C0 +000000 +000000 +000000 +003FFF +01FFFF +03E1F0 +07C0F8 +0F807C +0F807C +1F003C +1F003E +1F003E +1F003E +1F003E +1F003E +1F003C +0F807C +0F807C +07C0F8 +03E1F0 +01FFC0 +003F80 +000700 +00FC00 +03E000 +07C000 +03F000 +00EF80 +0780F0 +1E003C +3C003E +78001F +F8001F +F8001F +F8001F +FC003E +7E00FE +3FFFF8 +07FFC0 +ENDCHAR +STARTCHAR 011E +ENCODING 286 +SWIDTH 580 0 +DWIDTH 29 0 +BBX 29 44 2 -1 +BITMAP +07C07C00 +07C07800 +03E1F000 +00FFE000 +003F8000 +00000000 +00000000 +007F8000 +03FFF000 +07E07C00 +0F801E00 +1F000F00 +3F000700 +3E000700 +7E000300 +7C000300 +7C000300 +7C000300 +FC000000 +F8000000 +F8000000 +F8000000 +F8000000 +F8000000 +F8000000 +F8000000 +F8000000 +F800FFF8 +F800FFF8 +F80007C0 +F80007C0 +F80007C0 +7C0007C0 +7C0007C0 +7C0007C0 +7C0007C0 +3E000FC0 +3E000F80 +1F000F80 +1F801F00 +0FC03E00 +07E07C00 +01FFF000 +007FC000 +ENDCHAR +STARTCHAR 011F +ENCODING 287 +SWIDTH 500 0 +DWIDTH 25 0 +BBX 24 44 -1 -12 +BITMAP +0F80F8 +0F80F0 +07C3E0 +01FFC0 +007F00 +000000 +000000 +000000 +003FFF +01FFFF +03E1F0 +07C0F8 +0F807C +0F807C +1F003C +1F003E +1F003E +1F003E +1F003E +1F003E +1F003C +0F807C +0F807C +07C0F8 +03E1F0 +01FFC0 +003F80 +000700 +00FC00 +03E000 +07C000 +03F000 +00EF80 +0780F0 +1E003C +3C003E +78001F +F8001F +F8001F +F8001F +FC003E +7E00FE +3FFFF8 +07FFC0 +ENDCHAR +STARTCHAR 0120 +ENCODING 288 +SWIDTH 620 0 +DWIDTH 31 0 +BBX 29 44 2 -1 +BITMAP +003E0000 +003E0000 +003E0000 +003E0000 +003E0000 +00000000 +00000000 +007F8000 +03FFF000 +07E07C00 +0F801E00 +1F000F00 +3F000700 +3E000700 +7E000300 +7C000300 +7C000300 +7C000300 +FC000000 +F8000000 +F8000000 +F8000000 +F8000000 +F8000000 +F8000000 +F8000000 +F8000000 +F800FFF8 +F800FFF8 +F80007C0 +F80007C0 +F80007C0 +7C0007C0 +7C0007C0 +7C0007C0 +7C0007C0 +3E000FC0 +3E000F80 +1F000F80 +1F801F00 +0FC03E00 +07E07C00 +01FFF000 +007FC000 +ENDCHAR +STARTCHAR 0121 +ENCODING 289 +SWIDTH 480 0 +DWIDTH 24 0 +BBX 24 44 0 -12 +BITMAP +007C00 +007C00 +007C00 +007C00 +007C00 +000000 +000000 +000000 +003FFF +01FFFF +03E1F0 +07C0F8 +0F807C +0F807C +1F003C +1F003E +1F003E +1F003E +1F003E +1F003E +1F003C +0F807C +0F807C +07C0F8 +03E1F0 +01FFC0 +003F80 +000700 +00FC00 +03E000 +07C000 +03F000 +00EF80 +0780F0 +1E003C +3C003E +78001F +F8001F +F8001F +F8001F +FC003E +7E00FE +3FFFF8 +07FFC0 +ENDCHAR +STARTCHAR 0124 +ENCODING 292 +SWIDTH 640 0 +DWIDTH 32 0 +BBX 31 45 0 0 +BITMAP +00038000 +0007C000 +0007E000 +000EE000 +001C7000 +00183800 +00301800 +00000000 +00000000 +FFE007FE +FFE007FE +1F0001F0 +1F0001F0 +1F0001F0 +1F0001F0 +1F0001F0 +1F0001F0 +1F0001F0 +1F0001F0 +1F0001F0 +1F0001F0 +1F0001F0 +1F0001F0 +1F0001F0 +1F0001F0 +1F0001F0 +1FFFFFF0 +1FFFFFF0 +1F0001F0 +1F0001F0 +1F0001F0 +1F0001F0 +1F0001F0 +1F0001F0 +1F0001F0 +1F0001F0 +1F0001F0 +1F0001F0 +1F0001F0 +1F0001F0 +1F0001F0 +1F0001F0 +1F0001F0 +FFE007FE +FFE007FE +ENDCHAR +STARTCHAR 0125 +ENCODING 293 +SWIDTH 580 0 +DWIDTH 29 0 +BBX 27 45 1 0 +BITMAP +0E000000 +1F000000 +1F800000 +3B800000 +71C00000 +60E00000 +C0600000 +00000000 +00000000 +FF000000 +1F000000 +1F000000 +1F000000 +1F000000 +1F000000 +1F000000 +1F000000 +1F000000 +1F000000 +1F000000 +1F000000 +1F1FC000 +1F7FF000 +1FE0F800 +1FC07C00 +1F003E00 +1F003E00 +1F001F00 +1F001F00 +1F001F00 +1F001F00 +1F001F00 +1F001F00 +1F001F00 +1F001F00 +1F001F00 +1F001F00 +1F001F00 +1F001F00 +1F001F00 +1F001F00 +1F001F00 +1F001F00 +FFE0FFE0 +FFE0FFE0 +ENDCHAR +STARTCHAR 0126 +ENCODING 294 +SWIDTH 680 0 +DWIDTH 34 0 +BBX 33 36 0 0 +BITMAP +7FF007FF00 +7FF007FF00 +0F8000F800 +0F8000F800 +0F8000F800 +0F8000F800 +0F8000F800 +0F8000F800 +0F8000F800 +0F8000F800 +FFFFFFFF80 +FFFFFFFF80 +0F8000F800 +0F8000F800 +0F8000F800 +0F8000F800 +0F8000F800 +0FFFFFF800 +0FFFFFF800 +0F8000F800 +0F8000F800 +0F8000F800 +0F8000F800 +0F8000F800 +0F8000F800 +0F8000F800 +0F8000F800 +0F8000F800 +0F8000F800 +0F8000F800 +0F8000F800 +0F8000F800 +0F8000F800 +0F8000F800 +7FF007FF00 +7FF007FF00 +ENDCHAR +STARTCHAR 0127 +ENCODING 295 +SWIDTH 580 0 +DWIDTH 29 0 +BBX 27 36 1 0 +BITMAP +FF000000 +1F000000 +1F000000 +1F000000 +1F000000 +1F000000 +1F000000 +FFFFC000 +FFFFC000 +1F000000 +1F000000 +1F000000 +1F3FC000 +1FFFF000 +1FE0F800 +1F807C00 +1F003E00 +1F003E00 +1F001E00 +1F001F00 +1F001F00 +1F001F00 +1F001F00 +1F001F00 +1F001F00 +1F001F00 +1F001F00 +1F001F00 +1F001F00 +1F001F00 +1F001F00 +1F001F00 +1F001F00 +1F001F00 +FFE0FFE0 +FFE0FFE0 +ENDCHAR +STARTCHAR 0128 +ENCODING 296 +SWIDTH 320 0 +DWIDTH 16 0 +BBX 15 46 1 0 +BITMAP +1800 +3C02 +7F02 +7F86 +67CC +C1FC +80F8 +8070 +0000 +0000 +3FF8 +3FF8 +07C0 +07C0 +07C0 +07C0 +07C0 +07C0 +07C0 +07C0 +07C0 +07C0 +07C0 +07C0 +07C0 +07C0 +07C0 +07C0 +07C0 +07C0 +07C0 +07C0 +07C0 +07C0 +07C0 +07C0 +07C0 +07C0 +07C0 +07C0 +07C0 +07C0 +07C0 +07C0 +3FF8 +3FF8 +ENDCHAR +STARTCHAR 0129 +ENCODING 297 +SWIDTH 280 0 +DWIDTH 14 0 +BBX 15 35 -1 0 +BITMAP +1800 +3C02 +7F02 +7F86 +67CC +C1FC +80F8 +8070 +0000 +0000 +0000 +3FC0 +07C0 +07C0 +07C0 +07C0 +07C0 +07C0 +07C0 +07C0 +07C0 +07C0 +07C0 +07C0 +07C0 +07C0 +07C0 +07C0 +07C0 +07C0 +07C0 +07C0 +07C0 +3FF0 +3FF0 +ENDCHAR +STARTCHAR 012A +ENCODING 298 +SWIDTH 300 0 +DWIDTH 15 0 +BBX 16 40 -1 0 +BITMAP +FFFF +FFFF +0000 +0000 +3FF8 +3FF8 +07C0 +07C0 +07C0 +07C0 +07C0 +07C0 +07C0 +07C0 +07C0 +07C0 +07C0 +07C0 +07C0 +07C0 +07C0 +07C0 +07C0 +07C0 +07C0 +07C0 +07C0 +07C0 +07C0 +07C0 +07C0 +07C0 +07C0 +07C0 +07C0 +07C0 +07C0 +07C0 +3FF8 +3FF8 +ENDCHAR +STARTCHAR 012B +ENCODING 299 +SWIDTH 260 0 +DWIDTH 13 0 +BBX 16 29 -2 0 +BITMAP +FFFF +FFFF +0000 +0000 +0000 +1FE0 +03E0 +03E0 +03E0 +03E0 +03E0 +03E0 +03E0 +03E0 +03E0 +03E0 +03E0 +03E0 +03E0 +03E0 +03E0 +03E0 +03E0 +03E0 +03E0 +03E0 +03E0 +1FF8 +1FF8 +ENDCHAR +STARTCHAR 012C +ENCODING 300 +SWIDTH 280 0 +DWIDTH 14 0 +BBX 17 43 -1 0 +BITMAP +F80F80 +F80F00 +7C3E00 +1FFC00 +07F000 +000000 +000000 +3FF800 +3FF800 +07C000 +07C000 +07C000 +07C000 +07C000 +07C000 +07C000 +07C000 +07C000 +07C000 +07C000 +07C000 +07C000 +07C000 +07C000 +07C000 +07C000 +07C000 +07C000 +07C000 +07C000 +07C000 +07C000 +07C000 +07C000 +07C000 +07C000 +07C000 +07C000 +07C000 +07C000 +07C000 +3FF800 +3FF800 +ENDCHAR +STARTCHAR 012D +ENCODING 301 +SWIDTH 260 0 +DWIDTH 13 0 +BBX 17 31 -2 0 +BITMAP +F80F80 +F80F00 +7C3E00 +1FFC00 +07F000 +000000 +000000 +1FE000 +03E000 +03E000 +03E000 +03E000 +03E000 +03E000 +03E000 +03E000 +03E000 +03E000 +03E000 +03E000 +03E000 +03E000 +03E000 +03E000 +03E000 +03E000 +03E000 +03E000 +03E000 +1FF800 +1FF800 +ENDCHAR +STARTCHAR 012E +ENCODING 302 +SWIDTH 280 0 +DWIDTH 14 0 +BBX 14 44 1 -8 +BITMAP +FFE0 +FFE0 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +FFE0 +FFE0 +03E0 +03E0 +03E0 +03E0 +01F0 +01F0 +00FC +003C +ENDCHAR +STARTCHAR 012F +ENCODING 303 +SWIDTH 260 0 +DWIDTH 13 0 +BBX 10 43 1 -8 +BITMAP +1F00 +1F00 +1F00 +1F00 +1F00 +0000 +0000 +0000 +0000 +0000 +0000 +FF00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +FFC0 +FFC0 +7C00 +7C00 +7C00 +7C00 +3E00 +3E00 +1F80 +0780 +ENDCHAR +STARTCHAR 0130 +ENCODING 304 +SWIDTH 280 0 +DWIDTH 14 0 +BBX 11 43 1 0 +BITMAP +0F80 +0F80 +0F80 +0F80 +0F80 +0000 +0000 +FFE0 +FFE0 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +FFE0 +FFE0 +ENDCHAR +STARTCHAR 0131 +ENCODING 305 +SWIDTH 260 0 +DWIDTH 13 0 +BBX 10 24 1 0 +BITMAP +FF00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +FFC0 +FFC0 +ENDCHAR +STARTCHAR 0134 +ENCODING 308 +SWIDTH 480 0 +DWIDTH 24 0 +BBX 22 46 1 -1 +BITMAP +0001C0 +0003E0 +0003F0 +000770 +000E38 +000C1C +00180C +000000 +000000 +000FFC +000FFC +0003E0 +0003E0 +0003E0 +0003E0 +0003E0 +0003E0 +0003E0 +0003E0 +0003E0 +0003E0 +0003E0 +0003E0 +0003E0 +0003E0 +0003E0 +0003E0 +0003E0 +0003E0 +0003E0 +0003E0 +0003E0 +0003E0 +0003E0 +0003E0 +0003E0 +0003E0 +3003E0 +F003E0 +F003E0 +7007E0 +7807C0 +3C0FC0 +1E1F80 +0FFF00 +01F800 +ENDCHAR +STARTCHAR 0135 +ENCODING 309 +SWIDTH 280 0 +DWIDTH 14 0 +BBX 11 45 2 -12 +BITMAP +0E00 +1F00 +3B80 +31C0 +60C0 +C060 +0000 +0000 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +3E00 +7C00 +F000 +ENDCHAR +STARTCHAR 0136 +ENCODING 310 +SWIDTH 460 0 +DWIDTH 23 0 +BBX 1 1 0 0 +BITMAP +00 +ENDCHAR +STARTCHAR 0139 +ENCODING 313 +SWIDTH 520 0 +DWIDTH 26 0 +BBX 23 46 1 0 +BITMAP +03E000 +07C000 +078000 +0F8000 +0F0000 +1E0000 +3C0000 +0C0000 +000000 +000000 +FFC000 +FFC000 +1F0000 +1F0000 +1F0000 +1F0000 +1F0000 +1F0000 +1F0000 +1F0000 +1F0000 +1F0000 +1F0000 +1F0000 +1F0000 +1F0000 +1F0000 +1F0000 +1F0000 +1F0000 +1F0000 +1F0000 +1F0000 +1F0000 +1F0000 +1F0000 +1F0000 +1F0000 +1F0000 +1F0000 +1F0000 +1F0006 +1F0006 +1F0006 +FFFFFE +FFFFFE +ENDCHAR +STARTCHAR 013A +ENCODING 314 +SWIDTH 240 0 +DWIDTH 12 0 +BBX 11 46 1 0 +BITMAP +03E0 +07C0 +0780 +0F80 +0F00 +1E00 +3C00 +0C00 +0000 +0000 +FF00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +FFE0 +FFE0 +ENDCHAR +STARTCHAR 013D +ENCODING 317 +SWIDTH 520 0 +DWIDTH 26 0 +BBX 23 36 1 0 +BITMAP +FFC3E0 +FFC3E0 +1F03E0 +1F03E0 +1F03E0 +1F00E0 +1F0060 +1F00C0 +1F0180 +1F0300 +1F0000 +1F0000 +1F0000 +1F0000 +1F0000 +1F0000 +1F0000 +1F0000 +1F0000 +1F0000 +1F0000 +1F0000 +1F0000 +1F0000 +1F0000 +1F0000 +1F0000 +1F0000 +1F0000 +1F0000 +1F0000 +1F0006 +1F0006 +1F0006 +FFFFFE +FFFFFE +ENDCHAR +STARTCHAR 013E +ENCODING 318 +SWIDTH 320 0 +DWIDTH 16 0 +BBX 14 36 1 0 +BITMAP +FF7C +1F7C +1F7C +1F7C +1F7C +1F1C +1F0C +1F18 +1F30 +1F60 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +FFE0 +FFE0 +ENDCHAR +STARTCHAR 013F +ENCODING 319 +SWIDTH 520 0 +DWIDTH 26 0 +BBX 23 36 1 0 +BITMAP +FFC000 +FFC000 +1F0000 +1F0000 +1F0000 +1F0000 +1F0000 +1F0000 +1F0000 +1F0000 +1F0000 +1F0000 +1F0000 +1F0000 +1F0000 +1F0000 +1F0000 +1F0000 +1F0000 +1F0000 +1F07C0 +1F07C0 +1F07C0 +1F07C0 +1F07C0 +1F0000 +1F0000 +1F0000 +1F0000 +1F0000 +1F0000 +1F0006 +1F0006 +1F0006 +FFFFFE +FFFFFE +ENDCHAR +STARTCHAR 0140 +ENCODING 320 +SWIDTH 360 0 +DWIDTH 18 0 +BBX 15 36 1 0 +BITMAP +FF00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F3E +1F3E +1F3E +1F3E +1F3E +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +FFE0 +FFE0 +ENDCHAR +STARTCHAR 0141 +ENCODING 321 +SWIDTH 560 0 +DWIDTH 28 0 +BBX 27 38 1 0 +BITMAP +01F00000 +01F00000 +01F00000 +01F00000 +01F00000 +01F00000 +01F00000 +01F00000 +01F3C000 +01F7C000 +01FF0000 +01FE0000 +01F80000 +03F00000 +07F00000 +1FF00000 +3FF00000 +F9F00000 +01F00000 +01F00000 +01F00000 +01F00000 +01F00000 +01F00000 +01F00000 +01F00000 +01F00000 +01F00000 +01F00000 +01F00000 +01F00000 +01F00000 +01F00000 +01F00000 +01F00000 +01F00000 +01FFFFE0 +00FFFFE0 +ENDCHAR +STARTCHAR 0142 +ENCODING 322 +SWIDTH 380 0 +DWIDTH 19 0 +BBX 17 40 1 -2 +BITMAP +03E000 +03E000 +03E000 +03E000 +03E000 +03E000 +03E000 +03E000 +03E000 +03E000 +03EF80 +03FF00 +03FC00 +03F000 +07E000 +1FE000 +3FE000 +FBE000 +03E000 +03E000 +03E000 +03E000 +03E000 +03E000 +03E000 +03E000 +03E000 +03E000 +03E000 +03E000 +03E000 +03E000 +03E000 +03E000 +03E000 +03E000 +03E000 +03E000 +03E000 +03E000 +ENDCHAR +STARTCHAR 0143 +ENCODING 323 +SWIDTH 600 0 +DWIDTH 30 0 +BBX 29 46 1 0 +BITMAP +0007C000 +000F8000 +000F0000 +001F0000 +001E0000 +003C0000 +00780000 +00180000 +00000000 +00000000 +FF8007F8 +FF8007F8 +1FC000C0 +1FC000C0 +1FE000C0 +1BF000C0 +1BF000C0 +19F800C0 +19F800C0 +18FC00C0 +187E00C0 +187E00C0 +183F00C0 +183F00C0 +181F80C0 +180FC0C0 +180FC0C0 +1807E0C0 +1807E0C0 +1803F0C0 +1801F8C0 +1801F8C0 +1800FCC0 +1800FEC0 +18007EC0 +18003FC0 +18003FC0 +18001FC0 +18001FC0 +18000FC0 +180007C0 +180007C0 +180003C0 +180003C0 +FE0001C0 +FE0000C0 +ENDCHAR +STARTCHAR 0144 +ENCODING 324 +SWIDTH 580 0 +DWIDTH 29 0 +BBX 26 34 1 0 +BITMAP +0003E000 +0007C000 +00078000 +000F8000 +000F0000 +001E0000 +003C0000 +000C0000 +00000000 +00000000 +FF1F8000 +1F7FE000 +1FE1F800 +1F80F800 +1F007C00 +1F007C00 +1F003E00 +1F003E00 +1F003E00 +1F003E00 +1F003E00 +1F003E00 +1F003E00 +1F003E00 +1F003E00 +1F003E00 +1F003E00 +1F003E00 +1F003E00 +1F003E00 +1F003E00 +1F003E00 +FFE1FFC0 +FFE1FFC0 +ENDCHAR +STARTCHAR 0147 +ENCODING 327 +SWIDTH 600 0 +DWIDTH 30 0 +BBX 29 45 1 0 +BITMAP +00E03000 +00706000 +0038C000 +001DC000 +000F8000 +000F0000 +00000000 +00000000 +00000000 +FF8007F8 +FF8007F8 +1FC000C0 +1FC000C0 +1FE000C0 +1BF000C0 +1BF000C0 +19F800C0 +19F800C0 +18FC00C0 +187E00C0 +187E00C0 +183F00C0 +183F00C0 +181F80C0 +180FC0C0 +180FC0C0 +1807E0C0 +1807E0C0 +1803F0C0 +1801F8C0 +1801F8C0 +1800FCC0 +1800FEC0 +18007EC0 +18003FC0 +18003FC0 +18001FC0 +18001FC0 +18000FC0 +180007C0 +180007C0 +180003C0 +180003C0 +FE0001C0 +FE0000C0 +ENDCHAR +STARTCHAR 0148 +ENCODING 328 +SWIDTH 560 0 +DWIDTH 28 0 +BBX 26 33 1 0 +BITMAP +01C06000 +00E0C000 +00718000 +003B8000 +001F0000 +001E0000 +00000000 +00000000 +00000000 +FF1F8000 +1F7FE000 +1FE1F800 +1F80F800 +1F007C00 +1F007C00 +1F003E00 +1F003E00 +1F003E00 +1F003E00 +1F003E00 +1F003E00 +1F003E00 +1F003E00 +1F003E00 +1F003E00 +1F003E00 +1F003E00 +1F003E00 +1F003E00 +1F003E00 +1F003E00 +FFE1FFC0 +FFE1FFC0 +ENDCHAR +STARTCHAR 0149 +ENCODING 329 +SWIDTH 700 0 +DWIDTH 35 0 +BBX 31 31 3 0 +BITMAP +F8000000 +F8000000 +F8000000 +F8000000 +F8000000 +38000000 +18000000 +37F8FC00 +60FBFF00 +C0FF0FC0 +00FC07C0 +00F803E0 +00F803E0 +00F801F0 +00F801F0 +00F801F0 +00F801F0 +00F801F0 +00F801F0 +00F801F0 +00F801F0 +00F801F0 +00F801F0 +00F801F0 +00F801F0 +00F801F0 +00F801F0 +00F801F0 +00F801F0 +07FF0FFE +07FF0FFE +ENDCHAR +STARTCHAR 014A +ENCODING 330 +SWIDTH 580 0 +DWIDTH 29 0 +BBX 25 44 2 -8 +BITMAP +F8000F80 +FC000F80 +FC000F80 +FE000F80 +FF000F80 +FF000F80 +FF800F80 +FF800F80 +FFC00F80 +FFC00F80 +FBE00F80 +FBE00F80 +F9F00F80 +F9F80F80 +F8F80F80 +F87C0F80 +F87C0F80 +F83E0F80 +F83E0F80 +F81F0F80 +F80F0F80 +F80F8F80 +F807CF80 +F807CF80 +F803EF80 +F801EF80 +F801FF80 +F800FF80 +F800FF80 +F8007F80 +F8007F80 +F8003F80 +F8001F80 +F8001F80 +F8000F80 +F8000F80 +00000F80 +00000F80 +00000F80 +00001F00 +00001F00 +00003E00 +0000FC00 +0000F000 +ENDCHAR +STARTCHAR 014B +ENCODING 331 +SWIDTH 520 0 +DWIDTH 26 0 +BBX 23 33 1 -9 +BITMAP +FF1F80 +1F61E0 +1F80F0 +1F0078 +1F0078 +1F007C +1F003C +1F003C +1F003E +1F003E +1F003E +1F003E +1F003E +1F003E +1F003E +1F003E +1F003E +1F003E +1F003E +1F003E +1F003E +1F003E +FFE03E +FFE03E +00003E +00003E +00003E +00003E +00007C +00007C +0000F8 +0003F0 +0003C0 +ENDCHAR +STARTCHAR 014C +ENCODING 332 +SWIDTH 620 0 +DWIDTH 31 0 +BBX 27 41 2 -1 +BITMAP +07FFF800 +07FFF800 +00000000 +00000000 +007F8000 +01FFF000 +07E0FC00 +0F807E00 +1F003F00 +1F001F00 +3E000F80 +7E000F80 +7C000FC0 +7C0007C0 +FC0007C0 +FC0007E0 +FC0007E0 +FC0007E0 +F80007E0 +F80003E0 +F80003E0 +F80003E0 +F80003E0 +F80003E0 +F80003E0 +F80003E0 +F80007E0 +F80007E0 +FC0007E0 +FC0007E0 +FC0007C0 +7C0007C0 +7C000FC0 +7E000F80 +3E000F80 +1F001F00 +1F003F00 +0F807E00 +07E0FC00 +01FFF000 +007FC000 +ENDCHAR +STARTCHAR 014D +ENCODING 333 +SWIDTH 500 0 +DWIDTH 25 0 +BBX 22 30 2 -1 +BITMAP +1FFFE0 +1FFFE0 +000000 +000000 +000000 +01FE00 +07FF80 +1F87E0 +3F03F0 +3E01F0 +7C00F8 +7C00F8 +7C00F8 +F8007C +F8007C +F8007C +F8007C +F8007C +F8007C +F8007C +F8007C +F8007C +7C00F8 +7C00F8 +7C00F8 +3E01F0 +3F03F0 +1F87E0 +0FFFC0 +01FE00 +ENDCHAR +STARTCHAR 014E +ENCODING 334 +SWIDTH 600 0 +DWIDTH 30 0 +BBX 27 44 2 -1 +BITMAP +07C07C00 +07C07800 +03E1F000 +00FFE000 +003F8000 +00000000 +00000000 +007F8000 +01FFF000 +07E0FC00 +0F807E00 +1F003F00 +1F001F00 +3E000F80 +7E000F80 +7C000FC0 +7C0007C0 +FC0007C0 +FC0007E0 +FC0007E0 +FC0007E0 +F80007E0 +F80003E0 +F80003E0 +F80003E0 +F80003E0 +F80003E0 +F80003E0 +F80003E0 +F80007E0 +F80007E0 +FC0007E0 +FC0007E0 +FC0007C0 +7C0007C0 +7C000FC0 +7E000F80 +3E000F80 +1F001F00 +1F003F00 +0F807E00 +07E0FC00 +01FFF000 +007FC000 +ENDCHAR +STARTCHAR 014F +ENCODING 335 +SWIDTH 500 0 +DWIDTH 25 0 +BBX 22 32 1 -1 +BITMAP +1F01F0 +1F01E0 +0F87C0 +03FF80 +00FE00 +000000 +000000 +01FE00 +07FF80 +1F87E0 +3F03F0 +3E01F0 +7C00F8 +7C00F8 +7C00F8 +F8007C +F8007C +F8007C +F8007C +F8007C +F8007C +F8007C +F8007C +F8007C +7C00F8 +7C00F8 +7C00F8 +3E01F0 +3F03F0 +1F87E0 +0FFFC0 +01FE00 +ENDCHAR +STARTCHAR 0150 +ENCODING 336 +SWIDTH 600 0 +DWIDTH 30 0 +BBX 27 46 2 -1 +BITMAP +001F8FC0 +003F1F80 +007C3E00 +00F07800 +01E0F000 +0783C000 +0E070000 +00000000 +00000000 +007F8000 +01FFF000 +07E0FC00 +0F807E00 +1F003F00 +1F001F00 +3E000F80 +7E000F80 +7C000FC0 +7C0007C0 +FC0007C0 +FC0007E0 +FC0007E0 +FC0007E0 +F80007E0 +F80003E0 +F80003E0 +F80003E0 +F80003E0 +F80003E0 +F80003E0 +F80003E0 +F80007E0 +F80007E0 +FC0007E0 +FC0007E0 +FC0007C0 +7C0007C0 +7C000FC0 +7E000F80 +3E000F80 +1F001F00 +1F003F00 +0F807E00 +07E0FC00 +01FFF000 +007FC000 +ENDCHAR +STARTCHAR 0151 +ENCODING 337 +SWIDTH 500 0 +DWIDTH 25 0 +BBX 24 34 2 -1 +BITMAP +007E3F +00FC7E +01F0F8 +03C1E0 +0783C0 +1E0F00 +381C00 +000000 +000000 +01FE00 +07FF80 +1F87E0 +3F03F0 +3E01F0 +7C00F8 +7C00F8 +7C00F8 +F8007C +F8007C +F8007C +F8007C +F8007C +F8007C +F8007C +F8007C +F8007C +7C00F8 +7C00F8 +7C00F8 +3E01F0 +3F03F0 +1F87E0 +0FFFC0 +01FE00 +ENDCHAR +STARTCHAR 0152 +ENCODING 338 +SWIDTH 860 0 +DWIDTH 43 0 +BBX 39 37 2 -1 +BITMAP +007FFFFFFE +03FFFFFFFE +07F0FF0006 +0FC03F0006 +1F801F0000 +3F001F0000 +3F001F0000 +7E001F0000 +7E001F0000 +7C001F0000 +7C001F0000 +FC001F0000 +FC001F0000 +F8001F0000 +F8001F00C0 +F8001F00C0 +F8001F00C0 +F8001FFFC0 +F8001FFFC0 +F8001F00C0 +F8001F00C0 +F8001F00C0 +F8001F0000 +F8001F0000 +FC001F0000 +7C001F0000 +7C001F0000 +7C001F0000 +7E001F0000 +3E001F0000 +3F001F0000 +1F001F0000 +1F801F0006 +0FC03F0006 +07F0FF0006 +03FFFFFFFE +007F800000 +ENDCHAR +STARTCHAR 0153 +ENCODING 339 +SWIDTH 860 0 +DWIDTH 43 0 +BBX 39 25 2 -1 +BITMAP +00FF007F00 +07FFC1FFC0 +0F83F3C1F0 +1F01F780F0 +3E00FF0078 +7C007F007C +7C007E003C +7C007E003C +F8003E003E +F8003FFFFE +F8003FFFFE +F8003E0000 +F8003E0000 +F8003E0000 +F8003E0000 +F8003E0000 +F8003E0000 +7C007F0000 +7C007F0002 +7C007F0006 +3E00FF800E +3F01F7C01C +1F83F3F078 +07FFC1FFE0 +01FF003F80 +ENDCHAR +STARTCHAR 0154 +ENCODING 340 +SWIDTH 660 0 +DWIDTH 33 0 +BBX 31 45 1 0 +BITMAP +0007C000 +000F8000 +000F0000 +001F0000 +001E0000 +003C0000 +00780000 +00180000 +00000000 +FFFFE000 +FFFFFC00 +1F007E00 +1F001F00 +1F000F80 +1F0007C0 +1F0007C0 +1F0003E0 +1F0003E0 +1F0003E0 +1F0003E0 +1F0003E0 +1F0007C0 +1F0007C0 +1F000F80 +1F001F80 +1F007F00 +1FFFFC00 +1FFFF000 +1F07E000 +1F03E000 +1F03F000 +1F03F000 +1F01F800 +1F00F800 +1F00FC00 +1F007C00 +1F007E00 +1F003F00 +1F003F80 +1F001F80 +1F000FC0 +1F000FE0 +1F0007F0 +FFE003FE +FFE001FE +ENDCHAR +STARTCHAR 0155 +ENCODING 341 +SWIDTH 440 0 +DWIDTH 22 0 +BBX 20 34 1 0 +BITMAP +000F80 +001F00 +001E00 +003E00 +003C00 +007800 +00F000 +003000 +000000 +000000 +FF1F80 +1F7FE0 +1FE1F0 +1F8060 +1F0000 +1F0000 +1F0000 +1F0000 +1F0000 +1F0000 +1F0000 +1F0000 +1F0000 +1F0000 +1F0000 +1F0000 +1F0000 +1F0000 +1F0000 +1F0000 +1F0000 +1F0000 +FFE000 +FFE000 +ENDCHAR +STARTCHAR 0158 +ENCODING 344 +SWIDTH 600 0 +DWIDTH 30 0 +BBX 31 45 1 0 +BITMAP +01C06000 +00E0C000 +00718000 +003B8000 +001F0000 +001E0000 +00000000 +00000000 +00000000 +FFFFE000 +FFFFFC00 +1F007E00 +1F001F00 +1F000F80 +1F0007C0 +1F0007C0 +1F0003E0 +1F0003E0 +1F0003E0 +1F0003E0 +1F0003E0 +1F0007C0 +1F0007C0 +1F000F80 +1F001F80 +1F007F00 +1FFFFC00 +1FFFF000 +1F07E000 +1F03E000 +1F03F000 +1F03F000 +1F01F800 +1F00F800 +1F00FC00 +1F007C00 +1F007E00 +1F003F00 +1F003F80 +1F001F80 +1F000FC0 +1F000FE0 +1F0007F0 +FFE003FE +FFE001FE +ENDCHAR +STARTCHAR 0159 +ENCODING 345 +SWIDTH 440 0 +DWIDTH 22 0 +BBX 20 33 1 0 +BITMAP +0380C0 +01C180 +00E300 +007700 +003E00 +003C00 +000000 +000000 +000000 +FF1F80 +1F7FE0 +1FE1F0 +1F8060 +1F0000 +1F0000 +1F0000 +1F0000 +1F0000 +1F0000 +1F0000 +1F0000 +1F0000 +1F0000 +1F0000 +1F0000 +1F0000 +1F0000 +1F0000 +1F0000 +1F0000 +1F0000 +FFE000 +FFE000 +ENDCHAR +STARTCHAR 015A +ENCODING 346 +SWIDTH 520 0 +DWIDTH 26 0 +BBX 23 47 2 -1 +BITMAP +000F80 +001F00 +001E00 +003E00 +003C00 +007800 +00F000 +003000 +000000 +000000 +01FE00 +0FFFE0 +1F83F0 +3F00F0 +7E0070 +7C0070 +F80030 +F80000 +F80000 +F80000 +F80000 +FC0000 +FC0000 +7E0000 +7F0000 +3FC000 +1FF800 +0FFF00 +03FFC0 +00FFE0 +001FF0 +0003F8 +0000FC +00007C +00007E +00003E +00003E +C0003E +C0003E +E0003E +E0007C +E0007C +F000F8 +7801F0 +3E07E0 +0FFFC0 +03FE00 +ENDCHAR +STARTCHAR 015B +ENCODING 347 +SWIDTH 420 0 +DWIDTH 21 0 +BBX 17 35 3 -1 +BITMAP +00F800 +01F000 +01E000 +03E000 +03C000 +078000 +0F0000 +030000 +000000 +000000 +07FF00 +1FFF00 +3E1F00 +7C0F00 +F80700 +F80300 +F80300 +F80000 +FC0000 +7E0000 +7FC000 +3FF000 +0FFC00 +03FE00 +007F00 +001F00 +001F80 +000F80 +800F80 +C00F80 +C01F80 +E01F00 +F87E00 +CFFC00 +03F000 +ENDCHAR +STARTCHAR 015C +ENCODING 348 +SWIDTH 520 0 +DWIDTH 26 0 +BBX 23 46 2 -1 +BITMAP +003800 +007C00 +007E00 +00EE00 +01C700 +018380 +030180 +000000 +000000 +01FE00 +0FFFE0 +1F83F0 +3F00F0 +7E0070 +7C0070 +F80030 +F80000 +F80000 +F80000 +F80000 +FC0000 +FC0000 +7E0000 +7F0000 +3FC000 +1FF800 +0FFF00 +03FFC0 +00FFE0 +001FF0 +0003F8 +0000FC +00007C +00007E +00003E +00003E +C0003E +C0003E +E0003E +E0007C +E0007C +F000F8 +7801F0 +3E07E0 +0FFFC0 +03FE00 +ENDCHAR +STARTCHAR 015D +ENCODING 349 +SWIDTH 400 0 +DWIDTH 20 0 +BBX 17 35 2 -1 +BITMAP +01C000 +03E000 +03F000 +077000 +0E3800 +0C1C00 +180C00 +000000 +000000 +000000 +07FF00 +1FFF00 +3E1F00 +7C0F00 +F80700 +F80300 +F80300 +F80000 +FC0000 +7E0000 +7FC000 +3FF000 +0FFC00 +03FE00 +007F00 +001F00 +001F80 +000F80 +800F80 +C00F80 +C01F80 +E01F00 +F87E00 +CFFC00 +03F000 +ENDCHAR +STARTCHAR 015E +ENCODING 350 +SWIDTH 520 0 +DWIDTH 26 0 +BBX 23 48 2 -12 +BITMAP +01FE00 +0FFFE0 +1F83F0 +3F00F0 +7E0070 +7C0070 +F80030 +F80000 +F80000 +F80000 +F80000 +FC0000 +FC0000 +7E0000 +7F0000 +3FC000 +1FF800 +0FFF00 +03FFC0 +00FFE0 +001FF0 +0003F8 +0000FC +00007C +00007E +00003E +00003E +C0003E +C0003E +E0003E +E0007C +E0007C +F000F8 +7801F0 +3E07E0 +0FFFC0 +03FE00 +008000 +018000 +01C000 +03F000 +00F800 +007800 +007800 +007800 +00F800 +07F000 +07E000 +ENDCHAR +STARTCHAR 015F +ENCODING 351 +SWIDTH 400 0 +DWIDTH 20 0 +BBX 17 36 2 -12 +BITMAP +07FF00 +1FFF00 +3E1F00 +7C0F00 +F80700 +F80300 +F80300 +F80000 +FC0000 +7E0000 +7FC000 +3FF000 +0FFC00 +03FE00 +007F00 +001F00 +001F80 +000F80 +800F80 +C00F80 +C01F80 +E01F00 +F87E00 +CFFC00 +03F000 +020000 +060000 +070000 +0FC000 +03E000 +01E000 +01E000 +01E000 +03E000 +1FC000 +1F8000 +ENDCHAR +STARTCHAR 0160 +ENCODING 352 +SWIDTH 520 0 +DWIDTH 26 0 +BBX 23 46 2 0 +BITMAP +070180 +038300 +01C600 +00EE00 +007C00 +007800 +000000 +000000 +000000 +01FE00 +0FFFE0 +1F83F0 +3F00F0 +7E0070 +7C0070 +F80030 +F80000 +F80000 +F80000 +F80000 +FC0000 +FC0000 +7E0000 +7F0000 +3FC000 +1FF800 +0FFF00 +03FFC0 +00FFE0 +001FF0 +0003F8 +0000FC +00007C +00007E +00003E +00003E +C0003E +C0003E +E0003E +E0007C +E0007C +F000F8 +7801F0 +3E07E0 +0FFFC0 +03FE00 +ENDCHAR +STARTCHAR 0161 +ENCODING 353 +SWIDTH 400 0 +DWIDTH 20 0 +BBX 17 34 3 0 +BITMAP +1C0600 +0E0C00 +071800 +03B800 +01F000 +01E000 +000000 +000000 +000000 +07FF00 +1FFF00 +3E1F00 +7C0F00 +F80700 +F80300 +F80300 +F80000 +FC0000 +7E0000 +7FC000 +3FF000 +0FFC00 +03FE00 +007F00 +001F00 +001F80 +000F80 +800F80 +C00F80 +C01F80 +E01F00 +F87E00 +CFFC00 +03F000 +ENDCHAR +STARTCHAR 0162 +ENCODING 354 +SWIDTH 540 0 +DWIDTH 27 0 +BBX 25 48 1 -12 +BITMAP +FFFFFF80 +FFFFFF80 +C03E0380 +C03E0380 +C03E0380 +003E0000 +003E0000 +003E0000 +003E0000 +003E0000 +003E0000 +003E0000 +003E0000 +003E0000 +003E0000 +003E0000 +003E0000 +003E0000 +003E0000 +003E0000 +003E0000 +003E0000 +003E0000 +003E0000 +003E0000 +003E0000 +003E0000 +003E0000 +003E0000 +003E0000 +003E0000 +003E0000 +003E0000 +003E0000 +01FF8000 +01FF8000 +00180000 +00100000 +00300000 +00380000 +007E0000 +001F0000 +000F0000 +000F0000 +000F0000 +001F0000 +00FE0000 +00FC0000 +ENDCHAR +STARTCHAR 0163 +ENCODING 355 +SWIDTH 320 0 +DWIDTH 16 0 +BBX 14 47 1 -12 +BITMAP +0080 +0180 +0380 +0780 +0F80 +0F80 +0F80 +0F80 +0F80 +0F80 +0F80 +FFF8 +FFF8 +0F80 +0F80 +0F80 +0F80 +0F80 +0F80 +0F80 +0F80 +0F80 +0F80 +0F80 +0F80 +0F80 +0F80 +0F80 +0F80 +0F80 +0F80 +0F80 +0FC0 +07F8 +00F8 +0060 +0040 +00C0 +00E0 +01F8 +007C +003C +003C +003C +007C +03F8 +03F0 +ENDCHAR +STARTCHAR 0164 +ENCODING 356 +SWIDTH 560 0 +DWIDTH 28 0 +BBX 25 45 1 0 +BITMAP +01C06000 +00E0C000 +00718000 +003B8000 +001F0000 +001E0000 +00000000 +00000000 +00000000 +FFFFFF80 +FFFFFF80 +C03E0380 +C03E0380 +C03E0380 +003E0000 +003E0000 +003E0000 +003E0000 +003E0000 +003E0000 +003E0000 +003E0000 +003E0000 +003E0000 +003E0000 +003E0000 +003E0000 +003E0000 +003E0000 +003E0000 +003E0000 +003E0000 +003E0000 +003E0000 +003E0000 +003E0000 +003E0000 +003E0000 +003E0000 +003E0000 +003E0000 +003E0000 +003E0000 +01FF8000 +01FF8000 +ENDCHAR +STARTCHAR 0165 +ENCODING 357 +SWIDTH 400 0 +DWIDTH 20 0 +BBX 19 37 1 0 +BITMAP +0003E0 +0003E0 +0083E0 +0183E0 +0383E0 +0780E0 +0F8060 +0F80C0 +0F8180 +0F8300 +0F8000 +0F8000 +0F8000 +FFF800 +FFF800 +0F8000 +0F8000 +0F8000 +0F8000 +0F8000 +0F8000 +0F8000 +0F8000 +0F8000 +0F8000 +0F8000 +0F8000 +0F8000 +0F8000 +0F8000 +0F8000 +0F8000 +0F8000 +0F8000 +0FC000 +07F800 +00F800 +ENDCHAR +STARTCHAR 0166 +ENCODING 358 +SWIDTH 540 0 +DWIDTH 27 0 +BBX 25 36 1 0 +BITMAP +FFFFFF80 +FFFFFF80 +C03E0380 +C03E0380 +C03E0380 +003E0000 +003E0000 +003E0000 +003E0000 +003E0000 +003E0000 +003E0000 +003E0000 +003E0000 +003E0000 +003E0000 +003E0000 +0FFFF000 +0FFFF000 +003E0000 +003E0000 +003E0000 +003E0000 +003E0000 +003E0000 +003E0000 +003E0000 +003E0000 +003E0000 +003E0000 +003E0000 +003E0000 +003E0000 +003E0000 +01FF8000 +01FF8000 +ENDCHAR +STARTCHAR 0167 +ENCODING 359 +SWIDTH 320 0 +DWIDTH 16 0 +BBX 13 35 1 0 +BITMAP +0080 +0180 +0380 +0780 +0F80 +0F80 +0F80 +0F80 +0F80 +0F80 +0F80 +FFF8 +3FF8 +0F80 +0F80 +0F80 +0F80 +0F80 +0F80 +FFF8 +FFF8 +0F80 +0F80 +0F80 +0F80 +0F80 +0F80 +0F80 +0F80 +0F80 +0F80 +0F80 +0FC0 +07F8 +00F8 +ENDCHAR +STARTCHAR 0168 +ENCODING 360 +SWIDTH 700 0 +DWIDTH 35 0 +BBX 34 47 1 -1 +BITMAP +000C000000 +001E010000 +003F810000 +003FC30000 +0033E60000 +0060FE0000 +00407C0000 +0040380000 +0000000000 +0000000000 +FFC001FFC0 +FFC001FFC0 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F80003E00 +0F80007C00 +0F80007C00 +0F80007C00 +07C0007800 +07C000F800 +03E000F800 +03E001F000 +01F003E000 +00FC0FC000 +003FFF8000 +0007FC0000 +ENDCHAR +STARTCHAR 0169 +ENCODING 361 +SWIDTH 580 0 +DWIDTH 29 0 +BBX 27 36 1 -1 +BITMAP +00600000 +00F00800 +01FC0800 +01FE1800 +019F3000 +0307F000 +0203E000 +0201C000 +00000000 +00000000 +00000000 +FF00FF00 +FF00FF00 +1F001F00 +1F001F00 +1F001F00 +1F001F00 +1F001F00 +1F001F00 +1F001F00 +1F001F00 +1F001F00 +1F001F00 +1F001F00 +1F001F00 +1F001F00 +1F001F00 +1F001F00 +1F001F00 +1F001F00 +0F801F00 +0F803F00 +07C07F00 +03E0FF00 +01FFDFE0 +007F0000 +ENDCHAR +STARTCHAR 016A +ENCODING 362 +SWIDTH 560 0 +DWIDTH 28 0 +BBX 34 41 1 -1 +BITMAP +007FFF8000 +007FFF8000 +0000000000 +0000000000 +FFC001FFC0 +FFC001FFC0 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F80003E00 +0F80007C00 +0F80007C00 +0F80007C00 +07C0007800 +07C000F800 +03E000F800 +03E001F000 +01F003E000 +00FC0FC000 +003FFF8000 +0007FC0000 +ENDCHAR +STARTCHAR 016B +ENCODING 363 +SWIDTH 560 0 +DWIDTH 28 0 +BBX 27 30 1 -1 +BITMAP +07FFF800 +07FFF800 +00000000 +00000000 +00000000 +FF00FF00 +FF00FF00 +1F001F00 +1F001F00 +1F001F00 +1F001F00 +1F001F00 +1F001F00 +1F001F00 +1F001F00 +1F001F00 +1F001F00 +1F001F00 +1F001F00 +1F001F00 +1F001F00 +1F001F00 +1F001F00 +1F001F00 +0F801F00 +0F803F00 +07C07F00 +03E0FF00 +01FFDFE0 +007F0000 +ENDCHAR +STARTCHAR 016C +ENCODING 364 +SWIDTH 700 0 +DWIDTH 35 0 +BBX 34 44 1 -1 +BITMAP +00F80F8000 +00F80F0000 +007C3E0000 +001FFC0000 +0007F00000 +0000000000 +0000000000 +FFC001FFC0 +FFC001FFC0 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F80003E00 +0F80007C00 +0F80007C00 +0F80007C00 +07C0007800 +07C000F800 +03E000F800 +03E001F000 +01F003E000 +00FC0FC000 +003FFF8000 +0007FC0000 +ENDCHAR +STARTCHAR 016D +ENCODING 365 +SWIDTH 560 0 +DWIDTH 28 0 +BBX 27 32 1 -1 +BITMAP +0F80F800 +0F80F000 +07C3E000 +01FFC000 +007F0000 +00000000 +00000000 +FF00FF00 +FF00FF00 +1F001F00 +1F001F00 +1F001F00 +1F001F00 +1F001F00 +1F001F00 +1F001F00 +1F001F00 +1F001F00 +1F001F00 +1F001F00 +1F001F00 +1F001F00 +1F001F00 +1F001F00 +1F001F00 +1F001F00 +0F801F00 +0F803F00 +07C07F00 +03E0FF00 +01FFDFE0 +007F0000 +ENDCHAR +STARTCHAR 016E +ENCODING 366 +SWIDTH 700 0 +DWIDTH 35 0 +BBX 34 46 1 -1 +BITMAP +0003C00000 +0007F00000 +0006300000 +000C180000 +000C180000 +000C180000 +000C180000 +0006300000 +0007F00000 +FFC1C1FFC0 +FFC001FFC0 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F80003E00 +0F80007C00 +0F80007C00 +0F80007C00 +07C0007800 +07C000F800 +03E000F800 +03E001F000 +01F003E000 +00FC0FC000 +003FFF8000 +0007FC0000 +ENDCHAR +STARTCHAR 016F +ENCODING 367 +SWIDTH 560 0 +DWIDTH 28 0 +BBX 27 37 1 -1 +BITMAP +003C0000 +007F0000 +00630000 +00C18000 +00C18000 +00C18000 +00C18000 +00630000 +007F0000 +001C0000 +00000000 +00000000 +FF00FF00 +FF00FF00 +1F001F00 +1F001F00 +1F001F00 +1F001F00 +1F001F00 +1F001F00 +1F001F00 +1F001F00 +1F001F00 +1F001F00 +1F001F00 +1F001F00 +1F001F00 +1F001F00 +1F001F00 +1F001F00 +1F001F00 +0F801F00 +0F803F00 +07C07F00 +03E0FF00 +01FFDFE0 +007F0000 +ENDCHAR +STARTCHAR 0170 +ENCODING 368 +SWIDTH 700 0 +DWIDTH 35 0 +BBX 34 46 1 -1 +BITMAP +0007E3F000 +000FC7E000 +001F0F8000 +003C1E0000 +00783C0000 +01E0F00000 +0381C00000 +0000000000 +0000000000 +FFC001FFC0 +FFC001FFC0 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F80003E00 +0F80007C00 +0F80007C00 +0F80007C00 +07C0007800 +07C000F800 +03E000F800 +03E001F000 +01F003E000 +00FC0FC000 +003FFF8000 +0007FC0000 +ENDCHAR +STARTCHAR 0171 +ENCODING 369 +SWIDTH 560 0 +DWIDTH 28 0 +BBX 27 35 0 -1 +BITMAP +001F8FC0 +003F1F80 +007C3E00 +00F07800 +01E0F000 +0783C000 +0E070000 +00000000 +00000000 +00000000 +FF00FF00 +FF00FF00 +1F001F00 +1F001F00 +1F001F00 +1F001F00 +1F001F00 +1F001F00 +1F001F00 +1F001F00 +1F001F00 +1F001F00 +1F001F00 +1F001F00 +1F001F00 +1F001F00 +1F001F00 +1F001F00 +1F001F00 +0F801F00 +0F803F00 +07C07F00 +03E0FF00 +01FFDFE0 +007F0000 +ENDCHAR +STARTCHAR 0174 +ENCODING 372 +SWIDTH 860 0 +DWIDTH 43 0 +BBX 41 45 1 0 +BITMAP +00001C000000 +00003E000000 +00003F000000 +000077000000 +0000E3800000 +0000C1C00000 +000180C00000 +000000000000 +000000000000 +FFCFFFF83F80 +FFCFFFF83F80 +1F03F0C00C00 +1F81F0C01C00 +1F81F9C01800 +0F81F9801800 +0FC0F9803800 +0FC0FF803000 +07C0FF003000 +07E07F007000 +07E07F006000 +03E07F006000 +03F03E00E000 +03F03E00C000 +01F03F00C000 +01F83F01C000 +01F81F018000 +00F81F818000 +00FC1F818000 +00FC1F838000 +007C3FC30000 +007C3FC30000 +007E37C70000 +003E77E60000 +003E67E60000 +003F63EE0000 +003FE3FC0000 +001FC3FC0000 +001FC1FC0000 +001FC1F80000 +000FC1F80000 +000F80F80000 +000F80F00000 +000780F00000 +000700700000 +000700700000 +ENDCHAR +STARTCHAR 0175 +ENCODING 373 +SWIDTH 740 0 +DWIDTH 37 0 +BBX 35 34 1 0 +BITMAP +0000E00000 +0001F00000 +0001F80000 +0003B80000 +00071C0000 +00060E0000 +000C060000 +0000000000 +0000000000 +0000000000 +FFDFFF07E0 +FFDFFF07E0 +1F03EC0100 +0F03E80300 +0F83F80200 +0F81F00600 +07C1F00600 +07C0F80400 +07C0F80C00 +03E0F80800 +03E07C1800 +01F0FC1800 +01F0FE1000 +01F0BE3000 +00F9BE3000 +00F91F6000 +007D1F6000 +007F0FC000 +007E0FC000 +003E0FC000 +003E078000 +001C078000 +001C030000 +0018030000 +ENDCHAR +STARTCHAR 0176 +ENCODING 374 +SWIDTH 640 0 +DWIDTH 32 0 +BBX 29 45 1 0 +BITMAP +00038000 +0007C000 +0007E000 +000EE000 +001C7000 +00183800 +00301800 +00000000 +00000000 +FFC001F8 +FFC001F8 +1F0000C0 +0F8001C0 +0FC00180 +07C00300 +07E00700 +03E00600 +03F00E00 +01F00C00 +00F81800 +00F81800 +007C3000 +007C7000 +003E6000 +001FE000 +001FC000 +000F8000 +000F8000 +000F8000 +000F8000 +000F8000 +000F8000 +000F8000 +000F8000 +000F8000 +000F8000 +000F8000 +000F8000 +000F8000 +000F8000 +000F8000 +000F8000 +000F8000 +007FE000 +007FE000 +ENDCHAR +STARTCHAR 0177 +ENCODING 375 +SWIDTH 520 0 +DWIDTH 26 0 +BBX 23 46 1 -12 +BITMAP +001C00 +003E00 +003F00 +007700 +00E380 +00C1C0 +0180C0 +000000 +000000 +000000 +FFC07E +FFC07E +1F0018 +1F0010 +0F8030 +0F8030 +078020 +07C060 +07C060 +03E040 +03E0C0 +01E080 +01F180 +01F180 +00F900 +00FB00 +00FB00 +007E00 +007E00 +003C00 +003C00 +003C00 +001800 +001800 +001000 +003000 +003000 +002000 +006000 +006000 +004000 +00C000 +008000 +018000 +070000 +0E0000 +ENDCHAR +STARTCHAR 0178 +ENCODING 376 +SWIDTH 520 0 +DWIDTH 26 0 +BBX 29 45 1 1 +BITMAP +00F83E00 +00F83E00 +00F83E00 +00F83E00 +00F83E00 +00000000 +00000000 +00000000 +00000000 +FFC001F8 +FFC001F8 +1F0000C0 +0F8001C0 +0FC00180 +07C00300 +07E00700 +03E00600 +03F00E00 +01F00C00 +00F81800 +00F81800 +007C3000 +007C7000 +003E6000 +001FE000 +001FC000 +000F8000 +000F8000 +000F8000 +000F8000 +000F8000 +000F8000 +000F8000 +000F8000 +000F8000 +000F8000 +000F8000 +000F8000 +000F8000 +000F8000 +000F8000 +000F8000 +000F8000 +007FE000 +007FE000 +ENDCHAR +STARTCHAR 0179 +ENCODING 377 +SWIDTH 580 0 +DWIDTH 29 0 +BBX 26 46 1 0 +BITMAP +0001F000 +0003E000 +0003C000 +0007C000 +00078000 +000F0000 +001E0000 +00060000 +00000000 +00000000 +7FFFFFC0 +7FFFFF80 +60001F80 +60001F00 +60003F00 +00003E00 +00007C00 +0000FC00 +0000F800 +0001F800 +0001F000 +0003F000 +0007E000 +0007C000 +000FC000 +000F8000 +001F8000 +001F0000 +003E0000 +007E0000 +007C0000 +00FC0000 +00F80000 +01F80000 +03F00000 +03E00000 +07E00000 +07C00000 +0FC00000 +0F800000 +1F000000 +3F0000C0 +3E0000C0 +7E0000C0 +7FFFFFC0 +FFFFFFC0 +ENDCHAR +STARTCHAR 017A +ENCODING 378 +SWIDTH 480 0 +DWIDTH 24 0 +BBX 21 34 2 0 +BITMAP +003E00 +007C00 +007800 +00F800 +00F000 +01E000 +03C000 +00C000 +000000 +000000 +FFFFF8 +FFFFF0 +C001E0 +C003E0 +C007C0 +000780 +000F80 +001F00 +003E00 +003C00 +007C00 +00F800 +00F000 +01F000 +03E000 +03C000 +07C000 +0F8000 +1F0000 +1E0008 +3E0008 +7C0008 +7FFFF8 +FFFFF8 +ENDCHAR +STARTCHAR 017B +ENCODING 379 +SWIDTH 580 0 +DWIDTH 29 0 +BBX 26 43 1 0 +BITMAP +003E0000 +003E0000 +003E0000 +003E0000 +003E0000 +00000000 +00000000 +7FFFFFC0 +7FFFFF80 +60001F80 +60001F00 +60003F00 +00003E00 +00007C00 +0000FC00 +0000F800 +0001F800 +0001F000 +0003F000 +0007E000 +0007C000 +000FC000 +000F8000 +001F8000 +001F0000 +003E0000 +007E0000 +007C0000 +00FC0000 +00F80000 +01F80000 +03F00000 +03E00000 +07E00000 +07C00000 +0FC00000 +0F800000 +1F000000 +3F0000C0 +3E0000C0 +7E0000C0 +7FFFFFC0 +FFFFFFC0 +ENDCHAR +STARTCHAR 017C +ENCODING 380 +SWIDTH 480 0 +DWIDTH 24 0 +BBX 21 32 1 0 +BITMAP +01F000 +01F000 +01F000 +01F000 +01F000 +000000 +000000 +000000 +FFFFF8 +FFFFF0 +C001E0 +C003E0 +C007C0 +000780 +000F80 +001F00 +003E00 +003C00 +007C00 +00F800 +00F000 +01F000 +03E000 +03C000 +07C000 +0F8000 +1F0000 +1E0008 +3E0008 +7C0008 +7FFFF8 +FFFFF8 +ENDCHAR +STARTCHAR 017D +ENCODING 381 +SWIDTH 520 0 +DWIDTH 26 0 +BBX 26 45 1 1 +BITMAP +00E03000 +00706000 +0038C000 +001DC000 +000F8000 +000F0000 +00000000 +00000000 +00000000 +7FFFFFC0 +7FFFFF80 +60001F80 +60001F00 +60003F00 +00003E00 +00007C00 +0000FC00 +0000F800 +0001F800 +0001F000 +0003F000 +0007E000 +0007C000 +000FC000 +000F8000 +001F8000 +001F0000 +003E0000 +007E0000 +007C0000 +00FC0000 +00F80000 +01F80000 +03F00000 +03E00000 +07E00000 +07C00000 +0FC00000 +0F800000 +1F000000 +3F0000C0 +3E0000C0 +7E0000C0 +7FFFFFC0 +FFFFFFC0 +ENDCHAR +STARTCHAR 017E +ENCODING 382 +SWIDTH 440 0 +DWIDTH 22 0 +BBX 21 33 2 1 +BITMAP +1C0600 +0E0C00 +071800 +03B800 +01F000 +01E000 +000000 +000000 +000000 +FFFFF8 +FFFFF0 +C001E0 +C003E0 +C007C0 +000780 +000F80 +001F00 +003E00 +003C00 +007C00 +00F800 +00F000 +01F000 +03E000 +03C000 +07C000 +0F8000 +1F0000 +1E0008 +3E0008 +7C0008 +7FFFF8 +FFFFF8 +ENDCHAR +STARTCHAR 0192 +ENCODING 402 +SWIDTH 480 0 +DWIDTH 24 0 +BBX 21 43 2 -7 +BITMAP +000FF0 +001FF8 +003E00 +003E00 +007C00 +007C00 +007C00 +007C00 +00FC00 +00F800 +00F800 +00F800 +07FF00 +07FF00 +01F800 +01F800 +01F000 +01F000 +01F000 +01F000 +03F000 +03E000 +03E000 +03E000 +03E000 +03E000 +03E000 +07C000 +07C000 +07C000 +07C000 +07C000 +07C000 +0F8000 +0F8000 +0F8000 +0F8000 +1F0000 +1F0000 +3E0000 +3E0000 +FC0000 +F00000 +ENDCHAR +STARTCHAR 01CD +ENCODING 461 +SWIDTH 620 0 +DWIDTH 31 0 +BBX 29 45 1 0 +BITMAP +00E03000 +00706000 +0038C000 +001DC000 +000F8000 +000F0000 +00000000 +00000000 +00000000 +00060000 +000F0000 +000F0000 +000F0000 +000F8000 +001F8000 +001F8000 +001FC000 +003FC000 +0037C000 +0037E000 +0077E000 +0063E000 +0063F000 +00E3F000 +00C1F000 +00C1F800 +01C1F800 +0180F800 +0180FC00 +0180FC00 +03807C00 +03FFFC00 +03FFFE00 +07007E00 +06003E00 +06003F00 +0E003F00 +0C001F00 +0C001F80 +1C001F80 +18000F80 +18000FC0 +38000FC0 +FE001FF8 +FE001FF8 +ENDCHAR +STARTCHAR 01CE +ENCODING 462 +SWIDTH 520 0 +DWIDTH 26 0 +BBX 23 34 1 -1 +BITMAP +070180 +038300 +01C600 +00EE00 +007C00 +007800 +000000 +000000 +000000 +03FE00 +1FFF80 +3C0FC0 +3807E0 +3003E0 +3001F0 +2001F0 +0001F0 +0001F0 +0001F0 +0003F0 +001DF0 +03E1F0 +1F01F0 +3C01F0 +7C01F0 +F801F0 +F801F0 +F803F0 +F803F0 +F807F0 +FC0DF0 +7E39F8 +3FF0FE +0FC000 +ENDCHAR +STARTCHAR 01CF +ENCODING 463 +SWIDTH 300 0 +DWIDTH 15 0 +BBX 12 45 1 0 +BITMAP +E030 +7060 +38C0 +1DC0 +0F80 +0F00 +0000 +0000 +0000 +FFE0 +FFE0 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +FFE0 +FFE0 +ENDCHAR +STARTCHAR 01D0 +ENCODING 464 +SWIDTH 260 0 +DWIDTH 13 0 +BBX 12 33 1 0 +BITMAP +E030 +7060 +38C0 +1DC0 +0F80 +0F00 +0000 +0000 +0000 +FF00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +FFC0 +FFC0 +ENDCHAR +STARTCHAR 01D1 +ENCODING 465 +SWIDTH 600 0 +DWIDTH 30 0 +BBX 27 46 2 -1 +BITMAP +0380C000 +01C18000 +00E30000 +00770000 +003E0000 +003C0000 +00000000 +00000000 +00000000 +007F8000 +01FFF000 +07E0FC00 +0F807E00 +1F003F00 +1F001F00 +3E000F80 +7E000F80 +7C000FC0 +7C0007C0 +FC0007C0 +FC0007E0 +FC0007E0 +FC0007E0 +F80007E0 +F80003E0 +F80003E0 +F80003E0 +F80003E0 +F80003E0 +F80003E0 +F80003E0 +F80007E0 +F80007E0 +FC0007E0 +FC0007E0 +FC0007C0 +7C0007C0 +7C000FC0 +7E000F80 +3E000F80 +1F001F00 +1F003F00 +0F807E00 +07E0FC00 +01FFF000 +007FC000 +ENDCHAR +STARTCHAR 01D2 +ENCODING 466 +SWIDTH 500 0 +DWIDTH 25 0 +BBX 22 34 2 -1 +BITMAP +070180 +038300 +01C600 +00EE00 +007C00 +007800 +000000 +000000 +000000 +01FE00 +07FF80 +1F87E0 +3F03F0 +3E01F0 +7C00F8 +7C00F8 +7C00F8 +F8007C +F8007C +F8007C +F8007C +F8007C +F8007C +F8007C +F8007C +F8007C +7C00F8 +7C00F8 +7C00F8 +3E01F0 +3F03F0 +1F87E0 +0FFFC0 +01FE00 +ENDCHAR +STARTCHAR 01D3 +ENCODING 467 +SWIDTH 700 0 +DWIDTH 35 0 +BBX 34 46 1 -1 +BITMAP +00380C0000 +001C180000 +000E300000 +0007700000 +0003E00000 +0003C00000 +0000000000 +0000000000 +0000000000 +FFC001FFC0 +FFC001FFC0 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F80003E00 +0F80007C00 +0F80007C00 +0F80007C00 +07C0007800 +07C000F800 +03E000F800 +03E001F000 +01F003E000 +00FC0FC000 +003FFF8000 +0007FC0000 +ENDCHAR +STARTCHAR 01D4 +ENCODING 468 +SWIDTH 580 0 +DWIDTH 29 0 +BBX 27 34 1 -1 +BITMAP +01C06000 +00E0C000 +00718000 +003B8000 +001F0000 +001E0000 +00000000 +00000000 +00000000 +FF00FF00 +FF00FF00 +1F001F00 +1F001F00 +1F001F00 +1F001F00 +1F001F00 +1F001F00 +1F001F00 +1F001F00 +1F001F00 +1F001F00 +1F001F00 +1F001F00 +1F001F00 +1F001F00 +1F001F00 +1F001F00 +1F001F00 +0F801F00 +0F803F00 +07C07F00 +03E0FF00 +01FFDFE0 +007F0000 +ENDCHAR +STARTCHAR 01D5 +ENCODING 469 +SWIDTH 700 0 +DWIDTH 35 0 +BBX 34 48 1 -1 +BITMAP +007FFF8000 +007FFF8000 +0000000000 +007C1F0000 +007C1F0000 +007C1F0000 +007C1F0000 +007C1F0000 +0000000000 +0000000000 +0000000000 +FFC001FFC0 +FFC001FFC0 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F80003E00 +0F80007C00 +0F80007C00 +0F80007C00 +07C0007800 +07C000F800 +03E000F800 +03E001F000 +01F003E000 +00FC0FC000 +003FFF8000 +0007FC0000 +ENDCHAR +STARTCHAR 01D6 +ENCODING 470 +SWIDTH 560 0 +DWIDTH 28 0 +BBX 27 37 1 -1 +BITMAP +07FFF800 +07FFF800 +00000000 +00000000 +07C1F000 +07C1F000 +07C1F000 +07C1F000 +07C1F000 +00000000 +00000000 +00000000 +FF00FF00 +FF00FF00 +1F001F00 +1F001F00 +1F001F00 +1F001F00 +1F001F00 +1F001F00 +1F001F00 +1F001F00 +1F001F00 +1F001F00 +1F001F00 +1F001F00 +1F001F00 +1F001F00 +1F001F00 +1F001F00 +1F001F00 +0F801F00 +0F803F00 +07C07F00 +03E0FF00 +01FFDFE0 +007F0000 +ENDCHAR +STARTCHAR 01D7 +ENCODING 471 +SWIDTH 700 0 +DWIDTH 35 0 +BBX 34 53 1 -1 +BITMAP +00003E0000 +00007C0000 +0000780000 +0000F80000 +0000F00000 +0001E00000 +0003C00000 +0000C00000 +003E0F8000 +003E0F8000 +003E0F8000 +003E0F8000 +003E0F8000 +0000000000 +0000000000 +0000000000 +FFC001FFC0 +FFC001FFC0 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F80003E00 +0F80007C00 +0F80007C00 +0F80007C00 +07C0007800 +07C000F800 +03E000F800 +03E001F000 +01F003E000 +00FC0FC000 +003FFF8000 +0007FC0000 +ENDCHAR +STARTCHAR 01D8 +ENCODING 472 +SWIDTH 560 0 +DWIDTH 28 0 +BBX 27 42 1 -1 +BITMAP +0007C000 +000F8000 +000F0000 +001F0000 +001E0000 +003C0000 +00780000 +00180000 +00000000 +07C1F000 +07C1F000 +07C1F000 +07C1F000 +07C1F000 +00000000 +00000000 +00000000 +FF00FF00 +FF00FF00 +1F001F00 +1F001F00 +1F001F00 +1F001F00 +1F001F00 +1F001F00 +1F001F00 +1F001F00 +1F001F00 +1F001F00 +1F001F00 +1F001F00 +1F001F00 +1F001F00 +1F001F00 +1F001F00 +1F001F00 +0F801F00 +0F803F00 +07C07F00 +03E0FF00 +01FFDFE0 +007F0000 +ENDCHAR +STARTCHAR 01D9 +ENCODING 473 +SWIDTH 700 0 +DWIDTH 35 0 +BBX 34 51 1 -1 +BITMAP +00380C0000 +001C180000 +000E300000 +0007700000 +0003E00000 +0003C00000 +0000000000 +007C1F0000 +007C1F0000 +007C1F0000 +007C1F0000 +007C1F0000 +0000000000 +0000000000 +FFC001FFC0 +FFC001FFC0 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F80003E00 +0F80007C00 +0F80007C00 +0F80007C00 +07C0007800 +07C000F800 +03E000F800 +03E001F000 +01F003E000 +00FC0FC000 +003FFF8000 +0007FC0000 +ENDCHAR +STARTCHAR 01DA +ENCODING 474 +SWIDTH 560 0 +DWIDTH 28 0 +BBX 27 41 0 -1 +BITMAP +01C06000 +00E0C000 +00718000 +003B8000 +001F0000 +001E0000 +00000000 +00000000 +03E0F800 +03E0F800 +03E0F800 +03E0F800 +03E0F800 +00000000 +00000000 +00000000 +FF00FF00 +FF00FF00 +1F001F00 +1F001F00 +1F001F00 +1F001F00 +1F001F00 +1F001F00 +1F001F00 +1F001F00 +1F001F00 +1F001F00 +1F001F00 +1F001F00 +1F001F00 +1F001F00 +1F001F00 +1F001F00 +1F001F00 +0F801F00 +0F803F00 +07C07F00 +03E0FF00 +01FFDFE0 +007F0000 +ENDCHAR +STARTCHAR 01DB +ENCODING 475 +SWIDTH 700 0 +DWIDTH 35 0 +BBX 34 54 1 -1 +BITMAP +007C000000 +003E000000 +001E000000 +001F000000 +000F000000 +0007800000 +0003800000 +0003000000 +0000000000 +00F83E0000 +00F83E0000 +00F83E0000 +00F83E0000 +00F83E0000 +0000000000 +0000000000 +0000000000 +FFC001FFC0 +FFC001FFC0 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F80003E00 +0F80007C00 +0F80007C00 +0F80007C00 +07C0007800 +07C000F800 +03E000F800 +03E001F000 +01F003E000 +00FC0FC000 +003FFF8000 +0007FC0000 +ENDCHAR +STARTCHAR 01DC +ENCODING 476 +SWIDTH 560 0 +DWIDTH 28 0 +BBX 27 43 1 -1 +BITMAP +01F00000 +00F80000 +00780000 +007C0000 +003C0000 +001E0000 +000E0000 +000C0000 +00000000 +00000000 +07C1F000 +07C1F000 +07C1F000 +07C1F000 +07C1F000 +00000000 +00000000 +00000000 +FF00FF00 +FF00FF00 +1F001F00 +1F001F00 +1F001F00 +1F001F00 +1F001F00 +1F001F00 +1F001F00 +1F001F00 +1F001F00 +1F001F00 +1F001F00 +1F001F00 +1F001F00 +1F001F00 +1F001F00 +1F001F00 +1F001F00 +0F801F00 +0F803F00 +07C07F00 +03E0FF00 +01FFDFE0 +007F0000 +ENDCHAR +STARTCHAR 01E2 +ENCODING 482 +SWIDTH 920 0 +DWIDTH 46 0 +BBX 45 40 0 0 +BITMAP +0000001FFFE0 +0000001FFFE0 +000000000000 +000000000000 +000007FFFFF8 +000007FFFFF8 +000003F80018 +000002F80018 +000006F80018 +00000CF80000 +000008F80000 +000018F80000 +000030F80000 +000030F80000 +000060F80000 +000040F80000 +0000C0F80000 +000180F80000 +000180F80300 +000300F80300 +000200F80300 +000600FFFF00 +000C00FFFF00 +000C00F80300 +001800F80300 +003FFFF80300 +003FFFF80000 +007000F80000 +006000F80000 +00C000F80000 +01C000F80000 +018000F80000 +030000F80000 +030000F80000 +060000F80000 +0C0000F80018 +0C0000F80018 +180000F80018 +FC0007FFFFF8 +FC0007FFFFF8 +ENDCHAR +STARTCHAR 01E3 +ENCODING 483 +SWIDTH 780 0 +DWIDTH 39 0 +BBX 37 30 1 -1 +BITMAP +003FFFC000 +003FFFC000 +0000000000 +0000000000 +0000000000 +01FE01FC00 +1FFFC7FF00 +1E07FF07C0 +1C03FE03C0 +1801FC01E0 +1800FC01F0 +1000F800F0 +0000F800F0 +0000F800F8 +0000FFFFF8 +0003FFFFF8 +001CF80000 +03E0F80000 +1E00F80000 +3C00F80000 +7800F80000 +F800F80000 +F800FC0000 +F801FC0008 +F803FC0018 +F8073E0030 +FC0E1F0070 +7E3C0FE3C0 +3FF807FF80 +0FC000FE00 +ENDCHAR +STARTCHAR 01E6 +ENCODING 486 +SWIDTH 620 0 +DWIDTH 31 0 +BBX 29 46 2 -1 +BITMAP +01C06000 +00E0C000 +00718000 +003B8000 +001F0000 +001E0000 +00000000 +00000000 +00000000 +007F8000 +03FFF000 +07E07C00 +0F801E00 +1F000F00 +3F000700 +3E000700 +7E000300 +7C000300 +7C000300 +7C000300 +FC000000 +F8000000 +F8000000 +F8000000 +F8000000 +F8000000 +F8000000 +F8000000 +F8000000 +F800FFF8 +F800FFF8 +F80007C0 +F80007C0 +F80007C0 +7C0007C0 +7C0007C0 +7C0007C0 +7C0007C0 +3E000FC0 +3E000F80 +1F000F80 +1F801F00 +0FC03E00 +07E07C00 +01FFF000 +007FC000 +ENDCHAR +STARTCHAR 01E7 +ENCODING 487 +SWIDTH 480 0 +DWIDTH 24 0 +BBX 24 45 0 -12 +BITMAP +0380C0 +01C180 +00E300 +007700 +003E00 +003C00 +000000 +000000 +000000 +003FFF +01FFFF +03E1F0 +07C0F8 +0F807C +0F807C +1F003C +1F003E +1F003E +1F003E +1F003E +1F003E +1F003C +0F807C +0F807C +07C0F8 +03E1F0 +01FFC0 +003F80 +000700 +00FC00 +03E000 +07C000 +03F000 +00EF80 +0780F0 +1E003C +3C003E +78001F +F8001F +F8001F +F8001F +FC003E +7E00FE +3FFFF8 +07FFC0 +ENDCHAR +STARTCHAR 01FC +ENCODING 508 +SWIDTH 920 0 +DWIDTH 46 0 +BBX 45 46 0 0 +BITMAP +000000007C00 +00000000F800 +00000000F000 +00000001F000 +00000001E000 +00000003C000 +000000078000 +000000018000 +000000000000 +000000000000 +000007FFFFF8 +000007FFFFF8 +000003F80018 +000002F80018 +000006F80018 +00000CF80000 +000008F80000 +000018F80000 +000030F80000 +000030F80000 +000060F80000 +000040F80000 +0000C0F80000 +000180F80000 +000180F80300 +000300F80300 +000200F80300 +000600FFFF00 +000C00FFFF00 +000C00F80300 +001800F80300 +003FFFF80300 +003FFFF80000 +007000F80000 +006000F80000 +00C000F80000 +01C000F80000 +018000F80000 +030000F80000 +030000F80000 +060000F80000 +0C0000F80018 +0C0000F80018 +180000F80018 +FC0007FFFFF8 +FC0007FFFFF8 +ENDCHAR +STARTCHAR 01FD +ENCODING 509 +SWIDTH 780 0 +DWIDTH 39 0 +BBX 37 35 1 -1 +BITMAP +00003E0000 +00007C0000 +0000780000 +0000F80000 +0000F00000 +0001E00000 +0003C00000 +0000C00000 +0000000000 +0000000000 +01FE01FC00 +1FFFC7FF00 +1E07FF07C0 +1C03FE03C0 +1801FC01E0 +1800FC01F0 +1000F800F0 +0000F800F0 +0000F800F8 +0000FFFFF8 +0003FFFFF8 +001CF80000 +03E0F80000 +1E00F80000 +3C00F80000 +7800F80000 +F800F80000 +F800FC0000 +F801FC0008 +F803FC0018 +F8073E0030 +FC0E1F0070 +7E3C0FE3C0 +3FF807FF80 +0FC000FE00 +ENDCHAR +STARTCHAR 01FE +ENCODING 510 +SWIDTH 640 0 +DWIDTH 32 0 +BBX 29 47 1 -1 +BITMAP +0001F000 +0003E000 +0003C000 +0007C000 +00078000 +000F0000 +001E0000 +00060000 +00000000 +00000000 +003FF818 +00FFFC38 +03F07F30 +07C01FE0 +0F800FE0 +1F800FC0 +1F0007C0 +1F0007C0 +3E0007E0 +3E0007E0 +3E000FE0 +7E0019E0 +7C0031F0 +7C0061F0 +7C0041F0 +7C00C1F0 +7C0181F0 +7C0301F0 +7C0601F0 +7C0401F0 +7C0801F0 +7C1801F0 +7C3001F0 +7C6001F0 +7C4001F0 +7C8001F0 +3F8003E0 +3F0003E0 +3E0003E0 +3F0003C0 +1F0007C0 +1F8007C0 +3F800F80 +67C01F00 +C3F07E00 +C1FFFC00 +003FE000 +ENDCHAR +STARTCHAR 01FF +ENCODING 511 +SWIDTH 500 0 +DWIDTH 25 0 +BBX 22 35 2 -1 +BITMAP +001F00 +003E00 +003C00 +007C00 +007800 +00F000 +01E000 +006000 +000000 +000000 +01FF8C +07FFDC +1F87F8 +3E01F0 +3E01F0 +7C00F8 +7C00F8 +7801F8 +F8037C +F8067C +F8047C +F8087C +F8107C +F8207C +F8407C +F8807C +F9807C +7B0078 +7E00F8 +7C00F8 +3C01F0 +3E01F0 +3F87E0 +47FFC0 +01FE00 +ENDCHAR +STARTCHAR 0200 +ENCODING 512 +SWIDTH 600 0 +DWIDTH 30 0 +BBX 29 46 1 0 +BITMAP +0007C000 +07C3E000 +03E1E000 +01E1F000 +01F0F000 +00F07800 +00783800 +00383000 +00300000 +00000000 +00060000 +000F0000 +000F0000 +000F0000 +000F8000 +001F8000 +001F8000 +001FC000 +003FC000 +0037C000 +0037E000 +0077E000 +0063E000 +0063F000 +00E3F000 +00C1F000 +00C1F800 +01C1F800 +0180F800 +0180FC00 +0180FC00 +03807C00 +03FFFC00 +03FFFE00 +07007E00 +06003E00 +06003F00 +0E003F00 +0C001F00 +0C001F80 +1C001F80 +18000F80 +18000FC0 +38000FC0 +FE001FF8 +FE001FF8 +ENDCHAR +STARTCHAR 0232 +ENCODING 562 +SWIDTH 660 0 +DWIDTH 33 0 +BBX 29 40 1 0 +BITMAP +01FFFE00 +01FFFE00 +00000000 +00000000 +FFC001F8 +FFC001F8 +1F0000C0 +0F8001C0 +0FC00180 +07C00300 +07E00700 +03E00600 +03F00E00 +01F00C00 +00F81800 +00F81800 +007C3000 +007C7000 +003E6000 +001FE000 +001FC000 +000F8000 +000F8000 +000F8000 +000F8000 +000F8000 +000F8000 +000F8000 +000F8000 +000F8000 +000F8000 +000F8000 +000F8000 +000F8000 +000F8000 +000F8000 +000F8000 +000F8000 +007FE000 +007FE000 +ENDCHAR +STARTCHAR 02C6 +ENCODING 710 +SWIDTH 380 0 +DWIDTH 19 0 +BBX 11 7 4 29 +BITMAP +0E00 +1F00 +1F80 +3B80 +71C0 +60E0 +C060 +ENDCHAR +STARTCHAR 02C7 +ENCODING 711 +SWIDTH 360 0 +DWIDTH 18 0 +BBX 12 6 3 29 +BITMAP +E030 +7060 +38C0 +1DC0 +0F80 +0F00 +ENDCHAR +STARTCHAR 02C9 +ENCODING 713 +SWIDTH 400 0 +DWIDTH 20 0 +BBX 16 2 2 34 +BITMAP +FFFF +FFFF +ENDCHAR +STARTCHAR 02D8 +ENCODING 728 +SWIDTH 420 0 +DWIDTH 21 0 +BBX 17 5 2 29 +BITMAP +F80F80 +F80F00 +7C3E00 +1FFC00 +07F000 +ENDCHAR +STARTCHAR 02DA +ENCODING 730 +SWIDTH 260 0 +DWIDTH 13 0 +BBX 9 10 2 25 +BITMAP +3C00 +7F00 +6300 +C180 +C180 +C180 +C180 +6300 +7F00 +1C00 +ENDCHAR +STARTCHAR 02DB +ENCODING 731 +SWIDTH 240 0 +DWIDTH 12 0 +BBX 8 9 2 -8 +BITMAP +F8 +F8 +F8 +F8 +F8 +7C +7C +3F +0F +ENDCHAR +STARTCHAR 02DC +ENCODING 732 +SWIDTH 380 0 +DWIDTH 19 0 +BBX 15 8 2 28 +BITMAP +1800 +3C02 +7F02 +7F86 +67CC +C1FC +80F8 +8070 +ENDCHAR +STARTCHAR 02DD +ENCODING 733 +SWIDTH 520 0 +DWIDTH 26 0 +BBX 22 7 2 28 +BITMAP +01F8FC +03F1F8 +07C3E0 +0F0780 +1E0F00 +783C00 +E07000 +ENDCHAR +STARTCHAR 037E +ENCODING 894 +SWIDTH 180 0 +DWIDTH 9 0 +BBX 5 29 2 -5 +BITMAP +F8 +F8 +F8 +F8 +F8 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +F8 +F8 +F8 +F8 +F8 +38 +18 +30 +60 +C0 +ENDCHAR +STARTCHAR 0386 +ENCODING 902 +SWIDTH 640 0 +DWIDTH 32 0 +BBX 29 39 1 0 +BITMAP +01F00000 +03E00000 +03C00000 +07C60000 +078F0000 +0F0F0000 +1E0F0000 +060F8000 +001F8000 +001F8000 +001FC000 +003FC000 +0037C000 +0037E000 +0077E000 +0063E000 +0063F000 +00E3F000 +00C1F000 +00C1F800 +01C1F800 +0180F800 +0180FC00 +0180FC00 +03807C00 +03FFFC00 +03FFFE00 +07007E00 +06003E00 +06003F00 +0E003F00 +0C001F00 +0C001F80 +1C001F80 +18000F80 +18000FC0 +38000FC0 +FE001FF8 +FE001FF8 +ENDCHAR +STARTCHAR 0388 +ENCODING 904 +SWIDTH 660 0 +DWIDTH 33 0 +BBX 30 41 1 0 +BITMAP +0F800000 +1F000000 +1E000000 +3E000000 +3C000000 +7BFFFFFC +F3FFFFFC +307C000C +007C000C +007C0000 +007C0000 +007C0000 +007C0000 +007C0000 +007C0000 +007C0000 +007C0000 +007C0000 +007C0000 +007C0180 +007C0180 +007C0180 +007FFF80 +007FFF80 +007C0180 +007C0180 +007C0180 +007C0000 +007C0000 +007C0000 +007C0000 +007C0000 +007C0000 +007C0000 +007C0000 +007C0000 +007C000C +007C000C +007C000C +03FFFFFC +03FFFFFC +ENDCHAR +STARTCHAR 0389 +ENCODING 905 +SWIDTH 740 0 +DWIDTH 37 0 +BBX 39 41 -2 0 +BITMAP +0F80000000 +1F00000000 +1E00000000 +3E00000000 +3C00000000 +78FFE007FE +F0FFE007FE +301F0001F0 +001F0001F0 +001F0001F0 +001F0001F0 +001F0001F0 +001F0001F0 +001F0001F0 +001F0001F0 +001F0001F0 +001F0001F0 +001F0001F0 +001F0001F0 +001F0001F0 +001F0001F0 +001F0001F0 +001FFFFFF0 +001FFFFFF0 +001F0001F0 +001F0001F0 +001F0001F0 +001F0001F0 +001F0001F0 +001F0001F0 +001F0001F0 +001F0001F0 +001F0001F0 +001F0001F0 +001F0001F0 +001F0001F0 +001F0001F0 +001F0001F0 +001F0001F0 +00FFE007FE +00FFE007FE +ENDCHAR +STARTCHAR 038A +ENCODING 906 +SWIDTH 340 0 +DWIDTH 17 0 +BBX 17 42 -2 0 +BITMAP +0F8000 +1F0000 +1E0000 +3E0000 +3C0000 +780000 +F3FF80 +33FF80 +007C00 +007C00 +007C00 +007C00 +007C00 +007C00 +007C00 +007C00 +007C00 +007C00 +007C00 +007C00 +007C00 +007C00 +007C00 +007C00 +007C00 +007C00 +007C00 +007C00 +007C00 +007C00 +007C00 +007C00 +007C00 +007C00 +007C00 +007C00 +007C00 +007C00 +007C00 +007C00 +03FF80 +03FF80 +ENDCHAR +STARTCHAR 038C +ENCODING 908 +SWIDTH 680 0 +DWIDTH 34 0 +BBX 32 40 0 -1 +BITMAP +0F800000 +1F000000 +1E000000 +3E03FC00 +3C0FFF80 +783F07E0 +F07C03F0 +30F801F8 +00F800F8 +01F0007C +03F0007C +03E0007E +03E0003E +07E0003E +07E0003F +07E0003F +07E0003F +07C0003F +07C0001F +07C0001F +07C0001F +07C0001F +07C0001F +07C0001F +07C0001F +07C0003F +07C0003F +07E0003F +07E0003F +07E0003E +03E0003E +03E0007E +03F0007C +01F0007C +00F800F8 +00F801F8 +007C03F0 +003F07E0 +000FFF80 +0003FE00 +ENDCHAR +STARTCHAR 038E +ENCODING 910 +SWIDTH 660 0 +DWIDTH 33 0 +BBX 37 42 -6 0 +BITMAP +0F80000000 +1F00000000 +1E00000000 +3E00000000 +3C00000000 +7800000000 +F0FFC001F8 +30FFC001F8 +001F0000C0 +000F8001C0 +000FC00180 +0007C00300 +0007E00700 +0003E00600 +0003F00E00 +0001F00C00 +0000F81800 +0000F81800 +00007C3000 +00007C7000 +00003E6000 +00001FE000 +00001FC000 +00000F8000 +00000F8000 +00000F8000 +00000F8000 +00000F8000 +00000F8000 +00000F8000 +00000F8000 +00000F8000 +00000F8000 +00000F8000 +00000F8000 +00000F8000 +00000F8000 +00000F8000 +00000F8000 +00000F8000 +00007FE000 +00007FE000 +ENDCHAR +STARTCHAR 038F +ENCODING 911 +SWIDTH 800 0 +DWIDTH 40 0 +BBX 36 40 1 0 +BITMAP +0F80000000 +1F00000000 +1E00000000 +3E003C0000 +3C07FFE000 +781FC3F800 +F07E007E00 +30FC003F00 +01F8001F80 +01F0000F80 +03E00007C0 +03E00007C0 +07C00003E0 +07C00003E0 +07C00003E0 +0F800001F0 +0F800001F0 +0F800001F0 +0F800001F0 +0F800001F0 +0F800001F0 +0F800001F0 +0F800001F0 +0F800001F0 +07C00001E0 +07C00003E0 +03C00003C0 +03E00007C0 +01F0000780 +00F0000F00 +0078001E00 +003C003C00 +000E007800 +0203006020 +0203006020 +0203006020 +03FF007FE0 +03FF007FE0 +03FF007FE0 +03FF007FE0 +ENDCHAR +STARTCHAR 0391 +ENCODING 913 +SWIDTH 640 0 +DWIDTH 32 0 +BBX 29 36 1 0 +BITMAP +00060000 +000F0000 +000F0000 +000F0000 +000F8000 +001F8000 +001F8000 +001FC000 +003FC000 +0037C000 +0037E000 +0077E000 +0063E000 +0063F000 +00E3F000 +00C1F000 +00C1F800 +01C1F800 +0180F800 +0180FC00 +0180FC00 +03807C00 +03FFFC00 +03FFFE00 +07007E00 +06003E00 +06003F00 +0E003F00 +0C001F00 +0C001F80 +1C001F80 +18000F80 +18000FC0 +38000FC0 +FE001FF8 +FE001FF8 +ENDCHAR +STARTCHAR 0392 +ENCODING 914 +SWIDTH 560 0 +DWIDTH 28 0 +BBX 26 36 1 0 +BITMAP +FFFFC000 +FFFFF000 +1F01F800 +1F007C00 +1F003E00 +1F003E00 +1F001F00 +1F001F00 +1F001F00 +1F001F00 +1F001F00 +1F001F00 +1F003E00 +1F003E00 +1F007C00 +1F01F800 +1FFFF000 +1FFFFC00 +1F007E00 +1F003F00 +1F001F80 +1F000F80 +1F000F80 +1F0007C0 +1F0007C0 +1F0007C0 +1F0007C0 +1F0007C0 +1F0007C0 +1F000F80 +1F000F80 +1F001F00 +1F003F00 +1F007E00 +FFFFF800 +FFFFE000 +ENDCHAR +STARTCHAR 0393 +ENCODING 915 +SWIDTH 540 0 +DWIDTH 27 0 +BBX 25 36 1 0 +BITMAP +FFFFFF80 +FFFFFF80 +1F000080 +1F000080 +1F000080 +1F000000 +1F000000 +1F000000 +1F000000 +1F000000 +1F000000 +1F000000 +1F000000 +1F000000 +1F000000 +1F000000 +1F000000 +1F000000 +1F000000 +1F000000 +1F000000 +1F000000 +1F000000 +1F000000 +1F000000 +1F000000 +1F000000 +1F000000 +1F000000 +1F000000 +1F000000 +1F000000 +1F000000 +1F000000 +FFE00000 +FFE00000 +ENDCHAR +STARTCHAR 0394 +ENCODING 916 +SWIDTH 540 0 +DWIDTH 27 0 +BBX 25 36 1 0 +BITMAP +000C0000 +000C0000 +001C0000 +001E0000 +001E0000 +003E0000 +003F0000 +003F0000 +006F0000 +004F8000 +004F8000 +00CF8000 +00878000 +0087C000 +0187C000 +0103C000 +0103E000 +0303E000 +0201E000 +0201F000 +0601F000 +0401F000 +0400F800 +0C00F800 +0800F800 +08007800 +18007C00 +10007C00 +10003C00 +30003E00 +20003E00 +20001E00 +60001F00 +40001F00 +7FFFFF00 +FFFFFF80 +ENDCHAR +STARTCHAR 0395 +ENCODING 917 +SWIDTH 520 0 +DWIDTH 26 0 +BBX 24 36 1 0 +BITMAP +FFFFFF +FFFFFF +1F0003 +1F0003 +1F0000 +1F0000 +1F0000 +1F0000 +1F0000 +1F0000 +1F0000 +1F0000 +1F0000 +1F0000 +1F0060 +1F0060 +1F0060 +1FFFE0 +1FFFE0 +1F0060 +1F0060 +1F0060 +1F0000 +1F0000 +1F0000 +1F0000 +1F0000 +1F0000 +1F0000 +1F0000 +1F0000 +1F0003 +1F0003 +1F0003 +FFFFFF +FFFFFF +ENDCHAR +STARTCHAR 0396 +ENCODING 918 +SWIDTH 560 0 +DWIDTH 28 0 +BBX 26 36 1 0 +BITMAP +7FFFFFC0 +7FFFFF80 +60001F80 +60001F00 +60003F00 +00003E00 +00007C00 +0000FC00 +0000F800 +0001F800 +0001F000 +0003F000 +0007E000 +0007C000 +000FC000 +000F8000 +001F8000 +001F0000 +003E0000 +007E0000 +007C0000 +00FC0000 +00F80000 +01F80000 +03F00000 +03E00000 +07E00000 +07C00000 +0FC00000 +0F800000 +1F000000 +3F0000C0 +3E0000C0 +7E0000C0 +7FFFFFC0 +FFFFFFC0 +ENDCHAR +STARTCHAR 0397 +ENCODING 919 +SWIDTH 640 0 +DWIDTH 32 0 +BBX 31 36 1 0 +BITMAP +FFE007FE +FFE007FE +1F0001F0 +1F0001F0 +1F0001F0 +1F0001F0 +1F0001F0 +1F0001F0 +1F0001F0 +1F0001F0 +1F0001F0 +1F0001F0 +1F0001F0 +1F0001F0 +1F0001F0 +1F0001F0 +1F0001F0 +1FFFFFF0 +1FFFFFF0 +1F0001F0 +1F0001F0 +1F0001F0 +1F0001F0 +1F0001F0 +1F0001F0 +1F0001F0 +1F0001F0 +1F0001F0 +1F0001F0 +1F0001F0 +1F0001F0 +1F0001F0 +1F0001F0 +1F0001F0 +FFE007FE +FFE007FE +ENDCHAR +STARTCHAR 0398 +ENCODING 920 +SWIDTH 620 0 +DWIDTH 31 0 +BBX 27 37 2 -1 +BITMAP +007FC000 +01FFF800 +07E0FC00 +0F803E00 +1F001F00 +3F001F80 +3E000F80 +3E000F80 +7C0007C0 +7C0007C0 +7C0007C0 +F80007C0 +F80003E0 +F80003E0 +F80003E0 +F80003E0 +F80003E0 +FFFFFFE0 +FFFFFFE0 +F80003E0 +F80003E0 +F80003E0 +F80003E0 +F80003E0 +F80003E0 +FC0007E0 +7C0007C0 +7C0007C0 +7C0007C0 +3E000F80 +3E000F80 +3F001F80 +1F001F00 +0F803E00 +07E0FC00 +03FFF800 +007FC000 +ENDCHAR +STARTCHAR 0399 +ENCODING 921 +SWIDTH 280 0 +DWIDTH 14 0 +BBX 11 36 1 0 +BITMAP +FFE0 +FFE0 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +1F00 +FFE0 +FFE0 +ENDCHAR +STARTCHAR 039A +ENCODING 922 +SWIDTH 660 0 +DWIDTH 33 0 +BBX 30 36 1 0 +BITMAP +FFE003F0 +FFE003F0 +1F000180 +1F000700 +1F000E00 +1F001C00 +1F003000 +1F006000 +1F00C000 +1F038000 +1F070000 +1F0E0000 +1F1C0000 +1F300000 +1F600000 +1FE00000 +1FF00000 +1FF80000 +1FFC0000 +1FFE0000 +1F7F0000 +1F3F8000 +1F1F8000 +1F1FC000 +1F0FE000 +1F07F000 +1F03F800 +1F01FC00 +1F00FE00 +1F007F00 +1F003F80 +1F001FC0 +1F000FC0 +1F000FE0 +FFE00FFC +FFE00FFC +ENDCHAR +STARTCHAR 039B +ENCODING 923 +SWIDTH 620 0 +DWIDTH 31 0 +BBX 29 36 1 0 +BITMAP +00030000 +00070000 +00070000 +00078000 +000F8000 +000F8000 +000FC000 +001FC000 +001FC000 +0013C000 +0033E000 +0033E000 +0021E000 +0061F000 +0061F000 +0040F000 +00C0F800 +00C0F800 +0080F800 +01807C00 +01807C00 +01007C00 +03003E00 +03003E00 +02003E00 +06001E00 +06001F00 +04001F00 +0C000F00 +0C000F80 +08000F80 +18000F80 +180007C0 +100007C0 +FC001FF8 +FC001FF8 +ENDCHAR +STARTCHAR 039C +ENCODING 924 +SWIDTH 760 0 +DWIDTH 38 0 +BBX 35 36 1 0 +BITMAP +FF80003FE0 +FF80003FE0 +1F80003F00 +1FC0007F00 +1FC0007F00 +1FC0007F00 +1FE000FF00 +1FE000FF00 +1BE000FF00 +1BF001DF00 +1BF001DF00 +19F001DF00 +19F8039F00 +19F8039F00 +18F8039F00 +18FC071F00 +18FC071F00 +187C071F00 +187E0E1F00 +187E0E1F00 +183E0E1F00 +183F1C1F00 +183F1C1F00 +181F1C1F00 +181FB81F00 +181FB81F00 +180FB01F00 +180FF01F00 +180FF01F00 +1807E01F00 +1807E01F00 +1807E01F00 +1803C01F00 +1803C01F00 +FF03C07FE0 +FF01807FE0 +ENDCHAR +STARTCHAR 039D +ENCODING 925 +SWIDTH 620 0 +DWIDTH 31 0 +BBX 29 36 1 0 +BITMAP +FF8007F8 +FF8007F8 +1FC000C0 +1FC000C0 +1FE000C0 +1BF000C0 +1BF000C0 +19F800C0 +19F800C0 +18FC00C0 +187E00C0 +187E00C0 +183F00C0 +183F00C0 +181F80C0 +180FC0C0 +180FC0C0 +1807E0C0 +1807E0C0 +1803F0C0 +1801F8C0 +1801F8C0 +1800FCC0 +1800FEC0 +18007EC0 +18003FC0 +18003FC0 +18001FC0 +18001FC0 +18000FC0 +180007C0 +180007C0 +180003C0 +180003C0 +FE0001C0 +FE0000C0 +ENDCHAR +STARTCHAR 039E +ENCODING 926 +SWIDTH 420 0 +DWIDTH 21 0 +BBX 20 36 0 0 +BITMAP +FFFFF0 +FFFFF0 +000000 +000000 +000000 +000000 +000000 +000000 +000000 +000000 +000000 +000000 +000000 +000000 +000000 +000000 +000000 +1FFFC0 +1FFFC0 +000000 +000000 +000000 +000000 +000000 +000000 +000000 +000000 +000000 +000000 +000000 +000000 +000000 +000000 +000000 +FFFFF0 +FFFFF0 +ENDCHAR +STARTCHAR 039F +ENCODING 927 +SWIDTH 600 0 +DWIDTH 30 0 +BBX 27 37 2 -1 +BITMAP +007F8000 +01FFF000 +07E0FC00 +0F807E00 +1F003F00 +1F001F00 +3E000F80 +7E000F80 +7C000FC0 +7C0007C0 +FC0007C0 +FC0007E0 +FC0007E0 +FC0007E0 +F80007E0 +F80003E0 +F80003E0 +F80003E0 +F80003E0 +F80003E0 +F80003E0 +F80003E0 +F80007E0 +F80007E0 +FC0007E0 +FC0007E0 +FC0007C0 +7C0007C0 +7C000FC0 +7E000F80 +3E000F80 +1F001F00 +1F003F00 +0F807E00 +07E0FC00 +01FFF000 +007FC000 +ENDCHAR +STARTCHAR 03A0 +ENCODING 928 +SWIDTH 600 0 +DWIDTH 30 0 +BBX 26 36 2 0 +BITMAP +FFFFFFC0 +FFFFFFC0 +1F003E00 +1F003E00 +1F003E00 +1F003E00 +1F003E00 +1F003E00 +1F003E00 +1F003E00 +1F003E00 +1F003E00 +1F003E00 +1F003E00 +1F003E00 +1F003E00 +1F003E00 +1F003E00 +1F003E00 +1F003E00 +1F003E00 +1F003E00 +1F003E00 +1F003E00 +1F003E00 +1F003E00 +1F003E00 +1F003E00 +1F003E00 +1F003E00 +1F003E00 +1F003E00 +1F003E00 +1F003E00 +FFE1FFC0 +FFE1FFC0 +ENDCHAR +STARTCHAR 03A1 +ENCODING 929 +SWIDTH 580 0 +DWIDTH 29 0 +BBX 27 36 1 0 +BITMAP +FFFFE000 +FFFFFC00 +1F007E00 +1F001F80 +1F000F80 +1F0007C0 +1F0007C0 +1F0003E0 +1F0003E0 +1F0003E0 +1F0003E0 +1F0003E0 +1F0007C0 +1F0007C0 +1F000F80 +1F001F80 +1F007E00 +1FFFFC00 +1FFFE000 +1F000000 +1F000000 +1F000000 +1F000000 +1F000000 +1F000000 +1F000000 +1F000000 +1F000000 +1F000000 +1F000000 +1F000000 +1F000000 +1F000000 +1F000000 +FFE00000 +FFE00000 +ENDCHAR +STARTCHAR 03A3 +ENCODING 931 +SWIDTH 540 0 +DWIDTH 27 0 +BBX 22 36 3 0 +BITMAP +FFFFFC +7FFFFC +78000C +3C000C +1E000C +1E0000 +0F0000 +0F8000 +078000 +03C000 +03E000 +01E000 +00F000 +00F800 +007800 +003C00 +003E00 +001E00 +001C00 +000C00 +001800 +003000 +002000 +004000 +00C000 +018000 +010000 +020000 +06000C +0C000C +08000C +1FFFFC +3FFFFC +7FFFFC +7FFFFC +FFFFFC +ENDCHAR +STARTCHAR 03A4 +ENCODING 932 +SWIDTH 560 0 +DWIDTH 28 0 +BBX 25 36 1 0 +BITMAP +FFFFFF80 +FFFFFF80 +C03E0380 +C03E0380 +C03E0380 +003E0000 +003E0000 +003E0000 +003E0000 +003E0000 +003E0000 +003E0000 +003E0000 +003E0000 +003E0000 +003E0000 +003E0000 +003E0000 +003E0000 +003E0000 +003E0000 +003E0000 +003E0000 +003E0000 +003E0000 +003E0000 +003E0000 +003E0000 +003E0000 +003E0000 +003E0000 +003E0000 +003E0000 +003E0000 +01FF8000 +01FF8000 +ENDCHAR +STARTCHAR 03A5 +ENCODING 933 +SWIDTH 620 0 +DWIDTH 31 0 +BBX 29 36 1 0 +BITMAP +FFC001F8 +FFC001F8 +1F0000C0 +0F8001C0 +0FC00180 +07C00300 +07E00700 +03E00600 +03F00E00 +01F00C00 +00F81800 +00F81800 +007C3000 +007C7000 +003E6000 +001FE000 +001FC000 +000F8000 +000F8000 +000F8000 +000F8000 +000F8000 +000F8000 +000F8000 +000F8000 +000F8000 +000F8000 +000F8000 +000F8000 +000F8000 +000F8000 +000F8000 +000F8000 +000F8000 +007FE000 +007FE000 +ENDCHAR +STARTCHAR 03A6 +ENCODING 934 +SWIDTH 660 0 +DWIDTH 33 0 +BBX 31 36 1 0 +BITMAP +001FF800 +001FF800 +0007C000 +0007C000 +0007C000 +0007C000 +007FFC00 +01E7CF80 +07C7C7C0 +0F87C3E0 +1F07C1F0 +3E07C0F8 +7C07C07C +7C07C07C +7C07C07C +F807C03E +F807C03E +F807C03E +F807C03E +F807C03E +F807C03E +7C07C07C +7C07C07C +7C07C0FC +3E07C0F8 +1F07C1F0 +0F87C3E0 +07C7C7C0 +03E7DF80 +007FFE00 +0007C000 +0007C000 +0007C000 +0007C000 +001FF800 +001FF800 +ENDCHAR +STARTCHAR 03A7 +ENCODING 935 +SWIDTH 640 0 +DWIDTH 32 0 +BBX 29 36 2 0 +BITMAP +FFC01FC0 +FFC01FC0 +1F000600 +1F800E00 +0F800C00 +0FC01800 +07C03800 +07E03000 +03F07000 +01F06000 +01F8E000 +00F9C000 +00FD8000 +007F8000 +003F0000 +003F0000 +001F0000 +001F8000 +001F8000 +001FC000 +003FE000 +0033E000 +0063F000 +00E1F000 +00C1F800 +01C0FC00 +01807C00 +03007E00 +03003E00 +06003F00 +0E001F00 +0C000F80 +1C000FC0 +180007C0 +FC001FF8 +FC001FF8 +ENDCHAR +STARTCHAR 03A8 +ENCODING 936 +SWIDTH 780 0 +DWIDTH 39 0 +BBX 36 36 1 0 +BITMAP +FF07FF07F0 +FF07FF07F0 +1F00F807C0 +1F00F807C0 +1F00F807C0 +1F00F807C0 +1F00F807C0 +1F00F807C0 +1F00F807C0 +1F00F807C0 +1F00F807C0 +1F00F807C0 +1F00F807C0 +1F00F807C0 +0F80F80F80 +0F80F80F80 +0FC0F81F80 +07C0F81F00 +03E0F83E00 +01F0F87C00 +00F8F8F800 +003EFBE000 +000FFF8000 +0000F80000 +0000F80000 +0000F80000 +0000F80000 +0000F80000 +0000F80000 +0000F80000 +0000F80000 +0000F80000 +0000F80000 +0000F80000 +0007FF0000 +0007FF0000 +ENDCHAR +STARTCHAR 03A9 +ENCODING 937 +SWIDTH 700 0 +DWIDTH 35 0 +BBX 32 37 1 0 +BITMAP +0003C000 +007FFE00 +01FC3F80 +07E007E0 +0FC003F0 +1F8001F8 +1F0000F8 +3E00007C +3E00007C +7C00003E +7C00003E +7C00003E +F800001F +F800001F +F800001F +F800001F +F800001F +F800001F +F800001F +F800001F +F800001F +7C00001E +7C00003E +3C00003C +3E00007C +1F000078 +0F0000F0 +078001E0 +03C003C0 +00E00780 +20300602 +20300602 +20300602 +3FF007FE +3FF007FE +3FF007FE +3FF007FE +ENDCHAR +STARTCHAR 03AA +ENCODING 938 +SWIDTH 300 0 +DWIDTH 15 0 +BBX 15 44 0 0 +BITMAP +F83E +F83E +F83E +F83E +F83E +0000 +0000 +0000 +7FF0 +7FF0 +0F80 +0F80 +0F80 +0F80 +0F80 +0F80 +0F80 +0F80 +0F80 +0F80 +0F80 +0F80 +0F80 +0F80 +0F80 +0F80 +0F80 +0F80 +0F80 +0F80 +0F80 +0F80 +0F80 +0F80 +0F80 +0F80 +0F80 +0F80 +0F80 +0F80 +0F80 +0F80 +7FF0 +7FF0 +ENDCHAR +STARTCHAR 03AB +ENCODING 939 +SWIDTH 640 0 +DWIDTH 32 0 +BBX 29 44 1 0 +BITMAP +007C1F00 +007C1F00 +007C1F00 +007C1F00 +007C1F00 +00000000 +00000000 +00000000 +FFC001F8 +FFC001F8 +1F0000C0 +0F8001C0 +0FC00180 +07C00300 +07E00700 +03E00600 +03F00E00 +01F00C00 +00F81800 +00F81800 +007C3000 +007C7000 +003E6000 +001FE000 +001FC000 +000F8000 +000F8000 +000F8000 +000F8000 +000F8000 +000F8000 +000F8000 +000F8000 +000F8000 +000F8000 +000F8000 +000F8000 +000F8000 +000F8000 +000F8000 +000F8000 +000F8000 +007FE000 +007FE000 +ENDCHAR +STARTCHAR 03AC +ENCODING 940 +SWIDTH 460 0 +DWIDTH 23 0 +BBX 24 36 2 -1 +BITMAP +000F80 +001F00 +001E00 +003E00 +003C00 +007800 +00F000 +003000 +000000 +000000 +000000 +01FE1E +07FF9E +1F87FE +3F03FE +3E01FE +7C00FE +7C00FE +7C00FE +F8007E +F8007E +F8007E +F8003E +F8003E +F8003E +F8007E +F8007E +F8007E +7C007E +7C00FE +7C00FE +3E01FE +3F03FE +1F87FF +07FF9F +01FE00 +ENDCHAR +STARTCHAR 03AD +ENCODING 941 +SWIDTH 460 0 +DWIDTH 23 0 +BBX 20 36 2 -1 +BITMAP +003E00 +007C00 +007800 +00F800 +00F000 +01E000 +03C000 +00C000 +000000 +000000 +000000 +03FE00 +1FFF80 +3F0FC0 +7E03E0 +FC01F0 +F801F0 +F80000 +F80000 +F80000 +7C0000 +3E0000 +1F8000 +07E000 +1F8000 +3E0000 +7C0000 +F80000 +F80000 +F80000 +F800C0 +FC01F0 +7C03E0 +3F07E0 +1FFF80 +03FE00 +ENDCHAR +STARTCHAR 03AE +ENCODING 942 +SWIDTH 460 0 +DWIDTH 23 0 +BBX 21 48 1 -12 +BITMAP +000F80 +001F00 +001E00 +003E00 +003C00 +007800 +00F000 +003000 +000000 +000000 +000000 +000000 +F9FC00 +FFCF80 +FF87C0 +FF03E0 +FE01E0 +FC01F0 +FC01F0 +FC00F0 +F800F8 +F800F8 +F800F8 +F800F8 +F800F8 +F800F8 +F800F8 +F800F8 +F800F8 +F800F8 +F800F8 +F800F8 +F800F8 +F800F8 +F800F8 +F800F8 +0000F8 +0000F8 +0000F8 +0000F8 +0000F8 +0000F8 +0000F8 +0000F8 +0000F8 +0000F8 +0000F8 +0000F8 +ENDCHAR +STARTCHAR 03B1 +ENCODING 945 +SWIDTH 560 0 +DWIDTH 28 0 +BBX 24 25 2 -1 +BITMAP +01FE1E +07FF9E +1F87FE +3F03FE +3E01FE +7C00FE +7C00FE +7C00FE +F8007E +F8007E +F8007E +F8003E +F8003E +F8003E +F8007E +F8007E +F8007E +7C007E +7C00FE +7C00FE +3E01FE +3F03FE +1F87FF +07FF9F +01FE00 +ENDCHAR +STARTCHAR 03B2 +ENCODING 946 +SWIDTH 520 0 +DWIDTH 26 0 +BBX 23 43 2 -7 +BITMAP +01FC00 +0F9F80 +1F07C0 +3E03E0 +7C01F0 +7C01F0 +F800F8 +F800F8 +F800F8 +F800F8 +F800F8 +F801F8 +F801F0 +F803E0 +F807E0 +F81F80 +FBFE00 +FBFC00 +F80F80 +F803E0 +F800F0 +F80078 +F8007C +F8007C +F8003E +F8003E +F8003E +F8003E +F8003E +F8007E +F8007C +FC00FC +FC00F8 +FE03F0 +FF87E0 +FFFFC0 +F87E00 +F80000 +F80000 +F80000 +F80000 +F80000 +180000 +ENDCHAR +STARTCHAR 03B3 +ENCODING 947 +SWIDTH 520 0 +DWIDTH 26 0 +BBX 23 36 2 -12 +BITMAP +F8003E +F8003E +78007C +7C007C +7C007C +3E00F8 +3E00F8 +1E01F0 +1F01F0 +1F01F0 +0F83E0 +0F83E0 +07C7C0 +07C7C0 +07C7C0 +03EF80 +03EF80 +01FF00 +01FF00 +01FF00 +00FE00 +00FE00 +007C00 +007C00 +007C00 +007C00 +007C00 +007C00 +007C00 +007C00 +007C00 +007C00 +007C00 +007C00 +007C00 +007C00 +ENDCHAR +STARTCHAR 03B4 +ENCODING 948 +SWIDTH 520 0 +DWIDTH 26 0 +BBX 23 35 2 -1 +BITMAP +0FFF80 +1FFF80 +0F0000 +0F8000 +07C000 +03C000 +03E000 +01F000 +00F000 +00F800 +03FE00 +0FC3C0 +1F01E0 +3E00F0 +3E0078 +7C007C +7C007C +7C003C +F8003E +F8003E +F8003E +F8003E +F8003E +F8003E +F8003E +F8003E +F8003E +7C007C +7C007C +7C00FC +3E00F8 +3F01F8 +1F83F0 +07FFC0 +00FF00 +ENDCHAR +STARTCHAR 03B5 +ENCODING 949 +SWIDTH 480 0 +DWIDTH 24 0 +BBX 20 25 2 -1 +BITMAP +03FE00 +1FFF80 +3F0FC0 +7E03E0 +FC01F0 +F801F0 +F80000 +F80000 +F80000 +7C0000 +3E0000 +1F8000 +07E000 +1F8000 +3E0000 +7C0000 +F80000 +F80000 +F80000 +F800C0 +FC01F0 +7C03E0 +3F07E0 +1FFF80 +03FE00 +ENDCHAR +STARTCHAR 03B6 +ENCODING 950 +SWIDTH 440 0 +DWIDTH 22 0 +BBX 18 46 1 -10 +BITMAP +0FFF80 +0FFFC0 +0007C0 +000F80 +001F00 +001E00 +003E00 +007C00 +007800 +00F800 +01F000 +01F000 +03E000 +03C000 +07C000 +078000 +0F8000 +1F0000 +1F0000 +1E0000 +3E0000 +3E0000 +7C0000 +7C0000 +7C0000 +F80000 +F80000 +F80000 +F80000 +F80000 +F80000 +FC0000 +7C0000 +3E0000 +1F0000 +07FE00 +001F80 +000F80 +0007C0 +0007C0 +0007C0 +0007C0 +000FC0 +000F80 +003F00 +003C00 +ENDCHAR +STARTCHAR 03B7 +ENCODING 951 +SWIDTH 480 0 +DWIDTH 24 0 +BBX 21 36 1 -12 +BITMAP +F9FC00 +FFCF80 +FF87C0 +FF03E0 +FE01E0 +FC01F0 +FC01F0 +FC00F0 +F800F8 +F800F8 +F800F8 +F800F8 +F800F8 +F800F8 +F800F8 +F800F8 +F800F8 +F800F8 +F800F8 +F800F8 +F800F8 +F800F8 +F800F8 +F800F8 +0000F8 +0000F8 +0000F8 +0000F8 +0000F8 +0000F8 +0000F8 +0000F8 +0000F8 +0000F8 +0000F8 +0000F8 +ENDCHAR +STARTCHAR 03B8 +ENCODING 952 +SWIDTH 540 0 +DWIDTH 27 0 +BBX 23 37 2 -1 +BITMAP +00FE00 +03CF80 +0703C0 +0F01E0 +1E01F0 +1C00F0 +3C00F8 +3C00F8 +780078 +78007C +78007C +78007C +F8003C +F8003E +F8003E +F8003E +F8003E +FFFFFE +FFFFFE +F8003E +F8003E +F8003E +F8003E +78003E +78003C +78007C +78007C +78007C +3C00F8 +3C00F8 +3E00F8 +1E01F0 +1F03F0 +0F87E0 +07EFC0 +03FF80 +00FE00 +ENDCHAR +STARTCHAR 03B9 +ENCODING 953 +SWIDTH 200 0 +DWIDTH 10 0 +BBX 5 24 2 0 +BITMAP +F8 +F8 +F8 +F8 +F8 +F8 +F8 +F8 +F8 +F8 +F8 +F8 +F8 +F8 +F8 +F8 +F8 +F8 +F8 +F8 +F8 +F8 +F8 +F8 +ENDCHAR +STARTCHAR 03BA +ENCODING 954 +SWIDTH 440 0 +DWIDTH 22 0 +BBX 18 24 2 0 +BITMAP +F80700 +F80E00 +F81C00 +F83800 +F87000 +F8E000 +F9C000 +FB8000 +FF0000 +FE0000 +FF0000 +FF8000 +FF8000 +FFC000 +FBE000 +F9F000 +F9F000 +F8F800 +F87C00 +F83E00 +F83E00 +F81F00 +F80F80 +F807C0 +ENDCHAR +STARTCHAR 03BB +ENCODING 955 +SWIDTH 520 0 +DWIDTH 26 0 +BBX 22 36 2 0 +BITMAP +0F8000 +0F8000 +0F8000 +07C000 +07C000 +03C000 +03E000 +03E000 +01F000 +01F000 +00F000 +00F800 +00F800 +00FC00 +00FC00 +01FC00 +01FE00 +01FE00 +03FF00 +03FF00 +07CF00 +07CF80 +07CF80 +0F87C0 +0F87C0 +0F83C0 +1F03E0 +1F03E0 +3E01F0 +3E01F0 +3E00F0 +7C00F8 +7C00F8 +78007C +F8007C +F8007C +ENDCHAR +STARTCHAR 03BC +ENCODING 956 +SWIDTH 540 0 +DWIDTH 27 0 +BBX 26 34 0 -10 +BITMAP +1F007C00 +1F007C00 +1F007C00 +1F007C00 +1F007C00 +1F007C00 +1F007C00 +1F007C00 +1F007C00 +1F007C00 +1F007C00 +1F007C00 +1F007C00 +1F007C00 +1F007C00 +1F007C00 +1F007C00 +1F807C00 +1F807E00 +1F807E00 +1F80FE00 +1FE1FE00 +1F7FDFC0 +1F7F9FC0 +1F0E0000 +1F000000 +3F000000 +3E000000 +3E000000 +3E000000 +7C000000 +7C000000 +F8000000 +70000000 +ENDCHAR +STARTCHAR 03BD +ENCODING 957 +SWIDTH 500 0 +DWIDTH 25 0 +BBX 21 24 2 0 +BITMAP +F000F8 +F800F8 +F800F8 +7801F0 +7C01F0 +7C01F0 +3C03E0 +3E03E0 +3E03E0 +1E07C0 +1F07C0 +1F07C0 +0F8F80 +0F8F80 +0F8F00 +07DF00 +07DF00 +07DE00 +03FE00 +03FE00 +03FC00 +01FC00 +01FC00 +01F800 +ENDCHAR +STARTCHAR 03BE +ENCODING 958 +SWIDTH 500 0 +DWIDTH 25 0 +BBX 23 46 1 -9 +BITMAP +003F80 +01FFC0 +03F000 +07C000 +0F8000 +0F8000 +1F0000 +1F0000 +1F0000 +1F0000 +1F0000 +1F8000 +0F8000 +0FC000 +07E000 +01F800 +00F800 +03F000 +07C000 +0F8000 +1F0000 +3E0000 +7C0000 +7C0000 +780000 +F80000 +F80000 +F80000 +F80000 +F80000 +FC0000 +7C0000 +7E0000 +3F0000 +1FE000 +07FFE0 +007FF8 +00007C +00007E +00003E +00003E +00003E +00007C +000078 +0001F8 +0003C0 +ENDCHAR +STARTCHAR 03BF +ENCODING 959 +SWIDTH 520 0 +DWIDTH 26 0 +BBX 22 25 2 -1 +BITMAP +01FE00 +07FF80 +1F87E0 +3F03F0 +3E01F0 +7E00F8 +7C00F8 +7C0078 +F8007C +F8007C +F8007C +F8007C +F8007C +F8007C +F8007C +F8007C +F8007C +780078 +7C00F8 +7C00F8 +3C00F0 +3E01F0 +1F03E0 +0787C0 +01FE00 +ENDCHAR +STARTCHAR 03C0 +ENCODING 960 +SWIDTH 500 0 +DWIDTH 25 0 +BBX 21 24 2 0 +BITMAP +FFFFF8 +FFFFF8 +1F07C0 +1F07C0 +1F07C0 +1F07C0 +1F07C0 +1F07C0 +1F07C0 +1F07C0 +1F07C0 +1F07C0 +1F07C0 +1F07C0 +1F07C0 +1F07C0 +1F07C0 +1F07C0 +1F07C0 +1F07C0 +1F07C0 +1F07C0 +1F07C0 +1F07C0 +ENDCHAR +STARTCHAR 03C1 +ENCODING 961 +SWIDTH 520 0 +DWIDTH 26 0 +BBX 23 36 2 -12 +BITMAP +00FF00 +03FFC0 +0F83F0 +1F01F8 +1E00F8 +3C007C +7C007C +78003C +78003E +F8003E +F8003E +F8003E +F8003E +F8003E +F8003E +F8003E +F8003E +FC007C +FC007C +FC007C +FE00F8 +FF01F8 +FF83F0 +F9FFC0 +F87F00 +F80000 +F80000 +F80000 +F80000 +F80000 +F80000 +F80000 +F80000 +F80000 +F80000 +F80000 +ENDCHAR +STARTCHAR 03C2 +ENCODING 962 +SWIDTH 500 0 +DWIDTH 25 0 +BBX 23 34 1 -10 +BITMAP +007F80 +03FF80 +07E000 +1F8000 +1F0000 +3E0000 +7E0000 +7C0000 +FC0000 +F80000 +F80000 +F80000 +F80000 +F80000 +F80000 +F80000 +7C0000 +7C0000 +3E0000 +3E0000 +1F0000 +0F8000 +03E000 +00FF80 +0003F0 +0000F8 +00007C +00003C +00003E +00003E +00003E +00007C +0000F8 +0000E0 +ENDCHAR +STARTCHAR 03C3 +ENCODING 963 +SWIDTH 580 0 +DWIDTH 29 0 +BBX 25 25 2 -1 +BITMAP +01FFFF80 +07FFFF80 +1F87E000 +3F03E000 +3E01F000 +7C00F800 +7C00F800 +7C00F800 +F8007C00 +F8007C00 +F8007C00 +F8007C00 +F8007C00 +F8007C00 +F8007C00 +F8007C00 +F8007C00 +7C00F800 +7C00F800 +7C00F800 +3E01F000 +3F03F000 +1F87E000 +0FFFC000 +01FE0000 +ENDCHAR +STARTCHAR 03C4 +ENCODING 964 +SWIDTH 400 0 +DWIDTH 20 0 +BBX 18 23 0 1 +BITMAP +FFFFC0 +FFFFC0 +01F000 +01F000 +01F000 +01F000 +01F000 +01F000 +01F000 +01F000 +01F000 +01F000 +01F000 +01F000 +01F000 +01F000 +01F000 +01F000 +01F000 +01F000 +01F000 +01F000 +01F000 +ENDCHAR +STARTCHAR 03C5 +ENCODING 965 +SWIDTH 540 0 +DWIDTH 27 0 +BBX 23 25 2 -1 +BITMAP +F8003E +F8003E +F8003E +F8003E +F8003E +F8003E +F8003E +F8003E +F8003E +F8003E +F8003E +F8003E +F8003E +F8003E +F8003E +F8003E +F8003E +F8003E +7C007C +7C007C +3E00F8 +3F01F8 +0FC7F0 +07FFC0 +00FE00 +ENDCHAR +STARTCHAR 03C6 +ENCODING 966 +SWIDTH 580 0 +DWIDTH 29 0 +BBX 26 36 1 -12 +BITMAP +00E1E000 +03823800 +0F061C00 +1E040E00 +3E040700 +3C040780 +7C040780 +780403C0 +F80403C0 +F80403C0 +F80403C0 +F80403C0 +F80403C0 +F80403C0 +F80403C0 +780403C0 +7C0407C0 +7C040780 +3C040780 +3E040F00 +1F041E00 +0F043C00 +03C47800 +01FFE000 +003F8000 +00040000 +00040000 +00040000 +00040000 +00040000 +00040000 +00040000 +00040000 +00040000 +00040000 +00040000 +ENDCHAR +STARTCHAR 03C7 +ENCODING 967 +SWIDTH 560 0 +DWIDTH 28 0 +BBX 24 36 2 -12 +BITMAP +F8001F +7C003E +7C003E +3E007C +3E007C +1F00F8 +1F00F8 +0F81F0 +0F81F0 +07C3E0 +07C3E0 +03E7C0 +03E7C0 +01FF80 +01FF80 +00FF00 +00FF00 +007E00 +007E00 +007E00 +007E00 +00FF00 +00FF00 +01FF80 +01FF80 +03E7C0 +03C7C0 +07C3E0 +0783E0 +0F81F0 +0F01F0 +1F00F8 +3E00F8 +3E007C +7C003C +7C003E +ENDCHAR +STARTCHAR 03C8 +ENCODING 968 +SWIDTH 520 0 +DWIDTH 26 0 +BBX 22 36 2 -12 +BITMAP +F87C7C +F87C7C +F87C7C +F87C7C +F87C7C +F87C7C +F87C7C +F87C7C +F87C7C +F87C7C +F87C7C +F87C7C +F87C7C +F87C7C +F87C7C +F87C7C +F87C7C +F87C7C +F87C7C +FC7C7C +7C7CF8 +7E7CF8 +3F7DF0 +1FFFE0 +01FF00 +007C00 +007C00 +007C00 +007C00 +007C00 +007C00 +007C00 +007C00 +007C00 +007C00 +007C00 +ENDCHAR +STARTCHAR 03C9 +ENCODING 969 +SWIDTH 680 0 +DWIDTH 34 0 +BBX 30 25 2 -1 +BITMAP +00303000 +00F03C00 +03C00F00 +07000380 +0F0003C0 +0E0001E0 +1C0000E0 +3C0000F0 +3C0000F0 +7C0000F8 +78000078 +78000078 +F803007C +F803007C +F803007C +F803007C +F803007C +F803007C +F803007C +780780F8 +7C0480F8 +3C0CC0F0 +3E1861F0 +0FF03FC0 +03800700 +ENDCHAR +STARTCHAR 03CA +ENCODING 970 +SWIDTH 260 0 +DWIDTH 13 0 +BBX 15 32 -1 0 +BITMAP +F83E +F83E +F83E +F83E +F83E +0000 +0000 +0000 +3FC0 +07C0 +07C0 +07C0 +07C0 +07C0 +07C0 +07C0 +07C0 +07C0 +07C0 +07C0 +07C0 +07C0 +07C0 +07C0 +07C0 +07C0 +07C0 +07C0 +07C0 +07C0 +3FF0 +3FF0 +ENDCHAR +STARTCHAR 03CB +ENCODING 971 +SWIDTH 520 0 +DWIDTH 26 0 +BBX 23 33 2 -1 +BITMAP +0F83E0 +0F83E0 +0F83E0 +0F83E0 +0F83E0 +000000 +000000 +000000 +F8003E +F8003E +F8003E +F8003E +F8003E +F8003E +F8003E +F8003E +F8003E +F8003E +F8003E +F8003E +F8003E +F8003E +F8003E +F8003E +F8003E +F8003E +7C007C +7C007C +3E00F8 +3F01F8 +0FC7F0 +07FFC0 +00FE00 +ENDCHAR +STARTCHAR 03CC +ENCODING 972 +SWIDTH 500 0 +DWIDTH 25 0 +BBX 22 35 2 -1 +BITMAP +003E00 +007C00 +007800 +00F800 +00F000 +01E000 +03C000 +00C000 +000000 +000000 +01FE00 +07FF80 +1F87E0 +3F03F0 +3E01F0 +7C00F8 +7C00F8 +7C00F8 +F8007C +F8007C +F8007C +F8007C +F8007C +F8007C +F8007C +F8007C +F8007C +7C00F8 +7C00F8 +7C00F8 +3E01F0 +3F03F0 +1F87E0 +0FFFC0 +01FE00 +ENDCHAR +STARTCHAR 03CD +ENCODING 973 +SWIDTH 500 0 +DWIDTH 25 0 +BBX 23 35 2 -1 +BITMAP +003E00 +007C00 +007800 +00F800 +00F000 +01E000 +03C000 +00C000 +000000 +000000 +F8003E +F8003E +F8003E +F8003E +F8003E +F8003E +F8003E +F8003E +F8003E +F8003E +F8003E +F8003E +F8003E +F8003E +F8003E +F8003E +F8003E +F8003E +7C007C +7C007C +3E00F8 +3F01F8 +0FC7F0 +07FFC0 +00FE00 +ENDCHAR +STARTCHAR 03CE +ENCODING 974 +SWIDTH 660 0 +DWIDTH 33 0 +BBX 30 35 2 -1 +BITMAP +0001F000 +0003E000 +0003C000 +0007C000 +00078000 +000F0000 +001E0000 +00060000 +00000000 +00000000 +00303000 +00F03C00 +03C00F00 +07000380 +0F0003C0 +0E0001E0 +1C0000E0 +3C0000F0 +3C0000F0 +7C0000F8 +78000078 +78000078 +F803007C +F803007C +F803007C +F803007C +F803007C +F803007C +F803007C +780780F8 +7C0480F8 +3C0CC0F0 +3E1861F0 +0FF03FC0 +03800700 +ENDCHAR +STARTCHAR 2013 +ENCODING 8211 +SWIDTH 500 0 +DWIDTH 25 0 +BBX 20 2 2 17 +BITMAP +FFFFF0 +FFFFF0 +ENDCHAR +STARTCHAR 2014 +ENCODING 8212 +SWIDTH 760 0 +DWIDTH 38 0 +BBX 33 2 2 17 +BITMAP +FFFFFFFF80 +FFFFFFFF80 +ENDCHAR +STARTCHAR 2018 +ENCODING 8216 +SWIDTH 180 0 +DWIDTH 9 0 +BBX 5 10 2 26 +BITMAP +18 +30 +60 +C0 +C0 +F8 +F8 +F8 +F8 +F8 +ENDCHAR +STARTCHAR 2019 +ENCODING 8217 +SWIDTH 180 0 +DWIDTH 9 0 +BBX 5 10 2 26 +BITMAP +F8 +F8 +F8 +F8 +F8 +18 +18 +30 +60 +C0 +ENDCHAR +STARTCHAR 201A +ENCODING 8218 +SWIDTH 180 0 +DWIDTH 9 0 +BBX 5 10 2 -5 +BITMAP +F8 +F8 +F8 +F8 +F8 +38 +18 +30 +60 +C0 +ENDCHAR +STARTCHAR 201C +ENCODING 8220 +SWIDTH 380 0 +DWIDTH 19 0 +BBX 15 11 2 25 +BITMAP +1806 +300C +6018 +C030 +C030 +E038 +F83E +F83E +F83E +F83E +F83E +ENDCHAR +STARTCHAR 201D +ENCODING 8221 +SWIDTH 380 0 +DWIDTH 19 0 +BBX 15 10 2 26 +BITMAP +F83E +F83E +F83E +F83E +F83E +380E +1806 +300C +6018 +C030 +ENDCHAR +STARTCHAR 201E +ENCODING 8222 +SWIDTH 380 0 +DWIDTH 19 0 +BBX 15 10 2 -5 +BITMAP +F83E +F83E +F83E +F83E +F83E +380E +1806 +300C +6018 +C030 +ENDCHAR +STARTCHAR 2020 +ENCODING 8224 +SWIDTH 440 0 +DWIDTH 22 0 +BBX 22 45 0 -10 +BITMAP +007800 +007800 +00FC00 +00FC00 +00FC00 +007800 +007800 +007800 +7C30F8 +FFB7FC +FFFFFC +FFB7FC +7C30F8 +003000 +003000 +003000 +007800 +007800 +00FC00 +01FE00 +00FC00 +00FC00 +00FC00 +007800 +007800 +007800 +007800 +007800 +007800 +007800 +007000 +003000 +003000 +003000 +003000 +003000 +003000 +003000 +003000 +003000 +003000 +003000 +003000 +003000 +003000 +ENDCHAR +STARTCHAR 2021 +ENCODING 8225 +SWIDTH 420 0 +DWIDTH 21 0 +BBX 22 48 -1 -12 +BITMAP +007000 +00F800 +00F800 +00F800 +00F800 +00F800 +007000 +007000 +7C70F8 +FFA7FC +FFFFFC +FFB7FC +7C30F8 +003000 +003000 +003000 +007800 +007800 +00FC00 +01FE00 +00FC00 +007800 +007800 +003000 +003000 +007800 +007800 +00FC00 +01FE00 +00FC00 +007800 +007800 +003000 +003000 +003000 +7C30F8 +FFA7FC +FFFFFC +FFB7FC +7C60F8 +006000 +00F000 +00F000 +00F800 +00F800 +00F800 +00F800 +007000 +ENDCHAR +STARTCHAR 2022 +ENCODING 8226 +SWIDTH 320 0 +DWIDTH 16 0 +BBX 12 12 2 12 +BITMAP +1F00 +3FC0 +7FE0 +FFE0 +FFF0 +FFF0 +FFF0 +FFF0 +FFE0 +7FE0 +3FC0 +1F00 +ENDCHAR +STARTCHAR 2026 +ENCODING 8230 +SWIDTH 860 0 +DWIDTH 43 0 +BBX 39 5 2 0 +BITMAP +F8007C003E +F8007C003E +F8007C003E +F8007C003E +F8007C003E +ENDCHAR +STARTCHAR 2030 +ENCODING 8240 +SWIDTH 780 0 +DWIDTH 39 0 +BBX 36 37 2 -1 +BITMAP +1E00C00000 +7F80C00000 +7380C00000 +E1C1800000 +E1C1800000 +E1C1000000 +E1C3000000 +E1C3000000 +E1C6000000 +7386000000 +7F84000000 +1E0C000000 +000C000000 +0008000000 +0018000000 +0010000000 +0030000000 +0030000000 +0020000000 +0060000000 +0040000000 +00C0000000 +00C0000000 +0080000000 +0180000000 +0183C00F80 +010FF03FE0 +030E7038E0 +021C387070 +061C387070 +061C387070 +041C387070 +0C1C387070 +081C387070 +080E7038E0 +180FF03FE0 +0003C00F80 +ENDCHAR +STARTCHAR 2039 +ENCODING 8249 +SWIDTH 260 0 +DWIDTH 13 0 +BBX 10 15 1 10 +BITMAP +07C0 +0FC0 +0F80 +1F00 +3E00 +7C00 +7C00 +F800 +7C00 +7C00 +3E00 +1F00 +0F80 +07C0 +07C0 +ENDCHAR +STARTCHAR 203A +ENCODING 8250 +SWIDTH 260 0 +DWIDTH 13 0 +BBX 10 21 2 7 +BITMAP +8000 +C000 +E000 +F000 +F800 +7800 +3C00 +1E00 +1F00 +0F80 +07C0 +0F80 +1F00 +3E00 +3C00 +7800 +F800 +F000 +E000 +C000 +8000 +ENDCHAR +STARTCHAR 2044 +ENCODING 8260 +SWIDTH 580 0 +DWIDTH 29 0 +BBX 27 36 1 0 +BITMAP +00000060 +00000040 +000000C0 +00000180 +00000300 +00000200 +00000600 +00000C00 +00000800 +00001000 +00003000 +00006000 +00004000 +0000C000 +00018000 +00030000 +00020000 +00060000 +000C0000 +00180000 +00100000 +00300000 +00600000 +00400000 +00C00000 +01800000 +03000000 +02000000 +06000000 +0C000000 +18000000 +10000000 +30000000 +60000000 +C0000000 +C0000000 +ENDCHAR +STARTCHAR 20AC +ENCODING 8364 +SWIDTH 520 0 +DWIDTH 26 0 +BBX 22 37 2 -1 +BITMAP +003F80 +00FBE0 +01F0F8 +03E0F8 +07C07C +0F807C +0F8000 +1F0000 +1F0000 +1F0000 +3E0000 +3E0000 +FFFF00 +FFFF00 +3E0000 +3E0000 +3E0000 +3E0000 +3E0000 +3E0000 +3E0000 +3E0000 +FFFF00 +FFFF00 +3E0000 +3E0000 +1F0000 +1F0000 +1F0000 +0F0000 +0F8000 +0F807C +07C07C +03E078 +01E0F8 +00FBF0 +003F80 +ENDCHAR +STARTCHAR 2122 +ENCODING 8482 +SWIDTH 980 0 +DWIDTH 49 0 +BBX 46 21 1 15 +BITMAP +FFFFC7FC03FC +FFFFC7FC03FC +C1F040FC07E0 +C1F040FE07E0 +C1F040FE0FE0 +01F000FE0FE0 +01F000DF0FE0 +01F000DF1BE0 +01F000DF1BE0 +01F000CF9BE0 +01F000CFB3E0 +01F000CFB3E0 +01F000C7F3E0 +01F000C7E3E0 +01F000C7E3E0 +01F000C3E3E0 +01F000C3C3E0 +01F000C3C3E0 +01F000C1C3E0 +0FFE07F98FFC +0FFE07F98FFC +ENDCHAR +STARTCHAR 2202 +ENCODING 8706 +SWIDTH 520 0 +DWIDTH 26 0 +BBX 22 37 2 -1 +BITMAP +01F800 +079E00 +0F0F00 +1F0780 +3E03C0 +0003C0 +0001E0 +0001E0 +0001F0 +0000F0 +0000F0 +0000F8 +0000F8 +000078 +000078 +0003FC +001FFC +00FE7C +03F87C +07E07C +1F807C +3F007C +3E007C +7C007C +7C007C +F8007C +F8007C +F800FC +F800F8 +F800F8 +F801F8 +7C01F0 +7C03E0 +3E07E0 +1F0FC0 +0FFF00 +03F800 +ENDCHAR +STARTCHAR 2206 +ENCODING 8710 +SWIDTH 600 0 +DWIDTH 30 0 +BBX 24 36 3 0 +BITMAP +001800 +001800 +003C00 +003C00 +003C00 +007E00 +007E00 +005E00 +00DF00 +00DF00 +009F00 +018F00 +018F80 +010F80 +010780 +0307C0 +0207C0 +0203C0 +0603E0 +0403E0 +0403E0 +0C01E0 +0801F0 +0801F0 +1800F0 +1000F8 +1000F8 +300078 +20007C +20007C +60003C +40003E +40003E +C0003E +FFFFFE +FFFFFF +ENDCHAR +STARTCHAR 220F +ENCODING 8719 +SWIDTH 760 0 +DWIDTH 38 0 +BBX 34 48 2 -12 +BITMAP +FFFFFFFFC0 +FFFFFFFFC0 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +FFE001FFC0 +FFE001FFC0 +ENDCHAR +STARTCHAR 2210 +ENCODING 8720 +SWIDTH 760 0 +DWIDTH 38 0 +BBX 34 48 2 -12 +BITMAP +FFE001FFC0 +FFE001FFC0 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +1F00003E00 +FFFFFFFFC0 +FFFFFFFFC0 +ENDCHAR +STARTCHAR 2211 +ENCODING 8721 +SWIDTH 620 0 +DWIDTH 31 0 +BBX 27 46 2 -10 +BITMAP +FFFFFFE0 +7FFFFFE0 +3C000020 +3E000020 +1F000020 +0F000000 +0F800000 +07C00000 +07C00000 +03E00000 +01E00000 +01F00000 +00F80000 +00780000 +007C0000 +003E0000 +003E0000 +001F0000 +000F8000 +000F8000 +0007C000 +0003E000 +0003E000 +0001C000 +0001C000 +00018000 +00030000 +00060000 +000C0000 +000C0000 +00180000 +00300000 +00600000 +00600000 +00C00000 +01800000 +03000000 +02000000 +06000060 +0C000060 +18000060 +1FFFFFE0 +3FFFFFE0 +7FFFFFE0 +FFFFFFE0 +FFFFFFE0 +ENDCHAR +STARTCHAR 2212 +ENCODING 8722 +SWIDTH 400 0 +DWIDTH 20 0 +BBX 16 2 2 17 +BITMAP +FFFF +FFFF +ENDCHAR +STARTCHAR 2215 +ENCODING 8725 +SWIDTH 580 0 +DWIDTH 29 0 +BBX 27 36 1 0 +BITMAP +00000060 +00000040 +000000C0 +00000180 +00000300 +00000200 +00000600 +00000C00 +00000800 +00001000 +00003000 +00006000 +00004000 +0000C000 +00018000 +00030000 +00020000 +00060000 +000C0000 +00180000 +00100000 +00300000 +00600000 +00400000 +00C00000 +01800000 +03000000 +02000000 +06000000 +0C000000 +18000000 +10000000 +30000000 +60000000 +C0000000 +C0000000 +ENDCHAR +STARTCHAR 2219 +ENCODING 8729 +SWIDTH 200 0 +DWIDTH 10 0 +BBX 5 5 2 19 +BITMAP +F8 +F8 +F8 +F8 +F8 +ENDCHAR +STARTCHAR 221A +ENCODING 8730 +SWIDTH 480 0 +DWIDTH 24 0 +BBX 19 38 1 0 +BITMAP +000060 +000040 +0000C0 +0000C0 +0000C0 +0000C0 +000080 +000180 +000180 +000180 +000100 +000300 +000300 +000300 +000200 +000600 +000600 +000600 +000400 +000C00 +FE0C00 +3E0C00 +1E0C00 +1F0800 +1F1800 +0F9800 +0F9800 +0F9000 +07F000 +07F000 +03F000 +03E000 +03E000 +01E000 +01E000 +00C000 +00C000 +00C000 +ENDCHAR +STARTCHAR 221E +ENCODING 8734 +SWIDTH 740 0 +DWIDTH 37 0 +BBX 33 15 2 6 +BITMAP +000007E000 +07E03FFC00 +1FF8783E00 +383CE00F00 +701FC00700 +E00FC00780 +E007800380 +E007800380 +E007800380 +E00FC00380 +700FC00700 +383CE00F00 +1FF8783E00 +07E03FF800 +00000FE000 +ENDCHAR +STARTCHAR 221F +ENCODING 8735 +SWIDTH 580 0 +DWIDTH 29 0 +BBX 27 35 2 0 +BITMAP +F8000000 +F8000000 +F8000000 +F8000000 +F8000000 +F8000000 +F8000000 +F8000000 +F8000000 +F8000000 +F8000000 +F8000000 +F8000000 +F8000000 +F8000000 +F8000000 +F8000000 +F8000000 +F8000000 +F8000000 +F8000000 +F8000000 +F8000000 +F8000000 +F8000000 +F8000000 +F8000000 +F8000000 +F8000000 +F8000000 +F8000000 +F8000000 +F8000000 +FFFFFFE0 +7FFFFFE0 +ENDCHAR +STARTCHAR 222B +ENCODING 8747 +SWIDTH 360 0 +DWIDTH 18 0 +BBX 17 48 1 -12 +BITMAP +00FC00 +01FE00 +03FF00 +03FF00 +03EF80 +03E000 +03E000 +03E000 +03E000 +03E000 +03E000 +03E000 +03E000 +03E000 +03E000 +03E000 +03E000 +03E000 +03E000 +03E000 +03E000 +03E000 +03E000 +03E000 +03E000 +03E000 +03E000 +03E000 +03E000 +03E000 +03E000 +03E000 +03E000 +03E000 +03E000 +03E000 +03E000 +03E000 +03E000 +03E000 +03E000 +03E000 +03E000 +FBE000 +7FE000 +7FE000 +3FC000 +1F8000 +ENDCHAR +STARTCHAR 2248 +ENCODING 8776 +SWIDTH 520 0 +DWIDTH 26 0 +BBX 23 15 2 12 +BITMAP +0FC000 +3FF07E +7CF8FC +F83FF0 +000FC0 +000000 +000000 +000000 +000000 +000000 +0FC000 +3FF07E +7CF8FC +F83FF0 +000FC0 +ENDCHAR +STARTCHAR 2249 +ENCODING 8777 +SWIDTH 500 0 +DWIDTH 25 0 +BBX 23 26 1 6 +BITMAP +0007C0 +000780 +000F80 +000F80 +000F00 +001F00 +1FFF00 +7EFE7C +F87EF8 +003FF0 +007C00 +007C00 +007C00 +00F800 +00F800 +0FF800 +3FF03E +7DFC7C +F9FFF0 +03E7C0 +03E000 +03E000 +07C000 +07C000 +07C000 +0F8000 +ENDCHAR +STARTCHAR 2260 +ENCODING 8800 +SWIDTH 400 0 +DWIDTH 20 0 +BBX 18 27 1 5 +BITMAP +0007C0 +0007C0 +000F80 +000F80 +001F00 +003F00 +FFFF80 +FFFF80 +007C00 +007C00 +00F800 +01F000 +01F000 +03E000 +03E000 +07C000 +07C000 +FFFF80 +FFFF80 +1F0000 +1F0000 +3E0000 +3E0000 +7E0000 +7C0000 +FC0000 +180000 +ENDCHAR +STARTCHAR 2261 +ENCODING 8801 +SWIDTH 380 0 +DWIDTH 19 0 +BBX 17 22 1 7 +BITMAP +FFFF80 +FFFF80 +000000 +000000 +000000 +000000 +000000 +000000 +000000 +000000 +FFFF80 +FFFF80 +000000 +000000 +000000 +000000 +000000 +000000 +000000 +000000 +FFFF80 +FFFF80 +ENDCHAR +STARTCHAR 2262 +ENCODING 8802 +SWIDTH 420 0 +DWIDTH 21 0 +BBX 19 33 1 2 +BITMAP +0003E0 +0003E0 +0007C0 +0007C0 +000F80 +000F80 +FFFF80 +FFFF80 +001F00 +003E00 +003E00 +007C00 +007C00 +00F800 +00F800 +00F000 +FFFF80 +FFFF80 +03E000 +03E000 +03C000 +07C000 +07C000 +0F8000 +0F8000 +1F0000 +FFFF80 +FFFF80 +3E0000 +3E0000 +7C0000 +7C0000 +F80000 +ENDCHAR +STARTCHAR 2264 +ENCODING 8804 +SWIDTH 540 0 +DWIDTH 27 0 +BBX 24 31 2 2 +BITMAP +00001E +00007C +0001F8 +0003E0 +000F80 +003F00 +007C00 +01F800 +07E000 +0F8000 +3F0000 +7C0000 +F00000 +FC0000 +3E0000 +0F8000 +07E000 +01F000 +007C00 +003F00 +000F80 +0007E0 +0001F0 +00007C +00003F +000000 +000000 +000000 +000000 +7FFFF8 +7FFFF8 +ENDCHAR +STARTCHAR 2265 +ENCODING 8805 +SWIDTH 540 0 +DWIDTH 27 0 +BBX 24 30 2 3 +BITMAP +F80000 +7C0000 +1F0000 +0FC000 +03E000 +01F800 +007C00 +001F00 +000FC0 +0003E0 +0000F8 +00007E +00001F +00007C +0001F8 +0003E0 +000FC0 +001F00 +007C00 +01F800 +03E000 +0F8000 +3F0000 +7C0000 +780000 +000000 +000000 +000000 +7FFFF8 +7FFFF8 +ENDCHAR +STARTCHAR 226E +ENCODING 8814 +SWIDTH 560 0 +DWIDTH 28 0 +BBX 24 34 2 1 +BITMAP +0001F0 +0001F0 +0001F0 +0003E0 +0003E0 +0003FF +0003FC +0007F8 +0007E0 +000FC0 +001FC0 +007F80 +01FF80 +03EF80 +0F8F80 +3F1F00 +7C1F00 +F81F00 +7E1E00 +1F3E00 +0FFE00 +03FE00 +00FC00 +007E00 +007F80 +007FC0 +007BF0 +00F8F8 +00F83E +00F800 +01F000 +01F000 +01F000 +01F000 +ENDCHAR +STARTCHAR 226F +ENCODING 8815 +SWIDTH 560 0 +DWIDTH 28 0 +BBX 24 34 2 1 +BITMAP +0F8000 +0F8000 +0F8000 +0F8000 +07C000 +FFC000 +7FC000 +1FC000 +07E000 +03F000 +03F800 +03FE00 +01FF80 +01F7C0 +01F1F0 +00F0F8 +00F83E +00F81F +00F87E +0079F8 +007FE0 +007FC0 +007F00 +007C00 +01FE00 +07FE00 +0FBE00 +3E1E00 +FC1F00 +001F00 +001F00 +000F80 +000F80 +000F80 +ENDCHAR +STARTCHAR 2310 +ENCODING 8976 +SWIDTH 540 0 +DWIDTH 27 0 +BBX 25 12 2 12 +BITMAP +FFFFFF80 +FFFFFF80 +C0000000 +C0000000 +C0000000 +C0000000 +C0000000 +C0000000 +C0000000 +C0000000 +C0000000 +C0000000 +ENDCHAR +STARTCHAR 2500 +ENCODING 9472 +SWIDTH 620 0 +DWIDTH 31 0 +BBX 27 2 2 17 +BITMAP +FFFFFFE0 +FFFFFFE0 +ENDCHAR +STARTCHAR 2502 +ENCODING 9474 +SWIDTH 200 0 +DWIDTH 10 0 +BBX 5 36 2 0 +BITMAP +F8 +F8 +F8 +F8 +F8 +F8 +F8 +F8 +F8 +F8 +F8 +F8 +F8 +F8 +F8 +F8 +F8 +F8 +F8 +F8 +F8 +F8 +F8 +F8 +F8 +F8 +F8 +F8 +F8 +F8 +F8 +F8 +F8 +F8 +F8 +F8 +ENDCHAR +STARTCHAR 250C +ENCODING 9484 +SWIDTH 460 0 +DWIDTH 23 0 +BBX 20 24 2 0 +BITMAP +7FFFF0 +FFFFF0 +F80000 +F80000 +F80000 +F80000 +F80000 +F80000 +F80000 +F80000 +F80000 +F80000 +F80000 +F80000 +F80000 +F80000 +F80000 +F80000 +F80000 +F80000 +F80000 +F80000 +F80000 +F80000 +ENDCHAR +STARTCHAR 2510 +ENCODING 9488 +SWIDTH 460 0 +DWIDTH 23 0 +BBX 20 24 1 0 +BITMAP +FFFFE0 +FFFFF0 +0001F0 +0001F0 +0001F0 +0001F0 +0001F0 +0001F0 +0001F0 +0001F0 +0001F0 +0001F0 +0001F0 +0001F0 +0001F0 +0001F0 +0001F0 +0001F0 +0001F0 +0001F0 +0001F0 +0001F0 +0001F0 +0001F0 +ENDCHAR +STARTCHAR 2514 +ENCODING 9492 +SWIDTH 460 0 +DWIDTH 23 0 +BBX 20 19 2 17 +BITMAP +F80000 +F80000 +F80000 +F80000 +F80000 +F80000 +F80000 +F80000 +F80000 +F80000 +F80000 +F80000 +F80000 +F80000 +F80000 +F80000 +F80000 +FFFFF0 +7FFFF0 +ENDCHAR +STARTCHAR 2518 +ENCODING 9496 +SWIDTH 460 0 +DWIDTH 23 0 +BBX 20 19 1 17 +BITMAP +0001F0 +0001F0 +0001F0 +0001F0 +0001F0 +0001F0 +0001F0 +0001F0 +0001F0 +0001F0 +0001F0 +0001F0 +0001F0 +0001F0 +0001F0 +0001F0 +0001F0 +FFFFF0 +FFFFE0 +ENDCHAR +STARTCHAR 251C +ENCODING 9500 +SWIDTH 420 0 +DWIDTH 21 0 +BBX 18 36 2 0 +BITMAP +F80000 +F80000 +F80000 +F80000 +F80000 +F80000 +F80000 +F80000 +F80000 +F80000 +F80000 +F80000 +F80000 +F80000 +F80000 +F80000 +F80000 +FFFFC0 +FFFFC0 +F80000 +F80000 +F80000 +F80000 +F80000 +F80000 +F80000 +F80000 +F80000 +F80000 +F80000 +F80000 +F80000 +F80000 +F80000 +F80000 +F80000 +ENDCHAR +STARTCHAR 2524 +ENCODING 9508 +SWIDTH 420 0 +DWIDTH 21 0 +BBX 18 36 1 0 +BITMAP +0007C0 +0007C0 +0007C0 +0007C0 +0007C0 +0007C0 +0007C0 +0007C0 +0007C0 +0007C0 +0007C0 +0007C0 +0007C0 +0007C0 +0007C0 +0007C0 +0007C0 +FFFFC0 +FFFFC0 +0007C0 +0007C0 +0007C0 +0007C0 +0007C0 +0007C0 +0007C0 +0007C0 +0007C0 +0007C0 +0007C0 +0007C0 +0007C0 +0007C0 +0007C0 +0007C0 +0007C0 +ENDCHAR +STARTCHAR 252C +ENCODING 9516 +SWIDTH 600 0 +DWIDTH 30 0 +BBX 29 19 1 0 +BITMAP +FFFFFFF8 +FFFFFFF8 +000F8000 +000F8000 +000F8000 +000F8000 +000F8000 +000F8000 +000F8000 +000F8000 +000F8000 +000F8000 +000F8000 +000F8000 +000F8000 +000F8000 +000F8000 +000F8000 +000F8000 +ENDCHAR +STARTCHAR 2534 +ENCODING 9524 +SWIDTH 600 0 +DWIDTH 30 0 +BBX 29 22 1 14 +BITMAP +000F8000 +000F8000 +000F8000 +000F8000 +000F8000 +000F8000 +000F8000 +000F8000 +000F8000 +000F8000 +000F8000 +000F8000 +000F8000 +000F8000 +000F8000 +000F8000 +000F8000 +000F8000 +000F8000 +000F8000 +FFFFFFF8 +FFFFFFF8 +ENDCHAR +STARTCHAR 253C +ENCODING 9532 +SWIDTH 560 0 +DWIDTH 28 0 +BBX 27 36 1 0 +BITMAP +001F0000 +001F0000 +001F0000 +001F0000 +001F0000 +001F0000 +001F0000 +001F0000 +001F0000 +001F0000 +001F0000 +001F0000 +001F0000 +001F0000 +001F0000 +001F0000 +001F0000 +001F0000 +001F0000 +001F0000 +FFFFFFE0 +FFFFFFE0 +001F0000 +001F0000 +001F0000 +001F0000 +001F0000 +001F0000 +001F0000 +001F0000 +001F0000 +001F0000 +001F0000 +001F0000 +001F0000 +001F0000 +ENDCHAR +STARTCHAR 2550 +ENCODING 9552 +SWIDTH 600 0 +DWIDTH 30 0 +BBX 27 9 2 10 +BITMAP +FFFFFFE0 +FFFFFFE0 +00000000 +00000000 +00000000 +00000000 +00000000 +FFFFFFE0 +FFFFFFE0 +ENDCHAR +STARTCHAR 2551 +ENCODING 9553 +SWIDTH 320 0 +DWIDTH 16 0 +BBX 12 36 2 0 +BITMAP +F9F0 +F9F0 +F9F0 +F9F0 +F9F0 +F9F0 +F9F0 +F9F0 +F9F0 +F9F0 +F9F0 +F9F0 +F9F0 +F9F0 +F9F0 +F9F0 +F9F0 +F9F0 +F9F0 +F9F0 +F9F0 +F9F0 +F9F0 +F9F0 +F9F0 +F9F0 +F9F0 +F9F0 +F9F0 +F9F0 +F9F0 +F9F0 +F9F0 +F9F0 +F9F0 +F9F0 +ENDCHAR +STARTCHAR 2552 +ENCODING 9554 +SWIDTH 460 0 +DWIDTH 23 0 +BBX 20 19 2 0 +BITMAP +7FFFF0 +FFFFF0 +F80000 +F80000 +F80000 +F80000 +F80000 +FFFFF0 +FFFFF0 +F80000 +F80000 +F80000 +F80000 +F80000 +F80000 +F80000 +F80000 +F80000 +F80000 +ENDCHAR +STARTCHAR 2553 +ENCODING 9555 +SWIDTH 460 0 +DWIDTH 23 0 +BBX 20 19 2 0 +BITMAP +7FFFF0 +FFFFF0 +F9F000 +F9F000 +F9F000 +F9F000 +F9F000 +F9F000 +F9F000 +F9F000 +F9F000 +F9F000 +F9F000 +F9F000 +F9F000 +F9F000 +F9F000 +F9F000 +F9F000 +ENDCHAR +STARTCHAR 2554 +ENCODING 9556 +SWIDTH 460 0 +DWIDTH 23 0 +BBX 20 19 2 0 +BITMAP +7FFFF0 +FFFFF0 +F80000 +F80000 +F80000 +F80000 +F80000 +F8FFF0 +F9FFF0 +F9F000 +F9F000 +F9F000 +F9F000 +F9F000 +F9F000 +F9F000 +F9F000 +F9F000 +F9F000 +ENDCHAR +STARTCHAR 2555 +ENCODING 9557 +SWIDTH 460 0 +DWIDTH 23 0 +BBX 20 19 1 0 +BITMAP +FFFFE0 +FFFFF0 +0001F0 +0001F0 +0001F0 +0001F0 +0001F0 +FFFFF0 +FFFFF0 +0001F0 +0001F0 +0001F0 +0001F0 +0001F0 +0001F0 +0001F0 +0001F0 +0001F0 +0001F0 +ENDCHAR +STARTCHAR 2556 +ENCODING 9558 +SWIDTH 480 0 +DWIDTH 24 0 +BBX 21 19 1 0 +BITMAP +FFFFF0 +FFFFF8 +007CF8 +007CF8 +007CF8 +007CF8 +007CF8 +007CF8 +007CF8 +007CF8 +007CF8 +007CF8 +007CF8 +007CF8 +007CF8 +007CF8 +007CF8 +007CF8 +007CF8 +ENDCHAR +STARTCHAR 2557 +ENCODING 9559 +SWIDTH 480 0 +DWIDTH 24 0 +BBX 20 19 2 0 +BITMAP +FFFFE0 +FFFFF0 +0001F0 +0001F0 +0001F0 +0001F0 +0001F0 +0001F0 +FFF9F0 +FFFDF0 +007DF0 +007DF0 +007DF0 +007DF0 +007DF0 +007DF0 +007DF0 +007DF0 +007DF0 +ENDCHAR +STARTCHAR 2558 +ENCODING 9560 +SWIDTH 460 0 +DWIDTH 23 0 +BBX 20 24 2 12 +BITMAP +F80000 +F80000 +F80000 +F80000 +F80000 +F80000 +F80000 +F80000 +F80000 +F80000 +F80000 +F80000 +F80000 +F80000 +F80000 +FFFFF0 +FFFFF0 +F80000 +F80000 +F80000 +F80000 +F80000 +FFFFF0 +7FFFF0 +ENDCHAR +STARTCHAR 2559 +ENCODING 9561 +SWIDTH 460 0 +DWIDTH 23 0 +BBX 20 21 2 15 +BITMAP +F9F000 +F9F000 +F9F000 +F9F000 +F9F000 +F9F000 +F9F000 +F9F000 +F9F000 +F9F000 +F9F000 +F9F000 +F9F000 +F9F000 +F9F000 +F9F000 +F9F000 +F9F000 +F9F000 +FFFFF0 +7FFFF0 +ENDCHAR +STARTCHAR 255A +ENCODING 9562 +SWIDTH 460 0 +DWIDTH 23 0 +BBX 20 24 2 12 +BITMAP +F9F000 +F9F000 +F9F000 +F9F000 +F9F000 +F9F000 +F9F000 +F9F000 +F9F000 +F9F000 +F9F000 +F9F000 +F9F000 +F9F000 +F9F000 +F9FFF0 +F8FFF0 +F80000 +F80000 +F80000 +F80000 +F80000 +FFFFF0 +7FFFF0 +ENDCHAR +STARTCHAR 255B +ENCODING 9563 +SWIDTH 460 0 +DWIDTH 23 0 +BBX 20 24 1 12 +BITMAP +0001F0 +0001F0 +0001F0 +0001F0 +0001F0 +0001F0 +0001F0 +0001F0 +0001F0 +0001F0 +0001F0 +0001F0 +0001F0 +0001F0 +0001F0 +FFFFF0 +FFFFF0 +0001F0 +0001F0 +0001F0 +0001F0 +0001F0 +FFFFF0 +FFFFE0 +ENDCHAR +STARTCHAR 255C +ENCODING 9564 +SWIDTH 480 0 +DWIDTH 24 0 +BBX 21 21 1 15 +BITMAP +007CF8 +007CF8 +007CF8 +007CF8 +007CF8 +007CF8 +007CF8 +007CF8 +007CF8 +007CF8 +007CF8 +007CF8 +007CF8 +007CF8 +007CF8 +007CF8 +007CF8 +007CF8 +007CF8 +FFFFF8 +FFFFF0 +ENDCHAR +STARTCHAR 255D +ENCODING 9565 +SWIDTH 460 0 +DWIDTH 23 0 +BBX 20 24 1 12 +BITMAP +007DF0 +007DF0 +007DF0 +007DF0 +007DF0 +007DF0 +007DF0 +007DF0 +007DF0 +007DF0 +007DF0 +007DF0 +007DF0 +007DF0 +007DF0 +FFFDF0 +FFF9F0 +0001F0 +0001F0 +0001F0 +0001F0 +0001F0 +FFFFF0 +FFFFE0 +ENDCHAR +STARTCHAR 255E +ENCODING 9566 +SWIDTH 420 0 +DWIDTH 21 0 +BBX 18 36 2 0 +BITMAP +F80000 +F80000 +F80000 +F80000 +F80000 +F80000 +F80000 +F80000 +F80000 +F80000 +F80000 +F80000 +F80000 +F80000 +F80000 +F80000 +F80000 +FFFFC0 +FFFFC0 +F80000 +F80000 +F80000 +F80000 +F80000 +FFFFC0 +FFFFC0 +F80000 +F80000 +F80000 +F80000 +F80000 +F80000 +F80000 +F80000 +F80000 +F80000 +ENDCHAR +STARTCHAR 255F +ENCODING 9567 +SWIDTH 460 0 +DWIDTH 23 0 +BBX 20 36 2 0 +BITMAP +F9F000 +F9F000 +F9F000 +F9F000 +F9F000 +F9F000 +F9F000 +F9F000 +F9F000 +F9F000 +F9F000 +F9F000 +F9F000 +F9F000 +F9F000 +F9F000 +F9F000 +F9F000 +F9F000 +F9F000 +F9FFF0 +F9FFF0 +F9F000 +F9F000 +F9F000 +F9F000 +F9F000 +F9F000 +F9F000 +F9F000 +F9F000 +F9F000 +F9F000 +F9F000 +F9F000 +F9F000 +ENDCHAR +STARTCHAR 2560 +ENCODING 9568 +SWIDTH 460 0 +DWIDTH 23 0 +BBX 20 36 2 0 +BITMAP +F9F000 +F9F000 +F9F000 +F9F000 +F9F000 +F9F000 +F9F000 +F9F000 +F9F000 +F9F000 +F9F000 +F9F000 +F9F000 +F9F000 +F9F000 +F9FFF0 +F8FFF0 +F80000 +F80000 +F80000 +F80000 +F80000 +F8FFF0 +F9FFF0 +F9F000 +F9F000 +F9F000 +F9F000 +F9F000 +F9F000 +F9F000 +F9F000 +F9F000 +F9F000 +F9F000 +F9F000 +ENDCHAR +STARTCHAR 2561 +ENCODING 9569 +SWIDTH 420 0 +DWIDTH 21 0 +BBX 18 38 1 -2 +BITMAP +0007C0 +0007C0 +0007C0 +0007C0 +0007C0 +0007C0 +0007C0 +0007C0 +0007C0 +0007C0 +0007C0 +0007C0 +0007C0 +0007C0 +0007C0 +0007C0 +0007C0 +FFFFC0 +FFFFC0 +0007C0 +0007C0 +0007C0 +0007C0 +0007C0 +FFFFC0 +FFFFC0 +0007C0 +0007C0 +0007C0 +0007C0 +0007C0 +0007C0 +0007C0 +0007C0 +0007C0 +0007C0 +0007C0 +0007C0 +ENDCHAR +STARTCHAR 2562 +ENCODING 9570 +SWIDTH 460 0 +DWIDTH 23 0 +BBX 21 36 0 0 +BITMAP +007CF8 +007CF8 +007CF8 +007CF8 +007CF8 +007CF8 +007CF8 +007CF8 +007CF8 +007CF8 +007CF8 +007CF8 +007CF8 +007CF8 +007CF8 +007CF8 +007CF8 +007CF8 +007CF8 +007CF8 +FFFCF8 +FFFCF8 +007CF8 +007CF8 +007CF8 +007CF8 +007CF8 +007CF8 +007CF8 +007CF8 +007CF8 +007CF8 +007CF8 +007CF8 +007CF8 +007CF8 +ENDCHAR +STARTCHAR 2563 +ENCODING 9571 +SWIDTH 460 0 +DWIDTH 23 0 +BBX 21 36 0 0 +BITMAP +007CF8 +007CF8 +007CF8 +007CF8 +007CF8 +007CF8 +007CF8 +007CF8 +007CF8 +007CF8 +007CF8 +007CF8 +007CF8 +007CF8 +007CF8 +FFFCF8 +FFF8F8 +0000F8 +0000F8 +0000F8 +0000F8 +0000F8 +FFF8F8 +FFFCF8 +007CF8 +007CF8 +007CF8 +007CF8 +007CF8 +007CF8 +007CF8 +007CF8 +007CF8 +007CF8 +007CF8 +007CF8 +ENDCHAR +STARTCHAR 2564 +ENCODING 9572 +SWIDTH 600 0 +DWIDTH 30 0 +BBX 29 19 1 0 +BITMAP +FFFFFFF0 +FFFFFFF0 +00000000 +00000000 +00000000 +00000000 +00000000 +FFFFFFF8 +FFFFFFF8 +000F8000 +000F8000 +000F8000 +000F8000 +000F8000 +000F8000 +000F8000 +000F8000 +000F8000 +000F8000 +ENDCHAR +STARTCHAR 2565 +ENCODING 9573 +SWIDTH 620 0 +DWIDTH 31 0 +BBX 28 19 1 0 +BITMAP +FFFFFFF0 +FFFFFFF0 +007DF000 +007DF000 +007DF000 +007DF000 +007DF000 +007DF000 +007DF000 +007DF000 +007DF000 +007DF000 +007DF000 +007DF000 +007DF000 +007DF000 +007DF000 +007DF000 +007DF000 +ENDCHAR +STARTCHAR 2566 +ENCODING 9574 +SWIDTH 600 0 +DWIDTH 30 0 +BBX 28 19 1 0 +BITMAP +FFFFFFF0 +FFFFFFF0 +00000000 +00000000 +00000000 +00000000 +00000000 +FFF8FFE0 +FFFDFC00 +007DF000 +007DF000 +007DF000 +007DF000 +007DF000 +007DF000 +007DF000 +007DF000 +007DF000 +007DF000 +ENDCHAR +STARTCHAR 2567 +ENCODING 9575 +SWIDTH 600 0 +DWIDTH 30 0 +BBX 29 24 1 12 +BITMAP +000F8000 +000F8000 +000F8000 +000F8000 +000F8000 +000F8000 +000F8000 +000F8000 +000F8000 +000F8000 +000F8000 +000F8000 +000F8000 +000F8000 +000F8000 +FFFFFFF8 +FFFFFFF8 +00000000 +00000000 +00000000 +00000000 +00000000 +FFFFFFF0 +FFFFFFF0 +ENDCHAR +STARTCHAR 2568 +ENCODING 9576 +SWIDTH 620 0 +DWIDTH 31 0 +BBX 28 22 1 14 +BITMAP +007DF000 +007DF000 +007DF000 +007DF000 +007DF000 +007DF000 +007DF000 +007DF000 +007DF000 +007DF000 +007DF000 +007DF000 +007DF000 +007DF000 +007DF000 +007DF000 +007DF000 +007DF000 +007DF000 +007DF000 +FFFFFFF0 +FFFFFFF0 +ENDCHAR +STARTCHAR 2569 +ENCODING 9577 +SWIDTH 600 0 +DWIDTH 30 0 +BBX 28 24 1 12 +BITMAP +007DF000 +007DF000 +007DF000 +007DF000 +007DF000 +007DF000 +007DF000 +007DF000 +007DF000 +007DF000 +007DF000 +007DF000 +007DF000 +007DF000 +007DF000 +FFFDFFF0 +FFF8FFF0 +00000000 +00000000 +00000000 +00000000 +00000000 +FFFFFFF0 +FFFFFFF0 +ENDCHAR +STARTCHAR 256A +ENCODING 9578 +SWIDTH 600 0 +DWIDTH 30 0 +BBX 29 36 1 0 +BITMAP +001F0000 +001F0000 +001F0000 +001F0000 +001F0000 +001F0000 +001F0000 +001F0000 +001F0000 +001F0000 +001F0000 +001F0000 +001F0000 +001F0000 +001F0000 +FFFFFFF8 +FFFFFFF8 +001F0000 +001F0000 +001F0000 +001F0000 +001F0000 +FFFFFFF8 +FFFFFFF8 +001F0000 +001F0000 +001F0000 +001F0000 +001F0000 +001F0000 +001F0000 +001F0000 +001F0000 +001F0000 +001F0000 +001F0000 +ENDCHAR +STARTCHAR 256B +ENCODING 9579 +SWIDTH 600 0 +DWIDTH 30 0 +BBX 28 36 1 0 +BITMAP +007DF000 +007DF000 +007DF000 +007DF000 +007DF000 +007DF000 +007DF000 +007DF000 +007DF000 +007DF000 +007DF000 +007DF000 +007DF000 +007DF000 +007DF000 +007DF000 +007DF000 +FFFFFFF0 +FFFFFFF0 +007DF000 +007DF000 +007DF000 +007DF000 +007DF000 +007DF000 +007DF000 +007DF000 +007DF000 +007DF000 +007DF000 +007DF000 +007DF000 +007DF000 +007DF000 +007DF000 +007DF000 +ENDCHAR +STARTCHAR 256C +ENCODING 9580 +SWIDTH 620 0 +DWIDTH 31 0 +BBX 29 36 1 0 +BITMAP +007CF800 +007CF800 +007CF800 +007CF800 +007CF800 +007CF800 +007CF800 +007CF800 +007CF800 +007CF800 +007CF800 +007CF800 +007CF800 +007CF800 +007CF800 +FFFCFFF8 +FFF87FF8 +00000000 +00000000 +00000000 +00000000 +00000000 +FFF87FF8 +FFFCFFF8 +007CF800 +007CF800 +007CF800 +007CF800 +007CF800 +007CF800 +007CF800 +007CF800 +007CF800 +007CF800 +007CF800 +007CF800 +ENDCHAR +STARTCHAR 263A +ENCODING 9786 +SWIDTH 860 0 +DWIDTH 43 0 +BBX 39 40 2 0 +BITMAP +0001FE0000 +000FFFE000 +003E01F800 +00F0003C00 +01C0000F00 +0300000380 +06000001C0 +0C000000E0 +1800000060 +1000000030 +2000000038 +6000000018 +4007C3E01C +4007C3E00C +4007C3E00C +8007C3E00C +8000000006 +8000000006 +8000000006 +8000000006 +8000000006 +8000000006 +8000000006 +8000000006 +804000080E +404000080C +406000180C +403000301C +6018006018 +200F01C038 +1003FF0030 +1800FC0060 +0C000000E0 +06000001C0 +0300000380 +01C0000F00 +00E0003C00 +003E01F800 +000FFFE000 +0001FE0000 +ENDCHAR +STARTCHAR 2640 +ENCODING 9792 +SWIDTH 620 0 +DWIDTH 31 0 +BBX 29 42 1 -4 +BITMAP +001FC000 +00FFF800 +01E03E00 +03000F00 +0E000380 +0C0001C0 +180000E0 +30000060 +20000070 +60000030 +40000030 +40000018 +40000018 +40000018 +C0000018 +40000018 +40000018 +40000018 +40000030 +60000030 +20000070 +30000060 +180000E0 +0C0001C0 +0E000380 +07000F00 +01E03E00 +00FFF800 +001FE000 +00030000 +00030000 +00030000 +00030000 +00030000 +00030000 +00030000 +00FFF800 +00FFF800 +00030000 +00030000 +00030000 +00030000 +ENDCHAR +STARTCHAR 2641 +ENCODING 9793 +SWIDTH 460 0 +DWIDTH 23 0 +BBX 1 1 0 0 +BITMAP +00 +ENDCHAR +STARTCHAR 2642 +ENCODING 9794 +SWIDTH 740 0 +DWIDTH 37 0 +BBX 33 33 2 0 +BITMAP +0000007F80 +0000007F80 +0000000380 +0000000580 +0000001980 +003F803180 +00FFF06180 +03C07CC180 +06001F8000 +1C00070000 +1000038000 +200001C000 +600000C000 +4000006000 +C000006000 +8000006000 +8000003000 +8000003000 +8000003000 +8000003000 +8000003000 +8000003000 +8000007000 +8000006000 +4000006000 +600000C000 +200001C000 +1000038000 +1C00070000 +06001E0000 +03C07C0000 +00FFF00000 +003FC00000 +ENDCHAR +STARTCHAR 2663 +ENCODING 9827 +SWIDTH 660 0 +DWIDTH 33 0 +BBX 32 34 1 0 +BITMAP +0007E000 +001FF800 +003FFC00 +007FFE00 +007FFE00 +00FFFF00 +00FFFF00 +00FFFF00 +00FFFF00 +00FFFF00 +00FFFF00 +00FFFF00 +01FFFF80 +0FFFFFF0 +1FFFFFF8 +3FFFFFFC +7FFFFFFE +7FFFFFFE +7FFFFFFE +FFFFFFFF +FFFFFFFF +7FFFFFFF +7FFFFFFE +7FFFFFFE +3FFFFFFC +3FFFFFFC +1FFDBFF8 +07F18FE0 +00018000 +00018000 +00018000 +00018000 +0007F000 +0007F000 +ENDCHAR +STARTCHAR 2665 +ENCODING 9829 +SWIDTH 700 0 +DWIDTH 35 0 +BBX 32 34 2 1 +BITMAP +07E007C0 +1FF81FF0 +3FFC7FF8 +7FFE7FFC +7FFEFFFE +FFFFFFFE +FFFFFFFE +FFFFFFFF +FFFFFFFF +FFFFFFFF +FFFFFFFF +FFFFFFFF +FFFFFFFE +FFFFFFFE +7FFFFFFE +7FFFFFFC +7FFFFFFC +3FFFFFFC +3FFFFFF8 +1FFFFFF8 +1FFFFFF0 +0FFFFFE0 +07FFFFE0 +07FFFFC0 +03FFFF80 +01FFFF80 +00FFFF00 +00FFFE00 +007FFC00 +003FF800 +001FF000 +000FE000 +0003C000 +00010000 +ENDCHAR +STARTCHAR 2666 +ENCODING 9830 +SWIDTH 540 0 +DWIDTH 27 0 +BBX 24 38 1 -1 +BITMAP +000800 +001800 +001C00 +003E00 +007E00 +007F00 +00FF00 +00FF80 +01FFC0 +03FFC0 +03FFE0 +07FFF0 +0FFFF0 +0FFFF8 +1FFFFC +3FFFFC +3FFFFE +7FFFFE +7FFFFF +FFFFFF +7FFFFF +3FFFFE +3FFFFC +1FFFFC +1FFFF8 +0FFFF8 +07FFF0 +07FFE0 +03FFE0 +01FFC0 +01FF80 +00FF80 +007F00 +007E00 +003E00 +001C00 +001800 +000800 +ENDCHAR +STARTCHAR 2669 +ENCODING 9833 +SWIDTH 420 0 +DWIDTH 21 0 +BBX 19 37 0 0 +BITMAP +000060 +000060 +000060 +000060 +000060 +000060 +000060 +000060 +000060 +000060 +000060 +000060 +000060 +000060 +000060 +000060 +000060 +000060 +000060 +000060 +000060 +000060 +000060 +000060 +000060 +01FC60 +07FF60 +1FFFE0 +3FFFE0 +7FFFE0 +7FFFE0 +FFFFE0 +7FFFC0 +7FFF80 +3FFF00 +1FFE00 +07F000 +ENDCHAR +STARTCHAR 266A +ENCODING 9834 +SWIDTH 640 0 +DWIDTH 32 0 +BBX 31 39 0 -1 +BITMAP +00006000 +00006000 +00006000 +00007F80 +00007FE0 +000061F0 +000060F8 +000060F8 +00006078 +0000607C +0000607C +0000603E +00006010 +00006000 +00006000 +00006000 +00006000 +00006000 +00006000 +00006000 +00006000 +00006000 +00006000 +00006000 +00006000 +00006000 +00006000 +01FC6000 +0FFF6000 +1FFFE000 +3FFFE000 +7FFFE000 +7FFFE000 +FFFFE000 +7FFFC000 +7FFF8000 +3FFF0000 +1FFE0000 +07F00000 +ENDCHAR +STARTCHAR 266B +ENCODING 9835 +SWIDTH 840 0 +DWIDTH 42 0 +BBX 39 44 1 -4 +BITMAP +0000000006 +00000000FE +0000001FFE +000001FFFE +00003FFFFE +00007FFF86 +00007FF806 +00007F0006 +0000700006 +0000600006 +0000600006 +0000600006 +0000600006 +0000600006 +0000600006 +0000600006 +0000600006 +0000600006 +0000600006 +0000600006 +0000600006 +0000600006 +0000600006 +0000600006 +0000600006 +0000600006 +0000600006 +0000600006 +0000603FE6 +000060FFFE +000061FFFE +000063FFFE +01FC67FFFE +0FFF67FFFE +1FFFEFFFFE +3FFFE7FFFC +7FFFE7FFF8 +7FFFE3FFF0 +FFFFE1FFC0 +7FFFC00800 +7FFFC00000 +3FFF000000 +1FFE000000 +07F0000000 +ENDCHAR +STARTCHAR 266C +ENCODING 9836 +SWIDTH 840 0 +DWIDTH 42 0 +BBX 39 43 1 -2 +BITMAP +0000000006 +00000000FE +0000001FFE +000003FFFE +00003FFFE6 +00007FFC06 +00007FC006 +0000780006 +0000600006 +0000600006 +0000600006 +000060001E +00006003FE +0000603FFE +000067FFF6 +00007FFF06 +00007FE006 +00007E0006 +0000600006 +0000600006 +0000600006 +0000600006 +0000600006 +0000600006 +0000600006 +0000600006 +0000600006 +0000601FC6 +000060FFF6 +000061FFFE +000063FFFE +007867FFFE +07FF67FFFE +1FFFEFFFFE +3FFFE7FFFC +7FFFE7FFF8 +7FFFE3FFF0 +FFFFE1FFE0 +7FFFC07F00 +7FFFC00000 +3FFF000000 +1FFE000000 +07F0000000 +ENDCHAR +STARTCHAR FB01 +ENCODING 64257 +SWIDTH 460 0 +DWIDTH 23 0 +BBX 20 36 1 0 +BITMAP +03E000 +0FF800 +0F9800 +1F0000 +1F0000 +1F0000 +1F0000 +1F0000 +1F0000 +1F0000 +1F0000 +1F0000 +FFFFC0 +FFE7C0 +1F07C0 +1F07C0 +1F07C0 +1F07C0 +1F07C0 +1F07C0 +1F07C0 +1F07C0 +1F07C0 +1F07C0 +1F07C0 +1F07C0 +1F07C0 +1F07C0 +1F07C0 +1F07C0 +1F07C0 +1F07C0 +1F07C0 +1F07C0 +FFFFF0 +FFFFF0 +ENDCHAR +STARTCHAR FB02 +ENCODING 64258 +SWIDTH 460 0 +DWIDTH 23 0 +BBX 21 36 1 0 +BITMAP +03FFC0 +0FFFC0 +0F9FC0 +1F07C0 +1F07C0 +1F07C0 +1F07C0 +1F07C0 +1F07C0 +1F07C0 +1F07C0 +1F07C0 +FFE7C0 +FFE7C0 +1F07C0 +1F07C0 +1F07C0 +1F07C0 +1F07C0 +1F07C0 +1F07C0 +1F07C0 +1F07C0 +1F07C0 +1F07C0 +1F07C0 +1F07C0 +1F07C0 +1F07C0 +1F07C0 +1F07C0 +1F07C0 +1F07C0 +1F07C0 +FFFFF8 +FFFFF8 +ENDCHAR +ENDFONT diff --git a/contrib/sdk/sources/SDL-1.2.2/SDL_bdf-1.2/showbdf.c b/contrib/sdk/sources/SDL-1.2.2/SDL_bdf-1.2/showbdf.c new file mode 100644 index 000000000..11c4bd43a --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/SDL_bdf-1.2/showbdf.c @@ -0,0 +1,185 @@ +/* +showbdf - shows a BDF font on the screen +Placed in the public domain by Andre de Leiradella on 21-jan-2003. + +You'll need SDL, SDLmain and SDL_gfxPrimitives to compile this program. +*/ + +#include +#include +#include +#include +#include +#include "SDL_bdf.h" +#include "SDL_gfxPrimitives.h" + +/* Reads a byte from a rwops. */ +static int ReadByteRwops(void *info) { + unsigned char b; + + if (SDL_RWread((SDL_RWops *)info, &b, 1, 1) != 1) + return -1; + return b; +} + +/* Put a pixel on a SDL surface. */ +static void PutPixel(void *surface, int x, int y, unsigned int color) { + pixelColor((SDL_Surface *)surface, (Sint16)x, (Sint16)y, (Uint32)color); +} + +/* Put a pixel on a b&w surface with 1 bit per pixel. The first 4 bytes hold the width of the surface. */ +static void PutBWPixel(void *surface, int x, int y, unsigned int color) { + (void)color; + y *= *(int *)surface; + ((unsigned char *)surface)[y + x / 8 + sizeof(int)] |= 1 << (x & 7); +} + +/* +Example showing how to simulate anti-aliased text reducing the size of an +image. This function will render a text to a new SDL_Surface. +*/ +static SDL_Surface *DrawAAH(BDF_Font *font, char *text, int entities, Uint8 r0, Uint8 g0, Uint8 b0, Uint8 r, Uint8 g, Uint8 b) { + SDL_Surface *surface; + int x0, y0, w, h, a; + unsigned char *pixels, *aux, *endimage, *endline; + static Uint8 alpha[16] = { 0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4}; + + if (entities) + BDF_SizeEntitiesH(font, text, &x0, &y0, &w, &h); + else + BDF_SizeH(font, text, &x0, &y0, &w, &h); +#if SDL_BYTEORDER == SDL_BIG_ENDIAN + surface = SDL_CreateRGBSurface(SDL_SWSURFACE | SDL_SRCALPHA, (w + 3) / 4, (h + 3) / 4, 32, 0xFF000000, 0x00FF0000, 0x0000FF00, 0x000000FF); +#else + surface = SDL_CreateRGBSurface(SDL_SWSURFACE | SDL_SRCALPHA, (w + 3) / 4, (h + 3) / 4, 32, 0x000000FF, 0x0000FF00, 0x00FF0000, 0xFF000000); +#endif + if (surface == NULL) + return NULL; + boxRGBA(surface, 0, 0, surface->w - 1, surface->h - 1, r0, g0, b0, 255); + w = (w + 7) / 8; + h = ((h + 3) / 4) * 4; + a = w * h * + sizeof(int); + pixels = (unsigned char *)malloc(a); + if (pixels == NULL) { + SDL_OutOfMemory(); + SDL_FreeSurface(surface); + return NULL; + } + memset(pixels, 0, a); + *(int *)pixels = w; + if (entities) + BDF_DrawEntitiesH(pixels, PutBWPixel, font, text, x0, y0, 0); + else + BDF_DrawH(pixels, PutBWPixel, font, text, x0, y0, 0); + aux = pixels + sizeof(int); + endimage = aux + w * h; + for (y0 = 0; aux < endimage; y0++, aux += w * 3) + for (endline = aux + w, x0 = 0; aux < endline; x0 += 2, aux++) { + a = alpha[aux[0] & 15]; + a += alpha[aux[w] & 15]; + a += alpha[aux[w * 2] & 15]; + a += alpha[aux[w * 3] & 15]; + pixelRGBA(surface, x0, y0, r, g, b, a * 255 / 16); + a = alpha[(aux[0] >> 4) & 15]; + a += alpha[(aux[w] >> 4) & 15]; + a += alpha[(aux[w * 2] >> 4) & 15]; + a += alpha[(aux[w * 3] >> 4) & 15]; + pixelRGBA(surface, x0 + 1, y0, r, g, b, a * 255 / 16); + } + free(pixels); + return surface; +} + +/* Calls DrawAAH to render the text without support to entities. */ +static SDL_Surface *RenderAAH(BDF_Font *font, char *text, Uint8 r0, Uint8 g0, Uint8 b0, Uint8 r, Uint8 g, Uint8 b) { + return DrawAAH(font, text, 0, r0, g0, b0, r, g, b); +} + +/* Calls DrawAAH to render the text with support to entities. */ +static SDL_Surface *RenderEntitiesAAH(BDF_Font *font, char *text, Uint8 r0, Uint8 g0, Uint8 b0, Uint8 r, Uint8 g, Uint8 b) { + return DrawAAH(font, text, 1, r0, g0, b0, r, g, b); +} + +int main(int argc, char *argv[]) { + SDL_RWops *rwops; + BDF_Font *font; + SDL_Surface *screen, *aatext; + int x0, y0, w, h; + SDL_Rect pos; + SDL_Event event; + char *text = "The quick fox jumped over the lazy dog"; + + if (argc != 2) { + fprintf(stderr, "Usage: showbdf \n"); + return -1; + } + /* Reads the font. */ + rwops = SDL_RWFromFile(argv[1], "rb"); + font = BDF_OpenFont(ReadByteRwops, (void *)rwops, &w); + SDL_RWclose(rwops); + /* Check for error code. */ + switch (w) { + case BDF_MEMORYERROR: + fprintf(stderr, "Not enough memory reading BDF font\n"); + return -1; + case BDF_READERROR: + fprintf(stderr, "Error while reading BDF font\n"); + return -1; + case BDF_WRONGVERSION: + fprintf(stderr, "Wrong BDF font version, can only handle versions up to 2.2\n"); + return -1; + case BDF_CANNOTHANDLEVERTICAL: + fprintf(stderr, "Wrong BDF font direction, can only handle horizontal direction\n"); + return -1; + case BDF_TOOMANYCHARACTERS: + case BDF_TOOFEWCHARACTERS: + case BDF_PARSEERROR: + fprintf(stderr, "Invalid BDF font\n"); + return -1; + } + /* Init SDL. */ + if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_NOPARACHUTE) < 0) { + fprintf(stderr, "Couldn't initialize SDL: %s\n", SDL_GetError()); + return -1; + } + atexit(SDL_Quit); + /* Check the size of the image required to acomodate the rendered text. */ + BDF_SizeH(font, text, &x0, &y0, &w, &h); + /* Set the video a little bit bigger than the minimum. */ + screen = SDL_SetVideoMode(w + 10, h + 15 + (h + 3) / 4, 0, SDL_SWSURFACE); + if (screen == NULL) { + fprintf(stderr, "Couldn't set %dx%d video mode: %s\n", w + 10, h + 15 + (h + 3) / 4, SDL_GetError()); + return -1; + } + /* Clear the screen to white. */ + boxColor(screen, 0, 0, screen->w - 1, screen->h - 1, 0xFFFFFFFF); + /* Render the text to the screen with black. */ + BDF_DrawH((void *)screen, PutPixel, font, text, x0 + 5, y0 + 5, 0x000000FF); + /* Render the same text with white blackgorund and black foreground to a new surface. */ + aatext = RenderAAH(font, text, 255, 255, 255, 0, 0, 0); + if (aatext == NULL) { + fprintf(stderr, "Couldn't render anti-aliased text: %s\n", SDL_GetError()); + return -1; + } + /* Blit it to the screen. */ + pos.x = (screen->w - aatext->w) / 2; + pos.y = h + 5 + aatext->h / 2; + SDL_BlitSurface(aatext, NULL, screen, &pos); + SDL_FreeSurface(aatext); + /* Update the screen. */ + SDL_UpdateRect(screen, 0, 0, 0, 0); + /* Wait for something to happen... */ + for(;;) { + if (SDL_WaitEvent(&event) < 0) { + fprintf(stderr, "SDL_PullEvent() error: %s\n", SDL_GetError()); + return -1; + } + switch (event.type) { + case SDL_MOUSEBUTTONDOWN: + case SDL_KEYDOWN: + case SDL_QUIT: + BDF_CloseFont(font); + return 0; + } + } +} diff --git a/contrib/sdk/sources/SDL-1.2.2/SDL_draw/AUTHORS b/contrib/sdk/sources/SDL-1.2.2/SDL_draw/AUTHORS new file mode 100644 index 000000000..0223710bb --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/SDL_draw/AUTHORS @@ -0,0 +1,3 @@ +Mario Palomo Torrero +Jose M. de la Huerga Fernández +Pepe González Mora diff --git a/contrib/sdk/sources/SDL-1.2.2/SDL_draw/COPYING b/contrib/sdk/sources/SDL-1.2.2/SDL_draw/COPYING new file mode 100644 index 000000000..191a97fe9 --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/SDL_draw/COPYING @@ -0,0 +1,437 @@ + GNU LIBRARY GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 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. + +[This is the first released version of the library GPL. It is + numbered 2 because it goes with version 2 of the ordinary GPL.] + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +Licenses are intended to guarantee your freedom to share and change +free software--to make sure the software is free for all its users. + + This license, the Library General Public License, applies to some +specially designated Free Software Foundation software, and to any +other libraries whose authors decide to use it. You can use it for +your libraries, 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 library, or if you modify it. + + For example, if you distribute copies of the library, whether gratis +or for a fee, you must give the recipients all the rights that we gave +you. You must make sure that they, too, receive or can get the source +code. If you link a program with the library, you must provide +complete object files to the recipients so that they can relink them +with the library, after making changes to the library and recompiling +it. And you must show them these terms so they know their rights. + + Our method of protecting your rights has two steps: (1) copyright +the library, and (2) offer you this license which gives you legal +permission to copy, distribute and/or modify the library. + + Also, for each distributor's protection, we want to make certain +that everyone understands that there is no warranty for this free +library. If the library is modified by someone else and passed on, we +want its recipients to know that what they have is not the original +version, 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 companies distributing free +software will individually obtain patent licenses, thus in effect +transforming the program into proprietary software. To prevent this, +we have made it clear that any patent must be licensed for everyone's +free use or not licensed at all. + + Most GNU software, including some libraries, is covered by the ordinary +GNU General Public License, which was designed for utility programs. This +license, the GNU Library General Public License, applies to certain +designated libraries. This license is quite different from the ordinary +one; be sure to read it in full, and don't assume that anything in it is +the same as in the ordinary license. + + The reason we have a separate public license for some libraries is that +they blur the distinction we usually make between modifying or adding to a +program and simply using it. Linking a program with a library, without +changing the library, is in some sense simply using the library, and is +analogous to running a utility program or application program. However, in +a textual and legal sense, the linked executable is a combined work, a +derivative of the original library, and the ordinary General Public License +treats it as such. + + Because of this blurred distinction, using the ordinary General +Public License for libraries did not effectively promote software +sharing, because most developers did not use the libraries. We +concluded that weaker conditions might promote sharing better. + + However, unrestricted linking of non-free programs would deprive the +users of those programs of all benefit from the free status of the +libraries themselves. This Library General Public License is intended to +permit developers of non-free programs to use free libraries, while +preserving your freedom as a user of such programs to change the free +libraries that are incorporated in them. (We have not seen how to achieve +this as regards changes in header files, but we have achieved it as regards +changes in the actual functions of the Library.) The hope is that this +will lead to faster development of free libraries. + + The precise terms and conditions for copying, distribution and +modification follow. Pay close attention to the difference between a +"work based on the library" and a "work that uses the library". The +former contains code derived from the library, while the latter only +works together with the library. + + Note that it is possible for a library to be covered by the ordinary +General Public License rather than by this special one. + + GNU LIBRARY GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License Agreement applies to any software library which +contains a notice placed by the copyright holder or other authorized +party saying it may be distributed under the terms of this Library +General Public License (also called "this License"). Each licensee is +addressed as "you". + + A "library" means a collection of software functions and/or data +prepared so as to be conveniently linked with application programs +(which use some of those functions and data) to form executables. + + The "Library", below, refers to any such software library or work +which has been distributed under these terms. A "work based on the +Library" means either the Library or any derivative work under +copyright law: that is to say, a work containing the Library or a +portion of it, either verbatim or with modifications and/or translated +straightforwardly into another language. (Hereinafter, translation is +included without limitation in the term "modification".) + + "Source code" for a work means the preferred form of the work for +making modifications to it. For a library, complete source code means +all the source code for all modules it contains, plus any associated +interface definition files, plus the scripts used to control compilation +and installation of the library. + + Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running a program using the Library is not restricted, and output from +such a program is covered only if its contents constitute a work based +on the Library (independent of the use of the Library in a tool for +writing it). Whether that is true depends on what the Library does +and what the program that uses the Library does. + + 1. You may copy and distribute verbatim copies of the Library's +complete source code as you receive it, in any medium, provided that +you conspicuously and appropriately publish on each copy an +appropriate copyright notice and disclaimer of warranty; keep intact +all the notices that refer to this License and to the absence of any +warranty; and distribute a copy of this License along with the +Library. + + You may charge a fee for the physical act of transferring a copy, +and you may at your option offer warranty protection in exchange for a +fee. + + 2. You may modify your copy or copies of the Library or any portion +of it, thus forming a work based on the Library, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) The modified work must itself be a software library. + + b) You must cause the files modified to carry prominent notices + stating that you changed the files and the date of any change. + + c) You must cause the whole of the work to be licensed at no + charge to all third parties under the terms of this License. + + d) If a facility in the modified Library refers to a function or a + table of data to be supplied by an application program that uses + the facility, other than as an argument passed when the facility + is invoked, then you must make a good faith effort to ensure that, + in the event an application does not supply such function or + table, the facility still operates, and performs whatever part of + its purpose remains meaningful. + + (For example, a function in a library to compute square roots has + a purpose that is entirely well-defined independent of the + application. Therefore, Subsection 2d requires that any + application-supplied function or table used by this function must + be optional: if the application does not supply it, the square + root function must still compute square roots.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Library, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Library, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote +it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Library. + +In addition, mere aggregation of another work not based on the Library +with the Library (or with a work based on the Library) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may opt to apply the terms of the ordinary GNU General Public +License instead of this License to a given copy of the Library. To do +this, you must alter all the notices that refer to this License, so +that they refer to the ordinary GNU General Public License, version 2, +instead of to this License. (If a newer version than version 2 of the +ordinary GNU General Public License has appeared, then you can specify +that version instead if you wish.) Do not make any other change in +these notices. + + Once this change is made in a given copy, it is irreversible for +that copy, so the ordinary GNU General Public License applies to all +subsequent copies and derivative works made from that copy. + + This option is useful when you wish to copy part of the code of +the Library into a program that is not a library. + + 4. You may copy and distribute the Library (or a portion or +derivative of it, under Section 2) in object code or executable form +under the terms of Sections 1 and 2 above provided that you accompany +it with the complete corresponding machine-readable source code, which +must be distributed under the terms of Sections 1 and 2 above on a +medium customarily used for software interchange. + + If distribution of object code is made by offering access to copy +from a designated place, then offering equivalent access to copy the +source code from the same place satisfies the requirement to +distribute the source code, even though third parties are not +compelled to copy the source along with the object code. + + 5. A program that contains no derivative of any portion of the +Library, but is designed to work with the Library by being compiled or +linked with it, is called a "work that uses the Library". Such a +work, in isolation, is not a derivative work of the Library, and +therefore falls outside the scope of this License. + + However, linking a "work that uses the Library" with the Library +creates an executable that is a derivative of the Library (because it +contains portions of the Library), rather than a "work that uses the +library". The executable is therefore covered by this License. +Section 6 states terms for distribution of such executables. + + When a "work that uses the Library" uses material from a header file +that is part of the Library, the object code for the work may be a +derivative work of the Library even though the source code is not. +Whether this is true is especially significant if the work can be +linked without the Library, or if the work is itself a library. The +threshold for this to be true is not precisely defined by law. + + If such an object file uses only numerical parameters, data +structure layouts and accessors, and small macros and small inline +functions (ten lines or less in length), then the use of the object +file is unrestricted, regardless of whether it is legally a derivative +work. (Executables containing this object code plus portions of the +Library will still fall under Section 6.) + + Otherwise, if the work is a derivative of the Library, you may +distribute the object code for the work under the terms of Section 6. +Any executables containing that work also fall under Section 6, +whether or not they are linked directly with the Library itself. + + 6. As an exception to the Sections above, you may also compile or +link a "work that uses the Library" with the Library to produce a +work containing portions of the Library, and distribute that work +under terms of your choice, provided that the terms permit +modification of the work for the customer's own use and reverse +engineering for debugging such modifications. + + You must give prominent notice with each copy of the work that the +Library is used in it and that the Library and its use are covered by +this License. You must supply a copy of this License. If the work +during execution displays copyright notices, you must include the +copyright notice for the Library among them, as well as a reference +directing the user to the copy of this License. Also, you must do one +of these things: + + a) Accompany the work with the complete corresponding + machine-readable source code for the Library including whatever + changes were used in the work (which must be distributed under + Sections 1 and 2 above); and, if the work is an executable linked + with the Library, with the complete machine-readable "work that + uses the Library", as object code and/or source code, so that the + user can modify the Library and then relink to produce a modified + executable containing the modified Library. (It is understood + that the user who changes the contents of definitions files in the + Library will not necessarily be able to recompile the application + to use the modified definitions.) + + b) Accompany the work with a written offer, valid for at + least three years, to give the same user the materials + specified in Subsection 6a, above, for a charge no more + than the cost of performing this distribution. + + c) If distribution of the work is made by offering access to copy + from a designated place, offer equivalent access to copy the above + specified materials from the same place. + + d) Verify that the user has already received a copy of these + materials or that you have already sent this user a copy. + + For an executable, the required form of the "work that uses the +Library" must include any data and utility programs needed for +reproducing the executable from it. However, as a special exception, +the 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. + + It may happen that this requirement contradicts the license +restrictions of other proprietary libraries that do not normally +accompany the operating system. Such a contradiction means you cannot +use both them and the Library together in an executable that you +distribute. + + 7. You may place library facilities that are a work based on the +Library side-by-side in a single library together with other library +facilities not covered by this License, and distribute such a combined +library, provided that the separate distribution of the work based on +the Library and of the other library facilities is otherwise +permitted, and provided that you do these two things: + + a) Accompany the combined library with a copy of the same work + based on the Library, uncombined with any other library + facilities. This must be distributed under the terms of the + Sections above. + + b) Give prominent notice with the combined library of the fact + that part of it is a work based on the Library, and explaining + where to find the accompanying uncombined form of the same work. + + 8. You may not copy, modify, sublicense, link with, or distribute +the Library except as expressly provided under this License. Any +attempt otherwise to copy, modify, sublicense, link with, or +distribute the Library is void, and will automatically terminate your +rights under this License. However, parties who have received copies, +or rights, from you under this License will not have their licenses +terminated so long as such parties remain in full compliance. + + 9. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Library or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Library (or any work based on the +Library), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Library or works based on it. + + 10. Each time you redistribute the Library (or any work based on the +Library), the recipient automatically receives a license from the +original licensor to copy, distribute, link with or modify the Library +subject to these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 11. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Library at all. For example, if a patent +license would not permit royalty-free redistribution of the Library by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Library. + +If any portion of this section is held invalid or unenforceable under any +particular circumstance, the balance of the section is intended to apply, +and the section as a whole is intended to apply in other circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 12. If the distribution and/or use of the Library is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Library under this License may add +an explicit geographical distribution limitation excluding those countries, +so that distribution is permitted only in or among countries not thus +excluded. In such case, this License incorporates the limitation as if +written in the body of this License. + + 13. The Free Software Foundation may publish revised and/or new +versions of the Library General Public License from time to time. +Such new versions will be similar in spirit to the present version, +but may differ in detail to address new problems or concerns. + +Each version is given a distinguishing version number. If the Library +specifies a version number of this License which applies to it and +"any later version", you have the option of following the terms and +conditions either of that version or of any later version published by +the Free Software Foundation. If the Library does not specify a +license version number, you may choose any version ever published by +the Free Software Foundation. + + 14. If you wish to incorporate parts of the Library into other free +programs whose distribution conditions are incompatible with these, +write to the author to ask for permission. For software which is +copyrighted by the Free Software Foundation, write to the Free +Software Foundation; we sometimes make exceptions for this. Our +decision will be guided by the two goals of preserving the free status +of all derivatives of our free software and of promoting the sharing +and reuse of software generally. + + NO WARRANTY + + 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO +WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. +EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR +OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY +KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE +LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME +THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN +WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY +AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU +FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR +CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE +LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING +RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A +FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF +SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH +DAMAGES. + + END OF TERMS AND CONDITIONS diff --git a/contrib/sdk/sources/SDL-1.2.2/SDL_draw/INSTALL b/contrib/sdk/sources/SDL-1.2.2/SDL_draw/INSTALL new file mode 100644 index 000000000..b42a17ac4 --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/SDL_draw/INSTALL @@ -0,0 +1,182 @@ +Basic Installation +================== + + These are generic installation instructions. + + The `configure' shell script attempts to guess correct values for +various system-dependent variables used during compilation. It uses +those values to create a `Makefile' in each directory of the package. +It may also create one or more `.h' files containing system-dependent +definitions. Finally, it creates a shell script `config.status' that +you can run in the future to recreate the current configuration, a file +`config.cache' that saves the results of its tests to speed up +reconfiguring, and a file `config.log' containing compiler output +(useful mainly for debugging `configure'). + + If you need to do unusual things to compile the package, please try +to figure out how `configure' could check whether to do them, and mail +diffs or instructions to the address given in the `README' so they can +be considered for the next release. If at some point `config.cache' +contains results you don't want to keep, you may remove or edit it. + + The file `configure.in' is used to create `configure' by a program +called `autoconf'. You only need `configure.in' if you want to change +it or regenerate `configure' using a newer version of `autoconf'. + +The simplest way to compile this package is: + + 1. `cd' to the directory containing the package's source code and type + `./configure' to configure the package for your system. If you're + using `csh' on an old version of System V, you might need to type + `sh ./configure' instead to prevent `csh' from trying to execute + `configure' itself. + + Running `configure' takes awhile. While running, it prints some + messages telling which features it is checking for. + + 2. Type `make' to compile the package. + + 3. Optionally, type `make check' to run any self-tests that come with + the package. + + 4. Type `make install' to install the programs and any data files and + documentation. + + 5. You can remove the program binaries and object files from the + source code directory by typing `make clean'. To also remove the + files that `configure' created (so you can compile the package for + a different kind of computer), type `make distclean'. There is + also a `make maintainer-clean' target, but that is intended mainly + for the package's developers. If you use it, you may have to get + all sorts of other programs in order to regenerate files that came + with the distribution. + +Compilers and Options +===================== + + Some systems require unusual options for compilation or linking that +the `configure' script does not know about. You can give `configure' +initial values for variables by setting them in the environment. Using +a Bourne-compatible shell, you can do that on the command line like +this: + CC=c89 CFLAGS=-O2 LIBS=-lposix ./configure + +Or on systems that have the `env' program, you can do it like this: + env CPPFLAGS=-I/usr/local/include LDFLAGS=-s ./configure + +Compiling For Multiple Architectures +==================================== + + You can compile the package for more than one kind of computer at the +same time, by placing the object files for each architecture in their +own directory. To do this, you must use a version of `make' that +supports the `VPATH' variable, such as GNU `make'. `cd' to the +directory where you want the object files and executables to go and run +the `configure' script. `configure' automatically checks for the +source code in the directory that `configure' is in and in `..'. + + If you have to use a `make' that does not supports the `VPATH' +variable, you have to compile the package for one architecture at a time +in the source code directory. After you have installed the package for +one architecture, use `make distclean' before reconfiguring for another +architecture. + +Installation Names +================== + + By default, `make install' will install the package's files in +`/usr/local/bin', `/usr/local/man', etc. You can specify an +installation prefix other than `/usr/local' by giving `configure' the +option `--prefix=PATH'. + + You can specify separate installation prefixes for +architecture-specific files and architecture-independent files. If you +give `configure' the option `--exec-prefix=PATH', the package will use +PATH as the prefix for installing programs and libraries. +Documentation and other data files will still use the regular prefix. + + In addition, if you use an unusual directory layout you can give +options like `--bindir=PATH' to specify different values for particular +kinds of files. Run `configure --help' for a list of the directories +you can set and what kinds of files go in them. + + If the package supports it, you can cause programs to be installed +with an extra prefix or suffix on their names by giving `configure' the +option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'. + +Optional Features +================= + + Some packages pay attention to `--enable-FEATURE' options to +`configure', where FEATURE indicates an optional part of the package. +They may also pay attention to `--with-PACKAGE' options, where PACKAGE +is something like `gnu-as' or `x' (for the X Window System). The +`README' should mention any `--enable-' and `--with-' options that the +package recognizes. + + For packages that use the X Window System, `configure' can usually +find the X include and library files automatically, but if it doesn't, +you can use the `configure' options `--x-includes=DIR' and +`--x-libraries=DIR' to specify their locations. + +Specifying the System Type +========================== + + There may be some features `configure' can not figure out +automatically, but needs to determine by the type of host the package +will run on. Usually `configure' can figure that out, but if it prints +a message saying it can not guess the host type, give it the +`--host=TYPE' option. TYPE can either be a short name for the system +type, such as `sun4', or a canonical name with three fields: + CPU-COMPANY-SYSTEM + +See the file `config.sub' for the possible values of each field. If +`config.sub' isn't included in this package, then this package doesn't +need to know the host type. + + If you are building compiler tools for cross-compiling, you can also +use the `--target=TYPE' option to select the type of system they will +produce code for and the `--build=TYPE' option to select the type of +system on which you are compiling the package. + +Sharing Defaults +================ + + If you want to set default values for `configure' scripts to share, +you can create a site shell script called `config.site' that gives +default values for variables like `CC', `cache_file', and `prefix'. +`configure' looks for `PREFIX/share/config.site' if it exists, then +`PREFIX/etc/config.site' if it exists. Or, you can set the +`CONFIG_SITE' environment variable to the location of the site script. +A warning: not all `configure' scripts look for a site script. + +Operation Controls +================== + + `configure' recognizes the following options to control how it +operates. + +`--cache-file=FILE' + Use and save the results of the tests in FILE instead of + `./config.cache'. Set FILE to `/dev/null' to disable caching, for + debugging `configure'. + +`--help' + Print a summary of the options to `configure', and exit. + +`--quiet' +`--silent' +`-q' + Do not print messages saying which checks are being made. To + suppress all normal output, redirect it to `/dev/null' (any error + messages will still be shown). + +`--srcdir=DIR' + Look for the package's source code in directory DIR. Usually + `configure' can determine that directory automatically. + +`--version' + Print the version of Autoconf used to generate the `configure' + script, and exit. + +`configure' also accepts some other, not widely useful, options. diff --git a/contrib/sdk/sources/SDL-1.2.2/SDL_draw/Makefile b/contrib/sdk/sources/SDL-1.2.2/SDL_draw/Makefile new file mode 100644 index 000000000..e1f64d2cb --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/SDL_draw/Makefile @@ -0,0 +1,5 @@ +OUTFILE = ../lib/libSDLdraw.a +OBJS = src/SDL_draw.o +CFLAGS = -Iinclude -I. -I../include + +include $(MENUETDEV)/makefiles/Makefile_for_lib diff --git a/contrib/sdk/sources/SDL-1.2.2/SDL_draw/NEWS b/contrib/sdk/sources/SDL-1.2.2/SDL_draw/NEWS new file mode 100644 index 000000000..e69de29bb diff --git a/contrib/sdk/sources/SDL-1.2.2/SDL_draw/README b/contrib/sdk/sources/SDL-1.2.2/SDL_draw/README new file mode 100644 index 000000000..10ff8a50f --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/SDL_draw/README @@ -0,0 +1,117 @@ + +SDL_draw 1.2.1 +~~~~~~~~~~~~~~ +The latest version of this library is available from: +http://sdl-draw.sourceforge.net/ + +This is a simple library to draw basic elements, like points, lines and +circles, on SDL surfaces. + +Library API +~~~~~~~~~~~ +#include "SDL_draw.h" + +//IMPORTANT: Call this function AFTER the call to 'SDL_SetVideoMode': +Draw_Init(); //Register the functions for current bpp + + +void Draw_Pixel(SDL_Surface *super, + Sint16 x, Sint16 y, Uint32 color); + + Draw a colored pixel on coordinates x,y. + + +void Draw_Line(SDL_Surface *super, + Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, + Uint32 color); + + Draw a line from x1,y1 to x2,y2. + + +void Draw_Circle(SDL_Surface *super, + Sint16 x0, Sint16 y0, Uint16 r, + Uint32 color); + + Draw a circle with center x0,y0 and radius r. + + +void Draw_FillCircle(SDL_Surface *super, + Sint16 x0, Sint16 y0, Uint16 r, + Uint32 color); + + Draw a filled circle with center x0,y0 and radius r. + + +void Draw_HLine(SDL_Surface *super, + Sint16 x0,Sint16 y0, Sint16 x1, + Uint32 color); + + Draw a horizontal line from x0,y0 to x1,y0. + + +void Draw_VLine(SDL_Surface *super, + Sint16 x0,Sint16 y0, Sint16 y1, + Uint32 color); + + Draw a vertical line from x0,y0 to x0,y1. + + +void Draw_Rect(SDL_Surface *super, + Sint16 x,Sint16 y, Uint16 w,Uint16 h, + Uint32 color); + + Draw a rectangle with upper left corner in x,y being w the width and h the + height. + + +void Draw_FillRect(SDL_Surface *super, + Sint16 x,Sint16 y, Uint16 w,Uint16 h, + Uint32 color); + + The same as above but the rectangle is filled. This function is equivalent + to SDL_FillRect (is a MACRO). + + +void Draw_Ellipse(SDL_Surface *super, + Sint16 x0, Sint16 y0, + Uint16 Xradius, Uint16 Yradius, + Uint32 color); + + Draw a ellipse with center in x0,y0. Xradius is the major axis and Yradius is + the minor axis. + + +void Draw_FillEllipse(SDL_Surface *super, + Sint16 x0, Sint16 y0, + Uint16 Xradius, Uint16 Yradius, + Uint32 color); + + Draw a filled ellipse (same parameters as the above function). + + +void Draw_Round(SDL_Surface *super, + Sint16 x0,Sint16 y0, Uint16 w,Uint16 h, + Uint16 corner, Uint32 color); + + Draw a rectangle with rounded corners. x0,y0 is the upper left corner of the + rectangle, w is the width and h is the height. corner is the radius of the + corner. + + +void Draw_Round(SDL_Surface *super, + Sint16 x0,Sint16 y0, Uint16 w,Uint16 h, + Uint16 corner, Uint32 color); + + The same as above but the rounded rectangle is filled. + + +The file sdldrawtest.c is a example application for the library. You can +compile it using (for GNU Compiler): + +$ export CFLAGS="`sdl-config --cflags` -I./include" +$ export LIBS="`sdl-config --libs` ./src/.libs/libSDL_draw.a" +$ gcc -o sdldrawtest sdldrawtest.c -Wall $CFLAGS $LIBS + +This library is under the GNU Library General Public License, see the file +"COPYING" for details. + diff --git a/contrib/sdk/sources/SDL-1.2.2/SDL_draw/TODO b/contrib/sdk/sources/SDL-1.2.2/SDL_draw/TODO new file mode 100644 index 000000000..51c08b97e --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/SDL_draw/TODO @@ -0,0 +1,9 @@ +TODO 07-2002 +~~~~~~~~~~~~ + +- Draw_Arc +- Draw_Pie (or Draw_FillArc) +- Draw_Thick* (Thicks versions of the functions) +- Implement __antialiasing__ version of the functions (ex: Draw_ALine) +- Optimizations (Processor Pipeline and others) + diff --git a/contrib/sdk/sources/SDL-1.2.2/SDL_draw/confdefs.h b/contrib/sdk/sources/SDL-1.2.2/SDL_draw/confdefs.h new file mode 100644 index 000000000..6353d1c62 --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/SDL_draw/confdefs.h @@ -0,0 +1,3 @@ + +#define PACKAGE "SDL_draw" +#define VERSION "1.2.1" diff --git a/contrib/sdk/sources/SDL-1.2.2/SDL_draw/include/SDL_draw.h b/contrib/sdk/sources/SDL-1.2.2/SDL_draw/include/SDL_draw.h new file mode 100644 index 000000000..363584d4f --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/SDL_draw/include/SDL_draw.h @@ -0,0 +1,114 @@ +/*! + \file SDL_draw.h + \author Mario Palomo Torrero + \author Jose M. de la Huerga Fernández + \author Pepe González Mora + \date 05-2002 + + Drawing primitives for SDL. Main header file. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the Free Foundation, + Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ +#ifndef SDL_DRAW_H +#define SDL_DRAW_H + +#include "SDL.h" +#include "begin_code.h" + +#ifdef __cplusplus +extern "C" { +#endif + + +extern DECLSPEC void Draw_Init(void); + +extern DECLSPEC +void (*Draw_Pixel)(SDL_Surface *super, + Sint16 x, Sint16 y, Uint32 color); + +extern DECLSPEC +void (*Draw_Line)(SDL_Surface *super, + Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, + Uint32 color); + +extern DECLSPEC +void (*Draw_Circle)(SDL_Surface *super, + Sint16 x0, Sint16 y0, Uint16 r, + Uint32 color); + +extern DECLSPEC +void (*Draw_FillCircle)(SDL_Surface *super, + Sint16 x0, Sint16 y0, Uint16 r, + Uint32 color); + +extern DECLSPEC +void (*Draw_HLine)(SDL_Surface *super, + Sint16 x0,Sint16 y0, Sint16 x1, + Uint32 color); + +extern DECLSPEC +void (*Draw_VLine)(SDL_Surface *super, + Sint16 x0,Sint16 y0, Sint16 y1, + Uint32 color); + +extern DECLSPEC +void (*Draw_Rect)(SDL_Surface *super, + Sint16 x,Sint16 y, Uint16 w,Uint16 h, + Uint32 color); + +/* We wrap SDL_FillRect with the SDL_draw name convention */ +#define Draw_FillRect(SUPER, X, Y, W, H, COLOR) \ + do { \ + SDL_Rect r = {(X), (Y), (W), (H)}; \ + SDL_FillRect((SUPER), &r, (COLOR)); \ + }while(0) + + +extern DECLSPEC +void (*Draw_Ellipse)(SDL_Surface *super, + Sint16 x0, Sint16 y0, + Uint16 Xradius, Uint16 Yradius, + Uint32 color); + +extern DECLSPEC +void (*Draw_FillEllipse)(SDL_Surface *super, + Sint16 x0, Sint16 y0, + Uint16 Xradius, Uint16 Yradius, + Uint32 color); + +extern DECLSPEC +void (*Draw_Round)(SDL_Surface *super, + Sint16 x0,Sint16 y0, Uint16 w,Uint16 h, + Uint16 corner, Uint32 color); + +extern DECLSPEC +void (*Draw_FillRound)(SDL_Surface *super, + Sint16 x0,Sint16 y0, Uint16 w,Uint16 h, + Uint16 corner, Uint32 color); + + +/* We'll use SDL for reporting errors */ +#define Draw_SetError SDL_SetError +#define Draw_GetError SDL_GetError + + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#include "close_code.h" + +#endif /* SDL_DRAW_H */ + diff --git a/contrib/sdk/sources/SDL-1.2.2/SDL_draw/src/Draw_Circle.c b/contrib/sdk/sources/SDL-1.2.2/SDL_draw/src/Draw_Circle.c new file mode 100644 index 000000000..3d76b146a --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/SDL_draw/src/Draw_Circle.c @@ -0,0 +1,101 @@ +/*! + \file Draw_Circle.c + \author Mario Palomo + \author Jose M. de la Huerga Fernández + \author Pepe González Mora + \date 05-2002 + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the Free Foundation, + Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#define SDL_DRAW_PUTPIXEL_BPP(A, B, C) \ +*(##A##(##B##(Uint8*)super->pixels + (y0+y)*super->pitch + \ + (x0+x)*SDL_DRAW_BPP)) = ##C##; \ +*(##A##(##B##(Uint8*)super->pixels + (y0-y)*super->pitch + \ + (x0+x)*SDL_DRAW_BPP)) = ##C##; \ +*(##A##(##B##(Uint8*)super->pixels + (y0+y)*super->pitch + \ + (x0-x)*SDL_DRAW_BPP)) = ##C##; \ +*(##A##(##B##(Uint8*)super->pixels + (y0-y)*super->pitch + \ + (x0-x)*SDL_DRAW_BPP)) = ##C##; \ +*(##A##(##B##(Uint8*)super->pixels + (y0+x)*super->pitch + \ + (x0+y)*SDL_DRAW_BPP)) = ##C##; \ +*(##A##(##B##(Uint8*)super->pixels + (y0-x)*super->pitch + \ + (x0+y)*SDL_DRAW_BPP)) = ##C##; \ +*(##A##(##B##(Uint8*)super->pixels + (y0+x)*super->pitch + \ + (x0-y)*SDL_DRAW_BPP)) = ##C##; \ +*(##A##(##B##(Uint8*)super->pixels + (y0-x)*super->pitch + \ + (x0-y)*SDL_DRAW_BPP)) = ##C##; + +#if SDL_DRAW_BPP == 1 +#define SDL_DRAW_PUTPIXEL SDL_DRAW_PUTPIXEL_BPP(0+,0+,color) + +#elif SDL_DRAW_BPP == 2 +#define SDL_DRAW_PUTPIXEL SDL_DRAW_PUTPIXEL_BPP((Uint16*),0+,color) + +#elif SDL_DRAW_BPP == 3 +#define SDL_DRAW_PUTPIXEL \ + SDL_DRAW_PUTPIXEL_BPP(0+,1+,colorbyte1) \ + if (SDL_BYTEORDER == SDL_BIG_ENDIAN) { \ + SDL_DRAW_PUTPIXEL_BPP(0+,0+,colorbyte2) \ + SDL_DRAW_PUTPIXEL_BPP(0+,2+,colorbyte0) \ + }else{ \ + SDL_DRAW_PUTPIXEL_BPP(0+,0+,colorbyte0) \ + SDL_DRAW_PUTPIXEL_BPP(0+,2+,colorbyte2) \ + } + +#elif SDL_DRAW_BPP == 4 +#define SDL_DRAW_PUTPIXEL SDL_DRAW_PUTPIXEL_BPP((Uint32*),0+,color) + +#endif /*SDL_DRAW_BPP*/ + + +void SDL_DRAWFUNCTION(SDL_Surface *super, + Sint16 x0, Sint16 y0, Uint16 r, + Uint32 color) +{ +#if SDL_DRAW_BPP == 3 + Uint8 colorbyte0 = (Uint8) (color & 0xff); + Uint8 colorbyte1 = (Uint8) ((color >> 8) & 0xff); + Uint8 colorbyte2 = (Uint8) ((color >> 16) & 0xff); +#endif + + Sint16 x = 0; + Sint16 y = r-1; /*radius zero == draw nothing*/ + Sint16 d = 3 - 2*r; + Sint16 diagonalInc = 10 - 4*r; + Sint16 rightInc = 6; + + while (x <= y) { + + SDL_DRAW_PUTPIXEL + + if (d >= 0) { + d += diagonalInc; + diagonalInc += 8; + y -= 1; + } else { + d += rightInc; + diagonalInc += 4; + } + rightInc += 4; + x += 1; + } + +}/*Draw_Circle*/ + + +#undef SDL_DRAW_PUTPIXEL +#undef SDL_DRAW_PUTPIXEL_BPP + diff --git a/contrib/sdk/sources/SDL-1.2.2/SDL_draw/src/Draw_Ellipse.c b/contrib/sdk/sources/SDL-1.2.2/SDL_draw/src/Draw_Ellipse.c new file mode 100644 index 000000000..ba5ba03fc --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/SDL_draw/src/Draw_Ellipse.c @@ -0,0 +1,137 @@ +/*! + \file Draw_Ellipse.c + \author Mario Palomo + \author Jose M. de la Huerga Fernández + \author Pepe González Mora + \date 05-2002 + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the Free Foundation, + Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#define SDL_DRAW_PUTPIXEL_BPP(A, B, C) \ +*(##A##(##B##(Uint8*)super->pixels + (y0+y)*super->pitch + \ + (x0+x)*SDL_DRAW_BPP)) = ##C##; \ +*(##A##(##B##(Uint8*)super->pixels + (y0-y)*super->pitch + \ + (x0+x)*SDL_DRAW_BPP)) = ##C##; \ +*(##A##(##B##(Uint8*)super->pixels + (y0+y)*super->pitch + \ + (x0-x)*SDL_DRAW_BPP)) = ##C##; \ +*(##A##(##B##(Uint8*)super->pixels + (y0-y)*super->pitch + \ + (x0-x)*SDL_DRAW_BPP)) = ##C##; + + +#if SDL_DRAW_BPP == 1 +#define SDL_DRAW_PUTPIXEL SDL_DRAW_PUTPIXEL_BPP(0+,0+,color) + +#elif SDL_DRAW_BPP == 2 +#define SDL_DRAW_PUTPIXEL SDL_DRAW_PUTPIXEL_BPP((Uint16*),0+,color) + +#elif SDL_DRAW_BPP == 3 +#define SDL_DRAW_PUTPIXEL \ + SDL_DRAW_PUTPIXEL_BPP(0+,1+,colorbyte1) \ + if (SDL_BYTEORDER == SDL_BIG_ENDIAN) { \ + SDL_DRAW_PUTPIXEL_BPP(0+,0+,colorbyte2) \ + SDL_DRAW_PUTPIXEL_BPP(0+,2+,colorbyte0) \ + }else{ \ + SDL_DRAW_PUTPIXEL_BPP(0+,0+,colorbyte0) \ + SDL_DRAW_PUTPIXEL_BPP(0+,2+,colorbyte2) \ + } + +#elif SDL_DRAW_BPP == 4 +#define SDL_DRAW_PUTPIXEL SDL_DRAW_PUTPIXEL_BPP((Uint32*),0+,color) + +#endif /*SDL_DRAW_BPP*/ + + +void SDL_DRAWFUNCTION(SDL_Surface *super, + Sint16 x0, Sint16 y0, + Uint16 Xradius, Uint16 Yradius, + Uint32 color) +{ + Sint32 x, y; + Sint32 Xchange, Ychange; + Sint32 EllipseError; + Sint32 TwoASquare, TwoBSquare; + Sint32 StoppingX, StoppingY; + +#if SDL_DRAW_BPP == 3 + Uint8 colorbyte0 = (Uint8) (color & 0xff); + Uint8 colorbyte1 = (Uint8) ((color >> 8) & 0xff); + Uint8 colorbyte2 = (Uint8) ((color >> 16) & 0xff); +#endif + + TwoASquare = 2*Xradius*Xradius; + TwoBSquare = 2*Yradius*Yradius; + + /*1st set of points*/ + x = Xradius-1; /*radius zero == draw nothing*/ + y = 0; + + Xchange = Yradius*Yradius*(1-2*Xradius); + Ychange = Xradius*Xradius; + + EllipseError = 0; + + StoppingX = TwoBSquare*Xradius; + StoppingY = 0; + + /*Plot four ellipse points by iteration*/ + while (StoppingX > StoppingY) { + + SDL_DRAW_PUTPIXEL + + ++y; + StoppingY += TwoASquare; + EllipseError += Ychange; + Ychange += TwoASquare; + if (( 2*EllipseError + Xchange) > 0) { + --x; + StoppingX -= TwoBSquare; + EllipseError += Xchange; + Xchange += TwoBSquare; + } + }/*while*/ + + /*2nd set of points*/ + x = 0; + y = Yradius-1; /*radius zero == draw nothing*/ + Xchange = Yradius*Yradius; + Ychange = Xradius*Xradius*(1-2*Yradius); + EllipseError = 0; + StoppingX = 0; + StoppingY = TwoASquare*Yradius; + + /*Plot four ellipse points by iteration*/ + while (StoppingX < StoppingY) { + + SDL_DRAW_PUTPIXEL + + ++x; + StoppingX += TwoBSquare; + EllipseError += Xchange; + Xchange += TwoBSquare; + if ((2*EllipseError + Ychange) > 0) { + --y; + StoppingY -= TwoASquare; + EllipseError += Ychange; + Ychange += TwoASquare; + } + } + +}/*Draw_Ellipse*/ + + +#undef SDL_DRAW_PUTPIXEL +#undef SDL_DRAW_PUTPIXEL_BPP + diff --git a/contrib/sdk/sources/SDL-1.2.2/SDL_draw/src/Draw_FillCircle.c b/contrib/sdk/sources/SDL-1.2.2/SDL_draw/src/Draw_FillCircle.c new file mode 100644 index 000000000..632f7876d --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/SDL_draw/src/Draw_FillCircle.c @@ -0,0 +1,216 @@ +/*! + \file Draw_FillCircle.c + \author Mario Palomo + \author Jose M. de la Huerga Fernández + \author Pepe González Mora + \date 05-2002 + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the Free Foundation, + Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#if SDL_DRAW_BPP == 1 +#define SDL_DRAW_PUTPIXEL \ + memset(p0, color, 2*x+1); \ + memset(p1, color, 2*x+1); \ + p0 = ((Uint8*)super->pixels+ (y0+x)*super->pitch+ (x0-y)); \ + p1 = ((Uint8*)super->pixels+ (y0-x)*super->pitch+ (x0-y)); \ + memset(p0, color, 2*y+1); \ + memset(p1, color, 2*y+1); + +#elif SDL_DRAW_BPP == 2 +#define SDL_DRAW_PUTPIXEL \ + i = 2*x+1; \ + switch( i % 4 ) { \ + do{ \ + case 0: *(Uint16*)p0 = color; *(Uint16*)p1 = color; \ + p0+=2; p1+=2; \ + case 3: *(Uint16*)p0 = color; *(Uint16*)p1 = color; \ + p0+=2; p1+=2; \ + case 2: *(Uint16*)p0 = color; *(Uint16*)p1 = color; \ + p0+=2; p1+=2; \ + case 1: *(Uint16*)p0 = color; *(Uint16*)p1 = color; \ + p0+=2; p1+=2; \ + }while( (i-=4) > 0 ); \ + } \ + p0 = ((Uint8*)super->pixels+ (y0+x)*super->pitch+ (x0-y)*2); \ + p1 = ((Uint8*)super->pixels+ (y0-x)*super->pitch+ (x0-y)*2); \ + i = 2*y+1; \ + switch( i % 4 ) { \ + do{ \ + case 0: *(Uint16*)p0 = color; *(Uint16*)p1 = color; \ + p0+=2; p1+=2; \ + case 3: *(Uint16*)p0 = color; *(Uint16*)p1 = color; \ + p0+=2; p1+=2; \ + case 2: *(Uint16*)p0 = color; *(Uint16*)p1 = color; \ + p0+=2; p1+=2; \ + case 1: *(Uint16*)p0 = color; *(Uint16*)p1 = color; \ + p0+=2; p1+=2; \ + }while( (i-=4) > 0 ); \ + } + + +#elif SDL_DRAW_BPP == 3 +#define SDL_DRAW_PUTPIXEL_BPP_3_AUX \ + if (SDL_BYTEORDER == SDL_BIG_ENDIAN) { \ + p0[0] = colorbyte2; \ + p0[1] = colorbyte1; \ + p0[2] = colorbyte0; \ + p1[0] = colorbyte2; \ + p1[1] = colorbyte1; \ + p1[2] = colorbyte0; \ + } else { \ + p0[0] = colorbyte0; \ + p0[1] = colorbyte1; \ + p0[2] = colorbyte2; \ + p1[0] = colorbyte0; \ + p1[1] = colorbyte1; \ + p1[2] = colorbyte2; \ + } + +#define SDL_DRAW_PUTPIXEL \ + i = 2*x+1; \ + switch( i % 4 ) { \ + do{ \ + case 0: SDL_DRAW_PUTPIXEL_BPP_3_AUX \ + p0+=3; p1+=3; \ + case 3: SDL_DRAW_PUTPIXEL_BPP_3_AUX \ + p0+=3; p1+=3; \ + case 2: SDL_DRAW_PUTPIXEL_BPP_3_AUX \ + p0+=3; p1+=3; \ + case 1: SDL_DRAW_PUTPIXEL_BPP_3_AUX \ + p0+=3; p1+=3; \ + }while( (i-=4) > 0 ); \ + } \ + p0 = ((Uint8*)super->pixels+ (y0+x)*super->pitch+ (x0-y)*3); \ + p1 = ((Uint8*)super->pixels+ (y0-x)*super->pitch+ (x0-y)*3); \ + i = 2*y+1; \ + switch( i % 4 ) { \ + do{ \ + case 0: SDL_DRAW_PUTPIXEL_BPP_3_AUX \ + p0+=3; p1+=3; \ + case 3: SDL_DRAW_PUTPIXEL_BPP_3_AUX \ + p0+=3; p1+=3; \ + case 2: SDL_DRAW_PUTPIXEL_BPP_3_AUX \ + p0+=3; p1+=3; \ + case 1: SDL_DRAW_PUTPIXEL_BPP_3_AUX \ + p0+=3; p1+=3; \ + }while( (i-=4) > 0 ); \ + } + + +#elif SDL_DRAW_BPP == 4 + +#ifdef __linux__ +#define SDL_DRAW_WMEMSET_START \ +if (sizeof(wchar_t) == sizeof(Uint32)) { \ + wmemset((wchar_t*)p0, color, 2*x+1); \ + wmemset((wchar_t*)p1, color, 2*x+1); \ + p0 = ((Uint8*)super->pixels+ (y0+x)*super->pitch+ (x0-y)*4); \ + p1 = ((Uint8*)super->pixels+ (y0-x)*super->pitch+ (x0-y)*4); \ + wmemset((wchar_t*)p0, color, 2*y+1); \ + wmemset((wchar_t*)p1, color, 2*y+1); \ +} else { +#define SDL_DRAW_WMEMSET_END } +#else +#define SDL_DRAW_WMEMSET_START +#define SDL_DRAW_WMEMSET_END +#endif + +#define SDL_DRAW_PUTPIXEL \ +SDL_DRAW_WMEMSET_START \ + i = 2*x+1; \ + switch( i % 4 ) { \ + do{ \ + case 0: *(Uint32*)p0 = color; *(Uint32*)p1 = color; \ + p0+=4; p1+=4; \ + case 3: *(Uint32*)p0 = color; *(Uint32*)p1 = color; \ + p0+=4; p1+=4; \ + case 2: *(Uint32*)p0 = color; *(Uint32*)p1 = color; \ + p0+=4; p1+=4; \ + case 1: *(Uint32*)p0 = color; *(Uint32*)p1 = color; \ + p0+=4; p1+=4; \ + }while( (i-=4) > 0 ); \ + } \ + p0 = ((Uint8*)super->pixels+ (y0+x)*super->pitch+ (x0-y)*4); \ + p1 = ((Uint8*)super->pixels+ (y0-x)*super->pitch+ (x0-y)*4); \ + i = 2*y+1; \ + switch( i % 4 ) { \ + do{ \ + case 0: *(Uint32*)p0 = color; *(Uint32*)p1 = color; \ + p0+=4; p1+=4; \ + case 3: *(Uint32*)p0 = color; *(Uint32*)p1 = color; \ + p0+=4; p1+=4; \ + case 2: *(Uint32*)p0 = color; *(Uint32*)p1 = color; \ + p0+=4; p1+=4; \ + case 1: *(Uint32*)p0 = color; *(Uint32*)p1 = color; \ + p0+=4; p1+=4; \ + }while( (i-=4) > 0 ); \ + } \ +SDL_DRAW_WMEMSET_END + +#endif /*SDL_DRAW_BPP*/ + + + +void SDL_DRAWFUNCTION(SDL_Surface *super, + Sint16 x0, Sint16 y0, Uint16 r, + Uint32 color) +{ +#if SDL_DRAW_BPP == 3 + Uint8 colorbyte0 = (Uint8) (color & 0xff); + Uint8 colorbyte1 = (Uint8) ((color >> 8) & 0xff); + Uint8 colorbyte2 = (Uint8) ((color >> 16) & 0xff); +#endif + + register Uint8 *p0; + register Uint8 *p1; +#if SDL_DRAW_BPP != 1 + register Sint16 i; +#endif + + Sint16 x = 0; + Sint16 y = r-1; /*radius zero == draw nothing*/ + Sint16 d = 3 - 2*r; + Sint16 diagonalInc = 10 - 4*r; + Sint16 rightInc = 6; + + while (x <= y) { + + p0 = ((Uint8*)super->pixels+ (y0+y)*super->pitch+ (x0-x)*SDL_DRAW_BPP); + p1 = ((Uint8*)super->pixels+ (y0-y)*super->pitch+ (x0-x)*SDL_DRAW_BPP); + + SDL_DRAW_PUTPIXEL + + if (d >= 0) { + d += diagonalInc; + diagonalInc += 8; + y -= 1; + } else { + d += rightInc; + diagonalInc += 4; + } + rightInc += 4; + x += 1; + } + +}/*Draw_FillCircle*/ + + +#undef SDL_DRAW_PUTPIXEL +#undef SDL_DRAW_PUTPIXEL_BPP_3_AUX + +#undef SDL_DRAW_WMEMSET_START +#undef SDL_DRAW_WMEMSET_END + diff --git a/contrib/sdk/sources/SDL-1.2.2/SDL_draw/src/Draw_FillEllipse.c b/contrib/sdk/sources/SDL-1.2.2/SDL_draw/src/Draw_FillEllipse.c new file mode 100644 index 000000000..ce8864790 --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/SDL_draw/src/Draw_FillEllipse.c @@ -0,0 +1,217 @@ +/*! + \file Draw_FillEllipse.c + \author Mario Palomo + \author Jose M. de la Huerga Fernández + \author Pepe González Mora + \date 05-2002 + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the Free Foundation, + Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#if SDL_DRAW_BPP == 1 +#define SDL_DRAW_PUTPIXEL \ + memset(((Uint8*)super->pixels+ (y0+y)*super->pitch+ (x0-x)), \ + color, 2*x+1); \ + memset(((Uint8*)super->pixels+ (y0-y)*super->pitch+ (x0-x)), \ + color, 2*x+1); + + +#elif SDL_DRAW_BPP == 2 +#define SDL_DRAW_PUTPIXEL \ +{ \ + p0 = ((Uint8*)super->pixels+ (y0+y)*super->pitch+ (x0-x)*2); \ + p1 = ((Uint8*)super->pixels+ (y0-y)*super->pitch+ (x0-x)*2); \ + i = 2*x+1; \ + switch( i % 4 ) { \ + do{ \ + case 0: *(Uint16*)p0 = color; *(Uint16*)p1 = color; \ + p0+=2; p1+=2; \ + case 3: *(Uint16*)p0 = color; *(Uint16*)p1 = color; \ + p0+=2; p1+=2; \ + case 2: *(Uint16*)p0 = color; *(Uint16*)p1 = color; \ + p0+=2; p1+=2; \ + case 1: *(Uint16*)p0 = color; *(Uint16*)p1 = color; \ + p0+=2; p1+=2; \ + }while( (i-=4) > 0 ); \ + } \ +} + + +#elif SDL_DRAW_BPP == 3 +#define SDL_DRAW_PUTPIXEL_BPP_3_AUX \ + if (SDL_BYTEORDER == SDL_BIG_ENDIAN) { \ + p0[0] = colorbyte2; \ + p0[1] = colorbyte1; \ + p0[2] = colorbyte0; \ + p1[0] = colorbyte2; \ + p1[1] = colorbyte1; \ + p1[2] = colorbyte0; \ + } else { \ + p0[0] = colorbyte0; \ + p0[1] = colorbyte1; \ + p0[2] = colorbyte2; \ + p1[0] = colorbyte0; \ + p1[1] = colorbyte1; \ + p1[2] = colorbyte2; \ + } + +#define SDL_DRAW_PUTPIXEL \ +{ \ + p0 = ((Uint8*)super->pixels+ (y0+y)*super->pitch+ (x0-x)*3); \ + p1 = ((Uint8*)super->pixels+ (y0-y)*super->pitch+ (x0-x)*3); \ + i = 2*x+1; \ + switch( i % 4 ) { \ + do{ \ + case 0: SDL_DRAW_PUTPIXEL_BPP_3_AUX \ + p0+=3; p1+=3; \ + case 3: SDL_DRAW_PUTPIXEL_BPP_3_AUX \ + p0+=3; p1+=3; \ + case 2: SDL_DRAW_PUTPIXEL_BPP_3_AUX \ + p0+=3; p1+=3; \ + case 1: SDL_DRAW_PUTPIXEL_BPP_3_AUX \ + p0+=3; p1+=3; \ + }while( (i-=4) > 0 ); \ + } \ +} + + +#elif SDL_DRAW_BPP == 4 + +#ifdef __linux__ +#define SDL_DRAW_WMEMSET_START \ +if (sizeof(wchar_t) == sizeof(Uint32)) { \ + wmemset( (wchar_t*)((Uint8*)super->pixels+ (y0+y)*super->pitch+ (x0-x)*4), \ + color, 2*x+1); \ + wmemset( (wchar_t*)((Uint8*)super->pixels+ (y0-y)*super->pitch+ (x0-x)*4), \ + color, 2*x+1); \ +} else { +#define SDL_DRAW_WMEMSET_END } +#else +#define SDL_DRAW_WMEMSET_START +#define SDL_DRAW_WMEMSET_END +#endif + +#define SDL_DRAW_PUTPIXEL \ +SDL_DRAW_WMEMSET_START \ + p0 = ((Uint8*)super->pixels+ (y0+y)*super->pitch+ (x0-x)*4); \ + p1 = ((Uint8*)super->pixels+ (y0-y)*super->pitch+ (x0-x)*4); \ + i = 2*x+1; \ + switch( i % 4 ) { \ + do{ \ + case 0: *(Uint32*)p0 = color; *(Uint32*)p1 = color; \ + p0+=4; p1+=4; \ + case 3: *(Uint32*)p0 = color; *(Uint32*)p1 = color; \ + p0+=4; p1+=4; \ + case 2: *(Uint32*)p0 = color; *(Uint32*)p1 = color; \ + p0+=4; p1+=4; \ + case 1: *(Uint32*)p0 = color; *(Uint32*)p1 = color; \ + p0+=4; p1+=4; \ + }while( (i-=4) > 0 ); \ + } \ +SDL_DRAW_WMEMSET_END + +#endif /*SDL_DRAW_BPP*/ + + + +void SDL_DRAWFUNCTION(SDL_Surface *super, + Sint16 x0, Sint16 y0, + Uint16 Xradius, Uint16 Yradius, + Uint32 color) +{ +#if SDL_DRAW_BPP == 3 + Uint8 colorbyte0 = (Uint8) (color & 0xff); + Uint8 colorbyte1 = (Uint8) ((color >> 8) & 0xff); + Uint8 colorbyte2 = (Uint8) ((color >> 16) & 0xff); +#endif + +#if SDL_DRAW_BPP != 1 + register Uint8 *p0; + register Uint8 *p1; + register Sint16 i; +#endif + + Sint32 x, y; + Sint32 Xchange, Ychange; + Sint32 EllipseError; + Sint32 TwoASquare, TwoBSquare; + Sint32 StoppingX, StoppingY; + + TwoASquare = 2*Xradius*Xradius; + TwoBSquare = 2*Yradius*Yradius; + + /*1st set of points*/ + x = Xradius-1; /*radius zero == draw nothing*/ + y = 0; + + Xchange = Yradius*Yradius*(1-2*Xradius); + Ychange = Xradius*Xradius; + + EllipseError = 0; + + StoppingX = TwoBSquare*Xradius; + StoppingY = 0; + + /*Plot 2 ellipse scan lines for iteration*/ + while (StoppingX > StoppingY) { + + SDL_DRAW_PUTPIXEL + + ++y; + StoppingY += TwoASquare; + EllipseError += Ychange; + Ychange += TwoASquare; + if (( 2*EllipseError + Xchange) > 0) { + --x; + StoppingX -= TwoBSquare; + EllipseError += Xchange; + Xchange += TwoBSquare; + } + }/*while*/ + + /*2nd set of points*/ + x = 0; + y = Yradius-1; /*radius zero == draw nothing*/ + Xchange = Yradius*Yradius; + Ychange = Xradius*Xradius*(1-2*Yradius); + EllipseError = 0; + StoppingX = 0; + StoppingY = TwoASquare*Yradius; + + /*Plot 2 ellipse scan lines for iteration*/ + while (StoppingX < StoppingY) { + + SDL_DRAW_PUTPIXEL + + ++x; + StoppingX += TwoBSquare; + EllipseError += Xchange; + Xchange += TwoBSquare; + if ((2*EllipseError + Ychange) > 0) { + --y; + StoppingY -= TwoASquare; + EllipseError += Ychange; + Ychange += TwoASquare; + } + } +}/*Draw_FillEllipse*/ + + +#undef SDL_DRAW_PUTPIXEL +#undef SDL_DRAW_PUTPIXEL_BPP_3_AUX + +#undef SDL_DRAW_WMEMSET_START +#undef SDL_DRAW_WMEMSET_END + diff --git a/contrib/sdk/sources/SDL-1.2.2/SDL_draw/src/Draw_FillRound.c b/contrib/sdk/sources/SDL-1.2.2/SDL_draw/src/Draw_FillRound.c new file mode 100644 index 000000000..b31dff709 --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/SDL_draw/src/Draw_FillRound.c @@ -0,0 +1,248 @@ +/*! + \file Draw_FillRound.c + \author Mario Palomo + \author Jose M. de la Huerga Fernández + \author Pepe González Mora + \date 05-2002 + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the Free Foundation, + Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#if SDL_DRAW_BPP == 1 +#define SDL_DRAW_PUTPIXEL \ + memset(p0, color, X2center - Xcenter + 2*corner+1); \ + memset(p1, color, X2center - Xcenter + 2*corner+1); \ + p0 = ((Uint8*)super->pixels+(Y2center+corner)*super->pitch+(Xcenter-x)); \ + p1 = ((Uint8*)super->pixels+(Ycenter-corner)*super->pitch +(Xcenter-x)); \ + memset(p0, color, X2center - Xcenter + 2*x+1); \ + memset(p1, color, X2center - Xcenter + 2*x+1); + +#elif SDL_DRAW_BPP == 2 +#define SDL_DRAW_PUTPIXEL \ + i = X2center - Xcenter + 2*corner+1; \ + switch( i % 4 ) { \ + do{ \ + case 0: *(Uint16*)p0 = color; *(Uint16*)p1 = color; \ + p0+=2; p1+=2; \ + case 3: *(Uint16*)p0 = color; *(Uint16*)p1 = color; \ + p0+=2; p1+=2; \ + case 2: *(Uint16*)p0 = color; *(Uint16*)p1 = color; \ + p0+=2; p1+=2; \ + case 1: *(Uint16*)p0 = color; *(Uint16*)p1 = color; \ + p0+=2; p1+=2; \ + }while( (i-=4) > 0 ); \ + } \ + p0 = ((Uint8*)super->pixels+(Y2center+corner)*super->pitch+(Xcenter-x)*2); \ + p1 = ((Uint8*)super->pixels+(Ycenter-corner)*super->pitch +(Xcenter-x)*2); \ + i = X2center - Xcenter + 2*x+1; \ + switch( i % 4 ) { \ + do{ \ + case 0: *(Uint16*)p0 = color; *(Uint16*)p1 = color; \ + p0+=2; p1+=2; \ + case 3: *(Uint16*)p0 = color; *(Uint16*)p1 = color; \ + p0+=2; p1+=2; \ + case 2: *(Uint16*)p0 = color; *(Uint16*)p1 = color; \ + p0+=2; p1+=2; \ + case 1: *(Uint16*)p0 = color; *(Uint16*)p1 = color; \ + p0+=2; p1+=2; \ + }while( (i-=4) > 0 ); \ + } + +#elif SDL_DRAW_BPP == 3 +#define SDL_DRAW_PUTPIXEL_BPP_3_AUX \ + if (SDL_BYTEORDER == SDL_BIG_ENDIAN) { \ + p0[0] = colorbyte2; \ + p0[1] = colorbyte1; \ + p0[2] = colorbyte0; \ + p1[0] = colorbyte2; \ + p1[1] = colorbyte1; \ + p1[2] = colorbyte0; \ + } else { \ + p0[0] = colorbyte0; \ + p0[1] = colorbyte1; \ + p0[2] = colorbyte2; \ + p1[0] = colorbyte0; \ + p1[1] = colorbyte1; \ + p1[2] = colorbyte2; \ + } + +#define SDL_DRAW_PUTPIXEL \ + i = X2center - Xcenter + 2*corner+1; \ + switch( i % 4 ) { \ + do{ \ + case 0: SDL_DRAW_PUTPIXEL_BPP_3_AUX \ + p0+=3; p1+=3; \ + case 3: SDL_DRAW_PUTPIXEL_BPP_3_AUX \ + p0+=3; p1+=3; \ + case 2: SDL_DRAW_PUTPIXEL_BPP_3_AUX \ + p0+=3; p1+=3; \ + case 1: SDL_DRAW_PUTPIXEL_BPP_3_AUX \ + p0+=3; p1+=3; \ + }while( (i-=4) > 0 ); \ + } \ + p0 = ((Uint8*)super->pixels+(Y2center+corner)*super->pitch+(Xcenter-x)*3); \ + p1 = ((Uint8*)super->pixels+(Ycenter-corner)*super->pitch +(Xcenter-x)*3); \ + i = X2center - Xcenter + 2*x+1; \ + switch( i % 4 ) { \ + do{ \ + case 0: SDL_DRAW_PUTPIXEL_BPP_3_AUX \ + p0+=3; p1+=3; \ + case 3: SDL_DRAW_PUTPIXEL_BPP_3_AUX \ + p0+=3; p1+=3; \ + case 2: SDL_DRAW_PUTPIXEL_BPP_3_AUX \ + p0+=3; p1+=3; \ + case 1: SDL_DRAW_PUTPIXEL_BPP_3_AUX \ + p0+=3; p1+=3; \ + }while( (i-=4) > 0 ); \ + } + + +#elif SDL_DRAW_BPP == 4 + +#ifdef __linux__ +#define SDL_DRAW_WMEMSET_START \ +if (sizeof(wchar_t) == sizeof(Uint32)) { \ + wmemset((wchar_t*)p0, color, X2center - Xcenter + 2*corner+1); \ + wmemset((wchar_t*)p1, color, X2center - Xcenter + 2*corner+1); \ + p0 = ((Uint8*)super->pixels+(Y2center+corner)*super->pitch+(Xcenter-x)*4); \ + p1 = ((Uint8*)super->pixels+(Ycenter-corner)*super->pitch +(Xcenter-x)*4); \ + wmemset((wchar_t*)p0, color, X2center - Xcenter + 2*x+1); \ + wmemset((wchar_t*)p1, color, X2center - Xcenter + 2*x+1); \ +} else { +#define SDL_DRAW_WMEMSET_END } +#else +#define SDL_DRAW_WMEMSET_START +#define SDL_DRAW_WMEMSET_END +#endif + +#define SDL_DRAW_PUTPIXEL \ +SDL_DRAW_WMEMSET_START \ + i = X2center - Xcenter + 2*corner+1; \ + switch( i % 4 ) { \ + do{ \ + case 0: *(Uint32*)p0 = color; *(Uint32*)p1 = color; \ + p0+=4; p1+=4; \ + case 3: *(Uint32*)p0 = color; *(Uint32*)p1 = color; \ + p0+=4; p1+=4; \ + case 2: *(Uint32*)p0 = color; *(Uint32*)p1 = color; \ + p0+=4; p1+=4; \ + case 1: *(Uint32*)p0 = color; *(Uint32*)p1 = color; \ + p0+=4; p1+=4; \ + }while( (i-=4) > 0 ); \ + } \ + p0 = ((Uint8*)super->pixels+(Y2center+corner)*super->pitch+(Xcenter-x)*4); \ + p1 = ((Uint8*)super->pixels+(Ycenter-corner)*super->pitch +(Xcenter-x)*4); \ + i = X2center - Xcenter + 2*x+1; \ + switch( i % 4 ) { \ + do{ \ + case 0: *(Uint32*)p0 = color; *(Uint32*)p1 = color; \ + p0+=4; p1+=4; \ + case 3: *(Uint32*)p0 = color; *(Uint32*)p1 = color; \ + p0+=4; p1+=4; \ + case 2: *(Uint32*)p0 = color; *(Uint32*)p1 = color; \ + p0+=4; p1+=4; \ + case 1: *(Uint32*)p0 = color; *(Uint32*)p1 = color; \ + p0+=4; p1+=4; \ + }while( (i-=4) > 0 ); \ + } \ +SDL_DRAW_WMEMSET_END + +#endif /*SDL_DRAW_BPP*/ + + +void SDL_DRAWFUNCTION(SDL_Surface *super, + Sint16 x0,Sint16 y0, Uint16 w,Uint16 h, + Uint16 corner, Uint32 color) +{ +#if SDL_DRAW_BPP == 3 + Uint8 colorbyte0 = (Uint8) (color & 0xff); + Uint8 colorbyte1 = (Uint8) ((color >> 8) & 0xff); + Uint8 colorbyte2 = (Uint8) ((color >> 16) & 0xff); +#endif + + register Uint8 *p0; + register Uint8 *p1; +#if SDL_DRAW_BPP != 1 + register Sint16 i; +#endif + Sint16 dx, dy; + + Sint16 Xcenter, Ycenter, X2center, Y2center; + + Sint16 x = 0; + Sint16 rightInc = 6; + Sint16 d, diagonalInc; + + SDL_Rect r; + + + if (w==0 || h==0) return; + + /*TODO: We can do better :-)*/ + if (corner!=0) { + d = w= d ) { + if (corner+2 == d) --corner; + else corner = 0; + } + } + + d = 3 - (corner<<1); + diagonalInc = 10 - (corner<<2); + + /*Rectangles*/ + dx = w - (corner<<1); + Xcenter = x0+corner; + dy = h - (corner<<1); + Ycenter = y0+corner; + + /*Centers*/ + X2center=Xcenter+dx-1; + Y2center=Ycenter+dy-1; + + r.x = x0; r.y = Ycenter; + r.w = w; r.h = dy; + SDL_FillRect(super, &r, color); + + while (x < corner) { + + p0 = ((Uint8*)super->pixels+(Ycenter-x)*super->pitch + + (Xcenter-corner)*SDL_DRAW_BPP); + p1 = ((Uint8*)super->pixels+(Y2center+x)*super->pitch + + (Xcenter-corner)*SDL_DRAW_BPP); + + SDL_DRAW_PUTPIXEL + + if (d >= 0) { + d += diagonalInc; + diagonalInc += 8; + --corner; + } else { + d += rightInc; + diagonalInc += 4; + } + rightInc += 4; + ++x; + }/*while*/ + +}/*Draw_FillRound*/ + + +#undef SDL_DRAW_PUTPIXEL + +#undef SDL_DRAW_WMEMSET_START +#undef SDL_DRAW_WMEMSET_END + diff --git a/contrib/sdk/sources/SDL-1.2.2/SDL_draw/src/Draw_HLine.c b/contrib/sdk/sources/SDL-1.2.2/SDL_draw/src/Draw_HLine.c new file mode 100644 index 000000000..c7115e644 --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/SDL_draw/src/Draw_HLine.c @@ -0,0 +1,117 @@ +/*! + \file Draw_HLine.c + \author Mario Palomo + \author Jose M. de la Huerga Fernández + \author Pepe González Mora + \date 05-2002 + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the Free Foundation, + Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#if SDL_DRAW_BPP == 1 +#define SDL_DRAW_PUTPIXEL \ + memset(p, color, x1-x0+1); + +#elif SDL_DRAW_BPP == 2 +#define SDL_DRAW_PUTPIXEL \ + i = x1-x0+1; \ + switch( i % 4 ) { \ + do{ \ + case 0: *(Uint16*)p = color; p+=2; \ + case 3: *(Uint16*)p = color; p+=2; \ + case 2: *(Uint16*)p = color; p+=2; \ + case 1: *(Uint16*)p = color; p+=2; \ + }while( (i-=4) > 0 ); \ + } + +#elif SDL_DRAW_BPP == 3 +#define SDL_DRAW_PUTPIXEL_BPP_3_AUX \ + if (SDL_BYTEORDER == SDL_BIG_ENDIAN) { \ + p[0] = colorbyte2; \ + p[1] = colorbyte1; \ + p[2] = colorbyte0; \ + } else { \ + p[0] = colorbyte0; \ + p[1] = colorbyte1; \ + p[2] = colorbyte2; \ + } + +#define SDL_DRAW_PUTPIXEL \ + i = x1-x0+1; \ + switch( i % 4 ) { \ + do{ \ + case 0: SDL_DRAW_PUTPIXEL_BPP_3_AUX p+=3; \ + case 3: SDL_DRAW_PUTPIXEL_BPP_3_AUX p+=3; \ + case 2: SDL_DRAW_PUTPIXEL_BPP_3_AUX p+=3; \ + case 1: SDL_DRAW_PUTPIXEL_BPP_3_AUX p+=3; \ + }while( (i-=4) > 0 ); \ + } + +#elif SDL_DRAW_BPP == 4 + +#ifdef __linux__ +#define SDL_DRAW_WMEMSET_START \ +if (sizeof(wchar_t) == sizeof(Uint32)) { \ + wmemset((wchar_t*)p, color, x1-x0+1); \ +} else { +#define SDL_DRAW_WMEMSET_END } +#else +#define SDL_DRAW_WMEMSET_START +#define SDL_DRAW_WMEMSET_END +#endif + +#define SDL_DRAW_PUTPIXEL \ +SDL_DRAW_WMEMSET_START \ + i = x1-x0+1; \ + switch( i % 4 ) { \ + do{ \ + case 0: *(Uint32*)p = color; p+=4; \ + case 3: *(Uint32*)p = color; p+=4; \ + case 2: *(Uint32*)p = color; p+=4; \ + case 1: *(Uint32*)p = color; p+=4; \ + }while( (i-=4) > 0 ); \ + } \ +SDL_DRAW_WMEMSET_END + +#endif /*SDL_DRAW_BPP*/ + + +void SDL_DRAWFUNCTION(SDL_Surface *super, + Sint16 x0,Sint16 y0, Sint16 x1, + Uint32 color) +{ +#if SDL_DRAW_BPP == 3 + Uint8 colorbyte0 = (Uint8) (color & 0xff); + Uint8 colorbyte1 = (Uint8) ((color >> 8) & 0xff); + Uint8 colorbyte2 = (Uint8) ((color >> 16) & 0xff); +#endif + + register Uint8 *p; + register Sint16 i; + + if (x0 > x1) { i=x1; x1=x0; x0=i; } + p = (Uint8*)super->pixels + y0 * super->pitch + x0 * SDL_DRAW_BPP; + + SDL_DRAW_PUTPIXEL + +}/*Draw_HLine*/ + + +#undef SDL_DRAW_PUTPIXEL +#undef SDL_DRAW_PUTPIXEL_BPP_3_AUX + +#undef SDL_DRAW_WMEMSET_START +#undef SDL_DRAW_WMEMSET_END + diff --git a/contrib/sdk/sources/SDL-1.2.2/SDL_draw/src/Draw_Line.c b/contrib/sdk/sources/SDL-1.2.2/SDL_draw/src/Draw_Line.c new file mode 100644 index 000000000..eea5a257d --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/SDL_draw/src/Draw_Line.c @@ -0,0 +1,135 @@ +/*! + \file Draw_Line.c + \author Mario Palomo + \author Jose M. de la Huerga Fernández + \author Pepe González Mora + \date 05-2002 + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the Free Foundation, + Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ +#define SDL_DRAW_PUTPIXEL_BPP(A, B, C) \ +*(##A##(##B##(Uint8*)super->pixels + y*super->pitch + x*SDL_DRAW_BPP))=##C##; + +#if SDL_DRAW_BPP == 1 +#define SDL_DRAW_PUTPIXEL SDL_DRAW_PUTPIXEL_BPP(0+,0+,color) + +#elif SDL_DRAW_BPP == 2 +#define SDL_DRAW_PUTPIXEL SDL_DRAW_PUTPIXEL_BPP((Uint16*),0+,color) + +#elif SDL_DRAW_BPP == 3 +#define SDL_DRAW_PUTPIXEL \ + SDL_DRAW_PUTPIXEL_BPP(0+,1+,(Uint8)colorbyte1) \ + if (SDL_BYTEORDER == SDL_BIG_ENDIAN) { \ + SDL_DRAW_PUTPIXEL_BPP(0+,0+,(Uint8)colorbyte2) \ + SDL_DRAW_PUTPIXEL_BPP(0+,2+,(Uint8)colorbyte0) \ + }else{ \ + SDL_DRAW_PUTPIXEL_BPP(0+,0+,(Uint8)colorbyte0) \ + SDL_DRAW_PUTPIXEL_BPP(0+,2+,(Uint8)colorbyte2) \ + } + +#elif SDL_DRAW_BPP == 4 +#define SDL_DRAW_PUTPIXEL SDL_DRAW_PUTPIXEL_BPP((Uint32*),0+,color) + +#endif /*SDL_DRAW_BPP*/ + + +void SDL_DRAWFUNCTION(SDL_Surface *super, + Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, + Uint32 color) +{ +#if SDL_DRAW_BPP == 3 + Uint8 colorbyte0 = (Uint8) (color & 0xff); + Uint8 colorbyte1 = (Uint8) ((color >> 8) & 0xff); + Uint8 colorbyte2 = (Uint8) ((color >> 16) & 0xff); +#endif + + Sint16 x = x1; + Sint16 y = y1; + Sint16 dy = y2 - y1; + Sint16 dx = x2 - x1; + + Sint16 G, DeltaG1, DeltaG2, minG, maxG; + Sint16 swap; + Sint16 inc = 1; + + SDL_DRAW_PUTPIXEL + + if (abs(dy) < abs(dx)) { /* -1 < ramp < 1 */ + if (dx < 0) { + dx = -dx; + dy = -dy; + + swap = y2; + y2 = y1; + y1 = swap; + + swap = x2; + x2 = x1; + x1 = swap; + } + if (dy < 0) { + dy = -dy; + inc = -1; + } + + G = 2 * dy - dx; + DeltaG1 = 2 * (dy - dx); + DeltaG2 = 2 * dy; + + while (x++ < x2) { + if (G > 0) { G += DeltaG1; y += inc; } + else G += DeltaG2; + + SDL_DRAW_PUTPIXEL + }/*while*/ + + } else { /* ramp < -1 or ramp > 1 */ + if (dy < 0) { + dx = -dx; + dy = -dy; + + swap = y2; + y2 = y1; + y1 = swap; + + swap = x2; + x2 = x1; + x1 = swap; + } + if (dx < 0) { + dx = -dx; + inc = -1; + } + + G = 2 * dx - dy; + minG = maxG = G; + DeltaG1 = 2 * (dx - dy); + DeltaG2 = 2 * dx; + + while (y++ < y2) { + if (G > 0) { G += DeltaG1; x += inc; } + else G += DeltaG2; + + SDL_DRAW_PUTPIXEL + }/*while*/ + + }/*if*/ + +}/*Draw_Line*/ + + +#undef SDL_DRAW_PUTPIXEL +#undef SDL_DRAW_PUTPIXEL_BPP + diff --git a/contrib/sdk/sources/SDL-1.2.2/SDL_draw/src/Draw_Pixel.c b/contrib/sdk/sources/SDL-1.2.2/SDL_draw/src/Draw_Pixel.c new file mode 100644 index 000000000..b71ae9b85 --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/SDL_draw/src/Draw_Pixel.c @@ -0,0 +1,64 @@ +/*! + \file Draw_Pixel.c + \author Mario Palomo + \author Jose M. de la Huerga Fernández + \author Pepe González Mora + \date 05-2002 + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the Free Foundation, + Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ +#define SDL_DRAW_PUTPIXEL_BPP(A, B, C) \ +*(##A##(##B##(Uint8*)super->pixels + y*super->pitch + x*SDL_DRAW_BPP))=##C##; + +#if SDL_DRAW_BPP == 1 +#define SDL_DRAW_PUTPIXEL SDL_DRAW_PUTPIXEL_BPP(0+,0+,(Uint8)color) + +#elif SDL_DRAW_BPP == 2 +#define SDL_DRAW_PUTPIXEL SDL_DRAW_PUTPIXEL_BPP((Uint16*),0+,(Uint16)color) + +#elif SDL_DRAW_BPP == 3 +#define SDL_DRAW_PUTPIXEL \ + SDL_DRAW_PUTPIXEL_BPP(0+,1+,colorbyte1) \ + if (SDL_BYTEORDER == SDL_BIG_ENDIAN) { \ + SDL_DRAW_PUTPIXEL_BPP(0+,0+,colorbyte2) \ + SDL_DRAW_PUTPIXEL_BPP(0+,2+,colorbyte0) \ + }else{ \ + SDL_DRAW_PUTPIXEL_BPP(0+,0+,colorbyte0) \ + SDL_DRAW_PUTPIXEL_BPP(0+,2+,colorbyte2) \ + } + +#elif SDL_DRAW_BPP == 4 +#define SDL_DRAW_PUTPIXEL SDL_DRAW_PUTPIXEL_BPP((Uint32*),0+,color) + +#endif /*SDL_DRAW_BPP*/ + + +void SDL_DRAWFUNCTION(SDL_Surface *super, + Sint16 x, Sint16 y, Uint32 color) +{ +#if SDL_DRAW_BPP == 3 + Uint8 colorbyte0 = (Uint8) (color & 0xff); + Uint8 colorbyte1 = (Uint8) ((color >> 8) & 0xff); + Uint8 colorbyte2 = (Uint8) ((color >> 16) & 0xff); +#endif + + SDL_DRAW_PUTPIXEL + +}/*Draw_Pixel*/ + + +#undef SDL_DRAW_PUTPIXEL +#undef SDL_DRAW_PUTPIXEL_BPP + diff --git a/contrib/sdk/sources/SDL-1.2.2/SDL_draw/src/Draw_Rect.c b/contrib/sdk/sources/SDL-1.2.2/SDL_draw/src/Draw_Rect.c new file mode 100644 index 000000000..8553d9566 --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/SDL_draw/src/Draw_Rect.c @@ -0,0 +1,236 @@ +/*! + \file Draw_Rect.c + \author Mario Palomo + \author Jose M. de la Huerga Fernández + \author Pepe González Mora + \date 05-2002 + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the Free Foundation, + Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#if SDL_DRAW_BPP == 1 +#define SDL_DRAW_PUTPIXEL \ + memset(p0, color, w); \ + memset(p1, color, w); \ + \ + if (h<3) return; \ + p0 = (Uint8*)super->pixels + (y+1)*super->pitch + x; \ + p1 = (Uint8*)super->pixels + (y+1)*super->pitch + (x+w-1); \ + i = h-2; \ + switch( i % 4 ) { \ + do{ \ + case 0: \ + *p0 = color; p0+=super->pitch; \ + *p1 = color; p1+=super->pitch; \ + case 3: \ + *p0 = color; p0+=super->pitch; \ + *p1 = color; p1+=super->pitch; \ + case 2: \ + *p0 = color; p0+=super->pitch; \ + *p1 = color; p1+=super->pitch; \ + case 1: \ + *p0 = color; p0+=super->pitch; \ + *p1 = color; p1+=super->pitch; \ + }while( (i-=4) > 0 ); \ + } + + +#elif SDL_DRAW_BPP == 2 +#define SDL_DRAW_PUTPIXEL \ + i = w; \ + switch( i % 4 ) { \ + do{ \ + case 0: \ + *(Uint16*)p0 = color; p0+=2; \ + *(Uint16*)p1 = color; p1+=2; \ + case 3: \ + *(Uint16*)p0 = color; p0+=2; \ + *(Uint16*)p1 = color; p1+=2; \ + case 2: \ + *(Uint16*)p0 = color; p0+=2; \ + *(Uint16*)p1 = color; p1+=2; \ + case 1: \ + *(Uint16*)p0 = color; p0+=2; \ + *(Uint16*)p1 = color; p1+=2; \ + }while( (i-=4) > 0 ); \ + } \ + if (h<3) return; \ + p0 = (Uint8*)super->pixels + (y+1)*super->pitch + x*2; \ + p1 = (Uint8*)super->pixels + (y+1)*super->pitch + (x+w-1)*2; \ + i = h-2; \ + switch( i % 4 ) { \ + do{ \ + case 0: \ + *(Uint16*)p0 = color; p0+=super->pitch; \ + *(Uint16*)p1 = color; p1+=super->pitch; \ + case 3: \ + *(Uint16*)p0 = color; p0+=super->pitch; \ + *(Uint16*)p1 = color; p1+=super->pitch; \ + case 2: \ + *(Uint16*)p0 = color; p0+=super->pitch; \ + *(Uint16*)p1 = color; p1+=super->pitch; \ + case 1: \ + *(Uint16*)p0 = color; p0+=super->pitch; \ + *(Uint16*)p1 = color; p1+=super->pitch; \ + }while( (i-=4) > 0 ); \ + } + + +#elif SDL_DRAW_BPP == 3 +#define SDL_DRAW_PUTPIXEL_BPP_3_AUX \ + if (SDL_BYTEORDER == SDL_BIG_ENDIAN) { \ + p0[0] = colorbyte2; \ + p0[1] = colorbyte1; \ + p0[2] = colorbyte0; \ + p1[0] = colorbyte2; \ + p1[1] = colorbyte1; \ + p1[2] = colorbyte0; \ + } else { \ + p0[0] = colorbyte0; \ + p0[1] = colorbyte1; \ + p0[2] = colorbyte2; \ + p1[0] = colorbyte0; \ + p1[1] = colorbyte1; \ + p1[2] = colorbyte2; \ + } + +#define SDL_DRAW_PUTPIXEL \ + i = w; \ + switch( i % 4 ) { \ + do{ \ + case 0: \ + SDL_DRAW_PUTPIXEL_BPP_3_AUX \ + p0+=3; p1+=3; \ + case 3: \ + SDL_DRAW_PUTPIXEL_BPP_3_AUX \ + p0+=3; p1+=3; \ + case 2: \ + SDL_DRAW_PUTPIXEL_BPP_3_AUX \ + p0+=3; p1+=3; \ + case 1: \ + SDL_DRAW_PUTPIXEL_BPP_3_AUX \ + p0+=3; p1+=3; \ + }while( (i-=4) > 0 ); \ + } \ + if (h<3) return; \ + p0 = (Uint8*)super->pixels + (y+1)*super->pitch + x*3; \ + p1 = (Uint8*)super->pixels + (y+1)*super->pitch + (x+w-1)*3; \ + i = h-2; \ + switch( i % 4 ) { \ + do{ \ + case 0: \ + SDL_DRAW_PUTPIXEL_BPP_3_AUX \ + p0+=super->pitch; p1+=super->pitch; \ + case 3: \ + SDL_DRAW_PUTPIXEL_BPP_3_AUX \ + p0+=super->pitch; p1+=super->pitch; \ + case 2: \ + SDL_DRAW_PUTPIXEL_BPP_3_AUX \ + p0+=super->pitch; p1+=super->pitch; \ + case 1: \ + SDL_DRAW_PUTPIXEL_BPP_3_AUX \ + p0+=super->pitch; p1+=super->pitch; \ + }while( (i-=4) > 0 ); \ + } + + +#elif SDL_DRAW_BPP == 4 + +#ifdef __linux__ +#define SDL_DRAW_WMEMSET_START \ +if (sizeof(wchar_t) == sizeof(Uint32)) { \ + wmemset((wchar_t*)p0, color, w); \ + wmemset((wchar_t*)p1, color, w); \ +} else { +#define SDL_DRAW_WMEMSET_END } +#else +#define SDL_DRAW_WMEMSET_START +#define SDL_DRAW_WMEMSET_END +#endif + +#define SDL_DRAW_PUTPIXEL \ +SDL_DRAW_WMEMSET_START \ + i = w; \ + switch( i % 4 ) { \ + do{ \ + case 0: \ + *(Uint32*)p0 = color; p0+=4; \ + *(Uint32*)p1 = color; p1+=4; \ + case 3: \ + *(Uint32*)p0 = color; p0+=4; \ + *(Uint32*)p1 = color; p1+=4; \ + case 2: \ + *(Uint32*)p0 = color; p0+=4; \ + *(Uint32*)p1 = color; p1+=4; \ + case 1: \ + *(Uint32*)p0 = color; p0+=4; \ + *(Uint32*)p1 = color; p1+=4; \ + }while( (i-=4) > 0 ); \ + } \ +SDL_DRAW_WMEMSET_END \ + if (h<3) return; \ + p0 = (Uint8*)super->pixels + (y+1)*super->pitch + x*4; \ + p1 = (Uint8*)super->pixels + (y+1)*super->pitch + (x+w-1)*4; \ + i = h-2; \ + switch( i % 4 ) { \ + do{ \ + case 0: \ + *(Uint32*)p0 = color; p0+=super->pitch; \ + *(Uint32*)p1 = color; p1+=super->pitch; \ + case 3: \ + *(Uint32*)p0 = color; p0+=super->pitch; \ + *(Uint32*)p1 = color; p1+=super->pitch; \ + case 2: \ + *(Uint32*)p0 = color; p0+=super->pitch; \ + *(Uint32*)p1 = color; p1+=super->pitch; \ + case 1: \ + *(Uint32*)p0 = color; p0+=super->pitch; \ + *(Uint32*)p1 = color; p1+=super->pitch; \ + }while( (i-=4) > 0 ); \ + } + +#endif /*SDL_DRAW_BPP*/ + + +void SDL_DRAWFUNCTION(SDL_Surface *super, + Sint16 x, Sint16 y, Uint16 w, Uint16 h, + Uint32 color) +{ +#if SDL_DRAW_BPP == 3 + Uint8 colorbyte0 = (Uint8) (color & 0xff); + Uint8 colorbyte1 = (Uint8) ((color >> 8) & 0xff); + Uint8 colorbyte2 = (Uint8) ((color >> 16) & 0xff); +#endif + + register Uint8 *p0; + register Uint8 *p1; + register Sint16 i; + + if (w==0 || h==0) return; + + p0 = (Uint8*)super->pixels + y * super->pitch + x * SDL_DRAW_BPP; + p1 = (Uint8*)super->pixels + (y+h-1) * super->pitch + x * SDL_DRAW_BPP; + + SDL_DRAW_PUTPIXEL + +}/*Draw_Rect*/ + + +#undef SDL_DRAW_PUTPIXEL +#undef SDL_DRAW_PUTPIXEL_BPP_3_AUX + +#undef SDL_DRAW_WMEMSET_START +#undef SDL_DRAW_WMEMSET_END + diff --git a/contrib/sdk/sources/SDL-1.2.2/SDL_draw/src/Draw_Round.c b/contrib/sdk/sources/SDL-1.2.2/SDL_draw/src/Draw_Round.c new file mode 100644 index 000000000..122677e00 --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/SDL_draw/src/Draw_Round.c @@ -0,0 +1,326 @@ +/*! + \file Draw_Round.c + \author Mario Palomo + \author Jose M. de la Huerga Fernández + \author Pepe González Mora + \date 05-2002 + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the Free Foundation, + Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +/*Circle arcs*/ +#define SDL_DRAW_PUTPIXEL_CIRCLE_BPP(A, B, C) \ + *(##A##(##B##(Uint8*)super->pixels + (Ycenter-x)*super->pitch + \ + (Xcenter - corner)*SDL_DRAW_BPP)) = C##; \ + *(##A##(##B##(Uint8*)super->pixels + (Ycenter-corner)*super->pitch + \ + (Xcenter - x)*SDL_DRAW_BPP)) = C##; \ + *(##A##(##B##(Uint8*)super->pixels + (Ycenter-corner)*super->pitch + \ + (X2center + x)*SDL_DRAW_BPP)) = C##; \ + *(##A##(##B##(Uint8*)super->pixels + (Ycenter-x)*super->pitch + \ + (X2center + corner)*SDL_DRAW_BPP)) = C##; \ + *(##A##(##B##(Uint8*)super->pixels + (Y2center+corner)*super->pitch + \ + (X2center + x)*SDL_DRAW_BPP)) = C##; \ + *(##A##(##B##(Uint8*)super->pixels + (Y2center+x)*super->pitch + \ + (X2center + corner)*SDL_DRAW_BPP)) = C##; \ + *(##A##(##B##(Uint8*)super->pixels + (Y2center+corner)*super->pitch + \ + (Xcenter - x)*SDL_DRAW_BPP)) = C##; \ + *(##A##(##B##(Uint8*)super->pixels + (Y2center+x)*super->pitch + \ + (Xcenter - corner)*SDL_DRAW_BPP)) = C##; + + +#if SDL_DRAW_BPP == 1 +#define SDL_DRAW_PUTPIXEL_CIRCLE SDL_DRAW_PUTPIXEL_CIRCLE_BPP(0+,0+,color) + +#elif SDL_DRAW_BPP == 2 +#define SDL_DRAW_PUTPIXEL_CIRCLE SDL_DRAW_PUTPIXEL_CIRCLE_BPP((Uint16*),0+,color) + +#elif SDL_DRAW_BPP == 3 +#define SDL_DRAW_PUTPIXEL_CIRCLE \ + SDL_DRAW_PUTPIXEL_CIRCLE_BPP(0+,1+,colorbyte1) \ + if (SDL_BYTEORDER == SDL_BIG_ENDIAN) { \ + SDL_DRAW_PUTPIXEL_CIRCLE_BPP(0+,0+,colorbyte2) \ + SDL_DRAW_PUTPIXEL_CIRCLE_BPP(0+,2+,colorbyte0) \ + }else{ \ + SDL_DRAW_PUTPIXEL_CIRCLE_BPP(0+,0+,colorbyte0) \ + SDL_DRAW_PUTPIXEL_CIRCLE_BPP(0+,2+,colorbyte2) \ + } + +#elif SDL_DRAW_BPP == 4 +#define SDL_DRAW_PUTPIXEL_CIRCLE SDL_DRAW_PUTPIXEL_CIRCLE_BPP((Uint32*),0+,color) + +#endif /*SDL_DRAW_BPP*/ + + +/*Rectangles*/ +#if SDL_DRAW_BPP == 1 +#define SDL_DRAW_PUTPIXEL \ + memset(p0, color, dx); \ + memset(p1, color, dx); \ + \ + if (h<3) return; \ + p0 = (Uint8*)super->pixels + Ycenter*super->pitch + x0; \ + p1 = (Uint8*)super->pixels + Ycenter*super->pitch + x0+w-1; \ + i=dy; \ + switch( i % 4 ) { \ + do{ \ + case 0: \ + *p0 = color; p0+=super->pitch; \ + *p1 = color; p1+=super->pitch; \ + case 3: \ + *p0 = color; p0+=super->pitch; \ + *p1 = color; p1+=super->pitch; \ + case 2: \ + *p0 = color; p0+=super->pitch; \ + *p1 = color; p1+=super->pitch; \ + case 1: \ + *p0 = color; p0+=super->pitch; \ + *p1 = color; p1+=super->pitch; \ + }while( (i-=4) > 0 ); \ + } + +#elif SDL_DRAW_BPP == 2 +#define SDL_DRAW_PUTPIXEL \ + i=dx; \ + switch( i % 4 ) { \ + do{ \ + case 0: \ + *(Uint16*)p0 = color; p0+=2; \ + *(Uint16*)p1 = color; p1+=2; \ + case 3: \ + *(Uint16*)p0 = color; p0+=2; \ + *(Uint16*)p1 = color; p1+=2; \ + case 2: \ + *(Uint16*)p0 = color; p0+=2; \ + *(Uint16*)p1 = color; p1+=2; \ + case 1: \ + *(Uint16*)p0 = color; p0+=2; \ + *(Uint16*)p1 = color; p1+=2; \ + }while( (i-=4) > 0 ); \ + } \ + if (h<3) return; \ + p0 = (Uint8*)super->pixels + Ycenter*super->pitch + x0*2; \ + p1 = (Uint8*)super->pixels + Ycenter*super->pitch + (x0+w-1)*2; \ + i=dy; \ + switch( i % 4 ) { \ + do{ \ + case 0: \ + *(Uint16*)p0 = color; p0+=super->pitch; \ + *(Uint16*)p1 = color; p1+=super->pitch; \ + case 3: \ + *(Uint16*)p0 = color; p0+=super->pitch; \ + *(Uint16*)p1 = color; p1+=super->pitch; \ + case 2: \ + *(Uint16*)p0 = color; p0+=super->pitch; \ + *(Uint16*)p1 = color; p1+=super->pitch; \ + case 1: \ + *(Uint16*)p0 = color; p0+=super->pitch; \ + *(Uint16*)p1 = color; p1+=super->pitch; \ + }while( (i-=4) > 0 ); \ + } + + +#elif SDL_DRAW_BPP == 3 +#define SDL_DRAW_PUTPIXEL_BPP_3_AUX \ + if (SDL_BYTEORDER == SDL_BIG_ENDIAN) { \ + p0[0] = colorbyte2; \ + p0[1] = colorbyte1; \ + p0[2] = colorbyte0; \ + p1[0] = colorbyte2; \ + p1[1] = colorbyte1; \ + p1[2] = colorbyte0; \ + } else { \ + p0[0] = colorbyte0; \ + p0[1] = colorbyte1; \ + p0[2] = colorbyte2; \ + p1[0] = colorbyte0; \ + p1[1] = colorbyte1; \ + p1[2] = colorbyte2; \ + } + +#define SDL_DRAW_PUTPIXEL \ + i=dx; \ + switch( i % 4 ) { \ + do{ \ + case 0: \ + SDL_DRAW_PUTPIXEL_BPP_3_AUX \ + p0+=3; p1+=3; \ + case 3: \ + SDL_DRAW_PUTPIXEL_BPP_3_AUX \ + p0+=3; p1+=3; \ + case 2: \ + SDL_DRAW_PUTPIXEL_BPP_3_AUX \ + p0+=3; p1+=3; \ + case 1: \ + SDL_DRAW_PUTPIXEL_BPP_3_AUX \ + p0+=3; p1+=3; \ + }while( (i-=4) > 0 ); \ + } \ + if (h<3) return; \ + p0 = (Uint8*)super->pixels + Ycenter*super->pitch + x0*3; \ + p1 = (Uint8*)super->pixels + Ycenter*super->pitch + (x0+w-1)*3; \ + i=dy; \ + switch( i % 4 ) { \ + do{ \ + case 0: \ + SDL_DRAW_PUTPIXEL_BPP_3_AUX \ + p0+=super->pitch; p1+=super->pitch; \ + case 3: \ + SDL_DRAW_PUTPIXEL_BPP_3_AUX \ + p0+=super->pitch; p1+=super->pitch; \ + case 2: \ + SDL_DRAW_PUTPIXEL_BPP_3_AUX \ + p0+=super->pitch; p1+=super->pitch; \ + case 1: \ + SDL_DRAW_PUTPIXEL_BPP_3_AUX \ + p0+=super->pitch; p1+=super->pitch; \ + }while( (i-=4) > 0 ); \ + } + + +#elif SDL_DRAW_BPP == 4 +#ifdef __linux__ +#define SDL_DRAW_WMEMSET_START \ +if (sizeof(wchar_t) == sizeof(Uint32)) { \ + wmemset((wchar_t*)p0, color, dx); \ + wmemset((wchar_t*)p1, color, dx); \ +} else { +#define SDL_DRAW_WMEMSET_END } +#else +#define SDL_DRAW_WMEMSET_START +#define SDL_DRAW_WMEMSET_END +#endif + +#define SDL_DRAW_PUTPIXEL \ +SDL_DRAW_WMEMSET_START \ + i=dx; \ + switch( i % 4 ) { \ + do{ \ + case 0: \ + *(Uint32*)p0 = color; p0+=4; \ + *(Uint32*)p1 = color; p1+=4; \ + case 3: \ + *(Uint32*)p0 = color; p0+=4; \ + *(Uint32*)p1 = color; p1+=4; \ + case 2: \ + *(Uint32*)p0 = color; p0+=4; \ + *(Uint32*)p1 = color; p1+=4; \ + case 1: \ + *(Uint32*)p0 = color; p0+=4; \ + *(Uint32*)p1 = color; p1+=4; \ + }while( (i-=4) > 0 ); \ + } \ +SDL_DRAW_WMEMSET_END \ + if (h<3) return; \ + p0 = (Uint8*)super->pixels + Ycenter*super->pitch + x0*4; \ + p1 = (Uint8*)super->pixels + Ycenter*super->pitch + (x0+w-1)*4; \ + i=dy; \ + switch( i % 4 ) { \ + do{ \ + case 0: \ + *(Uint32*)p0 = color; p0+=super->pitch; \ + *(Uint32*)p1 = color; p1+=super->pitch; \ + case 3: \ + *(Uint32*)p0 = color; p0+=super->pitch; \ + *(Uint32*)p1 = color; p1+=super->pitch; \ + case 2: \ + *(Uint32*)p0 = color; p0+=super->pitch; \ + *(Uint32*)p1 = color; p1+=super->pitch; \ + case 1: \ + *(Uint32*)p0 = color; p0+=super->pitch; \ + *(Uint32*)p1 = color; p1+=super->pitch; \ + }while( (i-=4) > 0 ); \ + } + +#endif /*SDL_DRAW_BPP*/ + + + +void SDL_DRAWFUNCTION(SDL_Surface *super, + Sint16 x0,Sint16 y0, Uint16 w,Uint16 h, + Uint16 corner, Uint32 color) +{ +#if SDL_DRAW_BPP == 3 + Uint8 colorbyte0 = (Uint8) (color & 0xff); + Uint8 colorbyte1 = (Uint8) ((color >> 8) & 0xff); + Uint8 colorbyte2 = (Uint8) ((color >> 16) & 0xff); +#endif + + register Uint8 *p0; + register Uint8 *p1; + register Sint16 i; + Sint16 dx, dy; + + Sint16 Xcenter, Ycenter, X2center, Y2center; + + Sint16 x = 0; + Sint16 rightInc = 6; + Sint16 d, diagonalInc; + + if (w==0 || h==0) return; + + /*TODO: We can do better :-)*/ + if (corner!=0) { + d = w= d ) { + if (corner+2 == d) --corner; + else corner = 0; + } + } + + d = 3 - (corner<<1); + diagonalInc = 10 - (corner<<2); + + /*Rectangles*/ + dx = w - (corner<<1); + Xcenter = x0+corner; + dy = h - (corner<<1); + Ycenter = y0+corner; + + /*Centers*/ + X2center=Xcenter+dx-1; + Y2center=Ycenter+dy-1; + + p0 = (Uint8*)super->pixels + y0 * super->pitch + Xcenter*SDL_DRAW_BPP; + p1 = (Uint8*)super->pixels + (y0+h-1) * super->pitch + Xcenter*SDL_DRAW_BPP; + + SDL_DRAW_PUTPIXEL + + while (x < corner) { + + SDL_DRAW_PUTPIXEL_CIRCLE + + if (d >= 0) { + d += diagonalInc; + diagonalInc += 8; + --corner; + } else { + d += rightInc; + diagonalInc += 4; + } + rightInc += 4; + ++x; + }/*while*/ + +}/*Draw_Round*/ + + +#undef SDL_DRAW_PUTPIXEL +#undef SDL_DRAW_PUTPIXEL_CIRCLE +#undef SDL_DRAW_PUTPIXEL_CIRCLE_BPP + +#undef SDL_DRAW_WMEMSET_START +#undef SDL_DRAW_WMEMSET_END + diff --git a/contrib/sdk/sources/SDL-1.2.2/SDL_draw/src/Draw_VLine.c b/contrib/sdk/sources/SDL-1.2.2/SDL_draw/src/Draw_VLine.c new file mode 100644 index 000000000..5d0caaa36 --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/SDL_draw/src/Draw_VLine.c @@ -0,0 +1,109 @@ +/*! + \file Draw_VLine.c + \author Mario Palomo + \author Jose M. de la Huerga Fernández + \author Pepe González Mora + \date 05-2002 + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the Free Foundation, + Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#if SDL_DRAW_BPP == 1 +#define SDL_DRAW_PUTPIXEL \ + i = y1-y0+1; \ + switch( i % 4 ) { \ + do{ \ + case 0: *p = color; p+=super->pitch; \ + case 3: *p = color; p+=super->pitch; \ + case 2: *p = color; p+=super->pitch; \ + case 1: *p = color; p+=super->pitch; \ + }while( (i-=4) > 0 ); \ + } + +#elif SDL_DRAW_BPP == 2 +#define SDL_DRAW_PUTPIXEL \ + i = y1-y0+1; \ + switch( i % 4 ) { \ + do{ \ + case 0: *(Uint16*)p = color; p+=super->pitch; \ + case 3: *(Uint16*)p = color; p+=super->pitch; \ + case 2: *(Uint16*)p = color; p+=super->pitch; \ + case 1: *(Uint16*)p = color; p+=super->pitch; \ + }while( (i-=4) > 0 ); \ + } + +#elif SDL_DRAW_BPP == 3 +#define SDL_DRAW_PUTPIXEL_BPP_3_AUX \ + if (SDL_BYTEORDER == SDL_BIG_ENDIAN) { \ + p[0] = colorbyte2; \ + p[1] = colorbyte1; \ + p[2] = colorbyte0; \ + } else { \ + p[0] = colorbyte0; \ + p[1] = colorbyte1; \ + p[2] = colorbyte2; \ + } + +#define SDL_DRAW_PUTPIXEL \ + i = y1-y0+1; \ + switch( i % 4 ) { \ + do{ \ + case 0: SDL_DRAW_PUTPIXEL_BPP_3_AUX p+=super->pitch; \ + case 3: SDL_DRAW_PUTPIXEL_BPP_3_AUX p+=super->pitch; \ + case 2: SDL_DRAW_PUTPIXEL_BPP_3_AUX p+=super->pitch; \ + case 1: SDL_DRAW_PUTPIXEL_BPP_3_AUX p+=super->pitch; \ + }while( (i-=4) > 0 ); \ + } + + +#elif SDL_DRAW_BPP == 4 +#define SDL_DRAW_PUTPIXEL \ + i = y1-y0+1; \ + switch( i % 4 ) { \ + do{ \ + case 0: *(Uint32*)p = color; p+=super->pitch; \ + case 3: *(Uint32*)p = color; p+=super->pitch; \ + case 2: *(Uint32*)p = color; p+=super->pitch; \ + case 1: *(Uint32*)p = color; p+=super->pitch; \ + }while( (i-=4) > 0 ); \ + } + +#endif /*SDL_DRAW_BPP*/ + + +void SDL_DRAWFUNCTION(SDL_Surface *super, + Sint16 x0,Sint16 y0, Sint16 y1, + Uint32 color) +{ +#if SDL_DRAW_BPP == 3 + Uint8 colorbyte0 = (Uint8) (color & 0xff); + Uint8 colorbyte1 = (Uint8) ((color >> 8) & 0xff); + Uint8 colorbyte2 = (Uint8) ((color >> 16) & 0xff); +#endif + + register Uint8 *p; + register Sint16 i; + + if (y0 > y1) { i=y1; y1=y0; y0=i; } + p = (Uint8*)super->pixels + y0 * super->pitch + x0 * SDL_DRAW_BPP; + + SDL_DRAW_PUTPIXEL + +}/*Draw_VLine*/ + + +#undef SDL_DRAW_PUTPIXEL +#undef SDL_DRAW_PUTPIXEL_BPP_3_AUX + diff --git a/contrib/sdk/sources/SDL-1.2.2/SDL_draw/src/SDL_draw.c b/contrib/sdk/sources/SDL-1.2.2/SDL_draw/src/SDL_draw.c new file mode 100644 index 000000000..75be3f89a --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/SDL_draw/src/SDL_draw.c @@ -0,0 +1,546 @@ +/*! + \file SDL_draw.c + \author Mario Palomo Torrero + \author Jose M. de la Huerga Fernández + \author Pepe González Mora + \date 05-2002 + + Drawing primitives for SDL. Main implementation file. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the Free Foundation, + Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ +#include "SDL_draw.h" +#include +#include +#include +#include /*wmemset*/ + + +/*==================== BEGIN of Draw_Pixel ======================*/ + +#define SDL_DRAW_BPP 1 +#define SDL_DRAWFUNCTION Draw_Pixel_1 +#include "Draw_Pixel.c" +#undef SDL_DRAWFUNCTION +#undef SDL_DRAW_BPP + +#define SDL_DRAW_BPP 2 +#define SDL_DRAWFUNCTION Draw_Pixel_2 +#include "Draw_Pixel.c" +#undef SDL_DRAWFUNCTION +#undef SDL_DRAW_BPP + +#define SDL_DRAW_BPP 3 +#define SDL_DRAWFUNCTION Draw_Pixel_3 +#include "Draw_Pixel.c" +#undef SDL_DRAWFUNCTION +#undef SDL_DRAW_BPP + +#define SDL_DRAW_BPP 4 +#define SDL_DRAWFUNCTION Draw_Pixel_4 +#include "Draw_Pixel.c" +#undef SDL_DRAWFUNCTION +#undef SDL_DRAW_BPP + +static +void Draw_Pixel_error(SDL_Surface *super, + Sint16 x, Sint16 y, Uint32 color) +{ + SDL_printf("SDL_draw: Draw_Pixel ERROR!!." + " Have you call to SDL_Draw_Init()?\n"); + exit(-1); +} + +void (*Draw_Pixel)(SDL_Surface *super, + Sint16 x, Sint16 y, Uint32 color) = Draw_Pixel_error; + +/*===================== END of Draw_Pixel =======================*/ + +/*==================== BEGIN of Draw_Line ======================*/ + +#define SDL_DRAW_BPP 1 +#define SDL_DRAWFUNCTION Draw_Line_1 +#include "Draw_Line.c" +#undef SDL_DRAWFUNCTION +#undef SDL_DRAW_BPP + +#define SDL_DRAW_BPP 2 +#define SDL_DRAWFUNCTION Draw_Line_2 +#include "Draw_Line.c" +#undef SDL_DRAWFUNCTION +#undef SDL_DRAW_BPP + +#define SDL_DRAW_BPP 3 +#define SDL_DRAWFUNCTION Draw_Line_3 +#include "Draw_Line.c" +#undef SDL_DRAWFUNCTION +#undef SDL_DRAW_BPP + +#define SDL_DRAW_BPP 4 +#define SDL_DRAWFUNCTION Draw_Line_4 +#include "Draw_Line.c" +#undef SDL_DRAWFUNCTION +#undef SDL_DRAW_BPP + +static +void Draw_Line_error(SDL_Surface *super, + Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, + Uint32 color) +{ + SDL_printf("SDL_draw: Draw_Line ERROR!!." + " Have you call to SDL_Draw_Init()?\n"); + exit(-1); +} + +void (*Draw_Line)(SDL_Surface *super, + Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, + Uint32 color) = Draw_Line_error; + +/*===================== END of Draw_Line =======================*/ + +/*=================== BEGIN of Draw_Circle =====================*/ + +#define SDL_DRAW_BPP 1 +#define SDL_DRAWFUNCTION Draw_Circle_1 +#include "Draw_Circle.c" +#undef SDL_DRAWFUNCTION +#undef SDL_DRAW_BPP + +#define SDL_DRAW_BPP 2 +#define SDL_DRAWFUNCTION Draw_Circle_2 +#include "Draw_Circle.c" +#undef SDL_DRAWFUNCTION +#undef SDL_DRAW_BPP + +#define SDL_DRAW_BPP 3 +#define SDL_DRAWFUNCTION Draw_Circle_3 +#include "Draw_Circle.c" +#undef SDL_DRAWFUNCTION +#undef SDL_DRAW_BPP + +#define SDL_DRAW_BPP 4 +#define SDL_DRAWFUNCTION Draw_Circle_4 +#include "Draw_Circle.c" +#undef SDL_DRAWFUNCTION +#undef SDL_DRAW_BPP + +static +void Draw_Circle_error(SDL_Surface *super, + Sint16 x0, Sint16 y0, Uint16 r, + Uint32 color) +{ + SDL_printf("SDL_draw: Draw_Circle ERROR!!." + " Have you call to SDL_Draw_Init()?\n"); + exit(-1); +} + + +void (*Draw_Circle)(SDL_Surface *super, + Sint16 x0, Sint16 y0, Uint16 r, + Uint32 color) = Draw_Circle_error; + +/*==================== END of Draw_Circle ======================*/ + +/*================= BEGIN of Draw_FillCircle ===================*/ + +#define SDL_DRAW_BPP 1 +#define SDL_DRAWFUNCTION Draw_FillCircle_1 +#include "Draw_FillCircle.c" +#undef SDL_DRAWFUNCTION +#undef SDL_DRAW_BPP + +#define SDL_DRAW_BPP 2 +#define SDL_DRAWFUNCTION Draw_FillCircle_2 +#include "Draw_FillCircle.c" +#undef SDL_DRAWFUNCTION +#undef SDL_DRAW_BPP + +#define SDL_DRAW_BPP 3 +#define SDL_DRAWFUNCTION Draw_FillCircle_3 +#include "Draw_FillCircle.c" +#undef SDL_DRAWFUNCTION +#undef SDL_DRAW_BPP + +#define SDL_DRAW_BPP 4 +#define SDL_DRAWFUNCTION Draw_FillCircle_4 +#include "Draw_FillCircle.c" +#undef SDL_DRAWFUNCTION +#undef SDL_DRAW_BPP + +static +void Draw_FillCircle_error(SDL_Surface *super, + Sint16 x0, Sint16 y0, Uint16 r, + Uint32 color) +{ + SDL_printf("SDL_draw: Draw_FillCircle ERROR!!." + " Have you call to SDL_Draw_Init()?\n"); + exit(-1); +} + + +void (*Draw_FillCircle)(SDL_Surface *super, + Sint16 x0, Sint16 y0, Uint16 r, + Uint32 color) = Draw_FillCircle_error; + +/*================== END of Draw_FillCircle ====================*/ + +/*=================== BEGIN of Draw_HLine =====================*/ + +#define SDL_DRAW_BPP 1 +#define SDL_DRAWFUNCTION Draw_HLine_1 +#include "Draw_HLine.c" +#undef SDL_DRAWFUNCTION +#undef SDL_DRAW_BPP + +#define SDL_DRAW_BPP 2 +#define SDL_DRAWFUNCTION Draw_HLine_2 +#include "Draw_HLine.c" +#undef SDL_DRAWFUNCTION +#undef SDL_DRAW_BPP + +#define SDL_DRAW_BPP 3 +#define SDL_DRAWFUNCTION Draw_HLine_3 +#include "Draw_HLine.c" +#undef SDL_DRAWFUNCTION +#undef SDL_DRAW_BPP + +#define SDL_DRAW_BPP 4 +#define SDL_DRAWFUNCTION Draw_HLine_4 +#include "Draw_HLine.c" +#undef SDL_DRAWFUNCTION +#undef SDL_DRAW_BPP + +static +void Draw_HLine_error(SDL_Surface *super, + Sint16 x0,Sint16 y0, Sint16 x1, + Uint32 color) +{ + SDL_printf("SDL_draw: Draw_HLine ERROR!!." + " Have you call to SDL_Draw_Init()?\n"); + exit(-1); +} + +void (*Draw_HLine)(SDL_Surface *super, + Sint16 x0,Sint16 y0, Sint16 x1, + Uint32 color) = Draw_HLine_error; + +/*==================== END of Draw_HLine ======================*/ + +/*=================== BEGIN of Draw_VLine =====================*/ +#define SDL_DRAW_BPP 1 +#define SDL_DRAWFUNCTION Draw_VLine_1 +#include "Draw_VLine.c" +#undef SDL_DRAWFUNCTION +#undef SDL_DRAW_BPP + +#define SDL_DRAW_BPP 2 +#define SDL_DRAWFUNCTION Draw_VLine_2 +#include "Draw_VLine.c" +#undef SDL_DRAWFUNCTION +#undef SDL_DRAW_BPP + +#define SDL_DRAW_BPP 3 +#define SDL_DRAWFUNCTION Draw_VLine_3 +#include "Draw_VLine.c" +#undef SDL_DRAWFUNCTION +#undef SDL_DRAW_BPP + +#define SDL_DRAW_BPP 4 +#define SDL_DRAWFUNCTION Draw_VLine_4 +#include "Draw_VLine.c" +#undef SDL_DRAWFUNCTION +#undef SDL_DRAW_BPP + +static +void Draw_VLine_error(SDL_Surface *super, + Sint16 x0,Sint16 y0, Sint16 y1, + Uint32 color) +{ + SDL_printf("SDL_draw: Draw_VLine ERROR!!." + " Have you call to SDL_Draw_Init()?\n"); + exit(-1); +} + + +void (*Draw_VLine)(SDL_Surface *super, + Sint16 x0,Sint16 y0, Sint16 y1, + Uint32 color) = Draw_VLine_error; + +/*==================== END of Draw_VLine ======================*/ + +/*==================== BEGIN of Draw_Rect ======================*/ + +#define SDL_DRAW_BPP 1 +#define SDL_DRAWFUNCTION Draw_Rect_1 +#include "Draw_Rect.c" +#undef SDL_DRAWFUNCTION +#undef SDL_DRAW_BPP + +#define SDL_DRAW_BPP 2 +#define SDL_DRAWFUNCTION Draw_Rect_2 +#include "Draw_Rect.c" +#undef SDL_DRAWFUNCTION +#undef SDL_DRAW_BPP + +#define SDL_DRAW_BPP 3 +#define SDL_DRAWFUNCTION Draw_Rect_3 +#include "Draw_Rect.c" +#undef SDL_DRAWFUNCTION +#undef SDL_DRAW_BPP + +#define SDL_DRAW_BPP 4 +#define SDL_DRAWFUNCTION Draw_Rect_4 +#include "Draw_Rect.c" +#undef SDL_DRAWFUNCTION +#undef SDL_DRAW_BPP + +static +void Draw_Rect_error(SDL_Surface *super, + Sint16 x,Sint16 y, Uint16 w,Uint16 h, + Uint32 color) +{ + SDL_printf("SDL_draw: Draw_Rect ERROR!!." + " Have you call to SDL_Draw_Init()?\n"); + exit(-1); +} + +void (*Draw_Rect)(SDL_Surface *super, + Sint16 x,Sint16 y, Uint16 w,Uint16 h, + Uint32 color) = Draw_Rect_error; + +/*===================== END of Draw_Rect =======================*/ + +/*=================== BEGIN of Draw_Ellipse ====================*/ + +#define SDL_DRAW_BPP 1 +#define SDL_DRAWFUNCTION Draw_Ellipse_1 +#include "Draw_Ellipse.c" +#undef SDL_DRAWFUNCTION +#undef SDL_DRAW_BPP + +#define SDL_DRAW_BPP 2 +#define SDL_DRAWFUNCTION Draw_Ellipse_2 +#include "Draw_Ellipse.c" +#undef SDL_DRAWFUNCTION +#undef SDL_DRAW_BPP + +#define SDL_DRAW_BPP 3 +#define SDL_DRAWFUNCTION Draw_Ellipse_3 +#include "Draw_Ellipse.c" +#undef SDL_DRAWFUNCTION +#undef SDL_DRAW_BPP + +#define SDL_DRAW_BPP 4 +#define SDL_DRAWFUNCTION Draw_Ellipse_4 +#include "Draw_Ellipse.c" +#undef SDL_DRAWFUNCTION +#undef SDL_DRAW_BPP + +static +void Draw_Ellipse_error(SDL_Surface *super, + Sint16 x0, Sint16 y0, + Uint16 Xradius, Uint16 Yradius, + Uint32 color) +{ + SDL_printf("SDL_draw: Draw_Ellipse ERROR!!." + " Have you call to SDL_Draw_Init()?\n"); + exit(-1); +} + + +void (*Draw_Ellipse)(SDL_Surface *super, + Sint16 x0, Sint16 y0, + Uint16 Xradius, Uint16 Yradius, + Uint32 color) = Draw_Ellipse_error; + +/*==================== END of Draw_Ellipse =====================*/ + +/*================= BEGIN of Draw_FillEllipse ==================*/ + +#define SDL_DRAW_BPP 1 +#define SDL_DRAWFUNCTION Draw_FillEllipse_1 +#include "Draw_FillEllipse.c" +#undef SDL_DRAWFUNCTION +#undef SDL_DRAW_BPP + +#define SDL_DRAW_BPP 2 +#define SDL_DRAWFUNCTION Draw_FillEllipse_2 +#include "Draw_FillEllipse.c" +#undef SDL_DRAWFUNCTION +#undef SDL_DRAW_BPP + +#define SDL_DRAW_BPP 3 +#define SDL_DRAWFUNCTION Draw_FillEllipse_3 +#include "Draw_FillEllipse.c" +#undef SDL_DRAWFUNCTION +#undef SDL_DRAW_BPP + +#define SDL_DRAW_BPP 4 +#define SDL_DRAWFUNCTION Draw_FillEllipse_4 +#include "Draw_FillEllipse.c" +#undef SDL_DRAWFUNCTION +#undef SDL_DRAW_BPP + +static +void Draw_FillEllipse_error(SDL_Surface *super, + Sint16 x0, Sint16 y0, + Uint16 Xradius, Uint16 Yradius, + Uint32 color) +{ + SDL_printf("SDL_draw: Draw_FillEllipse ERROR!!." + " Have you call to SDL_Draw_Init()?\n"); + exit(-1); +} + + +void (*Draw_FillEllipse)(SDL_Surface *super, + Sint16 x0, Sint16 y0, + Uint16 Xradius, Uint16 Yradius, + Uint32 color) = Draw_FillEllipse_error; + +/*================== END of Draw_FillEllipse ===================*/ + +/*==================== BEGIN of Draw_Round =====================*/ + +#define SDL_DRAW_BPP 1 +#define SDL_DRAWFUNCTION Draw_Round_1 +#include "Draw_Round.c" +#undef SDL_DRAWFUNCTION +#undef SDL_DRAW_BPP + +#define SDL_DRAW_BPP 2 +#define SDL_DRAWFUNCTION Draw_Round_2 +#include "Draw_Round.c" +#undef SDL_DRAWFUNCTION +#undef SDL_DRAW_BPP + +#define SDL_DRAW_BPP 3 +#define SDL_DRAWFUNCTION Draw_Round_3 +#include "Draw_Round.c" +#undef SDL_DRAWFUNCTION +#undef SDL_DRAW_BPP + +#define SDL_DRAW_BPP 4 +#define SDL_DRAWFUNCTION Draw_Round_4 +#include "Draw_Round.c" +#undef SDL_DRAWFUNCTION +#undef SDL_DRAW_BPP + +static +void Draw_Round_error(SDL_Surface *super, + Sint16 x0,Sint16 y0, Uint16 w,Uint16 h, + Uint16 corner, Uint32 color) +{ + SDL_printf("SDL_draw: Draw_Round ERROR!!." + " Have you call to SDL_Draw_Init()?\n"); + exit(-1); +} + +void (*Draw_Round)(SDL_Surface *super, + Sint16 x0,Sint16 y0, Uint16 w,Uint16 h, + Uint16 corner, Uint32 color) = Draw_Round_error; + +/*===================== END of Draw_Round ======================*/ + +/*================== BEGIN of Draw_FillRound ===================*/ + +#define SDL_DRAW_BPP 1 +#define SDL_DRAWFUNCTION Draw_FillRound_1 +#include "Draw_FillRound.c" +#undef SDL_DRAWFUNCTION +#undef SDL_DRAW_BPP + +#define SDL_DRAW_BPP 2 +#define SDL_DRAWFUNCTION Draw_FillRound_2 +#include "Draw_FillRound.c" +#undef SDL_DRAWFUNCTION +#undef SDL_DRAW_BPP + +#define SDL_DRAW_BPP 3 +#define SDL_DRAWFUNCTION Draw_FillRound_3 +#include "Draw_FillRound.c" +#undef SDL_DRAWFUNCTION +#undef SDL_DRAW_BPP + +#define SDL_DRAW_BPP 4 +#define SDL_DRAWFUNCTION Draw_FillRound_4 +#include "Draw_FillRound.c" +#undef SDL_DRAWFUNCTION +#undef SDL_DRAW_BPP + +static +void Draw_FillRound_error(SDL_Surface *super, + Sint16 x0,Sint16 y0, Uint16 w,Uint16 h, + Uint16 corner, Uint32 color) +{ + SDL_printf("SDL_draw: Draw_FillRound ERROR!!." + " Have you call to SDL_Draw_Init()?\n"); + exit(-1); +} + +void (*Draw_FillRound)(SDL_Surface *super, + Sint16 x0,Sint16 y0, Uint16 w,Uint16 h, + Uint16 corner, Uint32 color) = Draw_FillRound_error; + +/*=================== END of Draw_FillRound ====================*/ + + +/*Assignment of function pointers:*/ +#define SDL_DRAW_FUNCTIONS_BPP(x) \ + Draw_Pixel = Draw_Pixel_##x; \ + Draw_Line = Draw_Line_##x; \ + Draw_Circle = Draw_Circle_##x; \ + Draw_FillCircle = Draw_FillCircle_##x; \ + Draw_HLine = Draw_HLine_##x; \ + Draw_VLine = Draw_VLine_##x; \ + Draw_Rect = Draw_Rect_##x; \ + Draw_Ellipse = Draw_Ellipse_##x; \ + Draw_FillEllipse = Draw_FillEllipse_##x; \ + Draw_Round = Draw_Round_##x; \ + Draw_FillRound = Draw_FillRound_##x + +/*IMPORTANT: Call this function AFTER the call to 'SDL_SetVideoMode'*/ +void Draw_Init(void) +{ + SDL_Surface *screen = SDL_GetVideoSurface(); + if (!screen) { + SDL_printf("SDL_draw: SDL_Draw_Init ERROR!!." + " Video Surface not found\n"); + exit(-2); + } + + + switch(screen->format->BytesPerPixel) { + case 1: + SDL_DRAW_FUNCTIONS_BPP(1); + break; + + case 2: + SDL_DRAW_FUNCTIONS_BPP(2); + break; + + case 3: + SDL_DRAW_FUNCTIONS_BPP(3); + break; + + case 4: + SDL_DRAW_FUNCTIONS_BPP(4); + break; + }/*switch*/ + +}/*Draw_Init*/ + +#undef SDL_DRAW_FUNCTIONS_BPP + diff --git a/contrib/sdk/sources/SDL-1.2.2/SDL_flic-1.2/Makefile b/contrib/sdk/sources/SDL-1.2.2/SDL_flic-1.2/Makefile new file mode 100644 index 000000000..d4b9f0c0c --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/SDL_flic-1.2/Makefile @@ -0,0 +1,5 @@ +CFLAGS = -DINLINE=__inline -I. -I$(MENUETDEV)/include/SDL +OUTFILE = libSDL_flic.a +OBJS = SDL_flic.o + +include $(MENUETDEV)/makefiles/Makefile_for_lib diff --git a/contrib/sdk/sources/SDL-1.2.2/SDL_flic-1.2/README.txt b/contrib/sdk/sources/SDL-1.2.2/SDL_flic-1.2/README.txt new file mode 100644 index 000000000..6afc4cd92 --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/SDL_flic-1.2/README.txt @@ -0,0 +1,31 @@ +SDL_flic version 1.2 + +http://www.geocities.com/andre_leiradella/ + +For copyright information see the source files. + +SDL_flic is a small library that renders frames of FLI and FLC animation files. + +The library has been tested with under Windows but should work on any platform. +The functions provided are: + +. int FLI_Version(void): Returns the library version in the format + MAJOR << 16 | MINOR. +. FLI_Animation *FLI_Open(SDL_RWops *rwops, int *error): Opens a FLIC animation + and returns a pointer to it. rwops is left at the same point it was before + the the call. error receives the result of the call. +. void FLI_Close(FLI_Animation *flic): Closes the animation, closes the stream + and frees all used memory. +. int FLI_NextFrame(FLI_Animation *flic): Renders the next frame of the + animation returning an int to indicate if it was successfull or not. +. int FLI_Rewind(FLI_Animation *flic): Rewinds the animation to the first + frame. +. int FLI_Skip(FLI_Animation *flic): Skips the current frame without rendering + it. + +TODO: + +. Handle other formats of FLIC animation. +. Play animation inside a thread? +. What else? Tell me: leiradella@bigfoot.com + diff --git a/contrib/sdk/sources/SDL-1.2.2/SDL_flic-1.2/SDL_flic.c b/contrib/sdk/sources/SDL-1.2.2/SDL_flic-1.2/SDL_flic.c new file mode 100644 index 000000000..255b67565 --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/SDL_flic-1.2/SDL_flic.c @@ -0,0 +1,469 @@ +/* +SDL_flic - renders FLIC animations +Copyright (C) 2003 Andre de Leiradella + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 2.1 of the License, or (at your option) any later version. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +For information about SDL_flic contact leiradella@bigfoot.com + +Version 1.0: first public release. +Version 1.1: fixed bug to set *error to FLI_OK when returning successfully from FLI_Open + added function FLI_Reset to reset the animation to the first frame +Version 1.2: added function FLI_Skip to skip the current frame without rendering + FLI_Animation->surface is now correctly locked and unlocked + the rwops stream is now part of the FLI_Animation structure and is closed inside FLI_Close + renamed FLI_Reset to FLI_Rewind + added function FLI_Version that returns the library version +*/ +#include +#include +#include +#include + +/* Library version. */ +#define FLI_MAJOR 1 +#define FLI_MINOR 2 + +/* Chunk types. */ +#define FLI_COLOR256 4 +#define FLI_SS2 7 +#define FLI_COLOR 11 +#define FLI_LC 12 +#define FLI_BLACK 13 +#define FLI_BRUN 15 +#define FLI_COPY 16 +#define FLI_PSTAMP 18 + +typedef struct { + Uint32 size, type, numchunks; +} FLI_Frame; + +typedef struct { + Uint32 size, type, index; +} FLI_Chunk; + +static INLINE void readbuffer(FLI_Animation *flic, void *buffer, int size) { + if (SDL_RWread(flic->rwops, buffer, 1, size) != size) + longjmp(flic->error, FLI_READERROR); +} + +static INLINE Uint8 readu8(FLI_Animation *flic) { + Uint8 b; + + readbuffer(flic, &b, 1); + return b; +} + +static INLINE Uint16 readu16(FLI_Animation *flic) { +#if SDL_BYTEORDER == SDL_BIG_ENDIAN + Uint16 hi, lo; + + readbuffer(flic, &lo, 1); + readbuffer(flic, &hi, 1); + return hi << 8 | lo; +#else + Uint16 w; + + readbuffer(flic, &w, 2); + return w; +#endif +} + +static INLINE Uint32 readu32(FLI_Animation *flic) { +#if SDL_BYTEORDER == SDL_BIG_ENDIAN + Uint32 hi; + + hi = readu16(flic); + return hi << 16 | readu16(flic); +#else + Uint32 u; + + readbuffer(flic, &u, 4); + return u; +#endif +} + +static void readheader(FLI_Animation *flic) { + /* Skip size, we don't need it. */ + SDL_RWseek(flic->rwops, 4, SEEK_CUR); + /* Read and check magic. */ + flic->format = readu16(flic); + if (flic->format != FLI_FLI && flic->format != FLI_FLC) + longjmp(flic->error, FLI_CORRUPTEDFILE); + /* Read number of frames, maximum is 4000 for FLI and FLC files. */ + flic->numframes = readu16(flic); + if (flic->numframes > 4000) + longjmp(flic->error, FLI_CORRUPTEDFILE); + /* Read width and height, must be 320x200 for FLI files. */ + flic->width = readu16(flic); + flic->height = readu16(flic); + if (flic->format == FLI_FLI && (flic->width != 320 || flic->height != 200)) + longjmp(flic->error, FLI_CORRUPTEDFILE); + /* Read color depth, must be 8 for FLI and FLC files. */ + flic->depth = readu16(flic); + if (flic->depth != 8) + longjmp(flic->error, FLI_CORRUPTEDFILE); + /* Skip the flags, it doesn't look like it follows the specs. */ + readu16(flic); + /* Read the delay between frames. */ + flic->delay = (flic->format == FLI_FLI) ? readu16(flic) : readu32(flic); + /* Skip rest of the header. */ + SDL_RWseek(flic->rwops, (flic->format == FLI_FLI) ? 110 : 108, SEEK_CUR); +} + +static INLINE void readframe(FLI_Animation *flic, FLI_Frame *frame) { + /* Read the size of the frame, must be less than or equal to 64k in FLI files. */ + frame->size = readu32(flic); + if (flic->format == FLI_FLI && frame->size > 65536) + longjmp(flic->error, FLI_CORRUPTEDFILE); + /* Read the type of the frame, must be 0xF1FA in FLI files or 0xF1FA or 0xF100 in FLC files. */ + frame->type = readu16(flic); + if (frame->type != 0xF1FA && (flic->format == FLI_FLC && frame->type != 0xF100)) + longjmp(flic->error, FLI_CORRUPTEDFILE); + /* Read the number of chunks in this frame. */ + frame->numchunks = readu16(flic); + /* Skip rest of the data. */ + SDL_RWseek(flic->rwops, 8, SEEK_CUR); +} + +static INLINE void readchunk(FLI_Animation *flic, FLI_Chunk *chunk) { + /* Read the chunk size. */ + chunk->size = readu32(flic); + /* Read the chunk type. */ + chunk->type = readu16(flic); +} + +static void handlecolor(FLI_Animation *flic, FLI_Chunk *chunk) { + int numpackets, index, count; + SDL_Color color; + + (void)chunk; + /* Number of packets. */ + numpackets = readu16(flic); + /* Color index that will be changed. */ + index = 0; + while (numpackets-- > 0) { + /* Skip some colors. */ + index += readu8(flic); + /* And change some others. */ + count = readu8(flic); + if (count == 0) + count = 256; + while (count-- > 0) { + /* r, g and b are in the range [0..63]. */ + color.r = ((Uint32)readu8(flic)) * 255 / 63; + color.g = ((Uint32)readu8(flic)) * 255 / 63; + color.b = ((Uint32)readu8(flic)) * 255 / 63; + SDL_SetColors(flic->surface, &color, index++, 1); + } + } +} + +static void handlelc(FLI_Animation *flic, FLI_Chunk *chunk) { + int numlines, numpackets, size; + Uint8 *line, *p; + + (void)chunk; + /* Skip lines at the top of the image. */ + line = (Uint8 *)flic->surface->pixels + readu16(flic) * flic->surface->pitch; + /* numlines lines will change. */ + numlines = readu16(flic); + while (numlines-- > 0) { + p = line; + line += flic->surface->pitch; + /* Each line has numpackets changes. */ + numpackets = readu8(flic); + while (numpackets-- > 0) { + /* Skip pixels at the beginning of the line. */ + p += readu8(flic); + /* size pixels will change. */ + size = (Sint8)readu8(flic); + if (size >= 0) { + /* Pixels follow. */ + readbuffer(flic, (void *)p, size); + } else { + size = -size; + /* One pixel to be repeated follow. */ + memset((void *)p, readu8(flic), size); + } + p += size; + } + } +} + +static void handleblack(FLI_Animation *flic, FLI_Chunk *chunk) { + (void)chunk; + /* Fill the surface with color 0. */ + if (SDL_FillRect(flic->surface, NULL, 0) != 0) + longjmp(flic->error, FLI_SDLERROR); +} + +static void handlebrun(FLI_Animation *flic, FLI_Chunk *chunk) { + int numlines, size; + Uint8 *p, *next; + + (void)chunk; + /* Begin at the top of the image. */ + p = (Uint8 *)flic->surface->pixels; + /* All lines will change. */ + numlines = flic->height; + while (numlines-- > 0) { + /* The number of packages is ignored, packets run until the next line is reached. */ + readu8(flic); + next = p + flic->surface->pitch; + while (p < next) { + /* size pixels will change. */ + size = (Sint8)readu8(flic); + if (size < 0) { + size = -size; + /* Pixels follow. */ + readbuffer(flic, (void *)p, size); + } else { + /* One pixel to be repeated follow. */ + memset((void *)p, readu8(flic), size); + } + p += size; + } + } +} + +static void handlecopy(FLI_Animation *flic, FLI_Chunk *chunk) { + (void)chunk; + /* Read the entire image from the stream. */ + readbuffer(flic, (void *)flic->surface->pixels, flic->width * flic->height); +} + +static void handlecolor256(FLI_Animation *flic, FLI_Chunk *chunk) { + int numpackets, index, count; + SDL_Color color; + + (void)chunk; + if (flic->format == FLI_FLI) + longjmp(flic->error, FLI_CORRUPTEDFILE); + /* Number of packets. */ + numpackets = readu16(flic); + /* Color index that will be changed. */ + index = 0; + while (numpackets-- > 0) { + /* Skip some colors. */ + index += readu8(flic); + /* And change some others. */ + count = readu8(flic); + if (count == 0) + count = 256; + while (count-- > 0) { + /* r, g and b are in the range [0..255]. */ + color.r = readu8(flic); + color.g = readu8(flic); + color.b = readu8(flic); + SDL_SetColors(flic->surface, &color, index++, 1); + } + } +} + +static void handless2(FLI_Animation *flic, FLI_Chunk *chunk) { + int numlines, y, code, size; + Uint8 *p, c; + + (void)chunk; + if (flic->format == FLI_FLI) + longjmp(flic->error, FLI_CORRUPTEDFILE); + /* numlines lines will change. */ + numlines = readu16(flic); + y = 0; + while (numlines > 0) { + /* Read the code. */ + code = readu16(flic); + switch ((code >> 14) & 0x03) { + case 0x00: + p = (Uint8 *)flic->surface->pixels + flic->surface->pitch * y; + while (code-- > 0) { + /* Skip some pixels. */ + p += readu8(flic); + size = ((Sint8)readu8(flic)) * 2; + if (size >= 0) { + /* Pixels follow. */ + readbuffer(flic, (void *)p, size); + } else { + size = -size; + readu8(flic); + /* One pixel to be repeated follow. */ + memset((void *)p, readu8(flic), size); + } + p += size; + } + y++; + numlines--; + break; + case 0x01: + longjmp(flic->error, FLI_CORRUPTEDFILE); + case 0x02: + /* Last pixel of the line. */ + p = (Uint8 *)flic->surface->pixels + flic->surface->pitch * (y + 1); + p[-1] = code & 0xFF; + break; + case 0x03: + /* Skip some lines. */ + y += (code ^ 0xFFFF) + 1; + break; + } + } +} + +int FLI_Version(void) { + return FLI_MAJOR << 16 | FLI_MINOR; +} + +FLI_Animation *FLI_Open(SDL_RWops *rwops, int *error) { + FLI_Animation *flic; + FLI_Frame frame; + int err; + + /* Alloc animation. */ + flic = (FLI_Animation *)malloc(sizeof(FLI_Animation)); + if (flic == NULL) { + if (error != NULL) *error = FLI_OUTOFMEMORY; + return NULL; + } + flic->rwops = rwops; + flic->surface = NULL; + /* Error handling. */ + err = setjmp(flic->error); + if (err != 0) { + if (error != NULL) *error = err; + FLI_Close(flic); + return NULL; + } + /* Read the header. */ + readheader(flic); + /* Create a buffer to hold the rendered frame. */ + flic->surface = SDL_CreateRGBSurface(SDL_SWSURFACE, flic->width, flic->height, 8, 0, 0, 0, 0); + if (flic->surface == NULL) + longjmp(flic->error, FLI_SDLERROR); + /* Read the first frame. */ + flic->offframe1 = SDL_RWtell(rwops); + readframe(flic, &frame); + /* If it's a prefix frame, skip it. */ + if (frame.type == 0xF100) { + SDL_RWseek(rwops, frame.size - 16, SEEK_CUR); + flic->offframe1 = SDL_RWtell(rwops); + flic->numframes--; + } + flic->offnextframe = flic->offframe1; + flic->nextframe = 1; + if (error != NULL) *error = FLI_OK; + return flic; +} + +void FLI_Close(FLI_Animation *flic) { + if (flic != NULL) { + if (flic->rwops != NULL) + SDL_RWclose(flic->rwops); + if (flic->surface != NULL) + SDL_FreeSurface(flic->surface); + free(flic); + } +} + +int FLI_NextFrame(FLI_Animation *flic) { + FLI_Frame frame; + FLI_Chunk chunk; + int error, locked; + Uint32 i; + + /* Flag to tell if the surface is locked. */ + locked = 0; + /* Error handling. */ + error = setjmp(flic->error); + if (error != 0) { + if (locked) + SDL_UnlockSurface(flic->surface); + return error; + } + /* Seek to the current frame. */ + SDL_RWseek(flic->rwops, flic->offnextframe, SEEK_SET); + /* Read the current frame. */ + readframe(flic, &frame); + /* Read and process each of the chunks of this frame. */ + SDL_LockSurface(flic->surface); + locked = 1; + (void)locked; + for (i = frame.numchunks; i != 0; i--) { + readchunk(flic, &chunk); + switch (chunk.type) { + case FLI_COLOR: + handlecolor(flic, &chunk); + break; + case FLI_LC: + handlelc(flic, &chunk); + break; + case FLI_BLACK: + handleblack(flic, &chunk); + break; + case FLI_BRUN: + handlebrun(flic, &chunk); + break; + case FLI_COPY: + handlecopy(flic, &chunk); + break; + case FLI_COLOR256: + handlecolor256(flic, &chunk); + break; + case FLI_SS2: + handless2(flic, &chunk); + break; + case FLI_PSTAMP: + /* Ignore this chunk. */ + break; + default: + longjmp(flic->error, FLI_CORRUPTEDFILE); + } + } + SDL_UnlockSurface(flic->surface); + /* Setup the number and position of next frame. If it wraps, go to the first one. */ + if (++flic->nextframe > flic->numframes) { + flic->offnextframe = flic->offframe1; + flic->nextframe = 1; + } else + flic->offnextframe += frame.size; + return FLI_OK; +} + +int FLI_Rewind(FLI_Animation *flic) { + flic->offnextframe = flic->offframe1; + flic->nextframe = 1; + return FLI_OK; +} + +int FLI_Skip(FLI_Animation *flic) { + FLI_Frame frame; + int error; + + /* Error handling. */ + error = setjmp(flic->error); + if (error != 0) + return error; + /* Seek to the current frame. */ + SDL_RWseek(flic->rwops, flic->offnextframe, SEEK_SET); + /* Read the current frame. */ + readframe(flic, &frame); + /* Skip to the next frame without rendering. */ + if (++flic->nextframe > flic->numframes) { + flic->offnextframe = flic->offframe1; + flic->nextframe = 1; + } else + flic->offnextframe += frame.size; + return FLI_OK; +} diff --git a/contrib/sdk/sources/SDL-1.2.2/SDL_flic-1.2/SDL_flic.h b/contrib/sdk/sources/SDL-1.2.2/SDL_flic-1.2/SDL_flic.h new file mode 100644 index 000000000..713a4b014 --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/SDL_flic-1.2/SDL_flic.h @@ -0,0 +1,102 @@ +/* +SDL_flic - renders FLIC animations +Copyright (C) 2003 Andre de Leiradella + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 2.1 of the License, or (at your option) any later version. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +For information about SDL_flic contact leiradella@bigfoot.com + +Version 1.0: first public release. +Version 1.1: fixed bug to set *error to FLI_OK when returning successfully from FLI_Open + added function FLI_Reset to reset the animation to the first frame +Version 1.2: added function FLI_Skip to skip the current frame without rendering + FLI_Animation->surface is now correctly locked and unlocked + the rwops stream is now part of the FLI_Animation structure and is closed inside FLI_Close + renamed FLI_Reset to FLI_Rewind + added function FLI_Version that returns the library version +*/ +#ifndef __SDL_flic_h__ +#define __SDL_flic_h__ + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* Supported formats. */ +#define FLI_FLI 0xAF11 +#define FLI_FLC 0xAF12 + +/* Error codes. */ + +/* No error. */ +#define FLI_OK 0 +/* Error reading the file. */ +#define FLI_READERROR 1 +/* Invalid frame size (corrupted file). */ +#define FLI_CORRUPTEDFILE 2 +/* Error in SDL operation. */ +#define FLI_SDLERROR 3 +/* Out of memory. */ +#define FLI_OUTOFMEMORY 4 + +/* +The animation structure, all members are read-only, don't try to longjmp to +error. +*/ +typedef struct { + Uint32 format, numframes, width, height, depth, delay, offframe1, nextframe, offnextframe; + /* rwops is where the animation is read from. */ + SDL_RWops *rwops; + /* surface is where the frames is rendered to. */ + SDL_Surface *surface; + /* error is used to longjmp in case of error so to avoid a chain of if's. */ + jmp_buf error; +} FLI_Animation; + +/* +Returns the library version in the format MAJOR << 16 | MINOR. +*/ +extern int FLI_Version(void); +/* +Opens a FLIC animation and return a pointer to it. rwops is left at the same +point it was before the the call. error receives the result of the call. +*/ +extern FLI_Animation *FLI_Open(SDL_RWops *rwops, int *error); +/* +Closes the animation, closes the stream and frees all used memory. +*/ +extern void FLI_Close(FLI_Animation *flic); +/* +Renders the next frame of the animation returning an int to indicate if it was +successfull or not. +*/ +extern int FLI_NextFrame(FLI_Animation *flic); +/* +Rewinds the animation to the first frame. +*/ +extern int FLI_Rewind(FLI_Animation *flic); +/* +Skips the current frame of the animation without rendering it. +*/ +extern int FLI_Skip(FLI_Animation *flic); + +#ifdef __cplusplus +}; +#endif + +#endif diff --git a/contrib/sdk/sources/SDL-1.2.2/SDL_flic-1.2/playflic.c b/contrib/sdk/sources/SDL-1.2.2/SDL_flic-1.2/playflic.c new file mode 100644 index 000000000..3ec8cd817 --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/SDL_flic-1.2/playflic.c @@ -0,0 +1,92 @@ +/* +playflic - play a FLIC file on the screen +Placed in the public domain by Andre de Leiradella on 24-fev-2003. + +You'll need SDL and SDLmain to compile this program. +*/ + +#include +#include +#include +#include +#include "SDL_flic.h" + +int main(int argc, char *argv[]) { + SDL_RWops *rwops; + FLI_Animation *flic; + int error; + SDL_Surface *screen; + SDL_Rect pos; + SDL_Event event; + Uint32 ticks, ticks2; + + if (argc != 2) { + fprintf(stderr, "Usage: playflic \n"); + return 0; + } + /* Open the flic. */ + rwops = SDL_RWFromFile(argv[1], "rb"); + if (rwops == NULL) { + fprintf(stderr, "FLIC file not found\n"); + return 0; + } + flic = FLI_Open(rwops, &error); + if (error != FLI_OK) + goto out; + /* Init SDL. */ + if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_NOPARACHUTE) < 0) { + fprintf(stderr, "Couldn't initialize SDL: %s\n", SDL_GetError()); + goto out; + } + atexit(SDL_Quit); + /* Set the video with the size of the flic. */ + screen = SDL_SetVideoMode(flic->width, flic->height, 0, SDL_SWSURFACE); + if (screen == NULL) { + fprintf(stderr, "Couldn't set %dx%d video mode: %s\n", flic->width, flic->height, SDL_GetError()); + goto out; + } + /* Play the flic. */ + pos.x = pos.y = 0; + ticks = SDL_GetTicks(); + for (;;) { + /* Render the next frame. */ + error = FLI_NextFrame(flic); + if (error != FLI_OK) + goto out; + /* Blit it. */ + SDL_BlitSurface(flic->surface, NULL, screen, &pos); + SDL_UpdateRect(screen, 0, 0, 0, 0); + /* Exit program in case of any event. */ + while (SDL_PollEvent(&event) == 1) { + switch (event.type) { + case SDL_MOUSEBUTTONDOWN: + case SDL_KEYDOWN: + case SDL_QUIT: + goto out; + } + } + /* Delay between frames. */ + ticks = SDL_GetTicks() - ticks; + if (ticks < flic->delay) + SDL_Delay(flic->delay - ticks); + ticks = SDL_GetTicks(); + } + out: + /* Describe the error. */ + switch (error) { + case FLI_READERROR: + fprintf(stderr, "Error while reading FLIC\n"); + break; + case FLI_CORRUPTEDFILE: + fprintf(stderr, "FLIC file corrupted\n"); + break; + case FLI_SDLERROR: + fprintf(stderr, "SDL error: %s\n", SDL_GetError()); + break; + case FLI_OUTOFMEMORY: + fprintf(stderr, "Out of memory\n"); + break; + } + FLI_Close(flic); + return 0; +} diff --git a/contrib/sdk/sources/SDL-1.2.2/SDL_flic-1.2/sample.flc b/contrib/sdk/sources/SDL-1.2.2/SDL_flic-1.2/sample.flc new file mode 100644 index 000000000..96bfa2e23 Binary files /dev/null and b/contrib/sdk/sources/SDL-1.2.2/SDL_flic-1.2/sample.flc differ diff --git a/contrib/sdk/sources/SDL-1.2.2/SDL_image/IMG.c b/contrib/sdk/sources/SDL-1.2.2/SDL_image/IMG.c new file mode 100644 index 000000000..45309f131 --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/SDL_image/IMG.c @@ -0,0 +1,134 @@ +/* + IMGLIB: An example image loading library for use with SDL + Copyright (C) 1999 Sam Lantinga + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the Free + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + Sam Lantinga + 5635-34 Springhouse Dr. + Pleasanton, CA 94588 (USA) + slouken@devolution.com +*/ + +/* A simple library to load images of various formats as SDL surfaces */ + +#include +#include +#include + +#include "SDL_image.h" + +#define ARRAYSIZE(a) (sizeof(a) / sizeof((a)[0])) + +/* Table of image detection and loading functions */ +static struct { + char *type; + int (*is)(SDL_RWops *src); + SDL_Surface *(*load)(SDL_RWops *src); +} supported[] = { + /* keep magicless formats first */ + { "TGA", 0, IMG_LoadTGA_RW }, + { "BMP", IMG_isBMP, IMG_LoadBMP_RW }, + { "PNM", IMG_isPNM, IMG_LoadPNM_RW }, /* P[BGP]M share code */ + { "XPM", IMG_isXPM, IMG_LoadXPM_RW }, + { "XCF", IMG_isXCF, IMG_LoadXCF_RW }, + { "PCX", IMG_isPCX, IMG_LoadPCX_RW }, + { "GIF", IMG_isGIF, IMG_LoadGIF_RW }, + { "JPG", IMG_isJPG, IMG_LoadJPG_RW }, + { "TIF", IMG_isTIF, IMG_LoadTIF_RW }, + { "PNG", IMG_isPNG, IMG_LoadPNG_RW } +}; + +/* Load an image from a file */ +SDL_Surface *IMG_Load(const char *file) +{ + SDL_RWops *src = SDL_RWFromFile(file, "rb"); + char *ext = strrchr(file, '.'); + if(ext) + ext++; + return IMG_LoadTyped_RW(src, 1, ext); +} + +/* Load an image from an SDL datasource (for compatibility) */ +SDL_Surface *IMG_Load_RW(SDL_RWops *src, int freesrc) +{ + return IMG_LoadTyped_RW(src, freesrc, NULL); +} + +/* Portable case-insensitive string compare function */ +int IMG_string_equals(const char *str1, const char *str2) +{ + while ( *str1 && *str2 ) { + if ( toupper((unsigned char)*str1) != + toupper((unsigned char)*str2) ) + break; + ++str1; + ++str2; + } + return (!*str1 && !*str2); +} + +/* Load an image from an SDL datasource, optionally specifying the type */ +SDL_Surface *IMG_LoadTyped_RW(SDL_RWops *src, int freesrc, char *type) +{ + int i, start; + SDL_Surface *image; + + /* Make sure there is something to do.. */ + if ( src == NULL ) { + return(NULL); + } + + /* See whether or not this data source can handle seeking */ + if ( SDL_RWseek(src, 0, SEEK_CUR) < 0 ) { + IMG_SetError("Can't seek in this data source"); + return(NULL); + } + + /* Detect the type of image being loaded */ + start = SDL_RWtell(src); + image = NULL; + for ( i=0; i < ARRAYSIZE(supported); ++i ) { + if( (supported[i].is + && (SDL_RWseek(src, start, SEEK_SET), + supported[i].is(src))) + || (type && IMG_string_equals(type, supported[i].type))) { +#ifdef DEBUG_IMGLIB + SDL_printf("IMGLIB: Loading image as %s\n", + supported[i].type); +#endif + SDL_RWseek(src, start, SEEK_SET); + image = supported[i].load(src); + break; + } + } + + /* Clean up, check for errors, and return */ + if ( freesrc ) { + SDL_RWclose(src); + } + if ( i == ARRAYSIZE(supported) ) { + IMG_SetError("Unsupported image format"); + } + return(image); +} + +/* Invert the alpha of a surface for use with OpenGL + This function is a no-op and only kept for backwards compatibility. + */ +int IMG_InvertAlpha(int on) +{ + return 1; +} diff --git a/contrib/sdk/sources/SDL-1.2.2/SDL_image/IMG_bmp.c b/contrib/sdk/sources/SDL-1.2.2/SDL_image/IMG_bmp.c new file mode 100644 index 000000000..87f4e0cb8 --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/SDL_image/IMG_bmp.c @@ -0,0 +1,69 @@ +/* + IMGLIB: An example image loading library for use with SDL + Copyright (C) 1999 Sam Lantinga + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the Free + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + Sam Lantinga + 5635-34 Springhouse Dr. + Pleasanton, CA 94588 (USA) + slouken@devolution.com +*/ + +/* This is a BMP image file loading framework */ + +#include +#include + +#include "SDL_image.h" + +#ifdef LOAD_BMP + +/* See if an image is contained in a data source */ +int IMG_isBMP(SDL_RWops *src) +{ + int is_BMP; + char magic[2]; + + is_BMP = 0; + if ( SDL_RWread(src, magic, 2, 1) ) { + if ( strncmp(magic, "BM", 2) == 0 ) { + is_BMP = 1; + } + } + return(is_BMP); +} + +/* Load a BMP type image from an SDL datasource */ +SDL_Surface *IMG_LoadBMP_RW(SDL_RWops *src) +{ + return(SDL_LoadBMP_RW(src, 0)); +} + +#else + +/* See if an image is contained in a data source */ +int IMG_isBMP(SDL_RWops *src) +{ + return(0); +} + +/* Load a BMP type image from an SDL datasource */ +SDL_Surface *IMG_LoadBMP_RW(SDL_RWops *src) +{ + return(NULL); +} + +#endif /* LOAD_BMP */ diff --git a/contrib/sdk/sources/SDL-1.2.2/SDL_image/IMG_gif.c b/contrib/sdk/sources/SDL-1.2.2/SDL_image/IMG_gif.c new file mode 100644 index 000000000..4503dfb4e --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/SDL_image/IMG_gif.c @@ -0,0 +1,604 @@ +/* + IMGLIB: An example image loading library for use with SDL + Copyright (C) 1999 Sam Lantinga + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the Free + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + Sam Lantinga + 5635-34 Springhouse Dr. + Pleasanton, CA 94588 (USA) + slouken@devolution.com +*/ + +/* This is a GIF image file loading framework */ + +#include +#include + +#include "SDL_image.h" + +#ifdef LOAD_GIF + +/* See if an image is contained in a data source */ +int IMG_isGIF(SDL_RWops *src) +{ + int is_GIF; + char magic[6]; + + is_GIF = 0; + if ( SDL_RWread(src, magic, 6, 1) ) { + if ( (strncmp(magic, "GIF", 3) == 0) && + ((memcmp(magic + 3, "87a", 3) == 0) || + (memcmp(magic + 3, "89a", 3) == 0)) ) { + is_GIF = 1; + } + } + return(is_GIF); +} + +/* Code from here to end of file has been adapted from XPaint: */ +/* +-------------------------------------------------------------------+ */ +/* | Copyright 1990, 1991, 1993 David Koblas. | */ +/* | Copyright 1996 Torsten Martinsen. | */ +/* | Permission to use, copy, modify, and distribute this software | */ +/* | and its documentation for any purpose and without fee is hereby | */ +/* | granted, provided that the above copyright notice appear in all | */ +/* | copies and that both that copyright notice and this permission | */ +/* | notice appear in supporting documentation. This software is | */ +/* | provided "as is" without express or implied warranty. | */ +/* +-------------------------------------------------------------------+ */ + +/* Adapted for use in SDL by Sam Lantinga -- 7/20/98 */ +#define USED_BY_SDL + +#include +#include + +#ifdef USED_BY_SDL +/* Changes to work with SDL: + + Include SDL header file + Use SDL_Surface rather than xpaint Image structure + Define SDL versions of RWSetMsg(), ImageNewCmap() and ImageSetCmap() +*/ +#include "SDL.h" + +#define Image SDL_Surface +#define RWSetMsg IMG_SetError +#define ImageNewCmap(w, h, s) SDL_AllocSurface(SDL_SWSURFACE,w,h,8,0,0,0,0) +#define ImageSetCmap(s, i, R, G, B) do { \ + s->format->palette->colors[i].r = R; \ + s->format->palette->colors[i].g = G; \ + s->format->palette->colors[i].b = B; \ + } while (0) +/* * * * * */ + +#else + +/* Original XPaint sources */ + +#include "image.h" +#include "rwTable.h" + +#define SDL_RWops FILE +#define SDL_RWclose fclose + +#endif /* USED_BY_SDL */ + + +#define MAXCOLORMAPSIZE 256 + +#define TRUE 1 +#define FALSE 0 + +#define CM_RED 0 +#define CM_GREEN 1 +#define CM_BLUE 2 + +#define MAX_LWZ_BITS 12 + +#define INTERLACE 0x40 +#define LOCALCOLORMAP 0x80 +#define BitSet(byte, bit) (((byte) & (bit)) == (bit)) + +#define ReadOK(file,buffer,len) SDL_RWread(file, buffer, len, 1) + +#define LM_to_uint(a,b) (((b)<<8)|(a)) + +static struct { + unsigned int Width; + unsigned int Height; + unsigned char ColorMap[3][MAXCOLORMAPSIZE]; + unsigned int BitPixel; + unsigned int ColorResolution; + unsigned int Background; + unsigned int AspectRatio; + int GrayScale; +} GifScreen; + +static struct { + int transparent; + int delayTime; + int inputFlag; + int disposal; +} Gif89; + +static int ReadColorMap(SDL_RWops * src, int number, + unsigned char buffer[3][MAXCOLORMAPSIZE], int *flag); +static int DoExtension(SDL_RWops * src, int label); +static int GetDataBlock(SDL_RWops * src, unsigned char *buf); +static int GetCode(SDL_RWops * src, int code_size, int flag); +static int LWZReadByte(SDL_RWops * src, int flag, int input_code_size); +static Image *ReadImage(SDL_RWops * src, int len, int height, int, + unsigned char cmap[3][MAXCOLORMAPSIZE], + int gray, int interlace, int ignore); + +Image * +IMG_LoadGIF_RW(SDL_RWops *src) +{ + unsigned char buf[16]; + unsigned char c; + unsigned char localColorMap[3][MAXCOLORMAPSIZE]; + int grayScale; + int useGlobalColormap; + int bitPixel; + int imageCount = 0; + char version[4]; + int imageNumber = 1; + Image *image = NULL; + + if ( src == NULL ) { + goto done; + } + if (!ReadOK(src, buf, 6)) { + RWSetMsg("error reading magic number"); + goto done; + } + if (strncmp((char *) buf, "GIF", 3) != 0) { + RWSetMsg("not a GIF file"); + goto done; + } + strncpy(version, (char *) buf + 3, 3); + version[3] = '\0'; + + if ((strcmp(version, "87a") != 0) && (strcmp(version, "89a") != 0)) { + RWSetMsg("bad version number, not '87a' or '89a'"); + goto done; + } + Gif89.transparent = -1; + Gif89.delayTime = -1; + Gif89.inputFlag = -1; + Gif89.disposal = 0; + + if (!ReadOK(src, buf, 7)) { + RWSetMsg("failed to read screen descriptor"); + goto done; + } + GifScreen.Width = LM_to_uint(buf[0], buf[1]); + GifScreen.Height = LM_to_uint(buf[2], buf[3]); + GifScreen.BitPixel = 2 << (buf[4] & 0x07); + GifScreen.ColorResolution = (((buf[4] & 0x70) >> 3) + 1); + GifScreen.Background = buf[5]; + GifScreen.AspectRatio = buf[6]; + + if (BitSet(buf[4], LOCALCOLORMAP)) { /* Global Colormap */ + if (ReadColorMap(src, GifScreen.BitPixel, GifScreen.ColorMap, + &GifScreen.GrayScale)) { + RWSetMsg("error reading global colormap"); + goto done; + } + } + do { + if (!ReadOK(src, &c, 1)) { + RWSetMsg("EOF / read error on image data"); + goto done; + } + if (c == ';') { /* GIF terminator */ + if (imageCount < imageNumber) { + RWSetMsg("only %d image%s found in file", + imageCount, imageCount > 1 ? "s" : ""); + goto done; + } + } + if (c == '!') { /* Extension */ + if (!ReadOK(src, &c, 1)) { + RWSetMsg("EOF / read error on extention function code"); + goto done; + } + DoExtension(src, c); + continue; + } + if (c != ',') { /* Not a valid start character */ + continue; + } + ++imageCount; + + if (!ReadOK(src, buf, 9)) { + RWSetMsg("couldn't read left/top/width/height"); + goto done; + } + useGlobalColormap = !BitSet(buf[8], LOCALCOLORMAP); + + bitPixel = 1 << ((buf[8] & 0x07) + 1); + + if (!useGlobalColormap) { + if (ReadColorMap(src, bitPixel, localColorMap, &grayScale)) { + RWSetMsg("error reading local colormap"); + goto done; + } + image = ReadImage(src, LM_to_uint(buf[4], buf[5]), + LM_to_uint(buf[6], buf[7]), + bitPixel, localColorMap, grayScale, + BitSet(buf[8], INTERLACE), + imageCount != imageNumber); + } else { + image = ReadImage(src, LM_to_uint(buf[4], buf[5]), + LM_to_uint(buf[6], buf[7]), + GifScreen.BitPixel, GifScreen.ColorMap, + GifScreen.GrayScale, BitSet(buf[8], INTERLACE), + imageCount != imageNumber); + } + } while (image == NULL); + +#ifdef USED_BY_SDL + if ( Gif89.transparent > 0 ) { + SDL_SetColorKey(image, SDL_SRCCOLORKEY, Gif89.transparent); + } +#endif + +done: + return image; +} + +static int +ReadColorMap(SDL_RWops *src, int number, + unsigned char buffer[3][MAXCOLORMAPSIZE], int *gray) +{ + int i; + unsigned char rgb[3]; + int flag; + + flag = TRUE; + + for (i = 0; i < number; ++i) { + if (!ReadOK(src, rgb, sizeof(rgb))) { + RWSetMsg("bad colormap"); + return 1; + } + buffer[CM_RED][i] = rgb[0]; + buffer[CM_GREEN][i] = rgb[1]; + buffer[CM_BLUE][i] = rgb[2]; + flag &= (rgb[0] == rgb[1] && rgb[1] == rgb[2]); + } + +#if 0 + if (flag) + *gray = (number == 2) ? PBM_TYPE : PGM_TYPE; + else + *gray = PPM_TYPE; +#else + *gray = 0; +#endif + + return FALSE; +} + +static int +DoExtension(SDL_RWops *src, int label) +{ + static unsigned char buf[256]; + char *str; + + switch (label) { + case 0x01: /* Plain Text Extension */ + str = "Plain Text Extension"; + break; + case 0xff: /* Application Extension */ + str = "Application Extension"; + break; + case 0xfe: /* Comment Extension */ + str = "Comment Extension"; + while (GetDataBlock(src, (unsigned char *) buf) != 0); + return FALSE; + case 0xf9: /* Graphic Control Extension */ + str = "Graphic Control Extension"; + (void) GetDataBlock(src, (unsigned char *) buf); + Gif89.disposal = (buf[0] >> 2) & 0x7; + Gif89.inputFlag = (buf[0] >> 1) & 0x1; + Gif89.delayTime = LM_to_uint(buf[1], buf[2]); + if ((buf[0] & 0x1) != 0) + Gif89.transparent = buf[3]; + + while (GetDataBlock(src, (unsigned char *) buf) != 0); + return FALSE; + default: + str = (char *)buf; + sprintf(str, "UNKNOWN (0x%02x)", label); + break; + } + + while (GetDataBlock(src, (unsigned char *) buf) != 0); + + return FALSE; +} + +static int ZeroDataBlock = FALSE; + +static int +GetDataBlock(SDL_RWops *src, unsigned char *buf) +{ + unsigned char count; + + if (!ReadOK(src, &count, 1)) { + /* pm_message("error in getting DataBlock size" ); */ + return -1; + } + ZeroDataBlock = count == 0; + + if ((count != 0) && (!ReadOK(src, buf, count))) { + /* pm_message("error in reading DataBlock" ); */ + return -1; + } + return count; +} + +static int +GetCode(SDL_RWops *src, int code_size, int flag) +{ + static unsigned char buf[280]; + static int curbit, lastbit, done, last_byte; + int i, j, ret; + unsigned char count; + + if (flag) { + curbit = 0; + lastbit = 0; + done = FALSE; + return 0; + } + if ((curbit + code_size) >= lastbit) { + if (done) { + if (curbit >= lastbit) + RWSetMsg("ran off the end of my bits"); + return -1; + } + buf[0] = buf[last_byte - 2]; + buf[1] = buf[last_byte - 1]; + + if ((count = GetDataBlock(src, &buf[2])) == 0) + done = TRUE; + + last_byte = 2 + count; + curbit = (curbit - lastbit) + 16; + lastbit = (2 + count) * 8; + } + ret = 0; + for (i = curbit, j = 0; j < code_size; ++i, ++j) + ret |= ((buf[i / 8] & (1 << (i % 8))) != 0) << j; + + curbit += code_size; + + return ret; +} + +static int +LWZReadByte(SDL_RWops *src, int flag, int input_code_size) +{ + static int fresh = FALSE; + int code, incode; + static int code_size, set_code_size; + static int max_code, max_code_size; + static int firstcode, oldcode; + static int clear_code, end_code; + static int table[2][(1 << MAX_LWZ_BITS)]; + static int stack[(1 << (MAX_LWZ_BITS)) * 2], *sp; + register int i; + + if (flag) { + set_code_size = input_code_size; + code_size = set_code_size + 1; + clear_code = 1 << set_code_size; + end_code = clear_code + 1; + max_code_size = 2 * clear_code; + max_code = clear_code + 2; + + GetCode(src, 0, TRUE); + + fresh = TRUE; + + for (i = 0; i < clear_code; ++i) { + table[0][i] = 0; + table[1][i] = i; + } + for (; i < (1 << MAX_LWZ_BITS); ++i) + table[0][i] = table[1][0] = 0; + + sp = stack; + + return 0; + } else if (fresh) { + fresh = FALSE; + do { + firstcode = oldcode = GetCode(src, code_size, FALSE); + } while (firstcode == clear_code); + return firstcode; + } + if (sp > stack) + return *--sp; + + while ((code = GetCode(src, code_size, FALSE)) >= 0) { + if (code == clear_code) { + for (i = 0; i < clear_code; ++i) { + table[0][i] = 0; + table[1][i] = i; + } + for (; i < (1 << MAX_LWZ_BITS); ++i) + table[0][i] = table[1][i] = 0; + code_size = set_code_size + 1; + max_code_size = 2 * clear_code; + max_code = clear_code + 2; + sp = stack; + firstcode = oldcode = GetCode(src, code_size, FALSE); + return firstcode; + } else if (code == end_code) { + int count; + unsigned char buf[260]; + + if (ZeroDataBlock) + return -2; + + while ((count = GetDataBlock(src, buf)) > 0); + + if (count != 0) { + /* + * pm_message("missing EOD in data stream (common occurence)"); + */ + } + return -2; + } + incode = code; + + if (code >= max_code) { + *sp++ = firstcode; + code = oldcode; + } + while (code >= clear_code) { + *sp++ = table[1][code]; + if (code == table[0][code]) + RWSetMsg("circular table entry BIG ERROR"); + code = table[0][code]; + } + + *sp++ = firstcode = table[1][code]; + + if ((code = max_code) < (1 << MAX_LWZ_BITS)) { + table[0][code] = oldcode; + table[1][code] = firstcode; + ++max_code; + if ((max_code >= max_code_size) && + (max_code_size < (1 << MAX_LWZ_BITS))) { + max_code_size *= 2; + ++code_size; + } + } + oldcode = incode; + + if (sp > stack) + return *--sp; + } + return code; +} + +static Image * +ReadImage(SDL_RWops * src, int len, int height, int cmapSize, + unsigned char cmap[3][MAXCOLORMAPSIZE], + int gray, int interlace, int ignore) +{ + Image *image; + unsigned char c; + int i, v; + int xpos = 0, ypos = 0, pass = 0; + + /* + ** Initialize the compression routines + */ + if (!ReadOK(src, &c, 1)) { + RWSetMsg("EOF / read error on image data"); + return NULL; + } + if (LWZReadByte(src, TRUE, c) < 0) { + RWSetMsg("error reading image"); + return NULL; + } + /* + ** If this is an "uninteresting picture" ignore it. + */ + if (ignore) { + while (LWZReadByte(src, FALSE, c) >= 0); + return NULL; + } + image = ImageNewCmap(len, height, cmapSize); + + for (i = 0; i < cmapSize; i++) + ImageSetCmap(image, i, cmap[CM_RED][i], + cmap[CM_GREEN][i], cmap[CM_BLUE][i]); + + while ((v = LWZReadByte(src, FALSE, c)) >= 0) { +#ifdef USED_BY_SDL + ((Uint8 *)image->pixels)[xpos + ypos * image->pitch] = v; +#else + image->data[xpos + ypos * len] = v; +#endif + ++xpos; + if (xpos == len) { + xpos = 0; + if (interlace) { + switch (pass) { + case 0: + case 1: + ypos += 8; + break; + case 2: + ypos += 4; + break; + case 3: + ypos += 2; + break; + } + + if (ypos >= height) { + ++pass; + switch (pass) { + case 1: + ypos = 4; + break; + case 2: + ypos = 2; + break; + case 3: + ypos = 1; + break; + default: + goto fini; + } + } + } else { + ++ypos; + } + } + if (ypos >= height) + break; + } + + fini: + + return image; +} + +#else + +/* See if an image is contained in a data source */ +int IMG_isGIF(SDL_RWops *src) +{ + return(0); +} + +/* Load a GIF type image from an SDL datasource */ +SDL_Surface *IMG_LoadGIF_RW(SDL_RWops *src) +{ + return(NULL); +} + +#endif /* LOAD_GIF */ diff --git a/contrib/sdk/sources/SDL-1.2.2/SDL_image/IMG_jpg.c b/contrib/sdk/sources/SDL-1.2.2/SDL_image/IMG_jpg.c new file mode 100644 index 000000000..4e8e56252 --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/SDL_image/IMG_jpg.c @@ -0,0 +1,242 @@ +/* + IMGLIB: An example image loading library for use with SDL + Copyright (C) 1999 Sam Lantinga + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the Free + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + Sam Lantinga + 5635-34 Springhouse Dr. + Pleasanton, CA 94588 (USA) + slouken@devolution.com +*/ + +/* This is a JPEG image file loading framework */ + +#include +#include + +#include "SDL_image.h" + +#ifdef LOAD_JPG + +#include + +/* Define this for fast loading and not as good image quality */ +/*#define FAST_JPEG*/ + +/* See if an image is contained in a data source */ +int IMG_isJPG(SDL_RWops *src) +{ + int is_JPG; + Uint8 magic[4]; + + is_JPG = 0; + if ( SDL_RWread(src, magic, 2, 1) ) { + if ( (magic[0] == 0xFF) && (magic[1] == 0xD8) ) { + SDL_RWread(src, magic, 4, 1); + SDL_RWread(src, magic, 4, 1); + if ( memcmp((char *)magic, "JFIF", 4) == 0 ) { + is_JPG = 1; + } + } + } + return(is_JPG); +} + +#define INPUT_BUFFER_SIZE 4096 +typedef struct { + struct jpeg_source_mgr pub; + + SDL_RWops *ctx; + Uint8 buffer[INPUT_BUFFER_SIZE]; +} my_source_mgr; + +/* + * Initialize source --- called by jpeg_read_header + * before any data is actually read. + */ +static void init_source (j_decompress_ptr cinfo) +{ + /* We don't actually need to do anything */ + return; +} + +/* + * Fill the input buffer --- called whenever buffer is emptied. + */ +static int fill_input_buffer (j_decompress_ptr cinfo) +{ + my_source_mgr * src = (my_source_mgr *) cinfo->src; + int nbytes; + + nbytes = SDL_RWread(src->ctx, src->buffer, 1, INPUT_BUFFER_SIZE); + if (nbytes <= 0) { + /* Insert a fake EOI marker */ + src->buffer[0] = (Uint8) 0xFF; + src->buffer[1] = (Uint8) JPEG_EOI; + nbytes = 2; + } + src->pub.next_input_byte = src->buffer; + src->pub.bytes_in_buffer = nbytes; + + 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. + */ +static void skip_input_data (j_decompress_ptr cinfo, long num_bytes) +{ + my_source_mgr * src = (my_source_mgr *) 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) src->pub.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; + } +} + +/* + * Terminate source --- called by jpeg_finish_decompress + * after all data has been read. + */ +static void term_source (j_decompress_ptr cinfo) +{ + /* We don't actually need to do anything */ + return; +} + +/* + * Prepare for input from a stdio stream. + * The caller must have already opened the stream, and is responsible + * for closing it after finishing decompression. + */ +static void jpeg_SDL_RW_src (j_decompress_ptr cinfo, SDL_RWops *ctx) +{ + my_source_mgr *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_source_mgr *) cinfo->src; + } + + src = (my_source_mgr *) 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->ctx = ctx; + src->pub.bytes_in_buffer = 0; /* forces fill_input_buffer on first read */ + src->pub.next_input_byte = NULL; /* until buffer loaded */ +} + +/* Load a JPEG type image from an SDL datasource */ +SDL_Surface *IMG_LoadJPG_RW(SDL_RWops *src) +{ + struct jpeg_error_mgr errmgr; + struct jpeg_decompress_struct cinfo; + JSAMPROW rowptr[1]; + SDL_Surface *surface; + + /* Create a decompression structure and load the JPEG header */ + cinfo.err = jpeg_std_error(&errmgr); + jpeg_create_decompress(&cinfo); + jpeg_SDL_RW_src(&cinfo, src); + jpeg_read_header(&cinfo, TRUE); + + /* Set 24-bit RGB output */ + cinfo.out_color_space = JCS_RGB; + cinfo.quantize_colors = FALSE; +#ifdef FAST_JPEG + cinfo.scale_num = 1; + cinfo.scale_denom = 1; + cinfo.dct_method = JDCT_FASTEST; + cinfo.do_fancy_upsampling = FALSE; +#endif + jpeg_calc_output_dimensions(&cinfo); + + /* Allocate an output surface to hold the image */ + surface = SDL_AllocSurface(SDL_SWSURFACE, + cinfo.output_width, cinfo.output_height, 24, +#if SDL_BYTEORDER == SDL_LIL_ENDIAN + 0x0000FF, 0x00FF00, 0xFF0000, +#else + 0xFF0000, 0x00FF00, 0x0000FF, +#endif + 0); + if ( surface == NULL ) { + IMG_SetError("Out of memory"); + goto done; + } + + /* Decompress the image */ + jpeg_start_decompress(&cinfo); + while ( cinfo.output_scanline < cinfo.output_height ) { + rowptr[0] = (JSAMPROW)(Uint8 *)surface->pixels + + cinfo.output_scanline * surface->pitch; + jpeg_read_scanlines(&cinfo, rowptr, (JDIMENSION) 1); + } + jpeg_finish_decompress(&cinfo); + + /* Clean up and return */ +done: + jpeg_destroy_decompress(&cinfo); + return(surface); +} + +#else + +/* See if an image is contained in a data source */ +int IMG_isJPG(SDL_RWops *src) +{ + return(0); +} + +/* Load a JPEG type image from an SDL datasource */ +SDL_Surface *IMG_LoadJPG_RW(SDL_RWops *src) +{ + return(NULL); +} + +#endif /* LOAD_JPG */ diff --git a/contrib/sdk/sources/SDL-1.2.2/SDL_image/IMG_pcx.c b/contrib/sdk/sources/SDL-1.2.2/SDL_image/IMG_pcx.c new file mode 100644 index 000000000..d1c08f5dc --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/SDL_image/IMG_pcx.c @@ -0,0 +1,253 @@ +/* + IMGLIB: An example image loading library for use with SDL + Copyright (C) 1999 Sam Lantinga + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the Free + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + Sam Lantinga + 5635-34 Springhouse Dr. + Pleasanton, CA 94588 (USA) + slouken@devolution.com +*/ + +/* + * PCX file reader: + * Supports: + * 1..4 bits/pixel in multiplanar format (1 bit/plane/pixel) + * 8 bits/pixel in single-planar format (8 bits/plane/pixel) + * 24 bits/pixel in 3-plane format (8 bits/plane/pixel) + * + * (The <8bpp formats are expanded to 8bpp surfaces) + * + * Doesn't support: + * single-planar packed-pixel formats other than 8bpp + * 4-plane 32bpp format with a fourth "intensity" plane + */ +#include +#include + +#include "SDL_endian.h" + +#include "SDL_image.h" + +#ifdef LOAD_PCX + +struct PCXheader { + Uint8 Manufacturer; + Uint8 Version; + Uint8 Encoding; + Uint8 BitsPerPixel; + Sint16 Xmin, Ymin, Xmax, Ymax; + Sint16 HDpi, VDpi; + Uint8 Colormap[48]; + Uint8 Reserved; + Uint8 NPlanes; + Sint16 BytesPerLine; + Sint16 PaletteInfo; + Sint16 HscreenSize; + Sint16 VscreenSize; + Uint8 Filler[54]; +}; + +/* See if an image is contained in a data source */ +int IMG_isPCX(SDL_RWops *src) +{ + int is_PCX; + const int ZSoft_Manufacturer = 10; + const int PC_Paintbrush_Version = 5; + const int PCX_RunLength_Encoding = 1; + struct PCXheader pcxh; + + is_PCX = 0; + if ( SDL_RWread(src, &pcxh, sizeof(pcxh), 1) == 1 ) { + if ( (pcxh.Manufacturer == ZSoft_Manufacturer) && + (pcxh.Version == PC_Paintbrush_Version) && + (pcxh.Encoding == PCX_RunLength_Encoding) ) { + is_PCX = 1; + } + } + return(is_PCX); +} + +/* Load a PCX type image from an SDL datasource */ +SDL_Surface *IMG_LoadPCX_RW(SDL_RWops *src) +{ + struct PCXheader pcxh; + Uint32 Rmask; + Uint32 Gmask; + Uint32 Bmask; + Uint32 Amask; + SDL_Surface *surface = NULL; + int width, height; + int y, bpl; + Uint8 *row, *buf = NULL; + char *error = NULL; + int bits, src_bits; + + if ( ! src ) { + goto done; + } + + if ( ! SDL_RWread(src, &pcxh, sizeof(pcxh), 1) ) { + error = "file truncated"; + goto done; + } + pcxh.Xmin = SDL_SwapLE16(pcxh.Xmin); + pcxh.Ymin = SDL_SwapLE16(pcxh.Ymin); + pcxh.Xmax = SDL_SwapLE16(pcxh.Xmax); + pcxh.Ymax = SDL_SwapLE16(pcxh.Ymax); + pcxh.BytesPerLine = SDL_SwapLE16(pcxh.BytesPerLine); + + /* Create the surface of the appropriate type */ + width = (pcxh.Xmax - pcxh.Xmin) + 1; + height = (pcxh.Ymax - pcxh.Ymin) + 1; + Rmask = Gmask = Bmask = Amask = 0; + src_bits = pcxh.BitsPerPixel * pcxh.NPlanes; + if((pcxh.BitsPerPixel == 1 && pcxh.NPlanes >= 1 && pcxh.NPlanes <= 4) + || (pcxh.BitsPerPixel == 8 && pcxh.NPlanes == 1)) { + bits = 8; + } else if(pcxh.BitsPerPixel == 8 && pcxh.NPlanes == 3) { + bits = 24; + if ( SDL_BYTEORDER == SDL_LIL_ENDIAN ) { + Rmask = 0x000000FF; + Gmask = 0x0000FF00; + Bmask = 0x00FF0000; + } else { + Rmask = 0xFF0000; + Gmask = 0x00FF00; + Bmask = 0x0000FF; + } + } else { + error = "unsupported PCX format"; + goto done; + } + surface = SDL_AllocSurface(SDL_SWSURFACE, width, height, + bits, Rmask, Gmask, Bmask, Amask); + if ( surface == NULL ) + goto done; + + bpl = pcxh.NPlanes * pcxh.BytesPerLine; + buf = malloc(bpl); + row = surface->pixels; + for ( y=0; yh; ++y ) { + /* decode a scan line to a temporary buffer first */ + int i, count = 0; + Uint8 ch; + Uint8 *dst = (src_bits == 8) ? row : buf; + for(i = 0; i < bpl; i++) { + if(!count) { + if(!SDL_RWread(src, &ch, 1, 1)) { + error = "file truncated"; + goto done; + } + if( (ch & 0xc0) == 0xc0) { + count = ch & 0x3f; + if(!SDL_RWread(src, &ch, 1, 1)) { + error = "file truncated"; + goto done; + } + } else + count = 1; + } + dst[i] = ch; + count--; + } + + if(src_bits <= 4) { + /* expand planes to 1 byte/pixel */ + Uint8 *src = buf; + int plane; + for(plane = 0; plane < pcxh.NPlanes; plane++) { + int i, j, x = 0; + for(i = 0; i < pcxh.BytesPerLine; i++) { + Uint8 byte = *src++; + for(j = 7; j >= 0; j--) { + unsigned bit = (byte >> j) & 1; + row[x++] |= bit << plane; + } + } + } + } else if(src_bits == 24) { + /* de-interlace planes */ + Uint8 *src = buf; + int plane; + for(plane = 0; plane < pcxh.NPlanes; plane++) { + int x; + dst = row + plane; + for(x = 0; x < width; x++) { + *dst = *src++; + dst += pcxh.NPlanes; + } + } + } + + row += surface->pitch; + } + + if(bits == 8) { + SDL_Color *colors = surface->format->palette->colors; + int nc = 1 << src_bits; + int i; + + surface->format->palette->ncolors = nc; + if(src_bits == 8) { + Uint8 ch; + /* look for a 256-colour palette */ + do { + if ( !SDL_RWread(src, &ch, 1, 1)) { + error = "file truncated"; + goto done; + } + } while ( ch != 12 ); + + for(i = 0; i < 256; i++) { + SDL_RWread(src, &colors[i].r, 1, 1); + SDL_RWread(src, &colors[i].g, 1, 1); + SDL_RWread(src, &colors[i].b, 1, 1); + } + } else { + for(i = 0; i < nc; i++) { + colors[i].r = pcxh.Colormap[i * 3]; + colors[i].g = pcxh.Colormap[i * 3 + 1]; + colors[i].b = pcxh.Colormap[i * 3 + 2]; + } + } + } + +done: + free(buf); + if ( error ) { + SDL_FreeSurface(surface); + IMG_SetError(error); + surface = NULL; + } + return(surface); +} + +#else + +/* See if an image is contained in a data source */ +int IMG_isPCX(SDL_RWops *src) +{ + return(0); +} + +/* Load a PCX type image from an SDL datasource */ +SDL_Surface *IMG_LoadPCX_RW(SDL_RWops *src) +{ + return(NULL); +} + +#endif /* LOAD_PCX */ diff --git a/contrib/sdk/sources/SDL-1.2.2/SDL_image/IMG_png.c b/contrib/sdk/sources/SDL-1.2.2/SDL_image/IMG_png.c new file mode 100644 index 000000000..e8655a0c8 --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/SDL_image/IMG_png.c @@ -0,0 +1,286 @@ +/* + IMGLIB: An example image loading library for use with SDL + Copyright (C) 1999 Sam Lantinga + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the Free + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + Sam Lantinga + 5635-34 Springhouse Dr. + Pleasanton, CA 94588 (USA) + slouken@devolution.com +*/ + +/* This is a PNG image file loading framework */ + +#include +#include + +#include "SDL_image.h" + +#ifdef LOAD_PNG + +/*============================================================================= + File: SDL_png.c + Purpose: A PNG loader and saver for the SDL library + Revision: + Created by: Philippe Lavoie (2 November 1998) + lavoie@zeus.genie.uottawa.ca + Modified by: + + Copyright notice: + Copyright (C) 1998 Philippe Lavoie + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the Free + Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + Comments: The load and save routine are basically the ones you can find + in the example.c file from the libpng distribution. + + Changes: + 5/17/99 - Modified to use the new SDL data sources - Sam Lantinga + +=============================================================================*/ + +#include "SDL_endian.h" + +#ifdef macintosh +#define MACOS +#endif +#include + +#define PNG_BYTES_TO_CHECK 4 + +/* See if an image is contained in a data source */ +int IMG_isPNG(SDL_RWops *src) +{ + unsigned char buf[PNG_BYTES_TO_CHECK]; + + /* Read in the signature bytes */ + if (SDL_RWread(src, buf, 1, PNG_BYTES_TO_CHECK) != PNG_BYTES_TO_CHECK) + return 0; + + /* Compare the first PNG_BYTES_TO_CHECK bytes of the signature. */ + return( !png_sig_cmp(buf, (png_size_t)0, PNG_BYTES_TO_CHECK)); +} + +/* Load a PNG type image from an SDL datasource */ +static void png_read_data(png_structp ctx, png_bytep area, png_size_t size) +{ + SDL_RWops *src; + + src = (SDL_RWops *)png_get_io_ptr(ctx); + SDL_RWread(src, area, size, 1); +} +SDL_Surface *IMG_LoadPNG_RW(SDL_RWops *src) +{ + SDL_Surface *volatile surface; + png_structp png_ptr; + png_infop info_ptr; + png_uint_32 width, height; + int bit_depth, color_type, interlace_type; + Uint32 Rmask; + Uint32 Gmask; + Uint32 Bmask; + Uint32 Amask; + SDL_Palette *palette; + png_bytep *volatile row_pointers; + int row, i; + volatile int ckey = -1; + png_color_16 *transv; + + /* Initialize the data we will clean up when we're done */ + png_ptr = NULL; info_ptr = NULL; row_pointers = NULL; surface = NULL; + + /* Check to make sure we have something to do */ + if ( ! src ) { + goto done; + } + + /* Create the PNG loading context structure */ + png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, + NULL,NULL,NULL); + if (png_ptr == NULL){ + IMG_SetError("Couldn't allocate memory for PNG file"); + goto done; + } + + /* Allocate/initialize the memory for image information. REQUIRED. */ + info_ptr = png_create_info_struct(png_ptr); + if (info_ptr == NULL) { + IMG_SetError("Couldn't create image information for PNG file"); + goto done; + } + + /* Set error handling if you are using setjmp/longjmp method (this is + * the normal method of doing things with libpng). REQUIRED unless you + * set up your own error handlers in png_create_read_struct() earlier. + */ + if ( setjmp(png_ptr->jmpbuf) ) { + IMG_SetError("Error reading the PNG file."); + goto done; + } + + /* Set up the input control */ + png_set_read_fn(png_ptr, src, png_read_data); + + /* Read PNG header info */ + png_read_info(png_ptr, info_ptr); + png_get_IHDR(png_ptr, info_ptr, &width, &height, &bit_depth, + &color_type, &interlace_type, NULL, NULL); + + /* tell libpng to strip 16 bit/color files down to 8 bits/color */ + png_set_strip_16(png_ptr) ; + + /* Extract multiple pixels with bit depths of 1, 2, and 4 from a single + * byte into separate bytes (useful for paletted and grayscale images). + */ + png_set_packing(png_ptr); + + /* scale greyscale values to the range 0..255 */ + if(color_type == PNG_COLOR_TYPE_GRAY) + png_set_expand(png_ptr); + + /* For images with a single "transparent colour", set colour key; + if more than one index has transparency, use full alpha channel */ + if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS)) { + int num_trans; + Uint8 *trans; + png_get_tRNS(png_ptr, info_ptr, &trans, &num_trans, + &transv); + if(color_type == PNG_COLOR_TYPE_PALETTE) { + if(num_trans == 1) { + /* exactly one transparent value: set colour key */ + ckey = trans[0]; + } else + png_set_expand(png_ptr); + } else + ckey = 0; /* actual value will be set later */ + } + + if ( color_type == PNG_COLOR_TYPE_GRAY_ALPHA ) + png_set_gray_to_rgb(png_ptr); + + png_read_update_info(png_ptr, info_ptr); + + png_get_IHDR(png_ptr, info_ptr, &width, &height, &bit_depth, + &color_type, &interlace_type, NULL, NULL); + + /* Allocate the SDL surface to hold the image */ + Rmask = Gmask = Bmask = Amask = 0 ; + if ( color_type != PNG_COLOR_TYPE_PALETTE ) { + if ( SDL_BYTEORDER == SDL_LIL_ENDIAN ) { + Rmask = 0x000000FF; + Gmask = 0x0000FF00; + Bmask = 0x00FF0000; + Amask = (info_ptr->channels == 4) ? 0xFF000000 : 0; + } else { + int s = (info_ptr->channels == 4) ? 0 : 8; + Rmask = 0xFF000000 >> s; + Gmask = 0x00FF0000 >> s; + Bmask = 0x0000FF00 >> s; + Amask = 0x000000FF >> s; + } + } + surface = SDL_AllocSurface(SDL_SWSURFACE, width, height, + bit_depth*info_ptr->channels, Rmask,Gmask,Bmask,Amask); + if ( surface == NULL ) { + IMG_SetError("Out of memory"); + goto done; + } + + if(ckey != -1) { + if(color_type != PNG_COLOR_TYPE_PALETTE) + /* FIXME: Should these be truncated or shifted down? */ + ckey = SDL_MapRGB(surface->format, + (Uint8)transv->red, + (Uint8)transv->green, + (Uint8)transv->blue); + SDL_SetColorKey(surface, SDL_SRCCOLORKEY, ckey); + } + + /* Create the array of pointers to image data */ + row_pointers = (png_bytep*) malloc(sizeof(png_bytep)*height); + if ( (row_pointers == NULL) ) { + IMG_SetError("Out of memory"); + SDL_FreeSurface(surface); + surface = NULL; + goto done; + } + for (row = 0; row < (int)height; row++) { + row_pointers[row] = (png_bytep) + (Uint8 *)surface->pixels + row*surface->pitch; + } + + /* Read the entire image in one go */ + png_read_image(png_ptr, row_pointers); + + /* read rest of file, get additional chunks in info_ptr - REQUIRED */ + png_read_end(png_ptr, info_ptr); + + /* Load the palette, if any */ + palette = surface->format->palette; + if ( palette ) { + if(color_type == PNG_COLOR_TYPE_GRAY) { + palette->ncolors = 256; + for(i = 0; i < 256; i++) { + palette->colors[i].r = i; + palette->colors[i].g = i; + palette->colors[i].b = i; + } + } else if (info_ptr->num_palette > 0 ) { + palette->ncolors = info_ptr->num_palette; + for( i=0; inum_palette; ++i ) { + palette->colors[i].b = info_ptr->palette[i].blue; + palette->colors[i].g = info_ptr->palette[i].green; + palette->colors[i].r = info_ptr->palette[i].red; + } + } + } + +done: /* Clean up and return */ + png_destroy_read_struct(&png_ptr, info_ptr ? &info_ptr : (png_infopp)0, + (png_infopp)0); + if ( row_pointers ) { + free(row_pointers); + } + return(surface); +} + +#else + +/* See if an image is contained in a data source */ +int IMG_isPNG(SDL_RWops *src) +{ + return(0); +} + +/* Load a PNG type image from an SDL datasource */ +SDL_Surface *IMG_LoadPNG_RW(SDL_RWops *src) +{ + return(NULL); +} + +#endif /* LOAD_PNG */ diff --git a/contrib/sdk/sources/SDL-1.2.2/SDL_image/IMG_pnm.c b/contrib/sdk/sources/SDL-1.2.2/SDL_image/IMG_pnm.c new file mode 100644 index 000000000..316f45009 --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/SDL_image/IMG_pnm.c @@ -0,0 +1,242 @@ +/* + IMGLIB: An example image loading library for use with SDL + Copyright (C) 1999 Sam Lantinga + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the Free + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + Sam Lantinga + 5635-34 Springhouse Dr. + Pleasanton, CA 94588 (USA) + slouken@devolution.com +*/ + +/* + * PNM (portable anymap) image loader: + * + * Supports: PBM, PGM and PPM, ASCII and binary formats + * (PBM and PGM are loaded as 8bpp surfaces) + * Does not support: maximum component value > 255 + */ + +#include +#include +#include +#include + +#include "SDL_image.h" + +#ifdef LOAD_PNM + +/* See if an image is contained in a data source */ +int IMG_isPNM(SDL_RWops *src) +{ + char magic[2]; + + /* + * PNM magic signatures: + * P1 PBM, ascii format + * P2 PGM, ascii format + * P3 PPM, ascii format + * P4 PBM, binary format + * P5 PGM, binary format + * P6 PPM, binary format + */ + return (SDL_RWread(src, magic, 2, 1) + && magic[0] == 'P' && magic[1] >= '1' && magic[1] <= '6'); +} + +/* read a non-negative integer from the source. return -1 upon error */ +static int ReadNumber(SDL_RWops *src) +{ + int number; + unsigned char ch; + + /* Initialize return value */ + number = 0; + + /* Skip leading whitespace */ + do { + if ( ! SDL_RWread(src, &ch, 1, 1) ) { + return(0); + } + /* Eat comments as whitespace */ + if ( ch == '#' ) { /* Comment is '#' to end of line */ + do { + if ( ! SDL_RWread(src, &ch, 1, 1) ) { + return -1; + } + } while ( (ch != '\r') && (ch != '\n') ); + } + } while ( isspace(ch) ); + + /* Add up the number */ + do { + number *= 10; + number += ch-'0'; + + if ( !SDL_RWread(src, &ch, 1, 1) ) { + return -1; + } + } while ( isdigit(ch) ); + + return(number); +} + +SDL_Surface *IMG_LoadPNM_RW(SDL_RWops *src) +{ + SDL_Surface *surface = NULL; + int width, height; + int maxval, y, bpl; + Uint8 *row; + Uint8 *buf = NULL; + char *error = NULL; + Uint8 magic[2]; + int ascii; + enum { PBM, PGM, PPM } kind; + +#define ERROR(s) do { error = (s); goto done; } while(0) + + if(!src) + return NULL; + + SDL_RWread(src, magic, 2, 1); + kind = magic[1] - '1'; + ascii = 1; + if(kind >= 3) { + ascii = 0; + kind -= 3; + } + + width = ReadNumber(src); + height = ReadNumber(src); + if(width <= 0 || height <= 0) + ERROR("Unable to read image width and height"); + + if(kind != PBM) { + maxval = ReadNumber(src); + if(maxval <= 0 || maxval > 255) + ERROR("unsupported PNM format"); + } else + maxval = 255; /* never scale PBMs */ + + /* binary PNM allows just a single character of whitespace after + the last parameter, and we've already consumed it */ + + if(kind == PPM) { + /* 24-bit surface in R,G,B byte order */ + surface = SDL_AllocSurface(SDL_SWSURFACE, width, height, 24, +#if SDL_BYTEORDER == SDL_LIL_ENDIAN + 0x000000ff, 0x0000ff00, 0x00ff0000, +#else + 0x00ff0000, 0x0000ff00, 0x000000ff, +#endif + 0); + } else { + /* load PBM/PGM as 8-bit indexed images */ + surface = SDL_AllocSurface(SDL_SWSURFACE, width, height, 8, + 0, 0, 0, 0); + } + if ( surface == NULL ) + ERROR("Out of memory"); + bpl = width * surface->format->BytesPerPixel; + if(kind == PGM) { + SDL_Color *c = surface->format->palette->colors; + int i; + for(i = 0; i < 256; i++) + c[i].r = c[i].g = c[i].b = i; + surface->format->palette->ncolors = 256; + } else if(kind == PBM) { + /* for some reason PBM has 1=black, 0=white */ + SDL_Color *c = surface->format->palette->colors; + c[0].r = c[0].g = c[0].b = 255; + c[1].r = c[1].g = c[1].b = 0; + surface->format->palette->ncolors = 2; + bpl = (width + 7) >> 3; + buf = malloc(bpl); + if(buf == NULL) + ERROR("Out of memory"); + } + + /* Read the image into the surface */ + row = surface->pixels; + for(y = 0; y < height; y++) { + if(ascii) { + int i; + if(kind == PBM) { + for(i = 0; i < width; i++) { + Uint8 ch; + do { + if(!SDL_RWread(src, &ch, + 1, 1)) + ERROR("file truncated"); + ch -= '0'; + } while(ch > 1); + row[i] = ch; + } + } else { + for(i = 0; i < bpl; i++) { + int c; + c = ReadNumber(src); + if(c < 0) + ERROR("file truncated"); + row[i] = c; + } + } + } else { + Uint8 *dst = (kind == PBM) ? buf : row; + if(!SDL_RWread(src, dst, bpl, 1)) + ERROR("file truncated"); + if(kind == PBM) { + /* expand bitmap to 8bpp */ + int i; + for(i = 0; i < width; i++) { + int bit = 7 - (i & 7); + row[i] = (buf[i >> 3] >> bit) & 1; + } + } + } + if(maxval < 255) { + /* scale up to full dynamic range (slow) */ + int i; + for(i = 0; i < bpl; i++) + row[i] = row[i] * 255 / maxval; + } + row += surface->pitch; + } +done: + free(buf); + if(error) { + SDL_FreeSurface(surface); + IMG_SetError(error); + surface = NULL; + } + return(surface); +} + +#else + +/* See if an image is contained in a data source */ +int IMG_isPNM(SDL_RWops *src) +{ + return(0); +} + +/* Load a PNM type image from an SDL datasource */ +SDL_Surface *IMG_LoadPNM_RW(SDL_RWops *src) +{ + return(NULL); +} + +#endif /* LOAD_PNM */ diff --git a/contrib/sdk/sources/SDL-1.2.2/SDL_image/IMG_tga.c b/contrib/sdk/sources/SDL-1.2.2/SDL_image/IMG_tga.c new file mode 100644 index 000000000..2a63a2db1 --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/SDL_image/IMG_tga.c @@ -0,0 +1,321 @@ +/* + IMGLIB: An example image loading library for use with SDL + Copyright (C) 1999 Sam Lantinga + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the Free + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + Sam Lantinga + 5635-34 Springhouse Dr. + Pleasanton, CA 94588 (USA) + slouken@devolution.com +*/ + +#include +#include +#include + +#include "SDL_endian.h" + +#include "SDL_image.h" + +#ifdef LOAD_TGA + +/* + * A TGA loader for the SDL library + * Supports: Reading 8, 15, 16, 24 and 32bpp images, with alpha or colourkey, + * uncompressed or RLE encoded. + * + * 2000-06-10 Mattias Engdegård : initial version + * 2000-06-26 Mattias Engdegård : read greyscale TGAs + * 2000-08-09 Mattias Engdegård : alpha inversion removed + */ + +struct TGAheader { + Uint8 infolen; /* length of info field */ + Uint8 has_cmap; /* 1 if image has colormap, 0 otherwise */ + Uint8 type; + + Uint8 cmap_start[2]; /* index of first colormap entry */ + Uint8 cmap_len[2]; /* number of entries in colormap */ + Uint8 cmap_bits; /* bits per colormap entry */ + + Uint8 yorigin[2]; /* image origin (ignored here) */ + Uint8 xorigin[2]; + Uint8 width[2]; /* image size */ + Uint8 height[2]; + Uint8 pixel_bits; /* bits/pixel */ + Uint8 flags; +}; + +enum tga_type { + TGA_TYPE_INDEXED = 1, + TGA_TYPE_RGB = 2, + TGA_TYPE_BW = 3, + TGA_TYPE_RLE_INDEXED = 9, + TGA_TYPE_RLE_RGB = 10, + TGA_TYPE_RLE_BW = 11 +}; + +#define TGA_INTERLEAVE_MASK 0xc0 +#define TGA_INTERLEAVE_NONE 0x00 +#define TGA_INTERLEAVE_2WAY 0x40 +#define TGA_INTERLEAVE_4WAY 0x80 + +#define TGA_ORIGIN_MASK 0x30 +#define TGA_ORIGIN_LEFT 0x00 +#define TGA_ORIGIN_RIGHT 0x10 +#define TGA_ORIGIN_LOWER 0x00 +#define TGA_ORIGIN_UPPER 0x20 + +/* read/write unaligned little-endian 16-bit ints */ +#define LE16(p) ((p)[0] + ((p)[1] << 8)) +#define SETLE16(p, v) ((p)[0] = (v), (p)[1] = (v) >> 8) + +static void unsupported(void) +{ + IMG_SetError("unsupported TGA format"); +} + +/* Load a TGA type image from an SDL datasource */ +SDL_Surface *IMG_LoadTGA_RW(SDL_RWops *src) +{ + struct TGAheader hdr; + int rle = 0; + int alpha = 0; + int indexed = 0; + int grey = 0; + int ckey = -1; + int ncols, w, h; + SDL_Surface *img; + Uint32 rmask, gmask, bmask, amask; + Uint8 *dst; + int i; + int bpp; + int lstep; + Uint32 pixel; + int count, rep; + + if(!SDL_RWread(src, &hdr, sizeof(hdr), 1)) + goto error; + ncols = LE16(hdr.cmap_len); + switch(hdr.type) { + case TGA_TYPE_RLE_INDEXED: + rle = 1; + /* fallthrough */ + case TGA_TYPE_INDEXED: + if(!hdr.has_cmap || hdr.pixel_bits != 8 || ncols > 256) + goto error; + indexed = 1; + break; + + case TGA_TYPE_RLE_RGB: + rle = 1; + /* fallthrough */ + case TGA_TYPE_RGB: + indexed = 0; + break; + + case TGA_TYPE_RLE_BW: + rle = 1; + /* fallthrough */ + case TGA_TYPE_BW: + if(hdr.pixel_bits != 8) + goto error; + /* Treat greyscale as 8bpp indexed images */ + indexed = grey = 1; + break; + + default: + unsupported(); + return NULL; + } + + bpp = (hdr.pixel_bits + 7) >> 3; + rmask = gmask = bmask = amask = 0; + switch(hdr.pixel_bits) { + case 8: + if(!indexed) { + unsupported(); + return NULL; + } + break; + + case 15: + case 16: + /* 15 and 16bpp both seem to use 5 bits/plane. The extra alpha bit + is ignored for now. */ + rmask = 0x7c00; + gmask = 0x03e0; + bmask = 0x001f; + break; + + case 32: + alpha = 1; + /* fallthrough */ + case 24: + if(SDL_BYTEORDER == SDL_BIG_ENDIAN) { + int s = alpha ? 0 : 8; + amask = 0x000000ff >> s; + rmask = 0x0000ff00 >> s; + gmask = 0x00ff0000 >> s; + bmask = 0xff000000 >> s; + } else { + amask = alpha ? 0xff000000 : 0; + rmask = 0x00ff0000; + gmask = 0x0000ff00; + bmask = 0x000000ff; + } + break; + + default: + unsupported(); + return NULL; + } + + if((hdr.flags & TGA_INTERLEAVE_MASK) != TGA_INTERLEAVE_NONE + || hdr.flags & TGA_ORIGIN_RIGHT) { + unsupported(); + return NULL; + } + + SDL_RWseek(src, hdr.infolen, SEEK_CUR); /* skip info field */ + + w = LE16(hdr.width); + h = LE16(hdr.height); + img = SDL_CreateRGBSurface(SDL_SWSURFACE, w, h, + bpp * 8, + rmask, gmask, bmask, amask); + + if(hdr.has_cmap) { + int palsiz = ncols * ((hdr.cmap_bits + 7) >> 3); + if(indexed && !grey) { + Uint8 *pal = malloc(palsiz), *p = pal; + SDL_Color *colors = img->format->palette->colors; + img->format->palette->ncolors = ncols; + SDL_RWread(src, pal, palsiz, 1); + for(i = 0; i < ncols; i++) { + switch(hdr.cmap_bits) { + case 15: + case 16: + { + Uint16 c = p[0] + (p[1] << 8); + p += 2; + colors[i].r = (c >> 7) & 0xf8; + colors[i].g = (c >> 2) & 0xf8; + colors[i].b = c << 3; + } + break; + case 24: + case 32: + colors[i].b = *p++; + colors[i].g = *p++; + colors[i].r = *p++; + if(hdr.cmap_bits == 32 && *p++ < 128) + ckey = i; + break; + } + } + free(pal); + if(ckey >= 0) + SDL_SetColorKey(img, SDL_SRCCOLORKEY, ckey); + } else { + /* skip unneeded colormap */ + SDL_RWseek(src, palsiz, SEEK_CUR); + } + } + + if(grey) { + SDL_Color *colors = img->format->palette->colors; + for(i = 0; i < 256; i++) + colors[i].r = colors[i].g = colors[i].b = i; + img->format->palette->ncolors = 256; + } + + if(hdr.flags & TGA_ORIGIN_UPPER) { + lstep = img->pitch; + dst = img->pixels; + } else { + lstep = -img->pitch; + dst = (Uint8 *)img->pixels + (h - 1) * img->pitch; + } + + /* The RLE decoding code is slightly convoluted since we can't rely on + spans not to wrap across scan lines */ + count = rep = 0; + for(i = 0; i < h; i++) { + if(rle) { + int x = 0; + for(;;) { + Uint8 c; + + if(count) { + int n = count; + if(n > w - x) + n = w - x; + SDL_RWread(src, dst + x * bpp, n * bpp, 1); + count -= n; + x += n; + if(x == w) + break; + } else if(rep) { + int n = rep; + if(n > w - x) + n = w - x; + rep -= n; + while(n--) { + memcpy(dst + x * bpp, &pixel, bpp); + x++; + } + if(x == w) + break; + } + + SDL_RWread(src, &c, 1, 1); + if(c & 0x80) { + SDL_RWread(src, &pixel, bpp, 1); + rep = (c & 0x7f) + 1; + } else { + count = c + 1; + } + } + + } else { + SDL_RWread(src, dst, w * bpp, 1); + } + if(SDL_BYTEORDER == SDL_BIG_ENDIAN && bpp == 2) { + /* swap byte order */ + int x; + Uint16 *p = (Uint16 *)dst; + for(x = 0; x < w; x++) + p[x] = SDL_Swap16(p[x]); + } + dst += lstep; + } + return img; + +error: + IMG_SetError("Error reading TGA data"); + return NULL; +} + +#else + +/* dummy TGA load routine */ +SDL_Surface *IMG_LoadTGA_RW(SDL_RWops *src) +{ + return(NULL); +} + +#endif /* LOAD_TGA */ diff --git a/contrib/sdk/sources/SDL-1.2.2/SDL_image/IMG_tif.c b/contrib/sdk/sources/SDL-1.2.2/SDL_image/IMG_tif.c new file mode 100644 index 000000000..f5057d8a9 --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/SDL_image/IMG_tif.c @@ -0,0 +1,174 @@ +/* + IMGLIB: An example image loading library for use with SDL + Copyright (C) 1999 Sam Lantinga + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the Free + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + Sam Lantinga + 5635-34 Springhouse Dr. + Pleasanton, CA 94588 (USA) + slouken@devolution.com + + 5/29/2000: TIFF loader written. Mark Baker (mbaker@0x7a69.net) + 2000-07-28: Fixed two off-by one bugs in reversal loop and made it work on + big-endian machines (Mattias) + 2000-08-09: Removed alpha inversion (Mattias) +*/ + + + +/* This is a TIFF image file loading framework */ + +#include + +#include "SDL_image.h" + +#ifdef LOAD_TIF + +#include + +/* + * These are the thunking routine to use the SDL_RWops* routines from + * libtiff's internals. +*/ + +static tsize_t tiff_read(thandle_t fd, tdata_t buf, tsize_t size) +{ + return SDL_RWread((SDL_RWops*)fd, buf, 1, size); +} + +static toff_t tiff_seek(thandle_t fd, toff_t offset, int origin) +{ + return SDL_RWseek((SDL_RWops*)fd, offset, origin); +} + +static tsize_t tiff_write(thandle_t fd, tdata_t buf, tsize_t size) +{ + return SDL_RWwrite((SDL_RWops*)fd, buf, 1, size); +} + +static int tiff_close(thandle_t fd) +{ + /* + * We don't want libtiff closing our SDL_RWops*, but if it's not given + * a routine to try, and if the image isn't a TIFF, it'll segfault. + */ + return 0; +} + +static toff_t tiff_size(thandle_t fd) +{ + Uint32 save_pos; + toff_t size; + + save_pos = SDL_RWtell((SDL_RWops*)fd); + SDL_RWseek((SDL_RWops*)fd, 0, SEEK_END); + size = SDL_RWtell((SDL_RWops*)fd); + SDL_RWseek((SDL_RWops*)fd, save_pos, SEEK_SET); + return size; +} + +int IMG_isTIF(SDL_RWops* src) +{ + TIFF* tiff; + TIFFErrorHandler prev_handler; + + /* Suppress output from libtiff */ + prev_handler = TIFFSetErrorHandler(NULL); + + /* Attempt to process the given file data */ + /* turn off memory mapped access with the m flag */ + tiff = TIFFClientOpen("SDL_image", "rm", (thandle_t)src, + tiff_read, tiff_write, tiff_seek, tiff_close, tiff_size, NULL, NULL); + + /* Reset the default error handler, since it can be useful for info */ + TIFFSetErrorHandler(prev_handler); + + /* If it's not a TIFF, then tiff will be NULL. */ + if(!tiff) + return 0; + + /* Free up any dynamically allocated memory libtiff uses */ + TIFFClose(tiff); + + return 1; +} + +SDL_Surface* IMG_LoadTIF_RW(SDL_RWops* src) +{ + TIFF* tiff; + SDL_Surface* surface = NULL; + Uint32 img_width, img_height; + Uint32 Rmask, Gmask, Bmask, Amask, mask; + Uint32 x, y; + Uint32 half; + + + /* turn off memory mapped access with the m flag */ + tiff = TIFFClientOpen("SDL_image", "rm", (thandle_t)src, + tiff_read, tiff_write, tiff_seek, tiff_close, tiff_size, NULL, NULL); + if(!tiff) + return NULL; + + /* Retrieve the dimensions of the image from the TIFF tags */ + TIFFGetField(tiff, TIFFTAG_IMAGEWIDTH, &img_width); + TIFFGetField(tiff, TIFFTAG_IMAGELENGTH, &img_height); + + Rmask = 0x000000FF; + Gmask = 0x0000FF00; + Bmask = 0x00FF0000; + Amask = 0xFF000000; + surface = SDL_AllocSurface(SDL_SWSURFACE, img_width, img_height, 32, + Rmask, Gmask, Bmask, Amask); + if(!surface) + return NULL; + + if(!TIFFReadRGBAImage(tiff, img_width, img_height, surface->pixels, 0)) + return NULL; + + /* libtiff loads the image upside-down, flip it back */ + half = img_height / 2; + for(y = 0; y < half; y++) + { + Uint32 *top = (Uint32 *)surface->pixels + y * surface->pitch/4; + Uint32 *bot = (Uint32 *)surface->pixels + + (img_height - y - 1) * surface->pitch/4; + for(x = 0; x < img_width; x++) + { + Uint32 tmp = top[x]; + top[x] = bot[x]; + bot[x] = tmp; + } + } + TIFFClose(tiff); + + return surface; +} + +#else + +/* See if an image is contained in a data source */ +int IMG_isTIF(SDL_RWops *src) +{ + return(0); +} + +/* Load a TIFF type image from an SDL datasource */ +SDL_Surface *IMG_LoadTIF_RW(SDL_RWops *src) +{ + return(NULL); +} + +#endif /* LOAD_TIF */ diff --git a/contrib/sdk/sources/SDL-1.2.2/SDL_image/IMG_xcf.c b/contrib/sdk/sources/SDL-1.2.2/SDL_image/IMG_xcf.c new file mode 100644 index 000000000..541e7dc22 --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/SDL_image/IMG_xcf.c @@ -0,0 +1,796 @@ +/* + IMGLIB: An example image loading library for use with SDL + Copyright (C) 1999 Sam Lantinga + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the Free + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + Sam Lantinga + 5635-34 Springhouse Dr. + Pleasanton, CA 94588 (USA) + slouken@devolution.com + + XCF support by Bernhard J. Pietsch +*/ + +/* This is a XCF image file loading framework */ + +#include +#include +#include + +#include "SDL_image.h" + +#ifdef LOAD_XCF + +static char prop_names [][30] = { + "end", + "colormap", + "active_layer", + "active_channel", + "selection", + "floating_selection", + "opacity", + "mode", + "visible", + "linked", + "preserve_transparency", + "apply_mask", + "edit_mask", + "show_mask", + "show_masked", + "offsets", + "color", + "compression", + "guides", + "resolution", + "tattoo", + "parasites", + "unit", + "paths", + "user_unit" +}; + +typedef enum +{ + PROP_END = 0, + PROP_COLORMAP = 1, + PROP_ACTIVE_LAYER = 2, + PROP_ACTIVE_CHANNEL = 3, + PROP_SELECTION = 4, + PROP_FLOATING_SELECTION = 5, + PROP_OPACITY = 6, + PROP_MODE = 7, + PROP_VISIBLE = 8, + PROP_LINKED = 9, + PROP_PRESERVE_TRANSPARENCY = 10, + PROP_APPLY_MASK = 11, + PROP_EDIT_MASK = 12, + PROP_SHOW_MASK = 13, + PROP_SHOW_MASKED = 14, + PROP_OFFSETS = 15, + PROP_COLOR = 16, + PROP_COMPRESSION = 17, + PROP_GUIDES = 18, + PROP_RESOLUTION = 19, + PROP_TATTOO = 20, + PROP_PARASITES = 21, + PROP_UNIT = 22, + PROP_PATHS = 23, + PROP_USER_UNIT = 24 +} xcf_prop_type; + +typedef enum { + COMPR_NONE = 0, + COMPR_RLE = 1, + COMPR_ZLIB = 2, + COMPR_FRACTAL = 3 +} xcf_compr_type; + +typedef enum { + IMAGE_RGB = 0, + IMAGE_GREYSCALE = 1, + IMAGE_INDEXED = 2 +} xcf_image_type; + +typedef struct { + Uint32 id; + Uint32 length; + union { + struct { + Uint32 num; + char * cmap; + } colormap; // 1 + struct { + Uint32 drawable_offset; + } floating_selection; // 5 + Sint32 opacity; + Sint32 mode; + int visible; + int linked; + int preserve_transparency; + int apply_mask; + int show_mask; + struct { + Sint32 x; + Sint32 y; + } offset; + unsigned char color [3]; + Uint8 compression; + struct { + Sint32 x; + Sint32 y; + } resolution; + struct { + char * name; + Uint32 flags; + Uint32 size; + char * data; + } parasite; + } data; +} xcf_prop; + +typedef struct { + char sign [14]; + Uint32 width; + Uint32 height; + Sint32 image_type; + xcf_prop * properties; + + Uint32 * layer_file_offsets; + Uint32 * channel_file_offsets; + + xcf_compr_type compr; + Uint32 cm_num; + unsigned char * cm_map; +} xcf_header; + +typedef struct { + Uint32 width; + Uint32 height; + Sint32 layer_type; + char * name; + xcf_prop * properties; + + Uint32 hierarchy_file_offset; + Uint32 layer_mask_offset; + + Uint32 offset_x; + Uint32 offset_y; +} xcf_layer; + +typedef struct { + Uint32 width; + Uint32 height; + char * name; + xcf_prop * properties; + + Uint32 hierarchy_file_offset; + + Uint32 color; + Uint32 opacity; + int selection : 1; +} xcf_channel; + +typedef struct { + Uint32 width; + Uint32 height; + Uint32 bpp; + + Uint32 * level_file_offsets; +} xcf_hierarchy; + +typedef struct { + Uint32 width; + Uint32 height; + + Uint32 * tile_file_offsets; +} xcf_level; + +typedef unsigned char * xcf_tile; + +typedef unsigned char * (* load_tile_type) (SDL_RWops *, Uint32, int, int, int); + + +/* See if an image is contained in a data source */ +int IMG_isXCF(SDL_RWops *src) { + int is_XCF; + char magic[14]; + + is_XCF = 0; + if ( SDL_RWread(src, magic, 14, 1) ) { + if (strncmp(magic, "gimp xcf ", 9) == 0) { + is_XCF = 1; + } + } + + return(is_XCF); +} + +static char * read_string (SDL_RWops * src) { + Uint32 tmp; + char * data; + + tmp = SDL_ReadBE32 (src); + if (tmp > 0) { + data = (char *) malloc (sizeof (char) * tmp); + SDL_RWread (src, data, tmp, 1); + } + else { + data = NULL; + } + + return data; +} + + +static Uint32 Swap32 (Uint32 v) { + return + ((v & 0x000000FF) << 16) + | ((v & 0x0000FF00)) + | ((v & 0x00FF0000) >> 16) + | ((v & 0xFF000000)); +} + +void xcf_read_property (SDL_RWops * src, xcf_prop * prop) { + prop->id = SDL_ReadBE32 (src); + prop->length = SDL_ReadBE32 (src); + + printf ("%.8X: %s: %d\n", SDL_RWtell (src), prop->id < 25 ? prop_names [prop->id] : "unknown", prop->length); + + switch (prop->id) { + case PROP_COLORMAP: + prop->data.colormap.num = SDL_ReadBE32 (src); + prop->data.colormap.cmap = (char *) malloc (sizeof (char) * prop->data.colormap.num * 3); + SDL_RWread (src, prop->data.colormap.cmap, prop->data.colormap.num*3, 1); + break; + + case PROP_OFFSETS: + prop->data.offset.x = SDL_ReadBE32 (src); + prop->data.offset.y = SDL_ReadBE32 (src); + break; + case PROP_OPACITY: + prop->data.opacity = SDL_ReadBE32 (src); + break; + case PROP_COMPRESSION: + case PROP_COLOR: + SDL_RWread (src, &prop->data, prop->length, 1); + break; + default: + // SDL_RWread (src, &prop->data, prop->length, 1); + SDL_RWseek (src, prop->length, SEEK_CUR); + } +} + +void free_xcf_header (xcf_header * h) { + if (h->cm_num) + free (h->cm_map); + + free (h); +} + +xcf_header * read_xcf_header (SDL_RWops * src) { + xcf_header * h; + xcf_prop prop; + + h = (xcf_header *) malloc (sizeof (xcf_header)); + SDL_RWread (src, h->sign, 14, 1); + h->width = SDL_ReadBE32 (src); + h->height = SDL_ReadBE32 (src); + h->image_type = SDL_ReadBE32 (src); + + h->properties = NULL; + h->compr = COMPR_NONE; + h->cm_num = 0; + h->cm_map = NULL; + + // Just read, don't save + do { + xcf_read_property (src, &prop); + if (prop.id == PROP_COMPRESSION) + h->compr = prop.data.compression; + else if (prop.id == PROP_COLORMAP) { + int i; + + h->cm_num = prop.data.colormap.num; + h->cm_map = (char *) malloc (sizeof (char) * 3 * h->cm_num); + memcpy (h->cm_map, prop.data.colormap.cmap, 3*sizeof (char)*h->cm_num); + free (prop.data.colormap.cmap); + } + } while (prop.id != PROP_END); + + return h; +} + +void free_xcf_layer (xcf_layer * l) { + free (l->name); + free (l); +} + +xcf_layer * read_xcf_layer (SDL_RWops * src) { + xcf_layer * l; + xcf_prop prop; + + l = (xcf_layer *) malloc (sizeof (xcf_layer)); + l->width = SDL_ReadBE32 (src); + l->height = SDL_ReadBE32 (src); + l->layer_type = SDL_ReadBE32 (src); + + l->name = read_string (src); + + do { + xcf_read_property (src, &prop); + if (prop.id == PROP_OFFSETS) { + l->offset_x = prop.data.offset.x; + l->offset_y = prop.data.offset.y; + } + } while (prop.id != PROP_END); + + l->hierarchy_file_offset = SDL_ReadBE32 (src); + l->layer_mask_offset = SDL_ReadBE32 (src); + + return l; +} + +void free_xcf_channel (xcf_channel * c) { + free (c->name); + free (c); +} + +xcf_channel * read_xcf_channel (SDL_RWops * src) { + xcf_channel * l; + xcf_prop prop; + + l = (xcf_channel *) malloc (sizeof (xcf_channel)); + l->width = SDL_ReadBE32 (src); + l->height = SDL_ReadBE32 (src); + + l->name = read_string (src); + + l->selection = 0; + do { + xcf_read_property (src, &prop); + switch (prop.id) { + case PROP_OPACITY: + l->opacity = prop.data.opacity << 24; + break; + case PROP_COLOR: + l->color = ((Uint32) prop.data.color[0] << 16) + | ((Uint32) prop.data.color[1] << 8) + | ((Uint32) prop.data.color[2]); + break; + case PROP_SELECTION: + l->selection = 1; + break; + default: + } + } while (prop.id != PROP_END); + + l->hierarchy_file_offset = SDL_ReadBE32 (src); + + return l; +} + +void free_xcf_hierarchy (xcf_hierarchy * h) { + free (h->level_file_offsets); + free (h); +} + +xcf_hierarchy * read_xcf_hierarchy (SDL_RWops * src) { + xcf_hierarchy * h; + int i; + + h = (xcf_hierarchy *) malloc (sizeof (xcf_hierarchy)); + h->width = SDL_ReadBE32 (src); + h->height = SDL_ReadBE32 (src); + h->bpp = SDL_ReadBE32 (src); + + h->level_file_offsets = NULL; + i = 0; + do { + h->level_file_offsets = (Uint32 *) realloc (h->level_file_offsets, sizeof (Uint32) * (i+1)); + h->level_file_offsets [i] = SDL_ReadBE32 (src); + } while (h->level_file_offsets [i++]); + + return h; +} + +void free_xcf_level (xcf_level * l) { + free (l->tile_file_offsets); + free (l); +} + +xcf_level * read_xcf_level (SDL_RWops * src) { + xcf_level * l; + int i; + + l = (xcf_level *) malloc (sizeof (xcf_level)); + l->width = SDL_ReadBE32 (src); + l->height = SDL_ReadBE32 (src); + + l->tile_file_offsets = NULL; + i = 0; + do { + l->tile_file_offsets = (Uint32 *) realloc (l->tile_file_offsets, sizeof (Uint32) * (i+1)); + l->tile_file_offsets [i] = SDL_ReadBE32 (src); + } while (l->tile_file_offsets [i++]); + + return l; +} + +void free_xcf_tile (unsigned char * t) { + free (t); +} + +unsigned char * load_xcf_tile_none (SDL_RWops * src, Uint32 len, int bpp, int x, int y) { + unsigned char * load; + + load = (char *) malloc (len); // expect this is okay + SDL_RWread (src, load, len, 1); + + return load; +} + +unsigned char * load_xcf_tile_rle (SDL_RWops * src, Uint32 len, int bpp, int x, int y) { + unsigned char * load, * t, * data, * d; + Uint32 reallen; + int i, size, count, j, length; + unsigned char val; + + t = load = (char *) malloc (len); + reallen = SDL_RWread (src, t, 1, len); + + data = (char *) malloc (x*y*bpp); + for (i = 0; i < bpp; i++) { + d = data + i; + size = x*y; + count = 0; + + while (size > 0) { + val = *t++; + + length = val; + if (length >= 128) { + length = 255 - (length - 1); + if (length == 128) { + length = (*t << 8) + t[1]; + t += 2; + } + + count += length; + size -= length; + + while (length-- > 0) { + *d = *t++; + d += bpp; + } + } + else { + length += 1; + if (length == 128) { + length = (*t << 8) + t[1]; + t += 2; + } + + count += length; + size -= length; + + val = *t++; + + for (j = 0; j < length; j++) { + *d = val; + d += bpp; + } + } + } + } + + free (load); + return (data); +} + +static Uint32 rgb2grey (Uint32 a) { + Uint8 l; + l = 0.2990 * ((a && 0x00FF0000) >> 16) + + 0.5870 * ((a && 0x0000FF00) >> 8) + + 0.1140 * ((a && 0x000000FF)); + + return (l << 16) | (l << 8) | l; +} + +void create_channel_surface (SDL_Surface * surf, xcf_image_type itype, Uint32 color, Uint32 opacity) { + Uint32 c; + + switch (itype) { + case IMAGE_RGB: + case IMAGE_INDEXED: + c = opacity | color; + break; + case IMAGE_GREYSCALE: + c = opacity | rgb2grey (color); + break; + } + SDL_FillRect (surf, NULL, c); +} + +int do_layer_surface (SDL_Surface * surface, SDL_RWops * src, xcf_header * head, xcf_layer * layer, load_tile_type load_tile) { + xcf_hierarchy * hierarchy; + xcf_level * level; + unsigned char * tile; + Uint8 * p8; + Uint16 * p16; + Uint32 * p; + int x, y, tx, ty, ox, oy, width, height, i, j; + Uint32 *row; + + SDL_RWseek (src, layer->hierarchy_file_offset, SEEK_SET); + hierarchy = read_xcf_hierarchy (src); + + level = NULL; + for (i = 0; hierarchy->level_file_offsets [i]; i++) { + SDL_RWseek (src, hierarchy->level_file_offsets [i], SEEK_SET); + level = read_xcf_level (src); + + ty = tx = 0; + for (j = 0; level->tile_file_offsets [j]; j++) { + SDL_RWseek (src, level->tile_file_offsets [j], SEEK_SET); + ox = tx+64 > level->width ? level->width % 64 : 64; + oy = ty+64 > level->height ? level->height % 64 : 64; + + if (level->tile_file_offsets [j+1]) { + tile = load_tile + (src, + level->tile_file_offsets [j+1] - level->tile_file_offsets [j], + hierarchy->bpp, + ox, oy); + } + else { + tile = load_tile + (src, + ox*oy*6, + hierarchy->bpp, + ox, oy); + } + + p8 = tile; + p16 = (Uint16 *) p8; + p = (Uint32 *) p8; + for (y=ty; y < ty+oy; y++) { + row = (Uint32 *)((Uint8 *)surface->pixels + y*surface->pitch + tx*4); + switch (hierarchy->bpp) { + case 4: + for (x=tx; x < tx+ox; x++) + *row++ = Swap32 (*p++); + break; + case 3: + for (x=tx; x < tx+ox; x++) { + *row = 0xFF000000; + *row |= ((Uint32) *(p8++) << 16); + *row |= ((Uint32) *(p8++) << 8); + *row |= ((Uint32) *(p8++) << 0); + row++; + } + break; + case 2: // Indexed/Greyscale + Alpha + switch (head->image_type) { + case IMAGE_INDEXED: + for (x=tx; x < tx+ox; x++) { + *row = ((Uint32) (head->cm_map [*p8*3]) << 16); + *row |= ((Uint32) (head->cm_map [*p8*3+1]) << 8); + *row |= ((Uint32) (head->cm_map [*p8++*3+2]) << 0); + *row |= ((Uint32) *p8++ << 24);; + row++; + } + break; + case IMAGE_GREYSCALE: + for (x=tx; x < tx+ox; x++) { + *row = ((Uint32) *p8 << 16); + *row |= ((Uint32) *p8 << 8); + *row |= ((Uint32) *p8++ << 0); + *row |= ((Uint32) *p8++ << 24);; + row++; + } + break; + default: + fprintf (stderr, "Unknown Gimp image type (%d)\n", head->image_type); + return 1; + } + break; + case 1: // Indexed/Greyscale + switch (head->image_type) { + case IMAGE_INDEXED: + for (x = tx; x < tx+ox; x++) { + *row++ = 0xFF000000 + | ((Uint32) (head->cm_map [*p8*3]) << 16) + | ((Uint32) (head->cm_map [*p8*3+1]) << 8) + | ((Uint32) (head->cm_map [*p8*3+2]) << 0); + p8++; + } + break; + case IMAGE_GREYSCALE: + for (x=tx; x < tx+ox; x++) { + *row++ = 0xFF000000 + | (((Uint32) (*p8)) << 16) + | (((Uint32) (*p8)) << 8) + | (((Uint32) (*p8++)) << 0); + } + break; + default: + fprintf (stderr, "Unknown Gimp image type (%d)\n", head->image_type); + return 1; + } + break; + } + } + tx += 64; + if (tx >= level->width) { + tx = 0; + ty += 64; + } + if (ty >= level->height) { + break; + } + + free_xcf_tile (tile); + } + free_xcf_level (level); + } + + free_xcf_hierarchy (hierarchy); +} + +SDL_Surface *IMG_LoadXCF_RW(SDL_RWops *src) { + SDL_Surface *surface, *lays; + xcf_header * head; + xcf_layer * layer; + xcf_channel ** channel; + int read_error, chnls, i, offsets; + Uint32 offset, fp; + + unsigned char * (* load_tile) (SDL_RWops *, Uint32, int, int, int); + + /* Initialize the data we will clean up when we're done */ + surface = NULL; + read_error = 0; + + /* Check to make sure we have something to do */ + if ( ! src ) { + goto done; + } + + head = read_xcf_header (src); + + switch (head->compr) { + case COMPR_NONE: + load_tile = load_xcf_tile_none; + break; + case COMPR_RLE: + load_tile = load_xcf_tile_rle; + break; + default: + fprintf (stderr, "Unsupported Compression.\n"); + free_xcf_header (head); + return NULL; + } + + /* Create the surface of the appropriate type */ + surface = SDL_AllocSurface(SDL_SWSURFACE, head->width, head->height, 32, + 0x00FF0000,0x0000FF00,0x000000FF,0xFF000000); + + if ( surface == NULL ) { + IMG_SetError("Out of memory"); + goto done; + } + + head->layer_file_offsets = NULL; + offsets = 0; + + while (offset = SDL_ReadBE32 (src)) { + head->layer_file_offsets = (Uint32 *) realloc (head->layer_file_offsets, sizeof (Uint32) * (offsets+1)); + head->layer_file_offsets [offsets] = offset; + offsets++; + } + fp = SDL_RWtell (src); + + lays = SDL_AllocSurface(SDL_SWSURFACE, head->width, head->height, 32, + 0x00FF0000,0x0000FF00,0x000000FF,0xFF000000); + + if ( lays == NULL ) { + IMG_SetError("Out of memory"); + goto done; + } + + // Blit layers backwards, because Gimp saves them highest first + for (i = offsets; i > 0; i--) { + SDL_Rect rs, rd; + SDL_RWseek (src, head->layer_file_offsets [i-1], SEEK_SET); + + layer = read_xcf_layer (src); + do_layer_surface (lays, src, head, layer, load_tile); + rs.x = 0; + rs.y = 0; + rs.w = layer->width; + rs.h = layer->height; + rd.x = layer->offset_x; + rd.y = layer->offset_y; + rd.w = layer->width; + rd.h = layer->height; + free_xcf_layer (layer); + + SDL_BlitSurface (lays, &rs, surface, &rd); + } + + SDL_FreeSurface (lays); + + SDL_RWseek (src, fp, SEEK_SET); + + // read channels + channel = NULL; + chnls = 0; + while (offset = SDL_ReadBE32 (src)) { + channel = (xcf_channel **) realloc (channel, sizeof (xcf_channel *) * (chnls+1)); + fp = SDL_RWtell (src); + SDL_RWseek (src, offset, SEEK_SET); + channel [chnls++] = (read_xcf_channel (src)); + SDL_RWseek (src, fp, SEEK_SET); + } + + if (chnls) { + SDL_Surface * chs; + + chs = SDL_AllocSurface(SDL_SWSURFACE, head->width, head->height, 32, + 0x00FF0000,0x0000FF00,0x000000FF,0xFF000000); + + if (chs == NULL) { + IMG_SetError("Out of memory"); + goto done; + } + for (i = 0; i < chnls; i++) { + // printf ("CNLBLT %i\n", i); + if (!channel [i]->selection) { + create_channel_surface (chs, head->image_type, channel [i]->color, channel [i]->opacity); + SDL_BlitSurface (chs, NULL, surface, NULL); + } + free_xcf_channel (channel [i]); + } + + SDL_FreeSurface (chs); + } + + done: + free_xcf_header (head); + if ( read_error ) { + SDL_FreeSurface(surface); + IMG_SetError("Error reading XCF data"); + surface = NULL; + } + + return(surface); +} + +#else + +/* See if an image is contained in a data source */ +int IMG_isXCF(SDL_RWops *src) +{ + return(0); +} + +/* Load a XCF type image from an SDL datasource */ +SDL_Surface *IMG_LoadXCF_RW(SDL_RWops *src) +{ + return(NULL); +} + +#endif /* LOAD_XCF */ diff --git a/contrib/sdk/sources/SDL-1.2.2/SDL_image/IMG_xpm.c b/contrib/sdk/sources/SDL-1.2.2/SDL_image/IMG_xpm.c new file mode 100644 index 000000000..de4e25431 --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/SDL_image/IMG_xpm.c @@ -0,0 +1,462 @@ +/* + IMGLIB: An example image loading library for use with SDL + Copyright (C) 1999 Sam Lantinga + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the Free + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + Sam Lantinga + 5635-34 Springhouse Dr. + Pleasanton, CA 94588 (USA) + slouken@devolution.com +*/ + +/* This is an XPM image file loading framework */ + +#include +#include +#include +#include + +#include "SDL_image.h" + +#ifdef LOAD_XPM + +/* See if an image is contained in a data source */ +int IMG_isXPM(SDL_RWops *src) +{ + int is_XPM; + char magic[10]; + + is_XPM = 0; + if ( SDL_RWread(src, magic, sizeof(magic), 1) ) { + if(memcmp(magic, "/* XPM */", 9) == 0) { + is_XPM = 1; + } + } + return(is_XPM); +} + +static char *SDL_RWgets(char *string, int maxlen, SDL_RWops *src) +{ + int i; + + for ( i=0; i<(maxlen-1); ++i ) { + if ( SDL_RWread(src, &string[i], 1, 1) <= 0 ) { + /* EOF or error */ + if ( i == 0 ) { + /* Hmm, EOF on initial read, return NULL */ + return NULL; + } + break; + } + /* In this case it's okay to use either '\r' or '\n' + as line separators because blank lines are just + ignored by the XPM format. + */ + if ( (string[i] == '\n') || (string[i] == '\r') ) { + break; + } + } + string[i] = '\0'; + return(string); +} + +/* Hash table to look up colors from pixel strings */ +#define STARTING_HASH_SIZE 256 + +struct hash_entry { + char *key; + Uint32 color; + struct hash_entry *next; +}; + +struct color_hash { + struct hash_entry **table; + struct hash_entry *entries; /* array of all entries */ + struct hash_entry *next_free; + int size; + int maxnum; +}; + +static int hash_key(const char *key, int cpp, int size) +{ + int hash; + + hash = 0; + while ( cpp-- > 0 ) { + hash = hash * 33 + *key++; + } + return hash & (size - 1); +} + +static struct color_hash *create_colorhash(int maxnum) +{ + int bytes, s; + struct color_hash *hash; + + /* we know how many entries we need, so we can allocate + everything here */ + hash = malloc(sizeof *hash); + if(!hash) + return NULL; + + /* use power-of-2 sized hash table for decoding speed */ + for(s = STARTING_HASH_SIZE; s < maxnum; s <<= 1) + ; + hash->size = s; + hash->maxnum = maxnum; + bytes = hash->size * sizeof(struct hash_entry **); + hash->entries = NULL; /* in case malloc fails */ + hash->table = malloc(bytes); + if(!hash->table) + return NULL; + memset(hash->table, 0, bytes); + hash->entries = malloc(maxnum * sizeof(struct hash_entry)); + if(!hash->entries) + return NULL; + hash->next_free = hash->entries; + return hash; +} + +static int add_colorhash(struct color_hash *hash, + char *key, int cpp, Uint32 color) +{ + int index = hash_key(key, cpp, hash->size); + struct hash_entry *e = hash->next_free++; + e->color = color; + e->key = key; + e->next = hash->table[index]; + hash->table[index] = e; + return 1; +} + +/* fast lookup that works if cpp == 1 */ +#define QUICK_COLORHASH(hash, key) ((hash)->table[*(Uint8 *)(key)]->color) + +static Uint32 get_colorhash(struct color_hash *hash, const char *key, int cpp) +{ + struct hash_entry *entry = hash->table[hash_key(key, cpp, hash->size)]; + while(entry) { + if(memcmp(key, entry->key, cpp) == 0) + return entry->color; + entry = entry->next; + } + return 0; /* garbage in - garbage out */ +} + +static void free_colorhash(struct color_hash *hash) +{ + if(hash && hash->table) { + free(hash->table); + free(hash->entries); + free(hash); + } +} + +#define ARRAYSIZE(a) (int)(sizeof(a) / sizeof((a)[0])) + +/* + * convert colour spec to RGB (in 0xrrggbb format). + * return 1 if successful. may scribble on the colorspec buffer. + */ +static int color_to_rgb(char *spec, Uint32 *rgb) +{ + /* poor man's rgb.txt */ + static struct { char *name; Uint32 rgb; } known[] = { + {"none", 0xffffffff}, + {"black", 0x00000000}, + {"white", 0x00ffffff}, + {"red", 0x00ff0000}, + {"green", 0x0000ff00}, + {"blue", 0x000000ff} + }; + + if(spec[0] == '#') { + char buf[7]; + ++spec; + switch(strlen(spec)) { + case 3: + buf[0] = buf[1] = spec[0]; + buf[2] = buf[3] = spec[1]; + buf[4] = buf[5] = spec[2]; + break; + case 6: + memcpy(buf, spec, 6); + break; + case 12: + buf[0] = spec[0]; + buf[1] = spec[1]; + buf[2] = spec[4]; + buf[3] = spec[5]; + buf[4] = spec[8]; + buf[5] = spec[9]; + break; + } + buf[6] = '\0'; + *rgb = strtol(buf, NULL, 16); + return 1; + } else { + int i; + for(i = 0; i < ARRAYSIZE(known); i++) + if(IMG_string_equals(known[i].name, spec)) { + *rgb = known[i].rgb; + return 1; + } + return 0; + } +} + +static char *skipspace(char *p) +{ + while(isspace((unsigned char)*p)) + ++p; + return p; +} + +static char *skipnonspace(char *p) +{ + while(!isspace((unsigned char)*p) && *p) + ++p; + return p; +} + +#ifndef MAX +#define MAX(a, b) ((a) > (b) ? (a) : (b)) +#endif + +/* Load a XPM type image from an SDL datasource */ +SDL_Surface *IMG_LoadXPM_RW(SDL_RWops *src) +{ + SDL_Surface *image; + char line[1024]; + char *here; + int index; + int x, y; + int w, h, ncolors, cpp; + int pixels_len; + char *pixels = NULL; + int indexed; + Uint8 *dst; + struct color_hash *colors; + SDL_Color *im_colors = NULL; + char *keystrings, *nextkey; + char *error = NULL; + + /* Skip to the first string, which describes the image */ + do { + here = SDL_RWgets(line, sizeof(line), src); + if ( !here ) { + IMG_SetError("Premature end of data"); + return(NULL); + } + here = skipspace(here); + } while(*here != '"'); + /* + * The header string of an XPMv3 image has the format + * + * [ ] + * + * where the hotspot coords are intended for mouse cursors. + * Right now we don't use the hotspots but it should be handled + * one day. + */ + if(sscanf(here + 1, "%d %d %d %d", &w, &h, &ncolors, &cpp) != 4 + || w <= 0 || h <= 0 || ncolors <= 0 || cpp <= 0) { + IMG_SetError("Invalid format description"); + return(NULL); + } + + keystrings = malloc(ncolors * cpp); + if(!keystrings) { + IMG_SetError("Out of memory"); + free(pixels); + return NULL; + } + nextkey = keystrings; + + /* Create the new surface */ + if(ncolors <= 256) { + indexed = 1; + image = SDL_CreateRGBSurface(SDL_SWSURFACE, w, h, 8, + 0, 0, 0, 0); + im_colors = image->format->palette->colors; + image->format->palette->ncolors = ncolors; + } else { + indexed = 0; + image = SDL_CreateRGBSurface(SDL_SWSURFACE, w, h, 32, + 0xff0000, 0x00ff00, 0x0000ff, 0); + } + if(!image) { + /* Hmm, some SDL error (out of memory?) */ + free(pixels); + return(NULL); + } + + /* Read the colors */ + colors = create_colorhash(ncolors); + if ( ! colors ) { + error = "Out of memory"; + goto done; + } + for(index = 0; index < ncolors; ++index ) { + char *key; + int len; + + do { + here = SDL_RWgets(line, sizeof(line), src); + if(!here) { + error = "Premature end of data"; + goto done; + } + here = skipspace(here); + } while(*here != '"'); + + ++here; + len = strlen(here); + if(len < cpp + 7) + continue; /* cannot be a valid line */ + + key = here; + key[cpp] = '\0'; + here += cpp + 1; + + /* parse a colour definition */ + for(;;) { + char nametype; + char *colname; + char delim; + Uint32 rgb; + + here = skipspace(here); + nametype = *here; + here = skipnonspace(here); + here = skipspace(here); + colname = here; + while(*here && !isspace((unsigned char)*here) + && *here != '"') + here++; + if(!*here) { + error = "color parse error"; + goto done; + } + if(nametype == 's') + continue; /* skip symbolic colour names */ + + delim = *here; + *here = '\0'; + if(delim) + here++; + + if(!color_to_rgb(colname, &rgb)) + continue; + + memcpy(nextkey, key, cpp); + if(indexed) { + SDL_Color *c = im_colors + index; + c->r = rgb >> 16; + c->g = rgb >> 8; + c->b = rgb; + add_colorhash(colors, nextkey, cpp, index); + } else + add_colorhash(colors, nextkey, cpp, rgb); + nextkey += cpp; + if(rgb == 0xffffffff) + SDL_SetColorKey(image, SDL_SRCCOLORKEY, + indexed ? index : rgb); + break; + } + } + + /* Read the pixels */ + pixels_len = w * cpp; + pixels = malloc(MAX(pixels_len + 5, 20)); + if(!pixels) { + error = "Out of memory"; + goto done; + } + dst = image->pixels; + for (y = 0; y < h; ) { + char *s; + char c; + do { + if(SDL_RWread(src, &c, 1, 1) <= 0) { + error = "Premature end of data"; + goto done; + } + } while(c == ' '); + if(c != '"') { + /* comment or empty line, skip it */ + while(c != '\n' && c != '\r') { + if(SDL_RWread(src, &c, 1, 1) <= 0) { + error = "Premature end of data"; + goto done; + } + } + continue; + } + if(SDL_RWread(src, pixels, pixels_len + 3, 1) <= 0) { + error = "Premature end of data"; + goto done; + } + s = pixels; + if(indexed) { + /* optimization for some common cases */ + if(cpp == 1) + for(x = 0; x < w; x++) + dst[x] = QUICK_COLORHASH(colors, + s + x); + else + for(x = 0; x < w; x++) + dst[x] = get_colorhash(colors, + s + x * cpp, + cpp); + } else { + for (x = 0; x < w; x++) + ((Uint32*)dst)[x] = get_colorhash(colors, + s + x * cpp, + cpp); + } + dst += image->pitch; + y++; + } + +done: + if(error) { + if(image) + SDL_FreeSurface(image); + image = NULL; + IMG_SetError(error); + } + free(pixels); + free(keystrings); + free_colorhash(colors); + return(image); +} + +#else + +/* See if an image is contained in a data source */ +int IMG_isXPM(SDL_RWops *src) +{ + return(0); +} + +/* Load a XPM type image from an SDL datasource */ +SDL_Surface *IMG_LoadXPM_RW(SDL_RWops *src) +{ + return(NULL); +} + +#endif /* LOAD_XPM */ diff --git a/contrib/sdk/sources/SDL-1.2.2/SDL_image/Makefile b/contrib/sdk/sources/SDL-1.2.2/SDL_image/Makefile new file mode 100644 index 000000000..0cef7f0a2 --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/SDL_image/Makefile @@ -0,0 +1,7 @@ +OBJS = IMG_bmp.o IMG.o IMG_gif.o IMG_jpg.o IMG_pcx.o IMG_png.o IMG_pnm.o \ + IMG_tga.o IMG_tif.o IMG_xcf.o IMG_xpm.o +OUTFILE = ../lib/libSDL_image.a +CFLAGS = -I../include -D_REENTRANT -DLOAD_BMP -DLOAD_GIF -DLOAD_JPG \ + -DLOAD_PCX -DLOAD_PNG -DLOAD_PNM -DLOAD_TGA -DLOAD_XPM + +include $(MENUETDEV)/makefiles/Makefile_for_lib diff --git a/contrib/sdk/sources/SDL-1.2.2/SDL_image/SDL_image.h b/contrib/sdk/sources/SDL-1.2.2/SDL_image/SDL_image.h new file mode 100644 index 000000000..5b002bdfc --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/SDL_image/SDL_image.h @@ -0,0 +1,93 @@ +/* + IMGLIB: An example image loading library for use with SDL + Copyright (C) 1999 Sam Lantinga + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public 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 + + Sam Lantinga + 5635-34 Springhouse Dr. + Pleasanton, CA 94588 (USA) + slouken@devolution.com +*/ + +/* A simple library to load images of various formats as SDL surfaces */ + +#ifndef _IMG_h +#define _IMG_h + +#include "SDL.h" +#include "begin_code.h" + +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +extern "C" { +#endif + +/* Load an image from an SDL data source. + The 'type' may be one of: "BMP", "GIF", "PNG", etc. + + If the image format supports a transparent pixel, SDL will set the + colorkey for the surface. You can enable RLE acceleration on the + surface afterwards by calling: + SDL_SetColorKey(image, SDL_RLEACCEL, image->format->colorkey); + */ +extern DECLSPEC SDL_Surface *IMG_LoadTyped_RW(SDL_RWops *src, int freesrc, + char *type); +/* Convenience functions */ +extern DECLSPEC SDL_Surface *IMG_Load(const char *file); +extern DECLSPEC SDL_Surface *IMG_Load_RW(SDL_RWops *src, int freesrc); + +/* Invert the alpha of a surface for use with OpenGL + This function is now a no-op, and only provided for backwards compatibility. +*/ +extern DECLSPEC int IMG_InvertAlpha(int on); + +/* Functions to detect a file type, given a seekable source */ +extern DECLSPEC int IMG_isBMP(SDL_RWops *src); +extern DECLSPEC int IMG_isPNM(SDL_RWops *src); +extern DECLSPEC int IMG_isXPM(SDL_RWops *src); +extern DECLSPEC int IMG_isXCF(SDL_RWops *src); +extern DECLSPEC int IMG_isPCX(SDL_RWops *src); +extern DECLSPEC int IMG_isGIF(SDL_RWops *src); +extern DECLSPEC int IMG_isJPG(SDL_RWops *src); +extern DECLSPEC int IMG_isTIF(SDL_RWops *src); +extern DECLSPEC int IMG_isPNG(SDL_RWops *src); + +/* Individual loading functions */ +extern DECLSPEC SDL_Surface *IMG_LoadBMP_RW(SDL_RWops *src); +extern DECLSPEC SDL_Surface *IMG_LoadPNM_RW(SDL_RWops *src); +extern DECLSPEC SDL_Surface *IMG_LoadXPM_RW(SDL_RWops *src); +extern DECLSPEC SDL_Surface *IMG_LoadXCF_RW(SDL_RWops *src); +extern DECLSPEC SDL_Surface *IMG_LoadPCX_RW(SDL_RWops *src); +extern DECLSPEC SDL_Surface *IMG_LoadGIF_RW(SDL_RWops *src); +extern DECLSPEC SDL_Surface *IMG_LoadJPG_RW(SDL_RWops *src); +extern DECLSPEC SDL_Surface *IMG_LoadTIF_RW(SDL_RWops *src); +extern DECLSPEC SDL_Surface *IMG_LoadPNG_RW(SDL_RWops *src); +extern DECLSPEC SDL_Surface *IMG_LoadTGA_RW(SDL_RWops *src); + +/* We'll use SDL for reporting errors */ +#define IMG_SetError SDL_SetError +#define IMG_GetError SDL_GetError + +/* used internally, NOT an exported function */ +extern DECLSPEC int IMG_string_equals(const char *str1, const char *str2); + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +} +#endif +#include "close_code.h" + +#endif /* _IMG_h */ diff --git a/contrib/sdk/sources/SDL-1.2.2/SDL_image/test/Makefile b/contrib/sdk/sources/SDL-1.2.2/SDL_image/test/Makefile new file mode 100644 index 000000000..526f44618 --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/SDL_image/test/Makefile @@ -0,0 +1,6 @@ +OUTFILE = showimg +OBJS = showimage.o +LIBS = -L../../lib -lSDL -lSDL_image -lSDL -lpng -ljpeg -lz +CFLAGS = -I../../include -I.. + +include $(MENUETDEV)/makefiles/Makefile_for_program diff --git a/contrib/sdk/sources/SDL-1.2.2/SDL_image/test/showimage.c b/contrib/sdk/sources/SDL-1.2.2/SDL_image/test/showimage.c new file mode 100644 index 000000000..7e9c0fba5 --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/SDL_image/test/showimage.c @@ -0,0 +1,185 @@ +/* + SHOW: A test application for the SDL image loading library. + Copyright (C) 1999 Sam Lantinga + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public 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 + + Sam Lantinga + 5635-34 Springhouse Dr. + Pleasanton, CA 94588 (USA) + slouken@devolution.com +*/ + +#include +#include +#include + +#include "SDL.h" +#include "SDL_image.h" + + +/* Draw a Gimpish background pattern to show transparency in the image */ +void draw_background(SDL_Surface *screen) +{ + Uint8 *dst = screen->pixels; + int x, y; + int bpp = screen->format->BytesPerPixel; + Uint32 col[2]; + col[0] = SDL_MapRGB(screen->format, 0x66, 0x66, 0x66); + col[1] = SDL_MapRGB(screen->format, 0x99, 0x99, 0x99); + for(y = 0; y < screen->h; y++) { + for(x = 0; x < screen->w; x++) { + /* use an 8x8 checkerboard pattern */ + Uint32 c = col[((x ^ y) >> 3) & 1]; + switch(bpp) { + case 1: + dst[x] = c; + break; + case 2: + ((Uint16 *)dst)[x] = c; + break; + case 3: + if(SDL_BYTEORDER == SDL_LIL_ENDIAN) { + dst[x * 3] = c; + dst[x * 3 + 1] = c >> 8; + dst[x * 3 + 2] = c >> 16; + } else { + dst[x * 3] = c >> 16; + dst[x * 3 + 1] = c >> 8; + dst[x * 3 + 2] = c; + } + break; + case 4: + ((Uint32 *)dst)[x] = c; + break; + } + } + dst += screen->pitch; + } +} + +int app_main(int argc, char *argv[]) +{ + Uint32 flags; + SDL_Surface *screen, *image; + int i, depth, done; + SDL_Event event; + + argv[1]="../1/test.png"; + argc=2; + /* Initialize the SDL library */ + if ( SDL_Init(SDL_INIT_VIDEO) < 0 ) { + SDL_printf("Couldn't initialize SDL: %s\n",SDL_GetError()); + return(255); + } + + flags = SDL_SWSURFACE; + for ( i=1; iw, image->h, 32, flags); + /* Use the deepest native mode, except that we emulate 32bpp + for viewing non-indexed images on 8bpp screens */ + if ( depth == 0 ) { + if ( image->format->BytesPerPixel > 1 ) { + depth = 32; + } else { + depth = 8; + } + } else + if ( (image->format->BytesPerPixel > 1) && (depth == 8) ) { + depth = 32; + } + if(depth == 8) + flags |= SDL_HWPALETTE; + screen = SDL_SetVideoMode(image->w, image->h, depth, flags); + if ( screen == NULL ) { + SDL_printf("Couldn't set %dx%dx%d video mode: %s\n", + image->w, image->h, depth, SDL_GetError()); + continue; + } + + /* Set the palette, if one exists */ + if ( image->format->palette ) { + SDL_SetColors(screen, image->format->palette->colors, + 0, image->format->palette->ncolors); + } + + /* Draw a background pattern if the surface has transparency */ + if(image->flags & (SDL_SRCALPHA | SDL_SRCCOLORKEY)) + draw_background(screen); + + /* Display the image */ + SDL_BlitSurface(image, NULL, screen, NULL); + SDL_UpdateRect(screen, 0, 0, 0, 0); + + done = 0; + while ( ! done ) { + if ( SDL_PollEvent(&event) ) { + switch (event.type) { + case SDL_KEYUP: + switch (event.key.keysym.sym) { + case SDLK_LEFT: + if ( i > 1 ) { + i -= 2; + done = 1; + } + break; + case SDLK_RIGHT: + if ( argv[i+1] ) { + done = 1; + } + break; + case SDLK_ESCAPE: + case SDLK_q: + argv[i+1] = NULL; + /* Drop through to done */ + case SDLK_SPACE: + case SDLK_TAB: + done = 1; + break; + default: + break; + } + break; + case SDL_QUIT: + argv[i+1] = NULL; + done = 1; + break; + default: + break; + } + } else { + SDL_Delay(3); + } + } + SDL_FreeSurface(image); + } + + /* We're done! */ + SDL_Quit(); + return(0); +} diff --git a/contrib/sdk/sources/SDL-1.2.2/SDL_image/test/test.png b/contrib/sdk/sources/SDL-1.2.2/SDL_image/test/test.png new file mode 100644 index 000000000..e10803acd Binary files /dev/null and b/contrib/sdk/sources/SDL-1.2.2/SDL_image/test/test.png differ diff --git a/contrib/sdk/sources/SDL-1.2.2/SDL_ttf/CHANGES b/contrib/sdk/sources/SDL-1.2.2/SDL_ttf/CHANGES new file mode 100644 index 000000000..c1b9ec8b2 --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/SDL_ttf/CHANGES @@ -0,0 +1,51 @@ + +1.2.2: +Sam Lantinga - Tue Sep 26 15:04:04 PDT 2000 + * Added TTF_RenderGlyph_* functions to render a single glyph +Michael Vance - Tue Sep 12 12:20:03 PDT 2000 + * Added TTF_GetGlyphMetrics() to retrieve the glyph bounding box +Sam Lantinga - Tue Sep 12 07:15:34 PDT 2000 + * Fixed the alpha blending for SDL 1.1.5 +Michael Vance - Mon Sep 11 15:45:05 PDT 2000 + * Added TTF_FontAscent() for completeness +Ray Kelm - Fri, 04 Aug 2000 20:58:00 -0400 + * Added support for cross-compiling Windows DLL from Linux + +1.2.1: +Sam Lantinga - Wed May 10 19:54:56 PDT 2000 + * Fixed bounding box width computation +Sam Lantinga - Wed May 10 19:52:39 PDT 2000 + * Fixed compile problem with Visual C++ + * Don't allocate memory for zero sized glyphs (like space) +Sam Lantinga - Sat May 6 13:39:15 PDT 2000 + * Fixed bolding of large fonts + +1.2.0: +Sam Lantinga - Fri May 5 11:08:24 PDT 2000 + * Added support for font styles (bold, italic, underline) + New functions: TTF_GetFontStyle(), TTF_SetFontStyle() + +1.1.1: +Sam Lantinga - Thu May 4 02:19:36 PDT 2000 + * Improved the quality of the alpha blended text rendering +Sam Lantinga - Thu May 4 01:11:00 PDT 2000 + * Added font glyph caching, speeded up text rendering + * Added font attribute information. + New functions: TTF_FontDescent(), TTF_FontLineSkip() + +1.1.0: +Sam Lantinga - Tue Apr 25 22:36:41 PDT 2000 + * Added two new styles of font rendering: + solid colorkey (no dither) and alpha blended dithering + New functions: TTF_RenderText_Solid(), TTF_RenderText_Blended() + +1.0.2: +Sam Lantinga - Sun Apr 23 18:01:44 PDT 2000 + * TTF_OpenFont() takes a const char * argument, instead of char * + +1.0.1: +Sam Lantinga - Wed Jan 19 22:10:52 PST 2000 + * Added CHANGES + * Added rpm spec file contributed by Hakan Tandogan + * Removed freetype.h header dependency from public headers + * Added /usr/include/freetype/ directory detection to configure.in diff --git a/contrib/sdk/sources/SDL-1.2.2/SDL_ttf/COPYING b/contrib/sdk/sources/SDL-1.2.2/SDL_ttf/COPYING new file mode 100644 index 000000000..191a97fe9 --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/SDL_ttf/COPYING @@ -0,0 +1,437 @@ + GNU LIBRARY GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 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. + +[This is the first released version of the library GPL. It is + numbered 2 because it goes with version 2 of the ordinary GPL.] + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +Licenses are intended to guarantee your freedom to share and change +free software--to make sure the software is free for all its users. + + This license, the Library General Public License, applies to some +specially designated Free Software Foundation software, and to any +other libraries whose authors decide to use it. You can use it for +your libraries, 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 library, or if you modify it. + + For example, if you distribute copies of the library, whether gratis +or for a fee, you must give the recipients all the rights that we gave +you. You must make sure that they, too, receive or can get the source +code. If you link a program with the library, you must provide +complete object files to the recipients so that they can relink them +with the library, after making changes to the library and recompiling +it. And you must show them these terms so they know their rights. + + Our method of protecting your rights has two steps: (1) copyright +the library, and (2) offer you this license which gives you legal +permission to copy, distribute and/or modify the library. + + Also, for each distributor's protection, we want to make certain +that everyone understands that there is no warranty for this free +library. If the library is modified by someone else and passed on, we +want its recipients to know that what they have is not the original +version, 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 companies distributing free +software will individually obtain patent licenses, thus in effect +transforming the program into proprietary software. To prevent this, +we have made it clear that any patent must be licensed for everyone's +free use or not licensed at all. + + Most GNU software, including some libraries, is covered by the ordinary +GNU General Public License, which was designed for utility programs. This +license, the GNU Library General Public License, applies to certain +designated libraries. This license is quite different from the ordinary +one; be sure to read it in full, and don't assume that anything in it is +the same as in the ordinary license. + + The reason we have a separate public license for some libraries is that +they blur the distinction we usually make between modifying or adding to a +program and simply using it. Linking a program with a library, without +changing the library, is in some sense simply using the library, and is +analogous to running a utility program or application program. However, in +a textual and legal sense, the linked executable is a combined work, a +derivative of the original library, and the ordinary General Public License +treats it as such. + + Because of this blurred distinction, using the ordinary General +Public License for libraries did not effectively promote software +sharing, because most developers did not use the libraries. We +concluded that weaker conditions might promote sharing better. + + However, unrestricted linking of non-free programs would deprive the +users of those programs of all benefit from the free status of the +libraries themselves. This Library General Public License is intended to +permit developers of non-free programs to use free libraries, while +preserving your freedom as a user of such programs to change the free +libraries that are incorporated in them. (We have not seen how to achieve +this as regards changes in header files, but we have achieved it as regards +changes in the actual functions of the Library.) The hope is that this +will lead to faster development of free libraries. + + The precise terms and conditions for copying, distribution and +modification follow. Pay close attention to the difference between a +"work based on the library" and a "work that uses the library". The +former contains code derived from the library, while the latter only +works together with the library. + + Note that it is possible for a library to be covered by the ordinary +General Public License rather than by this special one. + + GNU LIBRARY GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License Agreement applies to any software library which +contains a notice placed by the copyright holder or other authorized +party saying it may be distributed under the terms of this Library +General Public License (also called "this License"). Each licensee is +addressed as "you". + + A "library" means a collection of software functions and/or data +prepared so as to be conveniently linked with application programs +(which use some of those functions and data) to form executables. + + The "Library", below, refers to any such software library or work +which has been distributed under these terms. A "work based on the +Library" means either the Library or any derivative work under +copyright law: that is to say, a work containing the Library or a +portion of it, either verbatim or with modifications and/or translated +straightforwardly into another language. (Hereinafter, translation is +included without limitation in the term "modification".) + + "Source code" for a work means the preferred form of the work for +making modifications to it. For a library, complete source code means +all the source code for all modules it contains, plus any associated +interface definition files, plus the scripts used to control compilation +and installation of the library. + + Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running a program using the Library is not restricted, and output from +such a program is covered only if its contents constitute a work based +on the Library (independent of the use of the Library in a tool for +writing it). Whether that is true depends on what the Library does +and what the program that uses the Library does. + + 1. You may copy and distribute verbatim copies of the Library's +complete source code as you receive it, in any medium, provided that +you conspicuously and appropriately publish on each copy an +appropriate copyright notice and disclaimer of warranty; keep intact +all the notices that refer to this License and to the absence of any +warranty; and distribute a copy of this License along with the +Library. + + You may charge a fee for the physical act of transferring a copy, +and you may at your option offer warranty protection in exchange for a +fee. + + 2. You may modify your copy or copies of the Library or any portion +of it, thus forming a work based on the Library, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) The modified work must itself be a software library. + + b) You must cause the files modified to carry prominent notices + stating that you changed the files and the date of any change. + + c) You must cause the whole of the work to be licensed at no + charge to all third parties under the terms of this License. + + d) If a facility in the modified Library refers to a function or a + table of data to be supplied by an application program that uses + the facility, other than as an argument passed when the facility + is invoked, then you must make a good faith effort to ensure that, + in the event an application does not supply such function or + table, the facility still operates, and performs whatever part of + its purpose remains meaningful. + + (For example, a function in a library to compute square roots has + a purpose that is entirely well-defined independent of the + application. Therefore, Subsection 2d requires that any + application-supplied function or table used by this function must + be optional: if the application does not supply it, the square + root function must still compute square roots.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Library, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Library, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote +it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Library. + +In addition, mere aggregation of another work not based on the Library +with the Library (or with a work based on the Library) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may opt to apply the terms of the ordinary GNU General Public +License instead of this License to a given copy of the Library. To do +this, you must alter all the notices that refer to this License, so +that they refer to the ordinary GNU General Public License, version 2, +instead of to this License. (If a newer version than version 2 of the +ordinary GNU General Public License has appeared, then you can specify +that version instead if you wish.) Do not make any other change in +these notices. + + Once this change is made in a given copy, it is irreversible for +that copy, so the ordinary GNU General Public License applies to all +subsequent copies and derivative works made from that copy. + + This option is useful when you wish to copy part of the code of +the Library into a program that is not a library. + + 4. You may copy and distribute the Library (or a portion or +derivative of it, under Section 2) in object code or executable form +under the terms of Sections 1 and 2 above provided that you accompany +it with the complete corresponding machine-readable source code, which +must be distributed under the terms of Sections 1 and 2 above on a +medium customarily used for software interchange. + + If distribution of object code is made by offering access to copy +from a designated place, then offering equivalent access to copy the +source code from the same place satisfies the requirement to +distribute the source code, even though third parties are not +compelled to copy the source along with the object code. + + 5. A program that contains no derivative of any portion of the +Library, but is designed to work with the Library by being compiled or +linked with it, is called a "work that uses the Library". Such a +work, in isolation, is not a derivative work of the Library, and +therefore falls outside the scope of this License. + + However, linking a "work that uses the Library" with the Library +creates an executable that is a derivative of the Library (because it +contains portions of the Library), rather than a "work that uses the +library". The executable is therefore covered by this License. +Section 6 states terms for distribution of such executables. + + When a "work that uses the Library" uses material from a header file +that is part of the Library, the object code for the work may be a +derivative work of the Library even though the source code is not. +Whether this is true is especially significant if the work can be +linked without the Library, or if the work is itself a library. The +threshold for this to be true is not precisely defined by law. + + If such an object file uses only numerical parameters, data +structure layouts and accessors, and small macros and small inline +functions (ten lines or less in length), then the use of the object +file is unrestricted, regardless of whether it is legally a derivative +work. (Executables containing this object code plus portions of the +Library will still fall under Section 6.) + + Otherwise, if the work is a derivative of the Library, you may +distribute the object code for the work under the terms of Section 6. +Any executables containing that work also fall under Section 6, +whether or not they are linked directly with the Library itself. + + 6. As an exception to the Sections above, you may also compile or +link a "work that uses the Library" with the Library to produce a +work containing portions of the Library, and distribute that work +under terms of your choice, provided that the terms permit +modification of the work for the customer's own use and reverse +engineering for debugging such modifications. + + You must give prominent notice with each copy of the work that the +Library is used in it and that the Library and its use are covered by +this License. You must supply a copy of this License. If the work +during execution displays copyright notices, you must include the +copyright notice for the Library among them, as well as a reference +directing the user to the copy of this License. Also, you must do one +of these things: + + a) Accompany the work with the complete corresponding + machine-readable source code for the Library including whatever + changes were used in the work (which must be distributed under + Sections 1 and 2 above); and, if the work is an executable linked + with the Library, with the complete machine-readable "work that + uses the Library", as object code and/or source code, so that the + user can modify the Library and then relink to produce a modified + executable containing the modified Library. (It is understood + that the user who changes the contents of definitions files in the + Library will not necessarily be able to recompile the application + to use the modified definitions.) + + b) Accompany the work with a written offer, valid for at + least three years, to give the same user the materials + specified in Subsection 6a, above, for a charge no more + than the cost of performing this distribution. + + c) If distribution of the work is made by offering access to copy + from a designated place, offer equivalent access to copy the above + specified materials from the same place. + + d) Verify that the user has already received a copy of these + materials or that you have already sent this user a copy. + + For an executable, the required form of the "work that uses the +Library" must include any data and utility programs needed for +reproducing the executable from it. However, as a special exception, +the 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. + + It may happen that this requirement contradicts the license +restrictions of other proprietary libraries that do not normally +accompany the operating system. Such a contradiction means you cannot +use both them and the Library together in an executable that you +distribute. + + 7. You may place library facilities that are a work based on the +Library side-by-side in a single library together with other library +facilities not covered by this License, and distribute such a combined +library, provided that the separate distribution of the work based on +the Library and of the other library facilities is otherwise +permitted, and provided that you do these two things: + + a) Accompany the combined library with a copy of the same work + based on the Library, uncombined with any other library + facilities. This must be distributed under the terms of the + Sections above. + + b) Give prominent notice with the combined library of the fact + that part of it is a work based on the Library, and explaining + where to find the accompanying uncombined form of the same work. + + 8. You may not copy, modify, sublicense, link with, or distribute +the Library except as expressly provided under this License. Any +attempt otherwise to copy, modify, sublicense, link with, or +distribute the Library is void, and will automatically terminate your +rights under this License. However, parties who have received copies, +or rights, from you under this License will not have their licenses +terminated so long as such parties remain in full compliance. + + 9. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Library or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Library (or any work based on the +Library), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Library or works based on it. + + 10. Each time you redistribute the Library (or any work based on the +Library), the recipient automatically receives a license from the +original licensor to copy, distribute, link with or modify the Library +subject to these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 11. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Library at all. For example, if a patent +license would not permit royalty-free redistribution of the Library by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Library. + +If any portion of this section is held invalid or unenforceable under any +particular circumstance, the balance of the section is intended to apply, +and the section as a whole is intended to apply in other circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 12. If the distribution and/or use of the Library is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Library under this License may add +an explicit geographical distribution limitation excluding those countries, +so that distribution is permitted only in or among countries not thus +excluded. In such case, this License incorporates the limitation as if +written in the body of this License. + + 13. The Free Software Foundation may publish revised and/or new +versions of the Library General Public License from time to time. +Such new versions will be similar in spirit to the present version, +but may differ in detail to address new problems or concerns. + +Each version is given a distinguishing version number. If the Library +specifies a version number of this License which applies to it and +"any later version", you have the option of following the terms and +conditions either of that version or of any later version published by +the Free Software Foundation. If the Library does not specify a +license version number, you may choose any version ever published by +the Free Software Foundation. + + 14. If you wish to incorporate parts of the Library into other free +programs whose distribution conditions are incompatible with these, +write to the author to ask for permission. For software which is +copyrighted by the Free Software Foundation, write to the Free +Software Foundation; we sometimes make exceptions for this. Our +decision will be guided by the two goals of preserving the free status +of all derivatives of our free software and of promoting the sharing +and reuse of software generally. + + NO WARRANTY + + 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO +WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. +EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR +OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY +KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE +LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME +THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN +WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY +AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU +FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR +CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE +LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING +RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A +FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF +SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH +DAMAGES. + + END OF TERMS AND CONDITIONS diff --git a/contrib/sdk/sources/SDL-1.2.2/SDL_ttf/Makefile b/contrib/sdk/sources/SDL-1.2.2/SDL_ttf/Makefile new file mode 100644 index 000000000..2ef74ae0c --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/SDL_ttf/Makefile @@ -0,0 +1,5 @@ +OUTFILE = ../lib/libSDL_ttf.a +OBJS = SDL_ttf.o +CFLAGS = -I../include + +include $(MENUETDEV)/makefiles/Makefile_for_lib diff --git a/contrib/sdk/sources/SDL-1.2.2/SDL_ttf/README b/contrib/sdk/sources/SDL-1.2.2/SDL_ttf/README new file mode 100644 index 000000000..9b19de3cc --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/SDL_ttf/README @@ -0,0 +1,27 @@ + +This library is a wrapper around the excellent FreeType 1.2 library, +available at: + http://www.freetype.org/ + +WARNING: There may be patent issues with using the FreeType library. +Check the FreeType website for up-to-date details. + +This library allows you to use TrueType fonts to render text in SDL +applications. + +To make the library, first install the FreeType library, then type +'make' to build the SDL truetype library and 'make all' to build +the demo application. + +Be careful when including fonts with your application, as many of them +are copyrighted. The Microsoft fonts, for example, are not freely +redistributable and even the free "web" fonts they provide are only +redistributable in their special executable installer form (May 1998). +There are plenty of freeware and shareware fonts available on the Internet +though, and may suit your purposes. + +Please see the file "COPYING" for license information for this library. + +Enjoy! + -Sam Lantinga (5/1/98) + diff --git a/contrib/sdk/sources/SDL-1.2.2/SDL_ttf/SDL_ttf.c b/contrib/sdk/sources/SDL-1.2.2/SDL_ttf/SDL_ttf.c new file mode 100644 index 000000000..854a52d3a --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/SDL_ttf/SDL_ttf.c @@ -0,0 +1,1193 @@ + +#include +#include +#include +#include +#include + +#include + +#include "SDL.h" +#include "SDL_ttf.h" + +/* Macro to convert a character to a Unicode value -- assume already Unicode */ +#define UNICODE(c) c + +/* Round a float up to the nearest integeter and return that integer */ +static int round(float x) +{ + int value; + + value = (int)x; + if ( x > value ) { + value = value + 1; + } else + if ( x < value ) { + value = value - 1; + } + return value; +} + +/* The structure used to hold glyph information (cached) */ +struct glyph { + int cached; + TT_Raster_Map bitmap; + TT_Raster_Map pixmap; + int minx; + int maxx; + int miny; + int maxy; + int advance; +}; + +/* The structure used to hold internal font information */ +struct _TTF_Font { + TT_Face face; + TT_Instance inst; + TT_Glyph glyph; + TT_CharMap map; + + /* Font metrics */ + int pointsize; + int height; /* ascent - descent */ + float ascent; + float descent; + float lineskip; + + /* The font style */ + int style; + + /* Extra width in glyph bounds for text styles */ + int glyph_overhang; + float glyph_italics; + + /* For now, support Latin-1 character set caching */ + struct glyph *current; + struct glyph cache[256]; + struct glyph scratch; +}; + +/* The FreeType font engine */ +static TT_Engine engine; + +int TTF_Init(void) +{ + int error; + + error = TT_Init_FreeType(&engine); + if ( error ) { + SDL_SetError("Couldn't init FreeType engine"); + return(-1); + } + return(0); +} + +TTF_Font *TTF_OpenFont(const char *file, int ptsize) +{ + TTF_Font *font; + TT_Face_Properties properties; + TT_Instance_Metrics imetrics; + int i, n; + TT_UShort platform, encoding; + TT_Error error; + + font = (TTF_Font *)malloc(sizeof(*font)); + if ( font == NULL ) { + SDL_SetError("Out of memory"); + return(NULL); + } + memset(font, 0, sizeof(*font)); + + /* Open the font and create ancillary data */ + error = TT_Open_Face(engine, file, &font->face); + if ( error ) { + SDL_SetError("Couldn't load font file"); + free(font); + return(NULL); + } + error = TT_New_Glyph(font->face, &font->glyph); + if ( error ) { + SDL_SetError("Couldn't create glyph container"); + TTF_CloseFont(font); + return(NULL); + } + error = TT_New_Instance(font->face, &font->inst); + if ( error ) { + SDL_SetError("Couldn't create font instance"); + TTF_CloseFont(font); + return(NULL); + } + + /* Set the display resolution */ + error = TT_Set_Instance_Resolutions(font->inst, 72, 72); + if ( error ) { + SDL_SetError("Couldn't set font resolution"); + TTF_CloseFont(font); + return(NULL); + } + error = TT_Set_Instance_CharSize(font->inst, ptsize*64); + if ( error ) { + SDL_SetError("Couldn't set font size"); + TTF_CloseFont(font); + return(NULL); + } + + /* Get a Unicode mapping for this font */ + n = TT_Get_CharMap_Count(font->face); + for ( i=0; iface, i, &platform, &encoding); + if ( ((platform == TT_PLATFORM_MICROSOFT) && + (encoding == TT_MS_ID_UNICODE_CS)) || + ((platform == TT_PLATFORM_APPLE_UNICODE) && + (encoding == TT_APPLE_ID_DEFAULT)) ) { + TT_Get_CharMap(font->face, i, &font->map); + break; + } + } + if ( i == n ) { + SDL_SetError("Font doesn't have a Unicode mapping"); + TTF_CloseFont(font); + return(NULL); + } + + /* Get the font metrics for this font */ + TT_Get_Face_Properties(font->face, &properties ); + TT_Get_Instance_Metrics(font->inst, &imetrics); + font->pointsize = imetrics.y_ppem; + font->ascent = (float)properties.horizontal->Ascender / + properties.header->Units_Per_EM; + font->ascent *= font->pointsize; + font->descent = (float)properties.horizontal->Descender / + properties.header->Units_Per_EM; + font->descent *= font->pointsize; + font->lineskip = (float)properties.horizontal->Line_Gap / + properties.header->Units_Per_EM; + font->lineskip *= font->pointsize; + font->height = round(font->ascent - font->descent); + + /* Set the default font style */ + font->style = TTF_STYLE_NORMAL; + font->glyph_overhang = font->pointsize/10; + /* x offset = cos(((90.0-12)/360)*2*M_PI), or 12 degree angle */ + font->glyph_italics = 0.207; + font->glyph_italics *= font->height; + + return(font); +} + +static void Flush_Glyph(struct glyph *glyph) +{ + if ( glyph->bitmap.bitmap ) { + free(glyph->bitmap.bitmap); + glyph->bitmap.bitmap = 0; + } + if ( glyph->pixmap.bitmap ) { + free(glyph->pixmap.bitmap); + glyph->pixmap.bitmap = 0; + } + glyph->cached = 0; +} + +static void Flush_Cache(TTF_Font *font) +{ + int i; + + for ( i=0; i<(sizeof font->cache)/(sizeof font->cache[0]); ++i ) { + if ( font->cache[i].cached ) { + Flush_Glyph(&font->cache[i]); + } + } + if ( font->scratch.cached ) { + Flush_Glyph(&font->scratch); + } +} + +static TT_Error Load_Glyph(TTF_Font *font, Uint16 ch, struct glyph *glyph) +{ + TT_UShort index; + TT_Glyph_Metrics metrics; + TT_Outline outline; + int x_offset; + int y_offset; + TT_Error error; + + /* Load the glyph */ + index = TT_Char_Index(font->map, UNICODE(ch)); + error = TT_Load_Glyph(font->inst, font->glyph, index, TTLOAD_DEFAULT); + if ( error ) return error; + + /* Get the bounding box */ + TT_Get_Glyph_Metrics(font->glyph, &metrics); + glyph->minx = (metrics.bbox.xMin & -64) / 64; + glyph->maxx = ((metrics.bbox.xMax + 63) & -64) / 64; + glyph->miny = (metrics.bbox.yMin & -64) / 64; + glyph->maxy = ((metrics.bbox.yMax + 63) & -64) / 64; + glyph->advance = (metrics.advance & -64) / 64; + + /* Adjust for bold and italic text */ + if ( font->style & TTF_STYLE_BOLD ) { + glyph->maxx += font->glyph_overhang; + } + if ( font->style & TTF_STYLE_ITALIC ) { + glyph->maxx += round(font->glyph_italics); + } + + /* Get the bitmap memory */ + glyph->bitmap.width = ((glyph->maxx - glyph->minx) + 7) & ~7; + glyph->bitmap.rows = font->height; + glyph->bitmap.cols = glyph->bitmap.width/8; + glyph->bitmap.flow = TT_Flow_Down; + glyph->bitmap.size = (glyph->bitmap.rows * glyph->bitmap.cols); + if ( glyph->bitmap.size ) { + glyph->bitmap.bitmap = malloc(glyph->bitmap.size); + if ( ! glyph->bitmap.bitmap ) { + error = TT_Err_Out_Of_Memory; + goto was_error; + } + memset(glyph->bitmap.bitmap, 0, glyph->bitmap.size); + } else { + glyph->bitmap.bitmap = 0; + } + + /* Get the pixmap memory */ + glyph->pixmap.width = ((glyph->maxx - glyph->minx) + 3) & ~3; + glyph->pixmap.rows = font->height; + glyph->pixmap.cols = glyph->pixmap.width; + glyph->pixmap.flow = TT_Flow_Down; + glyph->pixmap.size = (glyph->pixmap.rows * glyph->pixmap.cols); + if ( glyph->pixmap.size ) { + glyph->pixmap.bitmap = malloc(glyph->pixmap.size); + if ( ! glyph->pixmap.bitmap ) { + error = TT_Err_Out_Of_Memory; + goto was_error; + } + memset(glyph->pixmap.bitmap, 0, glyph->pixmap.size); + } else { + glyph->pixmap.bitmap = 0; + } + + /* Render the glyph into the bitmap and pixmap */ + error = TT_Get_Glyph_Outline(font->glyph, &outline); + /* Handle the italic style */ + if ( font->style & TTF_STYLE_ITALIC ) { + TT_Matrix shear; + + shear.xx = 1<<16; + shear.xy = (int)(font->glyph_italics*(1<<16))/font->height; + shear.yx = 0; + shear.yy = 1<<16; + TT_Transform_Outline(&outline, &shear); + } + x_offset = -glyph->minx * 64; + y_offset = -round(font->descent) * 64; + TT_Translate_Outline(&outline, x_offset, y_offset); + error += TT_Get_Outline_Bitmap(engine, &outline, &glyph->bitmap); + error += TT_Get_Outline_Pixmap(engine, &outline, &glyph->pixmap); + /* Handle the bold style */ + if ( font->style & TTF_STYLE_BOLD ) { + int row, col; + int offset; + int pixel; + Uint8 *pixmap; + + /* The bitmap is easy, just render another copy */ + for ( offset=0; offset < font->glyph_overhang; ++offset ) { + TT_Translate_Outline(&outline, 64, 0); + error += TT_Get_Outline_Bitmap(engine, + &outline,&glyph->bitmap); + } + x_offset += font->glyph_overhang*64; + + /* The pixmap is a little harder, we have to add and clamp */ + for ( row=glyph->pixmap.rows-1; row >= 0; --row ) { + pixmap = (Uint8 *)glyph->pixmap.bitmap + + row*glyph->pixmap.cols; + for (offset=1; offset<=font->glyph_overhang; ++offset) { + for (col=glyph->pixmap.cols-1; col > 0; --col) { + pixel=(pixmap[col]+pixmap[col-1]); + if ( pixel > 4 ) { + pixel = 4; + } + pixmap[col] = (Uint8)pixel; + } + } + } + } + TT_Translate_Outline(&outline, -x_offset, -y_offset); +was_error: + if ( error ) { + if ( glyph->bitmap.bitmap ) { + free(glyph->bitmap.bitmap); + glyph->bitmap.bitmap = 0; + } + if ( glyph->pixmap.bitmap ) { + free(glyph->pixmap.bitmap); + glyph->pixmap.bitmap = 0; + } + return error; + } + + /* We're done, mark this glyph cached */ + glyph->cached = ch; + return TT_Err_Ok; +} + +static TT_Error Find_Glyph(TTF_Font *font, Uint16 ch) +{ + int retval; + + retval = 0; + if ( ch < 256 ) { + font->current = &font->cache[ch]; + } else { + if ( font->scratch.cached != ch ) { + Flush_Glyph(&font->scratch); + } + font->current = &font->scratch; + } + if ( ! font->current->cached ) { + retval = Load_Glyph(font, ch, font->current); + } + return retval; +} + +void TTF_CloseFont(TTF_Font *font) +{ + Flush_Cache(font); + TT_Close_Face(font->face); + free(font); +} + +static Uint16 *ASCII_to_UNICODE(Uint16 *unicode, const char *text, int len) +{ + int i; + + for ( i=0; i < len; ++i ) { + unicode[i] = ((const unsigned char *)text)[i]; + } + unicode[i] = 0; + + return unicode; +} + +static Uint16 *UTF8_to_UNICODE(Uint16 *unicode, const char *utf8, int len) +{ + int i, j; + Uint16 ch; + + for ( i=0, j=0; i < len; ++i, ++j ) { + ch = ((const unsigned char *)utf8)[i]; + if ( ch >= 0xF0 ) { + ch = (Uint16)(utf8[i]&0x07) << 18; + ch |= (Uint16)(utf8[++i]&0x3F) << 12; + ch |= (Uint16)(utf8[++i]&0x3F) << 6; + ch |= (Uint16)(utf8[++i]&0x3F); + } else + if ( ch >= 0xE0 ) { + ch = (Uint16)(utf8[i]&0x3F) << 12; + ch |= (Uint16)(utf8[++i]&0x3F) << 6; + ch |= (Uint16)(utf8[++i]&0x3F); + } else + if ( ch >= 0xC0 ) { + ch = (Uint16)(utf8[i]&0x3F) << 6; + ch |= (Uint16)(utf8[++i]&0x3F); + } + unicode[j] = ch; + } + unicode[j] = 0; + + return unicode; +} + +int TTF_FontHeight(TTF_Font *font) +{ + return(font->height); +} + +int TTF_FontAscent(TTF_Font *font) +{ + return(round(font->ascent)); +} + +int TTF_FontDescent(TTF_Font *font) +{ + return(round(font->descent)); +} + +int TTF_FontLineSkip(TTF_Font *font) +{ + return(round(font->lineskip)); +} + +int TTF_GlyphMetrics(TTF_Font *font, Uint16 ch, + int* minx, int* maxx, int* miny, int* maxy, int* advance) +{ + TT_Error error; + + error = Find_Glyph(font, ch); + + if ( error ) { + return -1; + } + + if ( minx ) { + *minx = font->current->minx; + } + if ( maxx ) { + *maxx = font->current->maxx; + } + if ( miny ) { + *miny = font->current->miny; + } + if ( maxy ) { + *maxy = font->current->maxy; + } + if ( advance ) { + *advance = font->current->advance; + } + return 0; +} + +int TTF_SizeText(TTF_Font *font, const char *text, int *w, int *h) +{ + Uint16 *unicode_text; + int unicode_len; + int status; + + /* Copy the Latin-1 text to a UNICODE text buffer */ + unicode_len = strlen(text); + unicode_text = (Uint16 *)malloc((unicode_len+1)*(sizeof *unicode_text)); + if ( unicode_text == NULL ) { + SDL_SetError("Out of memory"); + return -1; + } + ASCII_to_UNICODE(unicode_text, text, unicode_len); + + /* Render the new text */ + status = TTF_SizeUNICODE(font, unicode_text, w, h); + + /* Free the text buffer and return */ + free(unicode_text); + return status; +} + +int TTF_SizeUTF8(TTF_Font *font, const char *text, int *w, int *h) +{ + Uint16 *unicode_text; + int unicode_len; + int status; + + /* Copy the UTF-8 text to a UNICODE text buffer */ + unicode_len = strlen(text); + unicode_text = (Uint16 *)malloc((unicode_len+1)*(sizeof *unicode_text)); + if ( unicode_text == NULL ) { + SDL_SetError("Out of memory"); + return -1; + } + UTF8_to_UNICODE(unicode_text, text, unicode_len); + + /* Render the new text */ + status = TTF_SizeUNICODE(font, unicode_text, w, h); + + /* Free the text buffer and return */ + free(unicode_text); + return status; +} + +int TTF_SizeUNICODE(TTF_Font *font, const Uint16 *text, int *w, int *h) +{ + int status; + const Uint16 *ch; + int x, z, minx, maxx; + TT_Error error; + + /* Initialize everything to 0 */ + status = 0; + minx = maxx = 0; + + /* Load each character and sum it's bounding box */ + x= 0; + for ( ch=text; *ch; ++ch ) { + error = Find_Glyph(font, *ch); + if ( ! error ) { + z = x + font->current->minx; + if ( minx > z ) { + minx = z; + } + if ( font->style & TTF_STYLE_BOLD ) { + x += font->glyph_overhang; + } + if ( font->current->advance > font->current->maxx ) { + z = x + font->current->advance; + } else { + z = x + font->current->maxx; + } + if ( maxx < z ) { + maxx = z; + } + x += font->current->advance; + } + } + + /* Fill the bounds rectangle */ + if ( w ) { + *w = (maxx - minx); + } + if ( h ) { + *h = font->height; + } + return status; +} + +/* Convert the Latin-1 text to UNICODE and render it +*/ +SDL_Surface *TTF_RenderText_Solid(TTF_Font *font, + const char *text, SDL_Color fg) +{ + SDL_Surface *textbuf; + Uint16 *unicode_text; + int unicode_len; + + /* Copy the Latin-1 text to a UNICODE text buffer */ + unicode_len = strlen(text); + unicode_text = (Uint16 *)malloc((unicode_len+1)*(sizeof *unicode_text)); + if ( unicode_text == NULL ) { + SDL_SetError("Out of memory"); + return(NULL); + } + ASCII_to_UNICODE(unicode_text, text, unicode_len); + + /* Render the new text */ + textbuf = TTF_RenderUNICODE_Solid(font, unicode_text, fg); + + /* Free the text buffer and return */ + free(unicode_text); + return(textbuf); +} + +/* Convert the UTF-8 text to UNICODE and render it +*/ +SDL_Surface *TTF_RenderUTF8_Solid(TTF_Font *font, + const char *text, SDL_Color fg) +{ + SDL_Surface *textbuf; + Uint16 *unicode_text; + int unicode_len; + + /* Copy the UTF-8 text to a UNICODE text buffer */ + unicode_len = strlen(text); + unicode_text = (Uint16 *)malloc((unicode_len+1)*(sizeof *unicode_text)); + if ( unicode_text == NULL ) { + SDL_SetError("Out of memory"); + return(NULL); + } + UTF8_to_UNICODE(unicode_text, text, unicode_len); + + /* Render the new text */ + textbuf = TTF_RenderUNICODE_Solid(font, unicode_text, fg); + + /* Free the text buffer and return */ + free(unicode_text); + return(textbuf); +} + +SDL_Surface *TTF_RenderUNICODE_Solid(TTF_Font *font, + const Uint16 *text, SDL_Color fg) +{ + int xstart, width; + int w, h; + SDL_Surface *textbuf; + SDL_Palette *palette; + const Uint16 *ch; + Uint8 *src, *dst; + int row, col; + TT_Error error; + + /* Get the dimensions of the text surface */ + if ( (TTF_SizeUNICODE(font, text, &w, &h) < 0) || !w ) { + TTF_SetError("Text has zero width"); + return(NULL); + } + + /* Create the target surface */ + width = w; + w = (w+7)&~7; + textbuf = SDL_AllocSurface(SDL_SWSURFACE, w, h, 8, 0, 0, 0, 0); + if ( textbuf == NULL ) { + return(NULL); + } + + /* Fill the palette with the foreground color */ + palette = textbuf->format->palette; + palette->colors[0].r = 255-fg.r; + palette->colors[0].g = 255-fg.g; + palette->colors[0].b = 255-fg.b; + palette->colors[1].r = fg.r; + palette->colors[1].g = fg.g; + palette->colors[1].b = fg.b; + SDL_SetColorKey(textbuf, SDL_SRCCOLORKEY, 0); + + /* Load and render each character */ + xstart = 0; + for ( ch=text; *ch; ++ch ) { + error = Find_Glyph(font, *ch); + if ( ! error ) { + w = font->current->bitmap.width; + src = (Uint8 *)font->current->bitmap.bitmap; + for ( row = 0; row < h; ++row ) { + dst = (Uint8 *)textbuf->pixels + + row * textbuf->pitch + + xstart + font->current->minx; + for ( col = 0; col < w; col += 8 ) { + Uint8 c = *src++; + *dst++ |= (c&0x80)>>7; + c <<= 1; + *dst++ |= (c&0x80)>>7; + c <<= 1; + *dst++ |= (c&0x80)>>7; + c <<= 1; + *dst++ |= (c&0x80)>>7; + c <<= 1; + *dst++ |= (c&0x80)>>7; + c <<= 1; + *dst++ |= (c&0x80)>>7; + c <<= 1; + *dst++ |= (c&0x80)>>7; + c <<= 1; + *dst++ |= (c&0x80)>>7; + } + } + xstart += font->current->advance; + if ( font->style & TTF_STYLE_BOLD ) { + xstart += font->glyph_overhang; + } + } + } + /* Handle the underline style */ + if ( font->style & TTF_STYLE_UNDERLINE ) { + int row_offset; + + row_offset = round(font->ascent) + 1; + if ( row_offset > font->height ) { + row_offset = font->height-1; + } + memset((Uint8 *)textbuf->pixels+row_offset*textbuf->pitch, + 1, width); + } + return(textbuf); +} + +SDL_Surface *TTF_RenderGlyph_Solid(TTF_Font *font, Uint16 ch, SDL_Color fg) +{ + SDL_Surface *textbuf; + SDL_Palette *palette; + Uint8 *src, *dst; + int row, col; + TT_Error error; + struct glyph *glyph; + + /* Get the glyph itself */ + error = Find_Glyph(font, ch); + if ( error ) { + return(NULL); + } + glyph = font->current; + + /* Create the target surface */ + textbuf = SDL_CreateRGBSurface(SDL_SWSURFACE, + glyph->bitmap.width, glyph->bitmap.rows, 8, 0, 0, 0, 0); + if ( ! textbuf ) { + return(NULL); + } + + /* Fill the palette with the foreground color */ + palette = textbuf->format->palette; + palette->colors[0].r = 255-fg.r; + palette->colors[0].g = 255-fg.g; + palette->colors[0].b = 255-fg.b; + palette->colors[1].r = fg.r; + palette->colors[1].g = fg.g; + palette->colors[1].b = fg.b; + SDL_SetColorKey(textbuf, SDL_SRCCOLORKEY, 0); + + /* Load and render each character */ + src = (Uint8 *)font->current->bitmap.bitmap; + for ( row = 0; row < textbuf->h; ++row ) { + dst = (Uint8 *)textbuf->pixels + row * textbuf->pitch; + for ( col = 0; col < textbuf->w; col += 8 ) { + Uint8 c = *src++; + *dst++ |= (c&0x80)>>7; + c <<= 1; + *dst++ |= (c&0x80)>>7; + c <<= 1; + *dst++ |= (c&0x80)>>7; + c <<= 1; + *dst++ |= (c&0x80)>>7; + c <<= 1; + *dst++ |= (c&0x80)>>7; + c <<= 1; + *dst++ |= (c&0x80)>>7; + c <<= 1; + *dst++ |= (c&0x80)>>7; + c <<= 1; + *dst++ |= (c&0x80)>>7; + } + } + + /* Handle the underline style */ + if ( font->style & TTF_STYLE_UNDERLINE ) { + int row_offset; + + row_offset = round(font->ascent) + 1; + if ( row_offset > font->height ) { + row_offset = font->height-1; + } + memset((Uint8 *)textbuf->pixels+row_offset*textbuf->pitch, + 1, textbuf->w); + } + return(textbuf); +} + + +/* Convert the Latin-1 text to UNICODE and render it +*/ +SDL_Surface *TTF_RenderText_Shaded(TTF_Font *font, + const char *text, SDL_Color fg, SDL_Color bg) +{ + SDL_Surface *textbuf; + Uint16 *unicode_text; + int unicode_len; + + /* Copy the Latin-1 text to a UNICODE text buffer */ + unicode_len = strlen(text); + unicode_text = (Uint16 *)malloc((unicode_len+1)*(sizeof *unicode_text)); + if ( unicode_text == NULL ) { + SDL_SetError("Out of memory"); + return(NULL); + } + ASCII_to_UNICODE(unicode_text, text, unicode_len); + + /* Render the new text */ + textbuf = TTF_RenderUNICODE_Shaded(font, unicode_text, fg, bg); + + /* Free the text buffer and return */ + free(unicode_text); + return(textbuf); +} + +/* Convert the UTF-8 text to UNICODE and render it +*/ +SDL_Surface *TTF_RenderUTF8_Shaded(TTF_Font *font, + const char *text, SDL_Color fg, SDL_Color bg) +{ + SDL_Surface *textbuf; + Uint16 *unicode_text; + int unicode_len; + + /* Copy the UTF-8 text to a UNICODE text buffer */ + unicode_len = strlen(text); + unicode_text = (Uint16 *)malloc((unicode_len+1)*(sizeof *unicode_text)); + if ( unicode_text == NULL ) { + SDL_SetError("Out of memory"); + return(NULL); + } + UTF8_to_UNICODE(unicode_text, text, unicode_len); + + /* Render the new text */ + textbuf = TTF_RenderUNICODE_Shaded(font, unicode_text, fg, bg); + + /* Free the text buffer and return */ + free(unicode_text); + return(textbuf); +} + +SDL_Surface *TTF_RenderUNICODE_Shaded(TTF_Font *font, + const Uint16 *text, SDL_Color fg, SDL_Color bg) +{ + int xstart, width; + int w, h; + SDL_Surface *textbuf; + SDL_Palette *palette; + int index; + int rdiff, gdiff, bdiff; + const Uint16 *ch; + Uint8 *src, *dst; + int row, col; + TT_Error error; + + /* Get the dimensions of the text surface */ + if ( (TTF_SizeUNICODE(font, text, &w, &h) < 0) || !w ) { + TTF_SetError("Text has zero width"); + return(NULL); + } + + /* Create the target surface */ + width = w; + w = (w+3)&~3; + textbuf = SDL_AllocSurface(SDL_SWSURFACE, w, h, 8, 0, 0, 0, 0); + if ( textbuf == NULL ) { + return(NULL); + } + + /* Fill the palette with 5 levels of shading from bg to fg */ + palette = textbuf->format->palette; + rdiff = fg.r - bg.r; + gdiff = fg.g - bg.g; + bdiff = fg.b - bg.b; + for ( index=0; index<5; ++index ) { + palette->colors[index].r = bg.r + (index*rdiff)/4; + palette->colors[index].g = bg.g + (index*gdiff)/4; + palette->colors[index].b = bg.b + (index*bdiff)/4; + } + /* The other 3 levels are used as overflow when ORing pixels */ + for ( ; index<8; ++index ) { + palette->colors[index] = palette->colors[4]; + } + + /* Load and render each character */ + xstart = 0; + for ( ch=text; *ch; ++ch ) { + error = Find_Glyph(font, *ch); + if ( ! error ) { + w = font->current->pixmap.width; + src = (Uint8 *)font->current->pixmap.bitmap; + for ( row = 0; row < h; ++row ) { + dst = (Uint8 *)textbuf->pixels + + row * textbuf->pitch + + xstart + font->current->minx; + for ( col=w; col>0; col -= 4 ) { + *dst++ |= *src++; + *dst++ |= *src++; + *dst++ |= *src++; + *dst++ |= *src++; + } + } + xstart += font->current->advance; + if ( font->style & TTF_STYLE_BOLD ) { + xstart += font->glyph_overhang; + } + } + } + /* Handle the underline style */ + if ( font->style & TTF_STYLE_UNDERLINE ) { + int row_offset; + + row_offset = round(font->ascent) + 1; + if ( row_offset > font->height ) { + row_offset = font->height-1; + } + memset((Uint8 *)textbuf->pixels+row_offset*textbuf->pitch, + 4, width); + } + return(textbuf); +} + +SDL_Surface *TTF_RenderGlyph_Shaded(TTF_Font *font, + Uint16 ch, SDL_Color fg, SDL_Color bg) +{ + SDL_Surface *textbuf; + SDL_Palette *palette; + int index; + int rdiff, gdiff, bdiff; + Uint8 *src, *dst; + int row, col; + TT_Error error; + struct glyph *glyph; + + /* Get the glyph itself */ + error = Find_Glyph(font, ch); + if ( error ) { + return(NULL); + } + glyph = font->current; + + /* Create the target surface */ + textbuf = SDL_CreateRGBSurface(SDL_SWSURFACE, + glyph->pixmap.width, glyph->pixmap.rows, 8, 0, 0, 0, 0); + if ( ! textbuf ) { + return(NULL); + } + + /* Fill the palette with 5 levels of shading from bg to fg */ + palette = textbuf->format->palette; + rdiff = fg.r - bg.r; + gdiff = fg.g - bg.g; + bdiff = fg.b - bg.b; + for ( index=0; index<5; ++index ) { + palette->colors[index].r = bg.r + (index*rdiff)/4; + palette->colors[index].g = bg.g + (index*gdiff)/4; + palette->colors[index].b = bg.b + (index*bdiff)/4; + } + + /* Copy the character from the pixmap */ + for ( row=0; rowh; ++row ) { + src = glyph->pixmap.bitmap + row * glyph->pixmap.cols; + dst = (Uint8 *)textbuf->pixels + row * textbuf->pitch; + memcpy(dst, src, glyph->pixmap.cols); + } + + /* Handle the underline style */ + if ( font->style & TTF_STYLE_UNDERLINE ) { + int row_offset; + + row_offset = round(font->ascent) + 1; + if ( row_offset > font->height ) { + row_offset = font->height-1; + } + memset((Uint8 *)textbuf->pixels+row_offset*textbuf->pitch, + 4, glyph->pixmap.cols); + } + return(textbuf); +} + +/* Convert the Latin-1 text to UNICODE and render it +*/ +SDL_Surface *TTF_RenderText_Blended(TTF_Font *font, + const char *text, SDL_Color fg) +{ + SDL_Surface *textbuf; + Uint16 *unicode_text; + int unicode_len; + + /* Copy the Latin-1 text to a UNICODE text buffer */ + unicode_len = strlen(text); + unicode_text = (Uint16 *)malloc((unicode_len+1)*(sizeof *unicode_text)); + if ( unicode_text == NULL ) { + SDL_SetError("Out of memory"); + return(NULL); + } + ASCII_to_UNICODE(unicode_text, text, unicode_len); + + /* Render the new text */ + textbuf = TTF_RenderUNICODE_Blended(font, unicode_text, fg); + + /* Free the text buffer and return */ + free(unicode_text); + return(textbuf); +} + +/* Convert the UTF-8 text to UNICODE and render it +*/ +SDL_Surface *TTF_RenderUTF8_Blended(TTF_Font *font, + const char *text, SDL_Color fg) +{ + SDL_Surface *textbuf; + Uint16 *unicode_text; + int unicode_len; + + /* Copy the UTF-8 text to a UNICODE text buffer */ + unicode_len = strlen(text); + unicode_text = (Uint16 *)malloc((unicode_len+1)*(sizeof *unicode_text)); + if ( unicode_text == NULL ) { + SDL_SetError("Out of memory"); + return(NULL); + } + UTF8_to_UNICODE(unicode_text, text, unicode_len); + + /* Render the new text */ + textbuf = TTF_RenderUNICODE_Blended(font, unicode_text, fg); + + /* Free the text buffer and return */ + free(unicode_text); + return(textbuf); +} + +SDL_Surface *TTF_RenderUNICODE_Blended(TTF_Font *font, + const Uint16 *text, SDL_Color fg) +{ + int xstart, width; + int w, h; + SDL_Surface *textbuf; +#if SDL_VERSIONNUM(SDL_MAJOR_VERSION, SDL_MINOR_VERSION, SDL_PATCHLEVEL) >= \ + SDL_VERSIONNUM(1, 1, 5) /* The great alpha flip */ + Uint32 alpha_table[] = { + (0)<<24, (255-128)<<24, (255-64)<<24, (255-32)<<24, + (255)<<24, (255)<<24, (255)<<24, (255)<<24 + }; +#else + Uint32 alpha_table[] = { + (255<<24), (128<<24), (64<<24), (32<<24), 0, 0, 0, 0 + }; +#endif + Uint32 pixel; + const Uint16 *ch; + Uint8 *src; + Uint32 *dst; + int row, col; + TT_Error error; + + /* Get the dimensions of the text surface */ + if ( (TTF_SizeUNICODE(font, text, &w, &h) < 0) || !w ) { + TTF_SetError("Text has zero width"); + return(NULL); + } + + /* Create the target surface, 32-bit ARGB format */ + width = w; + w = (w+3)&~3; + textbuf = SDL_AllocSurface(SDL_SWSURFACE, w, h, 32, + 0x00FF0000, 0x0000FF00, 0x000000FF, + 0xFF000000); + if ( textbuf == NULL ) { + return(NULL); + } + + /* Load and render each character */ + xstart = 0; + for ( ch=text; *ch; ++ch ) { + error = Find_Glyph(font, *ch); + if ( ! error ) { + w = font->current->pixmap.width; + src = (Uint8 *)font->current->pixmap.bitmap; + for ( row = 0; row < h; ++row ) { + dst = (Uint32 *)textbuf->pixels + + row * textbuf->pitch/4 + + xstart + font->current->minx; + for ( col=w; col>0; col -= 4 ) { + *dst++ |= *src++; + *dst++ |= *src++; + *dst++ |= *src++; + *dst++ |= *src++; + } + } + xstart += font->current->advance; + if ( font->style & TTF_STYLE_BOLD ) { + xstart += font->glyph_overhang; + } + } + } + + /* Handle the underline style */ + if ( font->style & TTF_STYLE_UNDERLINE ) { + int row_offset; + + row_offset = round(font->ascent) + 1; + if ( row_offset > font->height ) { + row_offset = font->height-1; + } + dst = (Uint32 *)textbuf->pixels+row_offset*textbuf->pitch/4; + for ( col=width; col > 0; ++col ) { + *dst++ = 4; + } + } + + /* Build the alpha table */ + pixel = (fg.r<<16)|(fg.g<<8)|fg.b; + for ( xstart = 0; xstart < 8; ++xstart ) { + alpha_table[xstart] |= pixel; + } + + /* Transform the alpha values */ + for ( row = 0; row < textbuf->h; ++row ) { + dst = (Uint32 *)textbuf->pixels + row * textbuf->pitch/4; + for ( col=textbuf->w; col>0; col -= 4 ) { + *dst = alpha_table[*dst]; + ++dst; + *dst = alpha_table[*dst]; + ++dst; + *dst = alpha_table[*dst]; + ++dst; + *dst = alpha_table[*dst]; + ++dst; + } + } + return(textbuf); +} + +SDL_Surface *TTF_RenderGlyph_Blended(TTF_Font *font, Uint16 ch, SDL_Color fg) +{ + SDL_Surface *textbuf; +#if SDL_VERSIONNUM(SDL_MAJOR_VERSION, SDL_MINOR_VERSION, SDL_PATCHLEVEL) >= \ + SDL_VERSIONNUM(1, 1, 5) /* The great alpha flip */ + Uint32 alpha_table[] = { + (0)<<24, (255-128)<<24, (255-64)<<24, (255-32)<<24, + (255)<<24, (255)<<24, (255)<<24, (255)<<24 + }; +#else + Uint32 alpha_table[] = { + (255<<24), (128<<24), (64<<24), (32<<24), 0, 0, 0, 0 + }; +#endif + Uint32 pixel; + Uint8 *src; + Uint32 *dst; + int row, col; + TT_Error error; + struct glyph *glyph; + + /* Get the glyph itself */ + error = Find_Glyph(font, ch); + if ( error ) { + return(NULL); + } + glyph = font->current; + + /* Create the target surface, 32-bit ARGB format */ + textbuf = SDL_CreateRGBSurface(SDL_SWSURFACE, + glyph->pixmap.width, glyph->pixmap.rows, 32, + 0x00FF0000, 0x0000FF00, 0x000000FF, 0xFF000000); + if ( ! textbuf ) { + return(NULL); + } + + /* Copy the character from the pixmap */ + for ( row=0; rowh; ++row ) { + src = glyph->pixmap.bitmap + row * glyph->pixmap.cols; + dst = (Uint32 *)textbuf->pixels + row * textbuf->pitch/4; + for ( col=0; colpixmap.cols; ++col ) { + *dst++ = *src++; + } + } + + /* Handle the underline style */ + if ( font->style & TTF_STYLE_UNDERLINE ) { + int row_offset; + + row_offset = round(font->ascent) + 1; + if ( row_offset > font->height ) { + row_offset = font->height-1; + } + dst = (Uint32 *)textbuf->pixels+row_offset*textbuf->pitch/4; + for ( col=glyph->pixmap.cols; col > 0; ++col ) { + *dst++ = 4; + } + } + + /* Build the alpha table */ + pixel = (fg.r<<16)|(fg.g<<8)|fg.b; + for ( col = 0; col < 8; ++col ) { + alpha_table[col] |= pixel; + } + + /* Transform the alpha values */ + for ( row = 0; row < textbuf->h; ++row ) { + dst = (Uint32 *)textbuf->pixels + row * textbuf->pitch/4; + for ( col=textbuf->w; col>0; col -= 4 ) { + *dst = alpha_table[*dst]; + ++dst; + *dst = alpha_table[*dst]; + ++dst; + *dst = alpha_table[*dst]; + ++dst; + *dst = alpha_table[*dst]; + ++dst; + } + } + return(textbuf); +} + +void TTF_SetFontStyle(TTF_Font *font, int style) +{ + font->style = style; + Flush_Cache(font); +} + +int TTF_GetFontStyle(TTF_Font *font) +{ + return(font->style); +} + +void TTF_Quit(void) +{ + TT_Done_FreeType(engine); +} diff --git a/contrib/sdk/sources/SDL-1.2.2/SDL_ttf/SDL_ttf.h b/contrib/sdk/sources/SDL-1.2.2/SDL_ttf/SDL_ttf.h new file mode 100644 index 000000000..27d6779ff --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/SDL_ttf/SDL_ttf.h @@ -0,0 +1,176 @@ +/* + SDL_ttf: A companion library to SDL for working with TrueType (tm) fonts + Copyright (C) 1997 Sam Lantinga + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public 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 + + Sam Lantinga + 5635-34 Springhouse Dr. + Pleasanton, CA 94588 (USA) + slouken@devolution.com +*/ + +/* This library is a wrapper around the excellent FreeType 1.0 library, + available at: + http://www.physiol.med.tu-muenchen.de/~robert/freetype.html +*/ + +#ifndef _SDLttf_h +#define _SDLttf_h + +#include "SDL.h" +#include "begin_code.h" + +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +extern "C" { +#endif + +/* The internal structure containing font information */ +typedef struct _TTF_Font TTF_Font; + +/* Initialize the TTF engine - returns 0 if successful, -1 on error */ +extern DECLSPEC int TTF_Init(void); + +/* Open a font file and create a font of the specified point size */ +extern DECLSPEC TTF_Font *TTF_OpenFont(const char *file, int ptsize); + +/* Set and retrieve the font style + This font style is implemented by modifying the font glyphs, and + doesn't reflect any inherent properties of the truetype font file. +*/ +#define TTF_STYLE_NORMAL 0x00 +#define TTF_STYLE_BOLD 0x01 +#define TTF_STYLE_ITALIC 0x02 +#define TTF_STYLE_UNDERLINE 0x04 +extern DECLSPEC int TTF_GetFontStyle(TTF_Font *font); +extern DECLSPEC void TTF_SetFontStyle(TTF_Font *font, int style); + +/* Get the total height of the font - usually equal to point size */ +extern DECLSPEC int TTF_FontHeight(TTF_Font *font); + +/* Get the offset from the baseline to the top of the font + This is a positive value, relative to the baseline. + */ +extern DECLSPEC int TTF_FontAscent(TTF_Font *font); + +/* Get the offset from the baseline to the bottom of the font + This is a negative value, relative to the baseline. + */ +extern DECLSPEC int TTF_FontDescent(TTF_Font *font); + +/* Get the recommended spacing between lines of text for this font */ +extern DECLSPEC int TTF_FontLineSkip(TTF_Font *font); + +/* Get the metrics (dimensions) of a glyph */ +extern DECLSPEC int TTF_GlyphMetrics(TTF_Font *font, Uint16 ch, + int *minx, int *maxx, + int *miny, int *maxy, int *advance); + +/* Get the dimensions of a rendered string of text */ +extern DECLSPEC int TTF_SizeText(TTF_Font *font, const char *text, int *w, int *h); +extern DECLSPEC int TTF_SizeUTF8(TTF_Font *font, const char *text, int *w, int *h); +extern DECLSPEC int TTF_SizeUNICODE(TTF_Font *font, const Uint16 *text, int *w, int *h); + +/* Create an 8-bit palettized surface and render the given text at + fast quality with the given font and color. The 0 pixel is the + colorkey, giving a transparent background, and the 1 pixel is set + to the text color. + This function returns the new surface, or NULL if there was an error. +*/ +extern DECLSPEC SDL_Surface *TTF_RenderText_Solid(TTF_Font *font, + const char *text, SDL_Color fg); +extern DECLSPEC SDL_Surface *TTF_RenderUTF8_Solid(TTF_Font *font, + const char *text, SDL_Color fg); +extern DECLSPEC SDL_Surface *TTF_RenderUNICODE_Solid(TTF_Font *font, + const Uint16 *text, SDL_Color fg); + +/* Create an 8-bit palettized surface and render the given glyph at + fast quality with the given font and color. The 0 pixel is the + colorkey, giving a transparent background, and the 1 pixel is set + to the text color. The glyph is rendered without any padding or + centering in the X direction, and aligned normally in the Y direction. + This function returns the new surface, or NULL if there was an error. +*/ +extern DECLSPEC SDL_Surface *TTF_RenderGlyph_Solid(TTF_Font *font, + Uint16 ch, SDL_Color fg); + +/* Create an 8-bit palettized surface and render the given text at + high quality with the given font and colors. The 0 pixel is background, + while other pixels have varying degrees of the foreground color. + This function returns the new surface, or NULL if there was an error. +*/ +extern DECLSPEC SDL_Surface *TTF_RenderText_Shaded(TTF_Font *font, + const char *text, SDL_Color fg, SDL_Color bg); +extern DECLSPEC SDL_Surface *TTF_RenderUTF8_Shaded(TTF_Font *font, + const char *text, SDL_Color fg, SDL_Color bg); +extern DECLSPEC SDL_Surface *TTF_RenderUNICODE_Shaded(TTF_Font *font, + const Uint16 *text, SDL_Color fg, SDL_Color bg); + +/* Create an 8-bit palettized surface and render the given glyph at + high quality with the given font and colors. The 0 pixel is background, + while other pixels have varying degrees of the foreground color. + The glyph is rendered without any padding or centering in the X + direction, and aligned normally in the Y direction. + This function returns the new surface, or NULL if there was an error. +*/ +extern DECLSPEC SDL_Surface *TTF_RenderGlyph_Shaded(TTF_Font *font, + Uint16 ch, SDL_Color fg, SDL_Color bg); + +/* Create a 32-bit ARGB surface and render the given text at high quality, + using alpha blending to dither the font with the given color. + This function returns the new surface, or NULL if there was an error. +*/ +extern DECLSPEC SDL_Surface *TTF_RenderText_Blended(TTF_Font *font, + const char *text, SDL_Color fg); +extern DECLSPEC SDL_Surface *TTF_RenderUTF8_Blended(TTF_Font *font, + const char *text, SDL_Color fg); +extern DECLSPEC SDL_Surface *TTF_RenderUNICODE_Blended(TTF_Font *font, + const Uint16 *text, SDL_Color fg); + +/* Create a 32-bit ARGB surface and render the given glyph at high quality, + using alpha blending to dither the font with the given color. + The glyph is rendered without any padding or centering in the X + direction, and aligned normally in the Y direction. + This function returns the new surface, or NULL if there was an error. +*/ +extern DECLSPEC SDL_Surface *TTF_RenderGlyph_Blended(TTF_Font *font, + Uint16 ch, SDL_Color fg); + +/* For compatibility with previous versions, here are the old functions */ +#define TTF_RenderText(font, text, fg, bg) \ + TTF_RenderText_Shaded(font, text, fg, bg) +#define TTF_RenderUTF8(font, text, fg, bg) \ + TTF_RenderUTF8_Shaded(font, text, fg, bg) +#define TTF_RenderUNICODE(font, text, fg, bg) \ + TTF_RenderUNICODE_Shaded(font, text, fg, bg) + +/* Close an opened font file */ +extern DECLSPEC void TTF_CloseFont(TTF_Font *font); + +/* De-initialize the TTF engine */ +extern DECLSPEC void TTF_Quit(void); + +/* We'll use SDL for reporting errors */ +#define TTF_SetError SDL_SetError +#define TTF_GetError SDL_GetError + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +}; +#endif +#include "close_code.h" + +#endif /* _SDLttf_h */ diff --git a/contrib/sdk/sources/SDL-1.2.2/SDL_ttf/test/Makefile b/contrib/sdk/sources/SDL-1.2.2/SDL_ttf/test/Makefile new file mode 100644 index 000000000..a7d332ba7 --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/SDL_ttf/test/Makefile @@ -0,0 +1,6 @@ +OUTFILE = ttftest +OBJS = ttftest.o +LIBS = -L../../lib -lSDL -lSDL_ttf -lSDL -lpng -lttf +CFLAGS = -I../../include -I.. + +include $(MENUETDEV)/makefiles/Makefile_for_program diff --git a/contrib/sdk/sources/SDL-1.2.2/SDL_ttf/test/hydrogen.ttf b/contrib/sdk/sources/SDL-1.2.2/SDL_ttf/test/hydrogen.ttf new file mode 100644 index 000000000..ecdfd4363 Binary files /dev/null and b/contrib/sdk/sources/SDL-1.2.2/SDL_ttf/test/hydrogen.ttf differ diff --git a/contrib/sdk/sources/SDL-1.2.2/SDL_ttf/test/indigo.ttf b/contrib/sdk/sources/SDL-1.2.2/SDL_ttf/test/indigo.ttf new file mode 100644 index 000000000..7905fd51a Binary files /dev/null and b/contrib/sdk/sources/SDL-1.2.2/SDL_ttf/test/indigo.ttf differ diff --git a/contrib/sdk/sources/SDL-1.2.2/SDL_ttf/test/ttftest.c b/contrib/sdk/sources/SDL-1.2.2/SDL_ttf/test/ttftest.c new file mode 100644 index 000000000..2456c659d --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/SDL_ttf/test/ttftest.c @@ -0,0 +1,74 @@ +#include +#include +#include +#include "SDL.h" +#include "SDL_ttf.h" + +int app_main(int argc, char *argv[]) +{ + SDL_Surface *screen, *txt; + static SDL_Color kolor={0xC0,0xC0,0,0}; + static SDL_Color kolor1={0x00,0xC0,0xC0,0}; + SDL_Event event; + SDL_Rect xtmp={x:30,y:30}; + TTF_Font * fnt, * fnt1; + static int done=0; + int i; + if ( SDL_Init(SDL_INIT_VIDEO) < 0 ) + { + SDL_printf("Couldn't initialize SDL: %s\n",SDL_GetError()); + return(255); + } + screen = SDL_SetVideoMode(512,348,24,SDL_SWSURFACE); + if ( screen == NULL ) + { + SDL_printf("Couldn't set %dx%dx%d video mode: %s\n", + 640,480,24, SDL_GetError()); + exit(-1); + } + if(TTF_Init()!=0) + { + SDL_printf("Couldn't initialize TTF library\n"); + exit(-1); + } + fnt=TTF_OpenFont("/RD/1/INDIGO.TTF",50); + fnt1=TTF_OpenFont("/RD/1/HYDROGEN.TTF",35); + TTF_SetFontStyle(fnt,TTF_STYLE_ITALIC|TTF_STYLE_BOLD|TTF_STYLE_UNDERLINE); + txt=TTF_RenderText_Solid(fnt,"MenuetOS",kolor); + if(!txt) + { + SDL_printf("Unable to create rendering surface\n"); + exit(-1); + } + xtmp.w=txt->w; + xtmp.h=txt->h; + SDL_BlitSurface(txt,NULL,screen,&xtmp); + SDL_FreeSurface(txt); + txt=TTF_RenderText_Solid(fnt1,"supports TTF",kolor1); + xtmp.w=txt->w; + xtmp.h=txt->h; + xtmp.x=40; + xtmp.y=100; + SDL_BlitSurface(txt,NULL,screen,&xtmp); + SDL_FreeSurface(txt); + while ( ! done ) + { + if ( SDL_PollEvent(&event) ) + { + switch (event.type) + { + case SDL_QUIT: + argv[i+1] = NULL; + done = 1; + break; + default: + break; + } + } else { + SDL_Delay(3); + } + } + SDL_FreeSurface(txt); + SDL_Quit(); + return(0); +} diff --git a/contrib/sdk/sources/SDL-1.2.2/docs/html/audio.html b/contrib/sdk/sources/SDL-1.2.2/docs/html/audio.html new file mode 100644 index 000000000..ed70e21d6 --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/docs/html/audio.html @@ -0,0 +1,234 @@ +Audio
SDL Library Documentation
PrevNext

Chapter 10. Audio

Table of Contents
SDL_AudioSpec — Audio Specification Structure
SDL_OpenAudio — Opens the audio device with the desired parameters.
SDL_PauseAudio — Pauses and unpauses the audio callback processing
SDL_GetAudioStatus — Get the current audio state
SDL_LoadWAV — Load a WAVE file
SDL_FreeWAV — Frees previously opened WAV data
SDL_AudioCVT — Audio Conversion Structure
SDL_BuildAudioCVT — Initializes a SDL_AudioCVT structure for conversion
SDL_ConvertAudio — Convert audio data to a desired audio format.
SDL_MixAudio — Mix audio data
SDL_LockAudio — Lock out the callback function
SDL_UnlockAudio — Unlock the callback function
SDL_CloseAudio — Shuts down audio processing and closes the audio device.

Sound on the computer is translated from waves that you hear into a series of +values, or samples, each representing the amplitude of the wave. When these +samples are sent in a stream to a sound card, an approximation of the original +wave can be recreated. The more bits used to represent the amplitude, and the +greater frequency these samples are gathered, the closer the approximated +sound is to the original, and the better the quality of sound.

This library supports both 8 and 16 bit signed and unsigned sound samples, +at frequencies ranging from 11025 Hz to 44100 Hz, depending on the +underlying hardware. If the hardware doesn't support the desired audio +format or frequency, it can be emulated if desired (See +SDL_OpenAudio())

A commonly supported audio format is 16 bits per sample at 22050 Hz.


PrevHomeNext
SDL_JoystickCloseUpSDL_AudioSpec
\ No newline at end of file diff --git a/contrib/sdk/sources/SDL-1.2.2/docs/html/cdrom.html b/contrib/sdk/sources/SDL-1.2.2/docs/html/cdrom.html new file mode 100644 index 000000000..a53b83009 --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/docs/html/cdrom.html @@ -0,0 +1,252 @@ +CD-ROM
SDL Library Documentation
PrevNext

Chapter 11. CD-ROM

Table of Contents
SDL_CDNumDrives — Returns the number of CD-ROM drives on the system.
SDL_CDName — Returns a human-readable, system-dependent identifier for the CD-ROM.
SDL_CDOpen — Opens a CD-ROM drive for access.
SDL_CDStatus — Returns the current status of the given drive.
SDL_CDPlay — Play a CD
SDL_CDPlayTracks — Play the given CD track(s)
SDL_CDPause — Pauses a CDROM
SDL_CDResume — Resumes a CDROM
SDL_CDStop — Stops a CDROM
SDL_CDEject — Ejects a CDROM
SDL_CDClose — Closes a SDL_CD handle
SDL_CD — CDROM Drive Information
SDL_CDtrack — CD Track Information Structure

SDL supports audio control of up to 32 local CD-ROM drives at once.

You use this API to perform all the basic functions of a CD player, +including listing the tracks, playing, stopping, and ejecting the CD-ROM. +(Currently, multi-changer CD drives are not supported.)

Before you call any of the SDL CD-ROM functions, you must first call +"SDL_Init(SDL_INIT_CDROM)", which scans the system for +CD-ROM drives, and sets the program up for audio control. Check the +return code, which should be 0, to see if there +were any errors in starting up.

After you have initialized the library, you can find out how many drives +are available using the SDL_CDNumDrives() function. +The first drive listed is the system default CD-ROM drive. After you have +chosen a drive, and have opened it with SDL_CDOpen(), +you can check the status and start playing if there's a CD in the drive.

A CD-ROM is organized into one or more tracks, each consisting of a certain +number of "frames". Each frame is ~2K in size, and at normal playing speed, +a CD plays 75 frames per second. SDL works with the number of frames on a +CD, but this can easily be converted to the more familiar minutes/seconds +format by using the FRAMES_TO_MSF() macro.


PrevHomeNext
SDL_CloseAudioUpSDL_CDNumDrives
\ No newline at end of file diff --git a/contrib/sdk/sources/SDL-1.2.2/docs/html/event.html b/contrib/sdk/sources/SDL-1.2.2/docs/html/event.html new file mode 100644 index 000000000..69f89a114 --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/docs/html/event.html @@ -0,0 +1,208 @@ +Events
SDL Library Documentation
PrevNext

Chapter 8. Events

Introduction

Event handling allows your application to receive input from the user. Event handling is initalised (along with video) with a call to: +

SDL_Init(SDL_INIT_VIDEO);
+Interally, SDL stores all the events waiting to be handled in an event queue. Using functions like SDL_PollEvent and SDL_PeepEvents you can observe and handle waiting input events.

The key to event handling in SDL is the SDL_Event union. The event queue itself is composed of a series of SDL_Event unions, one for each waiting event. SDL_Event unions are read from the queue with the SDL_PollEvent function and it is then up to the application to process the information stored with them.


PrevHomeNext
SDL_WM_GrabInputUpSDL Event Structures.
\ No newline at end of file diff --git a/contrib/sdk/sources/SDL-1.2.2/docs/html/eventfunctions.html b/contrib/sdk/sources/SDL-1.2.2/docs/html/eventfunctions.html new file mode 100644 index 000000000..2c17338ae --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/docs/html/eventfunctions.html @@ -0,0 +1,236 @@ +Event Functions.
SDL Library Documentation
PrevChapter 8. EventsNext

Event Functions.

Table of Contents
SDL_PumpEvents — Pumps the event loop, gathering events from the input devices.
SDL_PeepEvents — Checks the event queue for messages and optionally returns them.
SDL_PollEvent — Polls for currently pending events.
SDL_WaitEvent — Waits indefinitely for the next available event.
SDL_PushEvent — Pushes an event onto the event queue
SDL_SetEventFilter — Sets up a filter to process all events before they are posted +to the event queue.
SDL_GetEventFilter — Retrieves a pointer to he event filter
SDL_EventState — This function allows you to set the state of processing certain events.
SDL_GetKeyState — Get a snapshot of the current keyboard state
SDL_GetModState — Get the state of modifier keys.
SDL_SetModState — Set the current key modifier state
SDL_GetKeyName — Get the name of an SDL virtual keysym
SDL_EnableUNICODE — Enable UNICODE translation
SDL_EnableKeyRepeat — Set keyboard repeat rate.
SDL_GetMouseState — Retrieve the current state of the mouse
SDL_GetRelativeMouseState — Retrieve the current state of the mouse
SDL_GetAppState — Get the state of the application
SDL_JoystickEventState — Enable/disable joystick event polling

PrevHomeNext
SDLKeyUpSDL_PumpEvents
\ No newline at end of file diff --git a/contrib/sdk/sources/SDL-1.2.2/docs/html/eventstructures.html b/contrib/sdk/sources/SDL-1.2.2/docs/html/eventstructures.html new file mode 100644 index 000000000..8184019f1 --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/docs/html/eventstructures.html @@ -0,0 +1,220 @@ +SDL Event Structures.
SDL Library Documentation
PrevChapter 8. EventsNext

SDL Event Structures.

Table of Contents
SDL_Event — General event structure
SDL_ActiveEvent — Application visibility event structure
SDL_KeyboardEvent — Keyboard event structure
SDL_MouseMotionEvent — Mouse motion event structure
SDL_MouseButtonEvent — Mouse button event structure
SDL_JoyAxisEvent — Joystick axis motion event structure
SDL_JoyButtonEvent — Joystick button event structure
SDL_JoyHatEvent — Joystick hat position change event structure
SDL_JoyBallEvent — Joystick trackball motion event structure
SDL_ResizeEvent — Window resize event structure
SDL_SysWMEvent — Platform-dependent window manager event.
SDL_UserEvent — A user-defined event type
SDL_QuitEvent — Quit requested event
SDL_keysym — Keysym structure
SDLKey — Keysym definitions.

PrevHomeNext
EventsUpSDL_Event
\ No newline at end of file diff --git a/contrib/sdk/sources/SDL-1.2.2/docs/html/general.html b/contrib/sdk/sources/SDL-1.2.2/docs/html/general.html new file mode 100644 index 000000000..af85763a4 --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/docs/html/general.html @@ -0,0 +1,207 @@ +General
SDL Library Documentation
PrevNext

Chapter 5. General

Table of Contents
SDL_Init — Initializes SDL
SDL_InitSubSystem — Initialize subsystems
SDL_QuitSubSystem — Shut down a subsystem
SDL_Quit — Shut down SDL
SDL_WasInit — Check which subsystems are initialized

Before SDL can be used in a program it must be initialized with SDL_Init. SDL_Init initializes all the subsystems that the user requests (video, audio, joystick, timers and/or cdrom). Once SDL is initialized with SDL_Init subsystems can be shut down and initialized as needed using SDL_InitSubSystem and SDL_QuitSubSystem.

SDL must also be shut down before the program exits to make sure it cleans up correctly. Calling SDL_Quit shuts down all subsystems and frees any resources allocated to SDL.


PrevHomeNext
SDL ReferenceUpSDL_Init
\ No newline at end of file diff --git a/contrib/sdk/sources/SDL-1.2.2/docs/html/guide.html b/contrib/sdk/sources/SDL-1.2.2/docs/html/guide.html new file mode 100644 index 000000000..44d74321d --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/docs/html/guide.html @@ -0,0 +1,167 @@ +SDL Guide
SDL Library Documentation
PrevNext

I. SDL Guide


PrevHomeNext
SDL Library Documentation Preface
\ No newline at end of file diff --git a/contrib/sdk/sources/SDL-1.2.2/docs/html/guideaboutsdldoc.html b/contrib/sdk/sources/SDL-1.2.2/docs/html/guideaboutsdldoc.html new file mode 100644 index 000000000..f62dc3296 --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/docs/html/guideaboutsdldoc.html @@ -0,0 +1,140 @@ +About SDLdoc
SDL Library Documentation
PrevPrefaceNext

About SDLdoc

SDLdoc (The SDL Documentation Project) was formed to completely rewrite the SDL documentation and to keep it continually up to date. The team consists completely of volunteers ranging from people working with SDL in their spare time to people who use SDL in their everyday working lives.

The latest version of this documentation can always be found here: http://sdldoc.csn.ul.ie Downloadable PS, man pages and html tarballs are available at http://sdldoc.csn.ul.ie/pub/


PrevHomeNext
PrefaceUpCredits
\ No newline at end of file diff --git a/contrib/sdk/sources/SDL-1.2.2/docs/html/guideaudioexamples.html b/contrib/sdk/sources/SDL-1.2.2/docs/html/guideaudioexamples.html new file mode 100644 index 000000000..8e52470cb --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/docs/html/guideaudioexamples.html @@ -0,0 +1,220 @@ +Audio Examples
SDL Library Documentation
PrevChapter 4. ExamplesNext

Audio Examples

Opening the audio device

    SDL_AudioSpec wanted;
+    extern void fill_audio(void *udata, Uint8 *stream, int len);
+
+    /* Set the audio format */
+    wanted.freq = 22050;
+    wanted.format = AUDIO_S16;
+    wanted.channels = 2;    /* 1 = mono, 2 = stereo */
+    wanted.samples = 1024;  /* Good low-latency value for callback */
+    wanted.callback = fill_audio;
+    wanted.userdata = NULL;
+
+    /* Open the audio device, forcing the desired format */
+    if ( SDL_OpenAudio(&wanted, NULL) < 0 ) {
+        fprintf(stderr, "Couldn't open audio: %s\n", SDL_GetError());
+        return(-1);
+    }
+    return(0);

Playing audio

    static Uint8 *audio_chunk;
+    static Uint32 audio_len;
+    static Uint8 *audio_pos;
+
+    /* The audio function callback takes the following parameters:
+       stream:  A pointer to the audio buffer to be filled
+       len:     The length (in bytes) of the audio buffer
+    */
+    void fill_audio(void *udata, Uint8 *stream, int len)
+    {
+        /* Only play if we have data left */
+        if ( audio_len == 0 )
+            return;
+
+        /* Mix as much data as possible */
+        len = ( len > audio_len ? audio_len : len );
+        SDL_MixAudio(stream, audio_pos, len, SDL_MIX_MAXVOLUME)
+        audio_pos += len;
+        audio_len -= len;
+    }
+
+    /* Load the audio data ... */
+
+    ;;;;;
+
+    audio_pos = audio_chunk;
+
+    /* Let the callback function play the audio chunk */
+    SDL_PauseAudio(0);
+
+    /* Do some processing */
+
+    ;;;;;
+
+    /* Wait for sound to complete */
+    while ( audio_len > 0 ) {
+        SDL_Delay(100);         /* Sleep 1/10 second */
+    }
+    SDL_CloseAudio();


PrevHomeNext
Event ExamplesUpCDROM Examples
\ No newline at end of file diff --git a/contrib/sdk/sources/SDL-1.2.2/docs/html/guidebasicsinit.html b/contrib/sdk/sources/SDL-1.2.2/docs/html/guidebasicsinit.html new file mode 100644 index 000000000..05f8cab17 --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/docs/html/guidebasicsinit.html @@ -0,0 +1,232 @@ +Initializing SDL
SDL Library Documentation
PrevChapter 1. The BasicsNext

Initializing SDL

SDL is composed of eight subsystems - Audio, CDROM, Event Handling, File I/O, Joystick Handling, Threading, Timers and Video. Before you can use any of these subsystems they must be initialized by calling SDL_Init (or SDL_InitSubSystem. SDL_Init must be called before any other SDL function. It automatically initializes the Event Handling, File I/O and Threading subsystems and it takes a parameter specifying which other subsystems to initialize. So, to initialize the default subsystems and the Video subsystems you would call: +

    SDL_Init ( SDL_INIT_VIDEO );
+To initialize the default subsystems, the Video subsystem and the Timers subsystem you would call: +
    SDL_Init ( SDL_INIT_VIDEO | SDL_INIT_TIMER );

SDL_Init is complemented by SDL_Quit (and SDL_QuitSubSystem). SDL_Quit shuts down all subsystems, including the default ones. It should always be called before a SDL application exits.

With SDL_Init and SDL_Quit firmly embedded in your programmers toolkit you can write your first and most basic SDL application. However, we must be prepare to handle errors. Many SDL functions return a value and indicates whether the function has succeeded or failed, SDL_Init, for instance, returns -1 if it could not initialize a subsystem. SDL provides a useful facility that allows you to determine exactly what the problem was, every time an error occurs within SDL an error message is stored which can be retrieved using SDL_GetError. Use this often, you can never know too much about an error.

Example 1-1. Initializing SDL

#include "SDL.h"   /* All SDL App's need this */
+#include <stdio.h>
+
+int main() {
+    
+    printf("Initializing SDL.\n");
+    
+    /* Initialize defaults, Video and Audio */
+    if((SDL_Init(SDL_INIT_VIDEO|SDL_INIT_AUDIO)==-1)) { 
+        printf("Could not initialize SDL: %s.\n", SDL_GetError());
+        exit(-1);
+    }
+
+    printf("SDL initialized.\n");
+
+    printf("Quiting SDL.\n");
+    
+    /* Shutdown all subsystems */
+    SDL_Quit();
+    
+    printf("Quiting....\n");
+
+    exit(0);
+}

PrevHomeNext
The BasicsUpGraphics and Video
\ No newline at end of file diff --git a/contrib/sdk/sources/SDL-1.2.2/docs/html/guidecdromexamples.html b/contrib/sdk/sources/SDL-1.2.2/docs/html/guidecdromexamples.html new file mode 100644 index 000000000..917a1a3c0 --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/docs/html/guidecdromexamples.html @@ -0,0 +1,267 @@ +CDROM Examples
SDL Library Documentation
PrevChapter 4. ExamplesNext

CDROM Examples

Listing CD-ROM drives

    #include "SDL.h"
+
+    /* Initialize SDL first */
+    if ( SDL_Init(SDL_INIT_CDROM) < 0 ) {
+        fprintf(stderr, "Couldn't initialize SDL: %s\n",SDL_GetError());
+        exit(1);
+    }
+    atexit(SDL_Quit);
+
+    /* Find out how many CD-ROM drives are connected to the system */
+    printf("Drives available: %d\n", SDL_CDNumDrives());
+    for ( i=0; i<SDL_CDNumDrives(); ++i ) {
+        printf("Drive %d:  \"%s\"\n", i, SDL_CDName(i));
+    }

Opening the default drive

    SDL_CD *cdrom;
+    CDstatus status;
+    char *status_str;
+
+    cdrom = SDL_CDOpen(0);
+    if ( cdrom == NULL ) {
+        fprintf(stderr, "Couldn't open default CD-ROM drive: %s\n",
+                        SDL_GetError());
+        exit(2);
+    }
+
+    status = SDL_CDStatus(cdrom);
+    switch (status) {
+        case CD_TRAYEMPTY:
+            status_str = "tray empty";
+            break;
+        case CD_STOPPED:
+            status_str = "stopped";
+            break;
+        case CD_PLAYING:
+            status_str = "playing";
+            break;
+        case CD_PAUSED:
+            status_str = "paused";
+            break;
+        case CD_ERROR:
+            status_str = "error state";
+            break;
+    }
+    printf("Drive status: %s\n", status_str);
+    if ( status >= CD_PLAYING ) {
+        int m, s, f;
+        FRAMES_TO_MSF(cdrom->cur_frame, &m, &s, &f);
+        printf("Currently playing track %d, %d:%2.2d\n",
+        cdrom->track[cdrom->cur_track].id, m, s);
+    }

Listing the tracks on a CD

    SDL_CD *cdrom;          /* Assuming this has already been set.. */
+    int i;
+    int m, s, f;
+
+    SDL_CDStatus(cdrom);
+    printf("Drive tracks: %d\n", cdrom->numtracks);
+    for ( i=0; i<cdrom->numtracks; ++i ) {
+        FRAMES_TO_MSF(cdrom->track[i].length, &m, &s, &f);
+        if ( f > 0 )
+            ++s;
+        printf("\tTrack (index %d) %d: %d:%2.2d\n", i,
+        cdrom->track[i].id, m, s);
+    }

Play an entire CD

    SDL_CD *cdrom;          /* Assuming this has already been set.. */
+
+    // Play entire CD:
+    if ( CD_INDRIVE(SDL_CDStatus(cdrom)) )
+        SDL_CDPlayTracks(cdrom, 0, 0, 0, 0);
+
+        // Play last track:
+        if ( CD_INDRIVE(SDL_CDStatus(cdrom)) ) {
+            SDL_CDPlayTracks(cdrom, cdrom->numtracks-1, 0, 0, 0);
+        }
+
+        // Play first and second track and 10 seconds of third track:
+        if ( CD_INDRIVE(SDL_CDStatus(cdrom)) )
+            SDL_CDPlayTracks(cdrom, 0, 0, 2, 10);


PrevHomeNext
Audio ExamplesUpTime Examples
\ No newline at end of file diff --git a/contrib/sdk/sources/SDL-1.2.2/docs/html/guidecredits.html b/contrib/sdk/sources/SDL-1.2.2/docs/html/guidecredits.html new file mode 100644 index 000000000..19e55c067 --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/docs/html/guidecredits.html @@ -0,0 +1,187 @@ +Credits
SDL Library Documentation
PrevPrefaceNext

Credits

Sam Lantinga, slouken@libsdl.org
Martin Donlon, akawaka@skynet.ie
Mattias Engdegård
Julian Peterson
Ken Jordan
Maxim Sobolev
Wesley Poole
Michael Vance
Andreas Umbach
Andreas Hofmeister


PrevHomeNext
About SDLdocUpThe Basics
\ No newline at end of file diff --git a/contrib/sdk/sources/SDL-1.2.2/docs/html/guideeventexamples.html b/contrib/sdk/sources/SDL-1.2.2/docs/html/guideeventexamples.html new file mode 100644 index 000000000..dd866839a --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/docs/html/guideeventexamples.html @@ -0,0 +1,239 @@ +Event Examples
SDL Library Documentation
PrevChapter 4. ExamplesNext

Event Examples

Filtering and Handling Events

#include <stdio.h>
+#include <stdlib.h>
+
+#include "SDL.h"
+
+/* This function may run in a separate event thread */
+int FilterEvents(const SDL_Event *event) {
+    static int boycott = 1;
+
+    /* This quit event signals the closing of the window */
+    if ( (event->type == SDL_QUIT) && boycott ) {
+        printf("Quit event filtered out -- try again.\n");
+        boycott = 0;
+        return(0);
+    }
+    if ( event->type == SDL_MOUSEMOTION ) {
+        printf("Mouse moved to (%d,%d)\n",
+                event->motion.x, event->motion.y);
+        return(0);    /* Drop it, we've handled it */
+    }
+    return(1);
+}
+
+int main(int argc, char *argv[])
+{
+    SDL_Event event;
+
+    /* Initialize the SDL library (starts the event loop) */
+    if ( SDL_Init(SDL_INIT_VIDEO) < 0 ) {
+        fprintf(stderr,
+                "Couldn't initialize SDL: %s\n", SDL_GetError());
+        exit(1);
+    }
+
+    /* Clean up on exit, exit on window close and interrupt */
+    atexit(SDL_Quit);
+
+    /* Ignore key events */
+    SDL_EventState(SDL_KEYDOWN, SDL_IGNORE);
+    SDL_EventState(SDL_KEYUP, SDL_IGNORE);
+
+    /* Filter quit and mouse motion events */
+    SDL_SetEventFilter(FilterEvents);
+
+    /* The mouse isn't much use unless we have a display for reference */
+    if ( SDL_SetVideoMode(640, 480, 8, 0) == NULL ) {
+        fprintf(stderr, "Couldn't set 640x480x8 video mode: %s\n",
+                        SDL_GetError());
+        exit(1);
+    }
+
+    /* Loop waiting for ESC+Mouse_Button */
+    while ( SDL_WaitEvent(&event) >= 0 ) {
+        switch (event.type) {
+            case SDL_ACTIVEEVENT: {
+                if ( event.active.state & SDL_APPACTIVE ) {
+                    if ( event.active.gain ) {
+                        printf("App activated\n");
+                    } else {
+                        printf("App iconified\n");
+                    }
+                }
+            }
+            break;
+                    
+            case SDL_MOUSEBUTTONDOWN: {
+                Uint8 *keys;
+
+                keys = SDL_GetKeyState(NULL);
+                if ( keys[SDLK_ESCAPE] == SDL_PRESSED ) {
+                    printf("Bye bye...\n");
+                    exit(0);
+                }
+                printf("Mouse button pressed\n");
+            }
+            break;
+
+            case SDL_QUIT: {
+                printf("Quit requested, quitting.\n");
+                exit(0);
+            }
+            break;
+        }
+    }
+    /* This should never happen */
+    printf("SDL_WaitEvent error: %s\n", SDL_GetError());
+    exit(1);
+}


PrevHomeNext
ExamplesUpAudio Examples
\ No newline at end of file diff --git a/contrib/sdk/sources/SDL-1.2.2/docs/html/guideexamples.html b/contrib/sdk/sources/SDL-1.2.2/docs/html/guideexamples.html new file mode 100644 index 000000000..e1698eb36 --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/docs/html/guideexamples.html @@ -0,0 +1,180 @@ +Examples
SDL Library Documentation
PrevNext

Chapter 4. Examples

Introduction

For the moment these examples are taken directly from the old SDL documentation. By the 1.2 release these examples should hopefully deal with most common SDL programming problems.


PrevHomeNext
Handling the KeyboardUpEvent Examples
\ No newline at end of file diff --git a/contrib/sdk/sources/SDL-1.2.2/docs/html/guideinput.html b/contrib/sdk/sources/SDL-1.2.2/docs/html/guideinput.html new file mode 100644 index 000000000..0ad9232c9 --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/docs/html/guideinput.html @@ -0,0 +1,731 @@ +Input handling
SDL Library Documentation
PrevNext

Chapter 3. Input handling

Handling Joysticks

Initialization

The first step in using a joystick in a SDL program is to initialize the Joystick subsystems of SDL. This done by passing the SDL_INIT_JOYSTICK flag to SDL_Init. The joystick flag will usually be used in conjunction with other flags (like the video flag) because the joystick is usually used to control something.

Example 3-1. Initializing SDL with Joystick Support

    if (SDL_Init( SDL_INIT_VIDEO | SDL_INIT_JOYSTICK ) < 0)
+    {
+        fprintf(stderr, "Couldn't initialize SDL: %s\n", SDL_GetError());
+        exit(1);
+    }

This will attempt to start SDL with both the video and the joystick subsystems activated.

Querying

If we have reached this point then we can safely assume that the SDL library has been initialized and that the Joystick subsystem is active. We can now call some video and/or sound functions to get things going before we need the joystick. Eventually we have to make sure that there is actually a joystick to work with. It's wise to always check even if you know a joystick will be present on the system because it can also help detect when the joystick is unplugged. The function used to check for joysticks is SDL_NumJoysticks.

This function simply returns the number of joysticks available on the system. If it is at least one then we are in good shape. The next step is to determine which joystick the user wants to use. If the number of joysticks available is only one then it is safe to assume that one joystick is the one the user wants to use. SDL has a function to get the name of the joysticks as assigned by the operations system and that function is SDL_JoystickName. The joystick is specified by an index where 0 is the first joystick and the last joystick is the number returned by SDL_NumJoysticks - 1. In the demonstration a list of all available joysticks is printed to stdout.

Example 3-2. Querying the Number of Available Joysticks

    printf("%i joysticks were found.\n\n", SDL_NumJoysticks() );
+    printf("The names of the joysticks are:\n");
+		
+    for( i=0; i < SDL_NumJoysticks(); i++ ) 
+    {
+        printf("    %s\n", SDL_JoystickName(i));
+    }

Opening a Joystick and Receiving Joystick Events

SDL's event driven architecture makes working with joysticks a snap. Joysticks can trigger 4 different types of events: +

SDL_JoyAxisEventOccurs when an axis changes
SDL_JoyBallEventOccurs when a joystick trackball's position changes
SDL_JoyHatEventOccurs when a hat's position changes
SDL_JoyButtonEventOccurs when a button is pressed or released

Events are received from all joysticks opened. The first thing that needs to be done in order to receive joystick events is to call SDL_JoystickEventState with the SDL_ENABLE flag. Next you must open the joysticks that you want to receive envents from. This is done with the SDL_JoystickOpen function. For the example we are only interested in events from the first joystick on the system, regardless of what it may be. To receive events from it we would do this:

Example 3-3. Opening a Joystick

    SDL_Joystick *joystick;
+
+    SDL_JoystickEventState(SDL_ENABLE);
+    joystick = SDL_JoystickOpen(0);

If we wanted to receive events for other joysticks we would open them with calls to SDL_JoystickOpen just like we opened joystick 0, except we would store the SDL_Joystick structure they return in a different pointer. We only need the joystick pointer when we are querying the joysticks or when we are closing the joystick.

Up to this point all the code we have is used just to initialize the joysticks in order to read values at run time. All we need now is an event loop, which is something that all SDL programs should have anyway to receive the systems quit events. We must now add code to check the event loop for at least some of the above mentioned events. Let's assume our event loop looks like this: +

    SDL_Event event;
+    /* Other initializtion code goes here */   
+
+    /* Start main game loop here */
+
+    while(SDL_PollEvent(&event))
+    {  
+        switch(event.type)
+        {  
+            case SDL_KEYDOWN:
+            /* handle keyboard stuff here */				
+            break;
+
+            case SDL_QUIT:
+            /* Set whatever flags are necessary to */
+            /* end the main game loop here */
+            break;
+        }
+    }
+
+    /* End loop here */
+To handle Joystick events we merely add cases for them, first we'll add axis handling code. Axis checks can get kinda of tricky because alot of the joystick events received are junk. Joystick axis have a tendency to vary just a little between polling due to the way they are designed. To compensate for this you have to set a threshold for changes and ignore the events that have'nt exceeded the threshold. 10% is usually a good threshold value. This sounds a lot more complicated than it is. Here is the Axis event handler:

Example 3-4. Joystick Axis Events

    case SDL_JOYAXISMOTION:  /* Handle Joystick Motion */
+    if ( ( event.jaxis.value < -3200 ) || (event.jaxis.value > 3200 ) ) 
+    {
+      /* code goes here */
+    }
+    break;

Another trick with axis events is that up-down and left-right movement are two different sets of axes. The most important axis is axis 0 (left-right) and axis 1 (up-down). To handle them seperatly in the code we do the following:

Example 3-5. More Joystick Axis Events

    case SDL_JOYAXISMOTION:  /* Handle Joystick Motion */
+    if ( ( event.jaxis.value < -3200 ) || (event.jaxis.value > 3200 ) ) 
+    {
+        if( event.jaxis.axis == 0) 
+        {
+            /* Left-right movement code goes here */
+        }
+
+        if( event.jaxis.axis == 1) 
+        {
+            /* Up-Down movement code goes here */
+        }
+    }
+    break;

Ideally the code here should use event.jaxis.value to scale something. For example lets assume you are using the joystick to control the movement of a spaceship. If the user is using an analog joystick and they push the stick a little bit they expect to move less than if they pushed it a lot. Designing your code for this situation is preferred because it makes the experience for users of analog controls better and remains the same for users of digital controls.

If your joystick has any additional axis then they may be used for other sticks or throttle controls and those axis return values too just with different event.jaxis.axis values.

Button handling is simple compared to the axis checking.

Example 3-6. Joystick Button Events

    case SDL_JOYBUTTONDOWN:  /* Handle Joystick Button Presses */
+    if ( event.jbutton.button == 0 ) 
+    {
+        /* code goes here */
+    }
+    break;

Button checks are simpler than axis checks because a button can only be pressed or not pressed. The SDL_JOYBUTTONDOWN event is triggered when a button is pressed and the SDL_JOYBUTTONUP event is fired when a button is released. We do have to know what button was pressed though, that is done by reading the event.jbutton.button field.

Lastly when we are through using our joysticks we should close them with a call to SDL_JoystickClose. To close our opened joystick 0 we would do this at the end of our program: +

    SDL_JoystickClose(joystick);

Advanced Joystick Functions

That takes care of the controls that you can count on being on every joystick under the sun, but there are a few extra things that SDL can support. Joyballs are next on our list, they are alot like axis we a few minor differences. Joyballs store relative changes unlike the the absolute postion stored in a axis event. Also one trackball event contains both the change in x and they change in y. Our case for it is as follows:

Example 3-7. Joystick Ball Events

    case SDL_JOYBALLMOTION:  /* Handle Joyball Motion */
+    if( event.jball.ball == 0 )
+    {
+      /* ball handling */
+    }
+    break;

The above checks the first joyball on the joystick. The change in position will be stored in event.jball.xrel and event.jball.yrel.

Finally we have the hat event. Hats report only the direction they are pushed in. We check hat's position with the bitmasks: + +

SDL_HAT_CENTERED
SDL_HAT_UP
SDL_HAT_RIGHT
SDL_HAT_DOWN
SDL_HAT_LEFT

+ +Also there are some predefined combinations of the above: +

SDL_HAT_RIGHTUP
SDL_HAT_RIGHTDOWN
SDL_HAT_LEFTUP
SDL_HAT_LEFTDOWN

+ +Our case for the hat may resemble the following:

Example 3-8. Joystick Hat Events

    case SDL_JOYHATMOTION:  /* Handle Hat Motion */
+    if ( event.jhat.hat | SDL_HAT_UP )
+    {
+        /* Do up stuff here */
+    }
+
+    if ( event.jhat.hat | SDL_HAT_LEFT )
+    {
+        /* Do left stuff here */
+    }
+
+    if ( event.jhat.hat | SDL_HAT_RIGHTDOWN )
+    {
+        /* Do right and down together stuff here */
+    }
+    break;

In addition to the queries for number of joysticks on the system and their names there are additional functions to query the capabilities of attached joysticks: +

SDL_JoystickNumAxesReturns the number of joysitck axes
SDL_JoystickNumButtonsReturns the number of joysitck buttons
SDL_JoystickNumBallsReturns the number of joysitck balls
SDL_JoystickNumHatsReturns the number of joysitck hats

+ +To use these functions we just have to pass in the joystick structure we got when we opened the joystick. For Example:

Example 3-9. Querying Joystick Characteristics

    int number_of_buttons;
+    SDL_Joystick *joystick;
+
+    joystick = SDL_JoystickOpen(0);
+    number_of_buttons = SDL_JoystickNumButtons(joystick);

This block of code would get the number of buttons on the first joystick in the system.


PrevHomeNext
Using OpenGL With SDLUpHandling the Keyboard
\ No newline at end of file diff --git a/contrib/sdk/sources/SDL-1.2.2/docs/html/guideinputkeyboard.html b/contrib/sdk/sources/SDL-1.2.2/docs/html/guideinputkeyboard.html new file mode 100644 index 000000000..d15875800 --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/docs/html/guideinputkeyboard.html @@ -0,0 +1,735 @@ +Handling the Keyboard
SDL Library Documentation
PrevChapter 3. Input handlingNext

Handling the Keyboard

Keyboard Related Structures

It should make it a lot easier to understand this tutorial is you are familiar with the data types involved in keyboard access, so I'll explain them first.

SDLKey

SDLKey is an enumerated type defined in SDL/include/SDL_keysym.h and detailed here. Each SDLKey symbol represents a key, SDLK_a corresponds to the 'a' key on a keyboard, SDLK_SPACE corresponds to the space bar, and so on.

SDLMod

SDLMod is an enumerated type, similar to SDLKey, however it enumerates keyboard modifiers (Control, Alt, Shift). The full list of modifier symbols is here. SDLMod values can be AND'd together to represent several modifiers.

SDL_keysym

typedef struct{
+  Uint8 scancode;
+  SDLKey sym;
+  SDLMod mod;
+  Uint16 unicode;
+} SDL_keysym;

The SDL_keysym structure describes a key press or a key release. The scancode field is hardware specific and should be ignored unless you know what your doing. The sym field is the SDLKey value of the key being pressed or released. The mod field describes the state of the keyboard modifiers at the time the key press or release occurred. So a value of KMOD_NUM | KMOD_CAPS | KMOD_LSHIFT would mean that Numlock, Capslock and the left shift key were all press (or enabled in the case of the lock keys). Finally, the unicode field stores the 16-bit unicode value of the key.

Note: It should be noted and understood that this field is only valid when the SDL_keysym is describing a key press, not a key release. Unicode values only make sense on a key press because the unicode value describes an international character and only key presses produce characters. More information on Unicode can be found at www.unicode.org

Note: Unicode translation must be enabled using the SDL_EnableUNICODE function.

SDL_KeyboardEvent

typedef struct{
+  Uint8 type;
+  Uint8 state;
+  SDL_keysym keysym;
+} SDL_KeyboardEvent;

The SDL_KeyboardEvent describes a keyboard event (obviously). The key member of the SDL_Event union is a SDL_KeyboardEvent structure. The type field specifies whether the event is a key release (SDL_KEYUP) or a key press (SDL_KEYDOWN) event. The state is largely redundant, it reports the same information as the type field but uses different values (SDL_RELEASED and SDL_PRESSED). The keysym contains information of the key press or release that this event represents (see above).

Reading Keyboard Events

Reading keybaord events from the event queue is quite simple (the event queue and using it is described here). We read events using SDL_PollEvent in a while() loop and check for SDL_KEYUP and SDL_KEYDOWN events using a switch statement, like so:

Example 3-10. Reading Keyboard Events

  SDL_Event event;
+  .
+  .
+  /* Poll for events. SDL_PollEvent() returns 0 when there are no  */
+  /* more events on the event queue, our while loop will exit when */
+  /* that occurs.                                                  */
+  while( SDL_PollEvent( &event ) ){
+    /* We are only worried about SDL_KEYDOWN and SDL_KEYUP events */
+    switch( event.type ){
+      case SDL_KEYDOWN:
+        printf( "Key press detected\n" );
+        break;
+
+      case SDL_KEYUP:
+        printf( "Key release detected\n" );
+        break;
+
+      default:
+        break;
+    }
+  }
+  .
+  .

This is a very basic example. No information about the key press or release is interpreted. We will explore the other extreme out our first full example below - reporting all available information about a keyboard event.

A More Detailed Look

Before we can read events SDL must be initialised with SDL_Init and a video mode must be set using SDL_SetVideoMode. There are, however, two other functions we must use to obtain all the information required. We must enable unicode translation by calling SDL_EnableUNICODE(1) and we must convert SDLKey values into something printable, using SDL_GetKeyName

Note: It is useful to note that unicode values < 0x80 translate directly a characters ASCII value. THis is used in the example below

Example 3-11. Interpreting Key Event Information


    #include "SDL.h"
+
+    /* Function Prototypes */
+    void PrintKeyInfo( SDL_KeyboardEvent *key );
+    void PrintModifiers( SDLMod mod );
+
+    /* main */
+    int main( int argc, char *argv[] ){
+        
+        SDL_Event event;
+        int quit = 0;
+        
+        /* Initialise SDL */
+        if( SDL_Init( SDL_INIT_VIDEO ) < 0){
+            fprintf( stderr, "Could not initialise SDL: %s\n", SDL_GetError() );
+            exit( -1 );
+        }
+
+        /* Set a video mode */
+        if( !SDL_SetVideoMode( 320, 200, 0, 0 ) ){
+            fprintf( stderr, "Could not set video mode: %s\n", SDL_GetError() );
+            SDL_Quit();
+            exit( -1 );
+        }
+
+        /* Enable Unicode translation */
+        SDL_EnableUNICODE( 1 );
+
+        /* Loop until an SDL_QUIT event is found */
+        while( !quit ){
+
+            /* Poll for events */
+            while( SDL_PollEvent( &event ) ){
+                
+                switch( event.type ){
+                    /* Keyboard event */
+                    /* Pass the event data onto PrintKeyInfo() */
+                    case SDL_KEYDOWN:
+                    case SDL_KEYUP:
+                        PrintKeyInfo( &event.key );
+                        break;
+
+                    /* SDL_QUIT event (window close) */
+                    case SDL_QUIT:
+                        quit = 1;
+                        break;
+
+                    default:
+                        break;
+                }
+
+            }
+
+        }
+
+        /* Clean up */
+        SDL_Quit();
+        exit( 0 );
+    }
+
+    /* Print all information about a key event */
+    void PrintKeyInfo( SDL_KeyboardEvent *key ){
+        /* Is it a release or a press? */
+        if( key->type == SDL_KEYUP )
+            printf( "Release:- " );
+        else
+            printf( "Press:- " );
+
+        /* Print the hardware scancode first */
+        printf( "Scancode: 0x%02X", key->keysym.scancode );
+        /* Print the name of the key */
+        printf( ", Name: %s", SDL_GetKeyName( key->keysym.sym ) );
+        /* We want to print the unicode info, but we need to make */
+        /* sure its a press event first (remember, release events */
+        /* don't have unicode info                                */
+        if( key->type == SDL_KEYDOWN ){
+            /* If the Unicode value is less than 0x80 then the    */
+            /* unicode value can be used to get a printable       */
+            /* representation of the key, using (char)unicode.    */
+            printf(", Unicode: " );
+            if( key->keysym.unicode < 0x80 && key->keysym.unicode > 0 ){
+                printf( "%c (0x%04X)", (char)key->keysym.unicode,
+                        key->keysym.unicode );
+            }
+            else{
+                printf( "? (0x%04X)", key->keysym.unicode );
+            }
+        }
+        printf( "\n" );
+        /* Print modifier info */
+        PrintModifiers( key->keysym.mod );
+    }
+
+    /* Print modifier info */
+    void PrintModifiers( SDLMod mod ){
+        printf( "Modifers: " );
+
+        /* If there are none then say so and return */
+        if( mod == KMOD_NONE ){
+            printf( "None\n" );
+            return;
+        }
+
+        /* Check for the presence of each SDLMod value */
+        /* This looks messy, but there really isn't    */
+        /* a clearer way.                              */
+        if( mod & KMOD_NUM ) printf( "NUMLOCK " );
+        if( mod & KMOD_CAPS ) printf( "CAPSLOCK " );
+        if( mod & KMOD_LCTRL ) printf( "LCTRL " );
+        if( mod & KMOD_RCTRL ) printf( "RCTRL " );
+        if( mod & KMOD_RSHIFT ) printf( "RSHIFT " );
+        if( mod & KMOD_LSHIFT ) printf( "LSHIFT " );
+        if( mod & KMOD_RALT ) printf( "RALT " );
+        if( mod & KMOD_LALT ) printf( "LALT " );
+        if( mod & KMOD_CTRL ) printf( "CTRL " );
+        if( mod & KMOD_SHIFT ) printf( "SHIFT " );
+        if( mod & KMOD_ALT ) printf( "ALT " );
+        printf( "\n" );
+    }

Game-type Input

I have found that people using keyboard events for games and other interactive applications don't always understand one fundemental point.

Keyboard events only take place when a keys state changes from being unpressed to pressed, and vice versa.

Imagine you have an image of an alien that you wish to move around using the cursor keys - when you pressed the left arrow key you want him to slide over to the left, when you press the down key you want him to slide down the screen. Examine the following code, it highlights and error that many people have made. +

    /* Alien screen coordinates */
+    int alien_x=0, alien_y=0;
+    .
+    .
+    /* Initialise SDL and video modes and all that */
+    .
+    /* Main game loop */
+    /* Check for events */
+    while( SDL_PollEvent( &event ) ){
+        switch( event.type ){
+            /* Look for a keypress */
+            case SDL_KEYDOWN:
+                /* Check the SDLKey values and move change the coords */
+                switch( event.key.keysym.sym ){
+                    case SDLK_LEFT:
+                        alien_x -= 1;
+                        break;
+                    case SDLK_RIGHT:
+                        alien_x += 1;
+                        break;
+                    case SDLK_UP:
+                        alien_y -= 1;
+                        break;
+                    case SDLK_DOWN:
+                        alien_y += 1;
+                        break;
+                    default:
+                        break;
+                }
+            }
+        }
+    }
+    .
+    .
+At first glance you may think this is a perfectly reasonable piece of code for the task, but it isn't. Like I said keyboard events only occur when a key changes state, so the user would have to press and release the left cursor key 100 times to move the alien 100 pixels to the left.

To get around this problem we must not use the events to change the position of the alien, we use the events to set flags which are then used in a seperate section of code to move the alien. Something like this:

Example 3-12. Proper Game Movement

    /* Alien screen coordinates */
+    int alien_x=0, alien_y=0;
+    int alien_xvel=0, alien_yvel=0;
+    .
+    .
+    /* Initialise SDL and video modes and all that */
+    .
+    /* Main game loop */
+    /* Check for events */
+    while( SDL_PollEvent( &event ) ){
+        switch( event.type ){
+            /* Look for a keypress */
+            case SDL_KEYDOWN:
+                /* Check the SDLKey values and move change the coords */
+                switch( event.key.keysym.sym ){
+                    case SDLK_LEFT:
+                        alien_xvel = -1;
+                        break;
+                    case SDLK_RIGHT:
+                        alien_xvel =  1;
+                        break;
+                    case SDLK_UP:
+                        alien_yvel = -1;
+                        break;
+                    case SDLK_DOWN:
+                        alien_yvel =  1;
+                        break;
+                    default:
+                        break;
+                }
+                break;
+            /* We must also use the SDL_KEYUP events to zero the x */
+            /* and y velocity variables. But we must also be       */
+            /* careful not to zero the velocities when we shouldn't*/
+            case SDL_KEYUP:
+                switch( event.key.keysym.sym ){
+                    case SDLK_LEFT:
+                        /* We check to make sure the alien is moving */
+                        /* to the left. If it is then we zero the    */
+                        /* velocity. If the alien is moving to the   */
+                        /* right then the right key is still press   */
+                        /* so we don't tocuh the velocity            */
+                        if( alien_xvel < 0 )
+                            alien_xvel = 0;
+                        break;
+                    case SDLK_RIGHT:
+                        if( alien_xvel > 0 )
+                            alien_xvel = 0;
+                        break;
+                    case SDLK_UP:
+                        if( alien_yvel < 0 )
+                            alien_yvel = 0;
+                        break;
+                    case SDLK_DOWN:
+                        if( alien_yvel > 0 )
+                            alien_yvel = 0;
+                        break;
+                    default:
+                        break;
+                }
+                break;
+            
+            default:
+                break;
+        }
+    }
+    .
+    .
+    /* Update the alien position */
+    alien_x += alien_xvel;
+    alien_y += alien_yvel;

As can be seen, we use two extra variables, alien_xvel and alien_yvel, which represent the motion of the ship, it is these variables that we update when we detect keypresses and releases.


PrevHomeNext
Input handlingUpExamples
\ No newline at end of file diff --git a/contrib/sdk/sources/SDL-1.2.2/docs/html/guidepreface.html b/contrib/sdk/sources/SDL-1.2.2/docs/html/guidepreface.html new file mode 100644 index 000000000..bb2323a7c --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/docs/html/guidepreface.html @@ -0,0 +1,170 @@ +Preface
SDL Library Documentation
PrevNext

Preface

About SDL

The SDL library is designed to make it easy to write games that run on Linux, *BSD, MacOS, Win32 and BeOS using the various native high-performance media interfaces, (for video, audio, etc) and presenting a single source-code level API to your application. SDL is a fairly low level API, but using it, completely portable applications can be written with a great deal of flexibility.


PrevHomeNext
SDL GuideUpAbout SDLdoc
\ No newline at end of file diff --git a/contrib/sdk/sources/SDL-1.2.2/docs/html/guidethebasics.html b/contrib/sdk/sources/SDL-1.2.2/docs/html/guidethebasics.html new file mode 100644 index 000000000..f594c292a --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/docs/html/guidethebasics.html @@ -0,0 +1,165 @@ +The Basics
SDL Library Documentation
PrevNext

Chapter 1. The Basics

Introduction

The SDL Guide section is pretty incomplete. If you feel you have anything to add mail akawaka@skynet.ie or visit http://akawaka.csn.ul.ie/tne/.


PrevHomeNext
CreditsUpInitializing SDL
\ No newline at end of file diff --git a/contrib/sdk/sources/SDL-1.2.2/docs/html/guidetimeexamples.html b/contrib/sdk/sources/SDL-1.2.2/docs/html/guidetimeexamples.html new file mode 100644 index 000000000..28b96945d --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/docs/html/guidetimeexamples.html @@ -0,0 +1,173 @@ +Time Examples
SDL Library Documentation
PrevChapter 4. ExamplesNext

Time Examples

Time based game loop

#define TICK_INTERVAL    30
+
+Uint32 TimeLeft(void)
+{
+    static Uint32 next_time = 0;
+    Uint32 now;
+
+    now = SDL_GetTicks();
+    if ( next_time <= now ) {
+        next_time = now+TICK_INTERVAL;
+        return(0);
+    }
+    return(next_time-now);
+}
+
+
+/* main game loop
+
+    while ( game_running ) {
+        UpdateGameState();
+        SDL_Delay(TimeLeft());
+    }


PrevHomeNext
CDROM ExamplesUpSDL Reference
\ No newline at end of file diff --git a/contrib/sdk/sources/SDL-1.2.2/docs/html/guidevideo.html b/contrib/sdk/sources/SDL-1.2.2/docs/html/guidevideo.html new file mode 100644 index 000000000..67fa7c654 --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/docs/html/guidevideo.html @@ -0,0 +1,455 @@ +Graphics and Video
SDL Library Documentation
PrevNext

Chapter 2. Graphics and Video

Introduction to SDL Video

Video is probably the most common thing that SDL is used for, and +so it has the most complete subsystem. Here are a few +examples to demonstrate the basics.

Initializing the Video Display

This is what almost all SDL programs have to do in one way or +another.

Example 2-1. Initializing the Video Display

    SDL_Surface *screen;
+
+    /* Initialize the SDL library */
+    if( SDL_Init(SDL_INIT_VIDEO) < 0 ) {
+        fprintf(stderr,
+                "Couldn't initialize SDL: %s\n", SDL_GetError());
+        exit(1);
+    }
+
+    /* Clean up on exit */
+    atexit(SDL_Quit);
+    
+    /*
+     * Initialize the display in a 640x480 8-bit palettized mode,
+     * requesting a software surface
+     */
+    screen = SDL_SetVideoMode(640, 480, 8, SDL_SWSURFACE);
+    if ( screen == NULL ) {
+        fprintf(stderr, "Couldn't set 640x480x8 video mode: %s\n",
+                        SDL_GetError());
+        exit(1);
+    }

Initializing the Best Video Mode

If you have a preference for a certain pixel depth but will accept any +other, use SDL_SetVideoMode with SDL_ANYFORMAT as below. You can also +use SDL_VideoModeOK() to find the native video mode that is closest to +the mode you request.

Example 2-2. Initializing the Best Video Mode

    /* Have a preference for 8-bit, but accept any depth */
+    screen = SDL_SetVideoMode(640, 480, 8, SDL_SWSURFACE|SDL_ANYFORMAT);
+    if ( screen == NULL ) {
+        fprintf(stderr, "Couldn't set 640x480x8 video mode: %s\n",
+                        SDL_GetError());
+        exit(1);
+    }
+    printf("Set 640x480 at %d bits-per-pixel mode\n",
+           screen->format->BitsPerPixel);

Loading and Displaying a BMP File

The following function loads and displays a BMP file given as +argument, once SDL is initialised and a video mode has been set.

Example 2-3. Loading and Displaying a BMP File

void display_bmp(char *file_name)
+{
+    SDL_Surface *image;
+
+    /* Load the BMP file into a surface */
+    image = SDL_LoadBMP(file_name);
+    if (image == NULL) {
+        fprintf(stderr, "Couldn't load %s: %s\n", file_name, SDL_GetError());
+        return;
+    }
+
+    /*
+     * Palettized screen modes will have a default palette (a standard
+     * 8*8*4 colour cube), but if the image is palettized as well we can
+     * use that palette for a nicer colour matching
+     */
+    if (image->format->palette && screen->format->palette) {
+    SDL_SetColors(screen, image->format->palette->colors, 0,
+                  image->format->palette->ncolors);
+    }
+
+    /* Blit onto the screen surface */
+    if(SDL_BlitSurface(image, NULL, screen, NULL) < 0)
+        fprintf(stderr, "BlitSurface error: %s\n", SDL_GetError());
+
+    SDL_UpdateRect(screen, 0, 0, image->w, image->h);
+
+    /* Free the allocated BMP surface */
+    SDL_FreeSurface(image);
+}

Drawing Directly to the Display

The following two functions can be used to get and set single +pixels of a surface. They are carefully written to work with any depth +currently supported by SDL. Remember to lock the surface before +calling them, and to unlock it before calling any other SDL +functions.

To convert between pixel values and their red, green, blue +components, use SDL_GetRGB() and SDL_MapRGB().

Example 2-4. getpixel()

/*
+ * Return the pixel value at (x, y)
+ * NOTE: The surface must be locked before calling this!
+ */
+Uint32 getpixel(SDL_Surface *surface, int x, int y)
+{
+    int bpp = surface->format->BytesPerPixel;
+    /* Here p is the address to the pixel we want to retrieve */
+    Uint8 *p = (Uint8 *)surface->pixels + y * surface->pitch + x * bpp;
+
+    switch(bpp) {
+    case 1:
+        return *p;
+
+    case 2:
+        return *(Uint16 *)p;
+
+    case 3:
+        if(SDL_BYTEORDER == SDL_BIG_ENDIAN)
+            return p[0] << 16 | p[1] << 8 | p[2];
+        else
+            return p[0] | p[1] << 8 | p[2] << 16;
+
+    case 4:
+        return *(Uint32 *)p;
+
+    default:
+        return 0;       /* shouldn't happen, but avoids warnings */
+    }
+}

Example 2-5. putpixel()

/*
+ * Set the pixel at (x, y) to the given value
+ * NOTE: The surface must be locked before calling this!
+ */
+void putpixel(SDL_Surface *surface, int x, int y, Uint32 pixel)
+{
+    int bpp = surface->format->BytesPerPixel;
+    /* Here p is the address to the pixel we want to set */
+    Uint8 *p = (Uint8 *)surface->pixels + y * surface->pitch + x * bpp;
+
+    switch(bpp) {
+    case 1:
+        *p = pixel;
+        break;
+
+    case 2:
+        *(Uint16 *)p = pixel;
+        break;
+
+    case 3:
+        if(SDL_BYTEORDER == SDL_BIG_ENDIAN) {
+            p[0] = (pixel >> 16) & 0xff;
+            p[1] = (pixel >> 8) & 0xff;
+            p[2] = pixel & 0xff;
+        } else {
+            p[0] = pixel & 0xff;
+            p[1] = (pixel >> 8) & 0xff;
+            p[2] = (pixel >> 16) & 0xff;
+        }
+        break;
+
+    case 4:
+        *(Uint32 *)p = pixel;
+        break;
+    }
+}

The following code uses the putpixel() function above to set a +yellow pixel in the middle of the screen.

Example 2-6. Using putpixel()


    /* Code to set a yellow pixel at the center of the screen */
+
+    int x, y;
+    Uint32 yellow;
+
+    /* Map the color yellow to this display (R=0xff, G=0xFF, B=0x00)
+       Note:  If the display is palettized, you must set the palette first.
+    */
+    yellow = SDL_MapRGB(screen->format, 0xff, 0xff, 0x00);
+
+    x = screen->w / 2;
+    y = screen->h / 2;
+
+    /* Lock the screen for direct access to the pixels */
+    if ( SDL_MUSTLOCK(screen) ) {
+        if ( SDL_LockSurface(screen) < 0 ) {
+            fprintf(stderr, "Can't lock screen: %s\n", SDL_GetError());
+            return;
+        }
+    }
+
+    putpixel(screen, x, y, yellow);
+
+    if ( SDL_MUSTLOCK(screen) ) {
+        SDL_UnlockSurface(screen);
+    }
+    /* Update just the part of the display that we've changed */
+    SDL_UpdateRect(screen, x, y, 1, 1);
+
+    return;

PrevHomeNext
Initializing SDLUpUsing OpenGL With SDL
\ No newline at end of file diff --git a/contrib/sdk/sources/SDL-1.2.2/docs/html/guidevideoexamples.html b/contrib/sdk/sources/SDL-1.2.2/docs/html/guidevideoexamples.html new file mode 100644 index 000000000..ba82241fa --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/docs/html/guidevideoexamples.html @@ -0,0 +1,473 @@ +Video Examples
SDL Library Documentation
PrevChapter 4. ExamplesNext

Video Examples

Initializing the video display

    SDL_Surface *screen;
+
+    /* Initialize the SDL library */
+    if( SDL_Init(SDL_INIT_VIDEO) < 0 ) {
+        fprintf(stderr,
+                "Couldn't initialize SDL: %s\n", SDL_GetError());
+        exit(1);
+    }
+
+    /* Clean up on exit */
+    atexit(SDL_Quit);
+
+    /* Initialize the display in a 640x480 8-bit palettized mode */
+    screen = SDL_SetVideoMode(640, 480, 8, SDL_SWSURFACE);
+    if ( screen == NULL ) {
+        fprintf(stderr, "Couldn't set 640x480x8 video mode: %s\n",
+                        SDL_GetError());
+        exit(1);
+    }

Initializing the best video mode

    /* Have a preference for 8-bit, but accept any depth */
+    screen = SDL_SetVideoMode(640, 480, 8, SDL_SWSURFACE|SDL_ANYFORMAT);
+    if ( screen == NULL ) {
+        fprintf(stderr, "Couldn't set 640x480x8 video mode: %s\n",
+                        SDL_GetError());
+        exit(1);
+    }
+    printf("Set 640x480 at %d bits-per-pixel mode\n",
+           screen->format->BitsPerPixel);

Loading and displaying a BMP file

    SDL_Surface *image;
+    SDL_Rect dest;
+    int ncolors, i;
+    SDL_Color *colors;
+
+    /* Load the BMP file into a surface */
+    image = SDL_LoadBMP("sample.bmp");
+    if ( image == NULL ) {
+        fprintf(stderr, "Couldn't load sample.bmp: %s\n",
+                        SDL_GetError());
+        return;
+    }
+
+    /* Set the display colors -- SDL_SetColors() only does something on
+       palettized displays, but it doesn't hurt anything on HiColor or
+       TrueColor displays.
+       If the display colors have already been set, this step can be
+       skipped, and the library will automatically map the image to
+       the current display colors.
+    */
+    if ( image->format->palette ) {
+        ncolors = image->format->palette->ncolors;
+        colors  = (SDL_Color *)malloc(ncolors*sizeof(SDL_Color));
+        memcpy(colors, image->format->palette->colors, ncolors);
+    } 
+    else {
+        int r, g, b;
+
+        /* Allocate 256 color palette */
+        ncolors = 256;
+        colors  = (SDL_Color *)malloc(ncolors*sizeof(SDL_Color));
+
+        /* Set a 3,3,2 color cube */
+        for ( r=0; r<8; ++r ) {
+            for ( g=0; g<8; ++g ) {
+                for ( b=0; b<4; ++b ) {
+                    i = ((r<<5)|(g<<2)|b);
+                    colors[i].r = r<<5;
+                    colors[i].g = g<<5;
+                    colors[i].b = b<<6;
+                }
+            }
+        }
+        /* Note: A better way of allocating the palette might be
+           to calculate the frequency of colors in the image
+           and create a palette based on that information.
+        */
+    }
+    /* Set colormap, try for all the colors, but don't worry about it */
+    SDL_SetColors(screen, colors, 0, ncolors);
+    free(colors);
+
+    /* Blit onto the screen surface */
+    dest.x = 0;
+    dest.y = 0;
+    dest.w = image->w;
+    dest.h = image->h;
+    SDL_BlitSurface(image, NULL, screen, &dest);
+
+    SDL_UpdateRects(screen, 1, &dest);
+
+    /* Free the allocated BMP surface */
+    SDL_FreeSurface(image);
+    return;

Drawing directly to the display

    /* Code to set a yellow pixel at the center of the screen */
+
+    Sint32   X, Y;
+    Uint32   pixel;
+    Uint8   *bits, bpp;
+
+    /* Map the color yellow to this display (R=0xFF, G=0xFF, B=0x00)
+       Note:  If the display is palettized, you must set the palette first.
+    */
+    pixel = SDL_MapRGB(screen->format, 0xFF, 0xFF, 0x00);
+
+    /* Calculate the framebuffer offset of the center of the screen */
+    if ( SDL_MUSTLOCK(screen) ) {
+        if ( SDL_LockSurface(screen) < 0 )
+            return;
+    }
+    bpp = screen->format->BytesPerPixel;
+    X = screen->w/2;
+    Y = screen->h/2;
+    bits = ((Uint8 *)screen->pixels)+Y*screen->pitch+X*bpp;
+
+    /* Set the pixel */
+    switch(bpp) {
+        case 1:
+            *((Uint8 *)(bits)) = (Uint8)pixel;
+            break;
+        case 2:
+            *((Uint16 *)(bits)) = (Uint16)pixel;
+            break;
+        case 3: { /* Format/endian independent */
+            Uint8 r, g, b;
+
+            r = (pixel>>screen->format->Rshift)&0xFF;
+            g = (pixel>>screen->format->Gshift)&0xFF;
+            b = (pixel>>screen->format->Bshift)&0xFF;
+            *((bits)+screen->format->Rshift/8) = r; 
+            *((bits)+screen->format->Gshift/8) = g;
+            *((bits)+screen->format->Bshift/8) = b;
+            }
+            break;
+        case 4:
+            *((Uint32 *)(bits)) = (Uint32)pixel;
+            break;
+    }
+
+    /* Update the display */
+    if ( SDL_MUSTLOCK(screen) ) {
+        SDL_UnlockSurface(screen);
+    }
+    SDL_UpdateRect(screen, X, Y, 1, 1);
+
+    return;

Fastest possible surface blit

There are three different ways you can draw an image to the screen: +

1.Create a surface and use SDL_BlitSurface to blit it to the screen
2.Create the video surface in system memory and call SDL_UpdateRect
3.Create the video surface in video memory and call SDL_LockSurface

+The best way to do this is to combine methods: +
#include <stdio.h>
+#include <stdlib.h>
+#include "SDL.h"
+#include "SDL_timer.h"
+
+void ComplainAndExit(void)
+{
+    fprintf(stderr, "Problem: %s\n", SDL_GetError());
+    exit(1);
+}
+
+int main(int argc, char *argv[])
+{
+    SDL_PixelFormat fmt;
+    SDL_Surface *screen, *locked;
+    SDL_Surface *imagebmp, *image;
+    SDL_Rect dstrect;
+    int i;
+    Uint8 *buffer;
+
+    /* Initialize SDL */
+    if ( SDL_Init(SDL_INIT_VIDEO) < 0 ) {
+        ComplainAndExit();
+    }
+    atexit(SDL_Quit);
+
+    /* Load a BMP image into a surface */
+    imagebmp = SDL_LoadBMP("image.bmp");
+    if ( imagebmp == NULL ) {
+        ComplainAndExit();
+    }
+
+    /* Set the video mode (640x480 at native depth) */
+    screen = SDL_SetVideoMode(640, 480, 0, SDL_HWSURFACE|SDL_FULLSCREEN);
+    if ( screen == NULL ) {
+        ComplainAndExit();
+    }
+
+    /* Set the video colormap */
+    if ( imagebmp->format->palette != NULL ) {
+        SDL_SetColors(screen,
+                      imagebmp->format->palette->colors, 0,
+                      imagebmp->format->palette->ncolors);
+    }
+
+    /* Convert the image to the video format (maps colors) */
+    image = SDL_DisplayFormat(imagebmp);
+    SDL_FreeSurface(imagebmp);
+    if ( image == NULL ) {
+        ComplainAndExit();
+    }
+
+    /* Draw bands of color on the raw surface */
+    if ( SDL_MUSTLOCK(screen) ) {
+        if ( SDL_LockSurface(screen) < 0 )
+            ComplainAndExit();
+    }
+    buffer=(Uint8 *)screen->pixels;
+    for ( i=0; i<screen->h; ++i ) {
+        memset(buffer,(i*255)/screen->h,
+               screen->w*screen->format->BytesPerPixel);
+               buffer += screen->pitch;
+    }
+    if ( SDL_MUSTLOCK(screen) ) {
+        SDL_UnlockSurface(screen);
+    }
+
+    /* Blit the image to the center of the screen */
+    dstrect.x = (screen->w-image->w)/2;
+    dstrect.y = (screen->h-image->h)/2;
+    dstrect.w = image->w;
+    dstrect.h = image->h;
+    if ( SDL_BlitSurface(image, NULL, screen, &dstrect) < 0 ) {
+        SDL_FreeSurface(image);
+        ComplainAndExit();
+    }
+    SDL_FreeSurface(image);
+
+    /* Update the screen */
+    SDL_UpdateRects(screen, 1, &dstrect);
+
+    SDL_Delay(5000);        /* Wait 5 seconds */
+    exit(0);
+}


PrevHomeNext
ExamplesUpEvent Examples
\ No newline at end of file diff --git a/contrib/sdk/sources/SDL-1.2.2/docs/html/guidevideoopengl.html b/contrib/sdk/sources/SDL-1.2.2/docs/html/guidevideoopengl.html new file mode 100644 index 000000000..76be8e2a2 --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/docs/html/guidevideoopengl.html @@ -0,0 +1,719 @@ +Using OpenGL With SDL
SDL Library Documentation
PrevChapter 2. Graphics and VideoNext

Using OpenGL With SDL

SDL has the ability to create and use OpenGL contexts on several platforms(Linux/X11, Win32, BeOS, MacOS Classic/Toolbox, MacOS X, FreeBSD/X11 and Solaris/X11). This allows you to use SDL's audio, event handling, threads and times in your OpenGL applications (a function often performed by GLUT).

Initialisation

Initialising SDL to use OpenGL is not very different to initialising SDL normally. There are three differences; you must pass SDL_OPENGL to SDL_SetVideoMode, you must specify several GL attributes (depth buffer size, framebuffer sizes) using SDL_GL_SetAttribute and finally, if you wish to use double buffering you must specify it as a GL attribute, not by passing the SDL_DOUBLEBUF flag to SDL_SetVideoMode.

Example 2-7. Initializing SDL with OpenGL

    /* Information about the current video settings. */
+    const SDL_VideoInfo* info = NULL;
+    /* Dimensions of our window. */
+    int width = 0;
+    int height = 0;
+    /* Color depth in bits of our window. */
+    int bpp = 0;
+    /* Flags we will pass into SDL_SetVideoMode. */
+    int flags = 0;
+
+    /* First, initialize SDL's video subsystem. */
+    if( SDL_Init( SDL_INIT_VIDEO ) < 0 ) {
+        /* Failed, exit. */
+        fprintf( stderr, "Video initialization failed: %s\n",
+             SDL_GetError( ) );
+        quit_tutorial( 1 );
+    }
+
+    /* Let's get some video information. */
+    info = SDL_GetVideoInfo( );
+
+    if( !info ) {
+        /* This should probably never happen. */
+        fprintf( stderr, "Video query failed: %s\n",
+             SDL_GetError( ) );
+        quit_tutorial( 1 );
+    }
+
+    /*
+     * Set our width/height to 640/480 (you would
+     * of course let the user decide this in a normal
+     * app). We get the bpp we will request from
+     * the display. On X11, VidMode can't change
+     * resolution, so this is probably being overly
+     * safe. Under Win32, ChangeDisplaySettings
+     * can change the bpp.
+     */
+    width = 640;
+    height = 480;
+    bpp = info->vfmt->BitsPerPixel;
+
+    /*
+     * Now, we want to setup our requested
+     * window attributes for our OpenGL window.
+     * We want *at least* 5 bits of red, green
+     * and blue. We also want at least a 16-bit
+     * depth buffer.
+     *
+     * The last thing we do is request a double
+     * buffered window. '1' turns on double
+     * buffering, '0' turns it off.
+     *
+     * Note that we do not use SDL_DOUBLEBUF in
+     * the flags to SDL_SetVideoMode. That does
+     * not affect the GL attribute state, only
+     * the standard 2D blitting setup.
+     */
+    SDL_GL_SetAttribute( SDL_GL_RED_SIZE, 5 );
+    SDL_GL_SetAttribute( SDL_GL_GREEN_SIZE, 5 );
+    SDL_GL_SetAttribute( SDL_GL_BLUE_SIZE, 5 );
+    SDL_GL_SetAttribute( SDL_GL_DEPTH_SIZE, 16 );
+    SDL_GL_SetAttribute( SDL_GL_DOUBLEBUFFER, 1 );
+
+    /*
+     * We want to request that SDL provide us
+     * with an OpenGL window, in a fullscreen
+     * video mode.
+     *
+     * EXERCISE:
+     * Make starting windowed an option, and
+     * handle the resize events properly with
+     * glViewport.
+     */
+    flags = SDL_OPENGL | SDL_FULLSCREEN;
+
+    /*
+     * Set the video mode
+     */
+    if( SDL_SetVideoMode( width, height, bpp, flags ) == 0 ) {
+        /* 
+         * This could happen for a variety of reasons,
+         * including DISPLAY not being set, the specified
+         * resolution not being available, etc.
+         */
+        fprintf( stderr, "Video mode set failed: %s\n",
+             SDL_GetError( ) );
+        quit_tutorial( 1 );
+    }

Drawing

Apart from initialisation, using OpenGL within SDL is the same as using OpenGL +with any other API, e.g. GLUT. You still use all the same function calls and +data types. However if you are using a double-buffered display, then you must +use +SDL_GL_SwapBuffers() +to swap the buffers and update the display. To request double-buffering +with OpenGL, use +SDL_GL_SetAttribute +with SDL_GL_DOUBLEBUFFER, and use +SDL_GL_GetAttribute +to see if you actually got it.

A full example code listing is now presented below.

Example 2-8. SDL and OpenGL

/*
+ * SDL OpenGL Tutorial.
+ * (c) Michael Vance, 2000
+ * briareos@lokigames.com
+ *
+ * Distributed under terms of the LGPL. 
+ */
+
+#include <SDL/SDL.h>
+#include <GL/gl.h>
+#include <GL/glu.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+
+static GLboolean should_rotate = GL_TRUE;
+
+static void quit_tutorial( int code )
+{
+    /*
+     * Quit SDL so we can release the fullscreen
+     * mode and restore the previous video settings,
+     * etc.
+     */
+    SDL_Quit( );
+
+    /* Exit program. */
+    exit( code );
+}
+
+static void handle_key_down( SDL_keysym* keysym )
+{
+
+    /* 
+     * We're only interested if 'Esc' has
+     * been presssed.
+     *
+     * EXERCISE: 
+     * Handle the arrow keys and have that change the
+     * viewing position/angle.
+     */
+    switch( keysym->sym ) {
+    case SDLK_ESCAPE:
+        quit_tutorial( 0 );
+        break;
+    case SDLK_SPACE:
+        should_rotate = !should_rotate;
+        break;
+    default:
+        break;
+    }
+
+}
+
+static void process_events( void )
+{
+    /* Our SDL event placeholder. */
+    SDL_Event event;
+
+    /* Grab all the events off the queue. */
+    while( SDL_PollEvent( &event ) ) {
+
+        switch( event.type ) {
+        case SDL_KEYDOWN:
+            /* Handle key presses. */
+            handle_key_down( &event.key.keysym );
+            break;
+        case SDL_QUIT:
+            /* Handle quit requests (like Ctrl-c). */
+            quit_tutorial( 0 );
+            break;
+        }
+
+    }
+
+}
+
+static void draw_screen( void )
+{
+    /* Our angle of rotation. */
+    static float angle = 0.0f;
+
+    /*
+     * EXERCISE:
+     * Replace this awful mess with vertex
+     * arrays and a call to glDrawElements.
+     *
+     * EXERCISE:
+     * After completing the above, change
+     * it to use compiled vertex arrays.
+     *
+     * EXERCISE:
+     * Verify my windings are correct here ;).
+     */
+    static GLfloat v0[] = { -1.0f, -1.0f,  1.0f };
+    static GLfloat v1[] = {  1.0f, -1.0f,  1.0f };
+    static GLfloat v2[] = {  1.0f,  1.0f,  1.0f };
+    static GLfloat v3[] = { -1.0f,  1.0f,  1.0f };
+    static GLfloat v4[] = { -1.0f, -1.0f, -1.0f };
+    static GLfloat v5[] = {  1.0f, -1.0f, -1.0f };
+    static GLfloat v6[] = {  1.0f,  1.0f, -1.0f };
+    static GLfloat v7[] = { -1.0f,  1.0f, -1.0f };
+    static GLubyte red[]    = { 255,   0,   0, 255 };
+    static GLubyte green[]  = {   0, 255,   0, 255 };
+    static GLubyte blue[]   = {   0,   0, 255, 255 };
+    static GLubyte white[]  = { 255, 255, 255, 255 };
+    static GLubyte yellow[] = {   0, 255, 255, 255 };
+    static GLubyte black[]  = {   0,   0,   0, 255 };
+    static GLubyte orange[] = { 255, 255,   0, 255 };
+    static GLubyte purple[] = { 255,   0, 255,   0 };
+
+    /* Clear the color and depth buffers. */
+    glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
+
+    /* We don't want to modify the projection matrix. */
+    glMatrixMode( GL_MODELVIEW );
+    glLoadIdentity( );
+
+    /* Move down the z-axis. */
+    glTranslatef( 0.0, 0.0, -5.0 );
+
+    /* Rotate. */
+    glRotatef( angle, 0.0, 1.0, 0.0 );
+
+    if( should_rotate ) {
+
+        if( ++angle > 360.0f ) {
+            angle = 0.0f;
+        }
+
+    }
+
+    /* Send our triangle data to the pipeline. */
+    glBegin( GL_TRIANGLES );
+
+    glColor4ubv( red );
+    glVertex3fv( v0 );
+    glColor4ubv( green );
+    glVertex3fv( v1 );
+    glColor4ubv( blue );
+    glVertex3fv( v2 );
+
+    glColor4ubv( red );
+    glVertex3fv( v0 );
+    glColor4ubv( blue );
+    glVertex3fv( v2 );
+    glColor4ubv( white );
+    glVertex3fv( v3 );
+
+    glColor4ubv( green );
+    glVertex3fv( v1 );
+    glColor4ubv( black );
+    glVertex3fv( v5 );
+    glColor4ubv( orange );
+    glVertex3fv( v6 );
+
+    glColor4ubv( green );
+    glVertex3fv( v1 );
+    glColor4ubv( orange );
+    glVertex3fv( v6 );
+    glColor4ubv( blue );
+    glVertex3fv( v2 );
+
+    glColor4ubv( black );
+    glVertex3fv( v5 );
+    glColor4ubv( yellow );
+    glVertex3fv( v4 );
+    glColor4ubv( purple );
+    glVertex3fv( v7 );
+
+    glColor4ubv( black );
+    glVertex3fv( v5 );
+    glColor4ubv( purple );
+    glVertex3fv( v7 );
+    glColor4ubv( orange );
+    glVertex3fv( v6 );
+
+    glColor4ubv( yellow );
+    glVertex3fv( v4 );
+    glColor4ubv( red );
+    glVertex3fv( v0 );
+    glColor4ubv( white );
+    glVertex3fv( v3 );
+
+    glColor4ubv( yellow );
+    glVertex3fv( v4 );
+    glColor4ubv( white );
+    glVertex3fv( v3 );
+    glColor4ubv( purple );
+    glVertex3fv( v7 );
+
+    glColor4ubv( white );
+    glVertex3fv( v3 );
+    glColor4ubv( blue );
+    glVertex3fv( v2 );
+    glColor4ubv( orange );
+    glVertex3fv( v6 );
+
+    glColor4ubv( white );
+    glVertex3fv( v3 );
+    glColor4ubv( orange );
+    glVertex3fv( v6 );
+    glColor4ubv( purple );
+    glVertex3fv( v7 );
+
+    glColor4ubv( green );
+    glVertex3fv( v1 );
+    glColor4ubv( red );
+    glVertex3fv( v0 );
+    glColor4ubv( yellow );
+    glVertex3fv( v4 );
+
+    glColor4ubv( green );
+    glVertex3fv( v1 );
+    glColor4ubv( yellow );
+    glVertex3fv( v4 );
+    glColor4ubv( black );
+    glVertex3fv( v5 );
+
+    glEnd( );
+
+    /*
+     * EXERCISE:
+     * Draw text telling the user that 'Spc'
+     * pauses the rotation and 'Esc' quits.
+     * Do it using vetors and textured quads.
+     */
+
+    /*
+     * Swap the buffers. This this tells the driver to
+     * render the next frame from the contents of the
+     * back-buffer, and to set all rendering operations
+     * to occur on what was the front-buffer.
+     *
+     * Double buffering prevents nasty visual tearing
+     * from the application drawing on areas of the
+     * screen that are being updated at the same time.
+     */
+    SDL_GL_SwapBuffers( );
+}
+
+static void setup_opengl( int width, int height )
+{
+    float ratio = (float) width / (float) height;
+
+    /* Our shading model--Gouraud (smooth). */
+    glShadeModel( GL_SMOOTH );
+
+    /* Culling. */
+    glCullFace( GL_BACK );
+    glFrontFace( GL_CCW );
+    glEnable( GL_CULL_FACE );
+
+    /* Set the clear color. */
+    glClearColor( 0, 0, 0, 0 );
+
+    /* Setup our viewport. */
+    glViewport( 0, 0, width, height );
+
+    /*
+     * Change to the projection matrix and set
+     * our viewing volume.
+     */
+    glMatrixMode( GL_PROJECTION );
+    glLoadIdentity( );
+    /*
+     * EXERCISE:
+     * Replace this with a call to glFrustum.
+     */
+    gluPerspective( 60.0, ratio, 1.0, 1024.0 );
+}
+
+int main( int argc, char* argv[] )
+{
+    /* Information about the current video settings. */
+    const SDL_VideoInfo* info = NULL;
+    /* Dimensions of our window. */
+    int width = 0;
+    int height = 0;
+    /* Color depth in bits of our window. */
+    int bpp = 0;
+    /* Flags we will pass into SDL_SetVideoMode. */
+    int flags = 0;
+
+    /* First, initialize SDL's video subsystem. */
+    if( SDL_Init( SDL_INIT_VIDEO ) < 0 ) {
+        /* Failed, exit. */
+        fprintf( stderr, "Video initialization failed: %s\n",
+             SDL_GetError( ) );
+        quit_tutorial( 1 );
+    }
+
+    /* Let's get some video information. */
+    info = SDL_GetVideoInfo( );
+
+    if( !info ) {
+        /* This should probably never happen. */
+        fprintf( stderr, "Video query failed: %s\n",
+             SDL_GetError( ) );
+        quit_tutorial( 1 );
+    }
+
+    /*
+     * Set our width/height to 640/480 (you would
+     * of course let the user decide this in a normal
+     * app). We get the bpp we will request from
+     * the display. On X11, VidMode can't change
+     * resolution, so this is probably being overly
+     * safe. Under Win32, ChangeDisplaySettings
+     * can change the bpp.
+     */
+    width = 640;
+    height = 480;
+    bpp = info->vfmt->BitsPerPixel;
+
+    /*
+     * Now, we want to setup our requested
+     * window attributes for our OpenGL window.
+     * We want *at least* 5 bits of red, green
+     * and blue. We also want at least a 16-bit
+     * depth buffer.
+     *
+     * The last thing we do is request a double
+     * buffered window. '1' turns on double
+     * buffering, '0' turns it off.
+     *
+     * Note that we do not use SDL_DOUBLEBUF in
+     * the flags to SDL_SetVideoMode. That does
+     * not affect the GL attribute state, only
+     * the standard 2D blitting setup.
+     */
+    SDL_GL_SetAttribute( SDL_GL_RED_SIZE, 5 );
+    SDL_GL_SetAttribute( SDL_GL_GREEN_SIZE, 5 );
+    SDL_GL_SetAttribute( SDL_GL_BLUE_SIZE, 5 );
+    SDL_GL_SetAttribute( SDL_GL_DEPTH_SIZE, 16 );
+    SDL_GL_SetAttribute( SDL_GL_DOUBLEBUFFER, 1 );
+
+    /*
+     * We want to request that SDL provide us
+     * with an OpenGL window, in a fullscreen
+     * video mode.
+     *
+     * EXERCISE:
+     * Make starting windowed an option, and
+     * handle the resize events properly with
+     * glViewport.
+     */
+    flags = SDL_OPENGL | SDL_FULLSCREEN;
+
+    /*
+     * Set the video mode
+     */
+    if( SDL_SetVideoMode( width, height, bpp, flags ) == 0 ) {
+        /* 
+         * This could happen for a variety of reasons,
+         * including DISPLAY not being set, the specified
+         * resolution not being available, etc.
+         */
+        fprintf( stderr, "Video mode set failed: %s\n",
+             SDL_GetError( ) );
+        quit_tutorial( 1 );
+    }
+
+    /*
+     * At this point, we should have a properly setup
+     * double-buffered window for use with OpenGL.
+     */
+    setup_opengl( width, height );
+
+    /*
+     * Now we want to begin our normal app process--
+     * an event loop with a lot of redrawing.
+     */
+    while( 1 ) {
+        /* Process incoming events. */
+        process_events( );
+        /* Draw the screen. */
+        draw_screen( );
+    }
+
+    /*
+     * EXERCISE:
+     * Record timings using SDL_GetTicks() and
+     * and print out frames per second at program
+     * end.
+     */
+
+    /* Never reached. */
+    return 0;
+}

PrevHomeNext
Graphics and VideoUpInput handling
\ No newline at end of file diff --git a/contrib/sdk/sources/SDL-1.2.2/docs/html/index.html b/contrib/sdk/sources/SDL-1.2.2/docs/html/index.html new file mode 100644 index 000000000..1417c74d9 --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/docs/html/index.html @@ -0,0 +1,1144 @@ +
Table of Contents
I. SDL Guide
Preface
About SDL
About SDLdoc
Credits
1. The Basics
Introduction
Initializing SDL
2. Graphics and Video
Introduction to SDL Video
Using OpenGL With SDL
3. Input handling
Handling Joysticks
Handling the Keyboard
4. Examples
Introduction
Event Examples
Audio Examples
CDROM Examples
Time Examples
II. SDL Reference
5. General
SDL_Init — Initializes SDL
SDL_InitSubSystem — Initialize subsystems
SDL_QuitSubSystem — Shut down a subsystem
SDL_Quit — Shut down SDL
SDL_WasInit — Check which subsystems are initialized
6. Video
SDL_GetVideoSurface — returns a pointer to the current display surface
SDL_GetVideoInfo — returns a pointer to information about the video hardware
SDL_VideoDriverName — Obtain the name of the video driver
SDL_ListModes — Returns a pointer to an array of available screen dimensions for +the given format and video flags
SDL_VideoModeOK — Check to see if a particular video mode is supported.
SDL_SetVideoMode — Set up a video mode with the specified width, height and bits-per-pixel.
SDL_UpdateRect — Makes sure the given area is updated on the given screen.
SDL_UpdateRects — Makes sure the given list of rectangles is updated on the given screen.
SDL_Flip — Swaps screen buffers
SDL_SetColors — Sets a portion of the colormap for the given 8-bit surface.
SDL_SetPalette — Sets the colors in the palette of an 8-bit surface.
SDL_SetGamma — Sets the color gamma function for the display
SDL_GetGammaRamp — Gets the color gamma lookup tables for the display
SDL_SetGammaRamp — Sets the color gamma lookup tables for the display
SDL_MapRGB — Map a RGB color value to a pixel format.
SDL_MapRGBA — Map a RGBA color value to a pixel format.
SDL_GetRGB — Get RGB values from a pixel in the specified pixel format.
SDL_GetRGBA — Get RGBA values from a pixel in the specified pixel format.
SDL_CreateRGBSurface — Create an empty SDL_Surface
SDL_CreateRGBSurfaceFrom — Create an SDL_Surface from pixel data
SDL_FreeSurface — Frees (deletes) a SDL_Surface
SDL_LockSurface — Lock a surface for directly access.
SDL_UnlockSurface — Unlocks a previously locked surface.
SDL_LoadBMP — Load a Windows BMP file into an SDL_Surface.
SDL_SaveBMP — Save an SDL_Surface as a Windows BMP file.
SDL_SetColorKey — Sets the color key (transparent pixel) in a blittable surface and +RLE acceleration.
SDL_SetAlpha — Adjust the alpha properties of a surface
SDL_SetClipRect — Sets the clipping rectangle for a surface.
SDL_GetClipRect — Gets the clipping rectangle for a surface.
SDL_ConvertSurface — Converts a surface to the same format as another surface.
SDL_BlitSurface — This performs a fast blit from the source surface to the destination surface.
SDL_FillRect — This function performs a fast fill of the given rectangle with some color
SDL_DisplayFormat — Convert a surface to the display format
SDL_DisplayFormatAlpha — Convert a surface to the display format
SDL_WarpMouse — Set the position of the mouse cursor.
SDL_CreateCursor — Creates a new mouse cursor.
SDL_FreeCursor — Frees a cursor created with SDL_CreateCursor.
SDL_SetCursor — Set the currently active mouse cursor.
SDL_GetCursor — Get the currently active mouse cursor.
SDL_ShowCursor — Toggle whether or not the cursor is shown on the screen.
SDL_GL_LoadLibrary — Specify an OpenGL library
SDL_GL_GetProcAddress — Get the address of a GL function
SDL_GL_GetAttribute — Get the value of a special SDL/OpenGL attribute
SDL_GL_SetAttribute — Set a special SDL/OpenGL attribute
SDL_GL_SwapBuffers — Swap OpenGL framebuffers/Update Display
SDL_CreateYUVOverlay — Create a YUV video overlay
SDL_LockYUVOverlay — Lock an overlay
SDL_UnlockYUVOverlay — Unlock an overlay
SDL_DisplayYUVOverlay — Blit the overlay to the display
SDL_FreeYUVOverlay — Free a YUV video overlay
SDL_GLattr — SDL GL Attributes
SDL_Rect — Defines a rectangular area
SDL_Color — Format independent color description
SDL_Palette — Color palette for 8-bit pixel formats
SDL_PixelFormat — Stores surface format information
SDL_Surface — Graphical Surface Structure
SDL_VideoInfo — Video Target information
SDL_Overlay — YUV video overlay
7. Window Management
SDL_WM_SetCaption — Sets the window tile and icon name.
SDL_WM_GetCaption — Gets the window title and icon name.
SDL_WM_SetIcon — Sets the icon for the display window.
SDL_WM_IconifyWindow — Iconify/Minimise the window
SDL_WM_ToggleFullScreen — Toggles fullscreen mode
SDL_WM_GrabInput — Grabs mouse and keyboard input.
8. Events
Introduction
SDL Event Structures.
Event Functions.
9. Joystick
SDL_NumJoysticks — Count available joysticks.
SDL_JoystickName — Get joystick name.
SDL_JoystickOpen — Opens a joystick for use.
SDL_JoystickOpened — Determine if a joystick has been opened
SDL_JoystickIndex — Get the index of an SDL_Joystick.
SDL_JoystickNumAxes — Get the number of joystick axes
SDL_JoystickNumBalls — Get the number of joystick trackballs
SDL_JoystickNumHats — Get the number of joystick hats
SDL_JoystickNumButtons — Get the number of joysitck buttons
SDL_JoystickUpdate — Updates the state of all joysticks
SDL_JoystickGetAxis — Get the current state of an axis
SDL_JoystickGetHat — Get the current state of a joystick hat
SDL_JoystickGetButton — Get the current state of a given button on a given joystick
SDL_JoystickGetBall — Get relative trackball motion
SDL_JoystickClose — Closes a previously opened joystick
10. Audio
SDL_AudioSpec — Audio Specification Structure
SDL_OpenAudio — Opens the audio device with the desired parameters.
SDL_PauseAudio — Pauses and unpauses the audio callback processing
SDL_GetAudioStatus — Get the current audio state
SDL_LoadWAV — Load a WAVE file
SDL_FreeWAV — Frees previously opened WAV data
SDL_AudioCVT — Audio Conversion Structure
SDL_BuildAudioCVT — Initializes a SDL_AudioCVT structure for conversion
SDL_ConvertAudio — Convert audio data to a desired audio format.
SDL_MixAudio — Mix audio data
SDL_LockAudio — Lock out the callback function
SDL_UnlockAudio — Unlock the callback function
SDL_CloseAudio — Shuts down audio processing and closes the audio device.
11. CD-ROM
SDL_CDNumDrives — Returns the number of CD-ROM drives on the system.
SDL_CDName — Returns a human-readable, system-dependent identifier for the CD-ROM.
SDL_CDOpen — Opens a CD-ROM drive for access.
SDL_CDStatus — Returns the current status of the given drive.
SDL_CDPlay — Play a CD
SDL_CDPlayTracks — Play the given CD track(s)
SDL_CDPause — Pauses a CDROM
SDL_CDResume — Resumes a CDROM
SDL_CDStop — Stops a CDROM
SDL_CDEject — Ejects a CDROM
SDL_CDClose — Closes a SDL_CD handle
SDL_CD — CDROM Drive Information
SDL_CDtrack — CD Track Information Structure
12. Multi-threaded Programming
SDL_CreateThread — Creates a new thread of execution that shares its parent's properties.
SDL_ThreadID — Get the 32-bit thread identifier for the current thread.
SDL_GetThreadID — Get the SDL thread ID of a SDL_Thread
SDL_WaitThread — Wait for a thread to finish.
SDL_KillThread — Gracelessly terminates the thread.
SDL_CreateMutex — Create a mutex
SDL_DestroyMutex — Destroy a mutex
SDL_mutexP — Lock a mutex
SDL_mutexV — Unlock a mutex
SDL_CreateSemaphore — Creates a new semaphore and assigns an initial value to it.
SDL_DestroySemaphore — Destroys a semaphore that was created by SDL_CreateSemaphore.
SDL_SemWait — Lock a semaphore and suspend the thread if the semaphore value is zero.
SDL_SemTryWait — Attempt to lock a semaphore but don't suspend the thread.
SDL_SemWaitTimeout — Lock a semaphore, but only wait up to a specified maximum time.
SDL_SemPost — Unlock a semaphore.
SDL_SemValue — Return the current value of a semaphore.
SDL_CreateCond — Create a condition variable
SDL_DestroyCond — Destroy a condition variable
SDL_CondSignal — Restart a thread wait on a condition variable
SDL_CondBroadcast — Restart all threads waiting on a condition variable
SDL_CondWait — Wait on a condition variable
SDL_CondWaitTimeout — Wait on a condition variable, with timeout
13. Time
SDL_GetTicks — Get the number of milliseconds since the SDL library initialization.
SDL_Delay — Wait a specified number of milliseconds before returning.
SDL_AddTimer — Add a timer which will call a callback after the specified number of milliseconds has +elapsed.
SDL_RemoveTimer — Remove a timer which was added with +SDL_AddTimer.
SDL_SetTimer — Set a callback to run after the specified number of milliseconds has +elapsed.

  Next
  SDL Guide
\ No newline at end of file diff --git a/contrib/sdk/sources/SDL-1.2.2/docs/html/joystick.html b/contrib/sdk/sources/SDL-1.2.2/docs/html/joystick.html new file mode 100644 index 000000000..ffa66512c --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/docs/html/joystick.html @@ -0,0 +1,285 @@ +Joystick
SDL Library Documentation
PrevNext

Chapter 9. Joystick

Table of Contents
SDL_NumJoysticks — Count available joysticks.
SDL_JoystickName — Get joystick name.
SDL_JoystickOpen — Opens a joystick for use.
SDL_JoystickOpened — Determine if a joystick has been opened
SDL_JoystickIndex — Get the index of an SDL_Joystick.
SDL_JoystickNumAxes — Get the number of joystick axes
SDL_JoystickNumBalls — Get the number of joystick trackballs
SDL_JoystickNumHats — Get the number of joystick hats
SDL_JoystickNumButtons — Get the number of joysitck buttons
SDL_JoystickUpdate — Updates the state of all joysticks
SDL_JoystickGetAxis — Get the current state of an axis
SDL_JoystickGetHat — Get the current state of a joystick hat
SDL_JoystickGetButton — Get the current state of a given button on a given joystick
SDL_JoystickGetBall — Get relative trackball motion
SDL_JoystickClose — Closes a previously opened joystick

Joysticks, and other similar input devices, have a very strong role in game playing and SDL provides comprehensive support for them. Axes, Buttons, POV Hats and trackballs are all supported.

Joystick support is initialized by passed the SDL_INIT_JOYSTICK flag to SDL_Init. Once initilized joysticks must be opened using SDL_JoystickOpen.

While using the functions describe in this secton may seem like the best way to access and read from joysticks, in most cases they aren't. Ideally joysticks should be read using the event system. To enable this, you must set the joystick event processing state with SDL_JoystickEventState. Joysticks must be opened before they can be used of course.

Note: If you are not handling the joystick via the event queue then you must explicitly request a joystick update by calling SDL_JoystickUpdate.

Note: Force Feedback is not yet support. Sam (slouken@libsdl.org) is soliciting suggestions from people with force-feedback experience on the best wat to desgin the API.


PrevHomeNext
SDL_JoystickEventStateUpSDL_NumJoysticks
\ No newline at end of file diff --git a/contrib/sdk/sources/SDL-1.2.2/docs/html/reference.html b/contrib/sdk/sources/SDL-1.2.2/docs/html/reference.html new file mode 100644 index 000000000..beee8f278 --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/docs/html/reference.html @@ -0,0 +1,187 @@ +SDL Reference
SDL Library Documentation
PrevNext

II. SDL Reference


PrevHomeNext
Time Examples General
\ No newline at end of file diff --git a/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlactiveevent.html b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlactiveevent.html new file mode 100644 index 000000000..02307cadc --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlactiveevent.html @@ -0,0 +1,327 @@ +SDL_ActiveEvent
SDL Library Documentation
PrevNext

SDL_ActiveEvent

Name

SDL_ActiveEvent -- Application visibility event structure

Structure Definition

typedef struct{
+  Uint8 type;
+  Uint8 gain;
+  Uint8 state;
+} SDL_ActiveEvent;

Structure Data

typeSDL_ACTIVEEVENT.
gain0 if the event is a loss or 1 if it is a gain.
stateSDL_APPMOUSEFOCUS if mouse focus was gained or lost, SDL_APPINPUTFOCUS if input focus was gained or lost, or SDL_APPACTIVE if the application was iconified (gain=0) or restored(gain=1).

Description

SDL_ActiveEvent is a member of the SDL_Event union and is used when an event of type SDL_ACTIVEEVENT is reported.

When the mouse leaves or enters the window area a SDL_APPMOUSEFOCUS type activation event occurs, if the mouse entered the window then gain will be 1, otherwise gain will be 0. A SDL_APPINPUTFOCUS type activation event occurs when the application loses or gains keyboard focus. This usually occurs when another application is made active. Finally, a SDL_APPACTIVE type event occurs when the application is either minimised/iconified (gain=0) or restored.

Note: This event does not occur when an application window is first created.


PrevHomeNext
SDL_EventUpSDL_KeyboardEvent
\ No newline at end of file diff --git a/contrib/sdk/sources/SDL-1.2.2/docs/html/sdladdtimer.html b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdladdtimer.html new file mode 100644 index 000000000..9b0c18afb --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdladdtimer.html @@ -0,0 +1,288 @@ +SDL_AddTimer
SDL Library Documentation
PrevNext

SDL_AddTimer

Name

SDL_AddTimer -- Add a timer which will call a callback after the specified number of milliseconds has +elapsed.

Synopsis

#include "SDL.h"

SDL_TimerID SDL_AddTimer(Uint32 interval, SDL_NewTimerCallback callback, void *param);

Callback

/* type definition for the "new" timer callback function */
+typedef Uint32 (*SDL_NewTimerCallback)(Uint32 interval, void *param);

Description

Adds a callback function to be run after the specified number of +milliseconds has elapsed. The callback function is passed the current +timer interval and the user supplied parameter from the +SDL_AddTimer call and returns the next timer +interval. If the returned value from the callback is the same as the one +passed in, the periodic alarm continues, otherwise a new alarm is +scheduled.

To cancel a currently running timer call +SDL_RemoveTimer with the +timer ID returned from +SDL_AddTimer.

The timer callback function may run in a different thread than your +main program, and so shouldn't call any functions from within itself. +You may always call SDL_PushEvent, however.

The granularity of the timer is platform-dependent, but you should count +on it being at least 10 ms as this is the most common number. +This means that if +you request a 16 ms timer, your callback will run approximately 20 ms +later on an unloaded system. If you wanted to set a flag signaling +a frame update at 30 frames per second (every 33 ms), you might set a +timer for 30 ms (see example below). + +If you use this function, you need to pass SDL_INIT_TIMER +to SDL_Init.

Return Value

Returns an ID value for the added timer or +NULL if there was an error.

Examples

my_timer_id = SDL_AddTimer((33/10)*10, my_callbackfunc, my_callback_param);


PrevHomeNext
SDL_DelayUpSDL_RemoveTimer
\ No newline at end of file diff --git a/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlaudiocvt.html b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlaudiocvt.html new file mode 100644 index 000000000..671e5030a --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlaudiocvt.html @@ -0,0 +1,548 @@ +SDL_AudioCVT
SDL Library Documentation
PrevNext

SDL_AudioCVT

Name

SDL_AudioCVT -- Audio Conversion Structure

Structure Definition

typedef struct{
+  int needed;
+  Uint16 src_format;
+  Uint16 dest_format;
+  double rate_incr;
+  Uint8 *buf;
+  int len;
+  int len_cvt;
+  int len_mult;
+  double len_ratio;
+  void (*filters[10])(struct SDL_AudioCVT *cvt, Uint16 format);
+  int filter_index;
+} SDL_AudioCVT;

Structure Data

neededSet to one if the conversion is possible
src_formatAudio format of the source
dest_formatAudio format of the destination
rate_incrRate conversion increment
bufAudio buffer
lenLength of the original audio buffer in bytes
len_cvtLength of converted audio buffer in bytes (calculated)
len_multbuf must be len*len_mult bytes in size(calculated)
len_ratioFinal audio size is len*len_ratio
filters[10](..)Pointers to functions needed for this conversion
filter_indexCurrent conversion function

Description

The SDL_AudioCVT is used to convert audio data between different formats. A SDL_AudioCVT structure is created with the SDL_BuildAudioCVT function, while the actual conversion is done by the SDL_ConvertAudio function.

Many of the fields in the SDL_AudioCVT structure should be considered private and their function will not be discussed here.

Uint8 *buf

This points to the audio data that will be used in the conversion. It is both the source and the destination, which means the converted audio data overwrites the original data. It also means that the converted data may be larger than the original data (if you were converting from 8-bit to 16-bit, for instance), so you must ensure buf is large enough. See below.

int len

This is the length of the original audio data in bytes.

int len_mult

As explained above, the audio buffer needs to be big enough to store the converted data, which may be bigger than the original audio data. The length of buf should be len*len_mult.

double len_ratio

When you have finished converting your audio data, you need to know how much of your audio buffer is valid. len*len_ratio is the size of the converted audio data in bytes. This is very similar to len_mult, however when the convert audio data is shorter than the original len_mult would be 1. len_ratio, on the other hand, would be a fractional number between 0 and 1.


PrevHomeNext
SDL_FreeWAVUpSDL_BuildAudioCVT
\ No newline at end of file diff --git a/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlaudiospec.html b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlaudiospec.html new file mode 100644 index 000000000..4b281fa29 --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlaudiospec.html @@ -0,0 +1,581 @@ +SDL_AudioSpec
SDL Library Documentation
PrevNext

SDL_AudioSpec

Name

SDL_AudioSpec -- Audio Specification Structure

Structure Definition

typedef struct{
+  int freq;
+  Uint16 format;
+  Uint8 channels;
+  Uint8 silence;
+  Uint16 samples;
+  Uint32 size;
+  void (*callback)(void *userdata, Uint8 *stream, int len);
+  void *userdata;
+} SDL_AudioSpec;

Structure Data

freqAudio frequency in samples per second
formatAudio data format
channelsNumber of channels: 1 mono, 2 stereo
silenceAudio buffer silence value (calculated)
samplesAudio buffer size in samples
sizeAudio buffer size in bytes (calculated)
callback(..)Callback function for filling the audio buffer
userdataPointer the user data which is passed to the callback function

Description

The SDL_AudioSpec structure is used to describe the format of some audio data. This structure is used by SDL_OpenAudio and SDL_LoadWAV. While all fields are used by SDL_OpenAudio only freq, format, samples and channels are used by SDL_LoadWAV. We will detail these common members here.

freq

The number of samples sent to the sound device every second. Common values are 11025, 22050 and 44100. The higher the better.

format

Specifies the size and type of each sample element +

AUDIO_U8

Unsigned 8-bit samples

AUDIO_S8

Signed 8-bit samples

AUDIO_U16 or AUDIO_U16LSB

Unsigned 16-bit little-endian samples

AUDIO_S16 or AUDIO_S16LSB

Signed 16-bit little-endian samples

AUDIO_U16MSB

Unsigned 16-bit big-endian samples

AUDIO_S16MSB

Signed 16-bit big-endian samples

AUDIO_U16SYS

Either AUDIO_U16LSB or AUDIO_U16MSB depending on you systems endianness

AUDIO_S16SYS

Either AUDIO_S16LSB or AUDIO_S16MSB depending on you systems endianness

channelsThe number of seperate sound channels. 1 is mono (single channel), 2 is stereo (dual channel).
samplesWhen used with SDL_OpenAudio this refers to the size of the audio buffer in samples. A sample a chunk of audio data of the size specified in format mulitplied by the number of channels. When the SDL_AudioSpec is used with SDL_LoadWAV samples is set to 4096.


PrevHomeNext
AudioUpSDL_OpenAudio
\ No newline at end of file diff --git a/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlblitsurface.html b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlblitsurface.html new file mode 100644 index 000000000..b91519138 --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlblitsurface.html @@ -0,0 +1,332 @@ +SDL_BlitSurface
SDL Library Documentation
PrevNext

SDL_BlitSurface

Name

SDL_BlitSurface -- This performs a fast blit from the source surface to the destination surface.

Synopsis

#include "SDL.h"

int SDL_BlitSurface(SDL_Surface *src, SDL_Rect *srcrect, SDL_Surface *dst, SDL_Rect *dstrect);

Description

This performs a fast blit from the source surface to the destination surface.

Only the position is used in the dstrect (the +width and height are ignored).

If either srcrect or +dstrect are NULL, the entire +surface (src or dst) is +copied.

The final blit rectangle is saved in +dstrect after all clipping is performed +(srcrect is not modified).

The blit function should not be called on a locked surface.

The results of blitting operations vary greatly depending on whether SDL_SRCAPLHA is set or not. See SDL_SetAlpha for an explaination of how this affects your results. Colorkeying and alpha attributes also interact with surface blitting, as the following pseudo-code should hopefully explain. +

if (source surface has SDL_SRCALPHA set) {
+    if (source surface has alpha channel (that is, format->Amask != 0))
+        blit using per-pixel alpha, ignoring any colour key
+    else {
+        if (source surface has SDL_SRCCOLORKEY set)
+            blit using the colour key AND the per-surface alpha value
+        else
+            blit using the per-surface alpha value
+    }
+} else {
+    if (source surface has SDL_SRCCOLORKEY set)
+        blit using the colour key
+    else
+        ordinary opaque rectangular blit
+}

Return Value

If the blit is successful, it returns 0, +otherwise it returns -1.

If either of the surfaces were in video memory, and the blit returns +-2, the video memory was lost, so it should be +reloaded with artwork and re-blitted: +

        while ( SDL_BlitSurface(image, imgrect, screen, dstrect) == -2 ) {
+                while ( SDL_LockSurface(image)) < 0 )
+                        Sleep(10);
+                -- Write image pixels to image->pixels --
+                SDL_UnlockSurface(image);
+        }
+This happens under DirectX 5.0 when the system switches away from your +fullscreen application. Locking the surface will also fail until you +have access to the video memory again.


PrevHomeNext
SDL_ConvertSurfaceUpSDL_FillRect
\ No newline at end of file diff --git a/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlbuildaudiocvt.html b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlbuildaudiocvt.html new file mode 100644 index 000000000..8b110440c --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlbuildaudiocvt.html @@ -0,0 +1,283 @@ +SDL_BuildAudioCVT
SDL Library Documentation
PrevNext

SDL_BuildAudioCVT

Name

SDL_BuildAudioCVT -- Initializes a SDL_AudioCVT structure for conversion

Synopsis

#include "SDL.h"

int SDL_BuildAudioCVT(SDL_AudioCVT *cvt, Uint16 src_format, Uint8 src_channels, int src_rate, Uint16 dst_format, Uint8 dst_channels, int dst_rate);

Description

Before an SDL_AudioCVT structure can be used to convert audio data it must be initialized with source and destination information.

src_format and dst_format are the source and destination format of the conversion. (For information on audio formats see SDL_AudioSpec). src_channels and dst_channels are the number of channels in the source and destination formats. Finally, src_rate and dst_rate are the frequency or samples-per-second of the source and destination formats. Once again, see SDL_AudioSpec.

Return Values

Returns -1 if the filter could not be built or 1 if it could.

Examples

See SDL_ConvertAudio.


PrevHomeNext
SDL_AudioCVTUpSDL_ConvertAudio
\ No newline at end of file diff --git a/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlcd.html b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlcd.html new file mode 100644 index 000000000..da51731a4 --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlcd.html @@ -0,0 +1,351 @@ +SDL_CD
SDL Library Documentation
PrevNext

SDL_CD

Name

SDL_CD -- CDROM Drive Information

Structure Definition

typedef struct{
+  int id;
+  CDstatus status;
+  int numtracks;
+  int cur_track;
+  int cur_frame;
+  SDL_CDtrack track[SDL_MAX_TRACKS+1];
+} SDL_CD;

Structure Data

idPrivate drive identifier
statusDrive status
numtracksNumber of tracks on the CD
cur_trackCurrent track
cur_frameCurrent frame offset within the track
track[SDL_MAX_TRACKS+1]Array of track descriptions. (see SDL_CDtrack)

Description

An SDL_CD structure is returned by SDL_CDOpen. It represents an opened CDROM device and stores information on the layout of the tracks on the disc.

A frame is the base data unit of a CD. CD_FPS frames is equal to 1 second of music. SDL provides two macros for converting between time and frames: FRAMES_TO_MSF(f, M,S,F) and MSF_TO_FRAMES.

Examples

int min, sec, frame;
+int frame_offset;
+
+FRAMES_TO_MSF(cdrom->cur_frame, &min, &sec, &frame);
+printf("Current Position: %d minutes, %d seconds, %d frames\n", min, sec, frame);
+
+frame_offset=MSF_TO_FRAMES(min, sec, frame);

PrevHomeNext
SDL_CDCloseUpSDL_CDtrack
\ No newline at end of file diff --git a/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlcdclose.html b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlcdclose.html new file mode 100644 index 000000000..6fd3bdff2 --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlcdclose.html @@ -0,0 +1,209 @@ +SDL_CDClose
SDL Library Documentation
PrevNext

SDL_CDClose

Name

SDL_CDClose -- Closes a SDL_CD handle

Synopsis

#include "SDL.h"

void SDL_CDClose(SDL_CD *cdrom);

Description

Closes the given cdrom handle.

See Also

SDL_CDOpen, +SDL_CD


PrevHomeNext
SDL_CDEjectUpSDL_CD
\ No newline at end of file diff --git a/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlcdeject.html b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlcdeject.html new file mode 100644 index 000000000..1b650e56a --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlcdeject.html @@ -0,0 +1,218 @@ +SDL_CDEject
SDL Library Documentation
PrevNext

SDL_CDEject

Name

SDL_CDEject -- Ejects a CDROM

Synopsis

#include "SDL.h"

int SDL_CDEject(SDL_CD *cdrom);

Description

Ejects the given cdrom.

Return Value

Returns 0 on success, or -1 on an error.

See Also

SDL_CD


PrevHomeNext
SDL_CDStopUpSDL_CDClose
\ No newline at end of file diff --git a/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlcdname.html b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlcdname.html new file mode 100644 index 000000000..4a3aa7fd3 --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlcdname.html @@ -0,0 +1,231 @@ +SDL_CDName
SDL Library Documentation
PrevNext

SDL_CDName

Name

SDL_CDName -- Returns a human-readable, system-dependent identifier for the CD-ROM.

Synopsis

#include "SDL.h"

const char *SDL_CDName(int drive);

Description

Returns a human-readable, system-dependent identifier for the CD-ROM. drive is the index of the drive. Drive indices start to 0 and end at SDL_CDNumDrives()-1.

Examples

  • "/dev/cdrom"

  • "E:"

  • "/dev/disk/ide/1/master"


PrevHomeNext
SDL_CDNumDrivesUpSDL_CDOpen
\ No newline at end of file diff --git a/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlcdnumdrives.html b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlcdnumdrives.html new file mode 100644 index 000000000..4f788bc80 --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlcdnumdrives.html @@ -0,0 +1,197 @@ +SDL_CDNumDrives
SDL Library Documentation
PrevNext

SDL_CDNumDrives

Name

SDL_CDNumDrives -- Returns the number of CD-ROM drives on the system.

Synopsis

#include "SDL.h"

int SDL_CDNumDrives(void);

Description

Returns the number of CD-ROM drives on the system.

See Also

SDL_CDOpen


PrevHomeNext
CD-ROMUpSDL_CDName
\ No newline at end of file diff --git a/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlcdopen.html b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlcdopen.html new file mode 100644 index 000000000..ae345ffb1 --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlcdopen.html @@ -0,0 +1,267 @@ +SDL_CDOpen
SDL Library Documentation
PrevNext

SDL_CDOpen

Name

SDL_CDOpen -- Opens a CD-ROM drive for access.

Synopsis

#include "SDL.h"

SDL_CD *SDL_CDOpen(int drive);

Description

Opens a CD-ROM drive for access. It returns a SDL_CD structure on success, or NULL if the drive was invalid or busy. This newly opened CD-ROM becomes the default CD used when other CD functions are passed a NULL CD-ROM handle.

Drives are numbered starting with 0. +Drive 0 is the system default CD-ROM.

Examples

SDL_CD *cdrom;
+int cur_track;
+int min, sec, frame;
+SDL_Init(SDL_INIT_CDROM);
+atexit(SDL_Quit);
+
+/* Check for CD drives */
+if(!SDL_CDNumDrives()){
+  /* None found */
+  fprintf(stderr, "No CDROM devices available\n");
+  exit(-1);
+}
+
+/* Open the default drive */
+cdrom=SDL_CDOpen(0);
+
+/* Did if open? Check if cdrom is NULL */
+if(!cdrom){
+  fprintf(stderr, "Couldn't open drive: %s\n", SDL_GetError());
+  exit(-1);
+}
+
+/* Print Volume info */
+printf("Name: %s\n", SDL_CDName(0));
+printf("Tracks: %d\n", cdrom->numtracks);
+for(cur_track=0;cur_track < cdrom->numtracks; cur_track++){
+  FRAMES_TO_MSF(cdrom->track[cur_track].length, &min, &sec, &frame);
+  printf("\tTrack %d: Length %d:%d\n", cur_track, min, sec);
+}
+
+SDL_CDClose(cdrom);

PrevHomeNext
SDL_CDNameUpSDL_CDStatus
\ No newline at end of file diff --git a/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlcdpause.html b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlcdpause.html new file mode 100644 index 000000000..7ae23b91d --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlcdpause.html @@ -0,0 +1,225 @@ +SDL_CDPause
SDL Library Documentation
PrevNext

SDL_CDPause

Name

SDL_CDPause -- Pauses a CDROM

Synopsis

#include "SDL.h"

int SDL_CDPause(SDL_CD *cdrom);

Description

Pauses play on the given cdrom.

Return Value

Returns 0 on success, or -1 on an error.


PrevHomeNext
SDL_CDPlayTracksUpSDL_CDResume
\ No newline at end of file diff --git a/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlcdplay.html b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlcdplay.html new file mode 100644 index 000000000..4cc90c3eb --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlcdplay.html @@ -0,0 +1,235 @@ +SDL_CDPlay
SDL Library Documentation
PrevNext

SDL_CDPlay

Name

SDL_CDPlay -- Play a CD

Synopsis

#include "SDL.h"

int SDL_CDPlay(SDL_CD *cdrom, int start, int length);

Description

Plays the given cdrom, starting a frame start for length frames.

Return Values

Returns 0 on success, or -1 on an error.


PrevHomeNext
SDL_CDStatusUpSDL_CDPlayTracks
\ No newline at end of file diff --git a/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlcdplaytracks.html b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlcdplaytracks.html new file mode 100644 index 000000000..9a71bc28a --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlcdplaytracks.html @@ -0,0 +1,317 @@ +SDL_CDPlayTracks
SDL Library Documentation
PrevNext

SDL_CDPlayTracks

Name

SDL_CDPlayTracks -- Play the given CD track(s)

Synopsis

#include "SDL.h"

int SDL_CDPlayTracks(SDL_CD *cdrom, int start_track, int start_frame, int ntracks, int nframes));

Description

SDL_CDPlayTracks plays the given CD starting at track +start_track, for ntracks tracks.

start_frame is the frame offset, from the beginning of the start_track, at which to start. nframes is the frame offset, from the beginning of the last track (start_track+ntracks), at which to end playing.

SDL_CDPlayTracks should only be called after calling +SDL_CDStatus +to get track information about the CD.

Note: Data tracks are ignored.

Return Value

Returns 0, or -1 +if there was an error.

Examples

/* assuming cdrom is a previously opened device */
+/* Play the entire CD */
+if(CD_INDRIVE(SDL_CDStatus(cdrom)))
+  SDL_CDPlayTracks(cdrom, 0, 0, 0, 0);
+
+/* Play the first track */
+if(CD_INDRIVE(SDL_CDStatus(cdrom)))
+  SDL_CDPlayTracks(cdrom, 0, 0, 1, 0);
+
+/* Play first 15 seconds of the 2nd track */
+if(CD_INDRIVE(SDL_CDStatus(cdrom)))
+  SDL_CDPlayTracks(cdrom, 1, 0, 0, CD_FPS*15);
+


PrevHomeNext
SDL_CDPlayUpSDL_CDPause
\ No newline at end of file diff --git a/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlcdresume.html b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlcdresume.html new file mode 100644 index 000000000..552c01e64 --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlcdresume.html @@ -0,0 +1,225 @@ +SDL_CDResume
SDL Library Documentation
PrevNext

SDL_CDResume

Name

SDL_CDResume -- Resumes a CDROM

Synopsis

#include "SDL.h"

int SDL_CDResume(SDL_CD *cdrom);

Description

Resumes play on the given cdrom.

Return Value

Returns 0 on success, or -1 on an error.


PrevHomeNext
SDL_CDPauseUpSDL_CDStop
\ No newline at end of file diff --git a/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlcdstatus.html b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlcdstatus.html new file mode 100644 index 000000000..b40ab3482 --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlcdstatus.html @@ -0,0 +1,265 @@ +SDL_CDStatus
SDL Library Documentation
PrevNext

SDL_CDStatus

Name

SDL_CDStatus -- Returns the current status of the given drive.

Synopsis

#include "SDL.h"

CDstatus SDL_CDStatus(SDL_CD *cdrom);

/* Given a status, returns true if there's a disk in the drive */
+#define CD_INDRIVE(status)      ((int)status > 0)

Description

This function returns the current status of the given drive. Status is described like so: +

typedef enum {
+  CD_TRAYEMPTY,
+  CD_STOPPED,
+  CD_PLAYING,
+  CD_PAUSED,
+  CD_ERROR = -1
+} CDstatus;

If the drive has a CD in it, the table of contents of the CD and current +play position of the CD will be stored in the SDL_CD structure.

The macro CD_INDRIVE is provided for convenience, +and given a status returns true if there's a disk in the drive.

Note: SDL_CDStatus also updates the SDL_CD structure passed to it.

Example

int playTrack(int track)
+{
+  int playing = 0;
+
+  if ( CD_INDRIVE(SDL_CDStatus(cdrom)) ) {
+  /* clamp to the actual number of tracks on the CD */
+    if (track >= cdrom->numtracks) {
+      track = cdrom->numtracks-1;
+    }
+
+    if ( SDL_CDPlayTracks(cdrom, track, 0, 1, 0) == 0 ) {
+      playing = 1;
+    }
+  }
+  return playing;
+}

See Also

SDL_CD


PrevHomeNext
SDL_CDOpenUpSDL_CDPlay
\ No newline at end of file diff --git a/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlcdstop.html b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlcdstop.html new file mode 100644 index 000000000..1cc3b1abc --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlcdstop.html @@ -0,0 +1,218 @@ +SDL_CDStop
SDL Library Documentation
PrevNext

SDL_CDStop

Name

SDL_CDStop -- Stops a CDROM

Synopsis

#include "SDL.h"

int SDL_CDStop(SDL_CD *cdrom);

Description

Stops play on the given cdrom.

Return Value

Returns 0 on success, or -1 on an error.

See Also

SDL_CDPlay,


PrevHomeNext
SDL_CDResumeUpSDL_CDEject
\ No newline at end of file diff --git a/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlcdtrack.html b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlcdtrack.html new file mode 100644 index 000000000..4966043d6 --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlcdtrack.html @@ -0,0 +1,305 @@ +SDL_CDtrack
SDL Library Documentation
PrevNext

SDL_CDtrack

Name

SDL_CDtrack -- CD Track Information Structure

Structure Definition

typedef struct{
+  Uint8 id;
+  Uint8 type;
+  Uint32 length;
+  Uint32 offset;
+} SDL_CDtrack;

Structure Data

idTrack number (0-99)
typeSDL_AUDIO_TRACK or SDL_DATA_TRACK
lengthLength, in frames, of this track
offsetFrame offset to the beginning of this track

Description

SDL_CDtrack stores data on each track on a CD, its fields should be pretty self explainatory. It is a member a the SDL_CD structure.

Note: Frames can be converted to standard timings. There are CD_FPS frames per second, so SDL_CDtrack.length/CD_FPS=length_in_seconds.

See Also

SDL_CD


PrevHomeNext
SDL_CDUpMulti-threaded Programming
\ No newline at end of file diff --git a/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlcloseaudio.html b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlcloseaudio.html new file mode 100644 index 000000000..bfd4e9b59 --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlcloseaudio.html @@ -0,0 +1,197 @@ +SDL_CloseAudio
SDL Library Documentation
PrevNext

SDL_CloseAudio

Name

SDL_CloseAudio -- Shuts down audio processing and closes the audio device.

Synopsis

#include "SDL.h"

void SDL_CloseAudio(void);

Description

This function shuts down audio processing and closes the audio device.

See Also

SDL_OpenAudio


PrevHomeNext
SDL_UnlockAudioUpCD-ROM
\ No newline at end of file diff --git a/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlcolor.html b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlcolor.html new file mode 100644 index 000000000..d0fa5eadd --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlcolor.html @@ -0,0 +1,292 @@ +SDL_Color
SDL Library Documentation
PrevNext

SDL_Color

Name

SDL_Color -- Format independent color description

Structure Definition

typedef struct{
+  Uint8 r;
+  Uint8 g;
+  Uint8 b;
+  Uint8 unused;
+} SDL_Color;

Structure Data

rRed intensity
gGreen intensity
bBlue intensity
unusedUnused

Description

SDL_Color describes a color in a format independent way. You can convert a SDL_Color to a pixel value for a certain pixel format using SDL_MapRGB.


PrevHomeNext
SDL_RectUpSDL_Palette
\ No newline at end of file diff --git a/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlcondbroadcast.html b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlcondbroadcast.html new file mode 100644 index 000000000..04b6acc71 --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlcondbroadcast.html @@ -0,0 +1,216 @@ +SDL_CondBroadcast
SDL Library Documentation
PrevNext

SDL_CondBroadcast

Name

SDL_CondBroadcast -- Restart all threads waiting on a condition variable

Synopsis

#include "SDL.h"
+#include "SDL_thread.h"

int SDL_CondBroadcast(SDL_cond *cond);

Description

Restarts all threads that are waiting on the condition variable, cond. Returns 0 on success, or -1 on an error.


PrevHomeNext
SDL_CondSignalUpSDL_CondWait
\ No newline at end of file diff --git a/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlcondsignal.html b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlcondsignal.html new file mode 100644 index 000000000..7b27847c2 --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlcondsignal.html @@ -0,0 +1,216 @@ +SDL_CondSignal
SDL Library Documentation
PrevNext

SDL_CondSignal

Name

SDL_CondSignal -- Restart a thread wait on a condition variable

Synopsis

#include "SDL.h"
+#include "SDL_thread.h"

int SDL_CondSignal(SDL_cond *cond);

Description

Restart one of the threads that are waiting on the condition variable, cond. Returns 0 on success of -1 on an error.


PrevHomeNext
SDL_DestroyCondUpSDL_CondBroadcast
\ No newline at end of file diff --git a/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlcondwait.html b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlcondwait.html new file mode 100644 index 000000000..c6b429006 --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlcondwait.html @@ -0,0 +1,223 @@ +SDL_CondWait
SDL Library Documentation
PrevNext

SDL_CondWait

Name

SDL_CondWait -- Wait on a condition variable

Synopsis

#include "SDL.h"
+#include "SDL_thread.h"

int SDL_CondWait(SDL_cond *cond, SDL_mutex *mut);

Description

Wait on the condition variable cond and unlock the provided mutex. The mutex must the locked before entering this function. Returns 0 when it is signalled, or -1 on an error.


PrevHomeNext
SDL_CondBroadcastUpSDL_CondWaitTimeout
\ No newline at end of file diff --git a/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlcondwaittimeout.html b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlcondwaittimeout.html new file mode 100644 index 000000000..c5d0f47d5 --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlcondwaittimeout.html @@ -0,0 +1,222 @@ +SDL_CondWaitTimeout
SDL Library Documentation
PrevNext

SDL_CondWaitTimeout

Name

SDL_CondWaitTimeout -- Wait on a condition variable, with timeout

Synopsis

#include "SDL.h"
+#include "SDL_thread.h"

int SDL_CondWaitTimeout(SDL_cond *cond, SDL_mutex *mutex, Uint32 ms);

Description

Wait on the condition variable cond for, at most, ms milliseconds. mut is unlocked so it must be locked when the function is called. Returns SDL_MUTEX_TIMEDOUT if the condition is not signalled in the allotted time, 0 if it was signalled or -1 on an error.

See Also

SDL_CondWait


PrevHomeNext
SDL_CondWaitUpTime
\ No newline at end of file diff --git a/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlconvertaudio.html b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlconvertaudio.html new file mode 100644 index 000000000..71659c94c --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlconvertaudio.html @@ -0,0 +1,399 @@ +SDL_ConvertAudio
SDL Library Documentation
PrevNext

SDL_ConvertAudio

Name

SDL_ConvertAudio -- Convert audio data to a desired audio format.

Synopsis

#include "SDL.h"

int SDL_ConvertAudio(SDL_AudioCVT *cvt);

Description

SDL_ConvertAudio takes one parameter, cvt, which was previously initilized. Initilizing a SDL_AudioCVT is a two step process. First of all, the structure must be passed to SDL_BuildAudioCVT along with source and destination format parameters. Secondly, the cvt->buf and cvt->len fields must be setup. cvt->buf should point to the audio data and cvt->len should be set to the length of the audio data in bytes. Remember, the length of the buffer pointed to by buf show be len*len_mult bytes in length.

Once the SDL_AudioCVTstructure is initilized then we can pass it to SDL_ConvertAudio, which will convert the audio data pointer to by cvt->buf. If SDL_ConvertAudio returned 0 then the conversion was completed successfully, otherwise -1 is returned.

If the conversion completed successfully then the converted audio data can be read from cvt->buf. The amount of valid, converted, audio data in the buffer is equal to cvt->len*cvt->len_ratio.

Examples

/* Converting some WAV data to hardware format */
+void my_audio_callback(void *userdata, Uint8 *stream, int len);
+
+SDL_AudioSpec *desired, *obtained;
+SDL_AudioSpec wav_spec;
+SDL_AudioCVT  wav_cvt;
+Uint32 wav_len;
+Uint8 *wav_buf;
+int ret;
+
+/* Allocated audio specs */
+desired=(SDL_AudioSpec *)malloc(sizeof(SDL_AudioSpec));
+obtained=(SDL_AudioSpec *)malloc(sizeof(SDL_AudioSpec));
+
+/* Set desired format */
+desired->freq=22050;
+desired->format=AUDIO_S16LSB;
+desired->samples=8192;
+desired->callback=my_audio_callback;
+desired->userdata=NULL;
+
+/* Open the audio device */
+if ( SDL_OpenAudio(desired, obtained) < 0 ){
+  fprintf(stderr, "Couldn't open audio: %s\n", SDL_GetError());
+  exit(-1);
+}
+        
+free(desired);
+
+/* Load the test.wav */
+if( SDL_LoadWAV("test.wav", &wav_spec, &wav_buf, &wav_len) == NULL ){
+  fprintf(stderr, "Could not open test.wav: %s\n", SDL_GetError());
+  SDL_CloseAudio();
+  free(obtained);
+  exit(-1);
+}
+                                            
+/* Build AudioCVT */
+ret = SDL_BuildAudioCVT(&wav_cvt,
+                        wav_spec.format, wav_spec.channels, wav_spec.freq,
+                        obtained->format, obtained->channels, obtained->freq);
+
+/* Check that the convert was built */
+if(ret==-1){
+  fprintf(stderr, "Couldn't build converter!\n");
+  SDL_CloseAudio();
+  free(obtained);
+  SDL_FreeWAV(wav_buf);
+}
+
+/* Setup for conversion */
+wav_cvt.buf=(Uint8 *)malloc(wav_len*wav_cvt.len_mult);
+wav_cvt.len=wav_len;
+memcpy(wav_cvt.buf, wav_buf, wav_len);
+
+/* We can delete to original WAV data now */
+SDL_FreeWAV(wav_buf);
+
+/* And now we're ready to convert */
+SDL_ConvertAudio(&wav_cvt);
+
+/* do whatever */
+.
+.
+.
+.
+

PrevHomeNext
SDL_BuildAudioCVTUpSDL_MixAudio
\ No newline at end of file diff --git a/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlconvertsurface.html b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlconvertsurface.html new file mode 100644 index 000000000..5f12f6e00 --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlconvertsurface.html @@ -0,0 +1,261 @@ +SDL_ConvertSurface
SDL Library Documentation
PrevNext

SDL_ConvertSurface

Name

SDL_ConvertSurface -- Converts a surface to the same format as another surface.

Synopsis

#include "SDL.h"

SDL_Surface *SDL_ConvertSurface(SDL_Surface *src, SDL_PixelFormat *fmt, Uint32 flags);

Description

Creates a new surface of the specified format, and then copies and maps +the given surface to it. If this function fails, it returns +NULL.

The flags parameter is passed to +SDL_CreateRGBSurface +and has those semantics.

This function is used internally by +SDL_DisplayFormat.

Return Value

Returns either a pointer to the new surface, or +NULL on error.


PrevHomeNext
SDL_GetClipRectUpSDL_BlitSurface
\ No newline at end of file diff --git a/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlcreatecond.html b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlcreatecond.html new file mode 100644 index 000000000..d74b0249e --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlcreatecond.html @@ -0,0 +1,232 @@ +SDL_CreateCond
SDL Library Documentation
PrevNext

SDL_CreateCond

Name

SDL_CreateCond -- Create a condition variable

Synopsis

#include "SDL.h"
+#include "SDL_thread.h"

SDL_cond *SDL_CreateCond(void);

Description

Creates a condition variable.

Examples

SDL_cond *cond;
+
+cond=SDL_CreateCond();
+.
+.
+/* Do stuff */
+
+.
+.
+SDL_DestroyCond(cond);

PrevHomeNext
SDL_SemValueUpSDL_DestroyCond
\ No newline at end of file diff --git a/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlcreatecursor.html b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlcreatecursor.html new file mode 100644 index 000000000..70ee39850 --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlcreatecursor.html @@ -0,0 +1,390 @@ +SDL_CreateCursor
SDL Library Documentation
PrevNext

SDL_CreateCursor

Name

SDL_CreateCursor -- Creates a new mouse cursor.

Synopsis

#include "SDL.h"

SDL_Cursor *SDL_CreateCursor(Uint8 *data, Uint8 *mask, int w, int h, int hot_x, int hot_y);

Description

Create a cursor using the specified data and mask (in MSB format). +The cursor width must be a multiple of 8 bits.

The cursor is created in black and white according to the following: +

Data / MaskResulting pixel on screen
0 / 1White
1 / 1Black
0 / 0Transparent
1 / 0Inverted color if possible, black if not.

Cursors created with this function must be freed with +SDL_FreeCursor.

Example

/* Stolen from the mailing list */
+/* Creates a new mouse cursor from an XPM */
+
+
+/* XPM */
+static const char *arrow[] = {
+  /* width height num_colors chars_per_pixel */
+  "    32    32        3            1",
+  /* colors */
+  "X c #000000",
+  ". c #ffffff",
+  "  c None",
+  /* pixels */
+  "X                               ",
+  "XX                              ",
+  "X.X                             ",
+  "X..X                            ",
+  "X...X                           ",
+  "X....X                          ",
+  "X.....X                         ",
+  "X......X                        ",
+  "X.......X                       ",
+  "X........X                      ",
+  "X.....XXXXX                     ",
+  "X..X..X                         ",
+  "X.X X..X                        ",
+  "XX  X..X                        ",
+  "X    X..X                       ",
+  "     X..X                       ",
+  "      X..X                      ",
+  "      X..X                      ",
+  "       XX                       ",
+  "                                ",
+  "                                ",
+  "                                ",
+  "                                ",
+  "                                ",
+  "                                ",
+  "                                ",
+  "                                ",
+  "                                ",
+  "                                ",
+  "                                ",
+  "                                ",
+  "                                ",
+  "0,0"
+};
+
+static SDL_Cursor *init_system_cursor(const char *image[])
+{
+  int i, row, col;
+  Uint8 data[4*32];
+  Uint8 mask[4*32];
+  int hot_x, hot_y;
+
+  i = -1;
+  for ( row=0; row<32; ++row ) {
+    for ( col=0; col<32; ++col ) {
+      if ( col % 8 ) {
+        data[i] <<= 1;
+        mask[i] <<= 1;
+      } else {
+        ++i;
+        data[i] = mask[i] = 0;
+      }
+      switch (image[4+row][col]) {
+        case 'X':
+          data[i] |= 0x01;
+          k[i] |= 0x01;
+          break;
+        case '.':
+          mask[i] |= 0x01;
+          break;
+        case ' ':
+          break;
+      }
+    }
+  }
+  sscanf(image[4+row], "%d,%d", &hot_x, &hot_y);
+  return SDL_CreateCursor(data, mask, 32, 32, hot_x, hot_y);
+}

PrevHomeNext
SDL_WarpMouseUpSDL_FreeCursor
\ No newline at end of file diff --git a/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlcreatemutex.html b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlcreatemutex.html new file mode 100644 index 000000000..34d907888 --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlcreatemutex.html @@ -0,0 +1,241 @@ +SDL_CreateMutex
SDL Library Documentation
PrevNext

SDL_CreateMutex

Name

SDL_CreateMutex -- Create a mutex

Synopsis

#include "SDL.h"
+#include "SDL_thread.h"

SDL_mutex *SDL_CreateMutex(void);

Description

Create a new, unlocked mutex.

Examples

SDL_mutex *mut;
+
+mut=SDL_CreateMutex();
+.
+.
+if(SDL_mutexP(mut)==-1){
+  fprintf(stderr, "Couldn't lock mutex\n");
+  exit(-1);
+}
+.
+/* Do stuff while mutex is locked */
+.
+.
+if(SDL_mutexV(mut)==-1){
+  fprintf(stderr, "Couldn't unlock mutex\n");
+  exit(-1);
+}
+
+SDL_DestroyMutex(mut);

PrevHomeNext
SDL_KillThreadUpSDL_DestroyMutex
\ No newline at end of file diff --git a/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlcreatergbsurface.html b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlcreatergbsurface.html new file mode 100644 index 000000000..3b0c44d8b --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlcreatergbsurface.html @@ -0,0 +1,450 @@ +SDL_CreateRGBSurface
SDL Library Documentation
PrevNext

SDL_CreateRGBSurface

Name

SDL_CreateRGBSurface -- Create an empty SDL_Surface

Synopsis

#include "SDL.h"

SDL_Surface *SDL_CreateRGBSurface(Uint32 flags, int width, int height, int depth, Uint32 Rmask, Uint32 Gmask, Uint32 Bmask, Uint32 Amask);

Description

Allocate an empty surface (must be called after SDL_SetVideoMode)

If depth is 8 bits an empty palette is allocated for the surface, otherwise a 'packed-pixel' SDL_PixelFormat is created using the [RGBA]mask's provided (see SDL_PixelFormat). The flags specifies the type of surface that should be created, it is an OR'd combination of the following possible values.

SDL_SWSURFACESDL will create the surface in system memory. This improves the performance of pixel level access, however you may not be able to take advantage of some types of hardware blitting.
SDL_HWSURFACESDL will attempt to create the surface in video memory. This will allow SDL to take advantage of Video->Video blits (which are often accelerated).
SDL_SRCCOLORKEYThis flag turns on colourkeying for blits from this surface. If +SDL_HWSURFACE is also specified and colourkeyed blits +are hardware-accelerated, then SDL will attempt to place the surface in +video memory. +Use SDL_SetColorKey +to set or clear this flag after surface creation.
SDL_SRCALPHAThis flag turns on alpha-blending for blits from this surface. If +SDL_HWSURFACE is also specified and alpha-blending blits +are hardware-accelerated, then the surface will be placed in video memory if +possible. +Use SDL_SetAlpha to +set or clear this flag after surface creation.

Note: If an alpha-channel is specified (that is, if Amask is +nonzero), then the SDL_SRCALPHA flag is automatically +set. You may remove this flag by calling +SDL_SetAlpha +after surface creation.

Return Value

Returns the created surface, or NULL upon error.

Example

    /* Create a 32-bit surface with the bytes of each pixel in R,G,B,A order,
+       as expected by OpenGL for textures */
+    SDL_Surface *surface;
+    Uint32 rmask, gmask, bmask, amask;
+
+    /* SDL interprets each pixel as a 32-bit number, so our masks must depend
+       on the endianness (byte order) of the machine */
+#if SDL_BYTEORDER == SDL_BIG_ENDIAN
+    rmask = 0xff000000;
+    gmask = 0x00ff0000;
+    bmask = 0x0000ff00;
+    amask = 0x000000ff;
+#else
+    rmask = 0x000000ff;
+    gmask = 0x0000ff00;
+    bmask = 0x00ff0000;
+    amask = 0xff000000;
+#endif
+
+    surface = SDL_CreateRGBSurface(SDL_SWSURFACE, width, height, 32,
+                                   rmask, gmask, bmask, amask);
+    if(surface == NULL) {
+        fprintf(stderr, "CreateRGBSurface failed: %s\n", SDL_GetError());
+        exit(1);
+    }

PrevHomeNext
SDL_GetRGBAUpSDL_CreateRGBSurfaceFrom
\ No newline at end of file diff --git a/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlcreatergbsurfacefrom.html b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlcreatergbsurfacefrom.html new file mode 100644 index 000000000..4bdfd9a36 --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlcreatergbsurfacefrom.html @@ -0,0 +1,248 @@ +SDL_CreateRGBSurfaceFrom
SDL Library Documentation
PrevNext

SDL_CreateRGBSurfaceFrom

Name

SDL_CreateRGBSurfaceFrom -- Create an SDL_Surface from pixel data

Synopsis

#include "SDL.h"

SDL_Surface *SDL_CreateRGBSurfaceFrom(void *pixels, int width, int height, int depth, int pitch, Uint32 Rmask, Uint32 Gmask, Uint32 Bmask, Uint32 Amask);

Description

Creates an SDL_Surface from the provided pixel data.

The data stored in pixels is assumed to be of the depth specified in the parameter list. The pixel data is not copied into the SDL_Surface structure so it should not be freed until the surface has been freed with a called to SDL_FreeSurface. pitch is the length of each scanline in bytes.

See SDL_CreateRGBSurface for a more detailed description of the other parameters.

Return Value

Returns the created surface, or NULL upon error.


PrevHomeNext
SDL_CreateRGBSurfaceUpSDL_FreeSurface
\ No newline at end of file diff --git a/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlcreatesemaphore.html b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlcreatesemaphore.html new file mode 100644 index 000000000..2b03e45bf --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlcreatesemaphore.html @@ -0,0 +1,295 @@ +SDL_CreateSemaphore
SDL Library Documentation
PrevNext

SDL_CreateSemaphore

Name

SDL_CreateSemaphore -- Creates a new semaphore and assigns an initial value to it.

Synopsis

#include "SDL.h"
+#include "SDL_thread.h"

SDL_sem *SDL_CreateSemaphore(Uint32 initial_value);

Description

SDL_CreateSemaphore() creates a new semaphore and +initializes it with the value initial_value. +Each locking operation on the semaphore by +SDL_SemWait, +SDL_SemTryWait or +SDL_SemWaitTimeout +will atomically decrement the semaphore value. The locking operation will be blocked +if the semaphore value is not positive (greater than zero). Each unlock operation by +SDL_SemPost +will atomically increment the semaphore value.

Return Value

Returns a pointer to an initialized semaphore or +NULL if there was an error.

Examples

SDL_sem *my_sem;
+
+my_sem = SDL_CreateSemaphore(INITIAL_SEM_VALUE);
+
+if (my_sem == NULL) {
+        return CREATE_SEM_FAILED;
+}


PrevHomeNext
SDL_mutexVUpSDL_DestroySemaphore
\ No newline at end of file diff --git a/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlcreatethread.html b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlcreatethread.html new file mode 100644 index 000000000..8d8a8d50f --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlcreatethread.html @@ -0,0 +1,215 @@ +SDL_CreateThread
SDL Library Documentation
PrevNext

SDL_CreateThread

Name

SDL_CreateThread -- Creates a new thread of execution that shares its parent's properties.

Synopsis

#include "SDL.h"
+#include "SDL_thread.h"

SDL_Thread *SDL_CreateThread(int (*fn)(void *), void *data);

Description

SDL_CreateThread creates a new thread of execution +that shares all of its parent's global memory, signal handlers, +file descriptors, etc, and runs the function fn +passed the void pointer data +The thread quits when this function returns.


PrevHomeNext
Multi-threaded ProgrammingUpSDL_ThreadID
\ No newline at end of file diff --git a/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlcreateyuvoverlay.html b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlcreateyuvoverlay.html new file mode 100644 index 000000000..13da9cc62 --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlcreateyuvoverlay.html @@ -0,0 +1,248 @@ +SDL_CreateYUVOverlay
SDL Library Documentation
PrevNext

SDL_CreateYUVOverlay

Name

SDL_CreateYUVOverlay -- Create a YUV video overlay

Synopsis

#include "SDL.h"

SDL_Overlay *SDL_CreateYUVOverlay(int width, int height, Uint32 format, SDL_Surface *display);

Description

SDL_CreateYUVOverlay creates a YUV overlay of the specified width, height and format (see SDL_Overlay for a list of available formats), for the provided display. A SDL_Overlay structure is returned.

The term 'overlay' is a misnomer since, unless the overlay is created in hardware, the contents for the display surface underneath the area where the overlay is shown will be overwritten when the overlay is displayed.


PrevHomeNext
SDL_GL_SwapBuffersUpSDL_LockYUVOverlay
\ No newline at end of file diff --git a/contrib/sdk/sources/SDL-1.2.2/docs/html/sdldelay.html b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdldelay.html new file mode 100644 index 000000000..6bd02ca3c --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdldelay.html @@ -0,0 +1,217 @@ +SDL_Delay
SDL Library Documentation
PrevNext

SDL_Delay

Name

SDL_Delay -- Wait a specified number of milliseconds before returning.

Synopsis

#include "SDL.h"

void SDL_Delay(Uint32 ms);

Description

Wait a specified number of milliseconds before returning. SDL_Delay will wait at least the specified time, but possible longer due to OS scheduling.

Note: Count on a delay granularity of at least 10 ms. +Some platforms have shorter clock ticks but this is the most common.

See Also

SDL_AddTimer


PrevHomeNext
SDL_GetTicksUpSDL_AddTimer
\ No newline at end of file diff --git a/contrib/sdk/sources/SDL-1.2.2/docs/html/sdldestroycond.html b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdldestroycond.html new file mode 100644 index 000000000..7cfbbbf62 --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdldestroycond.html @@ -0,0 +1,198 @@ +SDL_DestroyCond
SDL Library Documentation
PrevNext

SDL_DestroyCond

Name

SDL_DestroyCond -- Destroy a condition variable

Synopsis

#include "SDL.h"
+#include "SDL_thread.h"

void SDL_DestroyCond(SDL_cond *cond);

Description

Destroys a condition variable.


PrevHomeNext
SDL_CreateCondUpSDL_CondSignal
\ No newline at end of file diff --git a/contrib/sdk/sources/SDL-1.2.2/docs/html/sdldestroymutex.html b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdldestroymutex.html new file mode 100644 index 000000000..960d84030 --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdldestroymutex.html @@ -0,0 +1,201 @@ +SDL_DestroyMutex
SDL Library Documentation
PrevNext

SDL_DestroyMutex

Name

SDL_DestroyMutex -- Destroy a mutex

Synopsis

#include "SDL.h"
+#include "SDL_thread.h"

void SDL_DestroyMutex(SDL_mutex *mutex);

Description

Destroy a previously created mutex.


PrevHomeNext
SDL_CreateMutexUpSDL_mutexP
\ No newline at end of file diff --git a/contrib/sdk/sources/SDL-1.2.2/docs/html/sdldestroysemaphore.html b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdldestroysemaphore.html new file mode 100644 index 000000000..b704e6330 --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdldestroysemaphore.html @@ -0,0 +1,270 @@ +SDL_DestroySemaphore
SDL Library Documentation
PrevNext

SDL_DestroySemaphore

Name

SDL_DestroySemaphore -- Destroys a semaphore that was created by SDL_CreateSemaphore.

Synopsis

#include "SDL.h"
+#include "SDL_thread.h"

void SDL_DestroySemaphore(SDL_sem *sem);

Description

SDL_DestroySemaphore destroys the semaphore pointed to +by sem that was created by +SDL_CreateSemaphore. +It is not safe to destroy a semaphore if there are threads currently blocked +waiting on it.

Examples

if (my_sem != NULL) {
+        SDL_DestroySemaphore(my_sem);
+        my_sem = NULL;
+}


PrevHomeNext
SDL_CreateSemaphoreUpSDL_SemWait
\ No newline at end of file diff --git a/contrib/sdk/sources/SDL-1.2.2/docs/html/sdldisplayformat.html b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdldisplayformat.html new file mode 100644 index 000000000..58bfee22a --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdldisplayformat.html @@ -0,0 +1,254 @@ +SDL_DisplayFormat
SDL Library Documentation
PrevNext

SDL_DisplayFormat

Name

SDL_DisplayFormat -- Convert a surface to the display format

Synopsis

#include "SDL.h"

SDL_Surface *SDL_DisplayFormat(SDL_Surface *surface);

Description

This function takes a surface and copies it to a new surface of the +pixel format and colors of the video framebuffer, suitable for fast +blitting onto the display surface. It calls +SDL_ConvertSurface

If you want to take advantage of hardware colorkey or alpha blit +acceleration, you should set the colorkey and alpha value before +calling this function.

If you want an alpha channel, see SDL_DisplayFormatAlpha.

Return Value

If the conversion fails or runs out of memory, it returns +NULL


PrevHomeNext
SDL_FillRectUpSDL_DisplayFormatAlpha
\ No newline at end of file diff --git a/contrib/sdk/sources/SDL-1.2.2/docs/html/sdldisplayformatalpha.html b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdldisplayformatalpha.html new file mode 100644 index 000000000..82ac37a94 --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdldisplayformatalpha.html @@ -0,0 +1,242 @@ +SDL_DisplayFormatAlpha
SDL Library Documentation
PrevNext

SDL_DisplayFormatAlpha

Name

SDL_DisplayFormatAlpha -- Convert a surface to the display format

Synopsis

#include "SDL.h"

SDL_Surface *SDL_DisplayFormatAlpha(SDL_Surface *surface);

Description

This function takes a surface and copies it to a new surface of the +pixel format and colors of the video framebuffer plus an alpha channel, +suitable for fast blitting onto the display surface. It calls +SDL_ConvertSurface

If you want to take advantage of hardware colorkey or alpha blit +acceleration, you should set the colorkey and alpha value before +calling this function.

This function can be used to convert a colourkey to an alpha channel, +if the SDL_SRCCOLORKEY flag is set on the surface. +The generated surface will then be transparent (alpha=0) where the +pixels match the colourkey, and opaque (alpha=255) elsewhere.

Return Value

If the conversion fails or runs out of memory, it returns +NULL


PrevHomeNext
SDL_DisplayFormatUpSDL_WarpMouse
\ No newline at end of file diff --git a/contrib/sdk/sources/SDL-1.2.2/docs/html/sdldisplayyuvoverlay.html b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdldisplayyuvoverlay.html new file mode 100644 index 000000000..74a51abce --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdldisplayyuvoverlay.html @@ -0,0 +1,228 @@ +SDL_DisplayYUVOverlay
SDL Library Documentation
PrevNext

SDL_DisplayYUVOverlay

Name

SDL_DisplayYUVOverlay -- Blit the overlay to the display

Synopsis

#include "SDL.h"

int SDL_DisplayYUVOverlay(SDL_Overlay *overlay, SDL_Rect *dstrect);

Description

Blit the overlay to the surface specified when it was created. The SDL_Rect structure, dstrect, specifies the position and size of the destination. If the dstrect is a larger or smaller than the overlay then the overlay will be scaled, this is optimized for 2x scaling.


PrevHomeNext
SDL_UnlockYUVOverlayUpSDL_FreeYUVOverlay
\ No newline at end of file diff --git a/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlenablekeyrepeat.html b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlenablekeyrepeat.html new file mode 100644 index 000000000..09d33422f --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlenablekeyrepeat.html @@ -0,0 +1,230 @@ +SDL_EnableKeyRepeat
SDL Library Documentation
PrevNext

SDL_EnableKeyRepeat

Name

SDL_EnableKeyRepeat -- Set keyboard repeat rate.

Synopsis

#include "SDL.h"

int SDL_EnableKeyRepeat(int delay, int interval);

Description

Enables or disables the keyboard repeat rate. delay specifies how long the key must be pressed before it begins repeating, it then repeats at the speed specified by interval. Both delay and interval are expressed in milliseconds.

Setting delay to 0 disables key repeating completely. Good default values are SDL_DEFAULT_REPEAT_DELAY and SDL_DEFAULT_REPEAT_INTERVAL.

Return Value

Returns 0 on success and -1 on failure.


PrevHomeNext
SDL_EnableUNICODEUpSDL_GetMouseState
\ No newline at end of file diff --git a/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlenableunicode.html b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlenableunicode.html new file mode 100644 index 000000000..f8fd8f719 --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlenableunicode.html @@ -0,0 +1,228 @@ +SDL_EnableUNICODE
SDL Library Documentation
PrevNext

SDL_EnableUNICODE

Name

SDL_EnableUNICODE -- Enable UNICODE translation

Synopsis

#include "SDL.h"

int SDL_EnableUNICODE(int enable);

Description

Enables/Disables UNICODE keyboard translation.

If you wish to translate a keysym to it's printable representation, you need to enable UNICODE translation +using this function (enable=0) and then look in the unicode member +of the SDL_keysym structure. This value will be zero for keysyms +that do not have a printable representation. UNICODE translation is disabled by default as the conversion can cause a slight overhead.

Return Value

Returns the previous translation mode.

See Also

SDL_keysym


PrevHomeNext
SDL_GetKeyNameUpSDL_EnableKeyRepeat
\ No newline at end of file diff --git a/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlevent.html b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlevent.html new file mode 100644 index 000000000..0df7809be --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlevent.html @@ -0,0 +1,942 @@ +SDL_Event
SDL Library Documentation
PrevNext

SDL_Event

Name

SDL_Event -- General event structure

Structure Definition

typedef union{
+  Uint8 type;
+  SDL_ActiveEvent active;
+  SDL_KeyboardEvent key;
+  SDL_MouseMotionEvent motion;
+  SDL_MouseButtonEvent button;
+  SDL_JoyAxisEvent jaxis;
+  SDL_JoyBallEvent jball;
+  SDL_JoyHatEvent jhat;
+  SDL_JoyButtonEvent jbutton;
+  SDL_ResizeEvent resize;
+  SDL_QuitEvent quit;
+  SDL_UserEvent user;
+  SDL_SywWMEvent syswm;
+} SDL_Event;

Description

The SDL_Event union is the core to all event handling is SDL, its probably the most important structure after SDL_Surface. SDL_Event is a union of all event structures used in SDL, using it is a simple matter of knowing which union member relates to which event type.

Event typeEvent Structure
SDL_ACTIVEEVENTSDL_ActiveEvent
SDL_KEYDOWN/UPSDL_KeyboardEvent
SDL_MOUSEMOTIONSDL_MouseMotionEvent
SDL_MOUSEBUTTONDOWN/UPSDL_MouseButtonEvent
SDL_JOYAXISMOTIONSDL_JoyAxisEvent
SDL_JOYBALLMOTIONSDL_JoyBallEvent
SDL_JOYHATMOTIONSDL_JoyHatEvent
SDL_JOYBUTTONDOWN/UPSDL_JoyButtonEvent
SDL_QUITSDL_QuitEvent
SDL_SYSWMEVENTSDL_SysWMEvent
SDL_VIDEORESIZESDL_ResizeEvent
SDL_USEREVENTSDL_UserEvent

Use

The SDL_Event structure has two uses

  • Reading events on the event queue

  • Placing events on the event queue

Reading events from the event queue is done with either SDL_PollEvent or SDL_PeepEvents. We'll use SDL_PollEvent and step through an example.

First off, we create an empty SDL_Event structure. +

SDL_Event test_event;
+SDL_PollEvent removes the next event from the event queue, if there are no events on the queue it returns 0 otherwise it returns 1. We use a while loop to process each event in turn. +
while(SDL_PollEvent(&test_event)) {
+The SDL_PollEvent function take a pointer to an SDL_Event structure that is to be filled with event information. We know that if SDL_PollEvent removes an event from the queue then the event information will be placed in our test_event structure, but we also know that the type of event will be placed in the type member of test_event. So to handle each event type seperately we use a switch statement. +
  switch(test_event.type) {
+We need to know what kind of events we're looking for and the event type's of those events. So lets assume we want to detect where the user is moving the mouse pointer within our application. We look through our event types and notice that SDL_MOUSEMOTION is, more than likely, the event we're looking for. A little more research tells use that SDL_MOUSEMOTION events are handled within the SDL_MouseMotionEvent structure which is the motion member of SDL_Event. We can check for the SDL_MOUSEMOTION event type within our switch statement like so: +
    case SDL_MOUSEMOTION:
+All we need do now is read the information out of the motion member of test_event. +
      printf("We got a motion event.\n");
+      printf("Current mouse position is: (%d, %d)\n", test_event.motion.x, test_event.motion.y);
+      break;
+    default:
+      printf("Unhandled Event!\n");
+      break;
+  }
+}
+printf("Event queue empty.\n");

It is also possible to push events onto the event queue and so use it as a two-way communication path. Both SDL_PushEvent and SDL_PeepEvents allow you to place events onto the event queue. This is usually used to place a SDL_USEREVENT on the event queue, however you could use it to post fake input events if you wished. Creating your own events is a simple matter of choosing the event type you want, setting the type member and filling the appropriate member structure with information. +

SDL_Event user_event;
+
+user_event.type=SDL_USEREVENT;
+user_event.user.code=2;
+user_event.user.data1=NULL;
+user_event.user.data2=NULL;
+SDL_PushEvent(&user_event);


PrevHomeNext
SDL Event Structures.UpSDL_ActiveEvent
\ No newline at end of file diff --git a/contrib/sdk/sources/SDL-1.2.2/docs/html/sdleventstate.html b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdleventstate.html new file mode 100644 index 000000000..7fcaa1fb7 --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdleventstate.html @@ -0,0 +1,268 @@ +SDL_EventState
SDL Library Documentation
PrevNext

SDL_EventState

Name

SDL_EventState -- This function allows you to set the state of processing certain events.

Synopsis

#include "SDL.h"

Uint8 SDL_EventState(Uint8 type, int state);

Description

This function allows you to set the state of processing certain event type's.

If state is set to SDL_IGNORE, +that event type will be automatically dropped from the event queue and will +not be filtered.

If state is set to SDL_ENABLE, +that event type will be processed normally.

If state is set to SDL_QUERY, +SDL_EventState will return the current processing +state of the specified event type.

A list of event type's can be found in the SDL_Event section.

See Also

SDL_Event


PrevHomeNext
SDL_GetEventFilterUpSDL_GetKeyState
\ No newline at end of file diff --git a/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlfillrect.html b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlfillrect.html new file mode 100644 index 000000000..c49d08fcb --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlfillrect.html @@ -0,0 +1,270 @@ +SDL_FillRect
SDL Library Documentation
PrevNext

SDL_FillRect

Name

SDL_FillRect -- This function performs a fast fill of the given rectangle with some color

Synopsis

#include "SDL.h"

int SDL_FillRect(SDL_Surface *dst, SDL_Rect *dstrect, Uint32 color);

Description

This function performs a fast fill of the given rectangle with +color. If dstrect +is NULL, the whole surface will be filled with +color.

The color should be a pixel of the format used by the surface, and +can be generated by the +SDL_MapRGB +function.

If there is a clip rectangle set on the destination (set via +SDL_SetClipRect) then this +function will clip based on the intersection of the clip rectangle and +the dstrect rectangle.

Return Value

This function returns 0 on success, or +-1 on error.


PrevHomeNext
SDL_BlitSurfaceUpSDL_DisplayFormat
\ No newline at end of file diff --git a/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlflip.html b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlflip.html new file mode 100644 index 000000000..e410df4cb --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlflip.html @@ -0,0 +1,251 @@ +SDL_Flip
SDL Library Documentation
PrevNext

SDL_Flip

Name

SDL_Flip -- Swaps screen buffers

Synopsis

#include "SDL.h"

int SDL_Flip(SDL_Surface *screen);

Description

On hardware that supports double-buffering, this function sets up a flip +and returns. The hardware will wait for vertical retrace, and then swap +video buffers before the next video surface blit or lock will return. +On hardware that doesn't support double-buffering, this is equivalent +to calling SDL_UpdateRect(screen, 0, 0, 0, 0)

The SDL_DOUBLEBUF flag must have been passed to +SDL_SetVideoMode, + when +setting the video mode for this function to perform hardware flipping.

Return Value

This function returns 0 if successful, or +-1 if there was an error.


PrevHomeNext
SDL_UpdateRectsUpSDL_SetColors
\ No newline at end of file diff --git a/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlfreecursor.html b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlfreecursor.html new file mode 100644 index 000000000..ec5596da6 --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlfreecursor.html @@ -0,0 +1,201 @@ +SDL_FreeCursor
SDL Library Documentation
PrevNext

SDL_FreeCursor

Name

SDL_FreeCursor -- Frees a cursor created with SDL_CreateCursor.

Synopsis

#include "SDL.h"

void SDL_FreeCursor(SDL_Cursor *cursor);

Description

Frees a SDL_Cursor that was created using +SDL_CreateCursor.


PrevHomeNext
SDL_CreateCursorUpSDL_SetCursor
\ No newline at end of file diff --git a/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlfreesurface.html b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlfreesurface.html new file mode 100644 index 000000000..3aa59a544 --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlfreesurface.html @@ -0,0 +1,211 @@ +SDL_FreeSurface
SDL Library Documentation
PrevNext

SDL_FreeSurface

Name

SDL_FreeSurface -- Frees (deletes) a SDL_Surface

Synopsis

#include "SDL.h"

void SDL_FreeSurface(SDL_Surface *surface);

Description

Frees the resources used by a previously created SDL_Surface. If the surface was created using +SDL_CreateRGBSurfaceFrom then the pixel data is not freed.


PrevHomeNext
SDL_CreateRGBSurfaceFromUpSDL_LockSurface
\ No newline at end of file diff --git a/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlfreewav.html b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlfreewav.html new file mode 100644 index 000000000..ca31005af --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlfreewav.html @@ -0,0 +1,214 @@ +SDL_FreeWAV
SDL Library Documentation
PrevNext

SDL_FreeWAV

Name

SDL_FreeWAV -- Frees previously opened WAV data

Synopsis

#include "SDL.h"

void SDL_FreeWAV(Uint8 *audio_buf);

Description

After a WAVE file has been opened with SDL_LoadWAV its data can eventually be freed with SDL_FreeWAV. audio_buf is a pointer to the buffer created by SDL_LoadWAV.

See Also

SDL_LoadWAV


PrevHomeNext
SDL_LoadWAVUpSDL_AudioCVT
\ No newline at end of file diff --git a/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlfreeyuvoverlay.html b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlfreeyuvoverlay.html new file mode 100644 index 000000000..a855ffc9c --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlfreeyuvoverlay.html @@ -0,0 +1,225 @@ +SDL_FreeYUVOverlay
SDL Library Documentation
PrevNext

SDL_FreeYUVOverlay

Name

SDL_FreeYUVOverlay -- Free a YUV video overlay

Synopsis

#include "SDL.h"

void SDL_FreeYUVOverlay(SDL_Overlay *overlay);

Description

Frees and overlay created by SDL_CreateYUVOverlay.


PrevHomeNext
SDL_DisplayYUVOverlayUpSDL_GLattr
\ No newline at end of file diff --git a/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlgetappstate.html b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlgetappstate.html new file mode 100644 index 000000000..196d32c41 --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlgetappstate.html @@ -0,0 +1,255 @@ +SDL_GetAppState
SDL Library Documentation
PrevNext

SDL_GetAppState

Name

SDL_GetAppState -- Get the state of the application

Synopsis

#include "SDL.h"

Uint8 SDL_GetAppState(void);

Description

This function returns the current state of the application. The value returned is a bitwise combination of:

SDL_APPMOUSEFOCUSThe application has mouse focus.
SDL_APPINPUTFOCUSThe application has keyboard focus
SDL_APPACTIVEThe application is visible


PrevHomeNext
SDL_GetRelativeMouseStateUpSDL_JoystickEventState
\ No newline at end of file diff --git a/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlgetaudiostatus.html b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlgetaudiostatus.html new file mode 100644 index 000000000..2d77de99c --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlgetaudiostatus.html @@ -0,0 +1,213 @@ +SDL_GetAudioStatus
SDL Library Documentation
PrevNext

SDL_GetAudioStatus

Name

SDL_GetAudioStatus -- Get the current audio state

Synopsis

#include "SDL.h"

SDL_audiostatusSDL_GetAudioStatus(void);

Description

typedef enum{
+  SDL_AUDIO_STOPPED,
+  SDL_AUDIO_PAUSED,
+  SDL_AUDIO_PLAYING
+} SDL_audiostatus;

Returns either SDL_AUDIO_STOPPED, SDL_AUDIO_PAUSED or SDL_AUDIO_PLAYING depending on the current audio state.


PrevHomeNext
SDL_PauseAudioUpSDL_LoadWAV
\ No newline at end of file diff --git a/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlgetcliprect.html b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlgetcliprect.html new file mode 100644 index 000000000..cc5cc20e4 --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlgetcliprect.html @@ -0,0 +1,221 @@ +SDL_GetClipRect
SDL Library Documentation
PrevNext

SDL_GetClipRect

Name

SDL_GetClipRect -- Gets the clipping rectangle for a surface.

Synopsis

#include "SDL.h"

void SDL_GetClipRect(SDL_Surface *surface, SDL_Rect *rect);

Description

Gets the clipping rectangle for a surface. When this surface is the +destination of a blit, only the area within the clip rectangle is +drawn into.

The rectangle pointed to by rect will be +filled with the clipping rectangle of the surface.


PrevHomeNext
SDL_SetClipRectUpSDL_ConvertSurface
\ No newline at end of file diff --git a/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlgetcursor.html b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlgetcursor.html new file mode 100644 index 000000000..8cf514088 --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlgetcursor.html @@ -0,0 +1,211 @@ +SDL_GetCursor
SDL Library Documentation
PrevNext

SDL_GetCursor

Name

SDL_GetCursor -- Get the currently active mouse cursor.

Synopsis

#include "SDL.h"

SDL_Cursor *SDL_GetCursor(void);

Description

Returns the currently active mouse cursor.


PrevHomeNext
SDL_SetCursorUpSDL_ShowCursor
\ No newline at end of file diff --git a/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlgeteventfilter.html b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlgeteventfilter.html new file mode 100644 index 000000000..c9cdf9fd1 --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlgeteventfilter.html @@ -0,0 +1,227 @@ +SDL_GetEventFilter
SDL Library Documentation
PrevNext

SDL_GetEventFilter

Name

SDL_GetEventFilter -- Retrieves a pointer to he event filter

Synopsis

#include "SDL.h"

SDL_EventFilter SDL_GetEventFilter(void);

Description

This function retrieces a pointer to the event filter that was previously set using SDL_SetEventFilter. An SDL_EventFilter function is defined as: +

typedef int (*SDL_EventFilter)(const SDL_Event *event);

Return Value

Returns a pointer to the event filter or NULL if no filter has been set.


PrevHomeNext
SDL_SetEventFilterUpSDL_EventState
\ No newline at end of file diff --git a/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlgetgammaramp.html b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlgetgammaramp.html new file mode 100644 index 000000000..425b5e42e --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlgetgammaramp.html @@ -0,0 +1,211 @@ +SDL_GetGammaRamp
SDL Library Documentation
PrevNext

SDL_GetGammaRamp

Name

SDL_GetGammaRamp -- Gets the color gamma lookup tables for the display

Synopsis

#include "SDL.h"

int SDL_GetGammaRamp(Uint16 *redtable, Uint16 *greentable, Uint16 *bluetable);

Description

Gets the gamma translation lookup tables currently used by the display. +Each table is an array of 256 Uint16 values.

Not all display hardware is able to change gamma.

Return Value

Returns -1 on error.


PrevHomeNext
SDL_SetGammaUpSDL_SetGammaRamp
\ No newline at end of file diff --git a/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlgetkeyname.html b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlgetkeyname.html new file mode 100644 index 000000000..549151ee2 --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlgetkeyname.html @@ -0,0 +1,208 @@ +SDL_GetKeyName
SDL Library Documentation
PrevNext

SDL_GetKeyName

Name

SDL_GetKeyName -- Get the name of an SDL virtual keysym

Synopsis

#include "SDL.h"

char *SDL_GetKeyName(SDLKey key);

Description

Returns the SDL-defined name of the SDLKey key.

See Also

SDLKey


PrevHomeNext
SDL_SetModStateUpSDL_EnableUNICODE
\ No newline at end of file diff --git a/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlgetkeystate.html b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlgetkeystate.html new file mode 100644 index 000000000..aca727faf --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlgetkeystate.html @@ -0,0 +1,245 @@ +SDL_GetKeyState
SDL Library Documentation
PrevNext

SDL_GetKeyState

Name

SDL_GetKeyState -- Get a snapshot of the current keyboard state

Synopsis

#include "SDL.h"

Uint8 *SDL_GetKeyState(int *numkeys);

Description

Gets a snapshot of the current keyboard state. The current state is return as a pointer to an array, the size of this array is stored in numkeys. The array is indexed by the SDLK_* symbols. A value of 1 means the key is pressed and a value of 0 means its not.

Note: Use SDL_PumpEvents to update the state array.

Example

Uint8 *keystate = SDL_GetKeyState(NULL);
+if ( keystate[SDLK_RETURN] ) printf("Return Key Pressed.\n");


PrevHomeNext
SDL_EventStateUpSDL_GetModState
\ No newline at end of file diff --git a/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlgetmodstate.html b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlgetmodstate.html new file mode 100644 index 000000000..047a8ecca --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlgetmodstate.html @@ -0,0 +1,249 @@ +SDL_GetModState
SDL Library Documentation
PrevNext

SDL_GetModState

Name

SDL_GetModState -- Get the state of modifier keys.

Synopsis

#include "SDL.h"

SDLMod SDL_GetModState(void);

Description

Returns the current of the modifier keys (CTRL, ALT, etc.).

Return Value

The return value can be an OR'd combination of the SDLMod enum.

SDLMod

typedef enum {
+  KMOD_NONE  = 0x0000,
+  KMOD_LSHIFT= 0x0001,
+  KMOD_RSHIFT= 0x0002,
+  KMOD_LCTRL = 0x0040,
+  KMOD_RCTRL = 0x0080,
+  KMOD_LALT  = 0x0100,
+  KMOD_RALT  = 0x0200,
+  KMOD_LMETA = 0x0400,
+  KMOD_RMETA = 0x0800,
+  KMOD_NUM   = 0x1000,
+  KMOD_CAPS  = 0x2000,
+  KMOD_MODE  = 0x4000,
+} SDLMod;
+SDL also defines the following symbols for convenience: +
#define KMOD_CTRL (KMOD_LCTRL|KMOD_RCTRL)
+#define KMOD_SHIFT  (KMOD_LSHIFT|KMOD_RSHIFT)
+#define KMOD_ALT  (KMOD_LALT|KMOD_RALT)
+#define KMOD_META (KMOD_LMETA|KMOD_RMETA)


PrevHomeNext
SDL_GetKeyStateUpSDL_SetModState
\ No newline at end of file diff --git a/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlgetmousestate.html b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlgetmousestate.html new file mode 100644 index 000000000..65cfa5241 --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlgetmousestate.html @@ -0,0 +1,245 @@ +SDL_GetMouseState
SDL Library Documentation
PrevNext

SDL_GetMouseState

Name

SDL_GetMouseState -- Retrieve the current state of the mouse

Synopsis

#include "SDL.h"

Uint8 SDL_GetMouseState(int *x, int *y);

Description

The current button state is returned as a button bitmask, which can +be tested using the SDL_BUTTON(X) macros, and x and y are set to the +current mouse cursor position. You can pass NULL for either x or y.

Example

SDL_PumpEvents();
+if(SDL_GetMouseState(NULL, NULL)&SDL_BUTTON(1))
+  printf("Mouse Button 1(left) is pressed.\n");

PrevHomeNext
SDL_EnableKeyRepeatUpSDL_GetRelativeMouseState
\ No newline at end of file diff --git a/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlgetrelativemousestate.html b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlgetrelativemousestate.html new file mode 100644 index 000000000..9fb7fa68c --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlgetrelativemousestate.html @@ -0,0 +1,227 @@ +SDL_GetRelativeMouseState
SDL Library Documentation
PrevNext

SDL_GetRelativeMouseState

Name

SDL_GetRelativeMouseState -- Retrieve the current state of the mouse

Synopsis

#include "SDL.h"

Uint8 SDL_GetRelativeMouseState(int *x, int *y);

Description

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 change in the mouse position since the last call to SDL_GetRelativeMouseState or since event initialization. You can pass NULL for either x or y.


PrevHomeNext
SDL_GetMouseStateUpSDL_GetAppState
\ No newline at end of file diff --git a/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlgetrgb.html b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlgetrgb.html new file mode 100644 index 000000000..b06af435e --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlgetrgb.html @@ -0,0 +1,223 @@ +SDL_GetRGB
SDL Library Documentation
PrevNext

SDL_GetRGB

Name

SDL_GetRGB -- Get RGB values from a pixel in the specified pixel format.

Synopsis

#include "SDL.h"

void SDL_GetRGB(Uint32 pixel, SDL_PixelFormat *fmt, Uint8 *r, Uint8 *g, Uint8 *b);

Description

Get RGB component values from a pixel stored in the specified pixel format.

This function uses the entire 8-bit [0..255] range when converting color +components from pixel formats with less than 8-bits per RGB component +(e.g., a completely white pixel in 16-bit RGB565 format would return +[0xff, 0xff, 0xff] not [0xf8, 0xfc, 0xf8]).


PrevHomeNext
SDL_MapRGBAUpSDL_GetRGBA
\ No newline at end of file diff --git a/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlgetrgba.html b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlgetrgba.html new file mode 100644 index 000000000..a78661430 --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlgetrgba.html @@ -0,0 +1,214 @@ +SDL_GetRGBA
SDL Library Documentation
PrevNext

SDL_GetRGBA

Name

SDL_GetRGBA -- Get RGBA values from a pixel in the specified pixel format.

Synopsis

#include "SDL.h"

void SDL_GetRGBA(Uint32 pixel, SDL_PixelFormat *fmt, Uint8 *r, Uint8 *g, Uint8 *b, Uint8 *a);

Description

Get RGBA component values from a pixel stored in the specified pixel format.

This function uses the entire 8-bit [0..255] range when converting color +components from pixel formats with less than 8-bits per RGB component +(e.g., a completely white pixel in 16-bit RGB565 format would return +[0xff, 0xff, 0xff] not [0xf8, 0xfc, 0xf8]).

If the surface has no alpha component, the alpha will be returned as 0xff +(100% opaque).


PrevHomeNext
SDL_GetRGBUpSDL_CreateRGBSurface
\ No newline at end of file diff --git a/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlgetthreadid.html b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlgetthreadid.html new file mode 100644 index 000000000..2e9cafde2 --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlgetthreadid.html @@ -0,0 +1,201 @@ +SDL_GetThreadID
SDL Library Documentation
PrevNext

SDL_GetThreadID

Name

SDL_GetThreadID -- Get the SDL thread ID of a SDL_Thread

Synopsis

#include "SDL.h"
+#include "SDL_thread.h"

Uint32 SDL_GetThreadID(SDL_Thread *thread);

Description

Returns the ID of a SDL_Thread created by SDL_CreateThread.


PrevHomeNext
SDL_ThreadIDUpSDL_WaitThread
\ No newline at end of file diff --git a/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlgetticks.html b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlgetticks.html new file mode 100644 index 000000000..3c7312b7e --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlgetticks.html @@ -0,0 +1,198 @@ +SDL_GetTicks
SDL Library Documentation
PrevNext

SDL_GetTicks

Name

SDL_GetTicks -- Get the number of milliseconds since the SDL library initialization.

Synopsis

#include "SDL.h"

Uint32 SDL_GetTicks(void);

Description

Get the number of milliseconds since the SDL library initialization. +Note that this value wraps if the program runs for more than ~49 days.

See Also

SDL_Delay


PrevHomeNext
TimeUpSDL_Delay
\ No newline at end of file diff --git a/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlgetvideoinfo.html b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlgetvideoinfo.html new file mode 100644 index 000000000..86e68ac5b --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlgetvideoinfo.html @@ -0,0 +1,218 @@ +SDL_GetVideoInfo
SDL Library Documentation
PrevNext

SDL_GetVideoInfo

Name

SDL_GetVideoInfo -- returns a pointer to information about the video hardware

Synopsis

#include "SDL.h"

SDL_VideoInfo *SDL_GetVideoInfo(void);

Description

This function returns a read-only pointer to information about the video +hardware. If this is called before SDL_SetVideoMode, the +vfmt member of the returned structure will contain the +pixel format of the "best" video mode.


PrevHomeNext
SDL_GetVideoSurfaceUpSDL_VideoDriverName
\ No newline at end of file diff --git a/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlgetvideosurface.html b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlgetvideosurface.html new file mode 100644 index 000000000..11a540466 --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlgetvideosurface.html @@ -0,0 +1,200 @@ +SDL_GetVideoSurface
SDL Library Documentation
PrevNext

SDL_GetVideoSurface

Name

SDL_GetVideoSurface -- returns a pointer to the current display surface

Synopsis

#include "SDL.h"

SDL_Surface *SDL_GetVideoSurface(void);

Description

This function returns a pointer to the current display surface. +If SDL is doing format conversion on the display surface, this +function returns the publicly visible surface, not the real video +surface.

See Also

SDL_Surface


PrevHomeNext
VideoUpSDL_GetVideoInfo
\ No newline at end of file diff --git a/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlglattr.html b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlglattr.html new file mode 100644 index 000000000..62d711dc0 --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlglattr.html @@ -0,0 +1,368 @@ +SDL_GLattr
SDL Library Documentation
PrevNext

SDL_GLattr

Name

SDL_GLattr -- SDL GL Attributes

Attributes

SDL_GL_RED_SIZESize of the framebuffer red component, in bits
SDL_GL_GREEN_SIZESize of the framebuffer green component, in bits
SDL_GL_BLUE_SIZESize of the framebuffer blue component, in bits
SDL_GL_ALPHA_SIZESize of the framebuffer alpha component, in bits
SDL_GL_DOUBLEBUFFER0 or 1, enable or disable double buffering
SDL_GL_BUFFER_SIZESize of the framebuffer, in bits
SDL_GL_DEPTH_SIZESize of the depth buffer, in bits
SDL_GL_STENCIL_SIZESize of the stencil buffer, in bits
SDL_GL_ACCUM_RED_SIZESize of the accumulation buffer red component, in bits
SDL_GL_ACCUM_GREEN_SIZESize of the accumulation buffer green component, in bits
SDL_GL_ACCUM_BLUE_SIZESize of the accumulation buffer blue component, in bits
SDL_GL_ACCUM_ALPHA_SIZESize of the accumulation buffer alpha component, in bits

Description

While you can set most OpenGL attributes normally, the attributes list above must be known before SDL sets the video mode. These attributes a set and read with SDL_GL_SetAttribute and SDL_GL_GetAttribute.


PrevHomeNext
SDL_FreeYUVOverlayUpSDL_Rect
\ No newline at end of file diff --git a/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlglgetattribute.html b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlglgetattribute.html new file mode 100644 index 000000000..44847c5c9 --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlglgetattribute.html @@ -0,0 +1,239 @@ +SDL_GL_GetAttribute
SDL Library Documentation
PrevNext

SDL_GL_GetAttribute

Name

SDL_GL_GetAttribute -- Get the value of a special SDL/OpenGL attribute

Synopsis

#include "SDL.h"

int SDL_GL_GetAttribute(SDLGLattr attr, int *value);

Description

Places the value of the SDL/OpenGL attribute attr into value. This is useful after a call to SDL_SetVideoMode to check whether your attributes have been set as you expected.

Return Value

Returns 0 on success, or -1 on an error.


PrevHomeNext
SDL_GL_GetProcAddressUpSDL_GL_SetAttribute
\ No newline at end of file diff --git a/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlglgetprocaddress.html b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlglgetprocaddress.html new file mode 100644 index 000000000..7418bf6d0 --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlglgetprocaddress.html @@ -0,0 +1,251 @@ +SDL_GL_GetProcAddress
SDL Library Documentation
PrevNext

SDL_GL_GetProcAddress

Name

SDL_GL_GetProcAddress -- Get the address of a GL function

Synopsis

#include "SDL.h"

void *SDL_GL_GetProcAddress(const char* proc);

Description

Returns the address of the GL function proc, or NULL if the function is not found. If the GL library is loaded at runtime, with SDL_GL_LoadLibrary, then all GL functions must be retrieved this way. Usually this is used to retrieve function pointers to OpenGL extensions.

Example

typedef void (*GL_ActiveTextureARB_Func)(unsigned int);
+GL_ActiveTextureARB_Func glActiveTextureARB_ptr = 0;
+int has_multitexture=1;
+.
+.
+.
+/* Get function pointer */
+glActiveTextureARB_ptr=(GL_ActiveTextureARB_Func) SDL_GL_GetProcAddress("glActiveTextureARB");
+
+/* Check for a valid function ptr */
+if(!glActiveTextureARB_ptr){
+  fprintf(stderr, "Multitexture Extensions not present.\n");
+  has_multitexture=0;
+}
+.
+.
+.
+.
+if(has_multitexture){
+  glActiveTextureARB_ptr(GL_TEXTURE0_ARB);
+  .
+  .
+}
+else{
+  .
+  .
+}

PrevHomeNext
SDL_GL_LoadLibraryUpSDL_GL_GetAttribute
\ No newline at end of file diff --git a/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlglloadlibrary.html b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlglloadlibrary.html new file mode 100644 index 000000000..ca00e6aad --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlglloadlibrary.html @@ -0,0 +1,223 @@ +SDL_GL_LoadLibrary
SDL Library Documentation
PrevNext

SDL_GL_LoadLibrary

Name

SDL_GL_LoadLibrary -- Specify an OpenGL library

Synopsis

#include "SDL.h"

int SDL_GL_LoadLibrary(const char *path);

Description

If you wish, you may load the OpenGL library at runtime, this must be done before SDL_SetVideoMode is called. The path of the GL library is passed to SDL_GL_LoadLibrary and it returns 0 on success, or -1 on an error. You must then use SDL_GL_GetProcAddress to retrieve function pointers to GL functions.


PrevHomeNext
SDL_ShowCursorUpSDL_GL_GetProcAddress
\ No newline at end of file diff --git a/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlglsetattribute.html b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlglsetattribute.html new file mode 100644 index 000000000..184e1c3ec --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlglsetattribute.html @@ -0,0 +1,278 @@ +SDL_GL_SetAttribute
SDL Library Documentation
PrevNext

SDL_GL_SetAttribute

Name

SDL_GL_SetAttribute -- Set a special SDL/OpenGL attribute

Synopsis

#include "SDL.h"

int SDL_GL_SetAttribute(SDL_GLattr attr, int value);

Description

Sets the OpenGL attribute attr to value. The attributes you set don't take effect until after a call to SDL_SetVideoMode. You should use SDL_GL_GetAttribute to check the values after a SDL_SetVideoMode call.

Return Value

Returns 0 on success, or -1 on error.

Example

SDL_GL_SetAttribute( SDL_GL_RED_SIZE, 5 );
+SDL_GL_SetAttribute( SDL_GL_GREEN_SIZE, 5 );
+SDL_GL_SetAttribute( SDL_GL_BLUE_SIZE, 5 );
+SDL_GL_SetAttribute( SDL_GL_DEPTH_SIZE, 16 );
+SDL_GL_SetAttribute( SDL_GL_DOUBLEBUFFER, 1 );
+if ( (screen=SDL_SetVideoMode( 640, 480, 16, SDL_OPENGL )) == NULL ) {
+  fprintf(stderr, "Couldn't set GL mode: %s\n", SDL_GetError());
+  SDL_Quit();
+  return;
+}

Note: The SDL_DOUBLEBUF flag is not required to enable double buffering when setting an OpenGL video mode. Double buffering is enabled or disabled using the SDL_GL_DOUBLEBUFFER attribute.


PrevHomeNext
SDL_GL_GetAttributeUpSDL_GL_SwapBuffers
\ No newline at end of file diff --git a/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlglswapbuffers.html b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlglswapbuffers.html new file mode 100644 index 000000000..a95e2c634 --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlglswapbuffers.html @@ -0,0 +1,204 @@ +SDL_GL_SwapBuffers
SDL Library Documentation
PrevNext

SDL_GL_SwapBuffers

Name

SDL_GL_SwapBuffers -- Swap OpenGL framebuffers/Update Display

Synopsis

#include "SDL.h"

void SDL_GL_SwapBuffers(void );

Description

Swap the OpenGL buffers, if double-buffering is supported.


PrevHomeNext
SDL_GL_SetAttributeUpSDL_CreateYUVOverlay
\ No newline at end of file diff --git a/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlinit.html b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlinit.html new file mode 100644 index 000000000..c5ef3b614 --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlinit.html @@ -0,0 +1,360 @@ +SDL_Init
SDL Library Documentation
PrevNext

SDL_Init

Name

SDL_Init -- Initializes SDL

Synopsis

#include "SDL.h"

int SDL_Init(Uint32 flags);

Description

Initializes SDL. This should be called before all other SDL functions. The flags parameter specifies what part(s) of SDL to initialize.

SDL_INIT_TIMERInitializes the timer subsystem.
SDL_INIT_AUDIOInitializes the audio subsystem.
SDL_INIT_VIDEOInitializes the video subsystem.
SDL_INIT_CDROMInitializes the cdrom subsystem.
SDL_INIT_JOYSTICKInitializes the joystick subsystem.
SDL_INIT_EVERYTHINGInitialize all of the above.
SDL_INIT_NOPARACHUTEPrevents SDL from catching fatal signals.
SDL_INIT_EVENTTHREAD 

Return Value

Returns -1 on an error or 0 on success.


PrevHomeNext
GeneralUpSDL_InitSubSystem
\ No newline at end of file diff --git a/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlinitsubsystem.html b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlinitsubsystem.html new file mode 100644 index 000000000..59ad2d535 --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlinitsubsystem.html @@ -0,0 +1,275 @@ +SDL_InitSubSystem
SDL Library Documentation
PrevNext

SDL_InitSubSystem

Name

SDL_InitSubSystem -- Initialize subsystems

Synopsis

#include "SDL.h"

int SDL_InitSubSystem(Uint32 flags);

Description

After SDL has been initialized with SDL_Init you may initialize uninitialized subsystems with SDL_InitSubSystem. The flags parameter is the same as that used in SDL_Init.

Examples

/* Seperating Joystick and Video initialization. */
+SDL_Init(SDL_INIT_VIDEO);
+.
+.
+SDL_SetVideoMode(640, 480, 16, SDL_DOUBLEBUF|SDL_FULLSCREEN);
+.
+/* Do Some Video stuff */
+.
+.
+/* Initialize the joystick subsystem */
+SDL_InitSubSystem(SDL_INIT_JOYSTICK);
+
+/* Do some stuff with video and joystick */
+.
+.
+.
+/* Shut them both down */
+SDL_Quit();

Return Value

Returns -1 on an error or 0 on success.


PrevHomeNext
SDL_InitUpSDL_QuitSubSystem
\ No newline at end of file diff --git a/contrib/sdk/sources/SDL-1.2.2/docs/html/sdljoyaxisevent.html b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdljoyaxisevent.html new file mode 100644 index 000000000..533f7a87f --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdljoyaxisevent.html @@ -0,0 +1,322 @@ +SDL_JoyAxisEvent
SDL Library Documentation
PrevNext

SDL_JoyAxisEvent

Name

SDL_JoyAxisEvent -- Joystick axis motion event structure

Structure Definition

typedef struct{
+  Uint8 type;
+  Uint8 which;
+  Uint8 axis;
+  Sint16 value;
+} SDL_JoyAxisEvent;

Structure Data

typeSDL_JOYAXISMOTION
whichJoystick device index
axisJoystick axis index
valueAxis value (range: -32768 to 32767)

Description

SDL_JoyAxisEvent is a member of the SDL_Event union and is used when an event of type SDL_JOYAXISMOTION is reported.

A SDL_JOYAXISMOTION event occurs when ever a user moves an axis on the joystick. The field which is the index of the joystick that reported the event and axis is the index of the axis (for a more detailed explaination see the Joystick section). value is the current position of the axis.


PrevHomeNext
SDL_MouseButtonEventUpSDL_JoyButtonEvent
\ No newline at end of file diff --git a/contrib/sdk/sources/SDL-1.2.2/docs/html/sdljoyballevent.html b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdljoyballevent.html new file mode 100644 index 000000000..f1202ee2c --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdljoyballevent.html @@ -0,0 +1,332 @@ +SDL_JoyBallEvent
SDL Library Documentation
PrevNext

SDL_JoyBallEvent

Name

SDL_JoyBallEvent -- Joystick trackball motion event structure

Structure Definition

typedef struct{
+  Uint8 type;
+  Uint8 which;
+  Uint8 ball;
+  Sint16 xrel, yrel;
+} SDL_JoyBallEvent;

Structure Data

typeSDL_JOYBALLMOTION
whichJoystick device index
ballJoystick trackball index
xrel, yrelThe relative motion in the X/Y direction

Description

SDL_JoyBallEvent is a member of the SDL_Event union and is used when an event of type SDL_JOYBALLMOTION is reported.

A SDL_JOYBALLMOTION event occurs when a user moves a trackball on the joystick. The field which is the index of the joystick that reported the event and ball is the index of the trackball (for a more detailed explaination see the Joystick section). Trackballs only return relative motion, this is the change in position on the ball since it was last polled (last cycle of the event loop) and it is stored in xrel and yrel.


PrevHomeNext
SDL_JoyHatEventUpSDL_ResizeEvent
\ No newline at end of file diff --git a/contrib/sdk/sources/SDL-1.2.2/docs/html/sdljoybuttonevent.html b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdljoybuttonevent.html new file mode 100644 index 000000000..65b4248a5 --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdljoybuttonevent.html @@ -0,0 +1,343 @@ +SDL_JoyButtonEvent
SDL Library Documentation
PrevNext

SDL_JoyButtonEvent

Name

SDL_JoyButtonEvent -- Joystick button event structure

Structure Definition

typedef struct{
+  Uint8 type;
+  Uint8 which;
+  Uint8 button;
+  Uint8 state;
+} SDL_JoyButtonEvent;

Structure Data

typeSDL_JOYBUTTONDOWN or SDL_JOYBUTTONUP
whichJoystick device index
buttonJoystick button index
stateSDL_PRESSED or SDL_RELEASED

Description

SDL_JoyButtonEvent is a member of the SDL_Event union and is used when an event of type SDL_JOYBUTTONDOWN or SDL_JOYBUTTONUP is reported.

A SDL_JOYBUTTONDOWN or SDL_JOYBUTTONUP event occurs when ever a user presses or releases a button on a joystick. The field which is the index of the joystick that reported the event and button is the index of the button (for a more detailed explaination see the Joystick section). state is the current state or the button which is either SDL_PRESSED or SDL_RELEASED.


PrevHomeNext
SDL_JoyAxisEventUpSDL_JoyHatEvent
\ No newline at end of file diff --git a/contrib/sdk/sources/SDL-1.2.2/docs/html/sdljoyhatevent.html b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdljoyhatevent.html new file mode 100644 index 000000000..85236365d --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdljoyhatevent.html @@ -0,0 +1,405 @@ +SDL_JoyHatEvent
SDL Library Documentation
PrevNext

SDL_JoyHatEvent

Name

SDL_JoyHatEvent -- Joystick hat position change event structure

Structure Definition

typedef struct{
+  Uint8 type;
+  Uint8 which;
+  Uint8 hat;
+  Uint8 value;
+} SDL_JoyHatEvent;

Structure Data

typeSDL_JOY
whichJoystick device index
hatJoystick hat index
valueHat position

Description

SDL_JoyHatEvent is a member of the SDL_Event union and is used when an event of type SDL_JOYHATMOTION is reported.

A SDL_JOYHATMOTION event occurs when ever a user moves a hat on the joystick. The field which is the index of the joystick that reported the event and hat is the index of the hat (for a more detailed exlaination see the Joystick section). value is the current position of the hat. It is a logically OR'd combination of the following values (whose meanings should be pretty obvious:) :

SDL_HAT_CENTERED
SDL_HAT_UP
SDL_HAT_RIGHT
SDL_HAT_DOWN
SDL_HAT_LEFT

The following defines are also provided:

SDL_HAT_RIGHTUP
SDL_HAT_RIGHTDOWN
SDL_HAT_LEFTUP
SDL_HAT_LEFTDOWN


PrevHomeNext
SDL_JoyButtonEventUpSDL_JoyBallEvent
\ No newline at end of file diff --git a/contrib/sdk/sources/SDL-1.2.2/docs/html/sdljoystickclose.html b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdljoystickclose.html new file mode 100644 index 000000000..00a4a8ac6 --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdljoystickclose.html @@ -0,0 +1,215 @@ +SDL_JoystickClose
SDL Library Documentation
PrevNext

SDL_JoystickClose

Name

SDL_JoystickClose -- Closes a previously opened joystick

Synopsis

#include "SDL.h"

void SDL_JoystickClose(SDL_Joystick *joystick);

Description

Close a joystick that was previously opened with SDL_JoystickOpen.


PrevHomeNext
SDL_JoystickGetBallUpAudio
\ No newline at end of file diff --git a/contrib/sdk/sources/SDL-1.2.2/docs/html/sdljoystickeventstate.html b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdljoystickeventstate.html new file mode 100644 index 000000000..131ee3df2 --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdljoystickeventstate.html @@ -0,0 +1,282 @@ +SDL_JoystickEventState
SDL Library Documentation
PrevNext

SDL_JoystickEventState

Name

SDL_JoystickEventState -- Enable/disable joystick event polling

Synopsis

#include "SDL.h"

int SDL_JoystickEventState(int state);

Description

This function is used to enable or disable joystick event processing. With joystick event processing disabled you will have to update joystick states with SDL_JoystickUpdate and read the joystick information manually. state is either SDL_QUERY, SDL_ENABLE or SDL_IGNORE.

Note: Joystick event handling is prefered

Return Value

If state is SDL_QUERY then the current state is returned, otherwise the new processing state is returned.


PrevHomeNext
SDL_GetAppStateUpJoystick
\ No newline at end of file diff --git a/contrib/sdk/sources/SDL-1.2.2/docs/html/sdljoystickgetaxis.html b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdljoystickgetaxis.html new file mode 100644 index 000000000..3851c736f --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdljoystickgetaxis.html @@ -0,0 +1,263 @@ +SDL_JoystickGetAxis
SDL Library Documentation
PrevNext

SDL_JoystickGetAxis

Name

SDL_JoystickGetAxis -- Get the current state of an axis

Synopsis

#include "SDL.h"

Sint16 SDL_JoystickGetAxis(SDL_Joystick *joystick, int axis);

Description

SDL_JoystickGetAxis returns the current state of the given axis on the given joystick.

On most modern joysticks the X axis is usually represented by axis 0 and the Y axis by axis 1. The value returned by SDL_JoystickGetAxis is a signed integer (-32768 to 32768) representing the current position of the axis, it maybe necessary to impose certain tolerances on these values to account for jitter. It is worth noting that some joysticks use axes 2 and 3 for extra buttons.

Return Value

Returns a 16-bit signed integer representing the current position of the axis.

Examples

Sint16 x_move, y_move;
+SDL_Joystick *joy1;
+.
+.
+x_move=SDL_JoystickGetAxis(joy1, 0);
+y_move=SDL_JoystickGetAxis(joy1, 1);


PrevHomeNext
SDL_JoystickUpdateUpSDL_JoystickGetHat
\ No newline at end of file diff --git a/contrib/sdk/sources/SDL-1.2.2/docs/html/sdljoystickgetball.html b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdljoystickgetball.html new file mode 100644 index 000000000..f9ac14d50 --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdljoystickgetball.html @@ -0,0 +1,254 @@ +SDL_JoystickGetBall
SDL Library Documentation
PrevNext

SDL_JoystickGetBall

Name

SDL_JoystickGetBall -- Get relative trackball motion

Synopsis

#include "SDL.h"

int SDL_JoystickGetBall(SDL_Joystick *joystick, int ball, int *dx, int *dy);

Description

Get the ball axis change.

Trackballs can only return relative motion since the last call to SDL_JoystickGetBall, these motion deltas a placed into dx and dy.

Return Value

Returns 0 on success or -1 on failure

Examples

int delta_x, delta_y;
+SDL_Joystick *joy;
+.
+.
+.
+SDL_JoystickUpdate();
+if(SDL_JoystickGetBall(joy, 0, &delta_x, &delta_y)==-1)
+  printf("TrackBall Read Error!\n");
+printf("Trackball Delta- X:%d, Y:%d\n", delta_x, delta_y);


PrevHomeNext
SDL_JoystickGetButtonUpSDL_JoystickClose
\ No newline at end of file diff --git a/contrib/sdk/sources/SDL-1.2.2/docs/html/sdljoystickgetbutton.html b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdljoystickgetbutton.html new file mode 100644 index 000000000..dfd89670f --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdljoystickgetbutton.html @@ -0,0 +1,223 @@ +SDL_JoystickGetButton
SDL Library Documentation
PrevNext

SDL_JoystickGetButton

Name

SDL_JoystickGetButton -- Get the current state of a given button on a given joystick

Synopsis

#include "SDL.h"

Uint8 SDL_JoystickGetButton(SDL_Joystick *joystick, int button);

Description

SDL_JoystickGetButton returns the current state of the given button on the given joystick.

Return Value

1 if the button is pressed. Otherwise, 0.


PrevHomeNext
SDL_JoystickGetHatUpSDL_JoystickGetBall
\ No newline at end of file diff --git a/contrib/sdk/sources/SDL-1.2.2/docs/html/sdljoystickgethat.html b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdljoystickgethat.html new file mode 100644 index 000000000..a580bf25e --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdljoystickgethat.html @@ -0,0 +1,289 @@ +SDL_JoystickGetHat
SDL Library Documentation
PrevNext

SDL_JoystickGetHat

Name

SDL_JoystickGetHat -- Get the current state of a joystick hat

Synopsis

#include "SDL.h"

Uint8 SDL_JoystickGetHat(SDL_Joystick *joystick, int hat);

Description

SDL_JoystickGetHat returns the current state of the given hat on the given joystick.

Return Value

The current state is returned as a Uint8 which is defined as an OR'd combination of one or more of the following

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


PrevHomeNext
SDL_JoystickGetAxisUpSDL_JoystickGetButton
\ No newline at end of file diff --git a/contrib/sdk/sources/SDL-1.2.2/docs/html/sdljoystickindex.html b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdljoystickindex.html new file mode 100644 index 000000000..10c148167 --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdljoystickindex.html @@ -0,0 +1,210 @@ +SDL_JoystickIndex
SDL Library Documentation
PrevNext

SDL_JoystickIndex

Name

SDL_JoystickIndex -- Get the index of an SDL_Joystick.

Synopsis

#include "SDL.h"

int SDL_JoystickIndex(SDL_Joystick *joystick);

Description

Returns the index of a given SDL_Joystick structure.

Return Value

Index number of the joystick.


PrevHomeNext
SDL_JoystickOpenedUpSDL_JoystickNumAxes
\ No newline at end of file diff --git a/contrib/sdk/sources/SDL-1.2.2/docs/html/sdljoystickname.html b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdljoystickname.html new file mode 100644 index 000000000..a8ecbc045 --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdljoystickname.html @@ -0,0 +1,230 @@ +SDL_JoystickName
SDL Library Documentation
PrevNext

SDL_JoystickName

Name

SDL_JoystickName -- Get joystick name.

Synopsis

#include "SDL.h"

const char *SDL_JoystickName(int index);

Description

Get the implementation dependent name of joystick. The index parameter refers to the N'th joystick on the system.

Return Value

Returns a char pointer to the joystick name.

Examples

/* Print the names of all attached joysticks */
+int num_joy, i;
+num_joy=SDL_NumJoysticks();
+printf("%d joysticks found\n", num_joy);
+for(i=0;i<num_joy;i++)
+  printf("%s\n", SDL_JoystickName(i);


PrevHomeNext
SDL_NumJoysticksUpSDL_JoystickOpen
\ No newline at end of file diff --git a/contrib/sdk/sources/SDL-1.2.2/docs/html/sdljoysticknumaxes.html b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdljoysticknumaxes.html new file mode 100644 index 000000000..2caee66d1 --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdljoysticknumaxes.html @@ -0,0 +1,217 @@ +SDL_JoystickNumAxes
SDL Library Documentation
PrevNext

SDL_JoystickNumAxes

Name

SDL_JoystickNumAxes -- Get the number of joystick axes

Synopsis

#include "SDL.h"

int SDL_JoystickNumAxes(SDL_Joystick *joystick);

Description

Return the number of axes available from a previously opened SDL_Joystick.

Return Value

Number of axes.


PrevHomeNext
SDL_JoystickIndexUpSDL_JoystickNumBalls
\ No newline at end of file diff --git a/contrib/sdk/sources/SDL-1.2.2/docs/html/sdljoysticknumballs.html b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdljoysticknumballs.html new file mode 100644 index 000000000..c437ced55 --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdljoysticknumballs.html @@ -0,0 +1,217 @@ +SDL_JoystickNumBalls
SDL Library Documentation
PrevNext

SDL_JoystickNumBalls

Name

SDL_JoystickNumBalls -- Get the number of joystick trackballs

Synopsis

#include "SDL.h"

int SDL_JoystickNumBalls(SDL_Joystick *joystick);

Description

Return the number of trackballs available from a previously opened SDL_Joystick.

Return Value

Number of trackballs.


PrevHomeNext
SDL_JoystickNumAxesUpSDL_JoystickNumHats
\ No newline at end of file diff --git a/contrib/sdk/sources/SDL-1.2.2/docs/html/sdljoysticknumbuttons.html b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdljoysticknumbuttons.html new file mode 100644 index 000000000..14c8ab78c --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdljoysticknumbuttons.html @@ -0,0 +1,217 @@ +SDL_JoystickNumButtons
SDL Library Documentation
PrevNext

SDL_JoystickNumButtons

Name

SDL_JoystickNumButtons -- Get the number of joysitck buttons

Synopsis

#include "SDL.h"

int SDL_JoystickNumButtons(SDL_Joystick *joystick);

Description

Return the number of buttons available from a previously opened SDL_Joystick.

Return Value

Number of buttons.


PrevHomeNext
SDL_JoystickNumHatsUpSDL_JoystickUpdate
\ No newline at end of file diff --git a/contrib/sdk/sources/SDL-1.2.2/docs/html/sdljoysticknumhats.html b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdljoysticknumhats.html new file mode 100644 index 000000000..b1c428b28 --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdljoysticknumhats.html @@ -0,0 +1,217 @@ +SDL_JoystickNumHats
SDL Library Documentation
PrevNext

SDL_JoystickNumHats

Name

SDL_JoystickNumHats -- Get the number of joystick hats

Synopsis

#include "SDL.h"

int SDL_JoystickNumHats(SDL_Joystick *joystick);

Description

Return the number of hats available from a previously opened SDL_Joystick.

Return Value

Number of hats.


PrevHomeNext
SDL_JoystickNumBallsUpSDL_JoystickNumButtons
\ No newline at end of file diff --git a/contrib/sdk/sources/SDL-1.2.2/docs/html/sdljoystickopen.html b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdljoystickopen.html new file mode 100644 index 000000000..892852682 --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdljoystickopen.html @@ -0,0 +1,251 @@ +SDL_JoystickOpen
SDL Library Documentation
PrevNext

SDL_JoystickOpen

Name

SDL_JoystickOpen -- Opens a joystick for use.

Synopsis

#include "SDL.h"

SDL_Joystick *SDL_JoystickOpen(int index);

Description

Opens a joystick for use within SDL. The index refers to the N'th joystick in the system. A joystick must be opened before it game be used.

Return Value

Returns a SDL_Joystick structure on success. NULL on failure.

Examples

SDL_Joystick *joy;
+// Check for joystick
+if(SDL_NumJoysticks()>0){
+  // Open joystick
+  joy=SDL_JoystickOpen(0);
+  
+  if(joy)
+  {
+    printf("Opened Joystick 0\n");
+    printf("Name: %s\n", SDL_JoystickName(0));
+    printf("Number of Axes: %s\n", SDL_JoystickNumAxes(joy));
+    printf("Number of Buttons: %s\n", SDL_JoystickNumButtons(joy));
+    printf("Number of Balls: %s\n", SDL_JoystickNumBalls(joy));
+  }
+  else
+    printf("Couldn't open Joystick 0\n");
+  
+  // Close if opened
+  if(SDL_JoystickOpened(0))
+    SDL_JoystickClose(joy);
+}


PrevHomeNext
SDL_JoystickNameUpSDL_JoystickOpened
\ No newline at end of file diff --git a/contrib/sdk/sources/SDL-1.2.2/docs/html/sdljoystickopened.html b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdljoystickopened.html new file mode 100644 index 000000000..bf63be052 --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdljoystickopened.html @@ -0,0 +1,225 @@ +SDL_JoystickOpened
SDL Library Documentation
PrevNext

SDL_JoystickOpened

Name

SDL_JoystickOpened -- Determine if a joystick has been opened

Synopsis

#include "SDL.h"

int SDL_JoystickOpened(int index);

Description

Determines whether a joystick has already been opened within the application. index refers to the N'th joystick on the system.

Return Value

Returns 1 if the joystick has been opened, or 0 if it has not.


PrevHomeNext
SDL_JoystickOpenUpSDL_JoystickIndex
\ No newline at end of file diff --git a/contrib/sdk/sources/SDL-1.2.2/docs/html/sdljoystickupdate.html b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdljoystickupdate.html new file mode 100644 index 000000000..546fd6e62 --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdljoystickupdate.html @@ -0,0 +1,203 @@ +SDL_JoystickUpdate
SDL Library Documentation
PrevNext

SDL_JoystickUpdate

Name

SDL_JoystickUpdate -- Updates the state of all joysticks

Synopsis

#include "SDL.h"

void SDL_JoystickUpdate(void);

Description

Updates the state(position, buttons, etc.) of all open joysticks. If joystick events have been enabled with SDL_JoystickEventState then this is called automatically in the event loop.


PrevHomeNext
SDL_JoystickNumButtonsUpSDL_JoystickGetAxis
\ No newline at end of file diff --git a/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlkey.html b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlkey.html new file mode 100644 index 000000000..947be4ef3 --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlkey.html @@ -0,0 +1,2622 @@ +SDLKey
SDL Library Documentation
PrevNext

SDLKey

Name

SDLKey -- Keysym definitions.

Description

Table 8-1. SDL Keysym definitions

SDLKeyASCII valueCommon name
SDLK_BACKSPACE'\b'backspace
SDLK_TAB'\t'tab
SDLK_CLEAR clear
SDLK_RETURN'\r'return
SDLK_PAUSE pause
SDLK_ESCAPE'^['escape
SDLK_SPACE' 'space
SDLK_EXCLAIM'!'exclaim
SDLK_QUOTEDBL'"'quotedbl
SDLK_HASH'#'hash
SDLK_DOLLAR'$'dollar
SDLK_AMPERSAND'&'ampersand
SDLK_QUOTE'''quote
SDLK_LEFTPAREN'('left parenthesis
SDLK_RIGHTPAREN')'right parenthesis
SDLK_ASTERISK'*'asterisk
SDLK_PLUS'+'plus sign
SDLK_COMMA','comma
SDLK_MINUS'-'minus sign
SDLK_PERIOD'.'period
SDLK_SLASH'/'forward slash
SDLK_0'0'0
SDLK_1'1'1
SDLK_2'2'2
SDLK_3'3'3
SDLK_4'4'4
SDLK_5'5'5
SDLK_6'6'6
SDLK_7'7'7
SDLK_8'8'8
SDLK_9'9'9
SDLK_COLON':'colon
SDLK_SEMICOLON';'semicolon
SDLK_LESS'<'less-than sign
SDLK_EQUALS'='equals sign
SDLK_GREATER'>'greater-than sign
SDLK_QUESTION'?'question mark
SDLK_AT'@'at
SDLK_LEFTBRACKET'['left bracket
SDLK_BACKSLASH'\'backslash
SDLK_RIGHTBRACKET']'right bracket
SDLK_CARET'^'caret
SDLK_UNDERSCORE'_'underscore
SDLK_BACKQUOTE'`'grave
SDLK_a'a'a
SDLK_b'b'b
SDLK_c'c'c
SDLK_d'd'd
SDLK_e'e'e
SDLK_f'f'f
SDLK_g'g'g
SDLK_h'h'h
SDLK_i'i'i
SDLK_j'j'j
SDLK_k'k'k
SDLK_l'l'l
SDLK_m'm'm
SDLK_n'n'n
SDLK_o'o'o
SDLK_p'p'p
SDLK_q'q'q
SDLK_r'r'r
SDLK_s's's
SDLK_t't't
SDLK_u'u'u
SDLK_v'v'v
SDLK_w'w'w
SDLK_x'x'x
SDLK_y'y'y
SDLK_z'z'z
SDLK_DELETE'^?'delete
SDLK_KP0 keypad 0
SDLK_KP1 keypad 1
SDLK_KP2 keypad 2
SDLK_KP3 keypad 3
SDLK_KP4 keypad 4
SDLK_KP5 keypad 5
SDLK_KP6 keypad 6
SDLK_KP7 keypad 7
SDLK_KP8 keypad 8
SDLK_KP9 keypad 9
SDLK_KP_PERIOD'.'keypad period
SDLK_KP_DIVIDE'/'keypad divide
SDLK_KP_MULTIPLY'*'keypad multiply
SDLK_KP_MINUS'-'keypad minus
SDLK_KP_PLUS'+'keypad plus
SDLK_KP_ENTER'\r'keypad enter
SDLK_KP_EQUALS'='keypad equals
SDLK_UP up arrow
SDLK_DOWN down arrow
SDLK_RIGHT right arrow
SDLK_LEFT left arrow
SDLK_INSERT insert
SDLK_HOME home
SDLK_END end
SDLK_PAGEUP page up
SDLK_PAGEDOWN page down
SDLK_F1 F1
SDLK_F2 F2
SDLK_F3 F3
SDLK_F4 F4
SDLK_F5 F5
SDLK_F6 F6
SDLK_F7 F7
SDLK_F8 F8
SDLK_F9 F9
SDLK_F10 F10
SDLK_F11 F11
SDLK_F12 F12
SDLK_F13 F13
SDLK_F14 F14
SDLK_F15 F15
SDLK_NUMLOCK numlock
SDLK_CAPSLOCK capslock
SDLK_SCROLLOCK scrollock
SDLK_RSHIFT right shift
SDLK_LSHIFT left shift
SDLK_RCTRL right ctrl
SDLK_LCTRL left ctrl
SDLK_RALT right alt
SDLK_LALT left alt
SDLK_RMETA right meta
SDLK_LMETA left meta
SDLK_LSUPER left windows key
SDLK_RSUPER right windows key
SDLK_MODE mode shift
SDLK_HELP help
SDLK_PRINT print-screen
SDLK_SYSREQ SysRq
SDLK_BREAK break
SDLK_MENU menu
SDLK_POWER power
SDLK_EURO euro
+ +

Table 8-2. SDL modifier definitions

SDL ModifierMeaning
KMOD_NONENo modifiers applicable
KMOD_NUMNumlock is down
KMOD_CAPSCapslock is down
KMOD_LCTRLLeft Control is down
KMOD_RCTRLRight Control is down
KMOD_RSHIFTRight Shift is down
KMOD_LSHIFTLeft Shift is down
KMOD_RALTRight Alt is down
KMOD_LALTLeft Alt is down
KMOD_CTRLA Control key is down
KMOD_SHIFTA Shift key is down
KMOD_ALTAn Alt key is down


PrevHomeNext
SDL_keysymUpEvent Functions.
\ No newline at end of file diff --git a/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlkeyboardevent.html b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlkeyboardevent.html new file mode 100644 index 000000000..b84b50833 --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlkeyboardevent.html @@ -0,0 +1,367 @@ +SDL_KeyboardEvent
SDL Library Documentation
PrevNext

SDL_KeyboardEvent

Name

SDL_KeyboardEvent -- Keyboard event structure

Structure Definition

typedef struct{
+  Uint8 type;
+  Uint8 state;
+  SDL_keysym keysym;
+} SDL_KeyboardEvent;

Structure Data

typeSDL_KEYDOWN or SDL_KEYUP
stateSDL_PRESSED or SDL_RELEASED
keysymContains key press information

Description

SDL_KeyboardEvent is a member of the SDL_Event union and is used when an event of type SDL_KEYDOWN or SDL_KEYUP is reported.

The type and state actually report the same information, they just use different values to do it! A keyboard event occurs when a key is released (type=SDK_KEYUP or state=SDL_RELEASED) and when a key is pressed (type=SDL_KEYDOWN or state=SDL_PRESSED). The information on what key was pressed or released is in the keysym structure.

Note: Repeating SDL_KEYDOWN events will occur if key repeat is enabled (see SDL_EnableKeyRepeat).


PrevHomeNext
SDL_ActiveEventUpSDL_MouseMotionEvent
\ No newline at end of file diff --git a/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlkeysym.html b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlkeysym.html new file mode 100644 index 000000000..55a6a5920 --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlkeysym.html @@ -0,0 +1,347 @@ +SDL_keysym
SDL Library Documentation
PrevNext

SDL_keysym

Name

SDL_keysym -- Keysym structure

Structure Definition

typedef struct{
+  Uint8 scancode;
+  SDLKey sym;
+  SDLMod mod;
+  Uint16 unicode;
+} SDL_keysym;

Structure Data

scancodeHardware specific scancode
symSDL virtual keysym
modCurrent key modifiers
unicodeTranslated character

Description

The SDL_keysym structure is used by reporting key presses and releases since it is a part of the SDL_KeyboardEvent.

The scancode field should generally be left alone, it is the hardware dependent scancode returned by the keyboard. The sym field is extremely useful. It is the SDL-defined value of the key (see SDL Key Syms. This field is very useful when you are checking for certain key presses, like so: +

.
+.
+while(SDL_PollEvent(&event)){
+  switch(event.type){
+    case SDL_KEYDOWN:
+      if(event.key.keysym.sym==SDLK_LEFT)
+        move_left();
+      break;
+    .
+    .
+    .
+  }
+}
+.
+.
+mod stores the current state of the keyboard modifiers as explained in SDL_GetModState. The unicode is only used when UNICODE translation is enabled with SDL_EnableUNICODE. If unicode is non-zero then this a the UNICODE character corresponding to the keypress. If the high 9 bits of the character are 0, then this maps to the equivalent ASCII character: +
char ch;
+if ( (keysym.unicode & 0xFF80) == 0 ) {
+  ch = keysym.unicode & 0x7F;
+}
+else {
+  printf("An International Character.\n");
+}
+UNICODE translation does have a slight overhead so don't enable it unless its needed.

See Also

SDLKey


PrevHomeNext
SDL_QuitEventUpSDLKey
\ No newline at end of file diff --git a/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlkillthread.html b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlkillthread.html new file mode 100644 index 000000000..5e713c4eb --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlkillthread.html @@ -0,0 +1,215 @@ +SDL_KillThread
SDL Library Documentation
PrevNext

SDL_KillThread

Name

SDL_KillThread -- Gracelessly terminates the thread.

Synopsis

#include "SDL.h"
+#include "SDL_thread.h"

void SDL_KillThread(SDL_Thread *thread);

Description

SDL_KillThread gracelessly terminates the thread +associated with thread. If possible, you should +use some other form of IPC to signal the thread to quit.


PrevHomeNext
SDL_WaitThreadUpSDL_CreateMutex
\ No newline at end of file diff --git a/contrib/sdk/sources/SDL-1.2.2/docs/html/sdllistmodes.html b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdllistmodes.html new file mode 100644 index 000000000..34abac77b --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdllistmodes.html @@ -0,0 +1,302 @@ +SDL_ListModes
SDL Library Documentation
PrevNext

SDL_ListModes

Name

SDL_ListModes -- Returns a pointer to an array of available screen dimensions for +the given format and video flags

Synopsis

#include "SDL.h"

SDL_Rect **SDL_ListModes(SDL_PixelFormat *format, Uint32 flags);

Description

Return a pointer to an array of available screen dimensions for the given +format and video flags, sorted largest to smallest. Returns +NULL if there are no dimensions available for a particular +format, or -1 if any dimension is okay for +the given format.

If format is NULL, the mode list +will be for the format returned by SDL_GetVideoInfo()->vfmt. The flag parameter is an OR'd combination of surface flags. The flags are the same as those used SDL_SetVideoMode and they play a strong role in deciding what modes are valid. For instance, if you pass SDL_HWSURFACE as a flag only modes that support hardware video surfaces will be returned.

Example

SDL_Rect **modes;
+int i;
+.
+.
+.
+
+/* Get available fullscreen/hardware modes */
+modes=SDL_ListModes(NULL, SDL_FULLSCREEN|SDL_HWSURFACE);
+
+/* Check is there are any modes available */
+if(modes == (SDL_Rect **)0){
+  printf("No modes available!\n");
+  exit(-1);
+}
+
+/* Check if or resolution is restricted */
+if(modes == (SDL_Rect **)-1){
+  printf("All resolutions available.\n");
+}
+else{
+  /* Print valid modes */
+  printf("Available Modes\n");
+  for(i=0;modes[i];++i)
+    printf("  %d x %d\n", modes[i]->w, modes[i]->h);
+}
+.
+.

PrevHomeNext
SDL_VideoDriverNameUpSDL_VideoModeOK
\ No newline at end of file diff --git a/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlloadbmp.html b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlloadbmp.html new file mode 100644 index 000000000..8d85488ec --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlloadbmp.html @@ -0,0 +1,211 @@ +SDL_LoadBMP
SDL Library Documentation
PrevNext

SDL_LoadBMP

Name

SDL_LoadBMP -- Load a Windows BMP file into an SDL_Surface.

Synopsis

#include "SDL.h"

SDL_Surface *SDL_LoadBMP(const char *file);

Description

Loads a surface from a named Windows BMP file.

Return Value

Returns the new surface, or NULL +if there was an error.

See Also

SDL_SaveBMP


PrevHomeNext
SDL_UnlockSurfaceUpSDL_SaveBMP
\ No newline at end of file diff --git a/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlloadwav.html b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlloadwav.html new file mode 100644 index 000000000..4bd7a004a --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlloadwav.html @@ -0,0 +1,288 @@ +SDL_LoadWAV
SDL Library Documentation
PrevNext

SDL_LoadWAV

Name

SDL_LoadWAV -- Load a WAVE file

Synopsis

#include "SDL.h"

SDL_AudioSpec *SDL_LoadWAV(const char *file, SDL_AudioSpec *spec, Uint8 **audio_buf, Uint32 *audio_len);

Description

SDL_LoadWAV +This function loads a WAVE file into memory.

If this function succeeds, it returns the given +SDL_AudioSpec, +filled with the audio data format of the wave data, and sets +audio_buf to a malloc'd +buffer containing the audio data, and sets audio_len +to the length of that audio buffer, in bytes. You need to free the audio +buffer with SDL_FreeWAV when you are +done with it.

This function returns NULL and sets the SDL +error message if the wave file cannot be opened, uses an unknown data format, +or is corrupt. Currently raw, MS-ADPCM and IMA-ADPCM WAVE files are supported.

Example

SDL_AudioSpec wav_spec;
+Uint32 wav_length;
+Uint8 *wav_buffer;
+
+/* Load the WAV */
+if( SDL_LoadWAV("test.wav", &wav_spec, &wav_buffer, &wav_length) == NULL ){
+  fprintf(stderr, "Could not open test.wav: %s\n", SDL_GetError());
+  exit(-1);
+}
+.
+.
+.
+/* Do stuff with the WAV */
+.
+.
+/* Free It */
+SDL_FreeWAV(wav_buffer);

PrevHomeNext
SDL_GetAudioStatusUpSDL_FreeWAV
\ No newline at end of file diff --git a/contrib/sdk/sources/SDL-1.2.2/docs/html/sdllockaudio.html b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdllockaudio.html new file mode 100644 index 000000000..8d85bf877 --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdllockaudio.html @@ -0,0 +1,200 @@ +SDL_LockAudio
SDL Library Documentation
PrevNext

SDL_LockAudio

Name

SDL_LockAudio -- Lock out the callback function

Synopsis

#include "SDL.h"

void SDL_LockAudio(void);

Description

The lock manipulated by these functions protects the callback function. +During a LockAudio period, you can be guaranteed that the +callback function is not running. Do not call these from the callback +function or you will cause deadlock.


PrevHomeNext
SDL_MixAudioUpSDL_UnlockAudio
\ No newline at end of file diff --git a/contrib/sdk/sources/SDL-1.2.2/docs/html/sdllocksurface.html b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdllocksurface.html new file mode 100644 index 000000000..88e40b6f5 --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdllocksurface.html @@ -0,0 +1,299 @@ +SDL_LockSurface
SDL Library Documentation
PrevNext

SDL_LockSurface

Name

SDL_LockSurface -- Lock a surface for directly access.

Synopsis

#include "SDL.h"

int SDL_LockSurface(SDL_Surface *surface);

Description

SDL_LockSurface sets up a surface for directly +accessing the pixels. Between calls to SDL_LockSurface +and SDL_UnlockSurface, you can write to and read from +surface->pixels, using the pixel format stored in +surface->format. Once you are done accessing the +surface, you should use SDL_UnlockSurface to release it.

Not all surfaces require locking. +If SDL_MUSTLOCK(surface) +evaluates to 0, then you can read and write to the +surface at any time, and the pixel format of the surface will not change.

No operating system or library calls should be made between lock/unlock +pairs, as critical system locks may be held during this time.

It should be noted, that since SDL 1.1.8 surface locks are recursive. This means that you can lock a surface multiple times, but each lock must have a match unlock. +

    .
+    .
+    SDL_LockSurface( surface );
+    .
+    /* Surface is locked */
+    /* Direct pixel access on surface here */
+    .
+    SDL_LockSurface( surface );
+    .
+    /* More direct pixel access on surface */
+    .
+    SDL_UnlockSurface( surface );
+    /* Surface is still locked */
+    /* Note: Is versions < 1.1.8, the surface would have been */
+    /* no longer locked at this stage                         */
+    .
+    SDL_UnlockSurface( surface );
+    /* Surface is now unlocked */
+    .
+    .
+

Return Value

SDL_LockSurface returns 0, +or -1 if the surface couldn't be locked.


PrevHomeNext
SDL_FreeSurfaceUpSDL_UnlockSurface
\ No newline at end of file diff --git a/contrib/sdk/sources/SDL-1.2.2/docs/html/sdllockyuvoverlay.html b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdllockyuvoverlay.html new file mode 100644 index 000000000..56d3bab3b --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdllockyuvoverlay.html @@ -0,0 +1,244 @@ +SDL_LockYUVOverlay
SDL Library Documentation
PrevNext

SDL_LockYUVOverlay

Name

SDL_LockYUVOverlay -- Lock an overlay

Synopsis

#include "SDL.h"

int SDL_LockYUVOverlay(SDL_Overlay *overlay);

Description

Much the same as SDL_LockSurface, SDL_LockYUVOverlay locks the overlay for direct access to pixel data.

Return Value

Returns 0 on success, or -1 on an error.


PrevHomeNext
SDL_CreateYUVOverlayUpSDL_UnlockYUVOverlay
\ No newline at end of file diff --git a/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlmaprgb.html b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlmaprgb.html new file mode 100644 index 000000000..e214ee0b4 --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlmaprgb.html @@ -0,0 +1,246 @@ +SDL_MapRGB
SDL Library Documentation
PrevNext

SDL_MapRGB

Name

SDL_MapRGB -- Map a RGB color value to a pixel format.

Synopsis

#include "SDL.h"

Uint32 SDL_MapRGB(SDL_PixelFormat *fmt, Uint8 r, Uint8 g, Uint8 b);

Description

Maps the RGB color value to the specified pixel format and returns the +pixel value as a 32-bit int.

If the format has a palette (8-bit) the index of the closest matching +color in the palette will be returned.

If the specified pixel format has an alpha component it will be returned +as all 1 bits (fully opaque).

Return Value

A pixel value best approximating the given RGB color value for a given +pixel format. If the pixel format bpp (color depth) is less than 32-bpp +then the unused upper bits of the return value can safely be ignored +(e.g., with a 16-bpp format the return value can be assigned to a +Uint16, and similarly a Uint8 for an 8-bpp +format).


PrevHomeNext
SDL_SetGammaRampUpSDL_MapRGBA
\ No newline at end of file diff --git a/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlmaprgba.html b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlmaprgba.html new file mode 100644 index 000000000..ff7e01d8f --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlmaprgba.html @@ -0,0 +1,234 @@ +SDL_MapRGBA
SDL Library Documentation
PrevNext

SDL_MapRGBA

Name

SDL_MapRGBA -- Map a RGBA color value to a pixel format.

Synopsis

#include "SDL.h"

Uint32 SDL_MapRGBA(SDL_PixelFormat *fmt, Uint8 r, Uint8 g, Uint8 b, Uint8 a);

Description

Maps the RGBA color value to the specified pixel format and returns the +pixel value as a 32-bit int.

If the format has a palette (8-bit) the index of the closest matching +color in the palette will be returned.

If the specified pixel format has no alpha component the alpha value +will be ignored (as it will be in formats with a palette).

Return Value

A pixel value best approximating the given RGBA color value for a given +pixel format. If the pixel format bpp (color depth) is less than 32-bpp +then the unused upper bits of the return value can safely be ignored +(e.g., with a 16-bpp format the return value can be assigned to a +Uint16, and similarly a Uint8 for an 8-bpp +format).


PrevHomeNext
SDL_MapRGBUpSDL_GetRGB
\ No newline at end of file diff --git a/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlmixaudio.html b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlmixaudio.html new file mode 100644 index 000000000..c1112039d --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlmixaudio.html @@ -0,0 +1,215 @@ +SDL_MixAudio
SDL Library Documentation
PrevNext

SDL_MixAudio

Name

SDL_MixAudio -- Mix audio data

Synopsis

#include "SDL.h"

void SDL_MixAudio(Uint8 *dst, Uint8 *src, Uint32 len, int volume);

Description

This function takes two audio buffers of len bytes each +of the playing audio format and mixes them, performing addition, volume +adjustment, and overflow clipping. The volume ranges +from 0 to SDL_MIX_MAXVOLUME and should be set to the maximum +value for full audio volume. Note this does not change hardware volume. This is +provided for convenience -- you can mix your own audio data.


PrevHomeNext
SDL_ConvertAudioUpSDL_LockAudio
\ No newline at end of file diff --git a/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlmousebuttonevent.html b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlmousebuttonevent.html new file mode 100644 index 000000000..336a6d4a1 --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlmousebuttonevent.html @@ -0,0 +1,338 @@ +SDL_MouseButtonEvent
SDL Library Documentation
PrevNext

SDL_MouseButtonEvent

Name

SDL_MouseButtonEvent -- Mouse button event structure

Structure Definition

typedef struct{
+  Uint8 type;
+  Uint8 button;
+  Uint8 state;
+  Uint16 x, y;
+} SDL_MouseButtonEvent;

Structure Data

typeSDL_MOUSEBUTTONDOWN or SDL_MOUSEBUTTONUP
buttonThe mouse button index (SDL_BUTTON_LEFT, SDL_BUTTON_MIDDLE, SDL_BUTTON_RIGHT)
stateSDL_PRESSED or SDL_RELEASED
x, yThe X/Y coordinates of the mouse at press/release time

Description

SDL_MouseButtonEvent is a member of the SDL_Event union and is used when an event of type SDL_MOUSEBUTTONDOWN or SDL_MOUSEBUTTONUP is reported.

When a mouse button press or release is detected then number of the button pressed (from 1 to 255, with 1 usually being the left button and 2 the right) is placed into button, the position of the mouse when this event occured is stored in the x and the y fields. Like SDL_KeyboardEvent, information on whether the event was a press or a release event is stored in both the type and state fields, but this should be obvious.


PrevHomeNext
SDL_MouseMotionEventUpSDL_JoyAxisEvent
\ No newline at end of file diff --git a/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlmousemotionevent.html b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlmousemotionevent.html new file mode 100644 index 000000000..1854d8486 --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlmousemotionevent.html @@ -0,0 +1,357 @@ +SDL_MouseMotionEvent
SDL Library Documentation
PrevNext

SDL_MouseMotionEvent

Name

SDL_MouseMotionEvent -- Mouse motion event structure

Structure Definition

typedef struct{
+  Uint8 type;
+  Uint8 state;
+  Uint16 x, y;
+  Sint16 xrel, yrel;
+} SDL_MouseMotionEvent;

Structure Data

typeSDL_MOUSEMOTION
stateThe current button state
x, yThe X/Y coordinates of the mouse
xrel, yrelRelative motion in the X/Y direction

Description

SDL_MouseMotionEvent is a member of the SDL_Event union and is used when an event of type SDL_MOUSEMOTION is reported.

Simply put, a SDL_MOUSEMOTION type event occurs when a user moves the mouse within the application window or when SDL_WarpMouse is called. Both the absolute (x and y) and relative (xrel and yrel) coordinates are reported along with the current button states (state). The button state can be interpreted using the SDL_BUTTON macro (see SDL_GetMouseState).

If the cursor is hidden (SDL_ShowCursor(0)) and the input is grabbed (SDL_WM_GrabInput(SDL_GRAB_ON)), then the mouse will give relative motion events even when the cursor reaches the edge fo the screen. This is currently only implemented on Windows and Linux/Unix-a-likes.


PrevHomeNext
SDL_KeyboardEventUpSDL_MouseButtonEvent
\ No newline at end of file diff --git a/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlmutexp.html b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlmutexp.html new file mode 100644 index 000000000..055f1b99e --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlmutexp.html @@ -0,0 +1,233 @@ +SDL_mutexP
SDL Library Documentation
PrevNext

SDL_mutexP

Name

SDL_mutexP -- Lock a mutex

Synopsis

#include "SDL.h"
+#include "SDL_thread.h"

int SDL_mutexP(SDL_mutex *mutex);

Description

Locks the mutex, which was previously created with SDL_CreateMutex. If the mutex is already locked then SDL_mutexP will not return until it is unlocked. Returns 0 on success, or -1 on an error.

SDL also defines a macro #define SDL_LockMutex(m) SDL_mutexP(m).


PrevHomeNext
SDL_DestroyMutexUpSDL_mutexV
\ No newline at end of file diff --git a/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlmutexv.html b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlmutexv.html new file mode 100644 index 000000000..076ac2fd5 --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlmutexv.html @@ -0,0 +1,227 @@ +SDL_mutexV
SDL Library Documentation
PrevNext

SDL_mutexV

Name

SDL_mutexV -- Unlock a mutex

Synopsis

#include "SDL.h"
+#include "SDL_thread.h"

int SDL_mutexV(SDL_mutex *mutex);

Description

Unlocks the mutex, which was previously created with SDL_CreateMutex. Returns 0 on success, or -1 on an error.

SDL also defines a macro #define SDL_UnlockMutex(m) SDL_mutexV(m).


PrevHomeNext
SDL_mutexPUpSDL_CreateSemaphore
\ No newline at end of file diff --git a/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlnumjoysticks.html b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlnumjoysticks.html new file mode 100644 index 000000000..7c7e7a4ba --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlnumjoysticks.html @@ -0,0 +1,214 @@ +SDL_NumJoysticks
SDL Library Documentation
PrevNext

SDL_NumJoysticks

Name

SDL_NumJoysticks -- Count available joysticks.

Synopsis

#include "SDL.h"

int SDL_NumJoysticks(void);

Description

Counts the number of joysticks attached to the system.

Return Value

Returns the number of attached joysticks


PrevHomeNext
JoystickUpSDL_JoystickName
\ No newline at end of file diff --git a/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlopenaudio.html b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlopenaudio.html new file mode 100644 index 000000000..d9183bdbb --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlopenaudio.html @@ -0,0 +1,567 @@ +SDL_OpenAudio
SDL Library Documentation
PrevNext

SDL_OpenAudio

Name

SDL_OpenAudio -- Opens the audio device with the desired parameters.

Synopsis

#include "SDL.h"

int SDL_OpenAudio(SDL_AudioSpec *desired, SDL_AudioSpec *obtained);

Description

This function opens the audio device with the desired parameters, and +returns 0 if successful, placing the actual hardware parameters in the +structure pointed to by obtained. If obtained is NULL, the audio +data passed to the callback function will be guaranteed to be in the +requested format, and will be automatically converted to the hardware +audio format if necessary. This function returns -1 if it failed +to open the audio device, or couldn't set up the audio thread.

To open the audio device a desired SDL_AudioSpec must be created. +

SDL_AudioSpec *desired;
+.
+.
+desired=(SDL_AudioSpec *)malloc(sizeof(SDL_AudioSpec));
+You must then fill this structure with your desired audio specifications.

desired->freq

The desired audio frequency in samples-per-second.

desired->format

The desired audio format (see SDL_AudioSpec)

desired->samples

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 8192 inclusive, depending on the application and CPU speed. Smaller values yield faster response time, but can lead to underflow if the application is doing heavy processing and cannot fill the audio buffer in time. A stereo sample consists of both right and left channels in LR ordering. Note that the number of samples is directly related to time by the following formula: ms = (samples*1000)/freq

desired->callback

This 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. The callback prototype is: +

void callback(void *userdata, Uint8 *stream, int len);
+userdata is the pointer stored in userdata field of the SDL_AudioSpec. stream is a pointer to the audio buffer you want to fill with information and len is the length of the audio buffer in bytes.

desired->userdata

This pointer is passed as the first parameter to the callback function.

SDL_OpenAudio reads these fields from the desired SDL_AudioSpec structure pass to the function and attempts to find an audio configuration matching your desired. As mentioned above, if the obtained parameter is NULL then SDL with convert from your desired audio settings to the hardware settings as it plays.

If obtained is NULL then the desired SDL_AudioSpec is your working specification, otherwise the obtained SDL_AudioSpec becomes the working specification and the desirec specification can be deleted. The data in the working specification is used when building SDL_AudioCVT's for converting loaded data to the hardware format.

SDL_OpenAudio calculates the size and silence fields for both the desired and obtained specifications. The size field stores the total size of the audio buffer in bytes, while the silence stores the value used to represent silence in the audio buffer

The audio device starts out playing silence when it's opened, and should be enabled for playing by calling SDL_PauseAudio(0) when you are ready for your audio callback function to be called. Since the audio driver may modify the requested size of the audio buffer, you should allocate any local mixing buffers after you open the audio device.

Examples

/* Prototype of our callback function */
+void my_audio_callback(void *userdata, Uint8 *stream, int len);
+
+/* Open the audio device */
+SDL_AudioSpec *desired, *obtained;
+SDL_AudioSpec *hardware_spec;
+
+/* Allocate a desired SDL_AudioSpec */
+desired=(SDL_AudioSpec *)malloc(sizeof(SDL_AudioSpec));
+
+/* Allocate space for the obtained SDL_AudioSpec */
+obtained=(SDL_AudioSpec *)malloc(sizeof(SDL_AudioSpec));
+
+/* 22050Hz - FM Radio quality */
+desired->freq=22050;
+
+/* 16-bit signed audio */
+desired->format=AUDIO_S16LSB;
+
+/* Large audio buffer reduces risk of dropouts but increases response time */
+desired->samples=8192;
+
+/* Our callback function */
+desired->callback=my_audio_callback;
+
+desired->userdata=NULL;
+
+/* Open the audio device */
+if ( SDL_OpenAudio(desired, obtained) < 0 ){
+  fprintf(stderr, "Couldn't open audio: %s\n", SDL_GetError());
+  exit(-1);
+}
+/* desired spec is no longer needed */
+free(desired);
+hardware_spec=obtained;
+.
+.
+/* Prepare callback for playing */
+.
+.
+.
+/* Start playing */
+SDL_PauseAudio(0);

PrevHomeNext
SDL_AudioSpecUpSDL_PauseAudio
\ No newline at end of file diff --git a/contrib/sdk/sources/SDL-1.2.2/docs/html/sdloverlay.html b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdloverlay.html new file mode 100644 index 000000000..01107ec2f --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdloverlay.html @@ -0,0 +1,354 @@ +SDL_Overlay
SDL Library Documentation
PrevNext

SDL_Overlay

Name

SDL_Overlay -- YUV video overlay

Structure Definition

typedef struct{
+  Uint32 format;
+  int w, h;
+  int planes;
+  Uint16 *pitches;
+  Uint8 **pixels;
+  Uint32 hw_overlay:1;
+} SDL_Overlay;

Structure Data

formatOverlay format (see below)
w, hWidth and height of overlay
planesNumber of planes in the overlay. Usually either 1 or 3
pitchesAn array of pitches, one for each plane. Pitch is the length of a row in bytes.
pixelsAn array of pointers to teh data of each plane. The overlay should be locked before these pointers are used.
hw_overlayThis will be set to 1 if the overlay is hardware accelerated.

Description

A SDL_Overlay is similar to a SDL_Surface except it stores a YUV overlay. All the fields are read only, except for pixels which should be locked before use. The format field stores the format of the overlay which is one of the following: +

#define SDL_YV12_OVERLAY  0x32315659  /* Planar mode: Y + V + U */
+#define SDL_IYUV_OVERLAY  0x56555949  /* Planar mode: Y + U + V */
+#define SDL_YUY2_OVERLAY  0x32595559  /* Packed mode: Y0+U0+Y1+V0 */
+#define SDL_UYVY_OVERLAY  0x59565955  /* Packed mode: U0+Y0+V0+Y1 */
+#define SDL_YVYU_OVERLAY  0x55595659  /* Packed mode: Y0+V0+Y1+U0 */
+More information on YUV formats can be found at http://www.webartz.com/fourcc/indexyuv.htm.


PrevHomeNext
SDL_VideoInfoUpWindow Management
\ No newline at end of file diff --git a/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlpalette.html b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlpalette.html new file mode 100644 index 000000000..94ba5f20d --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlpalette.html @@ -0,0 +1,293 @@ +SDL_Palette
SDL Library Documentation
PrevNext

SDL_Palette

Name

SDL_Palette -- Color palette for 8-bit pixel formats

Structure Definition

typedef struct{
+  int ncolors;
+  SDL_Color *colors;
+} SDL_Palette;

Structure Data

ncolorsNumber of colors used in this palette
colorsPointer to SDL_Color structures that make up the palette.

Description

Each pixel in an 8-bit surface is an index into the colors field of the SDL_Palette structure store in SDL_PixelFormat. A SDL_Palette should never need to be created manually. It is automatically created when SDL allocates a SDL_PixelFormat for a surface. The colors values of a SDL_Surfaces palette can be set with the SDL_SetColors.


PrevHomeNext
SDL_ColorUpSDL_PixelFormat
\ No newline at end of file diff --git a/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlpauseaudio.html b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlpauseaudio.html new file mode 100644 index 000000000..837482058 --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlpauseaudio.html @@ -0,0 +1,213 @@ +SDL_PauseAudio
SDL Library Documentation
PrevNext

SDL_PauseAudio

Name

SDL_PauseAudio -- Pauses and unpauses the audio callback processing

Synopsis

#include "SDL.h"

void SDL_PauseAudio(int pause_on);

Description

This function pauses and unpauses the audio callback processing. +It should be called with pause_on=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.


PrevHomeNext
SDL_OpenAudioUpSDL_GetAudioStatus
\ No newline at end of file diff --git a/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlpeepevents.html b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlpeepevents.html new file mode 100644 index 000000000..780760b3d --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlpeepevents.html @@ -0,0 +1,296 @@ +SDL_PeepEvents
SDL Library Documentation
PrevNext

SDL_PeepEvents

Name

SDL_PeepEvents -- Checks the event queue for messages and optionally returns them.

Synopsis

#include "SDL.h"

int SDL_PeepEvents(SDL_Event *events, int numevents, SDL_eventaction action, Uint32 mask);

Description

Checks the event queue for messages and optionally returns them.

If action is SDL_ADDEVENT, up to +numevents events will be added to the back of the event + queue.

If action is SDL_PEEKEVENT, up to +numevents events at the front of the event queue, +matching mask, +will be returned and will not be removed from the queue.

If action is SDL_GETEVENT, up to +numevents events at the front of the event queue, +matching mask, +will be returned and will be removed from the queue.

This function is thread-safe.

Return Value

This function returns the number of events actually stored, or +-1 if there was an error.


PrevHomeNext
SDL_PumpEventsUpSDL_PollEvent
\ No newline at end of file diff --git a/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlpixelformat.html b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlpixelformat.html new file mode 100644 index 000000000..7fb829a67 --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlpixelformat.html @@ -0,0 +1,520 @@ +SDL_PixelFormat
SDL Library Documentation
PrevNext

SDL_PixelFormat

Name

SDL_PixelFormat -- Stores surface format information

Structure Definition

typedef struct{
+  SDL_Palette *palette;
+  Uint8  BitsPerPixel;
+  Uint8  BytesPerPixel;
+  Uint32 Rmask, Gmask, Bmask, Amask;
+  Uint8  Rshift, Gshift, Bshift, Ashift;
+  Uint8  Rloss, Gloss, Bloss, Aloss;
+  Uint32 colorkey;
+  Uint8  alpha;
+} SDL_PixelFormat;

Structure Data

palettePointer to the palette, or NULL if the BitsPerPixel>8
BitsPerPixelThe number of bits used to represent each pixel in a surface. Usually 8, 16, 24 or 32.
BytesPerPixelThe number of bytes used to represent each pixel in a surface. Usually one to four.
[RGBA]maskBinary mask used to retrieve individual color values
[RGBA]lossPrecision loss of each color component (2[RGBA]loss)
[RGBA]shiftBinary left shift of each color component in the pixel value
colorkeyPixel value of transparent pixels
alphaOverall surface alpha value

Description

A SDL_PixelFormat describes the format of the pixel data stored at the pixels field of a SDL_Surface. Every surface stores a SDL_PixelFormat in the format field.

If you wish to do pixel level modifications on a surface, then understanding how SDL stores its color information is essential.

8-bit pixel formats are the easiest to understand. Since its an 8-bit format, we have 8 BitsPerPixel and 1 BytesPerPixel. Since BytesPerPixel is 1, all pixels are represented by a Uint8 which contains an index into palette->colors. So, to determine the color of a pixel in a 8-bit surface: we read the color index from surface->pixels and we use that index to read the SDL_Color structure from surface->format->palette->colors. Like so: +

SDL_Surface *surface;
+SDL_PixelFormat *fmt;
+SDL_Color *color;
+Uint8 index;
+
+.
+.
+
+/* Create surface */
+.
+.
+fmt=surface->format;
+
+/* Check the bitdepth of the surface */
+if(fmt->BitsPerPixel!=8){
+  fprintf(stderr, "Not an 8-bit surface.\n");
+  return(-1);
+}
+
+/* Lock the surface */
+SDL_LockSurface(surface);
+
+/* Get the topleft pixel */
+index=*(Uint8 *)surface->pixels;
+color=fmt->palette->colors[index];
+
+/* Unlock the surface */
+SDL_UnlockSurface(surface);
+printf("Pixel Color-> Red: %d, Green: %d, Blue: %d. Index: %d\n",
+          color->r, color->g, color->b, index);
+.
+.

Pixel formats above 8-bit are an entirely different experience. They are +considered to be "TrueColor" formats and the color information is stored in the +pixels themselves, not in a palette. The mask, shift and loss fields tell us +how the color information is encoded. The mask fields allow us to isolate each +color component, the shift fields tell us the number of bits to the right of +each component in the pixel value and the loss fields tell us the number of +bits lost from each component when packing 8-bit color component in a pixel. +

/* Extracting color components from a 32-bit color value */
+SDL_PixelFormat *fmt;
+SDL_Surface *surface;
+Uint32 temp, pixel;
+Uint8 red, green, blue, alpha;
+.
+.
+.
+fmt=surface->format;
+SDL_LockSurface(surface);
+pixel=*((Uint32*)surface->pixels);
+SDL_UnlockSurface(surface);
+
+/* Get Red component */
+temp=pixel&fmt->Rmask; /* Isolate red component */
+temp=temp>>fmt->Rshift;/* Shift it down to 8-bit */
+temp=temp<<fmt->Rloss; /* Expand to a full 8-bit number */
+red=(Uint8)temp;
+
+/* Get Green component */
+temp=pixel&fmt->Gmask; /* Isolate green component */
+temp=temp>>fmt->Gshift;/* Shift it down to 8-bit */
+temp=temp<<fmt->Gloss; /* Expand to a full 8-bit number */
+green=(Uint8)temp;
+
+/* Get Blue component */
+temp=pixel&fmt->Bmask; /* Isolate blue component */
+temp=temp>>fmt->Bshift;/* Shift it down to 8-bit */
+temp=temp<<fmt->Bloss; /* Expand to a full 8-bit number */
+blue=(Uint8)temp;
+
+/* Get Alpha component */
+temp=pixel&fmt->Amask; /* Isolate alpha component */
+temp=temp>>fmt->Ashift;/* Shift it down to 8-bit */
+temp=temp<<fmt->Aloss; /* Expand to a full 8-bit number */
+alpha=(Uint8)temp;
+
+printf("Pixel Color -> R: %d,  G: %d,  B: %d,  A: %d\n", red, green, blue, alpha);
+.
+.
+.


PrevHomeNext
SDL_PaletteUpSDL_Surface
\ No newline at end of file diff --git a/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlpollevent.html b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlpollevent.html new file mode 100644 index 000000000..528b98324 --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlpollevent.html @@ -0,0 +1,261 @@ +SDL_PollEvent
SDL Library Documentation
PrevNext

SDL_PollEvent

Name

SDL_PollEvent -- Polls for currently pending events.

Synopsis

#include "SDL.h"

int SDL_PollEvent(SDL_Event *event);

Description

Polls for currently pending events, and returns 1 +if there are any pending events, or 0 if there +are none available.

If event is not NULL, the next +event is removed from the queue and stored in that area.

Examples

SDL_Event event; /* Event structure */
+
+.
+.
+.
+/* Check for events */
+while(SDL_PollEvent(&event)){  /* Loop until there are no events left on the queue */
+  switch(event.type){  /* Process the appropiate event type */
+    case SDL_KEYDOWN:  /* Handle a KEYDOWN event */         
+      printf("Oh! Key press\n");
+      break;
+    case SDL_MOUSEMOTION:
+      .
+      .
+      .
+    default: /* Report an unhandled event */
+      printf("I don't know what this event is!\n");
+  }
+}


PrevHomeNext
SDL_PeepEventsUpSDL_WaitEvent
\ No newline at end of file diff --git a/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlpumpevents.html b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlpumpevents.html new file mode 100644 index 000000000..9a6fb9187 --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlpumpevents.html @@ -0,0 +1,236 @@ +SDL_PumpEvents
SDL Library Documentation
PrevNext

SDL_PumpEvents

Name

SDL_PumpEvents -- Pumps the event loop, gathering events from the input devices.

Synopsis

#include "SDL.h"

void SDL_PumpEvents(void);

Description

Pumps the event loop, gathering events from the input devices.

SDL_PumpEvents gathers all the pending input information from devices and places it on the event queue. Without calls to SDL_PumpEvents no events would ever be placed on the queue. Often calls the need for SDL_PumpEvents is hidden from the user since SDL_PollEvent and SDL_WaitEvent implicitly call SDL_PumpEvents. However, if you are not polling or waiting for events (e.g. your filtering them), then you must call SDL_PumpEvents to force an event queue update.

Note: You can only call this function in the thread that set the video mode.


PrevHomeNext
Event Functions.UpSDL_PeepEvents
\ No newline at end of file diff --git a/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlpushevent.html b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlpushevent.html new file mode 100644 index 000000000..4a1a14c67 --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlpushevent.html @@ -0,0 +1,258 @@ +SDL_PushEvent
SDL Library Documentation
PrevNext

SDL_PushEvent

Name

SDL_PushEvent -- Pushes an event onto the event queue

Synopsis

#include "SDL.h"

int SDL_PushEvent(SDL_Event *event);

Description

The event queue can actually be used as a two way communication channel. Not only can events be read from the queue, but the user can also push their own events onto it. event is a pointer to the event structure you wish to push onto the queue.

Note: Pushing device input events onto the queue doesn't modify the state of the device within SDL.

Return Value

Returns 0 on success or -1 if the event couldn't be pushed.

Examples

See SDL_Event.


PrevHomeNext
SDL_WaitEventUpSDL_SetEventFilter
\ No newline at end of file diff --git a/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlquit.html b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlquit.html new file mode 100644 index 000000000..76b2577c1 --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlquit.html @@ -0,0 +1,236 @@ +SDL_Quit
SDL Library Documentation
PrevNext

SDL_Quit

Name

SDL_Quit -- Shut down SDL

Synopsis

#include "SDL.h"

void SDL_Quit(void);

Description

SDL_Quit shuts down all SDL subsystems and frees the resources allocated to them. This should always be called before you exit. For the sake of simplicity you can set SDL_Quit as your atexit call, like: +

SDL_Init(SDL_INIT_VIDEO|SDL_INIT_AUDIO);
+atexit(SDL_Quit);
+.
+.

Note: While using atexit maybe be fine for small programs, more advanced users should shut down SDL in their own cleanup code. Plus, using atexit in a library is a sure way to crash dynamically loaded code


PrevHomeNext
SDL_QuitSubSystemUpSDL_WasInit
\ No newline at end of file diff --git a/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlquitevent.html b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlquitevent.html new file mode 100644 index 000000000..a1703cd32 --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlquitevent.html @@ -0,0 +1,255 @@ +SDL_QuitEvent
SDL Library Documentation
PrevNext

SDL_QuitEvent

Name

SDL_QuitEvent -- Quit requested event

Structure Definition

typedef struct{
+  Uint8 type
+} SDL_QuitEvent;

Structure Data

typeSDL_QUIT

Description

SDL_QuitEvent is a member of the SDL_Event union and is used whan an event of type SDL_QUIT is reported.

As can be seen, the SDL_QuitEvent structure serves no useful purpose. The event itself, on the other hand, is very important. If you filter out or ignore a quit event then it is impossible for the user to close the window. On the other hand, if you do accept a quit event then the application window will be closed, and screen updates will still report success event though the application will no longer be visible.

Note: The macro SDL_QuitRequested will return non-zero if a quit event is pending


PrevHomeNext
SDL_UserEventUpSDL_keysym
\ No newline at end of file diff --git a/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlquitsubsystem.html b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlquitsubsystem.html new file mode 100644 index 000000000..0122e4b29 --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlquitsubsystem.html @@ -0,0 +1,240 @@ +SDL_QuitSubSystem
SDL Library Documentation
PrevNext

SDL_QuitSubSystem

Name

SDL_QuitSubSystem -- Shut down a subsystem

Synopsis

#include "SDL.h"

void SDL_QuitSubSystem(Uint32 flags);

Description

SDL_QuitSubSystem allows you to shut down a subsystem that has been previously initialized by SDL_Init or SDL_InitSubSystem. The flags tells SDL_QuitSubSystem which subsystems to shut down, it uses the same values that are passed to SDL_Init.


PrevHomeNext
SDL_InitSubSystemUpSDL_Quit
\ No newline at end of file diff --git a/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlrect.html b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlrect.html new file mode 100644 index 000000000..7f636ac43 --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlrect.html @@ -0,0 +1,250 @@ +SDL_Rect
SDL Library Documentation
PrevNext

SDL_Rect

Name

SDL_Rect -- Defines a rectangular area

Structure Definition

typedef struct{
+  Sint16 x, y;
+  Uint16 w, h;
+} SDL_Rect;

Structure Data

x, yPosition of the upper-left corner of the rectangle
w, hThe width and height of the rectangle

Description

A SDL_Rect defines a rectangular area of pixels. It is used by SDL_BlitSurface to define blitting regions and by several other video functions.


PrevHomeNext
SDL_GLattrUpSDL_Color
\ No newline at end of file diff --git a/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlremovetimer.html b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlremovetimer.html new file mode 100644 index 000000000..e9fcbd25c --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlremovetimer.html @@ -0,0 +1,228 @@ +SDL_RemoveTimer
SDL Library Documentation
PrevNext

SDL_RemoveTimer

Name

SDL_RemoveTimer -- Remove a timer which was added with +SDL_AddTimer.

Synopsis

#include "SDL.h"

SDL_bool SDL_RemoveTimer(SDL_TimerID id);

Description

Removes a timer callback previously added with +SDL_AddTimer.

Return Value

Returns a boolean value indicating success.

Examples

SDL_RemoveTimer(my_timer_id);

See Also

SDL_AddTimer


PrevHomeNext
SDL_AddTimerUpSDL_SetTimer
\ No newline at end of file diff --git a/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlresizeevent.html b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlresizeevent.html new file mode 100644 index 000000000..c83947caa --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlresizeevent.html @@ -0,0 +1,299 @@ +SDL_ResizeEvent
SDL Library Documentation
PrevNext

SDL_ResizeEvent

Name

SDL_ResizeEvent -- Window resize event structure

Structure Definition

typedef struct{
+  Uint8 type;
+  int w, h;
+} SDL_ResizeEvent;

Structure Data

typeSDL_VIDEORESIZE
w, hNew width and height of the window

Description

SDL_ResizeEvent is a member of the SDL_Event union and is used when an event of type SDL_VIDEORESIZE is reported.

When SDL_RESIZABLE is passed as a flag to SDL_SetVideoMode the user is allowed to resize the applications window. When the window is resized an SDL_VIDEORESIZE is report, with the new window width and height values stored in w and h, respectively. When an SDL_VIDEORESIZE is recieved the window should be resized to the new dimensions using SDL_SetVideoMode.


PrevHomeNext
SDL_JoyBallEventUpSDL_SysWMEvent
\ No newline at end of file diff --git a/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlsavebmp.html b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlsavebmp.html new file mode 100644 index 000000000..ec4173c92 --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlsavebmp.html @@ -0,0 +1,228 @@ +SDL_SaveBMP
SDL Library Documentation
PrevNext

SDL_SaveBMP

Name

SDL_SaveBMP -- Save an SDL_Surface as a Windows BMP file.

Synopsis

#include "SDL.h"

int SDL_SaveBMP(SDL_Surface *surface, const char *file);

Description

Saves the SDL_Surface surface as a Windows BMP file named file.

Return Value

Returns 0 if successful or +-1 +if there was an error.

See Also

SDL_LoadBMP


PrevHomeNext
SDL_LoadBMPUpSDL_SetColorKey
\ No newline at end of file diff --git a/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlsempost.html b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlsempost.html new file mode 100644 index 000000000..c2dbf3117 --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlsempost.html @@ -0,0 +1,291 @@ +SDL_SemPost
SDL Library Documentation
PrevNext

SDL_SemPost

Name

SDL_SemPost -- Unlock a semaphore.

Synopsis

#include "SDL.h"
+#include "SDL_thread.h"

int SDL_SemPost(SDL_sem *sem);

Description

SDL_SemPost unlocks the semaphore pointed to by +sem and atomically increments the semaphores value. +Threads that were blocking on the semaphore may be scheduled after this call +succeeds.

SDL_SemPost should be called after a semaphore is locked by a successful call to +SDL_SemWait, +SDL_SemTryWait or +SDL_SemWaitTimeout.

Return Value

Returns 0 if successful or +-1 if there was an error (leaving the semaphore unchanged).

Examples

SDL_SemPost(my_sem);


PrevHomeNext
SDL_SemWaitTimeoutUpSDL_SemValue
\ No newline at end of file diff --git a/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlsemtrywait.html b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlsemtrywait.html new file mode 100644 index 000000000..6c340a951 --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlsemtrywait.html @@ -0,0 +1,311 @@ +SDL_SemTryWait
SDL Library Documentation
PrevNext

SDL_SemTryWait

Name

SDL_SemTryWait -- Attempt to lock a semaphore but don't suspend the thread.

Synopsis

#include "SDL.h"
+#include "SDL_thread.h"

int SDL_SemTryWait(SDL_sem *sem);

Description

SDL_SemTryWait is a non-blocking varient of +SDL_SemWait. If the value of the semaphore +pointed to by sem is positive it will atomically +decrement the semaphore value and return 0, otherwise it will return +SDL_MUTEX_TIMEOUT instead of suspending the thread.

After SDL_SemTryWait is successful, the semaphore +can be released and its count atomically incremented by a successful call to +SDL_SemPost.

Return Value

Returns 0 if the semaphore was successfully locked or +either SDL_MUTEX_TIMEOUT or -1 +if the thread would have suspended or there was an error, respectivly.

If the semaphore was not successfully locked, the semaphore will be unchanged.

Examples

res = SDL_SemTryWait(my_sem);
+
+if (res == SDL_MUTEX_TIMEOUT) {
+        return TRY_AGAIN;
+}
+if (res == -1) {
+        return WAIT_ERROR;
+}
+
+...
+
+SDL_SemPost(my_sem);


PrevHomeNext
SDL_SemWaitUpSDL_SemWaitTimeout
\ No newline at end of file diff --git a/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlsemvalue.html b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlsemvalue.html new file mode 100644 index 000000000..fe3c2b263 --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlsemvalue.html @@ -0,0 +1,265 @@ +SDL_SemValue
SDL Library Documentation
PrevNext

SDL_SemValue

Name

SDL_SemValue -- Return the current value of a semaphore.

Synopsis

#include "SDL.h"
+#include "SDL/SDL_thread.h"

Uint32 SDL_SemValue(SDL_sem *sem);

Description

SDL_SemValue() returns the current semaphore value from +the semaphore pointed to by sem.

Return Value

Returns current value of the semaphore.

Examples

  sem_value = SDL_SemValue(my_sem);


PrevHomeNext
SDL_SemPostUpSDL_CreateCond
\ No newline at end of file diff --git a/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlsemwait.html b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlsemwait.html new file mode 100644 index 000000000..8304ec28b --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlsemwait.html @@ -0,0 +1,290 @@ +SDL_SemWait
SDL Library Documentation
PrevNext

SDL_SemWait

Name

SDL_SemWait -- Lock a semaphore and suspend the thread if the semaphore value is zero.

Synopsis

#include "SDL.h"
+#include "SDL_thread.h"

int SDL_SemWait(SDL_sem *sem);

Description

SDL_SemWait() suspends the calling thread until either +the semaphore pointed to by sem has a positive value, +the call is interrupted by a signal or error. If the call is successful it +will atomically decrement the semaphore value.

After SDL_SemWait() is successful, the semaphore +can be released and its count atomically incremented by a successful call to +SDL_SemPost.

Return Value

Returns 0 if successful or +-1 if there was an error (leaving the semaphore unchanged).

Examples

if (SDL_SemWait(my_sem) == -1) {
+        return WAIT_FAILED;
+}
+
+...
+
+SDL_SemPost(my_sem);


PrevHomeNext
SDL_DestroySemaphoreUpSDL_SemTryWait
\ No newline at end of file diff --git a/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlsemwaittimeout.html b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlsemwaittimeout.html new file mode 100644 index 000000000..ef3b970da --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlsemwaittimeout.html @@ -0,0 +1,314 @@ +SDL_SemWaitTimeout
SDL Library Documentation
PrevNext

SDL_SemWaitTimeout

Name

SDL_SemWaitTimeout -- Lock a semaphore, but only wait up to a specified maximum time.

Synopsis

#include "SDL.h"
+#include "SDL_thread.h"

int SDL_SemWaitTimeout(SDL_sem *sem, Uint32 timeout);

Description

SDL_SemWaitTimeout() is a varient of +SDL_SemWait +with a maximum timeout value. +If the value of the semaphore pointed to by sem is +positive (greater than zero) it will atomically decrement the semaphore value +and return 0, otherwise it will wait up to timeout +milliseconds trying to lock the semaphore. This function is to be avoided if +possible since on some platforms it is implemented by polling the semaphore +every millisecond in a busy loop.

After SDL_SemWaitTimeout() is successful, the semaphore +can be released and its count atomically incremented by a successful call to +SDL_SemPost.

Return Value

Returns 0 if the semaphore was successfully locked or +either SDL_MUTEX_TIMEOUT or -1 +if the timeout period was exceeded or there was an error, respectivly.

If the semaphore was not successfully locked, the semaphore will be unchanged.

Examples

res = SDL_SemWaitTimeout(my_sem, WAIT_TIMEOUT_MILLISEC);
+
+if (res == SDL_MUTEX_TIMEOUT) {
+        return TRY_AGAIN;
+}
+if (res == -1) {
+        return WAIT_ERROR;
+}
+
+...
+
+SDL_SemPost(my_sem);


PrevHomeNext
SDL_SemTryWaitUpSDL_SemPost
\ No newline at end of file diff --git a/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlsetalpha.html b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlsetalpha.html new file mode 100644 index 000000000..82ebd8efa --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlsetalpha.html @@ -0,0 +1,492 @@ +SDL_SetAlpha
SDL Library Documentation
PrevNext

SDL_SetAlpha

Name

SDL_SetAlpha -- Adjust the alpha properties of a surface

Synopsis

#include "SDL.h"

int SDL_SetAlpha(SDL_Surface *surface, Uint32 flag, Uint8 alpha);

Description

Note: This function and the semantics of SDL alpha blending have changed since version 1.1.4. Up until version 1.1.5, an alpha value of 0 was considered opaque and a value of 255 was considered transparent. This has now been inverted: 0 (SDL_ALPHA_TRANSPARENT) is now considered transparent and 255 (SDL_ALPHA_OPAQUE) is now considered opaque.

SDL_SetAlpha is used for setting the per-surface alpha +value and/or enabling and disabling alpha blending.

Thesurface parameter specifies which surface whose alpha +attributes you wish to adjust. flags is used to specify +whether alpha blending should be used (SDL_SRCALPHA) and +whether the surface should use RLE acceleration for blitting +(SDL_RLEACCEL). flags can be an OR'd +combination of these two options, one of these options or 0. If +SDL_SRCALPHA is not passed as a flag then all alpha +information is ignored when blitting the surface. The +alpha parameter is the per-surface alpha value; a +surface need not have an alpha channel to use per-surface alpha and blitting +can still be accelerated with SDL_RLEACCEL.

Note: The per-surface alpha value of 128 is considered a special case and +is optimised, so it's much faster than other per-surface values.

Alpha effects surface blitting in the following ways:

RGBA->RGB with SDL_SRCALPHA

The source is alpha-blended with the destination, using the alpha channel. SDL_SRCCOLORKEY and the per-surface alpha are ignored.

RGBA->RGB without SDL_SRCALPHA

The RGB data is copied from the source. The source alpha channel and the per-surface alpha value are ignored.

RGB->RGBA with SDL_SRCALPHA

The source is alpha-blended with the destination using the per-surface alpha +value. If SDL_SRCCOLORKEY is set, only the pixels not +matching the colorkey value are copied. The alpha channel of the copied pixels +is set to opaque.

RGB->RGBA without SDL_SRCALPHA

The RGB data is copied from the source and the alpha value of the copied pixels +is set to opaque. If SDL_SRCCOLORKEY is set, only the pixels +not matching the colorkey value are copied.

RGBA->RGBA with SDL_SRCALPHA

The source is alpha-blended with the destination using the source alpha +channel. The alpha channel in the destination surface is left untouched. +SDL_SRCCOLORKEY is ignored.

RGBA->RGBA without SDL_SRCALPHA

The RGBA data is copied to the destination surface. If SDL_SRCCOLORKEY is set, only the pixels not matching the colorkey value are copied.

RGB->RGB with SDL_SRCALPHA

The source is alpha-blended with the destination using the per-surface alpha value. If SDL_SRCCOLORKEY is set, only the pixels not matching the colorkey value are copied.

RGB->RGB without SDL_SRCALPHA

The RGB data is copied from the source. If SDL_SRCCOLORKEY is set, only the pixels not matching the colorkey value are copied.

Note: Note that RGBA->RGBA blits (with SDL_SRCALPHA set) keep the alpha +of the destination surface. This means that you cannot compose two arbitrary +RGBA surfaces this way and get the result you would expect from "overlaying" +them; the destination alpha will work as a mask.

Also note that per-pixel and per-surface alpha cannot be combined; +the per-pixel alpha is always used if available

Return Value

This function returns 0, or +-1 if there was an error.


PrevHomeNext
SDL_SetColorKeyUpSDL_SetClipRect
\ No newline at end of file diff --git a/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlsetcliprect.html b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlsetcliprect.html new file mode 100644 index 000000000..7b0b06393 --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlsetcliprect.html @@ -0,0 +1,233 @@ +SDL_SetClipRect
SDL Library Documentation
PrevNext

SDL_SetClipRect

Name

SDL_SetClipRect -- Sets the clipping rectangle for a surface.

Synopsis

#include "SDL.h"

void SDL_SetClipRect(SDL_Surface *surface, SDL_Rect *rect);

Description

Sets the clipping rectangle for a surface. When this surface is the +destination of a blit, only the area within the clip rectangle will be +drawn into.

The rectangle pointed to by rect will be +clipped to the edges of the surface so that the clip rectangle for a +surface can never fall outside the edges of the surface.

If rect is NULL the clipping +rectangle will be set to the full size of the surface.


PrevHomeNext
SDL_SetAlphaUpSDL_GetClipRect
\ No newline at end of file diff --git a/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlsetcolorkey.html b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlsetcolorkey.html new file mode 100644 index 000000000..357d4c598 --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlsetcolorkey.html @@ -0,0 +1,313 @@ +SDL_SetColorKey
SDL Library Documentation
PrevNext

SDL_SetColorKey

Name

SDL_SetColorKey -- Sets the color key (transparent pixel) in a blittable surface and +RLE acceleration.

Synopsis

#include "SDL.h"

int SDL_SetColorKey(SDL_Surface *surface, Uint32 flag, Uint32 key);

Description

Sets the color key (transparent pixel) in a blittable surface and enables or + disables RLE blit acceleration.

RLE acceleration can substantially speed up blitting of images with large +horizontal runs of transparent pixels (i.e., pixels that match the +key value). The key must be of the same pixel format as the surface, SDL_MapRGB is often useful for obtaining an acceptable value.

If flag is SDL_SRCCOLORKEY then +key is the transparent pixel value in the source image of a +blit.

If flag is OR'd with +SDL_RLEACCEL then the surface will be draw using RLE +acceleration when drawn with +SDL_BlitSurface. The surface will +actually be encoded for RLE acceleration the first time +SDL_BlitSurface or +SDL_DisplayFormat is called on the +surface.

If flag is 0, this function clears +any current color key.

Return Value

This function returns 0, or +-1 if there was an error.


PrevHomeNext
SDL_SaveBMPUpSDL_SetAlpha
\ No newline at end of file diff --git a/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlsetcolors.html b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlsetcolors.html new file mode 100644 index 000000000..2ab3733ad --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlsetcolors.html @@ -0,0 +1,350 @@ +SDL_SetColors
SDL Library Documentation
PrevNext

SDL_SetColors

Name

SDL_SetColors -- Sets a portion of the colormap for the given 8-bit surface.

Synopsis

#include "SDL.h"

int SDL_SetColors(SDL_Surface *surface, SDL_Color *colors, int firstcolor, int ncolors);

Description

Sets a portion of the colormap for the given 8-bit surface.

When surface is the surface associated with the current +display, the display colormap will be updated with the requested colors. If +SDL_HWPALETTE was set in SDL_SetVideoMode flags, +SDL_SetColors will always return 1, +and the palette is guaranteed to be set the way you desire, even if the window +colormap has to be warped or run under emulation.

The color components of a +SDL_Color +structure are 8-bits in size, giving you a total of 2563 +=16777216 colors.

Palettized (8-bit) screen surfaces with the SDL_HWPALETTE +flag have two palettes, a logical palette that is used for mapping blits +to/from the surface and a physical palette (that determines how the +hardware will map the colors to the display). SDL_SetColors +modifies both palettes (if present), and is equivalent to calling +SDL_SetPalette with the +flags set to +(SDL_LOGPAL | SDL_PHYSPAL).

Return Value

If surface is not a palettized surface, this function +does nothing, returning 0. If all of the colors were set +as passed to SDL_SetColors, it will return +1. If not all the color entries were set exactly as +given, it will return 0, and you should look at the +surface palette to determine the actual color palette.

Example

/* Create a display surface with a grayscale palette */
+SDL_Surface *screen;
+SDL_Color colors[256];
+int i;
+.
+.
+.
+/* Fill colors with color information */
+for(i=0;i<256;i++){
+  colors[i].r=i;
+  colors[i].g=i;
+  colors[i].b=i;
+}
+
+/* Create display */
+screen=SDL_SetVideoMode(640, 480, 8, SDL_HWPALETTE);
+if(!screen){
+  printf("Couldn't set video mode: %s\n", SDL_GetError());
+  exit(-1);
+}
+
+/* Set palette */
+SDL_SetColors(screen, colors, 0, 256);
+.
+.
+.
+.

PrevHomeNext
SDL_FlipUpSDL_SetPalette
\ No newline at end of file diff --git a/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlsetcursor.html b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlsetcursor.html new file mode 100644 index 000000000..a898420d0 --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlsetcursor.html @@ -0,0 +1,214 @@ +SDL_SetCursor
SDL Library Documentation
PrevNext

SDL_SetCursor

Name

SDL_SetCursor -- Set the currently active mouse cursor.

Synopsis

#include "SDL.h"

void *SDL_SetCursor(SDL_Cursor *cursor);

Description

Sets the currently active cursor to +the specified one. +If the cursor is currently visible, the change will be immediately +represented on the display.


PrevHomeNext
SDL_FreeCursorUpSDL_GetCursor
\ No newline at end of file diff --git a/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlseteventfilter.html b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlseteventfilter.html new file mode 100644 index 000000000..88db07efb --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlseteventfilter.html @@ -0,0 +1,273 @@ +SDL_SetEventFilter
SDL Library Documentation
PrevNext

SDL_SetEventFilter

Name

SDL_SetEventFilter -- Sets up a filter to process all events before they are posted +to the event queue.

Synopsis

#include "SDL.h"

void SDL_SetEventFilter(SDL_EventFilter filter);

Description

This function sets up a filter to process all events before they are posted +to the event queue. This is a very powerful and flexible feature. The filter +is prototyped as: +

typedef int (*SDL_EventFilter)(const SDL_Event *event);
+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. This allows selective +filtering of dynamically.

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.

Note: Events pushed onto the queue with SDL_PushEvent or SDL_PeepEvents do not get passed through the event filter.

Note: Be Careful! The event filter function may run in a different thread so be careful what you do within it.


PrevHomeNext
SDL_PushEventUpSDL_GetEventFilter
\ No newline at end of file diff --git a/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlsetgamma.html b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlsetgamma.html new file mode 100644 index 000000000..1c5f88c7f --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlsetgamma.html @@ -0,0 +1,223 @@ +SDL_SetGamma
SDL Library Documentation
PrevNext

SDL_SetGamma

Name

SDL_SetGamma -- Sets the color gamma function for the display

Synopsis

#include "SDL.h"

int SDL_SetGamma(float redgamma, float greengamma, float bluegamma);

Description

Sets the "gamma function" for the display of each color component. Gamma +controls the brightness/contrast of colors displayed on the screen. +A gamma value of 1.0 is identity (i.e., no adjustment +is made).

This function adjusts the gamma based on the "gamma function" parameter, +you can directly specify lookup tables for gamma adjustment with +SDL_SetGammaRamp.

Not all display hardware is able to change gamma.

Return Value

Returns -1 on error (or if gamma adjustment is not supported).


PrevHomeNext
SDL_SetPaletteUpSDL_GetGammaRamp
\ No newline at end of file diff --git a/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlsetgammaramp.html b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlsetgammaramp.html new file mode 100644 index 000000000..46ea1065e --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlsetgammaramp.html @@ -0,0 +1,222 @@ +SDL_SetGammaRamp
SDL Library Documentation
PrevNext

SDL_SetGammaRamp

Name

SDL_SetGammaRamp -- Sets the color gamma lookup tables for the display

Synopsis

#include "SDL.h"

int SDL_SetGammaRamp(Uint16 *redtable, Uint16 *greentable, Uint16 *bluetable);

Description

Sets the gamma lookup tables for the display for each color component. +Each table is an array of 256 Uint16 values, representing a mapping +between the input and output for that channel. The input is the index +into the array, and the output is the 16-bit gamma value at that index, +scaled to the output color precision. You may pass NULL to any of the +channels to leave them unchanged.

This function adjusts the gamma based on lookup tables, you can also +have the gamma calculated based on a "gamma function" parameter with +SDL_SetGamma.

Not all display hardware is able to change gamma.

Return Value

Returns -1 on error (or if gamma adjustment is not supported).


PrevHomeNext
SDL_GetGammaRampUpSDL_MapRGB
\ No newline at end of file diff --git a/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlsetmodstate.html b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlsetmodstate.html new file mode 100644 index 000000000..124a6028e --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlsetmodstate.html @@ -0,0 +1,229 @@ +SDL_SetModState
SDL Library Documentation
PrevNext

SDL_SetModState

Name

SDL_SetModState -- Set the current key modifier state

Synopsis

#include "SDL.h"

void SDL_SetModState(SDLMod modstate);

Description

The inverse of SDL_GetModState, SDL_SetModState allows you to impose modifier key states on your application.

Simply pass your desired modifier states into modstate. This value my be a logical OR'd combination of the following:

typedef enum {
+  KMOD_NONE  = 0x0000,
+  KMOD_LSHIFT= 0x0001,
+  KMOD_RSHIFT= 0x0002,
+  KMOD_LCTRL = 0x0040,
+  KMOD_RCTRL = 0x0080,
+  KMOD_LALT  = 0x0100,
+  KMOD_RALT  = 0x0200,
+  KMOD_LMETA = 0x0400,
+  KMOD_RMETA = 0x0800,
+  KMOD_NUM   = 0x1000,
+  KMOD_CAPS  = 0x2000,
+  KMOD_MODE  = 0x4000,
+} SDLMod;

PrevHomeNext
SDL_GetModStateUpSDL_GetKeyName
\ No newline at end of file diff --git a/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlsetpalette.html b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlsetpalette.html new file mode 100644 index 000000000..977673e67 --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlsetpalette.html @@ -0,0 +1,344 @@ +SDL_SetPalette
SDL Library Documentation
PrevNext

SDL_SetPalette

Name

SDL_SetPalette -- Sets the colors in the palette of an 8-bit surface.

Synopsis

#include "SDL.h"

int SDL_SetPalette(SDL_Surface *surface, int flags, SDL_Color *colors, int firstcolor, int ncolors);

Description

Sets a portion of the palette for the given 8-bit surface.

Palettized (8-bit) screen surfaces with the +SDL_HWPALETTE flag have two palettes, a logical +palette that is used for mapping blits to/from the surface and a +physical palette (that determines how the hardware will map the colors +to the display). SDL_BlitSurface +always uses the logical palette when blitting surfaces (if it has to +convert between surface pixel formats). Because of this, it is often +useful to modify only one or the other palette to achieve various +special color effects (e.g., screen fading, color flashes, screen dimming).

This function can modify either the logical or physical palette by +specifing SDL_LOGPAL or +SDL_PHYSPALthe in the flags +parameter.

When surface is the surface associated with the current +display, the display colormap will be updated with the requested colors. If +SDL_HWPALETTE was set in SDL_SetVideoMode flags, +SDL_SetPalette will always return 1, +and the palette is guaranteed to be set the way you desire, even if the window +colormap has to be warped or run under emulation.

The color components of a +SDL_Color structure +are 8-bits in size, giving you a total of +2563=16777216 colors.

Return Value

If surface is not a palettized surface, this function +does nothing, returning 0. If all of the colors were set +as passed to SDL_SetPalette, it will return +1. If not all the color entries were set exactly as +given, it will return 0, and you should look at the +surface palette to determine the actual color palette.

Example

        /* Create a display surface with a grayscale palette */
+        SDL_Surface *screen;
+        SDL_Color colors[256];
+        int i;
+        .
+        .
+        .
+        /* Fill colors with color information */
+        for(i=0;i<256;i++){
+          colors[i].r=i;
+          colors[i].g=i;
+          colors[i].b=i;
+        }
+
+        /* Create display */
+        screen=SDL_SetVideoMode(640, 480, 8, SDL_HWPALETTE);
+        if(!screen){
+          printf("Couldn't set video mode: %s\n", SDL_GetError());
+          exit(-1);
+        }
+
+        /* Set palette */
+        SDL_SetPalette(screen, SDL_LOGPAL|SDL_PHYSPAL, colors, 0, 256);
+        .
+        .
+        .
+        .

PrevHomeNext
SDL_SetColorsUpSDL_SetGamma
\ No newline at end of file diff --git a/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlsettimer.html b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlsettimer.html new file mode 100644 index 000000000..4e78dee2a --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlsettimer.html @@ -0,0 +1,261 @@ +SDL_SetTimer
SDL Library Documentation
Prev 

SDL_SetTimer

Name

SDL_SetTimer -- Set a callback to run after the specified number of milliseconds has +elapsed.

Synopsis

#include "SDL.h"

int SDL_SetTimer(Uint32 interval, SDL_TimerCallback callback);

Callback

/* Function prototype for the timer callback function */ +typedef Uint32 (*SDL_TimerCallback)(Uint32 interval);

Description

Set a callback to run after the specified number of milliseconds has +elapsed. 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.

To cancel a currently running timer, call +SDL_SetTimer(0, NULL);

The timer callback function may run in a different thread than your +main constant, and so shouldn't call any functions from within itself.

The maximum resolution of this timer is 10 ms, which means that if +you request a 16 ms timer, your callback will run approximately 20 ms +later on an unloaded system. If you wanted to set a flag signaling +a frame update at 30 frames per second (every 33 ms), you might set a +timer for 30 ms (see example below).

If you use this function, you need to pass SDL_INIT_TIMER +to SDL_Init().

Note: This function is kept for compatibility but has been superseded +by the new timer functions +SDL_AddTimer and +SDL_RemoveTimer which support +multiple timers.

Examples

SDL_SetTimer((33/10)*10, my_callback);

See Also

SDL_AddTimer


PrevHome 
SDL_RemoveTimerUp 
\ No newline at end of file diff --git a/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlsetvideomode.html b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlsetvideomode.html new file mode 100644 index 000000000..5e80b187f --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlsetvideomode.html @@ -0,0 +1,486 @@ +SDL_SetVideoMode
SDL Library Documentation
PrevNext

SDL_SetVideoMode

Name

SDL_SetVideoMode -- Set up a video mode with the specified width, height and bits-per-pixel.

Synopsis

#include "SDL.h"

SDL_Surface *SDL_SetVideoMode(int width, int height, int bpp, Uint32 flags);

Description

Set up a video mode with the specified width, height and bits-per-pixel.

If bpp is 0, it is treated as the +current display bits per pixel.

The flags parameter is the same as the flags field of the SDL_Surface structure. OR'd combinations of the following values are valid.

SDL_SWSURFACECreate the video surface in system memory
SDL_HWSURFACECreate the video surface in video memory
SDL_ASYNCBLITEnables the use of asynchronous to the display surface. This will usually slow down blitting on single CPU machines, but may provide a speed increase on SMP systems.
SDL_ANYFORMATNormally, if a video surface of the requested depth (bpp) is not available, SDL will emulate one with a shadow surface. Passing SDL_ANYFORMAT prevents this and causes SDL to use the video surface, regardless of its depth.
SDL_HWPALETTEGive SDL exclusive palette access. Without this flag you may not always get the the colors you request with SDL_SetColors.
SDL_DOUBLEBUFEnable double buffering; only valid with SDL_HWSURFACE. Calling SDL_Flip will flip the buffers and update the screen. If double buffering could not be enabled then SDL_Flip will just perform a SDL_UpdateRect on the entire screen.
SDL_FULLSCREENSDL will attempt to use a fullscreen mode
SDL_OPENGLCreate an OpenGL rendering context. You should have previously set OpenGL video attributes with SDL_GL_SetAttribute.
SDL_OPENGLBLITCreate an OpenGL rendering context, like above, but allow normal blitting operations.
SDL_RESIZABLECreate a resizable window. When the window is resized by the user a SDL_VIDEORESIZE event is generated and SDL_SetVideoMode can be called again with the new size.
SDL_NOFRAMEIf possible, SDL_NOFRAME causes SDL to create a window with no title bar or frame decoration. Fullscreen modes automatically have this flag set.

Note: Whatever flags SDL_SetVideoMode could satisfy are set in the flags member of the returned surface.

Return Value

The framebuffer surface, or NULL if it fails.


PrevHomeNext
SDL_VideoModeOKUpSDL_UpdateRect
\ No newline at end of file diff --git a/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlshowcursor.html b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlshowcursor.html new file mode 100644 index 000000000..fb29e7bd2 --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlshowcursor.html @@ -0,0 +1,231 @@ +SDL_ShowCursor
SDL Library Documentation
PrevNext

SDL_ShowCursor

Name

SDL_ShowCursor -- Toggle whether or not the cursor is shown on the screen.

Synopsis

#include "SDL.h"

int SDL_ShowCursor(int toggle);

Description

Toggle whether or not the cursor is shown on the screen. Passing SDL_ENABLE displays the cursor and passing SDL_DISABLE hides it. The current state of the mouse cursor can be queried by passing SDL_QUERY, either SDL_DISABLE or SDL_ENABLE will be returned.

The cursor starts off displayed, but can be turned off.

Return Value

Returns the current state of the cursor.


PrevHomeNext
SDL_GetCursorUpSDL_GL_LoadLibrary
\ No newline at end of file diff --git a/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlsurface.html b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlsurface.html new file mode 100644 index 000000000..a246ad072 --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlsurface.html @@ -0,0 +1,589 @@ +SDL_Surface
SDL Library Documentation
PrevNext

SDL_Surface

Name

SDL_Surface -- Graphical Surface Structure

Structure Definition

typedef struct SDL_Surface {
+        Uint32 flags;                           /* Read-only */
+        SDL_PixelFormat *format;                /* Read-only */
+        int w, h;                               /* Read-only */
+        Uint16 pitch;                           /* Read-only */
+        void *pixels;                           /* Read-write */
+
+        /* clipping information */
+        SDL_Rect clip_rect;                     /* Read-only */
+
+        /* Reference count -- used when freeing surface */
+        int refcount;                           /* Read-mostly */
+
+	/* This structure also contains private fields not shown here */
+} SDL_Surface;

Structure Data

flagsSurface flags
formatPixel format
w, hWidth and height of the surface
pitchLength of a surface scanline in bytes
pixelsPointer to the actual pixel data
clip_rectsurface clip rectangle

Description

SDL_Surface's represent areas of "graphical" +memory, memory that can be drawn to. The video framebuffer is returned +as a SDL_Surface by +SDL_SetVideoMode +and SDL_GetVideoSurface. +Most of the fields should be pretty obvious. +w and h are the +width and height of the surface in pixels. +pixels is a pointer to the actual pixel data, +the surface should be locked +before accessing this field. The clip_rect field +is the clipping rectangle as set by +SDL_SetClipRect.

The following are supported in the +flags field.

SDL_SWSURFACESurface is stored in system memory
SDL_HWSURFACESurface is stored in video memory
SDL_ASYNCBLITSurface uses asynchronous blits if possible
SDL_ANYFORMATAllows any pixel-format (Display surface)
SDL_HWPALETTESurface has exclusive palette
SDL_DOUBLEBUFSurface is double buffered (Display surface)
SDL_FULLSCREENSurface is full screen (Display Surface)
SDL_OPENGLSurface has an OpenGL context (Display Surface)
SDL_OPENGLBLITSurface supports OpenGL blitting (Display Surface)
SDL_RESIZABLESurface is resizable (Display Surface)
SDL_HWACCELSurface blit uses hardware acceleration
SDL_SRCCOLORKEYSurface use colorkey blitting
SDL_RLEACCELColorkey blitting is accelerated with RLE
SDL_SRCALPHASurface blit uses alpha blending
SDL_PREALLOCSurface uses preallocated memory


PrevHomeNext
SDL_PixelFormatUpSDL_VideoInfo
\ No newline at end of file diff --git a/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlsyswmevent.html b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlsyswmevent.html new file mode 100644 index 000000000..31ed6fedd --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlsyswmevent.html @@ -0,0 +1,224 @@ +SDL_SysWMEvent
SDL Library Documentation
PrevNext

SDL_SysWMEvent

Name

SDL_SysWMEvent -- Platform-dependent window manager event.

Description

The system window manager event contains a pointer to system-specific +information about unknown window manager events. If you enable this event +using +SDL_EventState(), +it will be generated whenever unhandled events are received from the window +manager. This can be used, for example, to implement cut-and-paste in your +application. + +

typedef struct {
+         Uint8 type;   /* Always SDL_SysWM */
+ } SDL_SysWMEvent;
+ +If you want to obtain system-specific information about the window manager, +you can fill the version member of a SDL_SysWMinfo +structure (details can be found in SDL_syswm.h, which must be included) using the SDL_VERSION() macro found in +SDL_version.h, and pass it to the +function: +

int SDL_GetWMInfo(SDL_SysWMinfo *info);


PrevHomeNext
SDL_ResizeEventUpSDL_UserEvent
\ No newline at end of file diff --git a/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlthreadid.html b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlthreadid.html new file mode 100644 index 000000000..8dfb7d924 --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlthreadid.html @@ -0,0 +1,182 @@ +SDL_ThreadID
SDL Library Documentation
PrevNext

SDL_ThreadID

Name

SDL_ThreadID -- Get the 32-bit thread identifier for the current thread.

Synopsis

#include "SDL.h"
+#include "SDL_thread.h"

Uint32 SDL_ThreadID(void);

Description

Get the 32-bit thread identifier for the current thread.


PrevHomeNext
SDL_CreateThreadUpSDL_GetThreadID
\ No newline at end of file diff --git a/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlunlockaudio.html b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlunlockaudio.html new file mode 100644 index 000000000..999622026 --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlunlockaudio.html @@ -0,0 +1,203 @@ +SDL_UnlockAudio
SDL Library Documentation
PrevNext

SDL_UnlockAudio

Name

SDL_UnlockAudio -- Unlock the callback function

Synopsis

#include "SDL.h"

void SDL_UnlockAudio(void);

Description

Unlocks a previous SDL_LockAudio call.


PrevHomeNext
SDL_LockAudioUpSDL_CloseAudio
\ No newline at end of file diff --git a/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlunlocksurface.html b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlunlocksurface.html new file mode 100644 index 000000000..754715630 --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlunlocksurface.html @@ -0,0 +1,211 @@ +SDL_UnlockSurface
SDL Library Documentation
PrevNext

SDL_UnlockSurface

Name

SDL_UnlockSurface -- Unlocks a previously locked surface.

Synopsis

#include "SDL.h"

void SDL_UnlockSurface(SDL_Surface *surface);

Description

Surfaces that were previously locked using SDL_LockSurface must be unlocked with SDL_UnlockSurface. Surfaces should be unlocked as soon as possible.

It should be noted that since 1.1.8, surface locks are recursive. See SDL_LockSurface.


PrevHomeNext
SDL_LockSurfaceUpSDL_LoadBMP
\ No newline at end of file diff --git a/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlunlockyuvoverlay.html b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlunlockyuvoverlay.html new file mode 100644 index 000000000..33e926ad7 --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlunlockyuvoverlay.html @@ -0,0 +1,217 @@ +SDL_UnlockYUVOverlay
SDL Library Documentation
PrevNext

SDL_UnlockYUVOverlay

Name

SDL_UnlockYUVOverlay -- Unlock an overlay

Synopsis

#include "SDL.h"

void SDL_UnlockYUVOverlay(SDL_Overlay *overlay);

Description

The opposite to SDL_LockYUVOverlay. Unlocks a previously locked overlay. An overlay must be unlocked before it can be displayed.


PrevHomeNext
SDL_LockYUVOverlayUpSDL_DisplayYUVOverlay
\ No newline at end of file diff --git a/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlupdaterect.html b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlupdaterect.html new file mode 100644 index 000000000..6b3ce0ea0 --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlupdaterect.html @@ -0,0 +1,258 @@ +SDL_UpdateRect
SDL Library Documentation
PrevNext

SDL_UpdateRect

Name

SDL_UpdateRect -- Makes sure the given area is updated on the given screen.

Synopsis

#include "SDL.h"

void SDL_UpdateRect(SDL_Surface *screen, Sint32 x, Sint32 y, Sint32 w, Sint32 h);

Description

Makes sure the given area is updated on the given screen. The rectangle must +be confined within the screen boundaries (no clipping is done).

If 'x', 'y', 'w' +and 'h' are all 0, +SDL_UpdateRect will update the +entire screen.

This function should not be called while 'screen' is +locked.


PrevHomeNext
SDL_SetVideoModeUpSDL_UpdateRects
\ No newline at end of file diff --git a/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlupdaterects.html b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlupdaterects.html new file mode 100644 index 000000000..6b569f597 --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlupdaterects.html @@ -0,0 +1,247 @@ +SDL_UpdateRects
SDL Library Documentation
PrevNext

SDL_UpdateRects

Name

SDL_UpdateRects -- Makes sure the given list of rectangles is updated on the given screen.

Synopsis

#include "SDL.h"

void SDL_UpdateRects(SDL_Surface *screen, int numrects, SDL_Rect *rects);

Description

Makes sure the given list of rectangles is updated on the given screen. +The rectangles must all be confined within the screen boundaries (no +clipping is done).

This function should not be called while screen is +locked.

Note: It is adviced to call this function only once per frame, since each +call has some processing overhead. This is no restriction since you +can pass any number of rectangles each time.

The rectangles are not automatically merged or checked for overlap. In +general, the programmer can use his knowledge about his particular +rectangles to merge them in an efficient way, to avoid overdraw.


PrevHomeNext
SDL_UpdateRectUpSDL_Flip
\ No newline at end of file diff --git a/contrib/sdk/sources/SDL-1.2.2/docs/html/sdluserevent.html b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdluserevent.html new file mode 100644 index 000000000..cff120aa7 --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdluserevent.html @@ -0,0 +1,329 @@ +SDL_UserEvent
SDL Library Documentation
PrevNext

SDL_UserEvent

Name

SDL_UserEvent -- A user-defined event type

Structure Definition

typedef struct{
+  Uint8 type;
+  int code;
+  void *data1;
+  void *data2;
+} SDL_UserEvent;

Structure Data

typeSDL_USEREVENT through to SDL_NUMEVENTS-1
codeUser defined event code
data1User defined data pointer
data2User defined data pointer

Description

SDL_UserEvent is in the user member of the structure SDL_Event. This event is unique, it is never created by SDL but only by the user. The event can be pushed onto the event queue using SDL_PushEvent. The contents of the structure members or completely up to the programmer, the only requirement is that type is a value from SDL_USEREVENT to SDL_NUMEVENTS-1 (inclusive).

Examples

SDL_Event event;
+
+event.type = SDL_USEREVENT;
+event.user.code = my_event_code;
+event.user.data1 = significant_data;
+event.user.data2 = 0;
+SDL_PushEvent(&event);


PrevHomeNext
SDL_SysWMEventUpSDL_QuitEvent
\ No newline at end of file diff --git a/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlvideodrivername.html b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlvideodrivername.html new file mode 100644 index 000000000..2d1ce4640 --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlvideodrivername.html @@ -0,0 +1,235 @@ +SDL_VideoDriverName
SDL Library Documentation
PrevNext

SDL_VideoDriverName

Name

SDL_VideoDriverName -- Obtain the name of the video driver

Synopsis

#include "SDL.h"

char *SDL_VideoDriverName(char *namebuf, int maxlen);

Description

The buffer pointed to by namebuf is filled up to a maximum of maxlen characters (include the NULL terminator) with the name of the initialised video driver. The driver name is a simple one word identifier like "x11" or "windib".

Return Value

Returns NULL if video has not been initialised with SDL_Init or a pointer to namebuf otherwise.


PrevHomeNext
SDL_GetVideoInfoUpSDL_ListModes
\ No newline at end of file diff --git a/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlvideoinfo.html b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlvideoinfo.html new file mode 100644 index 000000000..5cdc038ce --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlvideoinfo.html @@ -0,0 +1,400 @@ +SDL_VideoInfo
SDL Library Documentation
PrevNext

SDL_VideoInfo

Name

SDL_VideoInfo -- Video Target information

Structure Definition

typedef struct{
+  Uint32 hw_available:1;
+  Uint32 wm_available:1;
+  Uint32 blit_hw:1;
+  Uint32 blit_hw_CC:1;
+  Uint32 blit_hw_A:1;
+  Uint32 blit_sw:1;
+  Uint32 blit_sw_CC:1;
+  Uint32 blit_sw_A:1;
+  Uint32 blit_fill;
+  Uint32 video_mem;
+  SDL_PixelFormat *vfmt;
+} SDL_VideoInfo;

Structure Data

hw_availableIs it possible to create hardware surfaces?
wm_availableIs there a window manager available
blit_hwAre hardware to hardware blits accelerated?
blit_hw_CCAre hardware to hardware colorkey blits accelerated?
blit_hw_AAre hardware to hardware alpha blits accelerated?
blit_swAre software to hardware blits accelerated?
blit_sw_CCAre software to hardware colorkey blits accelerated?
blit_sw_AAre software to hardware alpha blits accelerated?
blit_fillAre color fills accelerated?
video_memTotal amount of video memory in Kilobytes
vfmtPixel format of the video device

Description

This (read-only) structure is returned by SDL_GetVideoInfo. It contains information on either the 'best' available mode (if called before SDL_SetVideoMode) or the current video mode.


PrevHomeNext
SDL_SurfaceUpSDL_Overlay
\ No newline at end of file diff --git a/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlvideomodeok.html b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlvideomodeok.html new file mode 100644 index 000000000..28079fb62 --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlvideomodeok.html @@ -0,0 +1,262 @@ +SDL_VideoModeOK
SDL Library Documentation
PrevNext

SDL_VideoModeOK

Name

SDL_VideoModeOK -- Check to see if a particular video mode is supported.

Synopsis

#include "SDL.h"

int SDL_VideoModeOK(int width, int height, int bpp, Uint32 flags);

Description

SDL_VideoModeOK returns 0 +if the requested mode is not supported under any bit depth, or returns the +bits-per-pixel of the closest available mode with the given width, height and requested surface flags (see SDL_SetVideoMode).

The bits-per-pixel value returned is only a suggested mode. You can usually request and bpp you want when setting the video mode and SDL will emulate that color depth with a shadow video surface.

The arguments to SDL_VideoModeOK are the same ones you +would pass to SDL_SetVideoMode

Example

SDL_Surface *screen;
+Uint32 bpp;
+.
+.
+.
+printf("Checking mode 640x480@16bpp.\n");
+bpp=SDL_VideoModeOK(640, 480, 16, SDL_HWSURFACE);
+
+if(!bpp){
+  printf("Mode not available.\n");
+  exit(-1);
+}
+
+printf("SDL Recommends 640x480@%dbpp.\n", bpp);
+screen=SDL_SetVideoMode(640, 480, bpp, SDL_HWSURFACE);
+.
+.

PrevHomeNext
SDL_ListModesUpSDL_SetVideoMode
\ No newline at end of file diff --git a/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlwaitevent.html b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlwaitevent.html new file mode 100644 index 000000000..9839f5339 --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlwaitevent.html @@ -0,0 +1,223 @@ +SDL_WaitEvent
SDL Library Documentation
PrevNext

SDL_WaitEvent

Name

SDL_WaitEvent -- Waits indefinitely for the next available event.

Synopsis

#include "SDL.h"

int SDL_WaitEvent(SDL_Event *event);

Description

Waits indefinitely for the next available event, returning +1, or 0 if there was +an error while waiting for events.

If event is not NULL, the next +event is removed from the queue and stored in that area.


PrevHomeNext
SDL_PollEventUpSDL_PushEvent
\ No newline at end of file diff --git a/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlwaitthread.html b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlwaitthread.html new file mode 100644 index 000000000..d3ae78129 --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlwaitthread.html @@ -0,0 +1,223 @@ +SDL_WaitThread
SDL Library Documentation
PrevNext

SDL_WaitThread

Name

SDL_WaitThread -- Wait for a thread to finish.

Synopsis

#include "SDL.h"
+#include "SDL_thread.h"

void SDL_WaitThread(SDL_Thread *thread, int *status);

Description

Wait for a thread to finish (timeouts are not supported).

Return Value

The return code for the thread function is placed in the area pointed to by +status, if status is not +NULL.


PrevHomeNext
SDL_GetThreadIDUpSDL_KillThread
\ No newline at end of file diff --git a/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlwarpmouse.html b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlwarpmouse.html new file mode 100644 index 000000000..51ee6994d --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlwarpmouse.html @@ -0,0 +1,197 @@ +SDL_WarpMouse
SDL Library Documentation
PrevNext

SDL_WarpMouse

Name

SDL_WarpMouse -- Set the position of the mouse cursor.

Synopsis

#include "SDL.h"

void SDL_WarpMouse(Uint16 x, Uint16 y);

Description

Set the position of the mouse cursor (generates a mouse motion event).


PrevHomeNext
SDL_DisplayFormatAlphaUpSDL_CreateCursor
\ No newline at end of file diff --git a/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlwasinit.html b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlwasinit.html new file mode 100644 index 000000000..b4a6e1abd --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlwasinit.html @@ -0,0 +1,276 @@ +SDL_WasInit
SDL Library Documentation
PrevNext

SDL_WasInit

Name

SDL_WasInit -- Check which subsystems are initialized

Synopsis

#include "SDL.h"

Uint32 SDL_WasInit(Uint32 flags);

Description

SDL_WasInit allows you to see which SDL subsytems have been initialized. flags is a bitwise OR'd combination of the subsystems you wish to check (see SDL_Init for a list of subsystem flags).

Return Value

SDL_WasInit returns a bitwised OR'd combination of the initialized subsystems.

Examples


/* Here are several ways you can use SDL_WasInit() */
+
+/* Get init data on all the subsystems */
+Uint32 subsystem_init;
+
+subsystem_init=SDL_WasInit(SDL_INIT_EVERYTHING);
+
+if(subsystem_init&SDL_INIT_VIDEO)
+  printf("Video is initialized.\n");
+else
+  printf("Video is not initialized.\n");
+
+
+
+/* Just check for one specfic subsystem */
+
+if(SDL_WasInit(SDL_INIT_VIDEO)!=0)
+  printf("Video is initialized.\n");
+else
+  printf("Video is not initialized.\n");
+
+
+
+
+/* Check for two subsystems */
+
+Uint32 subsystem_mask=SDL_INIT_VIDEO|SDL_INIT_AUDIO;
+
+if(SDL_WasInit(subsystem_mask)==subsystem_mask)
+  printf("Video and Audio initialized.\n");
+else
+  printf("Video and Audio not initialized.\n");

PrevHomeNext
SDL_QuitUpVideo
\ No newline at end of file diff --git a/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlwmgetcaption.html b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlwmgetcaption.html new file mode 100644 index 000000000..0c37bf3be --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlwmgetcaption.html @@ -0,0 +1,214 @@ +SDL_WM_GetCaption
SDL Library Documentation
PrevNext

SDL_WM_GetCaption

Name

SDL_WM_GetCaption -- Gets the window title and icon name.

Synopsis

#include "SDL.h"

void SDL_WM_GetCaption(char **title, char **icon);

Description

Set pointers to the window title and icon name.


PrevHomeNext
SDL_WM_SetCaptionUpSDL_WM_SetIcon
\ No newline at end of file diff --git a/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlwmgrabinput.html b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlwmgrabinput.html new file mode 100644 index 000000000..154d89d3e --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlwmgrabinput.html @@ -0,0 +1,216 @@ +SDL_WM_GrabInput
SDL Library Documentation
PrevNext

SDL_WM_GrabInput

Name

SDL_WM_GrabInput -- Grabs mouse and keyboard input.

Synopsis

#include "SDL.h"

SDL_GrabMode SDL_WM_GrabInput(SDL_GrabMode mode);

Description

Grabbing means that the mouse is confined to the application window, +and nearly all keyboard input is passed directly to the application, +and not interpreted by a window manager, if any.

When mode is SDL_GRAB_QUERY the grab mode is not changed, but the current grab mode is returned.

typedef enum {
+  SDL_GRAB_QUERY,
+  SDL_GRAB_OFF,
+  SDL_GRAB_ON
+} SDL_GrabMode;
+

Return Value

The current/new SDL_GrabMode.


PrevHomeNext
SDL_WM_ToggleFullScreenUpEvents
\ No newline at end of file diff --git a/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlwmiconifywindow.html b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlwmiconifywindow.html new file mode 100644 index 000000000..5892f6de8 --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlwmiconifywindow.html @@ -0,0 +1,203 @@ +SDL_WM_IconifyWindow
SDL Library Documentation
PrevNext

SDL_WM_IconifyWindow

Name

SDL_WM_IconifyWindow -- Iconify/Minimise the window

Synopsis

#include "SDL.h"

int SDL_WM_IconifyWindow(void);

Description

If the application is running in a window managed environment SDL attempts to iconify/minimise it. If SDL_WM_IconifyWindow is successful, the application will receive a SDL_APPACTIVE loss event.

Return Value

Returns non-zero on success or 0 if iconification is not support or was refused by the window manager.


PrevHomeNext
SDL_WM_SetIconUpSDL_WM_ToggleFullScreen
\ No newline at end of file diff --git a/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlwmsetcaption.html b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlwmsetcaption.html new file mode 100644 index 000000000..32f5bbbe6 --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlwmsetcaption.html @@ -0,0 +1,204 @@ +SDL_WM_SetCaption
SDL Library Documentation
PrevNext

SDL_WM_SetCaption

Name

SDL_WM_SetCaption -- Sets the window tile and icon name.

Synopsis

#include "SDL.h"

void SDL_WM_SetCaption(const char *title, const char *icon);

Description

Sets the title-bar and icon name of the display window.


PrevHomeNext
Window ManagementUpSDL_WM_GetCaption
\ No newline at end of file diff --git a/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlwmseticon.html b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlwmseticon.html new file mode 100644 index 000000000..0f2fc864b --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlwmseticon.html @@ -0,0 +1,244 @@ +SDL_WM_SetIcon
SDL Library Documentation
PrevNext

SDL_WM_SetIcon

Name

SDL_WM_SetIcon -- Sets the icon for the display window.

Synopsis

#include "SDL.h"

void SDL_WM_SetIcon(SDL_Surface *icon, Uint8 *mask);

Description

Sets the icon for the display window.

This function must be called before the first call to +SDL_SetVideoMode.

It takes an icon surface, and a mask in MSB format.

If mask is NULL, the entire +icon surface will be used as the icon.

Example

SDL_WM_SetIcon(SDL_LoadBMP("icon.bmp"), NULL);

PrevHomeNext
SDL_WM_GetCaptionUpSDL_WM_IconifyWindow
\ No newline at end of file diff --git a/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlwmtogglefullscreen.html b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlwmtogglefullscreen.html new file mode 100644 index 000000000..39bf69786 --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/docs/html/sdlwmtogglefullscreen.html @@ -0,0 +1,197 @@ +SDL_WM_ToggleFullScreen
SDL Library Documentation
PrevNext

SDL_WM_ToggleFullScreen

Name

SDL_WM_ToggleFullScreen -- Toggles fullscreen mode

Synopsis

#include "SDL.h"

int SDL_WM_ToggleFullScreen(SDL_Surface *surface);

Description

Toggles the application between windowed and fullscreen mode, if supported. (X11 is the only target currently supported, BeOS support is experimental).

Return Value

Returns 0 on failure or 1 on success.


PrevHomeNext
SDL_WM_IconifyWindowUpSDL_WM_GrabInput
\ No newline at end of file diff --git a/contrib/sdk/sources/SDL-1.2.2/docs/html/thread.html b/contrib/sdk/sources/SDL-1.2.2/docs/html/thread.html new file mode 100644 index 000000000..fb460e818 --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/docs/html/thread.html @@ -0,0 +1,305 @@ +Multi-threaded Programming
SDL Library Documentation
PrevNext

Chapter 12. Multi-threaded Programming

Table of Contents
SDL_CreateThread — Creates a new thread of execution that shares its parent's properties.
SDL_ThreadID — Get the 32-bit thread identifier for the current thread.
SDL_GetThreadID — Get the SDL thread ID of a SDL_Thread
SDL_WaitThread — Wait for a thread to finish.
SDL_KillThread — Gracelessly terminates the thread.
SDL_CreateMutex — Create a mutex
SDL_DestroyMutex — Destroy a mutex
SDL_mutexP — Lock a mutex
SDL_mutexV — Unlock a mutex
SDL_CreateSemaphore — Creates a new semaphore and assigns an initial value to it.
SDL_DestroySemaphore — Destroys a semaphore that was created by SDL_CreateSemaphore.
SDL_SemWait — Lock a semaphore and suspend the thread if the semaphore value is zero.
SDL_SemTryWait — Attempt to lock a semaphore but don't suspend the thread.
SDL_SemWaitTimeout — Lock a semaphore, but only wait up to a specified maximum time.
SDL_SemPost — Unlock a semaphore.
SDL_SemValue — Return the current value of a semaphore.
SDL_CreateCond — Create a condition variable
SDL_DestroyCond — Destroy a condition variable
SDL_CondSignal — Restart a thread wait on a condition variable
SDL_CondBroadcast — Restart all threads waiting on a condition variable
SDL_CondWait — Wait on a condition variable
SDL_CondWaitTimeout — Wait on a condition variable, with timeout

SDL provides functions for creating threads, mutexes, semphores and condition variables.

In general, you must be very aware of concurrency and data integrity issues +when writing multi-threaded programs. Some good guidelines include: +

  • Don't call SDL video/event functions from separate threads

  • Don't use any library functions in separate threads

  • Don't perform any memory management in separate threads

  • Lock global variables which may be accessed by multiple threads

  • Never terminate threads, always set a flag and wait for them to quit

  • Think very carefully about all possible ways your code may interact

Note: SDL's threading is not implemented on MacOS, due to that lack of preemptive thread support (eck!)


PrevHomeNext
SDL_CDtrackUpSDL_CreateThread
\ No newline at end of file diff --git a/contrib/sdk/sources/SDL-1.2.2/docs/html/time.html b/contrib/sdk/sources/SDL-1.2.2/docs/html/time.html new file mode 100644 index 000000000..75ce78f52 --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/docs/html/time.html @@ -0,0 +1,198 @@ +Time
SDL Library Documentation
PrevNext

Chapter 13. Time

Table of Contents
SDL_GetTicks — Get the number of milliseconds since the SDL library initialization.
SDL_Delay — Wait a specified number of milliseconds before returning.
SDL_AddTimer — Add a timer which will call a callback after the specified number of milliseconds has +elapsed.
SDL_RemoveTimer — Remove a timer which was added with +SDL_AddTimer.
SDL_SetTimer — Set a callback to run after the specified number of milliseconds has +elapsed.

SDL provides several cross-platform functions for dealing with time. +It provides a way to get the current time, a way to wait a little while, +and a simple timer mechanism. These functions give you two ways of moving an +object every x milliseconds: + +

  • Use a timer callback function. This may have the bad effect that it runs in a seperate thread or uses alarm signals, but it's easier to implement.

  • Or you can get the number of milliseconds passed, and move the object if, for example, 30 ms passed.


PrevHomeNext
SDL_CondWaitTimeoutUpSDL_GetTicks
\ No newline at end of file diff --git a/contrib/sdk/sources/SDL-1.2.2/docs/html/video.html b/contrib/sdk/sources/SDL-1.2.2/docs/html/video.html new file mode 100644 index 000000000..f3b94b687 --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/docs/html/video.html @@ -0,0 +1,499 @@ +Video
SDL Library Documentation
PrevNext

Chapter 6. Video

Table of Contents
SDL_GetVideoSurface — returns a pointer to the current display surface
SDL_GetVideoInfo — returns a pointer to information about the video hardware
SDL_VideoDriverName — Obtain the name of the video driver
SDL_ListModes — Returns a pointer to an array of available screen dimensions for +the given format and video flags
SDL_VideoModeOK — Check to see if a particular video mode is supported.
SDL_SetVideoMode — Set up a video mode with the specified width, height and bits-per-pixel.
SDL_UpdateRect — Makes sure the given area is updated on the given screen.
SDL_UpdateRects — Makes sure the given list of rectangles is updated on the given screen.
SDL_Flip — Swaps screen buffers
SDL_SetColors — Sets a portion of the colormap for the given 8-bit surface.
SDL_SetPalette — Sets the colors in the palette of an 8-bit surface.
SDL_SetGamma — Sets the color gamma function for the display
SDL_GetGammaRamp — Gets the color gamma lookup tables for the display
SDL_SetGammaRamp — Sets the color gamma lookup tables for the display
SDL_MapRGB — Map a RGB color value to a pixel format.
SDL_MapRGBA — Map a RGBA color value to a pixel format.
SDL_GetRGB — Get RGB values from a pixel in the specified pixel format.
SDL_GetRGBA — Get RGBA values from a pixel in the specified pixel format.
SDL_CreateRGBSurface — Create an empty SDL_Surface
SDL_CreateRGBSurfaceFrom — Create an SDL_Surface from pixel data
SDL_FreeSurface — Frees (deletes) a SDL_Surface
SDL_LockSurface — Lock a surface for directly access.
SDL_UnlockSurface — Unlocks a previously locked surface.
SDL_LoadBMP — Load a Windows BMP file into an SDL_Surface.
SDL_SaveBMP — Save an SDL_Surface as a Windows BMP file.
SDL_SetColorKey — Sets the color key (transparent pixel) in a blittable surface and +RLE acceleration.
SDL_SetAlpha — Adjust the alpha properties of a surface
SDL_SetClipRect — Sets the clipping rectangle for a surface.
SDL_GetClipRect — Gets the clipping rectangle for a surface.
SDL_ConvertSurface — Converts a surface to the same format as another surface.
SDL_BlitSurface — This performs a fast blit from the source surface to the destination surface.
SDL_FillRect — This function performs a fast fill of the given rectangle with some color
SDL_DisplayFormat — Convert a surface to the display format
SDL_DisplayFormatAlpha — Convert a surface to the display format
SDL_WarpMouse — Set the position of the mouse cursor.
SDL_CreateCursor — Creates a new mouse cursor.
SDL_FreeCursor — Frees a cursor created with SDL_CreateCursor.
SDL_SetCursor — Set the currently active mouse cursor.
SDL_GetCursor — Get the currently active mouse cursor.
SDL_ShowCursor — Toggle whether or not the cursor is shown on the screen.
SDL_GL_LoadLibrary — Specify an OpenGL library
SDL_GL_GetProcAddress — Get the address of a GL function
SDL_GL_GetAttribute — Get the value of a special SDL/OpenGL attribute
SDL_GL_SetAttribute — Set a special SDL/OpenGL attribute
SDL_GL_SwapBuffers — Swap OpenGL framebuffers/Update Display
SDL_CreateYUVOverlay — Create a YUV video overlay
SDL_LockYUVOverlay — Lock an overlay
SDL_UnlockYUVOverlay — Unlock an overlay
SDL_DisplayYUVOverlay — Blit the overlay to the display
SDL_FreeYUVOverlay — Free a YUV video overlay
SDL_GLattr — SDL GL Attributes
SDL_Rect — Defines a rectangular area
SDL_Color — Format independent color description
SDL_Palette — Color palette for 8-bit pixel formats
SDL_PixelFormat — Stores surface format information
SDL_Surface — Graphical Surface Structure
SDL_VideoInfo — Video Target information
SDL_Overlay — YUV video overlay

SDL presents a very simple interface to the display framebuffer. The +framebuffer is represented as an offscreen surface to which you can write +directly. If you want the screen to show what you have written, call the update function which will +guarantee that the desired portion of the screen is updated.

Before you call any of the SDL video functions, you must first call +SDL_Init(SDL_INIT_VIDEO), which initializes the video +and events in the SDL library. Check the return code, which should be +0, to see if there were any errors in starting up.

If you use both sound and video in your application, you need to call +SDL_Init(SDL_INIT_AUDIO | SDL_INIT_VIDEO) before opening the +sound device, otherwise under Win32 DirectX, you won't be able to set +full-screen display modes.

After you have initialized the library, you can start up the video display in a +number of ways. The easiest way is to pick a common screen resolution and +depth and just initialize the video, checking for errors. You will probably +get what you want, but SDL may be emulating your requested mode and converting +the display on update. The best way is to +query, for the best +video mode closest to the desired one, and then +convert +your images to that pixel format.

SDL currently supports any bit depth >= 8 bits per pixel. 8 bpp formats are +considered 8-bit palettized modes, while 12, 15, 16, 24, and 32 bits per pixel +are considered "packed pixel" modes, meaning each pixel contains the RGB color +components packed in the bits of the pixel.

After you have initialized your video mode, you can take the surface that was +returned, and write to it like any other framebuffer, calling the update +routine as you go.

When you have finished your video access and are ready to quit your +application, you should call "SDL_Quit()" to shutdown the +video and events.


PrevHomeNext
SDL_WasInitUpSDL_GetVideoSurface
\ No newline at end of file diff --git a/contrib/sdk/sources/SDL-1.2.2/docs/html/wm.html b/contrib/sdk/sources/SDL-1.2.2/docs/html/wm.html new file mode 100644 index 000000000..95efdf37e --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/docs/html/wm.html @@ -0,0 +1,180 @@ +Window Management
SDL Library Documentation
PrevNext

Chapter 7. Window Management

Table of Contents
SDL_WM_SetCaption — Sets the window tile and icon name.
SDL_WM_GetCaption — Gets the window title and icon name.
SDL_WM_SetIcon — Sets the icon for the display window.
SDL_WM_IconifyWindow — Iconify/Minimise the window
SDL_WM_ToggleFullScreen — Toggles fullscreen mode
SDL_WM_GrabInput — Grabs mouse and keyboard input.

SDL provides a small set of window management functions which allow applications to change their title and toggle from windowed mode to fullscreen (if available)


PrevHomeNext
SDL_OverlayUpSDL_WM_SetCaption
\ No newline at end of file diff --git a/contrib/sdk/sources/SDL-1.2.2/docs/index.html b/contrib/sdk/sources/SDL-1.2.2/docs/index.html new file mode 100644 index 000000000..90d50ec41 --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/docs/index.html @@ -0,0 +1,121 @@ + +Introduction +
+

Introduction

This library is designed to make it easy to write games that run on Linux, +Win32 and BeOS using the various native high-performance media interfaces, +(for video, audio, etc) and presenting a single source-code level API to +your application. This is a fairly low level API, but using this, completely +portable applications can be written with a great deal of flexibility.

The library is loaded as a dynamically linked library on its native +platform, and is currently compiled natively for Linux, compiled for +Win32 using a Linux hosted GCC +cross-compilation +environment, and compiled using the EGCS C++ compiler under BeOS.

An introduction to SDL can be found online at: +http://www.libsdl.org/intro/

There are code examples on each of the main library pages, and there are +fully fleshed example C++ classes and programs in the examples archive, +available on the +SDL download page.

For an introduction to basic multi-media programming concepts, you might try +some of the following links: +

Enjoy!

    Sam Lantinga +<slouken@libsdl.org>

+

+


+

Table of Contents

+ +
diff --git a/contrib/sdk/sources/SDL-1.2.2/fire-1.0/Makefile b/contrib/sdk/sources/SDL-1.2.2/fire-1.0/Makefile new file mode 100644 index 000000000..d7e7c33b6 --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/fire-1.0/Makefile @@ -0,0 +1,6 @@ +OUTFILE = sdlfire +OBJS = fire.o +LIBS = -L../lib -lSDL +CFLAGS = -I../include -I. + +include $(MENUETDEV)/makefiles/Makefile_for_program diff --git a/contrib/sdk/sources/SDL-1.2.2/fire-1.0/README b/contrib/sdk/sources/SDL-1.2.2/fire-1.0/README new file mode 100644 index 000000000..d9a992bd9 --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/fire-1.0/README @@ -0,0 +1,5 @@ +Fire demo by David Ashley. +dash@xdr.com +http://www.xdr.com/dash + +See the start of the fire.c program for more details. diff --git a/contrib/sdk/sources/SDL-1.2.2/fire-1.0/Tupfile.lua b/contrib/sdk/sources/SDL-1.2.2/fire-1.0/Tupfile.lua new file mode 100644 index 000000000..60337b27b --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/fire-1.0/Tupfile.lua @@ -0,0 +1,11 @@ +if tup.getconfig("NO_GCC") ~= "" then return end +if tup.getconfig("HELPERDIR") == "" +then + if tup.getconfig("NO_NASM") ~= "" then return end -- required for SDL compilation + HELPERDIR = "../../../../../programs" +end +tup.include(HELPERDIR .. "/use_gcc.lua") +tup.include(HELPERDIR .. "/use_menuetlibc.lua") +tup.include(HELPERDIR .. "/use_sdl.lua") +compile_gcc{"fire.c"} +link_gcc("fire") diff --git a/contrib/sdk/sources/SDL-1.2.2/fire-1.0/fire.c b/contrib/sdk/sources/SDL-1.2.2/fire-1.0/fire.c new file mode 100644 index 000000000..3de69681b --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/fire-1.0/fire.c @@ -0,0 +1,508 @@ +/* Fireworks demo written by Dave Ashley */ +/* dash@xdr.com */ +/* http://www.xdr.com/dash */ +/* Sat Jun 13 02:46:09 PDT 1998 */ +/* This is my first attempt at an SDL program */ +/* See the SDL home page http://www.devolution.com/~slouken/projects/SDL/ */ + +#include +#include +#include +#include + +#include "SDL.h" + +#define XSIZE 640 +#define YSIZE 480 + +SDL_Surface *thescreen; +unsigned char *vmem1, *vmem2; +int mousex,mousey; +SDL_Color themap[256]; + +int scrlock() +{ + if(SDL_MUSTLOCK(thescreen)) + { + if ( SDL_LockSurface(thescreen) < 0 ) + { + SDL_printf("Couldn't lock display surface: %s\n", + SDL_GetError()); + return -1; + } + } + return 0; +} +void scrunlock(void) +{ + if(SDL_MUSTLOCK(thescreen)) + SDL_UnlockSurface(thescreen); + SDL_UpdateRect(thescreen, 0, 0, 0, 0); +} + +#define MOUSEFRAC 2 +#define MAXBLOBS 512 +#define BLOBFRAC 6 +#define BLOBGRAVITY 5 +#define THRESHOLD 20 +#define SMALLSIZE 3 +#define BIGSIZE 6 + +#define ABS(x) ((x)<0 ? -(x) : (x)) + +int explodenum; + +char sizes[]={2,3,4,5,8,5,4,3}; + + +struct blob { + struct blob *blobnext; + int blobx; + int bloby; + int blobdx; + int blobdy; + int bloblife; + int blobsize; +} *blobs,*freeblobs,*activeblobs; + + +unsigned char **mul640; +int oldmode; + +char sqrttab[]={ +0,1,1,1,2,2,2,2,2,3,3,3,3,3,3,3, +4,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5, +5,5,5,5,6,6,6,6,6,6,6,6,6,6,6,6, +6,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, +8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, +8,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9, +9,9,9,9,10,10,10,10,10,10,10,10,10,10,10,10, +10,10,10,10,10,10,10,10,10,11,11,11,11,11,11,11, +11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11, +12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12, +12,12,12,12,12,12,12,12,12,13,13,13,13,13,13,13, +13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13, +13,13,13,13,14,14,14,14,14,14,14,14,14,14,14,14, +14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14, +14,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15, +15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15 +}; + + +void nomem(void) +{ + SDL_printf("Not enough low memory!\n"); + SDL_Quit(); + exit(1); +} + + + +void fire(unsigned char *p1,unsigned char *p2,int pitch,char *map) +{ +int x,y; +unsigned char *p3, *p4; + + for(y=2;y10 && mousex10 && mouseyblobnext; + ablob->bloblife=(rand()&511)+256; + ablob->blobdx=dx; + ablob->blobdy=dy; + ablob->blobx=(256+(rand()&127))<bloby=2<blobnext=activeblobs; + ablob->blobsize=BIGSIZE; + activeblobs=ablob; +} +void moveblobs(void) +{ +struct blob **lastblob,*ablob; +int x,y; + + lastblob=&activeblobs; + while(ablob=*lastblob) + { + x=ablob->blobx>>BLOBFRAC; + y=ablob->bloby>>BLOBFRAC; + if(!--ablob->bloblife || y<0 || x<10 || x>XSIZE-10) + { + *lastblob=ablob->blobnext; + ablob->blobnext=freeblobs; + freeblobs=ablob; + continue; + } + ablob->blobx+=ablob->blobdx; + ablob->bloby+=ablob->blobdy; + ablob->blobdy-=BLOBGRAVITY; + lastblob=&ablob->blobnext; + } +} +void putblobs(void) +{ +struct blob *ablob,*ablob2,*temp; +int x,y,dy; +int i,size; +long x2,y2,vel; + + ablob=activeblobs; + activeblobs=0; + while(ablob) + { + dy=ablob->blobdy; + if(ablob->blobsize!=SMALLSIZE && (dy>-THRESHOLD && dyblobnext; + ablob2->blobx=ablob->blobx; + ablob2->bloby=ablob->bloby; + for(;;) + { + x2=(rand()&511)-256; + y2=(rand()&511)-256; + vel=x2*x2+y2*y2; + if(vel>0x3000 && vel<0x10000L) break; + } + ablob2->blobdx=ablob->blobdx+x2; + ablob2->blobdy=ablob->blobdy+y2; + ablob2->bloblife=16+(rand()&31); + ablob2->blobsize=SMALLSIZE; + ablob2->blobnext=activeblobs; + activeblobs=ablob2; + ablob->bloblife=1; + } + } + x=ablob->blobx>>BLOBFRAC; + y=ablob->bloby>>BLOBFRAC; + size=ablob->blobsize; + if(size==BIGSIZE && ablob->blobdy>0 && ablob->blobdy<200) + size=sizes[ablob->bloblife&7]; + if(x>10 && x10 && yblobnext; + temp->blobnext=activeblobs; + activeblobs=temp; + } +} + + + +#define RATE 1 +void normal(char *map) +{ +int i,j; + for(i=0;i<8192;i++) + { + j=i/9; + map[i]=j<256 ? (j>=RATE ? j-RATE : 0) : 255; + } +} +void bright(char *map) +{ +int i; + for(i=0;i<8192;i++) map[i]=i>>3<255 ? (i>>3) : 255; +} + +void updatemap(void) +{ + SDL_SetColors(thescreen, themap, 0, 256); +} + + +void loadcolor(int n,int r,int g,int b) +{ + themap[n].r=r<<2; + themap[n].g=g<<2; + themap[n].b=b<<2; +} + + +void loadcolors(unsigned int which) +{ +int i,j; +int r,g,b; + + which%=11; + for(i=0;i<256;i++) + { + switch(which) + { + case 0: + if(i<64) loadcolor(i,0,0,0); + else if(i<128) loadcolor(i,i-64,0,0); + else if(i<192) loadcolor(i,63,i-128,0); + else loadcolor(i,63,63,i-192); + break; + case 1: + if(i<64) loadcolor(i,0,0,0); + else if(i<128) loadcolor(i,0,0,i-64); + else loadcolor(i,(i-128)>>1,(i-128)>>1,63); + break; + case 2: + loadcolor(i,i>>2,i>>2,i>>2); + break; + case 3: + r=rand()&0x3f; + g=rand()&0x3f; + b=rand()&0x3f; + loadcolor(i,r*i>>8,g*i>>8,b*i>>8); + break; + case 4: + loadcolor(i,i>>2,0,0); + break; + case 5: + loadcolor(i,0,i>>2,0); + break; + case 6: + loadcolor(i,0,0,i>>2); + break; + case 7: + j=i&15; + if(i&16) j=15-j; + j=(i>>2)*j/16; + loadcolor(i,j,j,j); + break; + case 8: + j=0; + if(i>8 && i<128) j=63; + loadcolor(i,j,j,j); + break; + case 9: + j=31-(i&31)<<1; + r=i&32 ? j : 0; + g=i&64 ? j : 0; + b=i&128 ? j : 0; + loadcolor(i,r,g,b); + break; + case 10: + j=(i&15)<<2; + if(i&16) j=63-j; + r=i&32 ? j : 0; + g=i&64 ? j : 0; + b=i&128 ? j : 0; + loadcolor(i,r,g,b); + break; + } + } + updatemap(); +} + +int main(int argc, char *argv[]) +{ +int i,k; +char *remap,*remap2; +unsigned char *p1, *p2; +long frames; +int flash; +int whichmap; +int key; +int ispaused; +unsigned long videoflags; +int done; +int now; +SDL_Event event; +long starttime; +int buttonstate; + + srand(time(NULL)); + if ( SDL_Init(SDL_INIT_VIDEO) < 0 ) + { + SDL_printf("Couldn't initialize SDL: %s\n",SDL_GetError()); + exit(1); + } + videoflags = SDL_SWSURFACE; + + thescreen = SDL_SetVideoMode(XSIZE, YSIZE, 8, videoflags); + if ( thescreen == NULL ) + { + SDL_printf("Couldn't set display mode: %s\n", + SDL_GetError()); + SDL_Quit(); + exit(5); + } + + vmem1=NULL; + vmem2=malloc(XSIZE*YSIZE); + if(!vmem2) nomem(); + mul640=malloc(YSIZE*sizeof(char *)); + if(!mul640) nomem(); + remap=malloc(16384); + if(!remap) nomem(); + remap2=malloc(16384); + if(!remap2) nomem(); + blobs=malloc(MAXBLOBS*sizeof(struct blob)); + if(!blobs) nomem(); + + SDL_printf("Fire demo by David Ashley (dash@xdr.com)"); + SDL_printf("1 = Change color map"); + SDL_printf("2 = Randomly change color map"); + SDL_printf("p = Pause"); + SDL_printf("spc = Fire"); + SDL_printf("esc = Exit"); + SDL_printf("Left mouse button = paint"); + SDL_printf("Right mouse button, CR = ignite atmosphere"); + + freeblobs=activeblobs=0; + for(i=0;ipixels ) + { + p1=vmem1=thescreen->pixels; + for (i=0;ipitch+vmem1; + memset(p1,0,XSIZE); + p1+=thescreen->pitch; + } + } + if(!ispaused) + { + now++; + if(!flash) + { + if(explodenum>96 && explodenum<160 && !(rand()&511) || (buttonstate&8)) + flash=60; + } else --flash; + explodenum=(now>>4)+1;if(explodenum==320) now=0; + if(explodenum>256) explodenum=256; + if(!(rand()&31)) + addblob(); + moveblobs(); + putblobs(); + if(buttonstate&2) trydisk(); + p1=vmem1; + p2=vmem2; + k=thescreen->pitch; + for(i=0;i + +#include "SDL_main.h" +#include "SDL_types.h" +#include "SDL_error.h" +#include "SDL_rwops.h" +#include "SDL_byteorder.h" + +#include "begin_code.h" +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +extern "C" { +#endif + +/* The calculated values in this structure are calculated by SDL_OpenAudio() */ +typedef struct { + int freq; /* DSP frequency -- samples per second */ + Uint16 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 samples */ + Uint16 padding; /* Necessary for some compile environments */ + Uint32 size; /* Audio buffer size in bytes (calculated) */ + /* This function is called when the audio device needs more data. + 'stream' is a pointer to the audio data buffer + 'len' is the length of that buffer in bytes. + Once the callback returns, the buffer will no longer be valid. + Stereo samples are stored in a LRLRLR ordering. + */ + void (*callback)(void *userdata, Uint8 *stream, int len); + void *userdata; +} SDL_AudioSpec; + +/* 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 + +/* Native audio byte ordering */ +#if SDL_BYTEORDER == SDL_LIL_ENDIAN +#define AUDIO_U16SYS AUDIO_U16LSB +#define AUDIO_S16SYS AUDIO_S16LSB +#else +#define AUDIO_U16SYS AUDIO_U16MSB +#define AUDIO_S16SYS AUDIO_S16MSB +#endif + + +/* A structure to hold a set of audio conversion filters and buffers */ +typedef struct SDL_AudioCVT { + int needed; /* Set to 1 if conversion possible */ + Uint16 src_format; /* Source audio format */ + Uint16 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 */ + void (*filters[10])(struct SDL_AudioCVT *cvt, Uint16 format); + int filter_index; /* Current audio conversion function */ +} SDL_AudioCVT; + + +/* Function prototypes */ + +/* 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 SDL_AudioInit(const char *driver_name); +extern DECLSPEC void SDL_AudioQuit(void); + +/* This function fills the given character buffer with the name of the + * current audio driver, and returns a pointer to it if the audio driver has + * been initialized. It returns NULL if no driver has been initialized. + */ +extern DECLSPEC char *SDL_AudioDriverName(char *namebuf, int maxlen); + +/* + * This function opens the audio device with the desired parameters, and + * returns 0 if successful, placing the actual hardware parameters in the + * structure pointed to by 'obtained'. If 'obtained' is NULL, the audio + * data passed to the callback function will be guaranteed to be in the + * requested format, and will be automatically converted to the hardware + * audio format if necessary. This function returns -1 if it failed + * to open the audio device, or couldn't set up the audio thread. + * + * When filling in the desired audio spec structure, + * 'desired->freq' should be the desired audio frequency in samples-per-second. + * 'desired->format' should be the desired audio format. + * 'desired->samples' is the desired size of the audio buffer, in samples. + * This number should be a power of two, and may be adjusted by the audio + * driver to a value more suitable for the hardware. Good values seem to + * range between 512 and 8096 inclusive, depending on the application and + * CPU speed. Smaller values yield faster response time, but can lead + * to underflow if the application is doing heavy processing and cannot + * fill the audio buffer in time. A stereo sample consists of both right + * and left channels in LR ordering. + * Note that the number of samples is directly related to time by the + * following formula: ms = (samples*1000)/freq + * 'desired->size' is the size in bytes of the audio buffer, and is + * calculated by SDL_OpenAudio(). + * 'desired->silence' is the value used to set the buffer to silence, + * and is calculated by SDL_OpenAudio(). + * 'desired->callback' should be set to a function that will be called + * when the audio device is ready for more data. It is passed a pointer + * to the audio buffer, and the length in bytes of the audio buffer. + * This function usually runs in a separate thread, and so you should + * protect data structures that it accesses by calling SDL_LockAudio() + * and SDL_UnlockAudio() in your code. + * 'desired->userdata' is passed as the first parameter to your callback + * function. + * + * The audio device starts out playing silence when it's opened, and should + * be enabled for playing by calling SDL_PauseAudio(0) when you are ready + * for your audio callback function to be called. Since the audio driver + * may modify the requested size of the audio buffer, you should allocate + * any local mixing buffers after you open the audio device. + */ +extern DECLSPEC int SDL_OpenAudio(SDL_AudioSpec *desired, SDL_AudioSpec *obtained); + +/* + * Get the current audio state: + */ +typedef enum { + SDL_AUDIO_STOPPED = 0, + SDL_AUDIO_PLAYING, + SDL_AUDIO_PAUSED +} SDL_audiostatus; +extern DECLSPEC SDL_audiostatus SDL_GetAudioStatus(void); + +/* + * This function pauses and unpauses the audio callback processing. + * It should be called with a parameter of 0 after opening the audio + * device to start playing sound. This is so you can safely initialize + * data for your callback function after opening the audio device. + * Silence will be written to the audio device during the pause. + */ +extern DECLSPEC void SDL_PauseAudio(int pause_on); + +/* + * This function loads a WAVE from the data source, automatically freeing + * that source if 'freesrc' is non-zero. For example, to load a WAVE file, + * you could do: + * SDL_LoadWAV_RW(SDL_RWFromFile("sample.wav", "rb"), 1, ...); + * + * If this function succeeds, it returns the given SDL_AudioSpec, + * filled with the audio data format of the wave data, and sets + * 'audio_buf' to a malloc()'d buffer containing the audio data, + * and sets 'audio_len' to the length of that audio buffer, in bytes. + * You need to free the audio buffer with SDL_FreeWAV() when you are + * done with it. + * + * This function returns NULL and sets the SDL error message if the + * wave file cannot be opened, uses an unknown data format, or is + * corrupt. Currently raw and MS-ADPCM WAVE files are supported. + */ +extern DECLSPEC SDL_AudioSpec *SDL_LoadWAV_RW(SDL_RWops *src, int freesrc, + SDL_AudioSpec *spec, Uint8 **audio_buf, Uint32 *audio_len); + +/* Compatibility convenience function -- loads a WAV from a file */ +#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 SDL_FreeWAV(Uint8 *audio_buf); + +/* + * This function takes a source format and rate and a destination format + * and rate, and initializes the 'cvt' structure with information needed + * by SDL_ConvertAudio() to convert a buffer of audio data from one format + * to the other. + * This function returns 0, or -1 if there was an error. + */ +extern DECLSPEC int SDL_BuildAudioCVT(SDL_AudioCVT *cvt, + Uint16 src_format, Uint8 src_channels, int src_rate, + Uint16 dst_format, Uint8 dst_channels, int dst_rate); + +/* Once you have initialized the 'cvt' structure using SDL_BuildAudioCVT(), + * created an audio buffer cvt->buf, and filled it with cvt->len bytes of + * audio data in the source format, this function will convert it in-place + * to the desired format. + * The data conversion may expand the size of the audio data, so the buffer + * cvt->buf should be allocated after the cvt structure is initialized by + * SDL_BuildAudioCVT(), and should be cvt->len*cvt->len_mult bytes long. + */ +extern DECLSPEC int SDL_ConvertAudio(SDL_AudioCVT *cvt); + +/* + * 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. + */ +#define SDL_MIX_MAXVOLUME 128 +extern DECLSPEC void SDL_MixAudio(Uint8 *dst, const Uint8 *src, Uint32 len, int volume); + +/* + * The lock manipulated by these functions protects the callback function. + * During a LockAudio/UnlockAudio pair, you can be guaranteed that the + * callback function is not running. Do not call these from the callback + * function or you will cause deadlock. + */ +extern DECLSPEC void SDL_LockAudio(void); +extern DECLSPEC void SDL_UnlockAudio(void); + +/* + * This function shuts down audio processing and closes the audio device. + */ +extern DECLSPEC void SDL_CloseAudio(void); + + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +} +#endif +#include "close_code.h" + +#endif /* _SDL_audio_h */ diff --git a/contrib/sdk/sources/SDL-1.2.2/include/SDL_byteorder.h b/contrib/sdk/sources/SDL-1.2.2/include/SDL_byteorder.h new file mode 100644 index 000000000..68791516d --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/include/SDL_byteorder.h @@ -0,0 +1,52 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997, 1998, 1999, 2000, 2001 Sam Lantinga + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the Free + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + Sam Lantinga + slouken@devolution.com +*/ + +#ifdef SAVE_RCSID +static char rcsid = + "@(#) $Id: SDL_byteorder.h,v 1.3 2001/05/10 20:25:51 hercules Exp $"; +#endif + +/* Macros for determining the byte-order of this platform */ + +#ifndef _SDL_byteorder_h +#define _SDL_byteorder_h + +/* The two types of endianness */ +#define SDL_LIL_ENDIAN 1234 +#define SDL_BIG_ENDIAN 4321 + +/* Pardon the mess, I'm trying to determine the endianness of this host. + I'm doing it by preprocessor defines rather than some sort of configure + script so that application code can use this too. The "right" way would + be to dynamically generate this file on install, but that's a lot of work. + */ +#if defined(__i386__) || defined(__ia64__) || defined(WIN32UNDEFINED) || \ + (defined(__alpha__) || defined(__alpha)) || \ + defined(__arm__) || \ + (defined(__mips__) && defined(__MIPSEL__)) || \ + defined(__LITTLE_ENDIAN__) +#define SDL_BYTEORDER SDL_LIL_ENDIAN +#else +#define SDL_BYTEORDER SDL_BIG_ENDIAN +#endif + +#endif /* _SDL_byteorder_h */ diff --git a/contrib/sdk/sources/SDL-1.2.2/include/SDL_byteorder.h.BAK b/contrib/sdk/sources/SDL-1.2.2/include/SDL_byteorder.h.BAK new file mode 100644 index 000000000..7e8c86be0 --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/include/SDL_byteorder.h.BAK @@ -0,0 +1,52 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997, 1998, 1999, 2000, 2001 Sam Lantinga + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the Free + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + Sam Lantinga + slouken@devolution.com +*/ + +#ifdef SAVE_RCSID +static char rcsid = + "@(#) $Id: SDL_byteorder.h,v 1.3 2001/05/10 20:25:51 hercules Exp $"; +#endif + +/* Macros for determining the byte-order of this platform */ + +#ifndef _SDL_byteorder_h +#define _SDL_byteorder_h + +/* The two types of endianness */ +#define SDL_LIL_ENDIAN 1234 +#define SDL_BIG_ENDIAN 4321 + +/* Pardon the mess, I'm trying to determine the endianness of this host. + I'm doing it by preprocessor defines rather than some sort of configure + script so that application code can use this too. The "right" way would + be to dynamically generate this file on install, but that's a lot of work. + */ +#if defined(__i386__) || defined(__ia64__) || defined(WIN32) || \ + (defined(__alpha__) || defined(__alpha)) || \ + defined(__arm__) || \ + (defined(__mips__) && defined(__MIPSEL__)) || \ + defined(__LITTLE_ENDIAN__) +#define SDL_BYTEORDER SDL_LIL_ENDIAN +#else +#define SDL_BYTEORDER SDL_BIG_ENDIAN +#endif + +#endif /* _SDL_byteorder_h */ diff --git a/contrib/sdk/sources/SDL-1.2.2/include/SDL_cdrom.h b/contrib/sdk/sources/SDL-1.2.2/include/SDL_cdrom.h new file mode 100644 index 000000000..ff4939042 --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/include/SDL_cdrom.h @@ -0,0 +1,175 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997, 1998, 1999, 2000, 2001 Sam Lantinga + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the Free + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + Sam Lantinga + slouken@devolution.com +*/ + +#ifdef SAVE_RCSID +static char rcsid = + "@(#) $Id: SDL_cdrom.h,v 1.2 2001/04/26 16:50:17 hercules Exp $"; +#endif + +/* This is the CD-audio control API for Simple DirectMedia Layer */ + +#ifndef _SDL_cdrom_h +#define _SDL_cdrom_h + +#include "SDL_types.h" + +#include "begin_code.h" +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +extern "C" { +#endif + +/* In order to use these functions, SDL_Init() must have been called + with the SDL_INIT_CDROM flag. This causes SDL to scan the system + for CD-ROM drives, and load appropriate drivers. +*/ + +/* The maximum number of CD-ROM tracks on a disk */ +#define SDL_MAX_TRACKS 99 + +/* The types of CD-ROM track possible */ +#define SDL_AUDIO_TRACK 0x00 +#define SDL_DATA_TRACK 0x04 + +/* The possible states which a CD-ROM drive can be in. */ +typedef enum { + CD_TRAYEMPTY, + CD_STOPPED, + CD_PLAYING, + CD_PAUSED, + CD_ERROR = -1 +} CDstatus; + +/* Given a status, returns true if there's a disk in the drive */ +#define CD_INDRIVE(status) ((int)status > 0) + +typedef struct { + Uint8 id; /* Track number */ + Uint8 type; /* Data or audio track */ + Uint16 unused; + Uint32 length; /* Length, in frames, of this track */ + Uint32 offset; /* Offset, in frames, from start of disk */ +} SDL_CDtrack; + +/* This structure is only current as of the last call to SDL_CDStatus() */ +typedef struct SDL_CD { + int id; /* Private drive identifier */ + CDstatus status; /* Current drive status */ + + /* The rest of this structure is only valid if there's a CD in drive */ + int numtracks; /* Number of tracks on disk */ + int cur_track; /* Current track position */ + int cur_frame; /* Current frame offset within current track */ + SDL_CDtrack track[SDL_MAX_TRACKS+1]; +} SDL_CD; + +/* Conversion functions from frames to Minute/Second/Frames and vice versa */ +#define CD_FPS 75 +#define FRAMES_TO_MSF(f, M,S,F) { \ + int value = f; \ + *(F) = value%CD_FPS; \ + value /= CD_FPS; \ + *(S) = value%60; \ + value /= 60; \ + *(M) = value; \ +} +#define MSF_TO_FRAMES(M, S, F) ((M)*60*CD_FPS+(S)*CD_FPS+(F)) + +/* CD-audio API functions: */ + +/* Returns the number of CD-ROM drives on the system, or -1 if + SDL_Init() has not been called with the SDL_INIT_CDROM flag. + */ +extern DECLSPEC int SDL_CDNumDrives(void); + +/* Returns a human-readable, system-dependent identifier for the CD-ROM. + Example: + "/dev/cdrom" + "E:" + "/dev/disk/ide/1/master" +*/ +extern DECLSPEC const char * SDL_CDName(int drive); + +/* Opens a CD-ROM drive for access. It returns a drive handle on success, + or NULL if the drive was invalid or busy. This newly opened CD-ROM + becomes the default CD used when other CD functions are passed a NULL + CD-ROM handle. + Drives are numbered starting with 0. Drive 0 is the system default CD-ROM. +*/ +extern DECLSPEC SDL_CD * SDL_CDOpen(int drive); + +/* This function returns the current status of the given drive. + If the drive has a CD in it, the table of contents of the CD and current + play position of the CD will be stored in the SDL_CD structure. +*/ +extern DECLSPEC CDstatus SDL_CDStatus(SDL_CD *cdrom); + +/* Play the given CD starting at 'start_track' and 'start_frame' for 'ntracks' + tracks and 'nframes' frames. If both 'ntrack' and 'nframe' are 0, play + until the end of the CD. This function will skip data tracks. + This function should only be called after calling SDL_CDStatus() to + get track information about the CD. + For example: + // Play entire CD: + if ( CD_INDRIVE(SDL_CDStatus(cdrom)) ) + SDL_CDPlayTracks(cdrom, 0, 0, 0, 0); + // Play last track: + if ( CD_INDRIVE(SDL_CDStatus(cdrom)) ) { + SDL_CDPlayTracks(cdrom, cdrom->numtracks-1, 0, 0, 0); + } + // Play first and second track and 10 seconds of third track: + if ( CD_INDRIVE(SDL_CDStatus(cdrom)) ) + SDL_CDPlayTracks(cdrom, 0, 0, 2, 10); + + This function returns 0, or -1 if there was an error. +*/ +extern DECLSPEC int SDL_CDPlayTracks(SDL_CD *cdrom, + int start_track, int start_frame, int ntracks, int nframes); + +/* Play the given CD starting at 'start' frame for 'length' frames. + It returns 0, or -1 if there was an error. +*/ +extern DECLSPEC int SDL_CDPlay(SDL_CD *cdrom, int start, int length); + +/* Pause play -- returns 0, or -1 on error */ +extern DECLSPEC int SDL_CDPause(SDL_CD *cdrom); + +/* Resume play -- returns 0, or -1 on error */ +extern DECLSPEC int SDL_CDResume(SDL_CD *cdrom); + +/* Stop play -- returns 0, or -1 on error */ +extern DECLSPEC int SDL_CDStop(SDL_CD *cdrom); + +/* Eject CD-ROM -- returns 0, or -1 on error */ +extern DECLSPEC int SDL_CDEject(SDL_CD *cdrom); + +/* Closes the handle for the CD-ROM drive */ +extern DECLSPEC void SDL_CDClose(SDL_CD *cdrom); + + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +} +#endif +#include "close_code.h" + +#endif /* _SDL_video_h */ diff --git a/contrib/sdk/sources/SDL-1.2.2/include/SDL_copying.h b/contrib/sdk/sources/SDL-1.2.2/include/SDL_copying.h new file mode 100644 index 000000000..b7259869d --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/include/SDL_copying.h @@ -0,0 +1,27 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997, 1998, 1999, 2000, 2001 Sam Lantinga + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the Free + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + Sam Lantinga + slouken@devolution.com +*/ + +#ifdef SAVE_RCSID +static char rcsid = + "@(#) $Id: SDL_copying.h,v 1.2 2001/04/26 16:50:17 hercules Exp $"; +#endif + diff --git a/contrib/sdk/sources/SDL-1.2.2/include/SDL_endian.h b/contrib/sdk/sources/SDL-1.2.2/include/SDL_endian.h new file mode 100644 index 000000000..8302534d3 --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/include/SDL_endian.h @@ -0,0 +1,138 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997, 1998, 1999, 2000, 2001 Sam Lantinga + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the Free + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + Sam Lantinga + slouken@devolution.com +*/ + +#ifdef SAVE_RCSID +static char rcsid = + "@(#) $Id: SDL_endian.h,v 1.2 2001/04/26 16:50:17 hercules Exp $"; +#endif + +/* Functions for reading and writing endian-specific values */ + +#ifndef _SDL_endian_h +#define _SDL_endian_h + +/* These functions read and write data of the specified endianness, + dynamically translating to the host machine endianness. + + e.g.: If you want to read a 16 bit value on big-endian machine from + an open file containing little endian values, you would use: + value = SDL_ReadLE16(rp); + Note that the read/write functions use SDL_RWops pointers + instead of FILE pointers. This allows you to read and write + endian values from large chunks of memory as well as files + and other data sources. +*/ + +#include + +#include "SDL_types.h" +#include "SDL_rwops.h" +#include "SDL_byteorder.h" + +#include "begin_code.h" +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +extern "C" { +#endif + +/* Use inline functions for compilers that support them, and static + functions for those that do not. Because these functions become + static for compilers that do not support inline functions, this + header should only be included in files that actually use them. +*/ +#ifndef SDL_Swap16 +static __inline__ Uint16 SDL_Swap16(Uint16 D) { + return((D<<8)|(D>>8)); +} +#endif +#ifndef SDL_Swap32 +static __inline__ Uint32 SDL_Swap32(Uint32 D) { + return((D<<24)|((D<<8)&0x00FF0000)|((D>>8)&0x0000FF00)|(D>>24)); +} +#endif +#ifdef SDL_HAS_64BIT_TYPE +#ifndef SDL_Swap64 +static __inline__ Uint64 SDL_Swap64(Uint64 val) { + Uint32 hi, lo; + + /* Separate into high and low 32-bit values and swap them */ + lo = (Uint32)(val&0xFFFFFFFF); + val >>= 32; + hi = (Uint32)(val&0xFFFFFFFF); + val = SDL_Swap32(lo); + val <<= 32; + val |= SDL_Swap32(hi); + return(val); +} +#endif +#else +#ifndef SDL_Swap64 +/* This is mainly to keep compilers from complaining in SDL code. + If there is no real 64-bit datatype, then compilers will complain about + the fake 64-bit datatype that SDL provides when it compiles user code. +*/ +#define SDL_Swap64(X) (X) +#endif +#endif /* SDL_HAS_64BIT_TYPE */ + + +/* 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_SwapBE16(X) SDL_Swap16(X) +#define SDL_SwapBE32(X) SDL_Swap32(X) +#define SDL_SwapBE64(X) SDL_Swap64(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_SwapBE16(X) (X) +#define SDL_SwapBE32(X) (X) +#define SDL_SwapBE64(X) (X) +#endif + +/* Read an item of the specified endianness and return in native format */ +extern DECLSPEC Uint16 SDL_ReadLE16(SDL_RWops *src); +extern DECLSPEC Uint16 SDL_ReadBE16(SDL_RWops *src); +extern DECLSPEC Uint32 SDL_ReadLE32(SDL_RWops *src); +extern DECLSPEC Uint32 SDL_ReadBE32(SDL_RWops *src); +extern DECLSPEC Uint64 SDL_ReadLE64(SDL_RWops *src); +extern DECLSPEC Uint64 SDL_ReadBE64(SDL_RWops *src); + +/* Write an item of native format to the specified endianness */ +extern DECLSPEC int SDL_WriteLE16(SDL_RWops *dst, Uint16 value); +extern DECLSPEC int SDL_WriteBE16(SDL_RWops *dst, Uint16 value); +extern DECLSPEC int SDL_WriteLE32(SDL_RWops *dst, Uint32 value); +extern DECLSPEC int SDL_WriteBE32(SDL_RWops *dst, Uint32 value); +extern DECLSPEC int SDL_WriteLE64(SDL_RWops *dst, Uint64 value); +extern DECLSPEC int SDL_WriteBE64(SDL_RWops *dst, Uint64 value); + + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +} +#endif +#include "close_code.h" + +#endif /* _SDL_endian_h */ diff --git a/contrib/sdk/sources/SDL-1.2.2/include/SDL_error.h b/contrib/sdk/sources/SDL-1.2.2/include/SDL_error.h new file mode 100644 index 000000000..a367008dc --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/include/SDL_error.h @@ -0,0 +1,62 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997, 1998, 1999, 2000, 2001 Sam Lantinga + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the Free + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + Sam Lantinga + slouken@devolution.com +*/ + +#ifdef SAVE_RCSID +static char rcsid = + "@(#) $Id: SDL_error.h,v 1.2 2001/04/26 16:50:17 hercules Exp $"; +#endif + +/* Simple error message routines for SDL */ + +#ifndef _SDL_error_h +#define _SDL_error_h + +#include "begin_code.h" +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +extern "C" { +#endif + +/* Public functions */ +extern DECLSPEC void SDL_SetError(const char *fmt, ...); +extern DECLSPEC char * SDL_GetError(void); +extern DECLSPEC void SDL_ClearError(void); + +/* Private error message function - used internally */ +#define SDL_OutOfMemory() SDL_Error(SDL_ENOMEM) +typedef enum { + SDL_ENOMEM, + SDL_EFREAD, + SDL_EFWRITE, + SDL_EFSEEK, + SDL_LASTERROR +} SDL_errorcode; +extern void SDL_Error(SDL_errorcode code); + + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +} +#endif +#include "close_code.h" + +#endif /* _SDL_error_h */ diff --git a/contrib/sdk/sources/SDL-1.2.2/include/SDL_events.h b/contrib/sdk/sources/SDL-1.2.2/include/SDL_events.h new file mode 100644 index 000000000..b46da70cd --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/include/SDL_events.h @@ -0,0 +1,335 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997, 1998, 1999, 2000, 2001 Sam Lantinga + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the Free + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + Sam Lantinga + slouken@devolution.com +*/ + +#ifdef SAVE_RCSID +static char rcsid = + "@(#) $Id: SDL_events.h,v 1.2 2001/04/26 16:50:17 hercules Exp $"; +#endif + +/* Include file for SDL event handling */ + +#ifndef _SDL_events_h +#define _SDL_events_h + +#include "SDL_types.h" +#include "SDL_active.h" +#include "SDL_keyboard.h" +#include "SDL_mouse.h" +#include "SDL_joystick.h" +#include "SDL_quit.h" + +#include "begin_code.h" +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +extern "C" { +#endif + +/* Event enumerations */ +enum { SDL_NOEVENT = 0, /* Unused (do not remove) */ + SDL_ACTIVEEVENT, /* Application loses/gains visibility */ + SDL_KEYDOWN, /* Keys pressed */ + SDL_KEYUP, /* Keys released */ + SDL_MOUSEMOTION, /* Mouse moved */ + SDL_MOUSEBUTTONDOWN, /* Mouse button pressed */ + SDL_MOUSEBUTTONUP, /* Mouse button released */ + SDL_JOYAXISMOTION, /* 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_QUIT, /* User-requested quit */ + SDL_SYSWMEVENT, /* System specific event */ + SDL_EVENT_RESERVEDA, /* Reserved for future use.. */ + SDL_EVENT_RESERVEDB, /* Reserved for future use.. */ + SDL_VIDEORESIZE, /* User resized video mode */ + SDL_VIDEOEXPOSE, /* Screen needs to be redrawn */ + SDL_EVENT_RESERVED2, /* Reserved for future use.. */ + SDL_EVENT_RESERVED3, /* Reserved for future use.. */ + SDL_EVENT_RESERVED4, /* Reserved for future use.. */ + SDL_EVENT_RESERVED5, /* Reserved for future use.. */ + SDL_EVENT_RESERVED6, /* Reserved for future use.. */ + SDL_EVENT_RESERVED7, /* Reserved for future use.. */ + /* Events SDL_USEREVENT through SDL_MAXEVENTS-1 are for your use */ + SDL_USEREVENT = 24, + SDL_PAINT_WND = 31, + /* This last event is only for bounding internal arrays + It is the number of bits in the event mask datatype -- Uint32 + */ + SDL_NUMEVENTS = 32 +}; + +/* Predefined event masks */ +#define SDL_EVENTMASK(X) (1<<(X)) +enum { + SDL_ACTIVEEVENTMASK = SDL_EVENTMASK(SDL_ACTIVEEVENT), + SDL_KEYDOWNMASK = SDL_EVENTMASK(SDL_KEYDOWN), + SDL_KEYUPMASK = SDL_EVENTMASK(SDL_KEYUP), + SDL_MOUSEMOTIONMASK = SDL_EVENTMASK(SDL_MOUSEMOTION), + SDL_MOUSEBUTTONDOWNMASK = SDL_EVENTMASK(SDL_MOUSEBUTTONDOWN), + SDL_MOUSEBUTTONUPMASK = SDL_EVENTMASK(SDL_MOUSEBUTTONUP), + SDL_MOUSEEVENTMASK = SDL_EVENTMASK(SDL_MOUSEMOTION)| + SDL_EVENTMASK(SDL_MOUSEBUTTONDOWN)| + SDL_EVENTMASK(SDL_MOUSEBUTTONUP), + SDL_JOYAXISMOTIONMASK = SDL_EVENTMASK(SDL_JOYAXISMOTION), + SDL_JOYBALLMOTIONMASK = SDL_EVENTMASK(SDL_JOYBALLMOTION), + SDL_JOYHATMOTIONMASK = SDL_EVENTMASK(SDL_JOYHATMOTION), + SDL_JOYBUTTONDOWNMASK = SDL_EVENTMASK(SDL_JOYBUTTONDOWN), + SDL_JOYBUTTONUPMASK = SDL_EVENTMASK(SDL_JOYBUTTONUP), + SDL_JOYEVENTMASK = SDL_EVENTMASK(SDL_JOYAXISMOTION)| + SDL_EVENTMASK(SDL_JOYBALLMOTION)| + SDL_EVENTMASK(SDL_JOYHATMOTION)| + SDL_EVENTMASK(SDL_JOYBUTTONDOWN)| + SDL_EVENTMASK(SDL_JOYBUTTONUP), + SDL_VIDEORESIZEMASK = SDL_EVENTMASK(SDL_VIDEORESIZE), + SDL_VIDEOEXPOSEMASK = SDL_EVENTMASK(SDL_VIDEOEXPOSE), + SDL_QUITMASK = SDL_EVENTMASK(SDL_QUIT), + SDL_SYSWMEVENTMASK = SDL_EVENTMASK(SDL_SYSWMEVENT) +}; +#define SDL_ALLEVENTS 0xFFFFFFFF + +/* Application visibility event structure */ +typedef struct { + Uint8 type; /* SDL_ACTIVEEVENT */ + Uint8 gain; /* Whether given states were gained or lost (1/0) */ + Uint8 state; /* A mask of the focus states */ +} SDL_ActiveEvent; + +/* Keyboard event structure */ +typedef struct { + Uint8 type; /* SDL_KEYDOWN or SDL_KEYUP */ + Uint8 which; /* The keyboard device index */ + Uint8 state; /* SDL_PRESSED or SDL_RELEASED */ + SDL_keysym keysym; +} SDL_KeyboardEvent; + +/* Mouse motion event structure */ +typedef struct { + Uint8 type; /* SDL_MOUSEMOTION */ + Uint8 which; /* The mouse device index */ + Uint8 state; /* The current button state */ + Uint16 x, y; /* The X/Y coordinates of the mouse */ + Sint16 xrel; /* The relative motion in the X direction */ + Sint16 yrel; /* The relative motion in the Y direction */ +} SDL_MouseMotionEvent; + +/* Mouse button event structure */ +typedef struct { + Uint8 type; /* SDL_MOUSEBUTTONDOWN or SDL_MOUSEBUTTONUP */ + Uint8 which; /* The mouse device index */ + Uint8 button; /* The mouse button index */ + Uint8 state; /* SDL_PRESSED or SDL_RELEASED */ + Uint16 x, y; /* The X/Y coordinates of the mouse at press time */ +} SDL_MouseButtonEvent; + +/* Joystick axis motion event structure */ +typedef struct { + Uint8 type; /* SDL_JOYAXISMOTION */ + Uint8 which; /* The joystick device index */ + Uint8 axis; /* The joystick axis index */ + Sint16 value; /* The axis value (range: -32768 to 32767) */ +} SDL_JoyAxisEvent; + +/* Joystick trackball motion event structure */ +typedef struct { + Uint8 type; /* SDL_JOYBALLMOTION */ + Uint8 which; /* The joystick device index */ + Uint8 ball; /* The joystick trackball index */ + Sint16 xrel; /* The relative motion in the X direction */ + Sint16 yrel; /* The relative motion in the Y direction */ +} SDL_JoyBallEvent; + +/* Joystick hat position change event structure */ +typedef struct { + Uint8 type; /* SDL_JOYHATMOTION */ + Uint8 which; /* The joystick device index */ + Uint8 hat; /* The joystick hat index */ + Uint8 value; /* The hat position value: + 8 1 2 + 7 0 3 + 6 5 4 + Note that zero means the POV is centered. + */ +} SDL_JoyHatEvent; + +/* Joystick button event structure */ +typedef struct { + Uint8 type; /* SDL_JOYBUTTONDOWN or SDL_JOYBUTTONUP */ + Uint8 which; /* The joystick device index */ + Uint8 button; /* The joystick button index */ + Uint8 state; /* SDL_PRESSED or SDL_RELEASED */ +} SDL_JoyButtonEvent; + +/* The "window resized" event + When you get this event, you are responsible for setting a new video + mode with the new width and height. + */ +typedef struct { + Uint8 type; /* SDL_VIDEORESIZE */ + int w; /* New width */ + int h; /* New height */ +} SDL_ResizeEvent; + +/* The "screen redraw" event */ +typedef struct { + Uint8 type; /* SDL_VIDEOEXPOSE */ +} SDL_ExposeEvent; + +/* The "quit requested" event */ +typedef struct { + Uint8 type; /* SDL_QUIT */ +} SDL_QuitEvent; + +/* A user-defined event type */ +typedef struct { + Uint8 type; /* SDL_USEREVENT through SDL_NUMEVENTS-1 */ + int code; /* User defined event code */ + void *data1; /* User defined data pointer */ + void *data2; /* User defined data pointer */ +} SDL_UserEvent; + +/* If you want to use this event, you should include SDL_syswm.h */ +struct SDL_SysWMmsg; +typedef struct SDL_SysWMmsg SDL_SysWMmsg; +typedef struct { + Uint8 type; + SDL_SysWMmsg *msg; +} SDL_SysWMEvent; + +/* General event structure */ +typedef union { + Uint8 type; + SDL_ActiveEvent active; + SDL_KeyboardEvent key; + SDL_MouseMotionEvent motion; + SDL_MouseButtonEvent button; + SDL_JoyAxisEvent jaxis; + SDL_JoyBallEvent jball; + SDL_JoyHatEvent jhat; + SDL_JoyButtonEvent jbutton; + SDL_ResizeEvent resize; + SDL_ExposeEvent expose; + SDL_QuitEvent quit; + SDL_UserEvent user; + SDL_SysWMEvent syswm; +} SDL_Event; + + +/* 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 SDL_PumpEvents(void); + +/* Checks the event queue for messages and optionally returns them. + If 'action' is SDL_ADDEVENT, up to 'numevents' events will be added to + the back of the event queue. + If 'action' is SDL_PEEKEVENT, up to 'numevents' events at the front + of the event queue, matching 'mask', will be returned and will not + be removed from the queue. + If 'action' is SDL_GETEVENT, up to 'numevents' events at the front + of the event queue, matching 'mask', will be returned and will be + removed from the queue. + This function returns the number of events actually stored, or -1 + if there was an error. This function is thread-safe. +*/ +typedef enum { + SDL_ADDEVENT, + SDL_PEEKEVENT, + SDL_GETEVENT +} SDL_eventaction; +/* */ +extern DECLSPEC int SDL_PeepEvents(SDL_Event *events, int numevents, + SDL_eventaction action, Uint32 mask); + +/* Polls for currently pending events, and returns 1 if there are any pending + events, or 0 if there are none available. If 'event' is not NULL, the next + event is removed from the queue and stored in that area. + */ +extern DECLSPEC int SDL_PollEvent(SDL_Event *event); + +/* Waits indefinitely for the next available event, returning 1, or 0 if there + was an error while waiting for events. If 'event' is not NULL, the next + event is removed from the queue and stored in that area. + */ +extern DECLSPEC int SDL_WaitEvent(SDL_Event *event); + +/* Add an event to the event queue. + This function returns 0, or -1 if the event couldn't be added to + the event queue. If the event queue is full, this function fails. + */ +extern DECLSPEC int SDL_PushEvent(SDL_Event *event); + +/* + This function sets up a filter to process all events before they + change internal state and are posted to the internal event queue. + + The filter is protypted as: +*/ +typedef int (*SDL_EventFilter)(const SDL_Event *event); +/* + 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 SDL_SetEventFilter(SDL_EventFilter filter); + +/* + Return the current event filter - can be used to "chain" filters. + If there is no event filter set, this function returns NULL. +*/ +extern DECLSPEC SDL_EventFilter SDL_GetEventFilter(void); + +/* + This function allows you to set the state of processing certain events. + If 'state' is set to SDL_IGNORE, that event will be automatically dropped + from the event queue and will not event be filtered. + If 'state' is set to SDL_ENABLE, that event will be processed normally. + If 'state' is set to SDL_QUERY, SDL_EventState() will return the + current processing state of the specified event. +*/ +#define SDL_QUERY -1 +#define SDL_IGNORE 0 +#define SDL_DISABLE 0 +#define SDL_ENABLE 1 +extern DECLSPEC Uint8 SDL_EventState(Uint8 type, int state); + + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +} +#endif +#include "close_code.h" + +#endif /* _SDL_events_h */ diff --git a/contrib/sdk/sources/SDL-1.2.2/include/SDL_getenv.h b/contrib/sdk/sources/SDL-1.2.2/include/SDL_getenv.h new file mode 100644 index 000000000..9d96f7654 --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/include/SDL_getenv.h @@ -0,0 +1,30 @@ + +/* Not all environments have a working getenv()/putenv() */ + +#if defined(macintosh) || defined(_WIN32_WCE) +#define NEED_SDL_GETENV +#endif + +#ifdef NEED_SDL_GETENV + +#include "begin_code.h" +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +extern "C" { +#endif + +/* Put a variable of the form "name=value" into the environment */ +extern DECLSPEC int SDL_putenv(const char *variable); +#define putenv(X) SDL_putenv(X) + +/* Retrieve a variable named "name" from the environment */ +extern DECLSPEC char *SDL_getenv(const char *name); +#define getenv(X) SDL_getenv(X) + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +} +#endif +#include "close_code.h" + +#endif /* NEED_GETENV */ diff --git a/contrib/sdk/sources/SDL-1.2.2/include/SDL_joystick.h b/contrib/sdk/sources/SDL-1.2.2/include/SDL_joystick.h new file mode 100644 index 000000000..f249990c0 --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/include/SDL_joystick.h @@ -0,0 +1,171 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997, 1998, 1999, 2000, 2001 Sam Lantinga + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the Free + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + Sam Lantinga + slouken@devolution.com +*/ + +#ifdef SAVE_RCSID +static char rcsid = + "@(#) $Id: SDL_joystick.h,v 1.2 2001/04/26 16:50:17 hercules Exp $"; +#endif + +/* Include file for SDL joystick event handling */ + +#ifndef _SDL_joystick_h +#define _SDL_joystick_h + +#include "SDL_types.h" + +#include "begin_code.h" +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +extern "C" { +#endif + +/* 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. +*/ + +/* The joystick structure used to identify an SDL joystick */ +struct _SDL_Joystick; +typedef struct _SDL_Joystick SDL_Joystick; + + +/* Function prototypes */ +/* + * Count the number of joysticks attached to the system + */ +extern DECLSPEC int 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 *SDL_JoystickName(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 the value which will + * identify this joystick in future joystick events. + * + * This function returns a joystick identifier, or NULL if an error occurred. + */ +extern DECLSPEC SDL_Joystick *SDL_JoystickOpen(int device_index); + +/* + * Returns 1 if the joystick has been opened, or 0 if it has not. + */ +extern DECLSPEC int SDL_JoystickOpened(int device_index); + +/* + * Get the device index of an opened joystick. + */ +extern DECLSPEC int SDL_JoystickIndex(SDL_Joystick *joystick); + +/* + * Get the number of general axis controls on a joystick + */ +extern DECLSPEC int 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 SDL_JoystickNumBalls(SDL_Joystick *joystick); + +/* + * Get the number of POV hats on a joystick + */ +extern DECLSPEC int SDL_JoystickNumHats(SDL_Joystick *joystick); + +/* + * Get the number of buttons on a joystick + */ +extern DECLSPEC int 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 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 SDL_JoystickEventState(int state); + +/* + * 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 SDL_JoystickGetAxis(SDL_Joystick *joystick, int axis); + +/* + * Get the current state of a POV hat on a joystick + * The return value is one of the following 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) +/* + * The hat indices start at index 0. + */ +extern DECLSPEC Uint8 SDL_JoystickGetHat(SDL_Joystick *joystick, int hat); + +/* + * Get the ball axis change since the last poll + * This returns 0, or -1 if you passed it invalid parameters. + * The ball indices start at index 0. + */ +extern DECLSPEC int 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 SDL_JoystickGetButton(SDL_Joystick *joystick, int button); + +/* + * Close a joystick previously opened with SDL_JoystickOpen() + */ +extern DECLSPEC void SDL_JoystickClose(SDL_Joystick *joystick); + + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +} +#endif +#include "close_code.h" + +#endif /* _SDL_joystick_h */ diff --git a/contrib/sdk/sources/SDL-1.2.2/include/SDL_keyboard.h b/contrib/sdk/sources/SDL-1.2.2/include/SDL_keyboard.h new file mode 100644 index 000000000..5e2213ba9 --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/include/SDL_keyboard.h @@ -0,0 +1,124 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997, 1998, 1999, 2000, 2001 Sam Lantinga + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the Free + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + Sam Lantinga + slouken@devolution.com +*/ + +#ifdef SAVE_RCSID +static char rcsid = + "@(#) $Id: SDL_keyboard.h,v 1.2 2001/04/26 16:50:17 hercules Exp $"; +#endif + +/* Include file for SDL keyboard event handling */ + +#ifndef _SDL_keyboard_h +#define _SDL_keyboard_h + +#include "SDL_types.h" +#include "SDL_keysym.h" + +#include "begin_code.h" +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +extern "C" { +#endif + +/* Keysym structure + - The scancode is hardware dependent, and should not be used by general + applications. If no hardware scancode is available, it will be 0. + + - The 'unicode' translated character is only available when character + translation is enabled by the SDL_EnableUNICODE() API. If non-zero, + this is a UNICODE character corresponding to the keypress. If the + high 9 bits of the character are 0, then this maps to the equivalent + ASCII character: + char ch; + if ( (keysym.unicode & 0xFF80) == 0 ) { + ch = keysym.unicode & 0x7F; + } else { + An international character.. + } + */ +typedef struct { + Uint8 scancode; /* hardware specific scancode */ + SDLKey sym; /* SDL virtual keysym */ + SDLMod mod; /* current key modifiers */ + Uint16 unicode; /* translated character */ +} SDL_keysym; + +/* This is the mask which refers to all hotkey bindings */ +#define SDL_ALL_HOTKEYS 0xFFFFFFFF + +/* Function prototypes */ +/* + * Enable/Disable UNICODE translation of keyboard input. + * This translation has some overhead, so translation defaults off. + * If 'enable' is 1, translation is enabled. + * If 'enable' is 0, translation is disabled. + * If 'enable' is -1, the translation state is not changed. + * It returns the previous state of keyboard translation. + */ +extern DECLSPEC int SDL_EnableUNICODE(int enable); + +/* + * Enable/Disable keyboard repeat. Keyboard repeat defaults to off. + * 'delay' is the initial delay in ms between the time when a key is + * pressed, and keyboard repeat begins. + * 'interval' is the time in ms between keyboard repeat events. + */ +#define SDL_DEFAULT_REPEAT_DELAY 500 +#define SDL_DEFAULT_REPEAT_INTERVAL 30 +/* + * If 'delay' is set to 0, keyboard repeat is disabled. + */ +extern DECLSPEC int SDL_EnableKeyRepeat(int delay, int interval); + +/* + * Get a snapshot of the current state of the keyboard. + * Returns an array of keystates, indexed by the SDLK_* syms. + * Used: + * Uint8 *keystate = SDL_GetKeyState(NULL); + * if ( keystate[SDLK_RETURN] ) ... is pressed. + */ +extern DECLSPEC Uint8 * SDL_GetKeyState(int *numkeys); + +/* + * Get the current key modifier state + */ +extern DECLSPEC SDLMod SDL_GetModState(void); + +/* + * Set the current key modifier state + * This does not change the keyboard state, only the key modifier flags. + */ +extern DECLSPEC void SDL_SetModState(SDLMod modstate); + +/* + * Get the name of an SDL virtual keysym + */ +extern DECLSPEC char * SDL_GetKeyName(SDLKey key); + + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +} +#endif +#include "close_code.h" + +#endif /* _SDL_keyboard_h */ diff --git a/contrib/sdk/sources/SDL-1.2.2/include/SDL_keysym.h b/contrib/sdk/sources/SDL-1.2.2/include/SDL_keysym.h new file mode 100644 index 000000000..cd1a3cd19 --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/include/SDL_keysym.h @@ -0,0 +1,315 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997, 1998, 1999, 2000, 2001 Sam Lantinga + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the Free + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + Sam Lantinga + slouken@devolution.com +*/ + +#ifdef SAVE_RCSID +static char rcsid = + "@(#) $Id: SDL_keysym.h,v 1.2 2001/04/26 16:50:17 hercules Exp $"; +#endif + +#ifndef _SDL_keysym_h +#define _SDL_keysym_h + +/* What we really want is a mapping of every raw key on the keyboard. + To support international keyboards, we use the range 0xA1 - 0xFF + as international virtual keycodes. We'll follow in the footsteps of X11... + The names of the keys + */ + +typedef enum { + /* The keyboard syms have been cleverly chosen to map to ASCII */ + SDLK_UNKNOWN = 0, + SDLK_FIRST = 0, + SDLK_BACKSPACE = 8, + SDLK_TAB = 9, + SDLK_CLEAR = 12, + SDLK_RETURN = 13, + SDLK_PAUSE = 19, + SDLK_ESCAPE = 27, + SDLK_SPACE = 32, + SDLK_EXCLAIM = 33, + SDLK_QUOTEDBL = 34, + SDLK_HASH = 35, + SDLK_DOLLAR = 36, + SDLK_AMPERSAND = 38, + SDLK_QUOTE = 39, + SDLK_LEFTPAREN = 40, + SDLK_RIGHTPAREN = 41, + SDLK_ASTERISK = 42, + SDLK_PLUS = 43, + SDLK_COMMA = 44, + SDLK_MINUS = 45, + SDLK_PERIOD = 46, + SDLK_SLASH = 47, + SDLK_0 = 48, + SDLK_1 = 49, + SDLK_2 = 50, + SDLK_3 = 51, + SDLK_4 = 52, + SDLK_5 = 53, + SDLK_6 = 54, + SDLK_7 = 55, + SDLK_8 = 56, + SDLK_9 = 57, + SDLK_COLON = 58, + SDLK_SEMICOLON = 59, + SDLK_LESS = 60, + SDLK_EQUALS = 61, + SDLK_GREATER = 62, + SDLK_QUESTION = 63, + SDLK_AT = 64, + /* + Skip uppercase letters + */ + SDLK_LEFTBRACKET = 91, + SDLK_BACKSLASH = 92, + SDLK_RIGHTBRACKET = 93, + SDLK_CARET = 94, + SDLK_UNDERSCORE = 95, + SDLK_BACKQUOTE = 96, + SDLK_a = 97, + SDLK_b = 98, + SDLK_c = 99, + SDLK_d = 100, + SDLK_e = 101, + SDLK_f = 102, + SDLK_g = 103, + SDLK_h = 104, + SDLK_i = 105, + SDLK_j = 106, + SDLK_k = 107, + SDLK_l = 108, + SDLK_m = 109, + SDLK_n = 110, + SDLK_o = 111, + SDLK_p = 112, + SDLK_q = 113, + SDLK_r = 114, + SDLK_s = 115, + SDLK_t = 116, + SDLK_u = 117, + SDLK_v = 118, + SDLK_w = 119, + SDLK_x = 120, + SDLK_y = 121, + SDLK_z = 122, + SDLK_DELETE = 127, + /* End of ASCII mapped keysyms */ + + /* International keyboard syms */ + SDLK_WORLD_0 = 160, /* 0xA0 */ + SDLK_WORLD_1 = 161, + SDLK_WORLD_2 = 162, + SDLK_WORLD_3 = 163, + SDLK_WORLD_4 = 164, + SDLK_WORLD_5 = 165, + SDLK_WORLD_6 = 166, + SDLK_WORLD_7 = 167, + SDLK_WORLD_8 = 168, + SDLK_WORLD_9 = 169, + SDLK_WORLD_10 = 170, + SDLK_WORLD_11 = 171, + SDLK_WORLD_12 = 172, + SDLK_WORLD_13 = 173, + SDLK_WORLD_14 = 174, + SDLK_WORLD_15 = 175, + SDLK_WORLD_16 = 176, + SDLK_WORLD_17 = 177, + SDLK_WORLD_18 = 178, + SDLK_WORLD_19 = 179, + SDLK_WORLD_20 = 180, + SDLK_WORLD_21 = 181, + SDLK_WORLD_22 = 182, + SDLK_WORLD_23 = 183, + SDLK_WORLD_24 = 184, + SDLK_WORLD_25 = 185, + SDLK_WORLD_26 = 186, + SDLK_WORLD_27 = 187, + SDLK_WORLD_28 = 188, + SDLK_WORLD_29 = 189, + SDLK_WORLD_30 = 190, + SDLK_WORLD_31 = 191, + SDLK_WORLD_32 = 192, + SDLK_WORLD_33 = 193, + SDLK_WORLD_34 = 194, + SDLK_WORLD_35 = 195, + SDLK_WORLD_36 = 196, + SDLK_WORLD_37 = 197, + SDLK_WORLD_38 = 198, + SDLK_WORLD_39 = 199, + SDLK_WORLD_40 = 200, + SDLK_WORLD_41 = 201, + SDLK_WORLD_42 = 202, + SDLK_WORLD_43 = 203, + SDLK_WORLD_44 = 204, + SDLK_WORLD_45 = 205, + SDLK_WORLD_46 = 206, + SDLK_WORLD_47 = 207, + SDLK_WORLD_48 = 208, + SDLK_WORLD_49 = 209, + SDLK_WORLD_50 = 210, + SDLK_WORLD_51 = 211, + SDLK_WORLD_52 = 212, + SDLK_WORLD_53 = 213, + SDLK_WORLD_54 = 214, + SDLK_WORLD_55 = 215, + SDLK_WORLD_56 = 216, + SDLK_WORLD_57 = 217, + SDLK_WORLD_58 = 218, + SDLK_WORLD_59 = 219, + SDLK_WORLD_60 = 220, + SDLK_WORLD_61 = 221, + SDLK_WORLD_62 = 222, + SDLK_WORLD_63 = 223, + SDLK_WORLD_64 = 224, + SDLK_WORLD_65 = 225, + SDLK_WORLD_66 = 226, + SDLK_WORLD_67 = 227, + SDLK_WORLD_68 = 228, + SDLK_WORLD_69 = 229, + SDLK_WORLD_70 = 230, + SDLK_WORLD_71 = 231, + SDLK_WORLD_72 = 232, + SDLK_WORLD_73 = 233, + SDLK_WORLD_74 = 234, + SDLK_WORLD_75 = 235, + SDLK_WORLD_76 = 236, + SDLK_WORLD_77 = 237, + SDLK_WORLD_78 = 238, + SDLK_WORLD_79 = 239, + SDLK_WORLD_80 = 240, + SDLK_WORLD_81 = 241, + SDLK_WORLD_82 = 242, + SDLK_WORLD_83 = 243, + SDLK_WORLD_84 = 244, + SDLK_WORLD_85 = 245, + SDLK_WORLD_86 = 246, + SDLK_WORLD_87 = 247, + SDLK_WORLD_88 = 248, + SDLK_WORLD_89 = 249, + SDLK_WORLD_90 = 250, + SDLK_WORLD_91 = 251, + SDLK_WORLD_92 = 252, + SDLK_WORLD_93 = 253, + SDLK_WORLD_94 = 254, + SDLK_WORLD_95 = 255, /* 0xFF */ + + /* Numeric keypad */ + SDLK_KP0 = 256, + SDLK_KP1 = 257, + SDLK_KP2 = 258, + SDLK_KP3 = 259, + SDLK_KP4 = 260, + SDLK_KP5 = 261, + SDLK_KP6 = 262, + SDLK_KP7 = 263, + SDLK_KP8 = 264, + SDLK_KP9 = 265, + SDLK_KP_PERIOD = 266, + SDLK_KP_DIVIDE = 267, + SDLK_KP_MULTIPLY = 268, + SDLK_KP_MINUS = 269, + SDLK_KP_PLUS = 270, + SDLK_KP_ENTER = 271, + SDLK_KP_EQUALS = 272, + + /* Arrows + Home/End pad */ + SDLK_UP = 273, + SDLK_DOWN = 274, + SDLK_RIGHT = 275, + SDLK_LEFT = 276, + SDLK_INSERT = 277, + SDLK_HOME = 278, + SDLK_END = 279, + SDLK_PAGEUP = 280, + SDLK_PAGEDOWN = 281, + + /* Function keys */ + SDLK_F1 = 282, + SDLK_F2 = 283, + SDLK_F3 = 284, + SDLK_F4 = 285, + SDLK_F5 = 286, + SDLK_F6 = 287, + SDLK_F7 = 288, + SDLK_F8 = 289, + SDLK_F9 = 290, + SDLK_F10 = 291, + SDLK_F11 = 292, + SDLK_F12 = 293, + SDLK_F13 = 294, + SDLK_F14 = 295, + SDLK_F15 = 296, + + /* Key state modifier keys */ + SDLK_NUMLOCK = 300, + SDLK_CAPSLOCK = 301, + SDLK_SCROLLOCK = 302, + SDLK_RSHIFT = 303, + SDLK_LSHIFT = 304, + SDLK_RCTRL = 305, + SDLK_LCTRL = 306, + SDLK_RALT = 307, + SDLK_LALT = 308, + SDLK_RMETA = 309, + SDLK_LMETA = 310, + SDLK_LSUPER = 311, /* Left "Windows" key */ + SDLK_RSUPER = 312, /* Right "Windows" key */ + SDLK_MODE = 313, /* "Alt Gr" key */ + SDLK_COMPOSE = 314, /* Multi-key compose key */ + + /* Miscellaneous function keys */ + SDLK_HELP = 315, + SDLK_PRINT = 316, + SDLK_SYSREQ = 317, + SDLK_BREAK = 318, + SDLK_MENU = 319, + SDLK_POWER = 320, /* Power Macintosh power key */ + SDLK_EURO = 321, /* Some european keyboards */ + + /* Add any other keys here */ + + SDLK_LAST +} SDLKey; + +/* 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_LMETA = 0x0400, + KMOD_RMETA = 0x0800, + KMOD_NUM = 0x1000, + KMOD_CAPS = 0x2000, + KMOD_MODE = 0x4000, + KMOD_RESERVED = 0x8000 +} SDLMod; + +#define KMOD_CTRL (KMOD_LCTRL|KMOD_RCTRL) +#define KMOD_SHIFT (KMOD_LSHIFT|KMOD_RSHIFT) +#define KMOD_ALT (KMOD_LALT|KMOD_RALT) +#define KMOD_META (KMOD_LMETA|KMOD_RMETA) + +#endif /* _SDL_keysym_h */ diff --git a/contrib/sdk/sources/SDL-1.2.2/include/SDL_main.h b/contrib/sdk/sources/SDL-1.2.2/include/SDL_main.h new file mode 100644 index 000000000..7841b9e77 --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/include/SDL_main.h @@ -0,0 +1,97 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997, 1998, 1999, 2000, 2001 Sam Lantinga + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the Free + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + Sam Lantinga + slouken@devolution.com +*/ + +#ifdef SAVE_RCSID +static char rcsid = + "@(#) $Id: SDL_main.h,v 1.3 2001/06/07 14:28:11 hercules Exp $"; +#endif + +#ifndef _SDL_main_h +#define _SDL_main_h + +/* Redefine main() on Win32 and MacOS so that it is called by winmain.c */ + +#if defined(WIN32UNDEFINED) || (defined(__MWERKS__) && !defined(__BEOS__)) || \ + defined(macintosh) || defined(__APPLE__) + +#ifdef __cplusplus +#define C_LINKAGE "C" +#else +#define C_LINKAGE +#endif /* __cplusplus */ + +/* The application's main() function must be called with C linkage, + and should be declared like this: +#ifdef __cplusplus +extern "C" +#endif + int main(int argc, char *argv[]) + { + } + */ +#define main SDL_main + +/* The prototype for the application's main() function */ +extern C_LINKAGE int SDL_main(int argc, char *argv[]); + + +/* From the SDL library code -- needed for registering the app on Win32 */ +#if defined(WIN32UNDEFINED) +#include "SDL_types.h" +#include "begin_code.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* This should be called from your WinMain() function, if any */ +extern DECLSPEC int SDL_RegisterApp(char *name, Uint32 style, void *hInst); + +#ifdef __cplusplus +} +#endif +#include "close_code.h" +#endif + +/* From the SDL library code -- needed for registering QuickDraw on MacOS */ +#if defined(macintosh) +#include "begin_code.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* Forward declaration so we don't need to include QuickDraw.h */ +struct QDGlobals; + +/* This should be called from your main() function, if any */ +extern DECLSPEC void SDL_InitQuickDraw(struct QDGlobals *the_qd); + +#ifdef __cplusplus +} +#endif +#include "close_code.h" +#endif + +#endif /* Need to redefine main()? */ + +#endif /* _SDL_main_h */ diff --git a/contrib/sdk/sources/SDL-1.2.2/include/SDL_main.h.BAK b/contrib/sdk/sources/SDL-1.2.2/include/SDL_main.h.BAK new file mode 100644 index 000000000..cd9582c60 --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/include/SDL_main.h.BAK @@ -0,0 +1,97 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997, 1998, 1999, 2000, 2001 Sam Lantinga + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the Free + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + Sam Lantinga + slouken@devolution.com +*/ + +#ifdef SAVE_RCSID +static char rcsid = + "@(#) $Id: SDL_main.h,v 1.3 2001/06/07 14:28:11 hercules Exp $"; +#endif + +#ifndef _SDL_main_h +#define _SDL_main_h + +/* Redefine main() on Win32 and MacOS so that it is called by winmain.c */ + +#if defined(WIN32) || (defined(__MWERKS__) && !defined(__BEOS__)) || \ + defined(macintosh) || defined(__APPLE__) + +#ifdef __cplusplus +#define C_LINKAGE "C" +#else +#define C_LINKAGE +#endif /* __cplusplus */ + +/* The application's main() function must be called with C linkage, + and should be declared like this: +#ifdef __cplusplus +extern "C" +#endif + int main(int argc, char *argv[]) + { + } + */ +#define main SDL_main + +/* The prototype for the application's main() function */ +extern C_LINKAGE int SDL_main(int argc, char *argv[]); + + +/* From the SDL library code -- needed for registering the app on Win32 */ +#if defined(WIN32) +#include "SDL_types.h" +#include "begin_code.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* This should be called from your WinMain() function, if any */ +extern DECLSPEC int SDL_RegisterApp(char *name, Uint32 style, void *hInst); + +#ifdef __cplusplus +} +#endif +#include "close_code.h" +#endif + +/* From the SDL library code -- needed for registering QuickDraw on MacOS */ +#if defined(macintosh) +#include "begin_code.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* Forward declaration so we don't need to include QuickDraw.h */ +struct QDGlobals; + +/* This should be called from your main() function, if any */ +extern DECLSPEC void SDL_InitQuickDraw(struct QDGlobals *the_qd); + +#ifdef __cplusplus +} +#endif +#include "close_code.h" +#endif + +#endif /* Need to redefine main()? */ + +#endif /* _SDL_main_h */ diff --git a/contrib/sdk/sources/SDL-1.2.2/include/SDL_mouse.h b/contrib/sdk/sources/SDL-1.2.2/include/SDL_mouse.h new file mode 100644 index 000000000..cc01611b9 --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/include/SDL_mouse.h @@ -0,0 +1,136 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997, 1998, 1999, 2000, 2001 Sam Lantinga + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the Free + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + Sam Lantinga + slouken@devolution.com +*/ + +#ifdef SAVE_RCSID +static char rcsid = + "@(#) $Id: SDL_mouse.h,v 1.2 2001/04/26 16:50:17 hercules Exp $"; +#endif + +/* Include file for SDL mouse event handling */ + +#ifndef _SDL_mouse_h +#define _SDL_mouse_h + +#include "SDL_types.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 WMcursor WMcursor; /* Implementation dependent */ +typedef struct { + SDL_Rect area; /* The area of the mouse cursor */ + Sint16 hot_x, hot_y; /* The "tip" of the cursor */ + Uint8 *data; /* B/W cursor data */ + Uint8 *mask; /* B/W cursor mask */ + Uint8 *save[2]; /* Place to save cursor area */ + WMcursor *wm_cursor; /* Window-manager cursor */ +} SDL_Cursor; + +/* Function prototypes */ +/* + * Retrieve the current state of the mouse. + * The current button state is returned as a button bitmask, which can + * be tested using the SDL_BUTTON(X) macros, and x and y are set to the + * current mouse cursor position. You can pass NULL for either x or y. + */ +extern DECLSPEC Uint8 SDL_GetMouseState(int *x, int *y); + +/* + * Retrieve the current state of the mouse. + * The current button state is returned as a button bitmask, which can + * be tested using the SDL_BUTTON(X) macros, and x and y are set to the + * mouse deltas since the last call to SDL_GetRelativeMouseState(). + */ +extern DECLSPEC Uint8 SDL_GetRelativeMouseState(int *x, int *y); + +/* + * Set the position of the mouse cursor (generates a mouse motion event) + */ +extern DECLSPEC void SDL_WarpMouse(Uint16 x, Uint16 y); + +/* + * Create a cursor using the specified data and mask (in MSB format). + * The cursor width must be a multiple of 8 bits. + * + * The cursor is created in black and white according to the following: + * data mask resulting pixel on screen + * 0 1 White + * 1 1 Black + * 0 0 Transparent + * 1 0 Inverted color if possible, black if not. + * + * Cursors created with this function must be freed with SDL_FreeCursor(). + */ +extern DECLSPEC SDL_Cursor *SDL_CreateCursor + (Uint8 *data, Uint8 *mask, int w, int h, int hot_x, int hot_y); + +/* + * Set the currently active cursor to the specified one. + * If the cursor is currently visible, the change will be immediately + * represented on the display. + */ +extern DECLSPEC void SDL_SetCursor(SDL_Cursor *cursor); + +/* + * Returns the currently active cursor. + */ +extern DECLSPEC SDL_Cursor * SDL_GetCursor(void); + +/* + * Deallocates a cursor created with SDL_CreateCursor(). + */ +extern DECLSPEC void SDL_FreeCursor(SDL_Cursor *cursor); + +/* + * Toggle whether or not the cursor is shown on the screen. + * The cursor start off displayed, but can be turned off. + * SDL_ShowCursor() returns 1 if the cursor was being displayed + * before the call, or 0 if it was not. You can query the current + * state by passing a 'toggle' value of -1. + */ +extern DECLSPEC int 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) (SDL_PRESSED<<(X-1)) +#define SDL_BUTTON_LEFT 1 +#define SDL_BUTTON_MIDDLE 2 +#define SDL_BUTTON_RIGHT 3 +#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) + + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +} +#endif +#include "close_code.h" + +#endif /* _SDL_mouse_h */ diff --git a/contrib/sdk/sources/SDL-1.2.2/include/SDL_mutex.h b/contrib/sdk/sources/SDL-1.2.2/include/SDL_mutex.h new file mode 100644 index 000000000..7cbad907a --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/include/SDL_mutex.h @@ -0,0 +1,163 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997, 1998, 1999, 2000, 2001 Sam Lantinga + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the Free + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + Sam Lantinga + slouken@devolution.com +*/ + +#ifdef SAVE_RCSID +static char rcsid = + "@(#) $Id: SDL_mutex.h,v 1.2 2001/04/26 16:50:17 hercules Exp $"; +#endif + +#ifndef _SDL_mutex_h +#define _SDL_mutex_h + +/* Functions to provide thread synchronization primitives + + These are independent of the other SDL routines. +*/ + +#include "SDL_main.h" +#include "SDL_types.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) + + +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ +/* Mutex functions */ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +/* The SDL mutex structure, defined in SDL_mutex.c */ +struct SDL_mutex; +typedef struct SDL_mutex SDL_mutex; + +/* Create a mutex, initialized unlocked */ +extern DECLSPEC SDL_mutex * SDL_CreateMutex(void); + +/* Lock the mutex (Returns 0, or -1 on error) */ +#define SDL_LockMutex(m) SDL_mutexP(m) +extern DECLSPEC int SDL_mutexP(SDL_mutex *mutex); + +/* Unlock the mutex (Returns 0, or -1 on error) */ +#define SDL_UnlockMutex(m) SDL_mutexV(m) +extern DECLSPEC int SDL_mutexV(SDL_mutex *mutex); + +/* Destroy a mutex */ +extern DECLSPEC void SDL_DestroyMutex(SDL_mutex *mutex); + + +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ +/* Semaphore functions */ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +/* The SDL semaphore structure, defined in SDL_sem.c */ +struct SDL_semaphore; +typedef struct SDL_semaphore SDL_sem; + +/* Create a semaphore, initialized with value, returns NULL on failure. */ +extern DECLSPEC SDL_sem * SDL_CreateSemaphore(Uint32 initial_value); + +/* Destroy a semaphore */ +extern DECLSPEC void SDL_DestroySemaphore(SDL_sem *sem); + +/* This function suspends the calling thread until the semaphore pointed + * to by sem has a positive count. It then atomically decreases the semaphore + * count. + */ +extern DECLSPEC int SDL_SemWait(SDL_sem *sem); + +/* Non-blocking variant of SDL_SemWait(), returns 0 if the wait succeeds, + SDL_MUTEX_TIMEDOUT if the wait would block, and -1 on error. +*/ +extern DECLSPEC int SDL_SemTryWait(SDL_sem *sem); + +/* Variant of SDL_SemWait() with a timeout in milliseconds, returns 0 if + the wait succeeds, SDL_MUTEX_TIMEDOUT if the wait does not succeed in + the allotted time, and -1 on error. + On some platforms this function is implemented by looping with a delay + of 1 ms, and so should be avoided if possible. +*/ +extern DECLSPEC int SDL_SemWaitTimeout(SDL_sem *sem, Uint32 ms); + +/* Atomically increases the semaphore's count (not blocking), returns 0, + or -1 on error. + */ +extern DECLSPEC int SDL_SemPost(SDL_sem *sem); + +/* Returns the current count of the semaphore */ +extern DECLSPEC Uint32 SDL_SemValue(SDL_sem *sem); + + +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ +/* Condition variable functions */ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +/* The SDL condition variable structure, defined in SDL_cond.c */ +struct SDL_cond; +typedef struct SDL_cond SDL_cond; + +/* Create a condition variable */ +extern DECLSPEC SDL_cond * SDL_CreateCond(void); + +/* Destroy a condition variable */ +extern DECLSPEC void SDL_DestroyCond(SDL_cond *cond); + +/* Restart one of the threads that are waiting on the condition variable, + returns 0 or -1 on error. + */ +extern DECLSPEC int SDL_CondSignal(SDL_cond *cond); + +/* Restart all threads that are waiting on the condition variable, + returns 0 or -1 on error. + */ +extern DECLSPEC int SDL_CondBroadcast(SDL_cond *cond); + +/* Wait on the condition variable, unlocking the provided mutex. + The mutex must be locked before entering this function! + Returns 0 when it is signaled, or -1 on error. + */ +extern DECLSPEC int SDL_CondWait(SDL_cond *cond, SDL_mutex *mut); + +/* Waits for at most 'ms' milliseconds, and returns 0 if the condition + variable is signaled, SDL_MUTEX_TIMEDOUT if the condition is not + signaled in the allotted time, and -1 on error. + On some platforms this function is implemented by looping with a delay + of 1 ms, and so should be avoided if possible. +*/ +extern DECLSPEC int SDL_CondWaitTimeout(SDL_cond *cond, SDL_mutex *mutex, Uint32 ms); + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +} +#endif +#include "close_code.h" + +#endif /* _SDL_mutex_h */ diff --git a/contrib/sdk/sources/SDL-1.2.2/include/SDL_quit.h b/contrib/sdk/sources/SDL-1.2.2/include/SDL_quit.h new file mode 100644 index 000000000..f903af9f5 --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/include/SDL_quit.h @@ -0,0 +1,52 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997, 1998, 1999, 2000, 2001 Sam Lantinga + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the Free + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + Sam Lantinga + slouken@devolution.com +*/ + +#ifdef SAVE_RCSID +static char rcsid = + "@(#) $Id: SDL_quit.h,v 1.2 2001/04/26 16:50:17 hercules Exp $"; +#endif + +/* Include file for SDL quit event handling */ + +#ifndef _SDL_quit_h +#define _SDL_quit_h + +/* + An SDL_QUITEVENT 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_QUITEVENT events as well. There is no way + to determine the cause of an SDL_QUITEVENT, but setting a signal + handler in your application will override the default generation of + quit events for that signal. +*/ + +/* There are no functions directly affecting the quit event */ +#define SDL_QuitRequested() \ + (SDL_PumpEvents(), SDL_PeepEvents(NULL,0,SDL_PEEKEVENT,SDL_QUITMASK)) + +#endif /* _SDL_quit_h */ diff --git a/contrib/sdk/sources/SDL-1.2.2/include/SDL_rwops.h b/contrib/sdk/sources/SDL-1.2.2/include/SDL_rwops.h new file mode 100644 index 000000000..2dfdaf367 --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/include/SDL_rwops.h @@ -0,0 +1,113 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997, 1998, 1999, 2000, 2001 Sam Lantinga + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the Free + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + Sam Lantinga + slouken@devolution.com +*/ + +#ifdef SAVE_RCSID +static char rcsid = + "@(#) $Id: SDL_rwops.h,v 1.2 2001/04/26 16:50:17 hercules Exp $"; +#endif + +/* This file provides a general interface for SDL to read and write + data sources. It can easily be extended to files, memory, etc. +*/ + +#ifndef _SDL_RWops_h +#define _SDL_RWops_h + +#include + +#include "SDL_types.h" + +#include "begin_code.h" +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +extern "C" { +#endif + +/* This is the read/write operation structure -- very basic */ + +typedef struct SDL_RWops { + /* Seek to 'offset' relative to whence, one of stdio's whence values: + SEEK_SET, SEEK_CUR, SEEK_END + Returns the final offset in the data source. + */ + int (*seek)(struct SDL_RWops *context, int offset, int whence); + + /* Read up to 'num' objects each of size 'objsize' from the data + source to the area pointed at by 'ptr'. + Returns the number of objects read, or -1 if the read failed. + */ + int (*read)(struct SDL_RWops *context, void *ptr, int size, int maxnum); + + /* Write exactly 'num' objects each of size 'objsize' from the area + pointed at by 'ptr' to data source. + Returns 'num', or -1 if the write failed. + */ + int (*write)(struct SDL_RWops *context, const void *ptr, int size, int num); + + /* Close and free an allocated SDL_FSops structure */ + int (*close)(struct SDL_RWops *context); + + Uint32 type; + union { + struct { + int autoclose; + FILE *fp; + } stdio; + struct { + Uint8 *base; + Uint8 *here; + Uint8 *stop; + } mem; + struct { + void *data1; + } unknown; + } hidden; + +} SDL_RWops; + + +/* Functions to create SDL_RWops structures from various data sources */ + +extern DECLSPEC SDL_RWops * SDL_RWFromFile(const char *file, const char *mode); + +extern DECLSPEC SDL_RWops * SDL_RWFromFP(FILE *fp, int autoclose); + +extern DECLSPEC SDL_RWops * SDL_RWFromMem(void *mem, int size); + +extern DECLSPEC SDL_RWops * SDL_AllocRW(void); +extern DECLSPEC void SDL_FreeRW(SDL_RWops *area); + +/* Macros to easily read and write from an SDL_RWops structure */ +#define SDL_RWseek(ctx, offset, whence) (ctx)->seek(ctx, offset, whence) +#define SDL_RWtell(ctx) (ctx)->seek(ctx, 0, SEEK_CUR) +#define SDL_RWread(ctx, ptr, size, n) (ctx)->read(ctx, ptr, size, n) +#define SDL_RWwrite(ctx, ptr, size, n) (ctx)->write(ctx, ptr, size, n) +#define SDL_RWclose(ctx) (ctx)->close(ctx) + + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +} +#endif +#include "close_code.h" + +#endif /* _SDL_RWops_h */ diff --git a/contrib/sdk/sources/SDL-1.2.2/include/SDL_syswm.h b/contrib/sdk/sources/SDL-1.2.2/include/SDL_syswm.h new file mode 100644 index 000000000..ccf6aa251 --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/include/SDL_syswm.h @@ -0,0 +1,165 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997, 1998, 1999, 2000, 2001 Sam Lantinga + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the Free + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + Sam Lantinga + slouken@devolution.com +*/ + +#ifdef SAVE_RCSID +static char rcsid = + "@(#) $Id: SDL_syswm.h,v 1.5 2001/07/08 09:00:06 hercules Exp $"; +#endif + +/* Include file for SDL custom system window manager hooks */ + +#ifndef _SDL_syswm_h +#define _SDL_syswm_h + +#include "SDL_version.h" + +#include "begin_code.h" +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +extern "C" { +#endif + +/* 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() +*/ +#ifdef SDL_PROTOTYPES_ONLY +struct SDL_SysWMinfo; +typedef struct SDL_SysWMinfo SDL_SysWMinfo; +#else + +/* This is the structure for custom window manager events */ +#if (defined(unix) || defined(__unix__) || defined(_AIX) || defined(__OpenBSD__)) && \ + (!defined(DISABLE_X11) && !defined(__CYGWIN32__)) + /* AIX is unix, of course, but the native compiler CSet doesn't define unix */ +#include +#include + +/* These are the various supported subsystems under UNIX */ +typedef enum { + SDL_SYSWM_X11 +} SDL_SYSWM_TYPE; + +/* The UNIX custom event structure */ +struct SDL_SysWMmsg { + SDL_version version; + SDL_SYSWM_TYPE subsystem; + union { + XEvent xevent; + } event; +}; + +/* The UNIX 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. + */ +typedef struct { + SDL_version version; + SDL_SYSWM_TYPE subsystem; + union { + struct { + Display *display; /* The X11 display */ + Window window; /* The X11 display window */ + /* These locking functions should be called around + any X11 functions using the display variable. + They lock the event thread, so should not be + called around event functions or from event filters. + */ + void (*lock_func)(void); + void (*unlock_func)(void); + + /* Introduced in SDL 1.0.2 */ + Window fswindow; /* The X11 fullscreen window */ + Window wmwindow; /* The X11 managed input window */ + } x11; + } info; +} SDL_SysWMinfo; + +#elif defined(ENABLE_NANOX) +#include + +/* The generic custom event structure */ +struct SDL_SysWMmsg { + SDL_version version; + int data; +}; + +/* The windows custom window manager information structure */ +typedef struct { + SDL_version version ; + GR_WINDOW_ID window ; /* The display window */ +} SDL_SysWMinfo; + +#elif defined(WIN32UNDEFINED) +#include + +/* The windows custom event structure */ +struct SDL_SysWMmsg { + SDL_version version; + HWND hwnd; /* The window for the message */ + UINT msg; /* The type of message */ + WPARAM wParam; /* WORD message parameter */ + LPARAM lParam; /* LONG message parameter */ +}; + +/* The windows custom window manager information structure */ +typedef struct { + SDL_version version; + HWND window; /* The Win32 display window */ +} SDL_SysWMinfo; + +#else + +/* The generic custom event structure */ +struct SDL_SysWMmsg { + SDL_version version; + int data; +}; + +/* The generic custom window manager information structure */ +typedef struct { + SDL_version version; + int data; +} SDL_SysWMinfo; + +#endif /* OS type */ + +#endif /* SDL_PROTOTYPES_ONLY */ + +/* Function prototypes */ +/* + * This function gives you custom hooks into the window manager information. + * It fills the structure pointed to by 'info' with custom information and + * returns 1 if the function is implemented. If it's not implemented, or + * the version member of the 'info' structure is invalid, it returns 0. + */ +extern DECLSPEC int SDL_GetWMInfo(SDL_SysWMinfo *info); + + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +} +#endif +#include "close_code.h" + +#endif /* _SDL_syswm_h */ diff --git a/contrib/sdk/sources/SDL-1.2.2/include/SDL_syswm.h.BAK b/contrib/sdk/sources/SDL-1.2.2/include/SDL_syswm.h.BAK new file mode 100644 index 000000000..9e5171c89 --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/include/SDL_syswm.h.BAK @@ -0,0 +1,165 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997, 1998, 1999, 2000, 2001 Sam Lantinga + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the Free + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + Sam Lantinga + slouken@devolution.com +*/ + +#ifdef SAVE_RCSID +static char rcsid = + "@(#) $Id: SDL_syswm.h,v 1.5 2001/07/08 09:00:06 hercules Exp $"; +#endif + +/* Include file for SDL custom system window manager hooks */ + +#ifndef _SDL_syswm_h +#define _SDL_syswm_h + +#include "SDL_version.h" + +#include "begin_code.h" +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +extern "C" { +#endif + +/* 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() +*/ +#ifdef SDL_PROTOTYPES_ONLY +struct SDL_SysWMinfo; +typedef struct SDL_SysWMinfo SDL_SysWMinfo; +#else + +/* This is the structure for custom window manager events */ +#if (defined(unix) || defined(__unix__) || defined(_AIX) || defined(__OpenBSD__)) && \ + (!defined(DISABLE_X11) && !defined(__CYGWIN32__)) + /* AIX is unix, of course, but the native compiler CSet doesn't define unix */ +#include +#include + +/* These are the various supported subsystems under UNIX */ +typedef enum { + SDL_SYSWM_X11 +} SDL_SYSWM_TYPE; + +/* The UNIX custom event structure */ +struct SDL_SysWMmsg { + SDL_version version; + SDL_SYSWM_TYPE subsystem; + union { + XEvent xevent; + } event; +}; + +/* The UNIX 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. + */ +typedef struct { + SDL_version version; + SDL_SYSWM_TYPE subsystem; + union { + struct { + Display *display; /* The X11 display */ + Window window; /* The X11 display window */ + /* These locking functions should be called around + any X11 functions using the display variable. + They lock the event thread, so should not be + called around event functions or from event filters. + */ + void (*lock_func)(void); + void (*unlock_func)(void); + + /* Introduced in SDL 1.0.2 */ + Window fswindow; /* The X11 fullscreen window */ + Window wmwindow; /* The X11 managed input window */ + } x11; + } info; +} SDL_SysWMinfo; + +#elif defined(ENABLE_NANOX) +#include + +/* The generic custom event structure */ +struct SDL_SysWMmsg { + SDL_version version; + int data; +}; + +/* The windows custom window manager information structure */ +typedef struct { + SDL_version version ; + GR_WINDOW_ID window ; /* The display window */ +} SDL_SysWMinfo; + +#elif defined(WIN32) +#include + +/* The windows custom event structure */ +struct SDL_SysWMmsg { + SDL_version version; + HWND hwnd; /* The window for the message */ + UINT msg; /* The type of message */ + WPARAM wParam; /* WORD message parameter */ + LPARAM lParam; /* LONG message parameter */ +}; + +/* The windows custom window manager information structure */ +typedef struct { + SDL_version version; + HWND window; /* The Win32 display window */ +} SDL_SysWMinfo; + +#else + +/* The generic custom event structure */ +struct SDL_SysWMmsg { + SDL_version version; + int data; +}; + +/* The generic custom window manager information structure */ +typedef struct { + SDL_version version; + int data; +} SDL_SysWMinfo; + +#endif /* OS type */ + +#endif /* SDL_PROTOTYPES_ONLY */ + +/* Function prototypes */ +/* + * This function gives you custom hooks into the window manager information. + * It fills the structure pointed to by 'info' with custom information and + * returns 1 if the function is implemented. If it's not implemented, or + * the version member of the 'info' structure is invalid, it returns 0. + */ +extern DECLSPEC int SDL_GetWMInfo(SDL_SysWMinfo *info); + + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +} +#endif +#include "close_code.h" + +#endif /* _SDL_syswm_h */ diff --git a/contrib/sdk/sources/SDL-1.2.2/include/SDL_thread.h b/contrib/sdk/sources/SDL-1.2.2/include/SDL_thread.h new file mode 100644 index 000000000..e905268cb --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/include/SDL_thread.h @@ -0,0 +1,79 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997, 1998, 1999, 2000, 2001 Sam Lantinga + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the Free + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + Sam Lantinga + slouken@devolution.com +*/ + +#ifdef SAVE_RCSID +static char rcsid = + "@(#) $Id: SDL_thread.h,v 1.2 2001/04/26 16:50:17 hercules Exp $"; +#endif + +#ifndef _SDL_thread_h +#define _SDL_thread_h + +/* Header for the SDL thread management routines + + These are independent of the other SDL routines. +*/ + +#include "SDL_main.h" +#include "SDL_types.h" + +/* Thread synchronization primitives */ +#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; + +/* Create a thread */ +extern DECLSPEC SDL_Thread * SDL_CreateThread(int (*fn)(void *), void *data); + +/* Get the 32-bit thread identifier for the current thread */ +extern DECLSPEC Uint32 SDL_ThreadID(void); + +/* Get the 32-bit thread identifier for the specified thread, + equivalent to SDL_ThreadID() if the specified thread is NULL. + */ +extern DECLSPEC Uint32 SDL_GetThreadID(SDL_Thread *thread); + +/* Wait for a thread to finish. + The return code for the thread function is placed in the area + pointed to by 'status', if 'status' is not NULL. + */ +extern DECLSPEC void SDL_WaitThread(SDL_Thread *thread, int *status); + +/* Forcefully kill a thread without worrying about its state */ +extern DECLSPEC void SDL_KillThread(SDL_Thread *thread); + + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +} +#endif +#include "close_code.h" + +#endif /* _SDL_thread_h */ diff --git a/contrib/sdk/sources/SDL-1.2.2/include/SDL_timer.h b/contrib/sdk/sources/SDL-1.2.2/include/SDL_timer.h new file mode 100644 index 000000000..fb6c4d60a --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/include/SDL_timer.h @@ -0,0 +1,118 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997, 1998, 1999, 2000, 2001 Sam Lantinga + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the Free + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + Sam Lantinga + slouken@devolution.com +*/ + +#ifdef SAVE_RCSID +static char rcsid = + "@(#) $Id: SDL_timer.h,v 1.2 2001/04/26 16:50:17 hercules Exp $"; +#endif + +#ifndef _SDL_timer_h +#define _SDL_timer_h + +/* Header for the SDL time management routines */ + +#include "SDL_main.h" +#include "SDL_types.h" + +#include "begin_code.h" +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +extern "C" { +#endif + +/* This is the OS scheduler timeslice, in milliseconds */ +#define SDL_TIMESLICE 10 + +/* This is the maximum resolution of the SDL timer on all platforms */ +#define TIMER_RESOLUTION 10 /* Experimentally determined */ + +/* Get the number of milliseconds since the SDL library initialization. + * Note that this value wraps if the program runs for more than ~49 days. + */ +extern DECLSPEC Uint32 SDL_GetTicks(void); + +/* Wait a specified number of milliseconds before returning */ +extern DECLSPEC void SDL_Delay(Uint32 ms); + +/* Function prototype for the timer callback function */ +typedef Uint32 (*SDL_TimerCallback)(Uint32 interval); + +/* Set a callback to run after the specified number of milliseconds has + * elapsed. 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. + * + * To cancel a currently running timer, call SDL_SetTimer(0, NULL); + * + * The timer callback function may run in a different thread than your + * main code, and so shouldn't call any functions from within itself. + * + * The maximum resolution of this timer is 10 ms, which means that if + * you request a 16 ms timer, your callback will run approximately 20 ms + * later on an unloaded system. If you wanted to set a flag signaling + * a frame update at 30 frames per second (every 33 ms), you might set a + * timer for 30 ms: + * SDL_SetTimer((33/10)*10, flag_update); + * + * If you use this function, you need to pass SDL_INIT_TIMER to SDL_Init(). + * + * Under UNIX, you should not use raise or use SIGALRM and this function + * in the same program, as it is implemented using setitimer(). You also + * should not use this function in multi-threaded applications as signals + * to multi-threaded apps have undefined behavior in some implementations. + */ +extern DECLSPEC int SDL_SetTimer(Uint32 interval, SDL_TimerCallback callback); + +/* New timer API, supports multiple timers + * Written by Stephane Peter + */ + +/* Function prototype for the new timer callback function. + * The callback function is passed the current timer interval and returns + * the next timer interval. If the returned value is the same as the one + * passed in, the periodic alarm continues, otherwise a new alarm is + * scheduled. If the callback returns 0, the periodic alarm is cancelled. + */ +typedef Uint32 (*SDL_NewTimerCallback)(Uint32 interval, void *param); + +/* Definition of the timer ID type */ +typedef struct _SDL_TimerID *SDL_TimerID; + +/* Add a new timer to the pool of timers already running. + Returns a timer ID, or NULL when an error occurs. + */ +extern DECLSPEC SDL_TimerID SDL_AddTimer(Uint32 interval, SDL_NewTimerCallback callback, void *param); + +/* Remove one of the multiple timers knowing its ID. + * Returns a boolean value indicating success. + */ +extern DECLSPEC SDL_bool SDL_RemoveTimer(SDL_TimerID t); + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +} +#endif +#include "close_code.h" + +#endif /* _SDL_timer_h */ diff --git a/contrib/sdk/sources/SDL-1.2.2/include/SDL_types.h b/contrib/sdk/sources/SDL-1.2.2/include/SDL_types.h new file mode 100644 index 000000000..f01b966ff --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/include/SDL_types.h @@ -0,0 +1,87 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997, 1998, 1999, 2000, 2001 Sam Lantinga + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the Free + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + Sam Lantinga + slouken@devolution.com +*/ + +#ifdef SAVE_RCSID +static char rcsid = + "@(#) $Id: SDL_types.h,v 1.2 2001/04/26 16:50:17 hercules Exp $"; +#endif + +/* General data types used by the SDL library */ + +#ifndef _SDL_types_h +#define _SDL_types_h + +/* The number of elements in a table */ +#define SDL_TABLESIZE(table) (sizeof(table)/sizeof(table[0])) + +/* Basic data types */ +typedef enum { + SDL_FALSE = 0, + SDL_TRUE = 1 +} SDL_bool; +typedef unsigned char Uint8; +typedef signed char Sint8; +typedef unsigned short Uint16; +typedef signed short Sint16; +typedef unsigned int Uint32; +typedef signed int Sint32; + +/* Figure out how to support 64-bit datatypes */ +#if !defined(__STRICT_ANSI__) +#if defined(__GNUC__) || defined(__MWERKS__) /* MJS */ +#define SDL_HAS_64BIT_TYPE long long +#elif defined(_MSC_VER) /* VC++ */ +#define SDL_HAS_64BIT_TYPE __int64 +#endif +#endif /* !__STRICT_ANSI__ */ + +/* The 64-bit datatype isn't supported on all platforms */ +#ifdef SDL_HAS_64BIT_TYPE +typedef unsigned SDL_HAS_64BIT_TYPE Uint64; +typedef SDL_HAS_64BIT_TYPE Sint64; +#else +/* This is really just a hack to prevent the compiler from complaining */ +typedef struct { + Uint32 hi; + Uint32 lo; +} Uint64, Sint64; +#endif + +/* Make sure the types really have the right sizes */ +#define SDL_COMPILE_TIME_ASSERT(name, x) \ + typedef int SDL_dummy_ ## name[(x) * 2 - 1] + +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); + +#undef SDL_COMPILE_TIME_ASSERT + +/* General keyboard/mouse state definitions */ +enum { SDL_PRESSED = 0x01, SDL_RELEASED = 0x00 }; + +#endif diff --git a/contrib/sdk/sources/SDL-1.2.2/include/SDL_version.h b/contrib/sdk/sources/SDL-1.2.2/include/SDL_version.h new file mode 100644 index 000000000..7f202155c --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/include/SDL_version.h @@ -0,0 +1,90 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997, 1998, 1999, 2000, 2001 Sam Lantinga + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the Free + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + Sam Lantinga + slouken@devolution.com +*/ + +#ifdef SAVE_RCSID +static char rcsid = + "@(#) $Id: SDL_version.h,v 1.3 2001/06/19 13:35:05 hercules Exp $"; +#endif + +/* This header defines the current SDL version */ + +#ifndef _SDL_version_h +#define _SDL_version_h + +#include "SDL_types.h" + +#include "begin_code.h" +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +extern "C" { +#endif + +/* Printable format: "%d.%d.%d", MAJOR, MINOR, PATCHLEVEL +*/ +#define SDL_MAJOR_VERSION 1 +#define SDL_MINOR_VERSION 2 +#define SDL_PATCHLEVEL 2 + +typedef struct { + Uint8 major; + Uint8 minor; + Uint8 patch; +} SDL_version; + +/* This macro can be used to fill a version structure with the compile-time + * version of the SDL library. + */ +#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: + (1,2,3) -> (1203) + 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)) + +/* This function gets the version of the dynamically linked SDL library. + it should NOT be used to fill a version structure, instead you should + use the SDL_Version() macro. + */ +extern DECLSPEC const SDL_version * SDL_Linked_Version(void); + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +} +#endif +#include "close_code.h" + +#endif /* _SDL_version_h */ diff --git a/contrib/sdk/sources/SDL-1.2.2/include/SDL_video.h b/contrib/sdk/sources/SDL-1.2.2/include/SDL_video.h new file mode 100644 index 000000000..5c761df3c --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/include/SDL_video.h @@ -0,0 +1,891 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997, 1998, 1999, 2000, 2001 Sam Lantinga + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the Free + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + Sam Lantinga + slouken@devolution.com +*/ + +#ifdef SAVE_RCSID +static char rcsid = + "@(#) $Id: SDL_video.h,v 1.3 2001/06/07 14:28:11 hercules Exp $"; +#endif + +/* Header file for access to the SDL raw framebuffer window */ + +#ifndef _SDL_video_h +#define _SDL_video_h + +#include + +#include "SDL_types.h" +#include "SDL_mutex.h" +#include "SDL_rwops.h" + +#include "begin_code.h" +/* Set up for C function definitions, even when using C++ */ +#ifdef __cplusplus +extern "C" { +#endif + +/* Transparency definitions: These define alpha as the opacity of a surface */ +#define SDL_ALPHA_OPAQUE 255 +#define SDL_ALPHA_TRANSPARENT 0 + +/* Useful data types */ +typedef struct { + Sint16 x, y; + Uint16 w, h; +} SDL_Rect; + +typedef struct { + Uint8 r; + Uint8 g; + Uint8 b; + Uint8 unused; +} SDL_Color; + +typedef struct { + int ncolors; + SDL_Color *colors; +} SDL_Palette; + +/* Everything in the pixel format structure is read-only */ +typedef struct SDL_PixelFormat { + SDL_Palette *palette; + Uint8 BitsPerPixel; + Uint8 BytesPerPixel; + Uint8 Rloss; + Uint8 Gloss; + Uint8 Bloss; + Uint8 Aloss; + Uint8 Rshift; + Uint8 Gshift; + Uint8 Bshift; + Uint8 Ashift; + Uint32 Rmask; + Uint32 Gmask; + Uint32 Bmask; + Uint32 Amask; + + /* RGB color key information */ + Uint32 colorkey; + /* Alpha value information (per-surface alpha) */ + Uint8 alpha; +} SDL_PixelFormat; + +/* typedef for private surface blitting functions */ +struct SDL_Surface; +typedef int (*SDL_blit)(struct SDL_Surface *src, SDL_Rect *srcrect, + struct SDL_Surface *dst, SDL_Rect *dstrect); + +/* This structure should be treated as read-only, except for '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 */ + Uint16 pitch; /* Read-only */ + void *pixels; /* Read-write */ + int offset; /* Private */ + + /* Hardware-specific surface info */ + struct private_hwdata *hwdata; + + /* clipping information */ + SDL_Rect clip_rect; /* Read-only */ + Uint32 unused1; /* for binary compatibility */ + + /* Allow recursive locks */ + Uint32 locked; /* Private */ + + /* info for fast blit mapping to other surfaces */ + struct SDL_BlitMap *map; /* Private */ + + /* format version, bumped at every change to invalidate blit maps */ + unsigned int format_version; /* Private */ + + /* Reference count -- used when freeing surface */ + int refcount; /* Read-mostly */ +} SDL_Surface; + +/* These are the currently supported flags for the SDL_surface */ +/* Available for SDL_CreateRGBSurface() or SDL_SetVideoMode() */ +#define SDL_SWSURFACE 0x00000000 /* Surface is in system memory */ +#define SDL_HWSURFACE 0x00000001 /* Surface is in video memory */ +#define SDL_ASYNCBLIT 0x00000004 /* Use asynchronous blits if possible */ +/* Available for SDL_SetVideoMode() */ +#define SDL_ANYFORMAT 0x10000000 /* Allow any video depth/pixel-format */ +#define SDL_HWPALETTE 0x20000000 /* Surface has exclusive palette */ +#define SDL_DOUBLEBUF 0x40000000 /* Set up double-buffered video mode */ +#define SDL_FULLSCREEN 0x80000000 /* Surface is a full screen display */ +#define SDL_OPENGL 0x00000002 /* Create an OpenGL rendering context */ +#define SDL_OPENGLBLIT 0x0000000A /* Create an OpenGL rendering context and use it for blitting */ +#define SDL_RESIZABLE 0x00000010 /* This video mode may be resized */ +#define SDL_NOFRAME 0x00000020 /* No window caption or edge frame */ +/* Used internally (read-only) */ +#define SDL_HWACCEL 0x00000100 /* Blit uses hardware acceleration */ +#define SDL_SRCCOLORKEY 0x00001000 /* Blit uses a source color key */ +#define SDL_RLEACCELOK 0x00002000 /* Private flag */ +#define SDL_RLEACCEL 0x00004000 /* Surface is RLE encoded */ +#define SDL_SRCALPHA 0x00010000 /* Blit uses source alpha blending */ +#define SDL_PREALLOC 0x01000000 /* Surface uses preallocated memory */ + +/* Evaluates to true if the surface needs to be locked before access */ +#define SDL_MUSTLOCK(surface) \ + (surface->offset || \ + ((surface->flags & (SDL_HWSURFACE|SDL_ASYNCBLIT|SDL_RLEACCEL)) != 0)) + + +/* Useful for determining the video hardware capabilities */ +typedef struct { + Uint32 hw_available :1; /* Flag: Can you create hardware surfaces? */ + Uint32 wm_available :1; /* Flag: Can you talk to a window manager? */ + Uint32 UnusedBits1 :6; + Uint32 UnusedBits2 :1; + Uint32 blit_hw :1; /* Flag: Accelerated blits HW --> HW */ + Uint32 blit_hw_CC :1; /* Flag: Accelerated blits with Colorkey */ + Uint32 blit_hw_A :1; /* Flag: Accelerated blits with Alpha */ + Uint32 blit_sw :1; /* Flag: Accelerated blits SW --> HW */ + Uint32 blit_sw_CC :1; /* Flag: Accelerated blits with Colorkey */ + Uint32 blit_sw_A :1; /* Flag: Accelerated blits with Alpha */ + Uint32 blit_fill :1; /* Flag: Accelerated color fill */ + Uint32 UnusedBits3 :16; + Uint32 video_mem; /* The total amount of video memory (in K) */ + SDL_PixelFormat *vfmt; /* Value: The format of the video surface */ +} SDL_VideoInfo; + + +/* The most common video overlay formats. + For an explanation of these pixel formats, see: + http://www.webartz.com/fourcc/indexyuv.htm + + For information on the relationship between color spaces, see: + http://www.neuro.sfc.keio.ac.jp/~aly/polygon/info/color-space-faq.html + */ +#define SDL_YV12_OVERLAY 0x32315659 /* Planar mode: Y + V + U (3 planes) */ +#define SDL_IYUV_OVERLAY 0x56555949 /* Planar mode: Y + U + V (3 planes) */ +#define SDL_YUY2_OVERLAY 0x32595559 /* Packed mode: Y0+U0+Y1+V0 (1 plane) */ +#define SDL_UYVY_OVERLAY 0x59565955 /* Packed mode: U0+Y0+V0+Y1 (1 plane) */ +#define SDL_YVYU_OVERLAY 0x55595659 /* Packed mode: Y0+V0+Y1+U0 (1 plane) */ + +/* The YUV hardware video overlay */ +typedef struct SDL_Overlay { + Uint32 format; /* Read-only */ + int w, h; /* Read-only */ + int planes; /* Read-only */ + Uint16 *pitches; /* Read-only */ + Uint8 **pixels; /* Read-write */ + + /* Hardware-specific surface info */ + struct private_yuvhwfuncs *hwfuncs; + struct private_yuvhwdata *hwdata; + + /* Special flags */ + Uint32 hw_overlay :1; /* Flag: This overlay hardware accelerated? */ + Uint32 UnusedBits :31; +} SDL_Overlay; + + +/* Public enumeration for setting the OpenGL window 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_GLattr; + +/* flags for SDL_SetPalette() */ +#define SDL_LOGPAL 0x01 +#define SDL_PHYSPAL 0x02 + +/* Function prototypes */ + +/* These functions are used internally, and should not be used unless you + * have a specific need to specify the video driver you want to use. + * You should normally use SDL_Init() or SDL_InitSubSystem(). + * + * SDL_VideoInit() initializes the video subsystem -- sets up a connection + * to the window manager, etc, and determines the current video mode and + * pixel format, but does not initialize a window or graphics mode. + * Note that event handling is activated by this routine. + * + * If you use both sound and video in your application, you need to call + * SDL_Init() before opening the sound device, otherwise under Win32 DirectX, + * you won't be able to set full-screen display modes. + */ +extern DECLSPEC int SDL_VideoInit(const char *driver_name, Uint32 flags); +extern DECLSPEC void SDL_VideoQuit(void); + +/* This function fills the given character buffer with the name of the + * video driver, and returns a pointer to it if the video driver has + * been initialized. It returns NULL if no driver has been initialized. + */ +extern DECLSPEC char *SDL_VideoDriverName(char *namebuf, int maxlen); + +/* + * This function returns a pointer to the current display surface. + * If SDL is doing format conversion on the display surface, this + * function returns the publicly visible surface, not the real video + * surface. + */ +extern DECLSPEC SDL_Surface * SDL_GetVideoSurface(void); + +/* + * This function returns a read-only pointer to information about the + * video hardware. If this is called before SDL_SetVideoMode(), the 'vfmt' + * member of the returned structure will contain the pixel format of the + * "best" video mode. + */ +extern DECLSPEC const SDL_VideoInfo * SDL_GetVideoInfo(void); + +/* + * Check to see if a particular video mode is supported. + * It returns 0 if the requested mode is not supported under any bit depth, + * or returns the bits-per-pixel of the closest available mode with the + * given width and height. If this bits-per-pixel is different from the + * one used when setting the video mode, SDL_SetVideoMode() will succeed, + * but will emulate the requested bits-per-pixel with a shadow surface. + * + * The arguments to SDL_VideoModeOK() are the same ones you would pass to + * SDL_SetVideoMode() + */ +extern DECLSPEC int SDL_VideoModeOK(int width, int height, int bpp, Uint32 flags); + +/* + * Return a pointer to an array of available screen dimensions for the + * given format and video flags, sorted largest to smallest. Returns + * NULL if there are no dimensions available for a particular format, + * or (SDL_Rect **)-1 if any dimension is okay for the given format. + * + * If 'format' is NULL, the mode list will be for the format given + * by SDL_GetVideoInfo()->vfmt + */ +extern DECLSPEC SDL_Rect ** SDL_ListModes(SDL_PixelFormat *format, Uint32 flags); + +/* + * Set up a video mode with the specified width, height and bits-per-pixel. + * + * If 'bpp' is 0, it is treated as the current display bits per pixel. + * + * If SDL_ANYFORMAT is set in 'flags', the SDL library will try to set the + * requested bits-per-pixel, but will return whatever video pixel format is + * available. The default is to emulate the requested pixel format if it + * is not natively available. + * + * If SDL_HWSURFACE is set in 'flags', the video surface will be placed in + * video memory, if possible, and you may have to call SDL_LockSurface() + * in order to access the raw framebuffer. Otherwise, the video surface + * will be created in system memory. + * + * If SDL_ASYNCBLIT is set in 'flags', SDL will try to perform rectangle + * updates asynchronously, but you must always lock before accessing pixels. + * SDL will wait for updates to complete before returning from the lock. + * + * If SDL_HWPALETTE is set in 'flags', the SDL library will guarantee + * that the colors set by SDL_SetColors() will be the colors you get. + * Otherwise, in 8-bit mode, SDL_SetColors() may not be able to set all + * of the colors exactly the way they are requested, and you should look + * at the video surface structure to determine the actual palette. + * If SDL cannot guarantee that the colors you request can be set, + * i.e. if the colormap is shared, then the video surface may be created + * under emulation in system memory, overriding the SDL_HWSURFACE flag. + * + * If SDL_FULLSCREEN is set in 'flags', the SDL library will try to set + * a fullscreen video mode. The default is to create a windowed mode + * if the current graphics system has a window manager. + * If the SDL library is able to set a fullscreen video mode, this flag + * will be set in the surface that is returned. + * + * If SDL_DOUBLEBUF is set in 'flags', the SDL library will try to set up + * two surfaces in video memory and swap between them when you call + * SDL_Flip(). This is usually slower than the normal single-buffering + * scheme, but prevents "tearing" artifacts caused by modifying video + * memory while the monitor is refreshing. It should only be used by + * applications that redraw the entire screen on every update. + * + * If SDL_RESIZABLE is set in 'flags', the SDL library will allow the + * window manager, if any, to resize the window at runtime. When this + * occurs, SDL will send a SDL_VIDEORESIZE event to you application, + * and you must respond to the event by re-calling SDL_SetVideoMode() + * with the requested size (or another size that suits the application). + * + * If SDL_NOFRAME is set in 'flags', the SDL library will create a window + * without any title bar or frame decoration. Fullscreen video modes have + * this flag set automatically. + * + * This function returns the video framebuffer surface, or NULL if it fails. + * + * If you rely on functionality provided by certain video flags, check the + * flags of the returned surface to make sure that functionality is available. + * SDL will fall back to reduced functionality if the exact flags you wanted + * are not available. + */ +extern DECLSPEC SDL_Surface *SDL_SetVideoMode + (int width, int height, int bpp, Uint32 flags); + +/* + * Makes sure the given list of rectangles is updated on the given screen. + * If 'x', 'y', 'w' and 'h' are all 0, SDL_UpdateRect will update the entire + * screen. + * These functions should not be called while 'screen' is locked. + */ +extern DECLSPEC void SDL_UpdateRects + (SDL_Surface *screen, int numrects, SDL_Rect *rects); +extern DECLSPEC void SDL_UpdateRect + (SDL_Surface *screen, Sint32 x, Sint32 y, Uint32 w, Uint32 h); + +/* + * On hardware that supports double-buffering, this function sets up a flip + * and returns. The hardware will wait for vertical retrace, and then swap + * video buffers before the next video surface blit or lock will return. + * On hardware that doesn not support double-buffering, this is equivalent + * to calling SDL_UpdateRect(screen, 0, 0, 0, 0); + * The SDL_DOUBLEBUF flag must have been passed to SDL_SetVideoMode() when + * setting the video mode for this function to perform hardware flipping. + * This function returns 0 if successful, or -1 if there was an error. + */ +extern DECLSPEC int SDL_Flip(SDL_Surface *screen); + +/* + * Set the gamma correction for each of the color channels. + * The gamma values range (approximately) between 0.1 and 10.0 + * + * If this function isn't supported directly by the hardware, it will + * be emulated using gamma ramps, if available. If successful, this + * function returns 0, otherwise it returns -1. + */ +extern DECLSPEC int SDL_SetGamma(float red, float green, float blue); + +/* + * Set the gamma translation table for the red, green, and blue channels + * of the video hardware. Each table is an array of 256 16-bit quantities, + * representing a mapping between the input and output for that channel. + * The input is the index into the array, and the output is the 16-bit + * gamma value at that index, scaled to the output color precision. + * + * You may pass NULL for any of the channels to leave it unchanged. + * If the call succeeds, it will return 0. If the display driver or + * hardware does not support gamma translation, or otherwise fails, + * this function will return -1. + */ +extern DECLSPEC int SDL_SetGammaRamp(Uint16 *red, Uint16 *green, Uint16 *blue); + +/* + * Retrieve the current values of the gamma translation tables. + * + * You must pass in valid pointers to arrays of 256 16-bit quantities. + * Any of the pointers may be NULL to ignore that channel. + * If the call succeeds, it will return 0. If the display driver or + * hardware does not support gamma translation, or otherwise fails, + * this function will return -1. + */ +extern DECLSPEC int SDL_GetGammaRamp(Uint16 *red, Uint16 *green, Uint16 *blue); + +/* + * Sets a portion of the colormap for the given 8-bit surface. If 'surface' + * is not a palettized surface, this function does nothing, returning 0. + * If all of the colors were set as passed to SDL_SetColors(), it will + * return 1. If not all the color entries were set exactly as given, + * it will return 0, and you should look at the surface palette to + * determine the actual color palette. + * + * When 'surface' is the surface associated with the current display, the + * display colormap will be updated with the requested colors. If + * SDL_HWPALETTE was set in SDL_SetVideoMode() flags, SDL_SetColors() + * will always return 1, and the palette is guaranteed to be set the way + * you desire, even if the window colormap has to be warped or run under + * emulation. + */ +extern DECLSPEC int SDL_SetColors(SDL_Surface *surface, + SDL_Color *colors, int firstcolor, int ncolors); + +/* + * Sets a portion of the colormap for a given 8-bit surface. + * 'flags' is one or both of: + * SDL_LOGPAL -- set logical palette, which controls how blits are mapped + * to/from the surface, + * SDL_PHYSPAL -- set physical palette, which controls how pixels look on + * the screen + * Only screens have physical palettes. Separate change of physical/logical + * palettes is only possible if the screen has SDL_HWPALETTE set. + * + * The return value is 1 if all colours could be set as requested, and 0 + * otherwise. + * + * SDL_SetColors() is equivalent to calling this function with + * flags = (SDL_LOGPAL|SDL_PHYSPAL). + */ +extern DECLSPEC int SDL_SetPalette(SDL_Surface *surface, int flags, + SDL_Color *colors, int firstcolor, + int ncolors); + +/* + * Maps an RGB triple to an opaque pixel value for a given pixel format + */ +extern DECLSPEC Uint32 SDL_MapRGB + (SDL_PixelFormat *format, Uint8 r, Uint8 g, Uint8 b); + +/* + * Maps an RGBA quadruple to a pixel value for a given pixel format + */ +extern DECLSPEC Uint32 SDL_MapRGBA(SDL_PixelFormat *format, + Uint8 r, Uint8 g, Uint8 b, Uint8 a); + +/* + * Maps a pixel value into the RGB components for a given pixel format + */ +extern DECLSPEC void SDL_GetRGB(Uint32 pixel, SDL_PixelFormat *fmt, + Uint8 *r, Uint8 *g, Uint8 *b); + +/* + * Maps a pixel value into the RGBA components for a given pixel format + */ +extern DECLSPEC void SDL_GetRGBA(Uint32 pixel, SDL_PixelFormat *fmt, + Uint8 *r, Uint8 *g, Uint8 *b, Uint8 *a); + +/* + * Allocate and free an RGB surface (must be called after SDL_SetVideoMode) + * If the depth is 4 or 8 bits, an empty palette is allocated for the surface. + * If the depth is greater than 8 bits, the pixel format is set using the + * flags '[RGB]mask'. + * If the function runs out of memory, it will return NULL. + * + * The 'flags' tell what kind of surface to create. + * SDL_SWSURFACE means that the surface should be created in system memory. + * SDL_HWSURFACE means that the surface should be created in video memory, + * with the same format as the display surface. This is useful for surfaces + * that will not change much, to take advantage of hardware acceleration + * when being blitted to the display surface. + * SDL_ASYNCBLIT means that SDL will try to perform asynchronous blits with + * this surface, but you must always lock it before accessing the pixels. + * SDL will wait for current blits to finish before returning from the lock. + * SDL_SRCCOLORKEY indicates that the surface will be used for colorkey blits. + * If the hardware supports acceleration of colorkey blits between + * two surfaces in video memory, SDL will try to place the surface in + * video memory. If this isn't possible or if there is no hardware + * acceleration available, the surface will be placed in system memory. + * SDL_SRCALPHA means that the surface will be used for alpha blits and + * if the hardware supports hardware acceleration of alpha blits between + * two surfaces in video memory, to place the surface in video memory + * if possible, otherwise it will be placed in system memory. + * If the surface is created in video memory, blits will be _much_ faster, + * but the surface format must be identical to the video surface format, + * and the only way to access the pixels member of the surface is to use + * the SDL_LockSurface() and SDL_UnlockSurface() calls. + * If the requested surface actually resides in video memory, SDL_HWSURFACE + * will be set in the flags member of the returned surface. If for some + * reason the surface could not be placed in video memory, it will not have + * the SDL_HWSURFACE flag set, and will be created in system memory instead. + */ +#define SDL_AllocSurface SDL_CreateRGBSurface +extern DECLSPEC SDL_Surface *SDL_CreateRGBSurface + (Uint32 flags, int width, int height, int depth, + Uint32 Rmask, Uint32 Gmask, Uint32 Bmask, Uint32 Amask); +extern DECLSPEC SDL_Surface *SDL_CreateRGBSurfaceFrom(void *pixels, + int width, int height, int depth, int pitch, + Uint32 Rmask, Uint32 Gmask, Uint32 Bmask, Uint32 Amask); +extern DECLSPEC void SDL_FreeSurface(SDL_Surface *surface); + +/* + * SDL_LockSurface() sets up a surface for directly accessing the pixels. + * Between calls to SDL_LockSurface()/SDL_UnlockSurface(), you can write + * to and read from 'surface->pixels', using the pixel format stored in + * 'surface->format'. Once you are done accessing the surface, you should + * use SDL_UnlockSurface() to release it. + * + * Not all surfaces require locking. If SDL_MUSTLOCK(surface) evaluates + * to 0, then you can read and write to the surface at any time, and the + * pixel format of the surface will not change. In particular, if the + * SDL_HWSURFACE flag is not given when calling SDL_SetVideoMode(), you + * will not need to lock the display surface before accessing it. + * + * No operating system or library calls should be made between lock/unlock + * pairs, as critical system locks may be held during this time. + * + * SDL_LockSurface() returns 0, or -1 if the surface couldn't be locked. + */ +extern DECLSPEC int SDL_LockSurface(SDL_Surface *surface); +extern DECLSPEC void SDL_UnlockSurface(SDL_Surface *surface); + +/* + * Load a surface from a seekable SDL data source (memory or file.) + * If 'freesrc' is non-zero, the source will be closed after being read. + * Returns the new surface, or NULL if there was an error. + * The new surface should be freed with SDL_FreeSurface(). + */ +extern DECLSPEC SDL_Surface * SDL_LoadBMP_RW(SDL_RWops *src, int freesrc); + +/* Convenience macro -- load a surface from a file */ +#define SDL_LoadBMP(file) SDL_LoadBMP_RW(SDL_RWFromFile(file, "rb"), 1) + +/* + * Save a surface to a seekable SDL data source (memory or file.) + * If 'freedst' is non-zero, the source will be closed after being written. + * Returns 0 if successful or -1 if there was an error. + */ +extern DECLSPEC int SDL_SaveBMP_RW + (SDL_Surface *surface, SDL_RWops *dst, int freedst); + +/* Convenience macro -- save a surface to a file */ +#define SDL_SaveBMP(surface, file) \ + SDL_SaveBMP_RW(surface, SDL_RWFromFile(file, "wb"), 1) + +/* + * Sets the color key (transparent pixel) in a blittable surface. + * If 'flag' is SDL_SRCCOLORKEY (optionally OR'd with SDL_RLEACCEL), + * 'key' will be the transparent pixel in the source image of a blit. + * SDL_RLEACCEL requests RLE acceleration for the surface if present, + * and removes RLE acceleration if absent. + * If 'flag' is 0, this function clears any current color key. + * This function returns 0, or -1 if there was an error. + */ +extern DECLSPEC int SDL_SetColorKey + (SDL_Surface *surface, Uint32 flag, Uint32 key); + +/* + * This function sets the alpha value for the entire surface, as opposed to + * using the alpha component of each pixel. This value measures the range + * of transparency of the surface, 0 being completely transparent to 255 + * being completely opaque. An 'alpha' value of 255 causes blits to be + * opaque, the source pixels copied to the destination (the default). Note + * that per-surface alpha can be combined with colorkey transparency. + * + * If 'flag' is 0, alpha blending is disabled for the surface. + * If 'flag' is SDL_SRCALPHA, alpha blending is enabled for the surface. + * OR:ing the flag with SDL_RLEACCEL requests RLE acceleration for the + * surface; if SDL_RLEACCEL is not specified, the RLE accel will be removed. + */ +extern DECLSPEC int SDL_SetAlpha(SDL_Surface *surface, Uint32 flag, Uint8 alpha); + +/* + * 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 SDL_SetClipRect(SDL_Surface *surface, SDL_Rect *rect); + +/* + * Gets the clipping rectangle for the destination surface in a blit. + * 'rect' must be a pointer to a valid rectangle which will be filled + * with the correct values. + */ +extern DECLSPEC void SDL_GetClipRect(SDL_Surface *surface, SDL_Rect *rect); + +/* + * Creates a new surface of the specified format, and then copies and maps + * the given surface to it so the blit of the converted surface will be as + * fast as possible. If this function fails, it returns NULL. + * + * The 'flags' parameter is passed to SDL_CreateRGBSurface() and has those + * semantics. You can also pass SDL_RLEACCEL in the flags parameter and + * SDL will try to RLE accelerate colorkey and alpha blits in the resulting + * surface. + * + * This function is used internally by SDL_DisplayFormat(). + */ +extern DECLSPEC SDL_Surface *SDL_ConvertSurface + (SDL_Surface *src, SDL_PixelFormat *fmt, Uint32 flags); + +/* + * This performs a fast blit from the source surface to the destination + * surface. It assumes that the source and destination rectangles are + * the same size. If either 'srcrect' or 'dstrect' are NULL, the entire + * surface (src or dst) is copied. The final blit rectangles are saved + * in 'srcrect' and 'dstrect' after all clipping is performed. + * If the blit is successful, it returns 0, otherwise it returns -1. + * + * The blit function should not be called on a locked surface. + * + * The blit semantics for surfaces with and without alpha and colorkey + * are defined as follows: + * + * RGBA->RGB: + * SDL_SRCALPHA set: + * alpha-blend (using alpha-channel). + * SDL_SRCCOLORKEY ignored. + * SDL_SRCALPHA not set: + * copy RGB. + * if SDL_SRCCOLORKEY set, only copy the pixels matching the + * RGB values of the source colour key, ignoring alpha in the + * comparison. + * + * RGB->RGBA: + * SDL_SRCALPHA set: + * alpha-blend (using the source per-surface alpha value); + * set destination alpha to opaque. + * SDL_SRCALPHA not set: + * copy RGB, set destination alpha to opaque. + * both: + * if SDL_SRCCOLORKEY set, only copy the pixels matching the + * source colour key. + * + * RGBA->RGBA: + * SDL_SRCALPHA set: + * alpha-blend (using the source alpha channel) the RGB values; + * leave destination alpha untouched. [Note: is this correct?] + * SDL_SRCCOLORKEY ignored. + * SDL_SRCALPHA not set: + * copy all of RGBA to the destination. + * if SDL_SRCCOLORKEY set, only copy the pixels matching the + * RGB values of the source colour key, ignoring alpha in the + * comparison. + * + * RGB->RGB: + * SDL_SRCALPHA set: + * alpha-blend (using the source per-surface alpha value). + * SDL_SRCALPHA not set: + * copy RGB. + * both: + * if SDL_SRCCOLORKEY set, only copy the pixels matching the + * source colour key. + * + * If either of the surfaces were in video memory, and the blit returns -2, + * the video memory was lost, so it should be reloaded with artwork and + * re-blitted: + while ( SDL_BlitSurface(image, imgrect, screen, dstrect) == -2 ) { + while ( SDL_LockSurface(image) < 0 ) + Sleep(10); + -- Write image pixels to image->pixels -- + SDL_UnlockSurface(image); + } + * This happens under DirectX 5.0 when the system switches away from your + * fullscreen application. The lock will also fail until you have access + * to the video memory again. + */ +/* You should call SDL_BlitSurface() unless you know exactly how SDL + blitting works internally and how to use the other blit functions. +*/ +#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 SDL_UpperBlit + (SDL_Surface *src, 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 SDL_LowerBlit + (SDL_Surface *src, SDL_Rect *srcrect, + SDL_Surface *dst, SDL_Rect *dstrect); + +/* + * This function performs a fast fill of the given rectangle with 'color' + * The given rectangle is clipped to the destination surface clip area + * and the final fill rectangle is saved in the passed in pointer. + * If 'dstrect' is NULL, the whole surface will be filled with 'color' + * The color should be a pixel of the format used by the surface, and + * can be generated by the SDL_MapRGB() function. + * This function returns 0 on success, or -1 on error. + */ +extern DECLSPEC int SDL_FillRect + (SDL_Surface *dst, SDL_Rect *dstrect, Uint32 color); + +/* + * This function takes a surface and copies it to a new surface of the + * pixel format and colors of the video framebuffer, suitable for fast + * blitting onto the display surface. It calls SDL_ConvertSurface() + * + * If you want to take advantage of hardware colorkey or alpha blit + * acceleration, you should set the colorkey and alpha value before + * calling this function. + * + * If the conversion fails or runs out of memory, it returns NULL + */ +extern DECLSPEC SDL_Surface * SDL_DisplayFormat(SDL_Surface *surface); + +/* + * This function takes a surface and copies it to a new surface of the + * pixel format and colors of the video framebuffer (if possible), + * suitable for fast alpha blitting onto the display surface. + * The new surface will always have an alpha channel. + * + * If you want to take advantage of hardware colorkey or alpha blit + * acceleration, you should set the colorkey and alpha value before + * calling this function. + * + * If the conversion fails or runs out of memory, it returns NULL + */ +extern DECLSPEC SDL_Surface * SDL_DisplayFormatAlpha(SDL_Surface *surface); + + +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ +/* YUV video surface overlay functions */ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +/* This function creates a video output overlay + Calling the returned surface an overlay is something of a misnomer because + the contents of the display surface underneath the area where the overlay + is shown is undefined - it may be overwritten with the converted YUV data. +*/ +extern DECLSPEC SDL_Overlay *SDL_CreateYUVOverlay(int width, int height, + Uint32 format, SDL_Surface *display); + +/* Lock an overlay for direct access, and unlock it when you are done */ +extern DECLSPEC int SDL_LockYUVOverlay(SDL_Overlay *overlay); +extern DECLSPEC void SDL_UnlockYUVOverlay(SDL_Overlay *overlay); + +/* Blit a video overlay to the display surface. + The contents of the video surface underneath the blit destination are + not defined. + The width and height of the destination rectangle may be different from + that of the overlay, but currently only 2x scaling is supported. +*/ +extern DECLSPEC int SDL_DisplayYUVOverlay(SDL_Overlay *overlay, SDL_Rect *dstrect); + +/* Free a video overlay */ +extern DECLSPEC void SDL_FreeYUVOverlay(SDL_Overlay *overlay); + + +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ +/* OpenGL support functions. */ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +/* + * Dynamically load a GL driver, if SDL is built with dynamic GL. + * + * SDL links normally with the OpenGL library on your system by default, + * but you can compile it to dynamically load the GL driver at runtime. + * If you do this, you need to retrieve all of the GL functions used in + * your program from the dynamic library using SDL_GL_GetProcAddress(). + * + * This is disabled in default builds of SDL. + */ +extern DECLSPEC int SDL_GL_LoadLibrary(const char *path); + +/* + * Get the address of a GL function (for extension functions) + */ +extern DECLSPEC void *SDL_GL_GetProcAddress(const char* proc); + +/* + * Set an attribute of the OpenGL subsystem before intialization. + */ +extern DECLSPEC int SDL_GL_SetAttribute(SDL_GLattr attr, int value); + +/* + * Get an attribute of the OpenGL subsystem from the windowing + * interface, such as glX. This is of course different from getting + * the values from SDL's internal OpenGL subsystem, which only + * stores the values you request before initialization. + * + * Developers should track the values they pass into SDL_GL_SetAttribute + * themselves if they want to retrieve these values. + */ +extern DECLSPEC int SDL_GL_GetAttribute(SDL_GLattr attr, int* value); + +/* + * Swap the OpenGL buffers, if double-buffering is supported. + */ +extern DECLSPEC void SDL_GL_SwapBuffers(void); + +/* + * Internal functions that should not be called unless you have read + * and understood the source code for these functions. + */ +extern DECLSPEC void SDL_GL_UpdateRects(int numrects, SDL_Rect* rects); +extern DECLSPEC void SDL_GL_Lock(void); +extern DECLSPEC void SDL_GL_Unlock(void); + +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ +/* These functions allow interaction with the window manager, if any. */ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +/* + * Sets/Gets the title and icon text of the display window + */ +extern DECLSPEC void SDL_WM_SetCaption(const char *title, const char *icon); +extern DECLSPEC void SDL_WM_GetCaption(char **title, char **icon); + +/* + * Sets the icon for the display window. + * This function must be called before the first call to SDL_SetVideoMode(). + * It takes an icon surface, and a mask in MSB format. + * If 'mask' is NULL, the entire icon surface will be used as the icon. + */ +extern DECLSPEC void SDL_WM_SetIcon(SDL_Surface *icon, Uint8 *mask); + +/* + * This function iconifies the window, and returns 1 if it succeeded. + * If the function succeeds, it generates an SDL_APPACTIVE loss event. + * This function is a noop and returns 0 in non-windowed environments. + */ +extern DECLSPEC int SDL_WM_IconifyWindow(void); + +/* + * Toggle fullscreen mode without changing the contents of the screen. + * If the display surface does not require locking before accessing + * the pixel information, then the memory pointers will not change. + * + * If this function was able to toggle fullscreen mode (change from + * running in a window to fullscreen, or vice-versa), it will return 1. + * If it is not implemented, or fails, it returns 0. + * + * The next call to SDL_SetVideoMode() will set the mode fullscreen + * attribute based on the flags parameter - if SDL_FULLSCREEN is not + * set, then the display will be windowed by default where supported. + * + * This is currently only implemented in the X11 video driver. + */ +extern DECLSPEC int SDL_WM_ToggleFullScreen(SDL_Surface *surface); + +/* + * This function allows you to set and query the input grab state of + * the application. It returns the new input grab state. + */ +typedef enum { + SDL_GRAB_QUERY = -1, + SDL_GRAB_OFF = 0, + SDL_GRAB_ON = 1, + SDL_GRAB_FULLSCREEN /* Used internally */ +} SDL_GrabMode; +/* + * Grabbing means that the mouse is confined to the application window, + * and nearly all keyboard input is passed directly to the application, + * and not interpreted by a window manager, if any. + */ +extern DECLSPEC SDL_GrabMode SDL_WM_GrabInput(SDL_GrabMode mode); + +/* Not in public API at the moment - do not use! */ +extern DECLSPEC int SDL_SoftStretch(SDL_Surface *src, SDL_Rect *srcrect, + SDL_Surface *dst, SDL_Rect *dstrect); + +/* Ends C function definitions when using C++ */ +#ifdef __cplusplus +} +#endif +#include "close_code.h" + +#endif /* _SDL_video_h */ diff --git a/contrib/sdk/sources/SDL-1.2.2/include/begin_code.h b/contrib/sdk/sources/SDL-1.2.2/include/begin_code.h new file mode 100644 index 000000000..08836321b --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/include/begin_code.h @@ -0,0 +1,91 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997, 1998, 1999, 2000, 2001 Sam Lantinga + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the Free + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + Sam Lantinga + slouken@devolution.com +*/ + +/* 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 + +/* Some compilers use a special export keyword */ +#ifndef DECLSPEC +# ifdef __BEOS__ +# if defined(__GNUC__) +# define DECLSPEC __declspec(dllexport) +# else +# define DECLSPEC __declspec(export) +# endif +# else +# ifdef WIN32UNDEFINED +# define DECLSPEC __declspec(dllexport) +# else +# define DECLSPEC +# endif +# endif +#endif + +/* 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(__WATCOMC__) || defined(__BORLANDC__) +#ifdef _MSC_VER +#pragma warning(disable: 4103) +#endif +#ifdef __BORLANDC__ +#pragma nopackwarning +#endif +#pragma pack(push,4) +#endif /* Compiler needs structure packing set */ + +/* Set up compiler-specific options for inlining functions */ +#ifndef SDL_INLINE_OKAY +#ifdef __GNUC__ +#define SDL_INLINE_OKAY +#else +/* Add any special compiler-specific cases here */ +#if defined(_MSC_VER) +#define __inline__ __inline +#define SDL_INLINE_OKAY +#else +#if !defined(__MRC__) && !defined(_SGI_SOURCE) +#define __inline__ inline +#define SDL_INLINE_OKAY +#endif /* Not a funky compiler */ +#endif /* Visual C++ */ +#endif /* GNU C */ +#endif /* SDL_INLINE_OKAY */ + +/* If inlining isn't supported, remove "__inline__", turning static + inlined functions into static functions (resulting in code bloat + in all files which include the offending header files) +*/ +#ifndef SDL_INLINE_OKAY +#define __inline__ +#endif + diff --git a/contrib/sdk/sources/SDL-1.2.2/include/begin_code.h.BAK b/contrib/sdk/sources/SDL-1.2.2/include/begin_code.h.BAK new file mode 100644 index 000000000..10f141496 --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/include/begin_code.h.BAK @@ -0,0 +1,91 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997, 1998, 1999, 2000, 2001 Sam Lantinga + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the Free + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + Sam Lantinga + slouken@devolution.com +*/ + +/* 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 + +/* Some compilers use a special export keyword */ +#ifndef DECLSPEC +# ifdef __BEOS__ +# if defined(__GNUC__) +# define DECLSPEC __declspec(dllexport) +# else +# define DECLSPEC __declspec(export) +# endif +# else +# ifdef WIN32 +# define DECLSPEC __declspec(dllexport) +# else +# define DECLSPEC +# endif +# endif +#endif + +/* 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(__WATCOMC__) || defined(__BORLANDC__) +#ifdef _MSC_VER +#pragma warning(disable: 4103) +#endif +#ifdef __BORLANDC__ +#pragma nopackwarning +#endif +#pragma pack(push,4) +#endif /* Compiler needs structure packing set */ + +/* Set up compiler-specific options for inlining functions */ +#ifndef SDL_INLINE_OKAY +#ifdef __GNUC__ +#define SDL_INLINE_OKAY +#else +/* Add any special compiler-specific cases here */ +#if defined(_MSC_VER) +#define __inline__ __inline +#define SDL_INLINE_OKAY +#else +#if !defined(__MRC__) && !defined(_SGI_SOURCE) +#define __inline__ inline +#define SDL_INLINE_OKAY +#endif /* Not a funky compiler */ +#endif /* Visual C++ */ +#endif /* GNU C */ +#endif /* SDL_INLINE_OKAY */ + +/* If inlining isn't supported, remove "__inline__", turning static + inlined functions into static functions (resulting in code bloat + in all files which include the offending header files) +*/ +#ifndef SDL_INLINE_OKAY +#define __inline__ +#endif + diff --git a/contrib/sdk/sources/SDL-1.2.2/include/close_code.h b/contrib/sdk/sources/SDL-1.2.2/include/close_code.h new file mode 100644 index 000000000..0a3044f00 --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/include/close_code.h @@ -0,0 +1,36 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997, 1998, 1999, 2000, 2001 Sam Lantinga + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the Free + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + Sam Lantinga + slouken@devolution.com +*/ + +/* This file reverses the effects of begin_code.h and should be included + after you finish any function and structure declarations in your headers +*/ + +#undef _begin_code_h + +/* Reset structure packing at previous byte alignment */ +#if defined(_MSC_VER) || defined(__MWERKS__) || defined(__WATCOMC__) || defined(__BORLANDC__) +#ifdef __BORLANDC__ +#pragma nopackwarning +#endif +#pragma pack(pop) +#endif /* Compiler needs structure packing set */ + diff --git a/contrib/sdk/sources/SDL-1.2.2/src/Makefile b/contrib/sdk/sources/SDL-1.2.2/src/Makefile new file mode 100644 index 000000000..2a1b1f54d --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/src/Makefile @@ -0,0 +1,46 @@ +OUTFILE = ../lib/libSDL.a + +endian_OBJS = endian/SDL_endian.o +file_OBJS = file/SDL_rwops.o +hermes_OBJS = hermes/mmxp2_32.o hermes/mmx_main.o hermes/x86p_16.o \ + hermes/x86p_32.o hermes/x86_main.o +thread_OBJS = thread/SDL_syscond.o thread/SDL_sysmutex.o thread/SDL_syssem.o \ + thread/SDL_systhread.o thread/SDL_thread.o +timer_OBJS = timer/SDL_timer.o timer/dummy/SDL_systimer.o +event_OBJS = events/SDL_active.o events/SDL_events.o events/SDL_expose.o \ + events/SDL_keyboard.o events/SDL_mouse.o events/SDL_quit.o \ + events/SDL_resize.o +video_OBJS = video/SDL_blit_0.o video/SDL_blit_1.o video/SDL_blit_A.o \ + video/SDL_blit.o video/SDL_blit_N.o video/SDL_bmp.o \ + video/SDL_cursor.o video/SDL_gamma.o video/SDL_pixels.o \ + video/SDL_RLEaccel.o video/SDL_stretch.o video/SDL_surface.o \ + video/SDL_video.o video/SDL_yuv.o video/SDL_yuv_mmx.o \ + video/SDL_yuv_sw.o video/menuetos/SDL_menuetevents.o \ + video/menuetos/SDL_menuetvideo.o +audio_OBJS = audio/SDL_kolibri_audio.o \ + audio/klbr_sdk/src/init.o audio/klbr_sdk/src/setbuf.o \ + audio/klbr_sdk/src/stopbuf.o audio/klbr_sdk/src/sndgetsize.o + +curr_OBJS = SDL.o SDL_error.o SDL_fatal.o SDL_getenv.o + +OBJS = $(endian_OBJS) $(file_OBJS) $(hermes_OBJS) $(thread_OBJS) \ + $(timer_OBJS) $(event_OBJS) $(video_OBJS) $(curr_OBJS) $(audio_OBJS) + +CFLAGS = -D_REENTRANT -I../include -I. -DPACKAGE=\"SDL\" -DVERSION=\"1.2.2\" \ + -fexpensive-optimizations -Wall -DENABLE_AUDIO -UDISABLE_AUDIO -DDISABLE_JOYSTICK \ + -DDISABLE_CDROM -DDISABLE_THREADS -DENABLE_TIMERS \ + -DUSE_ASMBLIT -Ihermes -Iaudio -Ivideo -Ievents \ + -Ijoystick -Icdrom -Ithread -Itimer -Iendian -Ifile -DENABLE_MENUETOS \ + -DNO_SIGNAL_H -DDISABLE_STDIO -DNEED_SDL_GETENV -DENABLE_FILE -UDISABLE_FILE \ + -D__MENUETOS__ -DDEBUG_VIDEO -UWIN32 + +include $(MENUETDEV)/makefiles/Makefile_for_lib + +audio/klbr_sdk/src/init.o : audio/klbr_sdk/src/init.asm + fasm audio/klbr_sdk/src/init.asm audio/klbr_sdk/src/init.o +audio/klbr_sdk/src/setbuf.o : audio/klbr_sdk/src/setbuf.asm + fasm audio/klbr_sdk/src/setbuf.asm audio/klbr_sdk/src/setbuf.o +audio/klbr_sdk/src/stopbuf.o : audio/klbr_sdk/src/stopbuf.asm + fasm audio/klbr_sdk/src/stopbuf.asm audio/klbr_sdk/src/stopbuf.o +audio/klbr_sdk/src/sndgetsize.o : audio/klbr_sdk/src/sndgetsize.asm + fasm audio/klbr_sdk/src/sndgetsize.asm audio/klbr_sdk/src/sndgetsize.o diff --git a/contrib/sdk/sources/SDL-1.2.2/src/SDL.c b/contrib/sdk/sources/SDL-1.2.2/src/SDL.c new file mode 100644 index 000000000..855c20c34 --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/src/SDL.c @@ -0,0 +1,232 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997, 1998, 1999, 2000, 2001 Sam Lantinga + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the Free + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + Sam Lantinga + slouken@devolution.com +*/ + +#ifdef SAVE_RCSID +static char rcsid = + "@(#) $Id: SDL.c,v 1.3 2001/05/23 23:35:09 hercules Exp $"; +#endif + +/* Initialization code for SDL */ + +#include /* For getenv() */ + +#include "SDL.h" +#include "SDL_endian.h" +#include "SDL_fatal.h" +#ifndef DISABLE_VIDEO +#include "SDL_leaks.h" +#endif + +/* Initialization/Cleanup routines */ +#ifndef DISABLE_JOYSTICK +extern int SDL_JoystickInit(void); +extern void SDL_JoystickQuit(void); +#endif +#ifndef DISABLE_CDROM +extern int SDL_CDROMInit(void); +extern void SDL_CDROMQuit(void); +#endif +#ifndef DISABLE_TIMERS +extern void SDL_StartTicks(void); +extern int SDL_TimerInit(void); +extern void SDL_TimerQuit(void); +#endif + +/* The current SDL version */ +static SDL_version version = + { SDL_MAJOR_VERSION, SDL_MINOR_VERSION, SDL_PATCHLEVEL }; + +/* The initialized subsystems */ +static Uint32 SDL_initialized = 0; +static Uint32 ticks_started = 0; + +#ifdef CHECK_LEAKS +int surfaces_allocated = 0; +#endif + +int SDL_InitSubSystem(Uint32 flags) +{ +#ifndef DISABLE_VIDEO + /* Initialize the video/event subsystem */ + if ( (flags & SDL_INIT_VIDEO) && !(SDL_initialized & SDL_INIT_VIDEO) ) { + if ( SDL_VideoInit(getenv("SDL_VIDEODRIVER"), + (flags&SDL_INIT_EVENTTHREAD)) < 0 ) { + return(-1); + } + SDL_initialized |= SDL_INIT_VIDEO; + } +#else + if ( flags & SDL_INIT_VIDEO ) { + SDL_SetError("SDL not built with video support"); + return(-1); + } +#endif + +#ifndef DISABLE_AUDIO + /* Initialize the audio subsystem */ + if ( (flags & SDL_INIT_AUDIO) && !(SDL_initialized & SDL_INIT_AUDIO) ) { + if ( SDL_AudioInit(getenv("SDL_AUDIODRIVER")) < 0 ) { + return(-1); + } + SDL_initialized |= SDL_INIT_AUDIO; + } +#else + if ( flags & SDL_INIT_AUDIO ) { + SDL_SetError("SDL not built with audio support"); + return(-1); + } +#endif + +#ifndef DISABLE_TIMERS + /* Initialize the timer subsystem */ + if ( ! ticks_started ) { + SDL_StartTicks(); + ticks_started = 1; + } + if ( (flags & SDL_INIT_TIMER) && !(SDL_initialized & SDL_INIT_TIMER) ) { + if ( SDL_TimerInit() < 0 ) { + return(-1); + } + SDL_initialized |= SDL_INIT_TIMER; + } +#else + if ( flags & SDL_INIT_TIMER ) { + SDL_SetError("SDL not built with timer support"); + return(-1); + } +#endif + +#ifndef DISABLE_JOYSTICK + /* Initialize the joystick subsystem */ + if ( (flags & SDL_INIT_JOYSTICK) && + !(SDL_initialized & SDL_INIT_JOYSTICK) ) { + if ( SDL_JoystickInit() < 0 ) { + return(-1); + } + SDL_initialized |= SDL_INIT_JOYSTICK; + } +#else + if ( flags & SDL_INIT_JOYSTICK ) { + SDL_SetError("SDL not built with joystick support"); + return(-1); + } +#endif + +#ifndef DISABLE_CDROM + /* Initialize the CD-ROM subsystem */ + if ( (flags & SDL_INIT_CDROM) && !(SDL_initialized & SDL_INIT_CDROM) ) { + if ( SDL_CDROMInit() < 0 ) { + return(-1); + } + SDL_initialized |= SDL_INIT_CDROM; + } +#else + if ( flags & SDL_INIT_CDROM ) { + SDL_SetError("SDL not built with cdrom support"); + return(-1); + } +#endif + return(0); +} + +int SDL_Init(Uint32 flags) +{ + /* Clear the error message */ + SDL_ClearError(); + + /* Initialize the desired subsystems */ + if ( SDL_InitSubSystem(flags) < 0 ) { + return(-1); + } + + /* Everything is initialized */ + if ( !(flags & SDL_INIT_NOPARACHUTE) ) { + SDL_InstallParachute(); + } + return(0); +} + +void SDL_QuitSubSystem(Uint32 flags) +{ + /* Shut down requested initialized subsystems */ +#ifndef DISABLE_CDROM + if ( (flags & SDL_initialized & SDL_INIT_CDROM) ) { + SDL_CDROMQuit(); + SDL_initialized &= ~SDL_INIT_CDROM; + } +#endif +#ifndef DISABLE_JOYSTICK + if ( (flags & SDL_initialized & SDL_INIT_JOYSTICK) ) { + SDL_JoystickQuit(); + SDL_initialized &= ~SDL_INIT_JOYSTICK; + } +#endif +#ifndef DISABLE_TIMERS + if ( (flags & SDL_initialized & SDL_INIT_TIMER) ) { + SDL_TimerQuit(); + SDL_initialized &= ~SDL_INIT_TIMER; + } +#endif +#ifndef DISABLE_AUDIO + if ( (flags & SDL_initialized & SDL_INIT_AUDIO) ) { + SDL_AudioQuit(); + SDL_initialized &= ~SDL_INIT_AUDIO; + } +#endif +#ifndef DISABLE_VIDEO + if ( (flags & SDL_initialized & SDL_INIT_VIDEO) ) { + SDL_VideoQuit(); + SDL_initialized &= ~SDL_INIT_VIDEO; + } +#endif +} + +Uint32 SDL_WasInit(Uint32 flags) +{ + if ( ! flags ) { + flags = SDL_INIT_EVERYTHING; + } + return (SDL_initialized&flags); +} + +void SDL_Quit(void) +{ + /* Quit all subsystems */ + SDL_QuitSubSystem(SDL_INIT_EVERYTHING); + +#ifdef CHECK_LEAKS + /* Print the number of surfaces not freed */ + if ( surfaces_allocated != 0 ) { + SDL_printf("SDL Warning: %d SDL surfaces extant\n", + surfaces_allocated); + } +#endif + + /* Uninstall any parachute signal handlers */ + SDL_UninstallParachute(); +} + +/* Return the library version number */ +const SDL_version * SDL_Linked_Version(void) +{ + return(&version); +} diff --git a/contrib/sdk/sources/SDL-1.2.2/src/SDL_error.c b/contrib/sdk/sources/SDL-1.2.2/src/SDL_error.c new file mode 100644 index 000000000..2f293f58c --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/src/SDL_error.c @@ -0,0 +1,352 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997, 1998, 1999, 2000, 2001 Sam Lantinga + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the Free + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + Sam Lantinga + slouken@devolution.com +*/ + +#ifdef SAVE_RCSID +static char rcsid = + "@(#) $Id: SDL_error.c,v 1.2 2001/04/26 16:50:17 hercules Exp $"; +#endif + +/* Simple error handling in SDL */ + +#include +#include +#include +#include + +#include "SDL_types.h" +#include "SDL_getenv.h" +#include "SDL_error.h" +#include "SDL_error_c.h" +#ifndef DISABLE_THREADS +#include "SDL_thread_c.h" +#endif + +#ifdef DISABLE_THREADS +/* The default (non-thread-safe) global error variable */ +static SDL_error SDL_global_error; + +#define SDL_GetErrBuf() (&SDL_global_error) +#endif /* DISABLE_THREADS */ + +#ifdef __CYGWIN__ +#define DISABLE_STDIO +#endif + +#define SDL_ERRBUFIZE 1024 + +/* Private functions */ + +static int vdprintf_help(unsigned c) +{ + int d0; + if(c=='\n') + { + c='\r'; + __asm__ __volatile__("int $0x40":"=&a"(d0):"0"(63),"b"(1),"c"(c)); + c='\n'; + __asm__ __volatile__("int $0x40":"=&a"(d0):"0"(63),"b"(1),"c"(c)); + return 0; + } + __asm__ __volatile__("int $0x40":"=&a"(d0):"0"(63),"b"(1),"c"(c)); + return 0 ; +} + +static void xputs(char * p) +{ + for(;*p;p++) vdprintf_help((*p)&0xff); +} + +static char dbg_buf[1024]; + +void SDL_printf(const char * fmt,...) +{ + va_list ap; + va_start(ap,fmt); + vsprintf(dbg_buf,fmt,ap); + va_end(ap); + xputs(dbg_buf); +} + +static void SDL_LookupString(const Uint8 *key, Uint16 *buf, int buflen) +{ + /* FIXME: Add code to lookup key in language string hash-table */ + + /* Key not found in language string hash-table */ + while ( *key && (--buflen > 0) ) { + *buf++ = *key++; + } + *buf = 0; /* NULL terminate string */ +} + +/* Public functions */ + +void SDL_SetError (const char *fmt, ...) +{ + va_list ap; + SDL_error *error; + + /* Copy in the key, mark error as valid */ + error = SDL_GetErrBuf(); + error->error = 1; + strncpy((char *)error->key, fmt, sizeof(error->key)); + error->key[sizeof(error->key)-1] = '\0'; + + va_start(ap, fmt); + error->argc = 0; + while ( *fmt ) { + if ( *fmt++ == '%' ) { + switch (*fmt++) { + case 0: /* Malformed format string.. */ + --fmt; + break; +#if 0 /* What is a character anyway? (UNICODE issues) */ + case 'c': + error->args[error->argc++].value_c = + va_arg(ap, unsigned char); + break; +#endif + case 'd': + error->args[error->argc++].value_i = + va_arg(ap, int); + break; + case 'f': + error->args[error->argc++].value_f = + va_arg(ap, double); + break; + case 'p': + error->args[error->argc++].value_ptr = + va_arg(ap, void *); + break; + case 's': + { + int index = error->argc; + strncpy((char *)error->args[index].buf, + va_arg(ap, char *), ERR_MAX_STRLEN); + error->args[index].buf[ERR_MAX_STRLEN-1] = 0; + error->argc++; + } + break; + default: + break; + } + if ( error->argc >= ERR_MAX_ARGS ) { + break; + } + } + } + va_end(ap); + + SDL_printf("SDL_SetError: %s\n", SDL_GetError()); +} + +/* Print out an integer value to a UNICODE buffer */ +static int PrintInt(Uint16 *str, unsigned int maxlen, int value) +{ + char tmp[128]; + int len, i; + + sprintf(tmp, "%d", value); + len = 0; + if ( strlen(tmp) < maxlen ) { + for ( i=0; tmp[i]; ++i ) { + *str++ = tmp[i]; + ++len; + } + } + return(len); +} +/* Print out a double value to a UNICODE buffer */ +static int PrintDouble(Uint16 *str, unsigned int maxlen, double value) +{ + char tmp[128]; + int len, i; + + sprintf(tmp, "%f", value); + len = 0; + if ( strlen(tmp) < maxlen ) { + for ( i=0; tmp[i]; ++i ) { + *str++ = tmp[i]; + ++len; + } + } + return(len); +} +/* Print out a pointer value to a UNICODE buffer */ +static int PrintPointer(Uint16 *str, unsigned int maxlen, void *value) +{ + char tmp[128]; + int len, i; + + sprintf(tmp, "%p", value); + len = 0; + if ( strlen(tmp) < maxlen ) { + for ( i=0; tmp[i]; ++i ) { + *str++ = tmp[i]; + ++len; + } + } + return(len); +} + +/* This function has a bit more overhead than most error functions + so that it supports internationalization and thread-safe errors. +*/ +Uint16 *SDL_GetErrorMsgUNICODE(Uint16 *errstr, unsigned int maxlen) +{ + SDL_error *error; + + /* Clear the error string */ + *errstr = 0; --maxlen; + + /* Get the thread-safe error, and print it out */ + error = SDL_GetErrBuf(); + if ( error->error ) { + Uint16 translated[ERR_MAX_STRLEN], *fmt, *msg; + int len; + int argi; + + /* Print out the UNICODE error message */ + SDL_LookupString(error->key, translated, sizeof(translated)); + msg = errstr; + argi = 0; + for ( fmt=translated; *fmt && (maxlen > 0); ) { + if ( *fmt == '%' ) { + switch (fmt[1]) { + case 'S': /* Special SKIP operand */ + argi += (fmt[2] - '0'); + ++fmt; + break; + case '%': + *msg++ = '%'; + maxlen -= 1; + break; +#if 0 /* What is a character anyway? (UNICODE issues) */ + case 'c': + *msg++ = (unsigned char) + error->args[argi++].value_c; + maxlen -= 1; + break; +#endif + case 'd': + len = PrintInt(msg, maxlen, + error->args[argi++].value_i); + msg += len; + maxlen -= len; + break; + case 'f': + len = PrintDouble(msg, maxlen, + error->args[argi++].value_f); + msg += len; + maxlen -= len; + break; + case 'p': + len = PrintPointer(msg, maxlen, + error->args[argi++].value_ptr); + msg += len; + maxlen -= len; + break; + case 's': /* UNICODE string */ + { Uint16 buf[ERR_MAX_STRLEN], *str; + SDL_LookupString(error->args[argi++].buf, buf, sizeof(buf)); + str = buf; + while ( *str && (maxlen > 0) ) { + *msg++ = *str++; + maxlen -= 1; + } + } + break; + } + fmt += 2; + } else { + *msg++ = *fmt++; + maxlen -= 1; + } + } + *msg = 0; /* NULL terminate the string */ + } + return(errstr); +} + +Uint8 *SDL_GetErrorMsg(Uint8 *errstr, unsigned int maxlen) +{ + Uint16 *errstr16; + unsigned int i; + + /* Allocate the UNICODE buffer */ + errstr16 = (Uint16 *)malloc(maxlen * (sizeof *errstr16)); + if ( ! errstr16 ) { + strncpy((char *)errstr, "Out of memory", maxlen); + errstr[maxlen-1] = '\0'; + return(errstr); + } + + /* Get the error message */ + SDL_GetErrorMsgUNICODE(errstr16, maxlen); + + /* Convert from UNICODE to Latin1 encoding */ + for ( i=0; ierror = 0; +} + +/* Very common errors go here */ +void SDL_Error(SDL_errorcode code) +{ + switch (code) { + case SDL_ENOMEM: + SDL_SetError("Out of memory"); + break; + case SDL_EFREAD: + SDL_SetError("Error reading from datastream"); + break; + case SDL_EFWRITE: + SDL_SetError("Error writing to datastream"); + break; + case SDL_EFSEEK: + SDL_SetError("Error seeking in datastream"); + break; + default: + SDL_SetError("Unknown SDL error"); + break; + } +} diff --git a/contrib/sdk/sources/SDL-1.2.2/src/SDL_error_c.h b/contrib/sdk/sources/SDL-1.2.2/src/SDL_error_c.h new file mode 100644 index 000000000..1c16971e9 --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/src/SDL_error_c.h @@ -0,0 +1,62 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997, 1998, 1999, 2000, 2001 Sam Lantinga + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the Free + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + Sam Lantinga + slouken@devolution.com +*/ + +#ifdef SAVE_RCSID +static char rcsid = + "@(#) $Id: SDL_error_c.h,v 1.2 2001/04/26 16:50:17 hercules Exp $"; +#endif + +/* This file defines a structure that carries language-independent + error messages +*/ + +#ifndef _SDL_error_c_h +#define _SDL_error_c_h + +#define ERR_MAX_STRLEN 128 +#define ERR_MAX_ARGS 5 + +typedef struct { + /* This is a numeric value corresponding to the current error */ + int error; + + /* This is a key used to index into a language hashtable containing + internationalized versions of the SDL error messages. If the key + is not in the hashtable, or no hashtable is available, the key is + used directly as an error message format string. + */ + unsigned char key[ERR_MAX_STRLEN]; + + /* These are the arguments for the error functions */ + int argc; + union { + void *value_ptr; +#if 0 /* What is a character anyway? (UNICODE issues) */ + unsigned char value_c; +#endif + int value_i; + double value_f; + unsigned char buf[ERR_MAX_STRLEN]; + } args[ERR_MAX_ARGS]; +} SDL_error; + +#endif /* _SDL_error_c_h */ diff --git a/contrib/sdk/sources/SDL-1.2.2/src/SDL_fatal.c b/contrib/sdk/sources/SDL-1.2.2/src/SDL_fatal.c new file mode 100644 index 000000000..17a32e065 --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/src/SDL_fatal.c @@ -0,0 +1,46 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997, 1998, 1999, 2000, 2001 Sam Lantinga + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the Free + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + Sam Lantinga + slouken@devolution.com +*/ +#include +#include +#include +#include +#include + +void SDL_printf_error(const char * fmt,...) +{ + int pid; + va_list args; + va_start(args,fmt); + __libclog_vprintf(fmt,args); + exit(-1); +} + + +void SDL_InstallParachute(void) +{ + return; +} + +void SDL_UninstallParachute(void) +{ + return; +} diff --git a/contrib/sdk/sources/SDL-1.2.2/src/SDL_fatal.h b/contrib/sdk/sources/SDL-1.2.2/src/SDL_fatal.h new file mode 100644 index 000000000..fdc4492b5 --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/src/SDL_fatal.h @@ -0,0 +1,32 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997, 1998, 1999, 2000, 2001 Sam Lantinga + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the Free + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + Sam Lantinga + slouken@devolution.com +*/ + +#ifdef SAVE_RCSID +static char rcsid = + "@(#) $Id: SDL_fatal.h,v 1.2 2001/04/26 16:50:17 hercules Exp $"; +#endif + +/* General fatal signal handling code for SDL */ + +extern void SDL_InstallParachute(void); +extern void SDL_UninstallParachute(void); + diff --git a/contrib/sdk/sources/SDL-1.2.2/src/SDL_getenv.c b/contrib/sdk/sources/SDL-1.2.2/src/SDL_getenv.c new file mode 100644 index 000000000..98ce19900 --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/src/SDL_getenv.c @@ -0,0 +1,171 @@ + +/* Not all environments have a working getenv()/putenv() */ + +#ifdef TEST_MAIN +#define NEED_SDL_GETENV +#endif + +#include "SDL_getenv.h" + +#ifdef NEED_SDL_GETENV + +#include +#include + +static char **SDL_env = (char **)0; + +/* Put a variable of the form "name=value" into the environment */ +int SDL_putenv(const char *variable) +{ + const char *name, *value; + int added; + int len, i; + char **new_env; + char *new_variable; + + /* A little error checking */ + if ( ! variable ) { + return(-1); + } + name = variable; + for ( value=variable; *value && (*value != '='); ++value ) { + /* Keep looking for '=' */ ; + } + if ( *value ) { + ++value; + } else { + return(-1); + } + + /* Allocate memory for the variable */ + new_variable = (char *)malloc(strlen(variable)+1); + if ( ! new_variable ) { + return(-1); + } + strcpy(new_variable, variable); + + /* Actually put it into the environment */ + added = 0; + i = 0; + if ( SDL_env ) { + /* Check to see if it's already there... */ + len = (value - name); + for ( ; SDL_env[i]; ++i ) { + if ( strncmp(SDL_env[i], name, len) == 0 ) { + break; + } + } + /* If we found it, just replace the entry */ + if ( SDL_env[i] ) { + free(SDL_env[i]); + SDL_env[i] = new_variable; + added = 1; + } + } + + /* Didn't find it in the environment, expand and add */ + if ( ! added ) { + new_env = realloc(SDL_env, (i+2)*sizeof(char *)); + if ( new_env ) { + SDL_env = new_env; + SDL_env[i++] = new_variable; + SDL_env[i++] = (char *)0; + added = 1; + } else { + free(new_variable); + } + } + return (added ? 0 : -1); +} + +/* Retrieve a variable named "name" from the environment */ +char *SDL_getenv(const char *name) +{ + int len, i; + char *value; + + value = (char *)0; + if ( SDL_env ) { + len = strlen(name); + for ( i=0; SDL_env[i] && !value; ++i ) { + if ( (strncmp(SDL_env[i], name, len) == 0) && + (SDL_env[i][len] == '=') ) { + value = &SDL_env[i][len+1]; + } + } + } + return value; +} + +#endif /* NEED_GETENV */ + +#ifdef TEST_MAIN +#include + +int main(int argc, char *argv[]) +{ + char *value; + + printf("Checking for non-existent variable... "); + fflush(stdout); + if ( ! getenv("EXISTS") ) { + printf("okay\n"); + } else { + printf("failed\n"); + } + printf("Setting FIRST=VALUE1 in the environment... "); + fflush(stdout); + if ( putenv("FIRST=VALUE1") == 0 ) { + printf("okay\n"); + } else { + printf("failed\n"); + } + printf("Getting FIRST from the environment... "); + fflush(stdout); + value = getenv("FIRST"); + if ( value && (strcmp(value, "VALUE1") == 0) ) { + printf("okay\n"); + } else { + printf("failed\n"); + } + printf("Setting SECOND=VALUE2 in the environment... "); + fflush(stdout); + if ( putenv("SECOND=VALUE2") == 0 ) { + printf("okay\n"); + } else { + printf("failed\n"); + } + printf("Getting SECOND from the environment... "); + fflush(stdout); + value = getenv("SECOND"); + if ( value && (strcmp(value, "VALUE2") == 0) ) { + printf("okay\n"); + } else { + printf("failed\n"); + } + printf("Setting FIRST=NOVALUE in the environment... "); + fflush(stdout); + if ( putenv("FIRST=NOVALUE") == 0 ) { + printf("okay\n"); + } else { + printf("failed\n"); + } + printf("Getting FIRST from the environment... "); + fflush(stdout); + value = getenv("FIRST"); + if ( value && (strcmp(value, "NOVALUE") == 0) ) { + printf("okay\n"); + } else { + printf("failed\n"); + } + printf("Checking for non-existent variable... "); + fflush(stdout); + if ( ! getenv("EXISTS") ) { + printf("okay\n"); + } else { + printf("failed\n"); + } + return(0); +} +#endif /* TEST_MAIN */ + diff --git a/contrib/sdk/sources/SDL-1.2.2/src/Tupfile.lua b/contrib/sdk/sources/SDL-1.2.2/src/Tupfile.lua new file mode 100644 index 000000000..7a3fa7425 --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/src/Tupfile.lua @@ -0,0 +1,32 @@ +if tup.getconfig("NO_GCC") ~= "" or tup.getconfig("NO_NASM") ~= "" then return end +tup.include("../../../../../programs/use_gcc.lua") +tup.include("../../../../../programs/use_menuetlibc.lua") +tup.include("../../../../../programs/use_sound.lua") +INCLUDES = INCLUDES .. " -I. -I../include -Ihermes -Iaudio -Ivideo -Ievents -Ijoystick -Icdrom -Ithread -Itimer -Iendian -Ifile" +CFLAGS = CFLAGS .. ' -D_REENTRANT -DPACKAGE=\"SDL\" -DVERSION=\"1.2.2\"' +CFLAGS = CFLAGS .. ' -DENABLE_AUDIO -UDISABLE_AUDIO -DDISABLE_JOYSTICK' +CFLAGS = CFLAGS .. ' -DDISABLE_CDROM -DDISABLE_THREADS -DENABLE_TIMERS' +CFLAGS = CFLAGS .. ' -DUSE_ASMBLIT -DENABLE_MENUETOS -DNO_SIGNAL_H -DDISABLE_STDIO -DNEED_SDL_GETENV' +CFLAGS = CFLAGS .. ' -DENABLE_FILE -UDISABLE_FILE -D__MENUETOS__ -DDEBUG_VIDEO -UWIN32' +FOLDERS = { + "", + "audio/", + "endian/", + "events/", + "file/", + "hermes/", + "joystick/", + "thread/", + "timer/", + "timer/dummy/", + "video/", + "video/menuetos/", +} + +for i,v in ipairs(FOLDERS) do + compile_gcc(v .. "*.c", v .. "%B.o") + tup.append_table(OBJS, + tup.foreach_rule(v .. "*.asm", "nasm -f coff -o %o %f", v .. "%B.o") + ) +end +tup.rule(OBJS, "kos32-ar rcs %o %f", {"../../../lib/libSDL.a", "../../../lib/"}) diff --git a/contrib/sdk/sources/SDL-1.2.2/src/audio/SDL_kolibri_audio.c b/contrib/sdk/sources/SDL-1.2.2/src/audio/SDL_kolibri_audio.c new file mode 100644 index 000000000..3b99fe5fa --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/src/audio/SDL_kolibri_audio.c @@ -0,0 +1,297 @@ +#include "SDL_audio.h" +#include +#include +#include +#include +#include + +static void GetNotify(__u32* event) +{ + __asm__("int $0x40" :: "a"(68),"b"(14),"c"(event)); +} +static int CreateThread(void* fn, char* p_stack) +{ + int res; + __asm__("int $0x40" : "=a"(res) : "a"(51),"b"(1),"c"(fn),"d"(p_stack)); + return res; +} +static char pinfo[1024]; +static int GetProcessInfo(int slot) +{ + int res; + __asm__("int $0x40" : "=a"(res) : "a"(9),"b"(pinfo),"c"(slot)); + return res; +} +static void ActivateWnd(int slot) +{ + __asm__("int $0x40" :: "a"(18),"b"(3),"c"(slot)); +} +static void Yield(void) +{ + __asm__("int $0x40" :: "a"(68),"b"(1)); +} + +static int bInitialized=0; +static SNDBUF hBuff=0; +static char* data=NULL; +static int audio_tid=0; +static int main_slot; +static __u32 main_tid; +static char audio_thread_stack[40960]; +static __u32 used_format=0; +static volatile int mix_size=0; + +static void (*callback)(void* userdata, Uint8* stream, int len); +static void* userdata; + +int SDL_AudioInit(const char* driver_name) +{ + if (bInitialized) + { + SDL_SetError("audio already initialized"); + return -1; + } + int ver; + if (InitSound(&ver)) + { + SDL_printf("Warning: cannot load drivers, sound output will be disabled\n"); + return 0; + } + bInitialized = 1; + return 0; +} + +void SDL_AudioQuit(void) +{ +} + +char* SDL_AudioDriverName(char* namebuf, int maxlen) +{ + if (!bInitialized) + return NULL; + strncpy(namebuf,"KolibriAudio",maxlen); + return namebuf; +} + +#define AUDIO_SUSPEND 1 +#define AUDIO_RESUME 2 +#define AUDIO_DIE 3 +static volatile int audio_command=0,audio_response=0,bLocked=0,bInCallback=0; +static void audio_thread(void) +{ + SDL_printf("audio_thread created\n"); + int bPaused; + __u32 event[6]; + // initialize + if (CreateBuffer(used_format|PCM_RING, 0, &hBuff)) + { + audio_response=1; + __menuet__sys_exit(); + } + GetBufferSize(hBuff, &mix_size); + SDL_printf("buffer created, size is %d\n",mix_size); + mix_size >>= 1; + data = malloc(mix_size); + audio_response=1; + if (!data) __menuet__sys_exit(); + // wait for resume + while (audio_command!=AUDIO_RESUME) + Yield(); + // initialize +/* bInCallback=1; + callback(userdata,data,mix_size); + SetBuffer(hBuff,data,0,mix_size); + callback(userdata,data,mix_size); + SetBuffer(hBuff,data,mix_size,mix_size); + bInCallback=0;*/ + audio_command=0; + bPaused=0; + audio_response=1; + PlayBuffer(hBuff,0); + // main loop + for (;;) + { + if (audio_command==AUDIO_RESUME) + { + PlayBuffer(hBuff,0); + audio_command = 0; + bPaused = 0; + audio_response = 1; + } + else if (audio_command==AUDIO_SUSPEND) + { + StopBuffer(hBuff); + audio_command = 0; + bPaused = 1; + audio_response = 1; + } + else if (audio_command==AUDIO_DIE) + { + audio_response = 1; + StopBuffer(hBuff); + DestroyBuffer(hBuff); + __menuet__sys_exit(); + } + else + { + GetProcessInfo(main_slot); + if (pinfo[0x32]==9 || *(__u32*)(pinfo+0x1E)!=main_tid) + { + audio_command = AUDIO_DIE; + continue; + } + } + if (bPaused) + __menuet__delay100(5); + else + { + GetNotify(event); + if (event[0] != 0xFF000001) + continue; + while (bLocked) + Yield(); + bInCallback=1; + callback(userdata,data,mix_size); + bInCallback=0; + SetBuffer(hBuff,data,event[3],mix_size); + } + } +} + +int SDL_OpenAudio(SDL_AudioSpec* desired, SDL_AudioSpec* obtained) +{ + if (!bInitialized) + { + SDL_SetError("Audio device was not initialized"); + return -1; + } + if (!obtained) + { + SDL_SetError("Audio format: software emulation is not supported"); + return -1; + } + if (used_format) + { + SDL_SetError("Audio device was already opened"); + return -1; + } + memcpy(obtained,desired,sizeof(SDL_AudioSpec)); + switch (desired->freq) + { + +#define HANDLE_FREQ(freq,symb) \ + case freq: \ + switch (desired->channels) \ + { \ + case 1: \ + switch (desired->format) \ + { \ + case AUDIO_U8: \ + case AUDIO_S8: \ + used_format = PCM_1_8_##symb; \ + break; \ + case AUDIO_U16SYS: \ + case AUDIO_S16SYS: \ + used_format = PCM_1_16_##symb; \ + break; \ + } \ + break; \ + case 2: \ + switch (desired->format) \ + { \ + case AUDIO_U8: \ + case AUDIO_S8: \ + used_format = PCM_2_8_##symb; \ + break; \ + case AUDIO_U16SYS: \ + case AUDIO_S16SYS: \ + used_format = PCM_2_16_##symb; \ + break; \ + } \ + break; \ + } \ + break; + + HANDLE_FREQ(48000,48); + HANDLE_FREQ(44100,44); + HANDLE_FREQ(32000,32); + HANDLE_FREQ(24000,24); + HANDLE_FREQ(22050,22); + HANDLE_FREQ(16000,16); + HANDLE_FREQ(12000,12); + HANDLE_FREQ(11025,11); + HANDLE_FREQ(8000,8); + } + if (!used_format) + { + SDL_SetError("Unknown audio format"); + return -1; + } + callback=desired->callback; + userdata=desired->userdata; + GetProcessInfo(-1); + main_tid = *(__u32*)(pinfo+0x1E); + for (main_slot=0;;main_slot++) + { + GetProcessInfo(main_slot); + if (pinfo[0x32]!=9 && *(__u32*)(pinfo+0x1E)==main_tid) + break; + } + audio_tid=CreateThread(audio_thread,audio_thread_stack+40960); + if (audio_tid<0) + { + SDL_SetError("Cannot create audio thread"); + return -1; + } + ActivateWnd(main_slot); + while (!audio_response) + Yield(); + if (!hBuff) + { + SDL_SetError("Cannot create audio buffer"); + return -1; + } + if (!data) + { + SDL_SetError("Cannot allocate audio buffer"); + return -1; + } + obtained->silence = (desired->format == AUDIO_U8 ? 0x80 : 0); + obtained->size = mix_size; + obtained->samples = obtained->size / obtained->channels; + if (desired->format == AUDIO_U16SYS || desired->format == AUDIO_S16SYS) + obtained->samples /= 2; + SDL_printf("obtained size is %d, samples %d\n",obtained->size, + obtained->samples); + return 0; +} +void SDL_CloseAudio(void) +{ + if (!audio_tid) return; + audio_response = 0; + audio_command = AUDIO_DIE; + while (!audio_response) + Yield(); + free(data); + used_format = 0; +} + +void SDL_PauseAudio(int pause_on) +{ + if (!audio_tid) return; + audio_response = 0; + audio_command = pause_on?AUDIO_SUSPEND:AUDIO_RESUME; + while (!audio_response) + Yield(); +} +void SDL_LockAudio(void) +{ + if (!audio_tid) return; + bLocked = 1; + while (bInCallback) + Yield(); +} +void SDL_UnlockAudio(void) +{ + bLocked = 0; +} diff --git a/contrib/sdk/sources/SDL-1.2.2/src/endian/SDL_endian.c b/contrib/sdk/sources/SDL-1.2.2/src/endian/SDL_endian.c new file mode 100644 index 000000000..3fe06dda5 --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/src/endian/SDL_endian.c @@ -0,0 +1,105 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997, 1998, 1999, 2000, 2001 Sam Lantinga + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the Free + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + Sam Lantinga + slouken@devolution.com +*/ + +/* Functions for dynamically reading and writing endian-specific values */ + +#include "SDL_endian.h" + +Uint16 SDL_ReadLE16 (SDL_RWops *src) +{ + Uint16 value; + + SDL_RWread(src, &value, (sizeof value), 1); + return(SDL_SwapLE16(value)); +} + +Uint16 SDL_ReadBE16 (SDL_RWops *src) +{ + Uint16 value; + + SDL_RWread(src, &value, (sizeof value), 1); + return(SDL_SwapBE16(value)); +} +Uint32 SDL_ReadLE32 (SDL_RWops *src) +{ + Uint32 value; + + SDL_RWread(src, &value, (sizeof value), 1); + return(SDL_SwapLE32(value)); +} +Uint32 SDL_ReadBE32 (SDL_RWops *src) +{ + Uint32 value; + + SDL_RWread(src, &value, (sizeof value), 1); + return(SDL_SwapBE32(value)); +} +Uint64 SDL_ReadLE64 (SDL_RWops *src) +{ + Uint64 value; + + SDL_RWread(src, &value, (sizeof value), 1); + return(SDL_SwapLE64(value)); +} +Uint64 SDL_ReadBE64 (SDL_RWops *src) +{ + Uint64 value; + + SDL_RWread(src, &value, (sizeof value), 1); + return(SDL_SwapBE64(value)); +} + +int SDL_WriteLE16 (SDL_RWops *dst, Uint16 value) +{ + value = SDL_SwapLE16(value); + return(SDL_RWwrite(dst, &value, (sizeof value), 1)); +} + +int SDL_WriteBE16 (SDL_RWops *dst, Uint16 value) +{ + value = SDL_SwapBE16(value); + return(SDL_RWwrite(dst, &value, (sizeof value), 1)); +} + +int SDL_WriteLE32 (SDL_RWops *dst, Uint32 value) +{ + value = SDL_SwapLE32(value); + return(SDL_RWwrite(dst, &value, (sizeof value), 1)); +} + +int SDL_WriteBE32 (SDL_RWops *dst, Uint32 value) +{ + value = SDL_SwapBE32(value); + return(SDL_RWwrite(dst, &value, (sizeof value), 1)); +} + +int SDL_WriteLE64 (SDL_RWops *dst, Uint64 value) +{ + value = SDL_SwapLE64(value); + return(SDL_RWwrite(dst, &value, (sizeof value), 1)); +} + +int SDL_WriteBE64 (SDL_RWops *dst, Uint64 value) +{ + value = SDL_SwapBE64(value); + return(SDL_RWwrite(dst, &value, (sizeof value), 1)); +} diff --git a/contrib/sdk/sources/SDL-1.2.2/src/events/SDL_active.c b/contrib/sdk/sources/SDL-1.2.2/src/events/SDL_active.c new file mode 100644 index 000000000..5e5a6df82 --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/src/events/SDL_active.c @@ -0,0 +1,91 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997, 1998, 1999, 2000, 2001 Sam Lantinga + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the Free + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + Sam Lantinga + slouken@devolution.com +*/ + + +/* Application focus/iconification handling code for SDL */ + +#include +#include + +#include "SDL_events.h" +#include "SDL_events_c.h" + + +/* These are static for our active event handling code */ +static Uint8 SDL_appstate = 0; + +/* Public functions */ +int SDL_AppActiveInit(void) +{ + /* Start completely active */ + SDL_appstate = (SDL_APPACTIVE|SDL_APPINPUTFOCUS|SDL_APPMOUSEFOCUS); + + /* That's it! */ + return(0); +} + +Uint8 SDL_GetAppState(void) +{ + return(SDL_appstate); +} + +/* This is global for SDL_eventloop.c */ +int SDL_PrivateAppActive(Uint8 gain, Uint8 state) +{ + int posted; + Uint8 new_state; + + /* Modify the current state with the given mask */ + if ( gain ) { + new_state = (SDL_appstate | state); + } else { + new_state = (SDL_appstate & ~state); + } + + /* Drop events that don't change state */ + if ( new_state == SDL_appstate ) { + return(0); + } + + /* Update internal active state */ + SDL_appstate = new_state; + + /* Post the event, if desired */ + posted = 0; + if ( SDL_ProcessEvents[SDL_ACTIVEEVENT] == SDL_ENABLE ) { + SDL_Event event; + memset(&event, 0, sizeof(event)); + event.type = SDL_ACTIVEEVENT; + event.active.gain = gain; + event.active.state = state; + if ( (SDL_EventOK == NULL) || (*SDL_EventOK)(&event) ) { + posted = 1; + SDL_PushEvent(&event); + } + } + + /* If we lost keyboard focus, post key-up events */ + if ( (state & SDL_APPINPUTFOCUS) && !gain ) { + SDL_ResetKeyboard(); + } + return(posted); +} diff --git a/contrib/sdk/sources/SDL-1.2.2/src/events/SDL_events.c b/contrib/sdk/sources/SDL-1.2.2/src/events/SDL_events.c new file mode 100644 index 000000000..a2a0a7f8e --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/src/events/SDL_events.c @@ -0,0 +1,471 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997, 1998, 1999, 2000, 2001 Sam Lantinga + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the Free + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + Sam Lantinga + slouken@devolution.com +*/ + + +/* General event handling code for SDL */ + +#include +#include + +#include "SDL.h" +#include "SDL_thread.h" +#include "SDL_mutex.h" +#include "SDL_events.h" +#include "SDL_events_c.h" +#include "SDL_timer_c.h" +#ifndef DISABLE_JOYSTICK +#include "SDL_joystick_c.h" +#endif +#ifndef ENABLE_X11 +#define DISABLE_X11 +#endif +#include "SDL_syswm.h" +#include "SDL_sysevents.h" + +/* Public data -- the event filter */ +SDL_EventFilter SDL_EventOK = NULL; +Uint8 SDL_ProcessEvents[SDL_NUMEVENTS]; +static Uint32 SDL_eventstate = 0; + +/* Private data -- event queue */ +#define MAXEVENTS 128 +static struct { + SDL_mutex *lock; + int active; + int head; + int tail; + SDL_Event event[MAXEVENTS]; + int wmmsg_next; + struct SDL_SysWMmsg wmmsg[MAXEVENTS]; +} SDL_EventQ; + +/* Private data -- event locking structure */ +static struct { + SDL_mutex *lock; + int safe; +} SDL_EventLock; + +/* Thread functions */ +static SDL_Thread *SDL_EventThread = NULL; /* Thread handle */ +static Uint32 event_thread; /* The event thread id */ + +void SDL_Lock_EventThread(void) +{ + if ( SDL_EventThread && (SDL_ThreadID() != event_thread) ) { + /* Grab lock and spin until we're sure event thread stopped */ + SDL_mutexP(SDL_EventLock.lock); + while ( ! SDL_EventLock.safe ) { + SDL_Delay(1); + } + } +} +void SDL_Unlock_EventThread(void) +{ + if ( SDL_EventThread && (SDL_ThreadID() != event_thread) ) { + SDL_mutexV(SDL_EventLock.lock); + } +} + +static int SDL_GobbleEvents(void *unused) +{ + SDL_SetTimerThreaded(2); + event_thread = SDL_ThreadID(); + while ( SDL_EventQ.active ) { + SDL_VideoDevice *video = current_video; + SDL_VideoDevice *this = current_video; + + /* Get events from the video subsystem */ + if ( video ) { + video->PumpEvents(this); + } + + /* Queue pending key-repeat events */ + SDL_CheckKeyRepeat(); + +#ifndef DISABLE_JOYSTICK + /* Check for joystick state change */ + if ( SDL_numjoysticks && (SDL_eventstate & SDL_JOYEVENTMASK) ) { + SDL_JoystickUpdate(); + } +#endif + + /* Give up the CPU for the rest of our timeslice */ + SDL_EventLock.safe = 1; + if( SDL_timer_running ) { + SDL_ThreadedTimerCheck(); + } + SDL_Delay(1); + + /* Check for event locking. + On the P of the lock mutex, if the lock is held, this thread + will wait until the lock is released before continuing. The + safe flag will be set, meaning that the other thread can go + about it's business. The safe flag is reset before the V, + so as soon as the mutex is free, other threads can see that + it's not safe to interfere with the event thread. + */ + SDL_mutexP(SDL_EventLock.lock); + SDL_EventLock.safe = 0; + SDL_mutexV(SDL_EventLock.lock); + } + SDL_SetTimerThreaded(0); + event_thread = 0; + return(0); +} + +static int SDL_StartEventThread(Uint32 flags) +{ + /* Reset everything to zero */ + SDL_EventThread = NULL; + memset(&SDL_EventLock, 0, sizeof(SDL_EventLock)); + + /* Create the lock and set ourselves active */ +#ifndef DISABLE_THREADS + SDL_EventQ.lock = SDL_CreateMutex(); + if ( SDL_EventQ.lock == NULL ) { +#ifdef macintosh /* On MacOS 7/8, you can't multithread, so no lock needed */ + ; +#else + return(-1); +#endif + } +#endif /* !DISABLE_THREADS */ + SDL_EventQ.active = 1; + + if ( (flags&SDL_INIT_EVENTTHREAD) == SDL_INIT_EVENTTHREAD ) { + SDL_EventLock.lock = SDL_CreateMutex(); + if ( SDL_EventLock.lock == NULL ) { + return(-1); + } + SDL_EventLock.safe = 0; + + SDL_EventThread = SDL_CreateThread(SDL_GobbleEvents, NULL); + if ( SDL_EventThread == NULL ) { + return(-1); + } + } else { + event_thread = 0; + } + return(0); +} + +static void SDL_StopEventThread(void) +{ + SDL_EventQ.active = 0; + if ( SDL_EventThread ) { + SDL_WaitThread(SDL_EventThread, NULL); + SDL_EventThread = NULL; + SDL_DestroyMutex(SDL_EventLock.lock); + } + SDL_DestroyMutex(SDL_EventQ.lock); +} + +Uint32 SDL_EventThreadID(void) +{ + return(event_thread); +} + +/* Public functions */ + +void SDL_StopEventLoop(void) +{ + /* Halt the event thread, if running */ + SDL_StopEventThread(); + + /* Clean out EventQ */ + SDL_EventQ.head = 0; + SDL_EventQ.tail = 0; + SDL_EventQ.wmmsg_next = 0; +} + +/* This function (and associated calls) may be called more than once */ +int SDL_StartEventLoop(Uint32 flags) +{ + int retcode; + + /* Clean out the event queue */ + SDL_EventThread = NULL; + SDL_EventQ.lock = NULL; + SDL_StopEventLoop(); + + /* No filter to start with, process most event types */ + SDL_EventOK = NULL; + memset(SDL_ProcessEvents,SDL_ENABLE,sizeof(SDL_ProcessEvents)); + SDL_eventstate = ~0; + /* It's not save to call SDL_EventState() yet */ + SDL_eventstate &= ~(0x00000001 << SDL_SYSWMEVENT); + SDL_ProcessEvents[SDL_SYSWMEVENT] = SDL_IGNORE; + + /* Initialize event handlers */ + retcode = 0; + retcode += SDL_AppActiveInit(); + retcode += SDL_KeyboardInit(); + retcode += SDL_MouseInit(); + retcode += SDL_QuitInit(); + if ( retcode < 0 ) { + /* We don't expect them to fail, but... */ + return(-1); + } + + /* Create the lock and event thread */ + if ( SDL_StartEventThread(flags) < 0 ) { + SDL_StopEventLoop(); + return(-1); + } + return(0); +} + + +/* Add an event to the event queue -- called with the queue locked */ +static int SDL_AddEvent(SDL_Event *event) +{ + int tail, added; + + tail = (SDL_EventQ.tail+1)%MAXEVENTS; + if ( tail == SDL_EventQ.head ) { + /* Overflow, drop event */ + added = 0; + } else { + SDL_EventQ.event[SDL_EventQ.tail] = *event; + if (event->type == SDL_SYSWMEVENT) { + /* Note that it's possible to lose an event */ + int next = SDL_EventQ.wmmsg_next; + SDL_EventQ.wmmsg[next] = *event->syswm.msg; + SDL_EventQ.event[SDL_EventQ.tail].syswm.msg = + &SDL_EventQ.wmmsg[next]; + SDL_EventQ.wmmsg_next = (next+1)%MAXEVENTS; + } + SDL_EventQ.tail = tail; + added = 1; + } + return(added); +} + +/* Cut an event, and return the next valid spot, or the tail */ +/* -- called with the queue locked */ +static int SDL_CutEvent(int spot) +{ + if ( spot == SDL_EventQ.head ) { + SDL_EventQ.head = (SDL_EventQ.head+1)%MAXEVENTS; + return(SDL_EventQ.head); + } else + if ( (spot+1)%MAXEVENTS == SDL_EventQ.tail ) { + SDL_EventQ.tail = spot; + return(SDL_EventQ.tail); + } else + /* We cut the middle -- shift everything over */ + { + int here, next; + + /* This can probably be optimized with memcpy() -- careful! */ + if ( --SDL_EventQ.tail < 0 ) { + SDL_EventQ.tail = MAXEVENTS-1; + } + for ( here=spot; here != SDL_EventQ.tail; here = next ) { + next = (here+1)%MAXEVENTS; + SDL_EventQ.event[here] = SDL_EventQ.event[next]; + } + return(spot); + } + /* NOTREACHED */ +} + +/* Lock the event queue, take a peep at it, and unlock it */ +int SDL_PeepEvents(SDL_Event *events, int numevents, SDL_eventaction action, + Uint32 mask) +{ + int i, used; + + /* Don't look after we've quit */ + if ( ! SDL_EventQ.active ) { + return(0); + } + /* Lock the event queue */ + used = 0; + if ( SDL_mutexP(SDL_EventQ.lock) == 0 ) { + if ( action == SDL_ADDEVENT ) { + for ( i=0; iPumpEvents(this); + } + + /* Queue pending key-repeat events */ + SDL_CheckKeyRepeat(); + +#ifndef DISABLE_JOYSTICK + /* Check for joystick state change */ + if ( SDL_numjoysticks && (SDL_eventstate & SDL_JOYEVENTMASK) ) { + SDL_JoystickUpdate(); + } +#endif + } +} + +/* Public functions */ + +int SDL_PollEvent (SDL_Event *event) +{ + SDL_PumpEvents(); + + return(SDL_PeepEvents(event, 1, SDL_GETEVENT, SDL_ALLEVENTS)); +} + +int SDL_WaitEvent (SDL_Event *event) +{ + while ( 1 ) { + SDL_PumpEvents(); + switch(SDL_PeepEvents(event, 1, SDL_GETEVENT, SDL_ALLEVENTS)) { + case -1: return -1; + case 1: return 1; + case 0: SDL_Delay(10); + } + } +} + +int SDL_PushEvent(SDL_Event *event) +{ + return(SDL_PeepEvents(event, 1, SDL_ADDEVENT, 0)); +} + +void SDL_SetEventFilter (SDL_EventFilter filter) +{ + SDL_Event bitbucket; + + /* Set filter and discard pending events */ + SDL_EventOK = filter; + while ( SDL_PollEvent(&bitbucket) > 0 ) + ; +} + +SDL_EventFilter SDL_GetEventFilter(void) +{ + return(SDL_EventOK); +} + +Uint8 SDL_EventState (Uint8 type, int state) +{ + SDL_Event bitbucket; + Uint8 current_state; + + /* If SDL_ALLEVENTS was specified... */ + if ( type == 0xFF ) { + current_state = SDL_IGNORE; + for ( type=0; type 0 ) + ; + return(current_state); + } + + /* Just set the state for one event type */ + current_state = SDL_ProcessEvents[type]; + switch (state) { + case SDL_IGNORE: + case SDL_ENABLE: + /* Set state and discard pending events */ + SDL_ProcessEvents[type] = state; + if ( state == SDL_ENABLE ) { + SDL_eventstate |= (0x00000001 << (type)); + } else { + SDL_eventstate &= ~(0x00000001 << (type)); + } + while ( SDL_PollEvent(&bitbucket) > 0 ) + ; + break; + default: + /* Querying state? */ + break; + } + return(current_state); +} + +/* This is a generic event handler. + */ +int SDL_PrivateSysWMEvent(SDL_SysWMmsg *message) +{ + int posted; + + posted = 0; + if ( SDL_ProcessEvents[SDL_SYSWMEVENT] == SDL_ENABLE ) { + SDL_Event event; + memset(&event, 0, sizeof(event)); + event.type = SDL_SYSWMEVENT; + event.syswm.msg = message; + if ( (SDL_EventOK == NULL) || (*SDL_EventOK)(&event) ) { + posted = 1; + SDL_PushEvent(&event); + } + } + /* Update internal event state */ + return(posted); +} diff --git a/contrib/sdk/sources/SDL-1.2.2/src/events/SDL_events_c.h b/contrib/sdk/sources/SDL-1.2.2/src/events/SDL_events_c.h new file mode 100644 index 000000000..8cc06fe05 --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/src/events/SDL_events_c.h @@ -0,0 +1,78 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997, 1998, 1999, 2000, 2001 Sam Lantinga + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the Free + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + Sam Lantinga + slouken@devolution.com +*/ + +#ifdef SAVE_RCSID +static char rcsid = + "@(#) $Id: SDL_events_c.h,v 1.2 2001/04/26 16:50:17 hercules Exp $"; +#endif + +/* Useful functions and variables from SDL_events.c */ +#include "SDL_events.h" + +/* Start and stop the event processing loop */ +extern int SDL_StartEventLoop(Uint32 flags); +extern void SDL_StopEventLoop(void); +extern void SDL_QuitInterrupt(void); + +extern void SDL_Lock_EventThread(); +extern void SDL_Unlock_EventThread(); +extern Uint32 SDL_EventThreadID(void); + +/* Event handler init routines */ +extern int SDL_AppActiveInit(void); +extern int SDL_KeyboardInit(void); +extern int SDL_MouseInit(void); +extern int SDL_QuitInit(void); + +/* The event filter function */ +extern SDL_EventFilter SDL_EventOK; + +/* The array of event processing states */ +extern Uint8 SDL_ProcessEvents[SDL_NUMEVENTS]; + +/* Internal event queueing functions + (from SDL_active.c, SDL_mouse.c, SDL_keyboard.c, SDL_quit.c, SDL_events.c) + */ +extern int SDL_PrivateAppActive(Uint8 gain, Uint8 state); +extern int SDL_PrivateMouseMotion(Uint8 buttonstate, int relative, + Sint16 x, Sint16 y); +extern int SDL_PrivateMouseButton(Uint8 state, Uint8 button,Sint16 x,Sint16 y); +extern int SDL_PrivateKeyboard(Uint8 state, SDL_keysym *key); +extern int SDL_PrivateResize(int w, int h); +extern int SDL_PrivateExpose(void); +extern int SDL_PrivateQuit(void); +extern int SDL_PrivateSysWMEvent(SDL_SysWMmsg *message); + +/* Used by the activity event handler to remove mouse focus */ +extern void SDL_MouseFocus(int focus); + +/* Used by the activity event handler to remove keyboard focus */ +extern void SDL_ResetKeyboard(void); + +/* Used by the event loop to queue pending keyboard repeat events */ +extern void SDL_CheckKeyRepeat(void); + +/* Used by the OS keyboard code to detect whether or not to do UNICODE */ +#ifndef DEFAULT_UNICODE_TRANSLATION +#define DEFAULT_UNICODE_TRANSLATION 0 /* Default off because of overhead */ +#endif +extern int SDL_TranslateUNICODE; diff --git a/contrib/sdk/sources/SDL-1.2.2/src/events/SDL_expose.c b/contrib/sdk/sources/SDL-1.2.2/src/events/SDL_expose.c new file mode 100644 index 000000000..da51128d4 --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/src/events/SDL_expose.c @@ -0,0 +1,51 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997, 1998, 1999, 2000, 2001 Sam Lantinga + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the Free + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + Sam Lantinga + slouken@devolution.com +*/ + + +/* Refresh event handling code for SDL */ + +#include "SDL_events.h" +#include "SDL_events_c.h" + + +/* This is global for SDL_eventloop.c */ +int SDL_PrivateExpose(void) +{ + int posted; + SDL_Event events[32]; + + /* Pull out all old refresh events */ + SDL_PeepEvents(events, sizeof(events)/sizeof(events[0]), + SDL_GETEVENT, SDL_VIDEOEXPOSEMASK); + + /* Post the event, if desired */ + posted = 0; + if ( SDL_ProcessEvents[SDL_VIDEOEXPOSE] == SDL_ENABLE ) { + SDL_Event event; + event.type = SDL_VIDEOEXPOSE; + if ( (SDL_EventOK == NULL) || (*SDL_EventOK)(&event) ) { + posted = 1; + SDL_PushEvent(&event); + } + } + return(posted); +} diff --git a/contrib/sdk/sources/SDL-1.2.2/src/events/SDL_keyboard.c b/contrib/sdk/sources/SDL-1.2.2/src/events/SDL_keyboard.c new file mode 100644 index 000000000..5f16e951c --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/src/events/SDL_keyboard.c @@ -0,0 +1,560 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997, 1998, 1999, 2000, 2001 Sam Lantinga + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the Free + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + Sam Lantinga + slouken@devolution.com +*/ + + +/* General keyboard handling code for SDL */ + +#include +#include +#include +#include + +#include "SDL_error.h" +#include "SDL_events.h" +#include "SDL_timer.h" +#include "SDL_events_c.h" +#include "SDL_sysevents.h" + + +/* Global keystate information */ +static Uint8 SDL_KeyState[SDLK_LAST]; +static SDLMod SDL_ModState; +int SDL_TranslateUNICODE = 0; + +static char *keynames[SDLK_LAST]; /* Array of keycode names */ + +/* + * jk 991215 - added + */ +struct { + int firsttime; /* if we check against the delay or repeat value */ + int delay; /* the delay before we start repeating */ + int interval; /* the delay between key repeat events */ + Uint32 timestamp; /* the time the first keydown event occurred */ + + SDL_Event evt; /* the event we are supposed to repeat */ +} SDL_KeyRepeat; + +/* Public functions */ +int SDL_KeyboardInit(void) +{ + SDL_VideoDevice *video = current_video; + SDL_VideoDevice *this = current_video; + Uint16 i; + + /* Set default mode of UNICODE translation */ + SDL_EnableUNICODE(DEFAULT_UNICODE_TRANSLATION); + + /* Initialize the tables */ + SDL_ModState = KMOD_NONE; + for ( i=0; iInitOSKeymap(this); + + SDL_EnableKeyRepeat(0, 0); + + /* Fill in the blanks in keynames */ + keynames[SDLK_BACKSPACE] = "backspace"; + keynames[SDLK_TAB] = "tab"; + keynames[SDLK_CLEAR] = "clear"; + keynames[SDLK_RETURN] = "return"; + keynames[SDLK_PAUSE] = "pause"; + keynames[SDLK_ESCAPE] = "escape"; + keynames[SDLK_SPACE] = "space"; + keynames[SDLK_EXCLAIM] = "!"; + keynames[SDLK_QUOTEDBL] = "\""; + keynames[SDLK_HASH] = "#"; + keynames[SDLK_DOLLAR] = "$"; + keynames[SDLK_AMPERSAND] = "&"; + keynames[SDLK_QUOTE] = "'"; + keynames[SDLK_LEFTPAREN] = "("; + keynames[SDLK_RIGHTPAREN] = ")"; + keynames[SDLK_ASTERISK] = "*"; + keynames[SDLK_PLUS] = "+"; + keynames[SDLK_COMMA] = ","; + keynames[SDLK_MINUS] = "-"; + keynames[SDLK_PERIOD] = "."; + keynames[SDLK_SLASH] = "/"; + keynames[SDLK_0] = "0"; + keynames[SDLK_1] = "1"; + keynames[SDLK_2] = "2"; + keynames[SDLK_3] = "3"; + keynames[SDLK_4] = "4"; + keynames[SDLK_5] = "5"; + keynames[SDLK_6] = "6"; + keynames[SDLK_7] = "7"; + keynames[SDLK_8] = "8"; + keynames[SDLK_9] = "9"; + keynames[SDLK_COLON] = ":"; + keynames[SDLK_SEMICOLON] = ";"; + keynames[SDLK_LESS] = "<"; + keynames[SDLK_EQUALS] = "="; + keynames[SDLK_GREATER] = ">"; + keynames[SDLK_QUESTION] = "?"; + keynames[SDLK_AT] = "@"; + keynames[SDLK_LEFTBRACKET] = "["; + keynames[SDLK_BACKSLASH] = "\\"; + keynames[SDLK_RIGHTBRACKET] = "]"; + keynames[SDLK_CARET] = "^"; + keynames[SDLK_UNDERSCORE] = "_"; + keynames[SDLK_BACKQUOTE] = "`"; + keynames[SDLK_a] = "a"; + keynames[SDLK_b] = "b"; + keynames[SDLK_c] = "c"; + keynames[SDLK_d] = "d"; + keynames[SDLK_e] = "e"; + keynames[SDLK_f] = "f"; + keynames[SDLK_g] = "g"; + keynames[SDLK_h] = "h"; + keynames[SDLK_i] = "i"; + keynames[SDLK_j] = "j"; + keynames[SDLK_k] = "k"; + keynames[SDLK_l] = "l"; + keynames[SDLK_m] = "m"; + keynames[SDLK_n] = "n"; + keynames[SDLK_o] = "o"; + keynames[SDLK_p] = "p"; + keynames[SDLK_q] = "q"; + keynames[SDLK_r] = "r"; + keynames[SDLK_s] = "s"; + keynames[SDLK_t] = "t"; + keynames[SDLK_u] = "u"; + keynames[SDLK_v] = "v"; + keynames[SDLK_w] = "w"; + keynames[SDLK_x] = "x"; + keynames[SDLK_y] = "y"; + keynames[SDLK_z] = "z"; + keynames[SDLK_DELETE] = "delete"; + + keynames[SDLK_WORLD_0] = "world 0"; + keynames[SDLK_WORLD_1] = "world 1"; + keynames[SDLK_WORLD_2] = "world 2"; + keynames[SDLK_WORLD_3] = "world 3"; + keynames[SDLK_WORLD_4] = "world 4"; + keynames[SDLK_WORLD_5] = "world 5"; + keynames[SDLK_WORLD_6] = "world 6"; + keynames[SDLK_WORLD_7] = "world 7"; + keynames[SDLK_WORLD_8] = "world 8"; + keynames[SDLK_WORLD_9] = "world 9"; + keynames[SDLK_WORLD_10] = "world 10"; + keynames[SDLK_WORLD_11] = "world 11"; + keynames[SDLK_WORLD_12] = "world 12"; + keynames[SDLK_WORLD_13] = "world 13"; + keynames[SDLK_WORLD_14] = "world 14"; + keynames[SDLK_WORLD_15] = "world 15"; + keynames[SDLK_WORLD_16] = "world 16"; + keynames[SDLK_WORLD_17] = "world 17"; + keynames[SDLK_WORLD_18] = "world 18"; + keynames[SDLK_WORLD_19] = "world 19"; + keynames[SDLK_WORLD_20] = "world 20"; + keynames[SDLK_WORLD_21] = "world 21"; + keynames[SDLK_WORLD_22] = "world 22"; + keynames[SDLK_WORLD_23] = "world 23"; + keynames[SDLK_WORLD_24] = "world 24"; + keynames[SDLK_WORLD_25] = "world 25"; + keynames[SDLK_WORLD_26] = "world 26"; + keynames[SDLK_WORLD_27] = "world 27"; + keynames[SDLK_WORLD_28] = "world 28"; + keynames[SDLK_WORLD_29] = "world 29"; + keynames[SDLK_WORLD_30] = "world 30"; + keynames[SDLK_WORLD_31] = "world 31"; + keynames[SDLK_WORLD_32] = "world 32"; + keynames[SDLK_WORLD_33] = "world 33"; + keynames[SDLK_WORLD_34] = "world 34"; + keynames[SDLK_WORLD_35] = "world 35"; + keynames[SDLK_WORLD_36] = "world 36"; + keynames[SDLK_WORLD_37] = "world 37"; + keynames[SDLK_WORLD_38] = "world 38"; + keynames[SDLK_WORLD_39] = "world 39"; + keynames[SDLK_WORLD_40] = "world 40"; + keynames[SDLK_WORLD_41] = "world 41"; + keynames[SDLK_WORLD_42] = "world 42"; + keynames[SDLK_WORLD_43] = "world 43"; + keynames[SDLK_WORLD_44] = "world 44"; + keynames[SDLK_WORLD_45] = "world 45"; + keynames[SDLK_WORLD_46] = "world 46"; + keynames[SDLK_WORLD_47] = "world 47"; + keynames[SDLK_WORLD_48] = "world 48"; + keynames[SDLK_WORLD_49] = "world 49"; + keynames[SDLK_WORLD_50] = "world 50"; + keynames[SDLK_WORLD_51] = "world 51"; + keynames[SDLK_WORLD_52] = "world 52"; + keynames[SDLK_WORLD_53] = "world 53"; + keynames[SDLK_WORLD_54] = "world 54"; + keynames[SDLK_WORLD_55] = "world 55"; + keynames[SDLK_WORLD_56] = "world 56"; + keynames[SDLK_WORLD_57] = "world 57"; + keynames[SDLK_WORLD_58] = "world 58"; + keynames[SDLK_WORLD_59] = "world 59"; + keynames[SDLK_WORLD_60] = "world 60"; + keynames[SDLK_WORLD_61] = "world 61"; + keynames[SDLK_WORLD_62] = "world 62"; + keynames[SDLK_WORLD_63] = "world 63"; + keynames[SDLK_WORLD_64] = "world 64"; + keynames[SDLK_WORLD_65] = "world 65"; + keynames[SDLK_WORLD_66] = "world 66"; + keynames[SDLK_WORLD_67] = "world 67"; + keynames[SDLK_WORLD_68] = "world 68"; + keynames[SDLK_WORLD_69] = "world 69"; + keynames[SDLK_WORLD_70] = "world 70"; + keynames[SDLK_WORLD_71] = "world 71"; + keynames[SDLK_WORLD_72] = "world 72"; + keynames[SDLK_WORLD_73] = "world 73"; + keynames[SDLK_WORLD_74] = "world 74"; + keynames[SDLK_WORLD_75] = "world 75"; + keynames[SDLK_WORLD_76] = "world 76"; + keynames[SDLK_WORLD_77] = "world 77"; + keynames[SDLK_WORLD_78] = "world 78"; + keynames[SDLK_WORLD_79] = "world 79"; + keynames[SDLK_WORLD_80] = "world 80"; + keynames[SDLK_WORLD_81] = "world 81"; + keynames[SDLK_WORLD_82] = "world 82"; + keynames[SDLK_WORLD_83] = "world 83"; + keynames[SDLK_WORLD_84] = "world 84"; + keynames[SDLK_WORLD_85] = "world 85"; + keynames[SDLK_WORLD_86] = "world 86"; + keynames[SDLK_WORLD_87] = "world 87"; + keynames[SDLK_WORLD_88] = "world 88"; + keynames[SDLK_WORLD_89] = "world 89"; + keynames[SDLK_WORLD_90] = "world 90"; + keynames[SDLK_WORLD_91] = "world 91"; + keynames[SDLK_WORLD_92] = "world 92"; + keynames[SDLK_WORLD_93] = "world 93"; + keynames[SDLK_WORLD_94] = "world 94"; + keynames[SDLK_WORLD_95] = "world 95"; + + keynames[SDLK_KP0] = "[0]"; + keynames[SDLK_KP1] = "[1]"; + keynames[SDLK_KP2] = "[2]"; + keynames[SDLK_KP3] = "[3]"; + keynames[SDLK_KP4] = "[4]"; + keynames[SDLK_KP5] = "[5]"; + keynames[SDLK_KP6] = "[6]"; + keynames[SDLK_KP7] = "[7]"; + keynames[SDLK_KP8] = "[8]"; + keynames[SDLK_KP9] = "[9]"; + keynames[SDLK_KP_PERIOD] = "[.]"; + keynames[SDLK_KP_DIVIDE] = "[/]"; + keynames[SDLK_KP_MULTIPLY] = "[*]"; + keynames[SDLK_KP_MINUS] = "[-]"; + keynames[SDLK_KP_PLUS] = "[+]"; + keynames[SDLK_KP_ENTER] = "enter"; + keynames[SDLK_KP_EQUALS] = "equals"; + + keynames[SDLK_UP] = "up"; + keynames[SDLK_DOWN] = "down"; + keynames[SDLK_RIGHT] = "right"; + keynames[SDLK_LEFT] = "left"; + keynames[SDLK_DOWN] = "down"; + keynames[SDLK_INSERT] = "insert"; + keynames[SDLK_HOME] = "home"; + keynames[SDLK_END] = "end"; + keynames[SDLK_PAGEUP] = "page up"; + keynames[SDLK_PAGEDOWN] = "page down"; + + keynames[SDLK_F1] = "f1"; + keynames[SDLK_F2] = "f2"; + keynames[SDLK_F3] = "f3"; + keynames[SDLK_F4] = "f4"; + keynames[SDLK_F5] = "f5"; + keynames[SDLK_F6] = "f6"; + keynames[SDLK_F7] = "f7"; + keynames[SDLK_F8] = "f8"; + keynames[SDLK_F9] = "f9"; + keynames[SDLK_F10] = "f10"; + keynames[SDLK_F11] = "f11"; + keynames[SDLK_F12] = "f12"; + keynames[SDLK_F13] = "f13"; + keynames[SDLK_F14] = "f14"; + keynames[SDLK_F15] = "f15"; + + keynames[SDLK_NUMLOCK] = "numlock"; + keynames[SDLK_CAPSLOCK] = "caps lock"; + keynames[SDLK_SCROLLOCK] = "scroll lock"; + keynames[SDLK_RSHIFT] = "right shift"; + keynames[SDLK_LSHIFT] = "left shift"; + keynames[SDLK_RCTRL] = "right ctrl"; + keynames[SDLK_LCTRL] = "left ctrl"; + keynames[SDLK_RALT] = "right alt"; + keynames[SDLK_LALT] = "left alt"; + keynames[SDLK_RMETA] = "right meta"; + keynames[SDLK_LMETA] = "left meta"; + keynames[SDLK_LSUPER] = "left super"; /* "Windows" keys */ + keynames[SDLK_RSUPER] = "right super"; + keynames[SDLK_MODE] = "alt gr"; + keynames[SDLK_COMPOSE] = "compose"; + + keynames[SDLK_HELP] = "help"; + keynames[SDLK_PRINT] = "print screen"; + keynames[SDLK_SYSREQ] = "sys req"; + keynames[SDLK_BREAK] = "break"; + keynames[SDLK_MENU] = "menu"; + keynames[SDLK_POWER] = "power"; + keynames[SDLK_EURO] = "euro"; + + /* Done. Whew. */ + return(0); +} + +/* We lost the keyboard, so post key up messages for all pressed keys */ +void SDL_ResetKeyboard(void) +{ + SDL_keysym keysym; + SDLKey key; + + memset(&keysym, 0, (sizeof keysym)); + for ( key=SDLK_FIRST; key= 0 ) { + SDL_TranslateUNICODE = enable; + } + return(old_mode); +} + +Uint8 * SDL_GetKeyState (int *numkeys) +{ + if ( numkeys != (int *)0 ) + *numkeys = SDLK_LAST; + return(SDL_KeyState); +} +SDLMod SDL_GetModState (void) +{ + return(SDL_ModState); +} +void SDL_SetModState (SDLMod modstate) +{ + SDL_ModState = modstate; +} + +char *SDL_GetKeyName(SDLKey key) +{ + char *keyname; + + keyname = NULL; + if ( key < SDLK_LAST ) { + keyname = keynames[key]; + } + if ( keyname == NULL ) { + keyname = "unknown key"; + } + return(keyname); +} + +/* These are global for SDL_eventloop.c */ +int SDL_PrivateKeyboard(Uint8 state, SDL_keysym *keysym) +{ + SDL_Event event; + int posted, repeatable; + Uint16 modstate; + + memset(&event, 0, sizeof(event)); + + /* Set up the keysym */ + modstate = (Uint16)SDL_ModState; + + repeatable = 0; + + if ( state == SDL_PRESSED ) { + keysym->mod = (SDLMod)modstate; + switch (keysym->sym) { + case SDLK_NUMLOCK: + modstate ^= KMOD_NUM; + if ( ! (modstate&KMOD_NUM) ) + state = SDL_RELEASED; + keysym->mod = (SDLMod)modstate; + break; + case SDLK_CAPSLOCK: + modstate ^= KMOD_CAPS; + if ( ! (modstate&KMOD_CAPS) ) + state = SDL_RELEASED; + keysym->mod = (SDLMod)modstate; + break; + case SDLK_LCTRL: + modstate |= KMOD_LCTRL; + break; + case SDLK_RCTRL: + modstate |= KMOD_RCTRL; + break; + case SDLK_LSHIFT: + modstate |= KMOD_LSHIFT; + break; + case SDLK_RSHIFT: + modstate |= KMOD_RSHIFT; + break; + case SDLK_LALT: + modstate |= KMOD_LALT; + break; + case SDLK_RALT: + modstate |= KMOD_RALT; + break; + case SDLK_LMETA: + modstate |= KMOD_LMETA; + break; + case SDLK_RMETA: + modstate |= KMOD_RMETA; + break; + case SDLK_MODE: + modstate |= KMOD_MODE; + break; + default: + repeatable = 1; + break; + } + } else { + switch (keysym->sym) { + case SDLK_NUMLOCK: + case SDLK_CAPSLOCK: + /* Only send keydown events */ + return(0); + case SDLK_LCTRL: + modstate &= ~KMOD_LCTRL; + break; + case SDLK_RCTRL: + modstate &= ~KMOD_RCTRL; + break; + case SDLK_LSHIFT: + modstate &= ~KMOD_LSHIFT; + break; + case SDLK_RSHIFT: + modstate &= ~KMOD_RSHIFT; + break; + case SDLK_LALT: + modstate &= ~KMOD_LALT; + break; + case SDLK_RALT: + modstate &= ~KMOD_RALT; + break; + case SDLK_LMETA: + modstate &= ~KMOD_LMETA; + break; + case SDLK_RMETA: + modstate &= ~KMOD_RMETA; + break; + case SDLK_MODE: + modstate &= ~KMOD_MODE; + break; + default: + break; + } + keysym->mod = (SDLMod)modstate; + } + + /* Figure out what type of event this is */ + switch (state) { + case SDL_PRESSED: + event.type = SDL_KEYDOWN; + break; + case SDL_RELEASED: + event.type = SDL_KEYUP; + /* + * jk 991215 - Added + */ + if ( SDL_KeyRepeat.timestamp ) { + SDL_KeyRepeat.timestamp = 0; + } + break; + default: + /* Invalid state -- bail */ + return(0); + } + +// /* Drop events that don't change state */ +// if ( SDL_KeyState[keysym->sym] == state ) { +// return(0); +// } + + /* Update internal keyboard state */ + SDL_ModState = (SDLMod)modstate; + SDL_KeyState[keysym->sym] = state; + + /* Post the event, if desired */ + posted = 0; + if ( SDL_ProcessEvents[event.type] == SDL_ENABLE ) { + event.key.state = state; + event.key.keysym = *keysym; + if ( (SDL_EventOK == NULL) || SDL_EventOK(&event) ) { + posted = 1; + /* + * jk 991215 - Added + */ + if (repeatable && (SDL_KeyRepeat.delay != 0)) { + SDL_KeyRepeat.evt = event; + SDL_KeyRepeat.firsttime = 1; + SDL_KeyRepeat.timestamp=SDL_GetTicks(); + } + SDL_PushEvent(&event); + } + } + return(posted); +} + +/* + * jk 991215 - Added + */ +void SDL_CheckKeyRepeat(void) +{ +/* if ( SDL_KeyRepeat.timestamp ) { + Uint32 now, interval; + + now = SDL_GetTicks(); + interval = (now - SDL_KeyRepeat.timestamp); + if ( SDL_KeyRepeat.firsttime ) { + if ( interval > (Uint32)SDL_KeyRepeat.delay ) { + SDL_KeyRepeat.timestamp = now; + SDL_KeyRepeat.firsttime = 0; + } + } else { + if ( interval > (Uint32)SDL_KeyRepeat.interval ) { + SDL_KeyRepeat.timestamp = now; + SDL_PushEvent(&SDL_KeyRepeat.evt); + } + } + }*/ +} + +int SDL_EnableKeyRepeat(int delay, int interval) +{ + if ( (delay < 0) || (interval < 0) ) { + SDL_SetError("keyboard repeat value less than zero"); + return(-1); + } + SDL_KeyRepeat.firsttime = 0; + SDL_KeyRepeat.delay = delay; + SDL_KeyRepeat.interval = interval; + SDL_KeyRepeat.timestamp = 0; + return(0); +} + diff --git a/contrib/sdk/sources/SDL-1.2.2/src/events/SDL_mouse.c b/contrib/sdk/sources/SDL-1.2.2/src/events/SDL_mouse.c new file mode 100644 index 000000000..4e0686f14 --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/src/events/SDL_mouse.c @@ -0,0 +1,246 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997, 1998, 1999, 2000, 2001 Sam Lantinga + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the Free + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + Sam Lantinga + slouken@devolution.com +*/ + + +/* General mouse handling code for SDL */ + +#include +#include +#include + +#include "SDL_events.h" +#include "SDL_events_c.h" +#include "SDL_cursor_c.h" +#include "SDL_sysvideo.h" + + +/* These are static for our mouse handling code */ +static Sint16 SDL_MouseX = 0; +static Sint16 SDL_MouseY = 0; +static Sint16 SDL_DeltaX = 0; +static Sint16 SDL_DeltaY = 0; +static Uint8 SDL_ButtonState = 0; + + +/* Public functions */ +int SDL_MouseInit(void) +{ + /* The mouse is at (0,0) */ + SDL_MouseX = 0; + SDL_MouseY = 0; + SDL_DeltaX = 0; + SDL_DeltaY = 0; + SDL_ButtonState = 0; + + /* That's it! */ + return(0); +} + +Uint8 SDL_GetMouseState (int *x, int *y) +{ + if ( x ) + *x = SDL_MouseX; + if ( y ) + *y = SDL_MouseY; + return(SDL_ButtonState); +} + +Uint8 SDL_GetRelativeMouseState (int *x, int *y) +{ + if ( x ) + *x = SDL_DeltaX; + if ( y ) + *y = SDL_DeltaY; + SDL_DeltaX = 0; + SDL_DeltaY = 0; + return(SDL_ButtonState); +} + +static void ClipOffset(Sint16 *x, Sint16 *y) +{ + /* This clips absolute mouse coordinates when the apparent + display surface is smaller than the real display surface. + */ + if ( SDL_VideoSurface->offset ) { + *y -= SDL_VideoSurface->offset/SDL_VideoSurface->pitch; + *x -= (SDL_VideoSurface->offset%SDL_VideoSurface->pitch)/ + SDL_VideoSurface->format->BytesPerPixel; + } +} + +/* These are global for SDL_eventloop.c */ +int SDL_PrivateMouseMotion(Uint8 buttonstate, int relative, Sint16 x, Sint16 y) +{ + int posted; + Uint16 X, Y; + Sint16 Xrel; + Sint16 Yrel; + + /* Don't handle mouse motion if there's no cursor surface */ + if ( SDL_VideoSurface == NULL ) { + return(0); + } + + /* Default buttonstate is the current one */ + if ( ! buttonstate ) { + buttonstate = SDL_ButtonState; + } + + Xrel = x; + Yrel = y; + if ( relative ) { + /* Push the cursor around */ + x = (SDL_MouseX+x); + y = (SDL_MouseY+y); + } else { + /* Do we need to clip {x,y} ? */ + ClipOffset(&x, &y); + } + + /* Mouse coordinates range from 0 - width-1 and 0 - height-1 */ + if ( x < 0 ) + X = 0; + else + if ( x >= SDL_VideoSurface->w ) + X = SDL_VideoSurface->w-1; + else + X = (Uint16)x; + + if ( y < 0 ) + Y = 0; + else + if ( y >= SDL_VideoSurface->h ) + Y = SDL_VideoSurface->h-1; + else + Y = (Uint16)y; + + /* If not relative mode, generate relative motion from clamped X/Y. + This prevents lots of extraneous large delta relative motion when + the screen is windowed mode and the mouse is outside the window. + */ + if ( ! relative ) { + Xrel = X-SDL_MouseX; + Yrel = Y-SDL_MouseY; + } + + /* Update internal mouse state */ + SDL_ButtonState = buttonstate; + SDL_MouseX = X; + SDL_MouseY = Y; + SDL_DeltaX += Xrel; + SDL_DeltaY += Yrel; + SDL_MoveCursor(SDL_MouseX, SDL_MouseY); + + /* Post the event, if desired */ + posted = 0; + if ( SDL_ProcessEvents[SDL_MOUSEMOTION] == SDL_ENABLE ) { + SDL_Event event; + memset(&event, 0, sizeof(event)); + event.type = SDL_MOUSEMOTION; + event.motion.state = buttonstate; + event.motion.x = X; + event.motion.y = Y; + event.motion.xrel = Xrel; + event.motion.yrel = Yrel; + if ( (SDL_EventOK == NULL) || (*SDL_EventOK)(&event) ) { + posted = 1; + SDL_PushEvent(&event); + } + } + return(posted); +} + +int SDL_PrivateMouseButton(Uint8 state, Uint8 button, Sint16 x, Sint16 y) +{ + SDL_Event event; + int posted; + int move_mouse; + Uint8 buttonstate; + + memset(&event, 0, sizeof(event)); + + /* Check parameters */ + if ( x || y ) { + ClipOffset(&x, &y); + move_mouse = 1; + /* Mouse coordinates range from 0 - width-1 and 0 - height-1 */ + if ( x < 0 ) + x = 0; + else + if ( x >= SDL_VideoSurface->w ) + x = SDL_VideoSurface->w-1; + + if ( y < 0 ) + y = 0; + else + if ( y >= SDL_VideoSurface->h ) + y = SDL_VideoSurface->h-1; + } else { + move_mouse = 0; + } + if ( ! x ) + x = SDL_MouseX; + if ( ! y ) + y = SDL_MouseY; + + /* Figure out which event to perform */ + buttonstate = SDL_ButtonState; + switch ( state ) { + case SDL_PRESSED: + event.type = SDL_MOUSEBUTTONDOWN; + buttonstate |= SDL_BUTTON(button); + break; + case SDL_RELEASED: + event.type = SDL_MOUSEBUTTONUP; + buttonstate &= ~SDL_BUTTON(button); + break; + default: + /* Invalid state -- bail */ + return(0); + } + + /* Update internal mouse state */ + SDL_ButtonState = buttonstate; + if ( move_mouse ) { + SDL_MouseX = x; + SDL_MouseY = y; + /* We don't wan't the cursor because MenuetOS doesn't allow + hiding mouse cursor */ + // uncommented for KolibriOS + SDL_MoveCursor(SDL_MouseX, SDL_MouseY); + } + + /* Post the event, if desired */ + posted = 0; + if ( SDL_ProcessEvents[event.type] == SDL_ENABLE ) { + event.button.state = state; + event.button.button = button; + event.button.x = x; + event.button.y = y; + if ( (SDL_EventOK == NULL) || (*SDL_EventOK)(&event) ) { + posted = 1; + SDL_PushEvent(&event); + } + } + return(posted); +} + diff --git a/contrib/sdk/sources/SDL-1.2.2/src/events/SDL_quit.c b/contrib/sdk/sources/SDL-1.2.2/src/events/SDL_quit.c new file mode 100644 index 000000000..8092469c4 --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/src/events/SDL_quit.c @@ -0,0 +1,79 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997, 1998, 1999, 2000, 2001 Sam Lantinga + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the Free + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + Sam Lantinga + slouken@devolution.com +*/ + +/* General quit handling code for SDL */ + +#include +#ifndef NO_SIGNAL_H +#include +#endif + +#include "SDL_events.h" +#include "SDL_events_c.h" + + +#ifndef NO_SIGNAL_H +static void SDL_HandleSIG(int sig) +{ + /* Reset the signal handler */ + signal(sig, SDL_HandleSIG); + + /* Signal a quit interrupt */ + SDL_PrivateQuit(); +} +#endif /* NO_SIGNAL_H */ + +/* Public functions */ +int SDL_QuitInit(void) +{ +#ifndef NO_SIGNAL_H + void (*ohandler)(int); + + /* Both SIGINT and SIGTERM are translated into quit interrupts */ + ohandler = signal(SIGINT, SDL_HandleSIG); + if ( ohandler != SIG_DFL ) + signal(SIGINT, ohandler); + ohandler = signal(SIGTERM, SDL_HandleSIG); + if ( ohandler != SIG_DFL ) + signal(SIGTERM, ohandler); +#endif /* NO_SIGNAL_H */ + + /* That's it! */ + return(0); +} + +/* This function returns 1 if it's okay to close the application window */ +int SDL_PrivateQuit(void) +{ + int posted; + + posted = 0; + if ( SDL_ProcessEvents[SDL_QUIT] == SDL_ENABLE ) { + SDL_Event event; + event.type = SDL_QUIT; + if ( (SDL_EventOK == NULL) || (*SDL_EventOK)(&event) ) { + posted = 1; + SDL_PushEvent(&event); + } + } + return(posted); +} diff --git a/contrib/sdk/sources/SDL-1.2.2/src/events/SDL_resize.c b/contrib/sdk/sources/SDL-1.2.2/src/events/SDL_resize.c new file mode 100644 index 000000000..9b127bf00 --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/src/events/SDL_resize.c @@ -0,0 +1,72 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997, 1998, 1999, 2000, 2001 Sam Lantinga + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the Free + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + Sam Lantinga + slouken@devolution.com +*/ + + +/* Resize event handling code for SDL */ + +#include "SDL_events.h" +#include "SDL_events_c.h" +#include "SDL_sysvideo.h" + + +/* Keep the last resize event so we don't post duplicates */ +static struct { + int w; + int h; +} last_resize; + +/* This is global for SDL_eventloop.c */ +int SDL_PrivateResize(int w, int h) +{ + int posted; + SDL_Event events[32]; + + /* See if this event would change the video surface */ + if ( !w || !h || + ((last_resize.w == w) && (last_resize.h == h)) ) { + return(0); + } + last_resize.w = w; + last_resize.h = h; + if ( ! SDL_VideoSurface || + ((w == SDL_VideoSurface->w) && (h == SDL_VideoSurface->h)) ) { + return(0); + } + + /* Pull out all old resize events */ + SDL_PeepEvents(events, sizeof(events)/sizeof(events[0]), + SDL_GETEVENT, SDL_VIDEORESIZEMASK); + + /* Post the event, if desired */ + posted = 0; + if ( SDL_ProcessEvents[SDL_VIDEORESIZE] == SDL_ENABLE ) { + SDL_Event event; + event.type = SDL_VIDEORESIZE; + event.resize.w = w; + event.resize.h = h; + if ( (SDL_EventOK == NULL) || (*SDL_EventOK)(&event) ) { + posted = 1; + SDL_PushEvent(&event); + } + } + return(posted); +} diff --git a/contrib/sdk/sources/SDL-1.2.2/src/events/SDL_sysevents.h b/contrib/sdk/sources/SDL-1.2.2/src/events/SDL_sysevents.h new file mode 100644 index 000000000..0f9e5b4d5 --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/src/events/SDL_sysevents.h @@ -0,0 +1,46 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997, 1998, 1999, 2000, 2001 Sam Lantinga + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the Free + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + Sam Lantinga + slouken@devolution.com +*/ + +#ifdef SAVE_RCSID +static char rcsid = + "@(#) $Id: SDL_sysevents.h,v 1.2 2001/04/26 16:50:17 hercules Exp $"; +#endif + +#include "SDL_sysvideo.h" + +/* Useful functions and variables from SDL_sysevents.c */ + +#ifdef __BEOS__ /* The Be event loop runs in a separate thread */ +#define MUST_THREAD_EVENTS +#endif + +#ifdef WIN32UNDEFINED /* Win32 doesn't allow a separate event thread */ +#define CANT_THREAD_EVENTS +#endif + +#ifdef macintosh /* MacOS 7/8 don't support preemptive multi-tasking */ +#define CANT_THREAD_EVENTS +#endif + +#ifdef __MENUETOS__ +#define CANT_THREAD_EVENTS +#endif diff --git a/contrib/sdk/sources/SDL-1.2.2/src/events/SDL_sysevents.h.BAK b/contrib/sdk/sources/SDL-1.2.2/src/events/SDL_sysevents.h.BAK new file mode 100644 index 000000000..8d5c13328 --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/src/events/SDL_sysevents.h.BAK @@ -0,0 +1,46 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997, 1998, 1999, 2000, 2001 Sam Lantinga + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the Free + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + Sam Lantinga + slouken@devolution.com +*/ + +#ifdef SAVE_RCSID +static char rcsid = + "@(#) $Id: SDL_sysevents.h,v 1.2 2001/04/26 16:50:17 hercules Exp $"; +#endif + +#include "SDL_sysvideo.h" + +/* Useful functions and variables from SDL_sysevents.c */ + +#ifdef __BEOS__ /* The Be event loop runs in a separate thread */ +#define MUST_THREAD_EVENTS +#endif + +#ifdef WIN32 /* Win32 doesn't allow a separate event thread */ +#define CANT_THREAD_EVENTS +#endif + +#ifdef macintosh /* MacOS 7/8 don't support preemptive multi-tasking */ +#define CANT_THREAD_EVENTS +#endif + +#ifdef __MENUETOS__ +#define CANT_THREAD_EVENTS +#endif diff --git a/contrib/sdk/sources/SDL-1.2.2/src/file/SDL_rwops.c b/contrib/sdk/sources/SDL-1.2.2/src/file/SDL_rwops.c new file mode 100644 index 000000000..aac99d33d --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/src/file/SDL_rwops.c @@ -0,0 +1,207 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997, 1998, 1999, 2000, 2001 Sam Lantinga + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the Free + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + Sam Lantinga + slouken@devolution.com +*/ + +/* This file provides a general interface for SDL to read and write + data sources. It can easily be extended to files, memory, etc. +*/ + +#include +#include +#include + +#include "SDL_error.h" +#include "SDL_rwops.h" + +/* Functions to read/write stdio file pointers */ + +static int stdio_seek(SDL_RWops *context, int offset, int whence) +{ + if ( fseek(context->hidden.stdio.fp, offset, whence) == 0 ) + { + return(ftell(context->hidden.stdio.fp)); + } else { + SDL_Error(SDL_EFSEEK); + return(-1); + } +} + +static int stdio_read(SDL_RWops *context, void *ptr, int size, int maxnum) +{ + size_t nread; + nread = fread(ptr, size, maxnum, context->hidden.stdio.fp); + if ( nread == 0 && ferror(context->hidden.stdio.fp) ) + { + SDL_Error(SDL_EFREAD); + } + return(nread); +} + +static int stdio_write(SDL_RWops *context, const void *ptr, int size, int num) +{ + size_t nwrote; + nwrote = fwrite(ptr, size, num, context->hidden.stdio.fp); + if ( nwrote == 0 && ferror(context->hidden.stdio.fp) ) + { + SDL_Error(SDL_EFWRITE); + } + return(nwrote); +} + +static int stdio_close(SDL_RWops *context) +{ + if ( context ) + { + if ( context->hidden.stdio.autoclose ) + { + fclose(context->hidden.stdio.fp); + } + free(context); + } + return(0); +} + +static int mem_seek(SDL_RWops *context, int offset, int whence) +{ + Uint8 *newpos; + switch (whence) + { + case SEEK_SET: + newpos = context->hidden.mem.base+offset; + break; + case SEEK_CUR: + newpos = context->hidden.mem.here+offset; + break; + case SEEK_END: + newpos = context->hidden.mem.stop+offset; + break; + default: + SDL_SetError("Unknown value for 'whence'"); + return(-1); + } + if ( newpos < context->hidden.mem.base ) + { + newpos = context->hidden.mem.base; + } + if ( newpos > context->hidden.mem.stop ) + { + newpos = context->hidden.mem.stop; + } + context->hidden.mem.here = newpos; + return(context->hidden.mem.here-context->hidden.mem.base); +} + +static int mem_read(SDL_RWops *context, void *ptr, int size, int maxnum) +{ + int num; + num = maxnum; + if ( (context->hidden.mem.here + (num*size)) > context->hidden.mem.stop ) + { + num = (context->hidden.mem.stop-context->hidden.mem.here)/size; + } + memcpy(ptr, context->hidden.mem.here, num*size); + context->hidden.mem.here += num*size; + return(num); +} + +static int mem_write(SDL_RWops *context, const void *ptr, int size, int num) +{ + if ( (context->hidden.mem.here + (num*size)) > context->hidden.mem.stop ) + { + num = (context->hidden.mem.stop-context->hidden.mem.here)/size; + } + memcpy(context->hidden.mem.here, ptr, num*size); + context->hidden.mem.here += num*size; + return(num); +} + +static int mem_close(SDL_RWops *context) +{ + if ( context ) + { + free(context); + } + return(0); +} + +SDL_RWops *SDL_RWFromFile(const char *file, const char *mode) +{ + FILE *fp; + SDL_RWops *rwops; + rwops = NULL; + fp = fopen(file, mode); + if ( fp == NULL ) + { + SDL_SetError("Couldn't open %s", file); + } else { + rwops = SDL_RWFromFP(fp, 1); + } + return(rwops); +} + +SDL_RWops *SDL_RWFromFP(FILE *fp, int autoclose) +{ + SDL_RWops *rwops; + rwops = SDL_AllocRW(); + if ( rwops != NULL ) + { + rwops->seek = stdio_seek; + rwops->read = stdio_read; + rwops->write = stdio_write; + rwops->close = stdio_close; + rwops->hidden.stdio.fp = fp; + rwops->hidden.stdio.autoclose = autoclose; + } + return(rwops); +} + +SDL_RWops *SDL_RWFromMem(void *mem, int size) +{ + SDL_RWops *rwops; + rwops = SDL_AllocRW(); + if ( rwops != NULL ) + { + rwops->seek = mem_seek; + rwops->read = mem_read; + rwops->write = mem_write; + rwops->close = mem_close; + rwops->hidden.mem.base = (Uint8 *)mem; + rwops->hidden.mem.here = rwops->hidden.mem.base; + rwops->hidden.mem.stop = rwops->hidden.mem.base+size; + } + return(rwops); +} + +SDL_RWops *SDL_AllocRW(void) +{ + SDL_RWops *area; + area = (SDL_RWops *)malloc(sizeof *area); + if ( area == NULL ) + { + SDL_OutOfMemory(); + } + return(area); +} + +void SDL_FreeRW(SDL_RWops *area) +{ + free(area); +} diff --git a/contrib/sdk/sources/SDL-1.2.2/src/hermes/HeadMMX.h b/contrib/sdk/sources/SDL-1.2.2/src/hermes/HeadMMX.h new file mode 100644 index 000000000..fcb5e3ad8 --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/src/hermes/HeadMMX.h @@ -0,0 +1,101 @@ +/* + Header definitions for the MMX routines for the HERMES library + Copyright (c) 1998 Christian Nentwich (c.nentwich@cs.ucl.ac.uk) + This source code is licensed under the GNU LGPL + + Please refer to the file COPYING.LIB contained in the distribution for + licensing conditions +*/ + +#ifndef __HERMES_HEAD_MMX__ +#define __HERMES_HEAD_MMX__ + + +/* If you cannot stand ifdefs, then please do not look into this file, it's + going to end your life :) */ + +#ifdef X86_ASSEMBLER + + +#ifdef __cplusplus +extern "C" { +#endif + +void STACKCALL ConvertMMX(HermesConverterInterface *); + +void STACKCALL ClearMMX_32(HermesClearInterface *); +void STACKCALL ClearMMX_24(HermesClearInterface *); +void STACKCALL ClearMMX_16(HermesClearInterface *); +void STACKCALL ClearMMX_8(HermesClearInterface *); + +void ConvertMMXpII32_24RGB888(); +void ConvertMMXpII32_16RGB565(); +void ConvertMMXpII32_16BGR565(); +void ConvertMMXpII32_16RGB555(); +void ConvertMMXpII32_16BGR565(); +void ConvertMMXpII32_16BGR555(); + +void ConvertMMXp32_16RGB555(); + +#ifdef __cplusplus +} +#endif + + + +/* Fix the underscore business with ELF compilers */ + +#if defined(__ELF__) && defined(__GNUC__) + #ifdef __cplusplus + extern "C" { + #endif + + void ConvertMMX(HermesConverterInterface *) __attribute__ ((alias ("_ConvertMMX"))); +#if 0 + void ClearMMX_32(HermesClearInterface *) __attribute__ ((alias ("_ClearMMX_32"))); + void ClearMMX_24(HermesClearInterface *) __attribute__ ((alias ("_ClearMMX_24"))); + void ClearMMX_16(HermesClearInterface *) __attribute__ ((alias ("_ClearMMX_16"))); + void ClearMMX_8(HermesClearInterface *) __attribute__ ((alias ("_ClearMMX_8"))); + + void ConvertMMXp32_16RGB555() __attribute__ ((alias ("_ConvertMMXp32_16RGB555"))); +#endif + + void ConvertMMXpII32_24RGB888() __attribute__ ((alias ("_ConvertMMXpII32_24RGB888"))); + void ConvertMMXpII32_16RGB565() __attribute__ ((alias ("_ConvertMMXpII32_16RGB565"))); + void ConvertMMXpII32_16BGR565() __attribute__ ((alias ("_ConvertMMXpII32_16BGR565"))); + void ConvertMMXpII32_16RGB555() __attribute__ ((alias ("_ConvertMMXpII32_16RGB555"))); + void ConvertMMXpII32_16BGR555() __attribute__ ((alias ("_ConvertMMXpII32_16BGR555"))); + + #ifdef __cplusplus + } + #endif + +#endif /* ELF and GNUC */ + + + + +/* Make it work with Watcom */ +#ifdef __WATCOMC__ +#pragma warning 601 9 + +#pragma aux ConvertMMX "_*" modify [EAX EBX ECX EDX ESI EDI] + +#pragma aux ClearMMX_32 "_*" modify [EAX EBX ECX EDX ESI EDI] +#pragma aux ClearMMX_24 "_*" modify [EAX EBX ECX EDX ESI EDI] +#pragma aux ClearMMX_16 "_*" modify [EAX EBX ECX EDX ESI EDI] +#pragma aux ClearMMX_8 "_*" modify [EAX EBX ECX EDX ESI EDI] + +#pragma aux ConvertMMXpII32_24RGB888 "_*" +#pragma aux ConvertMMXpII32_16RGB565 "_*" +#pragma aux ConvertMMXpII32_16BGR565 "_*" +#pragma aux ConvertMMXpII32_16RGB555 "_*" +#pragma aux ConvertMMXpII32_16BGR555 "_*" +#pragma aux ConvertMMXp32_16RGB555 "_*" + +#endif /* WATCOM */ + +#endif /* X86_ASSEMBLER */ + + +#endif diff --git a/contrib/sdk/sources/SDL-1.2.2/src/hermes/HeadX86.h b/contrib/sdk/sources/SDL-1.2.2/src/hermes/HeadX86.h new file mode 100644 index 000000000..6e10427f5 --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/src/hermes/HeadX86.h @@ -0,0 +1,195 @@ +/* + Header definitions for the x86 routines for the HERMES library + Copyright (c) 1998 Christian Nentwich (brn@eleet.mcb.at) + This source code is licensed under the GNU LGPL + + Please refer to the file COPYING.LIB contained in the distribution for + licensing conditions +*/ + +#ifndef __HERMES_HEAD_X86__ +#define __HERMES_HEAD_X86__ + + +#ifdef X86_ASSEMBLER + +/* If you can't stand IFDEFS, then close your eyes now, please :) */ + +/* Ok, we start with normal function definitions */ +#ifdef __cplusplus +extern "C" { +#endif + + +void STACKCALL ConvertX86(HermesConverterInterface *); +void STACKCALL ClearX86_32(HermesClearInterface *); +void STACKCALL ClearX86_24(HermesClearInterface *); +void STACKCALL ClearX86_16(HermesClearInterface *); +void STACKCALL ClearX86_8(HermesClearInterface *); + +int STACKCALL Hermes_X86_CPU(); + +void ConvertX86p32_32BGR888(); +void ConvertX86p32_32RGBA888(); +void ConvertX86p32_32BGRA888(); +void ConvertX86p32_24RGB888(); +void ConvertX86p32_24BGR888(); +void ConvertX86p32_16RGB565(); +void ConvertX86p32_16BGR565(); +void ConvertX86p32_16RGB555(); +void ConvertX86p32_16BGR555(); +void ConvertX86p32_8RGB332(); + +void ConvertX86p16_32RGB888(); +void ConvertX86p16_32BGR888(); +void ConvertX86p16_32RGBA888(); +void ConvertX86p16_32BGRA888(); +void ConvertX86p16_24RGB888(); +void ConvertX86p16_24BGR888(); +void ConvertX86p16_16BGR565(); +void ConvertX86p16_16RGB555(); +void ConvertX86p16_16BGR555(); +void ConvertX86p16_8RGB332(); + +void CopyX86p_4byte(); +void CopyX86p_3byte(); +void CopyX86p_2byte(); +void CopyX86p_1byte(); + +void ConvertX86pI8_32(); +void ConvertX86pI8_24(); +void ConvertX86pI8_16(); + +extern int32 ConvertX86p16_32RGB888_LUT_X86[512]; +extern int32 ConvertX86p16_32BGR888_LUT_X86[512]; +extern int32 ConvertX86p16_32RGBA888_LUT_X86[512]; +extern int32 ConvertX86p16_32BGRA888_LUT_X86[512]; + +#ifdef __cplusplus +} +#endif + + + + +/* Now fix up the ELF underscore problem */ + +#if defined(__ELF__) && defined(__GNUC__) + #ifdef __cplusplus + extern "C" { + #endif + + int Hermes_X86_CPU() __attribute__ ((alias ("_Hermes_X86_CPU"))); + + void ConvertX86(HermesConverterInterface *) __attribute__ ((alias ("_ConvertX86"))); + +#if 0 + void ClearX86_32(HermesClearInterface *) __attribute__ ((alias ("_ClearX86_32"))); + void ClearX86_24(HermesClearInterface *) __attribute__ ((alias ("_ClearX86_24"))); + void ClearX86_16(HermesClearInterface *) __attribute__ ((alias ("_ClearX86_16"))); + void ClearX86_8(HermesClearInterface *) __attribute__ ((alias ("_ClearX86_8"))); +#endif + + void ConvertX86p32_32BGR888() __attribute__ ((alias ("_ConvertX86p32_32BGR888"))); + void ConvertX86p32_32RGBA888() __attribute__ ((alias ("_ConvertX86p32_32RGBA888"))); + void ConvertX86p32_32BGRA888() __attribute__ ((alias ("_ConvertX86p32_32BGRA888"))); + void ConvertX86p32_24RGB888() __attribute__ ((alias ("_ConvertX86p32_24RGB888"))); + void ConvertX86p32_24BGR888() __attribute__ ((alias ("_ConvertX86p32_24BGR888"))); + void ConvertX86p32_16RGB565() __attribute__ ((alias ("_ConvertX86p32_16RGB565"))); + void ConvertX86p32_16BGR565() __attribute__ ((alias ("_ConvertX86p32_16BGR565"))); + void ConvertX86p32_16RGB555() __attribute__ ((alias ("_ConvertX86p32_16RGB555"))); + void ConvertX86p32_16BGR555() __attribute__ ((alias ("_ConvertX86p32_16BGR555"))); + void ConvertX86p32_8RGB332() __attribute__ ((alias ("_ConvertX86p32_8RGB332"))); + +#if 0 + void ConvertX86p16_32RGB888() __attribute__ ((alias ("_ConvertX86p16_32RGB888"))); + void ConvertX86p16_32BGR888() __attribute__ ((alias ("_ConvertX86p16_32BGR888"))); + void ConvertX86p16_32RGBA888() __attribute__ ((alias ("_ConvertX86p16_32RGBA888"))); + void ConvertX86p16_32BGRA888() __attribute__ ((alias ("_ConvertX86p16_32BGRA888"))); + void ConvertX86p16_24RGB888() __attribute__ ((alias ("_ConvertX86p16_24RGB888"))); + void ConvertX86p16_24BGR888() __attribute__ ((alias ("_ConvertX86p16_24BGR888"))); +#endif + void ConvertX86p16_16BGR565() __attribute__ ((alias ("_ConvertX86p16_16BGR565"))); + void ConvertX86p16_16RGB555() __attribute__ ((alias ("_ConvertX86p16_16RGB555"))); + void ConvertX86p16_16BGR555() __attribute__ ((alias ("_ConvertX86p16_16BGR555"))); + void ConvertX86p16_8RGB332() __attribute__ ((alias ("_ConvertX86p16_8RGB332"))); + +#if 0 + void CopyX86p_4byte() __attribute__ ((alias ("_CopyX86p_4byte"))); + void CopyX86p_3byte() __attribute__ ((alias ("_CopyX86p_3byte"))); + void CopyX86p_2byte() __attribute__ ((alias ("_CopyX86p_2byte"))); + void CopyX86p_1byte() __attribute__ ((alias ("_CopyX86p_1byte"))); + + void ConvertX86pI8_32() __attribute__ ((alias ("_ConvertX86pI8_32"))); + void ConvertX86pI8_24() __attribute__ ((alias ("_ConvertX86pI8_24"))); + void ConvertX86pI8_16() __attribute__ ((alias ("_ConvertX86pI8_16"))); + + extern int32 ConvertX86p16_32RGB888_LUT_X86[512] __attribute__ ((alias ("_ConvertX86p16_32RGB888_LUT_X86"))); + extern int32 ConvertX86p16_32BGR888_LUT_X86[512] __attribute__ ((alias ("_ConvertX86p16_32BGR888_LUT_X86"))); + extern int32 ConvertX86p16_32RGBA888_LUT_X86[512] __attribute__ ((alias ("_ConvertX86p16_32RGBA888_LUT_X86"))); + extern int32 ConvertX86p16_32BGRA888_LUT_X86[512] __attribute__ ((alias ("_ConvertX86p16_32BGRA888_LUT_X86"))); +#endif + + #ifdef __cplusplus + } + #endif + +#endif /* ELF & GNU */ + + + +/* Make it run with WATCOM C */ +#ifdef __WATCOMC__ +#pragma warning 601 9 + +#pragma aux Hermes_X86_CPU "_*" + +#pragma aux ConvertX86 "_*" modify [EAX EBX ECX EDX ESI EDI] +#pragma aux ClearX86_32 "_*" modify [EAX EBX ECX EDX ESI EDI] +#pragma aux ClearX86_24 "_*" modify [EAX EBX ECX EDX ESI EDI] +#pragma aux ClearX86_16 "_*" modify [EAX EBX ECX EDX ESI EDI] +#pragma aux ClearX86_8 "_*" modify [EAX EBX ECX EDX ESI EDI] + +#pragma aux ConvertX86p32_32BGR888 "_*" +#pragma aux ConvertX86p32_32RGBA888 "_*" +#pragma aux ConvertX86p32_32BGRA888 "_*" +#pragma aux ConvertX86p32_24RGB888 "_*" +#pragma aux ConvertX86p32_24BGR888 "_*" +#pragma aux ConvertX86p32_16RGB565 "_*" +#pragma aux ConvertX86p32_16BGR565 "_*" +#pragma aux ConvertX86p32_16RGB555 "_*" +#pragma aux ConvertX86p32_16BGR555 "_*" +#pragma aux ConvertX86p32_8RGB332 "_*" + +#pragma aux ConvertX86p16_32RGB888 "_*" +#pragma aux ConvertX86p16_32BGR888 "_*" +#pragma aux ConvertX86p16_32RGBA888 "_*" +#pragma aux ConvertX86p16_32BGRA888 "_*" +#pragma aux ConvertX86p16_24RGB888 "_*" +#pragma aux ConvertX86p16_24BGR888 "_*" +#pragma aux ConvertX86p16_16BGR565 "_*" +#pragma aux ConvertX86p16_16RGB555 "_*" +#pragma aux ConvertX86p16_16BGR555 "_*" +#pragma aux ConvertX86p16_8RGB332 "_*" + +#pragma aux CopyX86p_4byte "_*" +#pragma aux CopyX86p_3byte "_*" +#pragma aux CopyX86p_2byte "_*" +#pragma aux CopyX86p_1byte "_*" + +#pragma aux ConvertX86pI8_32 "_*" +#pragma aux ConvertX86pI8_24 "_*" +#pragma aux ConvertX86pI8_16 "_*" + +#pragma aux ConvertX86p16_32RGB888_LUT_X86 "_*" +#pragma aux ConvertX86p16_32BGR888_LUT_X86 "_*" +#pragma aux ConvertX86p16_32RGBA888_LUT_X86 "_*" +#pragma aux ConvertX86p16_32BGRA888_LUT_X86 "_*" + +#endif /* __WATCOMC__ */ + + +#endif /* X86_ASSEMBLER */ + + +#endif diff --git a/contrib/sdk/sources/SDL-1.2.2/src/hermes/mmx_main.asm b/contrib/sdk/sources/SDL-1.2.2/src/hermes/mmx_main.asm new file mode 100644 index 000000000..b1d2dbc7f --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/src/hermes/mmx_main.asm @@ -0,0 +1,74 @@ +; +; mmx format converter main loops for HERMES +; Some routines Copyright (c) 1998 Christian Nentwich (c.nentwich@cs.ucl.ac.uk) +; This source code is licensed under the GNU LGPL +; +; Please refer to the file COPYING.LIB contained in the distribution for +; licensing conditions +; + +BITS 32 + +GLOBAL _ConvertMMX +GLOBAL _mmxreturn + + +SECTION .text + +;; _ConvertMMX: +;; [ESP+8] ConverterInfo* +;; -------------------------------------------------------------------------- +;; ConverterInfo (ebp+..) +;; 0: void *s_pixels +;; 4: int s_width +;; 8: int s_height +;; 12: int s_add +;; 16: void *d_pixels +;; 20: int d_width +;; 24: int d_height +;; 28: int d_add +;; 32: void (*converter_function)() +;; 36: int32 *lookup + +_ConvertMMX: + push ebp + mov ebp,esp + +; Save the registers used by the blitters, necessary for optimized code + pusha + + mov eax,[ebp+8] + + cmp dword [eax+4],BYTE 0 + je endconvert + + mov ebp,eax + + mov esi,[ebp+0] + mov edi,[ebp+16] + +y_loop: + mov ecx,[ebp+4] + + jmp [ebp+32] + +_mmxreturn: + add esi,[ebp+12] + add edi,[ebp+28] + + dec dword [ebp+8] + jnz y_loop + + +; Restore the registers used by the blitters, necessary for optimized code + popa + + pop ebp + +endconvert: + emms + + ret + + + diff --git a/contrib/sdk/sources/SDL-1.2.2/src/hermes/mmxp2_32.asm b/contrib/sdk/sources/SDL-1.2.2/src/hermes/mmxp2_32.asm new file mode 100644 index 000000000..552b48437 --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/src/hermes/mmxp2_32.asm @@ -0,0 +1,386 @@ +; +; pII-optimised MMX format converters for HERMES +; Copyright (c) 1998 Christian Nentwich (c.nentwich@cs.ucl.ac.uk) +; and (c) 1999 Jonathan Matthew (jmatthew@uq.net.au) +; This source code is licensed under the GNU LGPL +; +; Please refer to the file COPYING.LIB contained in the distribution for +; licensing conditions +; +; COPYRIGHT NOTICE +; +; This file partly contains code that is (c) Intel Corporation, specifically +; the mode detection routine, and the converter to 15 bit (8 pixel +; conversion routine from the mmx programming tutorial pages). +; +; +; These routines aren't exactly pII optimised - it's just that as they +; are, they're terrible on p5 MMXs, but less so on pIIs. Someone needs to +; optimise them for p5 MMXs.. + +BITS 32 + + +GLOBAL _ConvertMMXpII32_24RGB888 +GLOBAL _ConvertMMXpII32_16RGB565 +GLOBAL _ConvertMMXpII32_16BGR565 +GLOBAL _ConvertMMXpII32_16RGB555 +GLOBAL _ConvertMMXpII32_16BGR555 + +EXTERN _mmxreturn + +SECTION .data + +ALIGN 8 + +;; Constants for conversion routines + +mmx32_rgb888_mask dd 00ffffffh,00ffffffh + +mmx32_rgb565_b dd 000000f8h, 000000f8h +mmx32_rgb565_g dd 0000fc00h, 0000fc00h +mmx32_rgb565_r dd 00f80000h, 00f80000h + +mmx32_rgb555_rb dd 00f800f8h,00f800f8h +mmx32_rgb555_g dd 0000f800h,0000f800h +mmx32_rgb555_mul dd 20000008h,20000008h +mmx32_bgr555_mul dd 00082000h,00082000h + + + +SECTION .text + +_ConvertMMXpII32_24RGB888: + + ; set up mm6 as the mask, mm7 as zero + movq mm6, qword [mmx32_rgb888_mask] + pxor mm7, mm7 + + mov edx, ecx ; save ecx + and ecx, 0fffffffch ; clear lower two bits + jnz .L1 + jmp .L2 + +.L1: + + movq mm0, [esi] ; A R G B a r g b + pand mm0, mm6 ; 0 R G B 0 r g b + movq mm1, [esi+8] ; A R G B a r g b + pand mm1, mm6 ; 0 R G B 0 r g b + + movq mm2, mm0 ; 0 R G B 0 r g b + punpckhdq mm2, mm7 ; 0 0 0 0 0 R G B + punpckldq mm0, mm7 ; 0 0 0 0 0 r g b + psllq mm2, 24 ; 0 0 R G B 0 0 0 + por mm0, mm2 ; 0 0 R G B r g b + + movq mm3, mm1 ; 0 R G B 0 r g b + psllq mm3, 48 ; g b 0 0 0 0 0 0 + por mm0, mm3 ; g b R G B r g b + + movq mm4, mm1 ; 0 R G B 0 r g b + punpckhdq mm4, mm7 ; 0 0 0 0 0 R G B + punpckldq mm1, mm7 ; 0 0 0 0 0 r g b + psrlq mm1, 16 ; 0 0 0 R G B 0 r + psllq mm4, 8 ; 0 0 0 0 R G B 0 + por mm1, mm4 ; 0 0 0 0 R G B r + + movq [edi], mm0 + add esi, BYTE 16 + movd [edi+8], mm1 + add edi, BYTE 12 + sub ecx, BYTE 4 + jnz .L1 + +.L2: + mov ecx, edx + and ecx, BYTE 3 + jz .L4 +.L3: + mov al, [esi] + mov bl, [esi+1] + mov dl, [esi+2] + mov [edi], al + mov [edi+1], bl + mov [edi+2], dl + add esi, BYTE 4 + add edi, BYTE 3 + dec ecx + jnz .L3 +.L4: + jmp _mmxreturn + + + +_ConvertMMXpII32_16RGB565: + + ; set up masks + movq mm5, [mmx32_rgb565_b] + movq mm6, [mmx32_rgb565_g] + movq mm7, [mmx32_rgb565_r] + + mov edx, ecx + shr ecx, 2 + jnz .L1 + jmp .L2 ; not necessary at the moment, but doesn't hurt (much) + +.L1: + movq mm0, [esi] ; argb + movq mm1, mm0 ; argb + pand mm0, mm6 ; 00g0 + movq mm3, mm1 ; argb + pand mm1, mm5 ; 000b + pand mm3, mm7 ; 0r00 + pslld mm1, 2 ; 0 0 000000bb bbb00000 + por mm0, mm1 ; 0 0 ggggggbb bbb00000 + psrld mm0, 5 ; 0 0 00000ggg gggbbbbb + + movq mm4, [esi+8] ; argb + movq mm2, mm4 ; argb + pand mm4, mm6 ; 00g0 + movq mm1, mm2 ; argb + pand mm2, mm5 ; 000b + pand mm1, mm7 ; 0r00 + pslld mm2, 2 ; 0 0 000000bb bbb00000 + por mm4, mm2 ; 0 0 ggggggbb bbb00000 + psrld mm4, 5 ; 0 0 00000ggg gggbbbbb + + packuswb mm3, mm1 ; R 0 r 0 + packssdw mm0, mm4 ; as above.. ish + por mm0, mm3 ; done. + movq [edi], mm0 + + add esi, 16 + add edi, 8 + dec ecx + jnz .L1 + +.L2: + mov ecx, edx + and ecx, BYTE 3 + jz .L4 +.L3: + mov al, [esi] + mov bh, [esi+1] + mov ah, [esi+2] + shr al, 3 + and eax, 0F81Fh ; BYTE? + shr ebx, 5 + and ebx, 07E0h ; BYTE? + add eax, ebx + mov [edi], al + mov [edi+1], ah + add esi, BYTE 4 + add edi, BYTE 2 + dec ecx + jnz .L3 + +.L4: + jmp _mmxreturn + + +_ConvertMMXpII32_16BGR565: + + movq mm5, [mmx32_rgb565_r] + movq mm6, [mmx32_rgb565_g] + movq mm7, [mmx32_rgb565_b] + + mov edx, ecx + shr ecx, 2 + jnz .L1 + jmp .L2 + +.L1: + movq mm0, [esi] ; a r g b + movq mm1, mm0 ; a r g b + pand mm0, mm6 ; 0 0 g 0 + movq mm3, mm1 ; a r g b + pand mm1, mm5 ; 0 r 0 0 + pand mm3, mm7 ; 0 0 0 b + + psllq mm3, 16 ; 0 b 0 0 + psrld mm1, 14 ; 0 0 000000rr rrr00000 + por mm0, mm1 ; 0 0 ggggggrr rrr00000 + psrld mm0, 5 ; 0 0 00000ggg gggrrrrr + + movq mm4, [esi+8] ; a r g b + movq mm2, mm4 ; a r g b + pand mm4, mm6 ; 0 0 g 0 + movq mm1, mm2 ; a r g b + pand mm2, mm5 ; 0 r 0 0 + pand mm1, mm7 ; 0 0 0 b + + psllq mm1, 16 ; 0 b 0 0 + psrld mm2, 14 ; 0 0 000000rr rrr00000 + por mm4, mm2 ; 0 0 ggggggrr rrr00000 + psrld mm4, 5 ; 0 0 00000ggg gggrrrrr + + packuswb mm3, mm1 ; BBBBB000 00000000 bbbbb000 00000000 + packssdw mm0, mm4 ; 00000GGG GGGRRRRR 00000GGG GGGRRRRR + por mm0, mm3 ; BBBBBGGG GGGRRRRR bbbbbggg gggrrrrr + movq [edi], mm0 + + add esi, BYTE 16 + add edi, BYTE 8 + dec ecx + jnz .L1 + +.L2: + and edx, BYTE 3 + jz .L4 +.L3: + mov al, [esi+2] + mov bh, [esi+1] + mov ah, [esi] + shr al, 3 + and eax, 0F81Fh ; BYTE ? + shr ebx, 5 + and ebx, 07E0h ; BYTE ? + add eax, ebx + mov [edi], al + mov [edi+1], ah + add esi, BYTE 4 + add edi, BYTE 2 + dec edx + jnz .L3 + +.L4: + jmp _mmxreturn + +_ConvertMMXpII32_16BGR555: + + ; the 16BGR555 converter is identical to the RGB555 one, + ; except it uses a different multiplier for the pmaddwd + ; instruction. cool huh. + + movq mm7, qword [mmx32_bgr555_mul] + jmp _convert_bgr555_cheat + +; This is the same as the Intel version.. they obviously went to +; much more trouble to expand/coil the loop than I did, so theirs +; would almost certainly be faster, even if only a little. +; I did rename 'mmx32_rgb555_add' to 'mmx32_rgb555_mul', which is +; (I think) a more accurate name.. +_ConvertMMXpII32_16RGB555: + + movq mm7,qword [mmx32_rgb555_mul] +_convert_bgr555_cheat: + movq mm6,qword [mmx32_rgb555_g] + + mov edx,ecx ; Save ecx + + and ecx,BYTE 0fffffff8h ; clear lower three bits + jnz .L_OK + jmp .L2 + +.L_OK: + + movq mm2,[esi+8] + + movq mm0,[esi] + movq mm3,mm2 + + pand mm3,qword [mmx32_rgb555_rb] + movq mm1,mm0 + + pand mm1,qword [mmx32_rgb555_rb] + pmaddwd mm3,mm7 + + pmaddwd mm1,mm7 + pand mm2,mm6 + +.L1: + movq mm4,[esi+24] + pand mm0,mm6 + + movq mm5,[esi+16] + por mm3,mm2 + + psrld mm3,6 + por mm1,mm0 + + movq mm0,mm4 + psrld mm1,6 + + pand mm0,qword [mmx32_rgb555_rb] + packssdw mm1,mm3 + + movq mm3,mm5 + pmaddwd mm0,mm7 + + pand mm3,qword [mmx32_rgb555_rb] + pand mm4,mm6 + + movq [edi],mm1 + pmaddwd mm3,mm7 + + add esi,BYTE 32 + por mm4,mm0 + + pand mm5,mm6 + psrld mm4,6 + + movq mm2,[esi+8] + por mm5,mm3 + + movq mm0,[esi] + psrld mm5,6 + + movq mm3,mm2 + movq mm1,mm0 + + pand mm3,qword [mmx32_rgb555_rb] + packssdw mm5,mm4 + + pand mm1,qword [mmx32_rgb555_rb] + pand mm2,mm6 + + movq [edi+8],mm5 + pmaddwd mm3,mm7 + + pmaddwd mm1,mm7 + add edi,BYTE 16 + + sub ecx,BYTE 8 + jz .L2 + jmp .L1 + + +.L2: + mov ecx,edx + + and ecx,BYTE 7 + jz .L4 + +.L3: + mov ebx,[esi] + add esi,BYTE 4 + + mov eax,ebx + mov edx,ebx + + shr eax,3 + shr edx,6 + + and eax,BYTE 0000000000011111b + and edx, 0000001111100000b + + shr ebx,9 + + or eax,edx + + and ebx, 0111110000000000b + + or eax,ebx + + mov [edi],ax + add edi,BYTE 2 + + dec ecx + jnz .L3 + +.L4: + jmp _mmxreturn + + + diff --git a/contrib/sdk/sources/SDL-1.2.2/src/hermes/x86_main.asm b/contrib/sdk/sources/SDL-1.2.2/src/hermes/x86_main.asm new file mode 100644 index 000000000..917a61572 --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/src/hermes/x86_main.asm @@ -0,0 +1,126 @@ +; +; x86 format converters for HERMES +; Some routines Copyright (c) 1998 Christian Nentwich (brn@eleet.mcb.at) +; This source code is licensed under the GNU LGPL +; +; Please refer to the file COPYING.LIB contained in the distribution for +; licensing conditions +; +; Most routines are (c) Glenn Fiedler (ptc@gaffer.org), used with permission +; + +BITS 32 + +GLOBAL _ConvertX86 +GLOBAL _x86return + +GLOBAL _Hermes_X86_CPU + + +SECTION .data + +cpu_flags dd 0 + + +SECTION .text + +;; _ConvertX86: +;; [ESP+8] ConverterInfo* +;; -------------------------------------------------------------------------- +;; ConverterInfo (ebp+..) +;; 0: void *s_pixels +;; 4: int s_width +;; 8: int s_height +;; 12: int s_add +;; 16: void *d_pixels +;; 20: int d_width +;; 24: int d_height +;; 28: int d_add +;; 32: void (*converter_function)() +;; 36: int32 *lookup + +_ConvertX86: + push ebp + mov ebp,esp + +; Save the registers used by the blitters, necessary for optimized code + pusha + + mov eax,[ebp+8] + + cmp dword [eax+4],BYTE 0 + je endconvert + + mov ebp,eax + + mov esi,[ebp+0] + mov edi,[ebp+16] + +y_loop: + mov ecx,[ebp+4] + + jmp [ebp+32] + +_x86return: + add esi,[ebp+12] + add edi,[ebp+28] + + dec dword [ebp+8] + jnz y_loop + +; Restore the registers used by the blitters, necessary for optimized code + popa + + pop ebp + +endconvert: + ret + + + +;; Hermes_X86_CPU returns the CPUID flags in eax + +_Hermes_X86_CPU: + pushfd + pop eax + + mov ecx,eax + + xor eax,040000h + push eax + + popfd + pushfd + + pop eax + xor eax,ecx + jz .L1 ; Processor is 386 + + push ecx + popfd + + mov eax,ecx + xor eax,200000h + + push eax + popfd + pushfd + + pop eax + xor eax,ecx + je .L1 + + pusha + + mov eax,1 + cpuid + + mov [cpu_flags],edx + + popa + + mov eax,[cpu_flags] + +.L1: + xor eax,eax + ret diff --git a/contrib/sdk/sources/SDL-1.2.2/src/hermes/x86p_16.asm b/contrib/sdk/sources/SDL-1.2.2/src/hermes/x86p_16.asm new file mode 100644 index 000000000..fd28a2b06 --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/src/hermes/x86p_16.asm @@ -0,0 +1,496 @@ +; +; x86 format converters for HERMES +; Copyright (c) 1998 Glenn Fielder (gaffer@gaffer.org) +; This source code is licensed under the GNU LGPL +; +; Please refer to the file COPYING.LIB contained in the distribution for +; licensing conditions +; +; Routines adjusted for Hermes by Christian Nentwich (brn@eleet.mcb.at) +; Used with permission. +; + + +BITS 32 + +GLOBAL _ConvertX86p16_32RGB888 +GLOBAL _ConvertX86p16_32BGR888 +GLOBAL _ConvertX86p16_32RGBA888 +GLOBAL _ConvertX86p16_32BGRA888 +GLOBAL _ConvertX86p16_24RGB888 +GLOBAL _ConvertX86p16_24BGR888 +GLOBAL _ConvertX86p16_16BGR565 +GLOBAL _ConvertX86p16_16RGB555 +GLOBAL _ConvertX86p16_16BGR555 +GLOBAL _ConvertX86p16_8RGB332 + +EXTERN _ConvertX86 +EXTERN _x86return + + +SECTION .text + + + +_ConvertX86p16_16BGR565: + + ; check short + cmp ecx,BYTE 16 + ja .L3 + + +.L1 ; short loop + mov al,[esi] + mov ah,[esi+1] + mov ebx,eax + mov edx,eax + shr eax,11 + and eax,BYTE 11111b + and ebx,11111100000b + shl edx,11 + add eax,ebx + add eax,edx + mov [edi],al + mov [edi+1],ah + add esi,BYTE 2 + add edi,BYTE 2 + dec ecx + jnz .L1 +.L2 + jmp _x86return + +.L3 ; head + mov eax,edi + and eax,BYTE 11b + jz .L4 + mov al,[esi] + mov ah,[esi+1] + mov ebx,eax + mov edx,eax + shr eax,11 + and eax,BYTE 11111b + and ebx,11111100000b + shl edx,11 + add eax,ebx + add eax,edx + mov [edi],al + mov [edi+1],ah + add esi,BYTE 2 + add edi,BYTE 2 + dec ecx + +.L4 ; save count + push ecx + + ; unroll twice + shr ecx,1 + + ; point arrays to end + lea esi,[esi+ecx*4] + lea edi,[edi+ecx*4] + + ; negative counter + neg ecx + jmp SHORT .L6 + +.L5 mov [edi+ecx*4-4],eax +.L6 mov eax,[esi+ecx*4] + + mov ebx,[esi+ecx*4] + and eax,07E007E0h + + mov edx,[esi+ecx*4] + and ebx,0F800F800h + + shr ebx,11 + and edx,001F001Fh + + shl edx,11 + add eax,ebx + + add eax,edx + inc ecx + + jnz .L5 + + mov [edi+ecx*4-4],eax + + ; tail + pop ecx + and ecx,BYTE 1 + jz .L7 + mov al,[esi] + mov ah,[esi+1] + mov ebx,eax + mov edx,eax + shr eax,11 + and eax,BYTE 11111b + and ebx,11111100000b + shl edx,11 + add eax,ebx + add eax,edx + mov [edi],al + mov [edi+1],ah + add esi,BYTE 2 + add edi,BYTE 2 + +.L7 + jmp _x86return + + + + + + +_ConvertX86p16_16RGB555: + + ; check short + cmp ecx,BYTE 32 + ja .L3 + + +.L1 ; short loop + mov al,[esi] + mov ah,[esi+1] + mov ebx,eax + shr ebx,1 + and ebx, 0111111111100000b + and eax,BYTE 0000000000011111b + add eax,ebx + mov [edi],al + mov [edi+1],ah + add esi,BYTE 2 + add edi,BYTE 2 + dec ecx + jnz .L1 +.L2 + jmp _x86return + +.L3 ; head + mov eax,edi + and eax,BYTE 11b + jz .L4 + mov al,[esi] + mov ah,[esi+1] + mov ebx,eax + shr ebx,1 + and ebx, 0111111111100000b + and eax,BYTE 0000000000011111b + add eax,ebx + mov [edi],al + mov [edi+1],ah + add esi,BYTE 2 + add edi,BYTE 2 + dec ecx + +.L4 ; save ebp + push ebp + + ; save count + push ecx + + ; unroll four times + shr ecx,2 + + ; point arrays to end + lea esi,[esi+ecx*8] + lea edi,[edi+ecx*8] + + ; negative counter + xor ebp,ebp + sub ebp,ecx + +.L5 mov eax,[esi+ebp*8] ; agi? + mov ecx,[esi+ebp*8+4] + + mov ebx,eax + mov edx,ecx + + and eax,0FFC0FFC0h + and ecx,0FFC0FFC0h + + shr eax,1 + and ebx,001F001Fh + + shr ecx,1 + and edx,001F001Fh + + add eax,ebx + add ecx,edx + + mov [edi+ebp*8],eax + mov [edi+ebp*8+4],ecx + + inc ebp + jnz .L5 + + ; tail + pop ecx +.L6 and ecx,BYTE 11b + jz .L7 + mov al,[esi] + mov ah,[esi+1] + mov ebx,eax + shr ebx,1 + and ebx, 0111111111100000b + and eax,BYTE 0000000000011111b + add eax,ebx + mov [edi],al + mov [edi+1],ah + add esi,BYTE 2 + add edi,BYTE 2 + dec ecx + jmp SHORT .L6 + +.L7 pop ebp + jmp _x86return + + + + + + +_ConvertX86p16_16BGR555: + + ; check short + cmp ecx,BYTE 16 + ja .L3 + + +.L1 ; short loop + mov al,[esi] + mov ah,[esi+1] + mov ebx,eax + mov edx,eax + shr eax,11 + and eax,BYTE 11111b + shr ebx,1 + and ebx,1111100000b + shl edx,10 + and edx,0111110000000000b + add eax,ebx + add eax,edx + mov [edi],al + mov [edi+1],ah + add esi,BYTE 2 + add edi,BYTE 2 + dec ecx + jnz .L1 +.L2 + jmp _x86return + +.L3 ; head + mov eax,edi + and eax,BYTE 11b + jz .L4 + mov al,[esi] + mov ah,[esi+1] + mov ebx,eax + mov edx,eax + shr eax,11 + and eax,BYTE 11111b + shr ebx,1 + and ebx,1111100000b + shl edx,10 + and edx,0111110000000000b + add eax,ebx + add eax,edx + mov [edi],al + mov [edi+1],ah + add esi,BYTE 2 + add edi,BYTE 2 + dec ecx + +.L4 ; save count + push ecx + + ; unroll twice + shr ecx,1 + + ; point arrays to end + lea esi,[esi+ecx*4] + lea edi,[edi+ecx*4] + + ; negative counter + neg ecx + jmp SHORT .L6 + +.L5 mov [edi+ecx*4-4],eax +.L6 mov eax,[esi+ecx*4] + + shr eax,1 + mov ebx,[esi+ecx*4] + + and eax,03E003E0h + mov edx,[esi+ecx*4] + + and ebx,0F800F800h + + shr ebx,11 + and edx,001F001Fh + + shl edx,10 + add eax,ebx + + add eax,edx + inc ecx + + jnz .L5 + + mov [edi+ecx*4-4],eax + + ; tail + pop ecx + and ecx,BYTE 1 + jz .L7 + mov al,[esi] + mov ah,[esi+1] + mov ebx,eax + mov edx,eax + shr eax,11 + and eax,BYTE 11111b + shr ebx,1 + and ebx,1111100000b + shl edx,10 + and edx,0111110000000000b + add eax,ebx + add eax,edx + mov [edi],al + mov [edi+1],ah + add esi,BYTE 2 + add edi,BYTE 2 + +.L7 + jmp _x86return + + + + + + +_ConvertX86p16_8RGB332: + + ; check short + cmp ecx,BYTE 16 + ja .L3 + + +.L1 ; short loop + mov al,[esi+0] + mov ah,[esi+1] + mov ebx,eax + mov edx,eax + and eax,BYTE 11000b ; blue + shr eax,3 + and ebx,11100000000b ; green + shr ebx,6 + and edx,1110000000000000b ; red + shr edx,8 + add eax,ebx + add eax,edx + mov [edi],al + add esi,BYTE 2 + inc edi + dec ecx + jnz .L1 +.L2 + jmp _x86return + +.L3 mov eax,edi + and eax,BYTE 11b + jz .L4 + mov al,[esi+0] + mov ah,[esi+1] + mov ebx,eax + mov edx,eax + and eax,BYTE 11000b ; blue + shr eax,3 + and ebx,11100000000b ; green + shr ebx,6 + and edx,1110000000000000b ; red + shr edx,8 + add eax,ebx + add eax,edx + mov [edi],al + add esi,BYTE 2 + inc edi + dec ecx + jmp SHORT .L3 + +.L4 ; save ebp + push ebp + + ; save count + push ecx + + ; unroll 4 times + shr ecx,2 + + ; prestep + mov dl,[esi+0] + mov bl,[esi+1] + mov dh,[esi+2] + +.L5 shl edx,16 + mov bh,[esi+3] + + shl ebx,16 + mov dl,[esi+4] + + mov dh,[esi+6] + mov bl,[esi+5] + + and edx,00011000000110000001100000011000b + mov bh,[esi+7] + + ror edx,16+3 + mov eax,ebx ; setup eax for reds + + and ebx,00000111000001110000011100000111b + and eax,11100000111000001110000011100000b ; reds + + ror ebx,16-2 + add esi,BYTE 8 + + ror eax,16 + add edi,BYTE 4 + + add eax,ebx + mov bl,[esi+1] ; greens + + add eax,edx + mov dl,[esi+0] ; blues + + mov [edi-4],eax + mov dh,[esi+2] + + dec ecx + jnz .L5 + + ; check tail + pop ecx + and ecx,BYTE 11b + jz .L7 + +.L6 ; tail + mov al,[esi+0] + mov ah,[esi+1] + mov ebx,eax + mov edx,eax + and eax,BYTE 11000b ; blue + shr eax,3 + and ebx,11100000000b ; green + shr ebx,6 + and edx,1110000000000000b ; red + shr edx,8 + add eax,ebx + add eax,edx + mov [edi],al + add esi,BYTE 2 + inc edi + dec ecx + jnz .L6 + +.L7 pop ebp + jmp _x86return + diff --git a/contrib/sdk/sources/SDL-1.2.2/src/hermes/x86p_32.asm b/contrib/sdk/sources/SDL-1.2.2/src/hermes/x86p_32.asm new file mode 100644 index 000000000..648fec4d2 --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/src/hermes/x86p_32.asm @@ -0,0 +1,1043 @@ +; +; x86 format converters for HERMES +; Some routines Copyright (c) 1998 Christian Nentwich (brn@eleet.mcb.at) +; This source code is licensed under the GNU LGPL +; +; Please refer to the file COPYING.LIB contained in the distribution for +; licensing conditions +; +; Most routines are (c) Glenn Fiedler (ptc@gaffer.org), used with permission +; + + +BITS 32 + +GLOBAL _ConvertX86p32_32BGR888 +GLOBAL _ConvertX86p32_32RGBA888 +GLOBAL _ConvertX86p32_32BGRA888 +GLOBAL _ConvertX86p32_24RGB888 +GLOBAL _ConvertX86p32_24BGR888 +GLOBAL _ConvertX86p32_16RGB565 +GLOBAL _ConvertX86p32_16BGR565 +GLOBAL _ConvertX86p32_16RGB555 +GLOBAL _ConvertX86p32_16BGR555 +GLOBAL _ConvertX86p32_8RGB332 + +EXTERN _x86return + +SECTION .text + + +;; _Convert_* +;; Paramters: +;; ESI = source +;; EDI = dest +;; ECX = amount (NOT 0!!! (the _ConvertX86 routine checks for that though)) +;; Destroys: +;; EAX, EBX, EDX + + +_ConvertX86p32_32BGR888: + + ; check short + cmp ecx,BYTE 32 + ja .L3 + +.L1 ; short loop + mov edx,[esi] + bswap edx + ror edx,8 + mov [edi],edx + add esi,BYTE 4 + add edi,BYTE 4 + dec ecx + jnz .L1 +.L2 + jmp _x86return + +.L3 ; save ebp + push ebp + + ; unroll four times + mov ebp,ecx + shr ebp,2 + + ; save count + push ecx + +.L4 mov eax,[esi] + mov ebx,[esi+4] + + bswap eax + + bswap ebx + + ror eax,8 + mov ecx,[esi+8] + + ror ebx,8 + mov edx,[esi+12] + + bswap ecx + + bswap edx + + ror ecx,8 + mov [edi+0],eax + + ror edx,8 + mov [edi+4],ebx + + mov [edi+8],ecx + mov [edi+12],edx + + add esi,BYTE 16 + add edi,BYTE 16 + + dec ebp + jnz .L4 + + ; check tail + pop ecx + and ecx,BYTE 11b + jz .L6 + +.L5 ; tail loop + mov edx,[esi] + bswap edx + ror edx,8 + mov [edi],edx + add esi,BYTE 4 + add edi,BYTE 4 + dec ecx + jnz .L5 + +.L6 pop ebp + jmp _x86return + + + + +_ConvertX86p32_32RGBA888: + + ; check short + cmp ecx,BYTE 32 + ja .L3 + +.L1 ; short loop + mov edx,[esi] + rol edx,8 + mov [edi],edx + add esi,BYTE 4 + add edi,BYTE 4 + dec ecx + jnz .L1 +.L2 + jmp _x86return + +.L3 ; save ebp + push ebp + + ; unroll four times + mov ebp,ecx + shr ebp,2 + + ; save count + push ecx + +.L4 mov eax,[esi] + mov ebx,[esi+4] + + rol eax,8 + mov ecx,[esi+8] + + rol ebx,8 + mov edx,[esi+12] + + rol ecx,8 + mov [edi+0],eax + + rol edx,8 + mov [edi+4],ebx + + mov [edi+8],ecx + mov [edi+12],edx + + add esi,BYTE 16 + add edi,BYTE 16 + + dec ebp + jnz .L4 + + ; check tail + pop ecx + and ecx,BYTE 11b + jz .L6 + +.L5 ; tail loop + mov edx,[esi] + rol edx,8 + mov [edi],edx + add esi,BYTE 4 + add edi,BYTE 4 + dec ecx + jnz .L5 + +.L6 pop ebp + jmp _x86return + + + + +_ConvertX86p32_32BGRA888: + + ; check short + cmp ecx,BYTE 32 + ja .L3 + +.L1 ; short loop + mov edx,[esi] + bswap edx + mov [edi],edx + add esi,BYTE 4 + add edi,BYTE 4 + dec ecx + jnz .L1 +.L2 + jmp _x86return + +.L3 ; save ebp + push ebp + + ; unroll four times + mov ebp,ecx + shr ebp,2 + + ; save count + push ecx + +.L4 mov eax,[esi] + mov ebx,[esi+4] + + mov ecx,[esi+8] + mov edx,[esi+12] + + bswap eax + + bswap ebx + + bswap ecx + + bswap edx + + mov [edi+0],eax + mov [edi+4],ebx + + mov [edi+8],ecx + mov [edi+12],edx + + add esi,BYTE 16 + add edi,BYTE 16 + + dec ebp + jnz .L4 + + ; check tail + pop ecx + and ecx,BYTE 11b + jz .L6 + +.L5 ; tail loop + mov edx,[esi] + bswap edx + mov [edi],edx + add esi,BYTE 4 + add edi,BYTE 4 + dec ecx + jnz .L5 + +.L6 pop ebp + jmp _x86return + + + + +;; 32 bit RGB 888 to 24 BIT RGB 888 + +_ConvertX86p32_24RGB888: + + ; check short + cmp ecx,BYTE 32 + ja .L3 + +.L1 ; short loop + mov al,[esi] + mov bl,[esi+1] + mov dl,[esi+2] + mov [edi],al + mov [edi+1],bl + mov [edi+2],dl + add esi,BYTE 4 + add edi,BYTE 3 + dec ecx + jnz .L1 +.L2 + jmp _x86return + +.L3 ; head + mov edx,edi + and edx,BYTE 11b + jz .L4 + mov al,[esi] + mov bl,[esi+1] + mov dl,[esi+2] + mov [edi],al + mov [edi+1],bl + mov [edi+2],dl + add esi,BYTE 4 + add edi,BYTE 3 + dec ecx + jmp SHORT .L3 + +.L4 ; unroll 4 times + push ebp + mov ebp,ecx + shr ebp,2 + + ; save count + push ecx + +.L5 mov eax,[esi] ; first dword eax = [A][R][G][B] + mov ebx,[esi+4] ; second dword ebx = [a][r][g][b] + + shl eax,8 ; eax = [R][G][B][.] + mov ecx,[esi+12] ; third dword ecx = [a][r][g][b] + + shl ebx,8 ; ebx = [r][g][b][.] + mov al,[esi+4] ; eax = [R][G][B][b] + + ror eax,8 ; eax = [b][R][G][B] (done) + mov bh,[esi+8+1] ; ebx = [r][g][G][.] + + mov [edi],eax + add edi,BYTE 3*4 + + shl ecx,8 ; ecx = [r][g][b][.] + mov bl,[esi+8+0] ; ebx = [r][g][G][B] + + rol ebx,16 ; ebx = [G][B][r][g] (done) + mov cl,[esi+8+2] ; ecx = [r][g][b][R] (done) + + mov [edi+4-3*4],ebx + add esi,BYTE 4*4 + + mov [edi+8-3*4],ecx + dec ebp + + jnz .L5 + + ; check tail + pop ecx + and ecx,BYTE 11b + jz .L7 + +.L6 ; tail loop + mov al,[esi] + mov bl,[esi+1] + mov dl,[esi+2] + mov [edi],al + mov [edi+1],bl + mov [edi+2],dl + add esi,BYTE 4 + add edi,BYTE 3 + dec ecx + jnz .L6 + +.L7 pop ebp + jmp _x86return + + + + +;; 32 bit RGB 888 to 24 bit BGR 888 + +_ConvertX86p32_24BGR888: + + ; check short + cmp ecx,BYTE 32 + ja .L3 + + +.L1 ; short loop + mov dl,[esi] + mov bl,[esi+1] + mov al,[esi+2] + mov [edi],al + mov [edi+1],bl + mov [edi+2],dl + add esi,BYTE 4 + add edi,BYTE 3 + dec ecx + jnz .L1 +.L2 + jmp _x86return + +.L3 ; head + mov edx,edi + and edx,BYTE 11b + jz .L4 + mov dl,[esi] + mov bl,[esi+1] + mov al,[esi+2] + mov [edi],al + mov [edi+1],bl + mov [edi+2],dl + add esi,BYTE 4 + add edi,BYTE 3 + dec ecx + jmp SHORT .L3 + +.L4 ; unroll 4 times + push ebp + mov ebp,ecx + shr ebp,2 + + ; save count + push ecx + +.L5 + mov eax,[esi] ; first dword eax = [A][R][G][B] + mov ebx,[esi+4] ; second dword ebx = [a][r][g][b] + + bswap eax ; eax = [B][G][R][A] + + bswap ebx ; ebx = [b][g][r][a] + + mov al,[esi+4+2] ; eax = [B][G][R][r] + mov bh,[esi+4+4+1] ; ebx = [b][g][G][a] + + ror eax,8 ; eax = [r][B][G][R] (done) + mov bl,[esi+4+4+2] ; ebx = [b][g][G][R] + + ror ebx,16 ; ebx = [G][R][b][g] (done) + mov [edi],eax + + mov [edi+4],ebx + mov ecx,[esi+12] ; third dword ecx = [a][r][g][b] + + bswap ecx ; ecx = [b][g][r][a] + + mov cl,[esi+8] ; ecx = [b][g][r][B] (done) + add esi,BYTE 4*4 + + mov [edi+8],ecx + add edi,BYTE 3*4 + + dec ebp + jnz .L5 + + ; check tail + pop ecx + and ecx,BYTE 11b + jz .L7 + +.L6 ; tail loop + mov dl,[esi] + mov bl,[esi+1] + mov al,[esi+2] + mov [edi],al + mov [edi+1],bl + mov [edi+2],dl + add esi,BYTE 4 + add edi,BYTE 3 + dec ecx + jnz .L6 + +.L7 + pop ebp + jmp _x86return + + + + +;; 32 bit RGB 888 to 16 BIT RGB 565 + +_ConvertX86p32_16RGB565: + ; check short + cmp ecx,BYTE 16 + ja .L3 + +.L1 ; short loop + mov bl,[esi+0] ; blue + mov al,[esi+1] ; green + mov ah,[esi+2] ; red + shr ah,3 + and al,11111100b + shl eax,3 + shr bl,3 + add al,bl + mov [edi+0],al + mov [edi+1],ah + add esi,BYTE 4 + add edi,BYTE 2 + dec ecx + jnz .L1 + +.L2: ; End of short loop + jmp _x86return + + +.L3 ; head + mov ebx,edi + and ebx,BYTE 11b + jz .L4 + + mov bl,[esi+0] ; blue + mov al,[esi+1] ; green + mov ah,[esi+2] ; red + shr ah,3 + and al,11111100b + shl eax,3 + shr bl,3 + add al,bl + mov [edi+0],al + mov [edi+1],ah + add esi,BYTE 4 + add edi,BYTE 2 + dec ecx + +.L4: + ; save count + push ecx + + ; unroll twice + shr ecx,1 + + ; point arrays to end + lea esi,[esi+ecx*8] + lea edi,[edi+ecx*4] + + ; negative counter + neg ecx + jmp SHORT .L6 + +.L5: + mov [edi+ecx*4-4],eax +.L6: + mov eax,[esi+ecx*8] + + shr ah,2 + mov ebx,[esi+ecx*8+4] + + shr eax,3 + mov edx,[esi+ecx*8+4] + + shr bh,2 + mov dl,[esi+ecx*8+2] + + shl ebx,13 + and eax,000007FFh + + shl edx,8 + and ebx,07FF0000h + + and edx,0F800F800h + add eax,ebx + + add eax,edx + inc ecx + + jnz .L5 + + mov [edi+ecx*4-4],eax + + ; tail + pop ecx + test cl,1 + jz .L7 + + mov bl,[esi+0] ; blue + mov al,[esi+1] ; green + mov ah,[esi+2] ; red + shr ah,3 + and al,11111100b + shl eax,3 + shr bl,3 + add al,bl + mov [edi+0],al + mov [edi+1],ah + add esi,BYTE 4 + add edi,BYTE 2 + +.L7: + jmp _x86return + + + + +;; 32 bit RGB 888 to 16 BIT BGR 565 + +_ConvertX86p32_16BGR565: + + ; check short + cmp ecx,BYTE 16 + ja .L3 + +.L1 ; short loop + mov ah,[esi+0] ; blue + mov al,[esi+1] ; green + mov bl,[esi+2] ; red + shr ah,3 + and al,11111100b + shl eax,3 + shr bl,3 + add al,bl + mov [edi+0],al + mov [edi+1],ah + add esi,BYTE 4 + add edi,BYTE 2 + dec ecx + jnz .L1 +.L2 + jmp _x86return + +.L3 ; head + mov ebx,edi + and ebx,BYTE 11b + jz .L4 + mov ah,[esi+0] ; blue + mov al,[esi+1] ; green + mov bl,[esi+2] ; red + shr ah,3 + and al,11111100b + shl eax,3 + shr bl,3 + add al,bl + mov [edi+0],al + mov [edi+1],ah + add esi,BYTE 4 + add edi,BYTE 2 + dec ecx + +.L4 ; save count + push ecx + + ; unroll twice + shr ecx,1 + + ; point arrays to end + lea esi,[esi+ecx*8] + lea edi,[edi+ecx*4] + + ; negative count + neg ecx + jmp SHORT .L6 + +.L5 + mov [edi+ecx*4-4],eax +.L6 + mov edx,[esi+ecx*8+4] + + mov bh,[esi+ecx*8+4] + mov ah,[esi+ecx*8] + + shr bh,3 + mov al,[esi+ecx*8+1] + + shr ah,3 + mov bl,[esi+ecx*8+5] + + shl eax,3 + mov dl,[esi+ecx*8+2] + + shl ebx,19 + and eax,0000FFE0h + + shr edx,3 + and ebx,0FFE00000h + + and edx,001F001Fh + add eax,ebx + + add eax,edx + inc ecx + + jnz .L5 + + mov [edi+ecx*4-4],eax + + ; tail + pop ecx + and ecx,BYTE 1 + jz .L7 + mov ah,[esi+0] ; blue + mov al,[esi+1] ; green + mov bl,[esi+2] ; red + shr ah,3 + and al,11111100b + shl eax,3 + shr bl,3 + add al,bl + mov [edi+0],al + mov [edi+1],ah + add esi,BYTE 4 + add edi,BYTE 2 + +.L7 + jmp _x86return + + + + +;; 32 BIT RGB TO 16 BIT RGB 555 + +_ConvertX86p32_16RGB555: + + ; check short + cmp ecx,BYTE 16 + ja .L3 + +.L1 ; short loop + mov bl,[esi+0] ; blue + mov al,[esi+1] ; green + mov ah,[esi+2] ; red + shr ah,3 + and al,11111000b + shl eax,2 + shr bl,3 + add al,bl + mov [edi+0],al + mov [edi+1],ah + add esi,BYTE 4 + add edi,BYTE 2 + dec ecx + jnz .L1 +.L2 + jmp _x86return + +.L3 ; head + mov ebx,edi + and ebx,BYTE 11b + jz .L4 + mov bl,[esi+0] ; blue + mov al,[esi+1] ; green + mov ah,[esi+2] ; red + shr ah,3 + and al,11111000b + shl eax,2 + shr bl,3 + add al,bl + mov [edi+0],al + mov [edi+1],ah + add esi,BYTE 4 + add edi,BYTE 2 + dec ecx + +.L4 ; save count + push ecx + + ; unroll twice + shr ecx,1 + + ; point arrays to end + lea esi,[esi+ecx*8] + lea edi,[edi+ecx*4] + + ; negative counter + neg ecx + jmp SHORT .L6 + +.L5 + mov [edi+ecx*4-4],eax +.L6 + mov eax,[esi+ecx*8] + + shr ah,3 + mov ebx,[esi+ecx*8+4] + + shr eax,3 + mov edx,[esi+ecx*8+4] + + shr bh,3 + mov dl,[esi+ecx*8+2] + + shl ebx,13 + and eax,000007FFh + + shl edx,7 + and ebx,07FF0000h + + and edx,07C007C00h + add eax,ebx + + add eax,edx + inc ecx + + jnz .L5 + + mov [edi+ecx*4-4],eax + + ; tail + pop ecx + and ecx,BYTE 1 + jz .L7 + mov bl,[esi+0] ; blue + mov al,[esi+1] ; green + mov ah,[esi+2] ; red + shr ah,3 + and al,11111000b + shl eax,2 + shr bl,3 + add al,bl + mov [edi+0],al + mov [edi+1],ah + add esi,BYTE 4 + add edi,BYTE 2 + +.L7 + jmp _x86return + + + + +;; 32 BIT RGB TO 16 BIT BGR 555 + +_ConvertX86p32_16BGR555: + + ; check short + cmp ecx,BYTE 16 + ja .L3 + + +.L1 ; short loop + mov ah,[esi+0] ; blue + mov al,[esi+1] ; green + mov bl,[esi+2] ; red + shr ah,3 + and al,11111000b + shl eax,2 + shr bl,3 + add al,bl + mov [edi+0],al + mov [edi+1],ah + add esi,BYTE 4 + add edi,BYTE 2 + dec ecx + jnz .L1 +.L2 + jmp _x86return + +.L3 ; head + mov ebx,edi + and ebx,BYTE 11b + jz .L4 + mov ah,[esi+0] ; blue + mov al,[esi+1] ; green + mov bl,[esi+2] ; red + shr ah,3 + and al,11111000b + shl eax,2 + shr bl,3 + add al,bl + mov [edi+0],al + mov [edi+1],ah + add esi,BYTE 4 + add edi,BYTE 2 + dec ecx + +.L4 ; save count + push ecx + + ; unroll twice + shr ecx,1 + + ; point arrays to end + lea esi,[esi+ecx*8] + lea edi,[edi+ecx*4] + + ; negative counter + neg ecx + jmp SHORT .L6 + +.L5 + mov [edi+ecx*4-4],eax +.L6 + mov edx,[esi+ecx*8+4] + + mov bh,[esi+ecx*8+4] + mov ah,[esi+ecx*8] + + shr bh,3 + mov al,[esi+ecx*8+1] + + shr ah,3 + mov bl,[esi+ecx*8+5] + + shl eax,2 + mov dl,[esi+ecx*8+2] + + shl ebx,18 + and eax,00007FE0h + + shr edx,3 + and ebx,07FE00000h + + and edx,001F001Fh + add eax,ebx + + add eax,edx + inc ecx + + jnz .L5 + + mov [edi+ecx*4-4],eax + + ; tail + pop ecx + and ecx,BYTE 1 + jz .L7 + mov ah,[esi+0] ; blue + mov al,[esi+1] ; green + mov bl,[esi+2] ; red + shr ah,3 + and al,11111000b + shl eax,2 + shr bl,3 + add al,bl + mov [edi+0],al + mov [edi+1],ah + add esi,BYTE 4 + add edi,BYTE 2 + +.L7 + jmp _x86return + + + + + +;; FROM 32 BIT RGB to 8 BIT RGB (rrrgggbbb) +;; This routine writes FOUR pixels at once (dword) and then, if they exist +;; the trailing three pixels +_ConvertX86p32_8RGB332: + + +.L_ALIGNED + push ecx + + shr ecx,2 ; We will draw 4 pixels at once + jnz .L1 + + jmp .L2 ; short jump out of range :( + +.L1: + mov eax,[esi] ; first pair of pixels + mov edx,[esi+4] + + shr dl,6 + mov ebx,eax + + shr al,6 + and ah,0e0h + + shr ebx,16 + and dh,0e0h + + shr ah,3 + and bl,0e0h + + shr dh,3 + + or al,bl + + mov ebx,edx + or al,ah + + shr ebx,16 + or dl,dh + + and bl,0e0h + + or dl,bl + + mov ah,dl + + + + mov ebx,[esi+8] ; second pair of pixels + + mov edx,ebx + and bh,0e0h + + shr bl,6 + and edx,0e00000h + + shr edx,16 + + shr bh,3 + + ror eax,16 + or bl,dl + + mov edx,[esi+12] + or bl,bh + + mov al,bl + + mov ebx,edx + and dh,0e0h + + shr dl,6 + and ebx,0e00000h + + shr dh,3 + mov ah,dl + + shr ebx,16 + or ah,dh + + or ah,bl + + rol eax,16 + add esi,BYTE 16 + + mov [edi],eax + add edi,BYTE 4 + + dec ecx + jz .L2 ; L1 out of range for short jump :( + + jmp .L1 +.L2: + + pop ecx + and ecx,BYTE 3 ; mask out number of pixels to draw + + jz .L4 ; Nothing to do anymore + +.L3: + mov eax,[esi] ; single pixel conversion for trailing pixels + + mov ebx,eax + + shr al,6 + and ah,0e0h + + shr ebx,16 + + shr ah,3 + and bl,0e0h + + or al,ah + or al,bl + + mov [edi],al + + inc edi + add esi,BYTE 4 + + dec ecx + jnz .L3 + +.L4: + jmp _x86return diff --git a/contrib/sdk/sources/SDL-1.2.2/src/joystick/SDL_joystick_c.h b/contrib/sdk/sources/SDL-1.2.2/src/joystick/SDL_joystick_c.h new file mode 100644 index 000000000..18301902b --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/src/joystick/SDL_joystick_c.h @@ -0,0 +1,42 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997, 1998, 1999, 2000, 2001 Sam Lantinga + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the Free + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + Sam Lantinga + slouken@devolution.com +*/ + +#ifdef SAVE_RCSID +static char rcsid = + "@(#) $Id: SDL_joystick_c.h,v 1.2 2001/04/26 16:50:17 hercules Exp $"; +#endif + +/* Useful functions and variables from SDL_joystick.c */ +#include "SDL_joystick.h" + +/* The number of available joysticks on the system */ +extern Uint8 SDL_numjoysticks; + +/* Internal event queueing functions */ +extern int SDL_PrivateJoystickAxis(SDL_Joystick *joystick, + Uint8 axis, Sint16 value); +extern int SDL_PrivateJoystickBall(SDL_Joystick *joystick, + Uint8 ball, Sint16 xrel, Sint16 yrel); +extern int SDL_PrivateJoystickHat(SDL_Joystick *joystick, + Uint8 hat, Uint8 value); +extern int SDL_PrivateJoystickButton(SDL_Joystick *joystick, + Uint8 button, Uint8 state); diff --git a/contrib/sdk/sources/SDL-1.2.2/src/joystick/SDL_sysjoystick.h b/contrib/sdk/sources/SDL-1.2.2/src/joystick/SDL_sysjoystick.h new file mode 100644 index 000000000..961a85025 --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/src/joystick/SDL_sysjoystick.h @@ -0,0 +1,86 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997, 1998, 1999, 2000, 2001 Sam Lantinga + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the Free + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + Sam Lantinga + slouken@devolution.com +*/ + +#ifdef SAVE_RCSID +static char rcsid = + "@(#) $Id: SDL_sysjoystick.h,v 1.2 2001/04/26 16:50:17 hercules Exp $"; +#endif + +/* This is the system specific header for the SDL joystick API */ + +#include "SDL_joystick.h" + +/* The SDL joystick structure */ +struct _SDL_Joystick { + Uint8 index; /* Device index */ + const char *name; /* Joystick name - system dependent */ + + int naxes; /* Number of axis controls on the joystick */ + Sint16 *axes; /* Current axis states */ + + int nhats; /* Number of hats on the joystick */ + Uint8 *hats; /* Current hat states */ + + int nballs; /* Number of trackballs on the joystick */ + struct balldelta { + int dx; + int dy; + } *balls; /* Current ball motion deltas */ + + int nbuttons; /* Number of buttons on the joystick */ + Uint8 *buttons; /* Current button states */ + + struct joystick_hwdata *hwdata; /* Driver dependent information */ + + int ref_count; /* Reference count for multiple opens */ +}; + +/* Function to scan the system for joysticks. + * Joystick 0 should be the system default joystick. + * This function should return the number of available joysticks, or -1 + * on an unrecoverable fatal error. + */ +extern int SDL_SYS_JoystickInit(void); + +/* Function to get the device-dependent name of a joystick */ +extern const char *SDL_SYS_JoystickName(int index); + +/* Function to open a joystick for use. + The joystick to open is specified by the index field of the joystick. + This should fill the nbuttons and naxes fields of the joystick structure. + It returns 0, or -1 if there is an error. + */ +extern int SDL_SYS_JoystickOpen(SDL_Joystick *joystick); + +/* Function to update the state of a joystick - called as a device poll. + * This function shouldn't update the joystick structure directly, + * but instead should call SDL_PrivateJoystick*() to deliver events + * and update joystick device state. + */ +extern void SDL_SYS_JoystickUpdate(SDL_Joystick *joystick); + +/* Function to close a joystick after use */ +extern void SDL_SYS_JoystickClose(SDL_Joystick *joystick); + +/* Function to perform any system-specific joystick related cleanup */ +extern void SDL_SYS_JoystickQuit(void); + diff --git a/contrib/sdk/sources/SDL-1.2.2/src/thread/SDL_syscond.c b/contrib/sdk/sources/SDL-1.2.2/src/thread/SDL_syscond.c new file mode 100644 index 000000000..e030c734f --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/src/thread/SDL_syscond.c @@ -0,0 +1,222 @@ +/* WARNING: This file was automatically generated! + * Original: ./src/thread/generic/SDL_syscond.c + */ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997, 1998, 1999, 2000, 2001 Sam Lantinga + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the Free + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + Sam Lantinga + slouken@devolution.com +*/ + + +/* An implementation of condition variables using semaphores and mutexes */ +/* + This implementation borrows heavily from the BeOS condition variable + implementation, written by Christopher Tate and Owen Smith. Thanks! + */ + +#include +#include + +#include "SDL_error.h" +#include "SDL_thread.h" + +struct SDL_cond +{ + SDL_mutex *lock; + int waiting; + int signals; + SDL_sem *wait_sem; + SDL_sem *wait_done; +}; + +/* Create a condition variable */ +SDL_cond * SDL_CreateCond(void) +{ + SDL_cond *cond; + + cond = (SDL_cond *) malloc(sizeof(SDL_cond)); + if ( cond ) { + cond->lock = SDL_CreateMutex(); + cond->wait_sem = SDL_CreateSemaphore(0); + cond->wait_done = SDL_CreateSemaphore(0); + cond->waiting = cond->signals = 0; + if ( ! cond->lock || ! cond->wait_sem || ! cond->wait_done ) { + SDL_DestroyCond(cond); + cond = NULL; + } + } else { + SDL_OutOfMemory(); + } + return(cond); +} + +/* Destroy a condition variable */ +void SDL_DestroyCond(SDL_cond *cond) +{ + if ( cond ) { + if ( cond->wait_sem ) { + SDL_DestroySemaphore(cond->wait_sem); + } + if ( cond->wait_done ) { + SDL_DestroySemaphore(cond->wait_done); + } + if ( cond->lock ) { + SDL_DestroyMutex(cond->lock); + } + free(cond); + } +} + +/* Restart one of the threads that are waiting on the condition variable */ +int SDL_CondSignal(SDL_cond *cond) +{ + if ( ! cond ) { + SDL_SetError("Passed a NULL condition variable"); + return -1; + } + + /* If there are waiting threads not already signalled, then + signal the condition and wait for the thread to respond. + */ + SDL_LockMutex(cond->lock); + if ( cond->waiting > cond->signals ) { + ++cond->signals; + SDL_SemPost(cond->wait_sem); + SDL_UnlockMutex(cond->lock); + SDL_SemWait(cond->wait_done); + } else { + SDL_UnlockMutex(cond->lock); + } + + return 0; +} + +/* Restart all threads that are waiting on the condition variable */ +int SDL_CondBroadcast(SDL_cond *cond) +{ + if ( ! cond ) { + SDL_SetError("Passed a NULL condition variable"); + return -1; + } + + /* If there are waiting threads not already signalled, then + signal the condition and wait for the thread to respond. + */ + SDL_LockMutex(cond->lock); + if ( cond->waiting > cond->signals ) { + int i, num_waiting; + + num_waiting = (cond->waiting - cond->signals); + cond->signals = cond->waiting; + for ( i=0; iwait_sem); + } + /* Now all released threads are blocked here, waiting for us. + Collect them all (and win fabulous prizes!) :-) + */ + SDL_UnlockMutex(cond->lock); + for ( i=0; iwait_done); + } + } else { + SDL_UnlockMutex(cond->lock); + } + + return 0; +} + +/* Wait on the condition variable for at most 'ms' milliseconds. + The mutex must be locked before entering this function! + The mutex is unlocked during the wait, and locked again after the wait. + +Typical use: + +Thread A: + SDL_LockMutex(lock); + while ( ! condition ) { + SDL_CondWait(cond); + } + SDL_UnlockMutex(lock); + +Thread B: + SDL_LockMutex(lock); + ... + condition = true; + ... + SDL_UnlockMutex(lock); + */ +int SDL_CondWaitTimeout(SDL_cond *cond, SDL_mutex *mutex, Uint32 ms) +{ + int retval; + + if ( ! cond ) { + SDL_SetError("Passed a NULL condition variable"); + return -1; + } + + /* Obtain the protection mutex, and increment the number of waiters. + This allows the signal mechanism to only perform a signal if there + are waiting threads. + */ + SDL_LockMutex(cond->lock); + ++cond->waiting; + SDL_UnlockMutex(cond->lock); + + /* Unlock the mutex, as is required by condition variable semantics */ + SDL_UnlockMutex(mutex); + + /* Wait for a signal */ + if ( ms == SDL_MUTEX_MAXWAIT ) { + retval = SDL_SemWait(cond->wait_sem); + } else { + retval = SDL_SemWaitTimeout(cond->wait_sem, ms); + } + + /* Let the signaler know we have completed the wait, otherwise + the signaler can race ahead and get the condition semaphore + if we are stopped between the mutex unlock and semaphore wait, + giving a deadlock. See the following URL for details: + http://www-classic.be.com/aboutbe/benewsletter/volume_III/Issue40.html + */ + SDL_LockMutex(cond->lock); + if ( cond->signals > 0 ) { + /* If we timed out, we need to eat a condition signal */ + if ( retval > 0 ) { + SDL_SemWait(cond->wait_sem); + } + /* We always notify the signal thread that we are done */ + SDL_SemPost(cond->wait_done); + + /* Signal handshake complete */ + --cond->signals; + } + --cond->waiting; + SDL_UnlockMutex(cond->lock); + + /* Lock the mutex, as is required by condition variable semantics */ + SDL_LockMutex(mutex); + + return retval; +} + +/* Wait on the condition variable forever */ +int SDL_CondWait(SDL_cond *cond, SDL_mutex *mutex) +{ + return SDL_CondWaitTimeout(cond, mutex, SDL_MUTEX_MAXWAIT); +} diff --git a/contrib/sdk/sources/SDL-1.2.2/src/thread/SDL_syscond_c.h b/contrib/sdk/sources/SDL-1.2.2/src/thread/SDL_syscond_c.h new file mode 100644 index 000000000..fc4c524e4 --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/src/thread/SDL_syscond_c.h @@ -0,0 +1,25 @@ +/* WARNING: This file was automatically generated! + * Original: ./src/thread/generic/SDL_syscond_c.h + */ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997, 1998, 1999, 2000, 2001 Sam Lantinga + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the Free + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + Sam Lantinga + slouken@devolution.com +*/ + diff --git a/contrib/sdk/sources/SDL-1.2.2/src/thread/SDL_sysmutex.c b/contrib/sdk/sources/SDL-1.2.2/src/thread/SDL_sysmutex.c new file mode 100644 index 000000000..325ada81c --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/src/thread/SDL_sysmutex.c @@ -0,0 +1,136 @@ +/* WARNING: This file was automatically generated! + * Original: ./src/thread/generic/SDL_sysmutex.c + */ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997, 1998, 1999, 2000, 2001 Sam Lantinga + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the Free + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + Sam Lantinga + slouken@devolution.com +*/ + + +/* An implementation of mutexes using semaphores */ + +#include +#include + +#include "SDL_error.h" +#include "SDL_thread.h" +#include "SDL_systhread_c.h" + + +struct SDL_mutex { + int recursive; + Uint32 owner; + SDL_sem *sem; +}; + +/* Create a mutex */ +SDL_mutex *SDL_CreateMutex(void) +{ + SDL_mutex *mutex; + + /* Allocate mutex memory */ + mutex = (SDL_mutex *)malloc(sizeof(*mutex)); + if ( mutex ) { + /* Create the mutex semaphore, with initial value 1 */ + mutex->sem = SDL_CreateSemaphore(1); + mutex->recursive = 0; + mutex->owner = 0; + if ( ! mutex->sem ) { + free(mutex); + mutex = NULL; + } + } else { + SDL_OutOfMemory(); + } + return mutex; +} + +/* Free the mutex */ +void SDL_DestroyMutex(SDL_mutex *mutex) +{ + if ( mutex ) { + if ( mutex->sem ) { + SDL_DestroySemaphore(mutex->sem); + } + free(mutex); + } +} + +/* Lock the semaphore */ +int SDL_mutexP(SDL_mutex *mutex) +{ +#ifdef DISABLE_THREADS + return 0; +#else + Uint32 this_thread; + + if ( mutex == NULL ) { + SDL_SetError("Passed a NULL mutex"); + return -1; + } + + this_thread = SDL_ThreadID(); + if ( mutex->owner == this_thread ) { + ++mutex->recursive; + } else { + /* The order of operations is important. + We set the locking thread id after we obtain the lock + so unlocks from other threads will fail. + */ + SDL_SemWait(mutex->sem); + mutex->owner = this_thread; + mutex->recursive = 0; + } + + return 0; +#endif /* DISABLE_THREADS */ +} + +/* Unlock the mutex */ +int SDL_mutexV(SDL_mutex *mutex) +{ +#ifdef DISABLE_THREADS + return 0; +#else + if ( mutex == NULL ) { + SDL_SetError("Passed a NULL mutex"); + return -1; + } + + /* If we don't own the mutex, we can't unlock it */ + if ( SDL_ThreadID() != mutex->owner ) { + SDL_SetError("mutex not owned by this thread"); + return -1; + } + + if ( mutex->recursive ) { + --mutex->recursive; + } else { + /* The order of operations is important. + First reset the owner so another thread doesn't lock + the mutex and set the ownership before we reset it, + then release the lock semaphore. + */ + mutex->owner = 0; + SDL_SemPost(mutex->sem); + } + return 0; +#endif /* DISABLE_THREADS */ +} diff --git a/contrib/sdk/sources/SDL-1.2.2/src/thread/SDL_sysmutex_c.h b/contrib/sdk/sources/SDL-1.2.2/src/thread/SDL_sysmutex_c.h new file mode 100644 index 000000000..9a236b336 --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/src/thread/SDL_sysmutex_c.h @@ -0,0 +1,25 @@ +/* WARNING: This file was automatically generated! + * Original: ./src/thread/generic/SDL_sysmutex_c.h + */ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997, 1998, 1999, 2000, 2001 Sam Lantinga + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the Free + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + Sam Lantinga + slouken@devolution.com +*/ + diff --git a/contrib/sdk/sources/SDL-1.2.2/src/thread/SDL_syssem.c b/contrib/sdk/sources/SDL-1.2.2/src/thread/SDL_syssem.c new file mode 100644 index 000000000..4c959c23a --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/src/thread/SDL_syssem.c @@ -0,0 +1,213 @@ +/* WARNING: This file was automatically generated! + * Original: ./src/thread/generic/SDL_syssem.c + */ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997, 1998, 1999, 2000, 2001 Sam Lantinga + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the Free + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + Sam Lantinga + slouken@devolution.com +*/ + + +/* An implementation of semaphores using mutexes and condition variables */ + +#include + +#include "SDL_error.h" +#include "SDL_timer.h" +#include "SDL_thread.h" +#include "SDL_systhread_c.h" + + +#ifdef DISABLE_THREADS + +SDL_sem *SDL_CreateSemaphore(Uint32 initial_value) +{ + SDL_SetError("SDL not configured with thread support"); + return (SDL_sem *)0; +} + +void SDL_DestroySemaphore(SDL_sem *sem) +{ + return; +} + +int SDL_SemTryWait(SDL_sem *sem) +{ + SDL_SetError("SDL not configured with thread support"); + return -1; +} + +int SDL_SemWaitTimeout(SDL_sem *sem, Uint32 timeout) +{ + SDL_SetError("SDL not configured with thread support"); + return -1; +} + +int SDL_SemWait(SDL_sem *sem) +{ + SDL_SetError("SDL not configured with thread support"); + return -1; +} + +Uint32 SDL_SemValue(SDL_sem *sem) +{ + return 0; +} + +int SDL_SemPost(SDL_sem *sem) +{ + SDL_SetError("SDL not configured with thread support"); + return -1; +} + +#else + +struct SDL_semaphore +{ + Uint32 count; + Uint32 waiters_count; + SDL_mutex *count_lock; + SDL_cond *count_nonzero; +}; + +SDL_sem *SDL_CreateSemaphore(Uint32 initial_value) +{ + SDL_sem *sem; + + sem = (SDL_sem *)malloc(sizeof(*sem)); + if ( ! sem ) { + SDL_OutOfMemory(); + return(0); + } + sem->count = initial_value; + sem->waiters_count = 0; + + sem->count_lock = SDL_CreateMutex(); + sem->count_nonzero = SDL_CreateCond(); + if ( ! sem->count_lock || ! sem->count_nonzero ) { + SDL_DestroySemaphore(sem); + return(0); + } + + return(sem); +} + +/* WARNING: + You cannot call this function when another thread is using the semaphore. +*/ +void SDL_DestroySemaphore(SDL_sem *sem) +{ + if ( sem ) { + sem->count = 0xFFFFFFFF; + while ( sem->waiters_count > 0) { + SDL_CondSignal(sem->count_nonzero); + SDL_Delay(10); + } + SDL_DestroyCond(sem->count_nonzero); + SDL_mutexP(sem->count_lock); + SDL_mutexV(sem->count_lock); + SDL_DestroyMutex(sem->count_lock); + free(sem); + } +} + +int SDL_SemTryWait(SDL_sem *sem) +{ + int retval; + + if ( ! sem ) { + SDL_SetError("Passed a NULL semaphore"); + return -1; + } + + retval = SDL_MUTEX_TIMEDOUT; + SDL_LockMutex(sem->count_lock); + if ( sem->count > 0 ) { + --sem->count; + retval = 0; + } + SDL_UnlockMutex(sem->count_lock); + + return retval; +} + +int SDL_SemWaitTimeout(SDL_sem *sem, Uint32 timeout) +{ + int retval; + + if ( ! sem ) { + SDL_SetError("Passed a NULL semaphore"); + return -1; + } + + /* A timeout of 0 is an easy case */ + if ( timeout == 0 ) { + return SDL_SemTryWait(sem); + } + + SDL_LockMutex(sem->count_lock); + ++sem->waiters_count; + retval = 0; + while ( (sem->count == 0) && (retval != SDL_MUTEX_TIMEDOUT) ) { + retval = SDL_CondWaitTimeout(sem->count_nonzero, + sem->count_lock, timeout); + } + --sem->waiters_count; + --sem->count; + SDL_UnlockMutex(sem->count_lock); + + return retval; +} + +int SDL_SemWait(SDL_sem *sem) +{ + return SDL_SemWaitTimeout(sem, SDL_MUTEX_MAXWAIT); +} + +Uint32 SDL_SemValue(SDL_sem *sem) +{ + Uint32 value; + + value = 0; + if ( sem ) { + SDL_LockMutex(sem->count_lock); + value = sem->count; + SDL_UnlockMutex(sem->count_lock); + } + return value; +} + +int SDL_SemPost(SDL_sem *sem) +{ + if ( ! sem ) { + SDL_SetError("Passed a NULL semaphore"); + return -1; + } + + SDL_LockMutex(sem->count_lock); + if ( sem->waiters_count > 0 ) { + SDL_CondSignal(sem->count_nonzero); + } + ++sem->count; + SDL_UnlockMutex(sem->count_lock); + + return 0; +} + +#endif /* DISABLE_THREADS */ diff --git a/contrib/sdk/sources/SDL-1.2.2/src/thread/SDL_syssem_c.h b/contrib/sdk/sources/SDL-1.2.2/src/thread/SDL_syssem_c.h new file mode 100644 index 000000000..8d24a0d84 --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/src/thread/SDL_syssem_c.h @@ -0,0 +1,25 @@ +/* WARNING: This file was automatically generated! + * Original: ./src/thread/generic/SDL_syssem_c.h + */ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997, 1998, 1999, 2000, 2001 Sam Lantinga + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the Free + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + Sam Lantinga + slouken@devolution.com +*/ + diff --git a/contrib/sdk/sources/SDL-1.2.2/src/thread/SDL_systhread.c b/contrib/sdk/sources/SDL-1.2.2/src/thread/SDL_systhread.c new file mode 100644 index 000000000..afbcc3066 --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/src/thread/SDL_systhread.c @@ -0,0 +1,58 @@ +/* WARNING: This file was automatically generated! + * Original: ./src/thread/generic/SDL_systhread.c + */ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997, 1998, 1999, 2000, 2001 Sam Lantinga + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the Free + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + Sam Lantinga + slouken@devolution.com +*/ + + +/* Thread management routines for SDL */ + +#include "SDL_error.h" +#include "SDL_thread.h" +#include "SDL_systhread.h" + +int SDL_SYS_CreateThread(SDL_Thread *thread, void *args) +{ + SDL_SetError("Threads are not supported on this platform"); + return(-1); +} + +void SDL_SYS_SetupThread(void) +{ + return; +} + +Uint32 SDL_ThreadID(void) +{ + return(0); +} + +void SDL_SYS_WaitThread(SDL_Thread *thread) +{ + return; +} + +void SDL_SYS_KillThread(SDL_Thread *thread) +{ + return; +} + diff --git a/contrib/sdk/sources/SDL-1.2.2/src/thread/SDL_systhread.h b/contrib/sdk/sources/SDL-1.2.2/src/thread/SDL_systhread.h new file mode 100644 index 000000000..5d66f21f8 --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/src/thread/SDL_systhread.h @@ -0,0 +1,48 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997, 1998, 1999, 2000, 2001 Sam Lantinga + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the Free + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + Sam Lantinga + slouken@devolution.com +*/ + +#ifdef SAVE_RCSID +static char rcsid = + "@(#) $Id: SDL_systhread.h,v 1.2 2001/04/26 16:50:17 hercules Exp $"; +#endif + +/* These are functions that need to be implemented by a port of SDL */ + +#include "SDL_thread_c.h" + +/* This function creates a thread, passing args to SDL_RunThread(), + saves a system-dependent thread id in thread->id, and returns 0 + on success. +*/ +extern int SDL_SYS_CreateThread(SDL_Thread *thread, void *args); + +/* This function does any necessary setup in the child thread */ +extern void SDL_SYS_SetupThread(void); + +/* This function waits for the thread to finish and frees any data + allocated by SDL_SYS_CreateThread() + */ +extern void SDL_SYS_WaitThread(SDL_Thread *thread); + +/* This function kills the thread and returns */ +extern void SDL_SYS_KillThread(SDL_Thread *thread); + diff --git a/contrib/sdk/sources/SDL-1.2.2/src/thread/SDL_systhread_c.h b/contrib/sdk/sources/SDL-1.2.2/src/thread/SDL_systhread_c.h new file mode 100644 index 000000000..6adbb6057 --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/src/thread/SDL_systhread_c.h @@ -0,0 +1,29 @@ +/* WARNING: This file was automatically generated! + * Original: ./src/thread/generic/SDL_systhread_c.h + */ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997, 1998, 1999, 2000, 2001 Sam Lantinga + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the Free + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + Sam Lantinga + slouken@devolution.com +*/ + +/* Stub until we implement threads on this platform */ +typedef int SYS_ThreadHandle; + +#define DISABLE_THREADS diff --git a/contrib/sdk/sources/SDL-1.2.2/src/thread/SDL_thread.c b/contrib/sdk/sources/SDL-1.2.2/src/thread/SDL_thread.c new file mode 100644 index 000000000..1cb25ce0a --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/src/thread/SDL_thread.c @@ -0,0 +1,296 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997, 1998, 1999, 2000, 2001 Sam Lantinga + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the Free + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + Sam Lantinga + slouken@devolution.com +*/ + + +/* System independent thread management routines for SDL */ + +#include +#include +#include + +#include "SDL_error.h" +#include "SDL_mutex.h" +#include "SDL_thread.h" +#include "SDL_thread_c.h" +#include "SDL_systhread.h" + +#define ARRAY_CHUNKSIZE 32 +/* The array of threads currently active in the application + (except the main thread) + The manipulation of an array here is safer than using a linked list. +*/ +static int SDL_maxthreads = 0; +static int SDL_numthreads = 0; +static SDL_Thread **SDL_Threads = NULL; +static SDL_mutex *thread_lock = NULL; +int _creating_thread_lock = 0; + +int SDL_ThreadsInit(void) +{ + int retval; + + retval = 0; + /* Set the thread lock creation flag so that we can reuse an + existing lock on the system - since this mutex never gets + destroyed (see SDL_ThreadsQuit()), we want to reuse it. + */ + _creating_thread_lock = 1; + thread_lock = SDL_CreateMutex(); + _creating_thread_lock = 0; + if ( thread_lock == NULL ) { + retval = -1; + } + return(retval); +} + +/* This should never be called... + If this is called by SDL_Quit(), we don't know whether or not we should + clean up threads here. If any threads are still running after this call, + they will no longer have access to any per-thread data. + */ +void SDL_ThreadsQuit() +{ + SDL_mutex *mutex; + + mutex = thread_lock; + thread_lock = NULL; + if ( mutex != NULL ) { + SDL_DestroyMutex(mutex); + } +} + +/* Routines for manipulating the thread list */ +static void SDL_AddThread(SDL_Thread *thread) +{ + SDL_Thread **threads; + + /* WARNING: + If the very first threads are created simultaneously, then + there could be a race condition causing memory corruption. + In practice, this isn't a problem because by definition there + is only one thread running the first time this is called. + */ + if ( thread_lock == NULL ) { + if ( SDL_ThreadsInit() < 0 ) { + return; + } + } + SDL_mutexP(thread_lock); + + /* Expand the list of threads, if necessary */ +#ifdef DEBUG_THREADS + printf("Adding thread (%d already - %d max)\n", + SDL_numthreads, SDL_maxthreads); +#endif + if ( SDL_numthreads == SDL_maxthreads ) { + threads=(SDL_Thread **)malloc((SDL_maxthreads+ARRAY_CHUNKSIZE)* + (sizeof *threads)); + if ( threads == NULL ) { + SDL_OutOfMemory(); + goto done; + } + memcpy(threads, SDL_Threads, SDL_numthreads*(sizeof *threads)); + SDL_maxthreads += ARRAY_CHUNKSIZE; + if ( SDL_Threads ) { + free(SDL_Threads); + } + SDL_Threads = threads; + } + SDL_Threads[SDL_numthreads++] = thread; +done: + SDL_mutexV(thread_lock); +} + +static void SDL_DelThread(SDL_Thread *thread) +{ + int i; + + if ( thread_lock ) { + SDL_mutexP(thread_lock); + for ( i=0; ithreadid ) { + errbuf = &SDL_Threads[i]->errbuf; + break; + } + } + SDL_mutexV(thread_lock); + } + return(errbuf); +} + + +/* Arguments and callback to setup and run the user thread function */ +typedef struct { + int (*func)(void *); + void *data; + SDL_Thread *info; + SDL_sem *wait; +} thread_args; + +void SDL_RunThread(void *data) +{ + thread_args *args; + int (*userfunc)(void *); + void *userdata; + int *statusloc; + + /* Perform any system-dependent setup + - this function cannot fail, and cannot use SDL_SetError() + */ + SDL_SYS_SetupThread(); + + /* Get the thread id */ + args = (thread_args *)data; + args->info->threadid = SDL_ThreadID(); + + /* Figure out what function to run */ + userfunc = args->func; + userdata = args->data; + statusloc = &args->info->status; + + /* Wake up the parent thread */ + SDL_SemPost(args->wait); + + /* Run the function */ + *statusloc = userfunc(userdata); +} + +SDL_Thread *SDL_CreateThread(int (*fn)(void *), void *data) +{ + SDL_Thread *thread; + thread_args *args; + int ret; + + /* Allocate memory for the thread info structure */ + thread = (SDL_Thread *)malloc(sizeof(*thread)); + if ( thread == NULL ) { + SDL_OutOfMemory(); + return(NULL); + } + memset(thread, 0, (sizeof *thread)); + thread->status = -1; + + /* Set up the arguments for the thread */ + args = (thread_args *)malloc(sizeof(*args)); + if ( args == NULL ) { + SDL_OutOfMemory(); + free(thread); + return(NULL); + } + args->func = fn; + args->data = data; + args->info = thread; + args->wait = SDL_CreateSemaphore(0); + if ( args->wait == NULL ) { + free(thread); + free(args); + return(NULL); + } + + /* Add the thread to the list of available threads */ + SDL_AddThread(thread); + + /* Create the thread and go! */ + ret = SDL_SYS_CreateThread(thread, args); + if ( ret >= 0 ) { + /* Wait for the thread function to use arguments */ + SDL_SemWait(args->wait); + } else { + /* Oops, failed. Gotta free everything */ + SDL_DelThread(thread); + free(thread); + thread = NULL; + } + SDL_DestroySemaphore(args->wait); + free(args); + + /* Everything is running now */ + return(thread); +} + +void SDL_WaitThread(SDL_Thread *thread, int *status) +{ + if ( thread ) { + SDL_SYS_WaitThread(thread); + if ( status ) { + *status = thread->status; + } + SDL_DelThread(thread); + free(thread); + } +} + +Uint32 SDL_GetThreadID(SDL_Thread *thread) +{ + Uint32 id; + + if ( thread ) { + id = thread->threadid; + } else { + id = SDL_ThreadID(); + } + return(id); +} + +void SDL_KillThread(SDL_Thread *thread) +{ + if ( thread ) { + SDL_SYS_KillThread(thread); + SDL_WaitThread(thread, NULL); + } +} + diff --git a/contrib/sdk/sources/SDL-1.2.2/src/thread/SDL_thread_c.h b/contrib/sdk/sources/SDL-1.2.2/src/thread/SDL_thread_c.h new file mode 100644 index 000000000..2751c0873 --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/src/thread/SDL_thread_c.h @@ -0,0 +1,44 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997, 1998, 1999, 2000, 2001 Sam Lantinga + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the Free + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + Sam Lantinga + slouken@devolution.com +*/ + +#ifndef _SDL_thread_c_h +#define _SDL_thread_c_h + +#include "SDL_error_c.h" +#include "SDL_systhread_c.h" + +/* This is the system-independent thread info structure */ +struct SDL_Thread { + Uint32 threadid; + SYS_ThreadHandle handle; + int status; + SDL_error errbuf; + void *data; +}; + +/* This is the function called to run a thread */ +extern void SDL_RunThread(void *data); + +/* Routine to get the thread-specific error variable */ +extern SDL_error *SDL_GetErrBuf(void); + +#endif /* _SDL_thread_c_h */ diff --git a/contrib/sdk/sources/SDL-1.2.2/src/timer/SDL_systimer.h b/contrib/sdk/sources/SDL-1.2.2/src/timer/SDL_systimer.h new file mode 100644 index 000000000..9da628c8a --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/src/timer/SDL_systimer.h @@ -0,0 +1,46 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997, 1998 Sam Lantinga + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the Free + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + Sam Lantinga + 5635-34 Springhouse Dr. + Pleasanton, CA 94588 (USA) + slouken@devolution.com +*/ + +#ifdef SAVE_RCSID +static char rcsid = + "@(#) $Id: SDL_systimer.h,v 1.2 2001/04/26 16:50:18 hercules Exp $"; +#endif + +/* The system dependent timer handling functions */ + +#include "SDL_timer.h" +#include "SDL_timer_c.h" + + +/* Initialize the system dependent timer subsystem */ +extern int SDL_SYS_TimerInit(void); + +/* Quit the system dependent timer subsystem */ +extern void SDL_SYS_TimerQuit(void); + +/* Start a timer set up by SDL_SetTimer() */ +extern int SDL_SYS_StartTimer(void); + +/* Stop a previously started timer */ +extern void SDL_SYS_StopTimer(void); diff --git a/contrib/sdk/sources/SDL-1.2.2/src/timer/SDL_timer.c b/contrib/sdk/sources/SDL-1.2.2/src/timer/SDL_timer.c new file mode 100644 index 000000000..57ed617f3 --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/src/timer/SDL_timer.c @@ -0,0 +1,281 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997, 1998 Sam Lantinga + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the Free + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + Sam Lantinga + 5635-34 Springhouse Dr. + Pleasanton, CA 94588 (USA) + slouken@devolution.com +*/ + +#include +#include /* For the definition of NULL */ + +#include "SDL_error.h" +#include "SDL_timer.h" +#include "SDL_timer_c.h" +#include "SDL_mutex.h" +#include "SDL_systimer.h" + +/* #define DEBUG_TIMERS */ + +int SDL_timer_started = 0; +int SDL_timer_running = 0; + +/* Data to handle a single periodic alarm */ +Uint32 SDL_alarm_interval = 0; +SDL_TimerCallback SDL_alarm_callback; + +static SDL_bool list_changed = SDL_FALSE; + +/* Data used for a thread-based timer */ +static int SDL_timer_threaded = 0; + +struct _SDL_TimerID { + Uint32 interval; + SDL_NewTimerCallback cb; + void *param; + Uint32 last_alarm; + struct _SDL_TimerID *next; +}; + +static SDL_TimerID SDL_timers = NULL; +static Uint32 num_timers = 0; +static SDL_mutex *SDL_timer_mutex; + +/* Set whether or not the timer should use a thread. + This should not be called while the timer subsystem is running. +*/ +int SDL_SetTimerThreaded(int value) +{ + int retval; + + if ( SDL_timer_started ) { + SDL_SetError("Timer already initialized"); + retval = -1; + } else { + retval = 0; + SDL_timer_threaded = value; + } + return retval; +} + +int SDL_TimerInit(void) +{ + int retval; + + SDL_timer_running = 0; + SDL_SetTimer(0, NULL); + retval = 0; + if ( ! SDL_timer_threaded ) { + retval = SDL_SYS_TimerInit(); + } + if ( SDL_timer_threaded ) { + SDL_timer_mutex = SDL_CreateMutex(); + } + SDL_timer_started = 1; + return(retval); +} + +void SDL_TimerQuit(void) +{ + SDL_SetTimer(0, NULL); + if ( SDL_timer_threaded < 2 ) { + SDL_SYS_TimerQuit(); + } + if ( SDL_timer_threaded ) { + SDL_DestroyMutex(SDL_timer_mutex); + } + SDL_timer_started = 0; + SDL_timer_threaded = 0; +} + +void SDL_ThreadedTimerCheck(void) +{ + Uint32 now, ms; + SDL_TimerID t, prev, next; + int removed; + + now = SDL_GetTicks(); + + SDL_mutexP(SDL_timer_mutex); + for ( prev = NULL, t = SDL_timers; t; t = next ) { + removed = 0; + ms = t->interval - SDL_TIMESLICE; + next = t->next; + if ( (t->last_alarm < now) && ((now - t->last_alarm) > ms) ) { + if ( (now - t->last_alarm) < t->interval ) { + t->last_alarm += t->interval; + } else { + t->last_alarm = now; + } + list_changed = SDL_FALSE; +#ifdef DEBUG_TIMERS + printf("Executing timer %p (thread = %d)\n", + t, SDL_ThreadID()); +#endif + SDL_mutexV(SDL_timer_mutex); + ms = t->cb(t->interval, t->param); + SDL_mutexP(SDL_timer_mutex); + if ( list_changed ) { + /* Abort, list of timers has been modified */ + break; + } + if ( ms != t->interval ) { + if ( ms ) { + t->interval = ROUND_RESOLUTION(ms); + } else { /* Remove the timer from the linked list */ +#ifdef DEBUG_TIMERS + printf("SDL: Removing timer %p\n", t); +#endif + if ( prev ) { + prev->next = next; + } else { + SDL_timers = next; + } + free(t); + -- num_timers; + removed = 1; + } + } + } + /* Don't update prev if the timer has disappeared */ + if ( ! removed ) { + prev = t; + } + } + SDL_mutexV(SDL_timer_mutex); +} + +SDL_TimerID SDL_AddTimer(Uint32 interval, SDL_NewTimerCallback callback, void *param) +{ + SDL_TimerID t; + if ( ! SDL_timer_mutex ) { + if ( SDL_timer_started ) { + SDL_SetError("This platform doesn't support multiple timers"); + } else { + SDL_SetError("You must call SDL_Init(SDL_INIT_TIMER) first"); + } + return NULL; + } + if ( ! SDL_timer_threaded ) { + SDL_SetError("Multiple timers require threaded events!"); + return NULL; + } + SDL_mutexP(SDL_timer_mutex); + t = (SDL_TimerID) malloc(sizeof(struct _SDL_TimerID)); + if ( t ) { + t->interval = ROUND_RESOLUTION(interval); + t->cb = callback; + t->param = param; + t->last_alarm = SDL_GetTicks(); + t->next = SDL_timers; + SDL_timers = t; + ++ num_timers; + list_changed = SDL_TRUE; + SDL_timer_running = 1; + } +#ifdef DEBUG_TIMERS + printf("SDL_AddTimer(%d) = %08x num_timers = %d\n", interval, (Uint32)t, num_timers); +#endif + SDL_mutexV(SDL_timer_mutex); + return t; +} + +SDL_bool SDL_RemoveTimer(SDL_TimerID id) +{ + SDL_TimerID t, prev = NULL; + SDL_bool removed; + + removed = SDL_FALSE; + SDL_mutexP(SDL_timer_mutex); + /* Look for id in the linked list of timers */ + for (t = SDL_timers; t; prev=t, t = t->next ) { + if ( t == id ) { + if(prev) { + prev->next = t->next; + } else { + SDL_timers = t->next; + } + free(t); + -- num_timers; + removed = SDL_TRUE; + list_changed = SDL_TRUE; + break; + } + } +#ifdef DEBUG_TIMERS + printf("SDL_RemoveTimer(%08x) = %d num_timers = %d thread = %d\n", (Uint32)id, removed, num_timers, SDL_ThreadID()); +#endif + SDL_mutexV(SDL_timer_mutex); + return removed; +} + +static void SDL_RemoveAllTimers(SDL_TimerID t) +{ + SDL_TimerID freeme; + + /* Changed to non-recursive implementation. + The recursive implementation is elegant, but subject to + stack overflow if there are lots and lots of timers. + */ + while ( t ) { + freeme = t; + t = t->next; + free(freeme); + } +} + +/* Old style callback functions are wrapped through this */ +static Uint32 callback_wrapper(Uint32 ms, void *param) +{ + SDL_TimerCallback func = (SDL_TimerCallback) param; + return (*func)(ms); +} + +int SDL_SetTimer(Uint32 ms, SDL_TimerCallback callback) +{ + int retval; + +#ifdef DEBUG_TIMERS + printf("SDL_SetTimer(%d)\n", ms); +#endif + retval = 0; + if ( SDL_timer_running ) { /* Stop any currently running timer */ + SDL_timer_running = 0; + if ( SDL_timer_threaded ) { + SDL_mutexP(SDL_timer_mutex); + SDL_RemoveAllTimers(SDL_timers); + SDL_timers = NULL; + SDL_mutexV(SDL_timer_mutex); + } else { + SDL_SYS_StopTimer(); + } + } + if ( ms ) { + if ( SDL_timer_threaded ) { + retval = (SDL_AddTimer(ms, callback_wrapper, + (void *)callback) != NULL); + } else { + SDL_timer_running = 1; + SDL_alarm_interval = ms; + SDL_alarm_callback = callback; + retval = SDL_SYS_StartTimer(); + } + } + return retval; +} diff --git a/contrib/sdk/sources/SDL-1.2.2/src/timer/SDL_timer_c.h b/contrib/sdk/sources/SDL-1.2.2/src/timer/SDL_timer_c.h new file mode 100644 index 000000000..aaf9bb941 --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/src/timer/SDL_timer_c.h @@ -0,0 +1,52 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997, 1998 Sam Lantinga + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the Free + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + Sam Lantinga + 5635-34 Springhouse Dr. + Pleasanton, CA 94588 (USA) + slouken@devolution.com +*/ + +#ifdef SAVE_RCSID +static char rcsid = + "@(#) $Id: SDL_timer_c.h,v 1.2 2001/04/26 16:50:18 hercules Exp $"; +#endif + +/* Useful functions and variables from SDL_timer.c */ +#include "SDL_timer.h" + +#define ROUND_RESOLUTION(X) \ + (((X+TIMER_RESOLUTION-1)/TIMER_RESOLUTION)*TIMER_RESOLUTION) + +extern int SDL_timer_started; +extern int SDL_timer_running; + +/* Data to handle a single periodic alarm */ +extern Uint32 SDL_alarm_interval; +extern SDL_TimerCallback SDL_alarm_callback; + +/* Set whether or not the timer should use a thread. + This should be called while the timer subsystem is running. +*/ +extern int SDL_SetTimerThreaded(int value); + +extern int SDL_TimerInit(void); +extern void SDL_TimerQuit(void); + +/* This function is called from the SDL event thread if it is available */ +extern void SDL_ThreadedTimerCheck(void); diff --git a/contrib/sdk/sources/SDL-1.2.2/src/timer/dummy/SDL_systimer.c b/contrib/sdk/sources/SDL-1.2.2/src/timer/dummy/SDL_systimer.c new file mode 100644 index 000000000..4230b0651 --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/src/timer/dummy/SDL_systimer.c @@ -0,0 +1,114 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997, 1998, 1999, 2000, 2001 Sam Lantinga + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the Free + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + Sam Lantinga + slouken@devolution.com +*/ + +#ifdef SAVE_RCSID +static char rcsid = + "@(#) $Id: SDL_systimer.c,v 1.2 2001/04/26 16:50:18 hercules Exp $"; +#endif + +#include +#include +#include +#include +#include +#include + +#include "SDL_error.h" +#include "SDL_timer.h" +#include "SDL_timer_c.h" + +#if _POSIX_THREAD_SYSCALL_SOFT +#include +#endif + +#if defined(DISABLE_THREADS) || defined(FORK_HACK) +#define USE_ITIMER +#endif + + +/* The first ticks value of the application */ +//static struct timeval start; +//static unsigned startlo,starthi; +//static unsigned clockrate; +static unsigned starttime; + +void SDL_StartTicks(void) +{ +// gettimeofday(&start, NULL); +// __asm__ ("int $0x40" : "=a"(clockrate) : "a"(18),"b"(5)); +// __asm__ ("rdtsc" : "=a"(startlo),"=d"(starthi)); + __asm__ ("int $0x40" : "=a"(starttime) : "a"(26),"b"(9)); +} + + +Uint32 SDL_GetTicks (void) +{ +/* struct timeval now; + Uint32 ticks; + gettimeofday(&now, NULL); + ticks=(now.tv_sec-start.tv_sec)*1000+(now.tv_usec-start.tv_usec)/1000; + return(ticks);*/ + /*int res; + __asm__ ("rdtsc\n\t" + "sub (_startlo),%%eax\n\t" + "sbb (_starthi),%%edx\n\t" + "push %%eax\n\t" + "mov %%edx,%%eax\n\t" + "mov $1000,%%ecx\n\t" + "mul %%ecx\n\t" + "xchg (%%esp),%%eax\n\t" + "mul %%ecx\n\t" + "add %%edx,(%%esp)\n\t" + "pop %%edx\n\t" + "divl (_clockrate)\n\t" : "=a"(res)); + return res;*/ + unsigned curtime; + __asm__ ("int $0x40" : "=a"(curtime) : "a"(26),"b"(9)); + return (curtime-starttime)*10; +} + +void SDL_Delay (Uint32 ms) +{ + __menuet__delay100(ms); +/* Uint32 start = SDL_GetTicks(); + do + __asm__("int $0x40" :: "a"(68),"b"(1)); + while (SDL_GetTicks()-start < ms);*/ +} + +int SDL_SYS_TimerInit(void) +{ + return(0); +} + +void SDL_SYS_TimerQuit(void) +{ +} + +int SDL_SYS_StartTimer(void) +{ + return(0); +} + +void SDL_SYS_StopTimer(void) +{ +} diff --git a/contrib/sdk/sources/SDL-1.2.2/src/video/SDL_RLEaccel.c b/contrib/sdk/sources/SDL-1.2.2/src/video/SDL_RLEaccel.c new file mode 100644 index 000000000..b730ff75b --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/src/video/SDL_RLEaccel.c @@ -0,0 +1,1552 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997, 1998, 1999, 2000, 2001 Sam Lantinga + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the Free + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + Sam Lantinga + slouken@devolution.com +*/ + + +/* + * RLE encoding for software colorkey and alpha-channel acceleration + * + * Original version by Sam Lantinga + * + * Mattias Engdegård (Yorick): Rewrite. New encoding format, encoder and + * decoder. Added per-surface alpha blitter. Added per-pixel alpha + * format, encoder and blitter. + * + * Many thanks to Xark and johns for hints, benchmarks and useful comments + * leading to this code. + * + * Welcome to Macro Mayhem. + */ + +/* + * The encoding translates the image data to a stream of segments of the form + * + * + * + * where is the number of transparent pixels to skip, + * is the number of opaque pixels to blit, + * and are the pixels themselves. + * + * This basic structure is used both for colorkeyed surfaces, used for simple + * binary transparency and for per-surface alpha blending, and for surfaces + * with per-pixel alpha. The details differ, however: + * + * Encoding of colorkeyed surfaces: + * + * Encoded pixels always have the same format as the target surface. + * and are unsigned 8 bit integers, except for 32 bit depth + * where they are 16 bit. This makes the pixel data aligned at all times. + * Segments never wrap around from one scan line to the next. + * + * The end of the sequence is marked by a zero , pair at the * + * beginning of a line. + * + * Encoding of surfaces with per-pixel alpha: + * + * The sequence begins with a struct RLEDestFormat describing the target + * pixel format, to provide reliable un-encoding. + * + * Each scan line is encoded twice: First all completely opaque pixels, + * encoded in the target format as described above, and then all + * partially transparent (translucent) pixels (where 1 <= alpha <= 254), + * in the following 32-bit format: + * + * For 32-bit targets, each pixel has the target RGB format but with + * the alpha value occupying the highest 8 bits. The and + * counts are 16 bit. + * + * For 16-bit targets, each pixel has the target RGB format, but with + * the middle component (usually green) shifted 16 steps to the left, + * and the hole filled with the 5 most significant bits of the alpha value. + * i.e. if the target has the format rrrrrggggggbbbbb, + * the encoded pixel will be 00000gggggg00000rrrrr0aaaaabbbbb. + * The and counts are 8 bit for the opaque lines, 16 bit + * for the translucent lines. Two padding bytes may be inserted + * before each translucent line to keep them 32-bit aligned. + * + * The end of the sequence is marked by a zero , pair at the + * beginning of an opaque line. + */ + +#include +#include +#include + +#include "SDL_types.h" +#include "SDL_video.h" +#include "SDL_error.h" +#include "SDL_sysvideo.h" +#include "SDL_blit.h" +#include "SDL_memops.h" +#include "SDL_RLEaccel_c.h" + +#ifndef MAX +#define MAX(a, b) ((a) > (b) ? (a) : (b)) +#endif +#ifndef MIN +#define MIN(a, b) ((a) < (b) ? (a) : (b)) +#endif + +#define PIXEL_COPY(to, from, len, bpp) \ +do { \ + if(bpp == 4) { \ + SDL_memcpy4(to, from, (unsigned)(len)); \ + } else { \ + SDL_memcpy(to, from, (unsigned)(len) * (bpp)); \ + } \ +} while(0) + +/* + * Various colorkey blit methods, for opaque and per-surface alpha + */ + +#define OPAQUE_BLIT(to, from, length, bpp, alpha) \ + PIXEL_COPY(to, from, length, bpp) + +/* + * For 32bpp pixels on the form 0x00rrggbb: + * If we treat the middle component separately, we can process the two + * remaining in parallel. This is safe to do because of the gap to the left + * of each component, so the bits from the multiplication don't collide. + * This can be used for any RGB permutation of course. + */ +#define ALPHA_BLIT32_888(to, from, length, bpp, alpha) \ + do { \ + int i; \ + Uint32 *src = (Uint32 *)(from); \ + Uint32 *dst = (Uint32 *)(to); \ + for(i = 0; i < (int)(length); i++) { \ + Uint32 s = *src++; \ + Uint32 d = *dst; \ + Uint32 s1 = s & 0xff00ff; \ + Uint32 d1 = d & 0xff00ff; \ + d1 = (d1 + ((s1 - d1) * alpha >> 8)) & 0xff00ff; \ + s &= 0xff00; \ + d &= 0xff00; \ + d = (d + ((s - d) * alpha >> 8)) & 0xff00; \ + *dst++ = d1 | d; \ + } \ + } while(0) + +/* + * For 16bpp pixels we can go a step further: put the middle component + * in the high 16 bits of a 32 bit word, and process all three RGB + * components at the same time. Since the smallest gap is here just + * 5 bits, we have to scale alpha down to 5 bits as well. + */ +#define ALPHA_BLIT16_565(to, from, length, bpp, alpha) \ + do { \ + int i; \ + Uint16 *src = (Uint16 *)(from); \ + Uint16 *dst = (Uint16 *)(to); \ + for(i = 0; i < (int)(length); i++) { \ + Uint32 s = *src++; \ + Uint32 d = *dst; \ + s = (s | s << 16) & 0x07e0f81f; \ + d = (d | d << 16) & 0x07e0f81f; \ + d += (s - d) * alpha >> 5; \ + d &= 0x07e0f81f; \ + *dst++ = d | d >> 16; \ + } \ + } while(0) + +#define ALPHA_BLIT16_555(to, from, length, bpp, alpha) \ + do { \ + int i; \ + Uint16 *src = (Uint16 *)(from); \ + Uint16 *dst = (Uint16 *)(to); \ + for(i = 0; i < (int)(length); i++) { \ + Uint32 s = *src++; \ + Uint32 d = *dst; \ + s = (s | s << 16) & 0x03e07c1f; \ + d = (d | d << 16) & 0x03e07c1f; \ + d += (s - d) * alpha >> 5; \ + d &= 0x03e07c1f; \ + *dst++ = d | d >> 16; \ + } \ + } while(0) + +/* + * The general slow catch-all function, for remaining depths and formats + */ +#define ALPHA_BLIT_ANY(to, from, length, bpp, alpha) \ + do { \ + int i; \ + Uint8 *src = from; \ + Uint8 *dst = to; \ + for(i = 0; i < (int)(length); i++) { \ + Uint32 s, d; \ + unsigned rs, gs, bs, rd, gd, bd; \ + switch(bpp) { \ + case 2: \ + s = *(Uint16 *)src; \ + d = *(Uint16 *)dst; \ + break; \ + case 3: \ + if(SDL_BYTEORDER == SDL_BIG_ENDIAN) { \ + s = (src[0] << 16) | (src[1] << 8) | src[2]; \ + d = (dst[0] << 16) | (dst[1] << 8) | dst[2]; \ + } else { \ + s = (src[2] << 16) | (src[1] << 8) | src[0]; \ + d = (dst[2] << 16) | (dst[1] << 8) | dst[0]; \ + } \ + break; \ + case 4: \ + s = *(Uint32 *)src; \ + d = *(Uint32 *)dst; \ + break; \ + } \ + RGB_FROM_PIXEL(s, fmt, rs, gs, bs); \ + RGB_FROM_PIXEL(d, fmt, rd, gd, bd); \ + rd += (rs - rd) * alpha >> 8; \ + gd += (gs - gd) * alpha >> 8; \ + bd += (bs - bd) * alpha >> 8; \ + PIXEL_FROM_RGB(d, fmt, rd, gd, bd); \ + switch(bpp) { \ + case 2: \ + *(Uint16 *)dst = d; \ + break; \ + case 3: \ + if(SDL_BYTEORDER == SDL_BIG_ENDIAN) { \ + dst[0] = d >> 16; \ + dst[1] = d >> 8; \ + dst[2] = d; \ + } else { \ + dst[0] = d; \ + dst[1] = d >> 8; \ + dst[2] = d >> 16; \ + } \ + break; \ + case 4: \ + *(Uint32 *)dst = d; \ + break; \ + } \ + src += bpp; \ + dst += bpp; \ + } \ + } while(0) + + +/* + * Special case: 50% alpha (alpha=128) + * This is treated specially because it can be optimized very well, and + * since it is good for many cases of semi-translucency. + * The theory is to do all three components at the same time: + * First zero the lowest bit of each component, which gives us room to + * add them. Then shift right and add the sum of the lowest bits. + */ +#define ALPHA_BLIT32_888_50(to, from, length, bpp, alpha) \ + do { \ + int i; \ + Uint32 *src = (Uint32 *)(from); \ + Uint32 *dst = (Uint32 *)(to); \ + for(i = 0; i < (int)(length); i++) { \ + Uint32 s = *src++; \ + Uint32 d = *dst; \ + *dst++ = (((s & 0x00fefefe) + (d & 0x00fefefe)) >> 1) \ + + (s & d & 0x00010101); \ + } \ + } while(0) + +/* + * For 16bpp, we can actually blend two pixels in parallel, if we take + * care to shift before we add, not after. + */ + +/* helper: blend a single 16 bit pixel at 50% */ +#define BLEND16_50(dst, src, mask) \ + do { \ + Uint32 s = *src++; \ + Uint32 d = *dst; \ + *dst++ = (((s & mask) + (d & mask)) >> 1) \ + + (s & d & (~mask & 0xffff)); \ + } while(0) + +/* basic 16bpp blender. mask is the pixels to keep when adding. */ +#define ALPHA_BLIT16_50(to, from, length, bpp, alpha, mask) \ + do { \ + unsigned n = (length); \ + Uint16 *src = (Uint16 *)(from); \ + Uint16 *dst = (Uint16 *)(to); \ + if(((unsigned long)src ^ (unsigned long)dst) & 3) { \ + /* source and destination not in phase, blit one by one */ \ + while(n--) \ + BLEND16_50(dst, src, mask); \ + } else { \ + if((unsigned long)src & 3) { \ + /* first odd pixel */ \ + BLEND16_50(dst, src, mask); \ + n--; \ + } \ + for(; n > 1; n -= 2) { \ + Uint32 s = *(Uint32 *)src; \ + Uint32 d = *(Uint32 *)dst; \ + *(Uint32 *)dst = ((s & (mask | mask << 16)) >> 1) \ + + ((d & (mask | mask << 16)) >> 1) \ + + (s & d & (~(mask | mask << 16))); \ + src += 2; \ + dst += 2; \ + } \ + if(n) \ + BLEND16_50(dst, src, mask); /* last odd pixel */ \ + } \ + } while(0) + +#define ALPHA_BLIT16_565_50(to, from, length, bpp, alpha) \ + ALPHA_BLIT16_50(to, from, length, bpp, alpha, 0xf7de) + +#define ALPHA_BLIT16_555_50(to, from, length, bpp, alpha) \ + ALPHA_BLIT16_50(to, from, length, bpp, alpha, 0xfbde) + + +#define CHOOSE_BLIT(blitter, alpha, fmt) \ + do { \ + if(alpha == 255) { \ + switch(fmt->BytesPerPixel) { \ + case 1: blitter(1, Uint8, OPAQUE_BLIT); break; \ + case 2: blitter(2, Uint8, OPAQUE_BLIT); break; \ + case 3: blitter(3, Uint8, OPAQUE_BLIT); break; \ + case 4: blitter(4, Uint16, OPAQUE_BLIT); break; \ + } \ + } else { \ + switch(fmt->BytesPerPixel) { \ + case 1: \ + /* No 8bpp alpha blitting */ \ + break; \ + \ + case 2: \ + switch(fmt->Rmask | fmt->Gmask | fmt->Bmask) { \ + case 0xffff: \ + if(fmt->Gmask == 0x07e0 \ + || fmt->Rmask == 0x07e0 \ + || fmt->Bmask == 0x07e0) { \ + if(alpha == 128) \ + blitter(2, Uint8, ALPHA_BLIT16_565_50); \ + else { \ + alpha >>= 3; /* use 5 bit alpha */ \ + blitter(2, Uint8, ALPHA_BLIT16_565); \ + } \ + } else \ + goto general16; \ + break; \ + \ + case 0x7fff: \ + if(fmt->Gmask == 0x03e0 \ + || fmt->Rmask == 0x03e0 \ + || fmt->Bmask == 0x03e0) { \ + if(alpha == 128) \ + blitter(2, Uint8, ALPHA_BLIT16_555_50); \ + else { \ + alpha >>= 3; /* use 5 bit alpha */ \ + blitter(2, Uint8, ALPHA_BLIT16_555); \ + } \ + break; \ + } \ + /* fallthrough */ \ + \ + default: \ + general16: \ + blitter(2, Uint8, ALPHA_BLIT_ANY); \ + } \ + break; \ + \ + case 3: \ + blitter(3, Uint8, ALPHA_BLIT_ANY); \ + break; \ + \ + case 4: \ + if((fmt->Rmask | fmt->Gmask | fmt->Bmask) == 0x00ffffff \ + && (fmt->Gmask == 0xff00 || fmt->Rmask == 0xff00 \ + || fmt->Bmask == 0xff00)) { \ + if(alpha == 128) \ + blitter(4, Uint16, ALPHA_BLIT32_888_50); \ + else \ + blitter(4, Uint16, ALPHA_BLIT32_888); \ + } else \ + blitter(4, Uint16, ALPHA_BLIT_ANY); \ + break; \ + } \ + } \ + } while(0) + + +/* + * This takes care of the case when the surface is clipped on the left and/or + * right. Top clipping has already been taken care of. + */ +static void RLEClipBlit(int w, Uint8 *srcbuf, SDL_Surface *dst, + Uint8 *dstbuf, SDL_Rect *srcrect, unsigned alpha) +{ + SDL_PixelFormat *fmt = dst->format; + +#define RLECLIPBLIT(bpp, Type, do_blit) \ + do { \ + int linecount = srcrect->h; \ + int ofs = 0; \ + int left = srcrect->x; \ + int right = left + srcrect->w; \ + dstbuf -= left * bpp; \ + for(;;) { \ + int run; \ + ofs += *(Type *)srcbuf; \ + run = ((Type *)srcbuf)[1]; \ + srcbuf += 2 * sizeof(Type); \ + if(run) { \ + /* clip to left and right borders */ \ + if(ofs < right) { \ + int start = 0; \ + int len = run; \ + int startcol; \ + if(left - ofs > 0) { \ + start = left - ofs; \ + len -= start; \ + if(len <= 0) \ + goto nocopy ## bpp ## do_blit; \ + } \ + startcol = ofs + start; \ + if(len > right - startcol) \ + len = right - startcol; \ + do_blit(dstbuf + startcol * bpp, srcbuf + start * bpp, \ + len, bpp, alpha); \ + } \ + nocopy ## bpp ## do_blit: \ + srcbuf += run * bpp; \ + ofs += run; \ + } else if(!ofs) \ + break; \ + if(ofs == w) { \ + ofs = 0; \ + dstbuf += dst->pitch; \ + if(!--linecount) \ + break; \ + } \ + } \ + } while(0) + + CHOOSE_BLIT(RLECLIPBLIT, alpha, fmt); + +#undef RLECLIPBLIT + +} + + +/* blit a colorkeyed RLE surface */ +int SDL_RLEBlit(SDL_Surface *src, SDL_Rect *srcrect, + SDL_Surface *dst, SDL_Rect *dstrect) +{ + Uint8 *dstbuf; + Uint8 *srcbuf; + int x, y; + int w = src->w; + unsigned alpha; + + /* Lock the destination if necessary */ + if ( dst->flags & (SDL_HWSURFACE|SDL_ASYNCBLIT) ) { + SDL_VideoDevice *video = current_video; + SDL_VideoDevice *this = current_video; + if ( video->LockHWSurface(this, dst) < 0 ) { + return(-1); + } + } + + /* Set up the source and destination pointers */ + x = dstrect->x; + y = dstrect->y; + dstbuf = (Uint8 *)dst->pixels + dst->offset + + y * dst->pitch + x * src->format->BytesPerPixel; + srcbuf = (Uint8 *)src->map->sw_data->aux_data; + + { + /* skip lines at the top if neccessary */ + int vskip = srcrect->y; + int ofs = 0; + if(vskip) { + +#define RLESKIP(bpp, Type) \ + for(;;) { \ + int run; \ + ofs += *(Type *)srcbuf; \ + run = ((Type *)srcbuf)[1]; \ + srcbuf += sizeof(Type) * 2; \ + if(run) { \ + srcbuf += run * bpp; \ + ofs += run; \ + } else if(!ofs) \ + goto done; \ + if(ofs == w) { \ + ofs = 0; \ + if(!--vskip) \ + break; \ + } \ + } + + switch(src->format->BytesPerPixel) { + case 1: RLESKIP(1, Uint8); break; + case 2: RLESKIP(2, Uint8); break; + case 3: RLESKIP(3, Uint8); break; + case 4: RLESKIP(4, Uint16); break; + } + +#undef RLESKIP + + } + } + + alpha = (src->flags & SDL_SRCALPHA) == SDL_SRCALPHA + ? src->format->alpha : 255; + /* if left or right edge clipping needed, call clip blit */ + if ( srcrect->x || srcrect->w != src->w ) { + RLEClipBlit(w, srcbuf, dst, dstbuf, srcrect, alpha); + } else { + SDL_PixelFormat *fmt = src->format; + +#define RLEBLIT(bpp, Type, do_blit) \ + do { \ + int linecount = srcrect->h; \ + int ofs = 0; \ + for(;;) { \ + unsigned run; \ + ofs += *(Type *)srcbuf; \ + run = ((Type *)srcbuf)[1]; \ + srcbuf += 2 * sizeof(Type); \ + if(run) { \ + do_blit(dstbuf + ofs * bpp, srcbuf, run, bpp, alpha); \ + srcbuf += run * bpp; \ + ofs += run; \ + } else if(!ofs) \ + break; \ + if(ofs == w) { \ + ofs = 0; \ + dstbuf += dst->pitch; \ + if(!--linecount) \ + break; \ + } \ + } \ + } while(0) + + CHOOSE_BLIT(RLEBLIT, alpha, fmt); + +#undef RLEBLIT + } + +done: + /* Unlock the destination if necessary */ + if ( dst->flags & (SDL_HWSURFACE|SDL_ASYNCBLIT) ) { + SDL_VideoDevice *video = current_video; + SDL_VideoDevice *this = current_video; + video->UnlockHWSurface(this, dst); + } + return(0); +} + +#undef OPAQUE_BLIT + +/* + * Per-pixel blitting macros for translucent pixels: + * These use the same techniques as the per-surface blitting macros + */ + +/* + * For 32bpp pixels, we have made sure the alpha is stored in the top + * 8 bits, so proceed as usual + */ +#define BLIT_TRANSL_888(src, dst) \ + do { \ + Uint32 s = src; \ + Uint32 d = dst; \ + unsigned alpha = s >> 24; \ + Uint32 s1 = s & 0xff00ff; \ + Uint32 d1 = d & 0xff00ff; \ + d1 = (d1 + ((s1 - d1) * alpha >> 8)) & 0xff00ff; \ + s &= 0xff00; \ + d &= 0xff00; \ + d = (d + ((s - d) * alpha >> 8)) & 0xff00; \ + dst = d1 | d; \ + } while(0) + +/* + * For 16bpp pixels, we have stored the 5 most significant alpha bits in + * bits 5-10. As before, we can process all 3 RGB components at the same time. + */ +#define BLIT_TRANSL_565(src, dst) \ + do { \ + Uint32 s = src; \ + Uint32 d = dst; \ + unsigned alpha = (s & 0x3e0) >> 5; \ + s &= 0x07e0f81f; \ + d = (d | d << 16) & 0x07e0f81f; \ + d += (s - d) * alpha >> 5; \ + d &= 0x07e0f81f; \ + dst = d | d >> 16; \ + } while(0) + +#define BLIT_TRANSL_555(src, dst) \ + do { \ + Uint32 s = src; \ + Uint32 d = dst; \ + unsigned alpha = (s & 0x3e0) >> 5; \ + s &= 0x03e07c1f; \ + d = (d | d << 16) & 0x03e07c1f; \ + d += (s - d) * alpha >> 5; \ + d &= 0x03e07c1f; \ + dst = d | d >> 16; \ + } while(0) + +/* used to save the destination format in the encoding. Designed to be + macro-compatible with SDL_PixelFormat but without the unneeded fields */ +typedef struct { + Uint8 BytesPerPixel; + Uint8 Rloss; + Uint8 Gloss; + Uint8 Bloss; + Uint8 Rshift; + Uint8 Gshift; + Uint8 Bshift; + Uint8 Ashift; + Uint32 Rmask; + Uint32 Gmask; + Uint32 Bmask; + Uint32 Amask; +} RLEDestFormat; + +/* blit a pixel-alpha RLE surface clipped at the right and/or left edges */ +static void RLEAlphaClipBlit(int w, Uint8 *srcbuf, SDL_Surface *dst, + Uint8 *dstbuf, SDL_Rect *srcrect) +{ + SDL_PixelFormat *df = dst->format; + /* + * clipped blitter: Ptype is the destination pixel type, + * Ctype the translucent count type, and do_blend the macro + * to blend one pixel. + */ +#define RLEALPHACLIPBLIT(Ptype, Ctype, do_blend) \ + do { \ + int linecount = srcrect->h; \ + int left = srcrect->x; \ + int right = left + srcrect->w; \ + dstbuf -= left * sizeof(Ptype); \ + do { \ + int ofs = 0; \ + /* blit opaque pixels on one line */ \ + do { \ + unsigned run; \ + ofs += ((Ctype *)srcbuf)[0]; \ + run = ((Ctype *)srcbuf)[1]; \ + srcbuf += 2 * sizeof(Ctype); \ + if(run) { \ + /* clip to left and right borders */ \ + int cofs = ofs; \ + int crun = run; \ + if(left - cofs > 0) { \ + crun -= left - cofs; \ + cofs = left; \ + } \ + if(crun > right - cofs) \ + crun = right - cofs; \ + if(crun > 0) \ + PIXEL_COPY(dstbuf + cofs * sizeof(Ptype), \ + srcbuf + (cofs - ofs) * sizeof(Ptype), \ + (unsigned)crun, sizeof(Ptype)); \ + srcbuf += run * sizeof(Ptype); \ + ofs += run; \ + } else if(!ofs) \ + return; \ + } while(ofs < w); \ + /* skip padding if necessary */ \ + if(sizeof(Ptype) == 2) \ + srcbuf += (unsigned long)srcbuf & 2; \ + /* blit translucent pixels on the same line */ \ + ofs = 0; \ + do { \ + unsigned run; \ + ofs += ((Uint16 *)srcbuf)[0]; \ + run = ((Uint16 *)srcbuf)[1]; \ + srcbuf += 4; \ + if(run) { \ + /* clip to left and right borders */ \ + int cofs = ofs; \ + int crun = run; \ + if(left - cofs > 0) { \ + crun -= left - cofs; \ + cofs = left; \ + } \ + if(crun > right - cofs) \ + crun = right - cofs; \ + if(crun > 0) { \ + Ptype *dst = (Ptype *)dstbuf + cofs; \ + Uint32 *src = (Uint32 *)srcbuf + (cofs - ofs); \ + int i; \ + for(i = 0; i < crun; i++) \ + do_blend(src[i], dst[i]); \ + } \ + srcbuf += run * 4; \ + ofs += run; \ + } \ + } while(ofs < w); \ + dstbuf += dst->pitch; \ + } while(--linecount); \ + } while(0) + + switch(df->BytesPerPixel) { + case 2: + if(df->Gmask == 0x07e0 || df->Rmask == 0x07e0 + || df->Bmask == 0x07e0) + RLEALPHACLIPBLIT(Uint16, Uint8, BLIT_TRANSL_565); + else + RLEALPHACLIPBLIT(Uint16, Uint8, BLIT_TRANSL_555); + break; + case 4: + RLEALPHACLIPBLIT(Uint32, Uint16, BLIT_TRANSL_888); + break; + } +} + +/* blit a pixel-alpha RLE surface */ +int SDL_RLEAlphaBlit(SDL_Surface *src, SDL_Rect *srcrect, + SDL_Surface *dst, SDL_Rect *dstrect) +{ + int x, y; + int w = src->w; + Uint8 *srcbuf, *dstbuf; + SDL_PixelFormat *df = dst->format; + + /* Lock the destination if necessary */ + if(dst->flags & (SDL_HWSURFACE|SDL_ASYNCBLIT)) { + SDL_VideoDevice *video = current_video; + SDL_VideoDevice *this = current_video; + if(video->LockHWSurface(this, dst) < 0) { + return -1; + } + } + + x = dstrect->x; + y = dstrect->y; + dstbuf = (Uint8 *)dst->pixels + dst->offset + + y * dst->pitch + x * df->BytesPerPixel; + srcbuf = (Uint8 *)src->map->sw_data->aux_data + sizeof(RLEDestFormat); + + { + /* skip lines at the top if necessary */ + int vskip = srcrect->y; + if(vskip) { + int ofs; + if(df->BytesPerPixel == 2) { + /* the 16/32 interleaved format */ + do { + /* skip opaque line */ + ofs = 0; + do { + int run; + ofs += srcbuf[0]; + run = srcbuf[1]; + srcbuf += 2; + if(run) { + srcbuf += 2 * run; + ofs += run; + } else if(!ofs) + goto done; + } while(ofs < w); + + /* skip padding */ + srcbuf += (unsigned long)srcbuf & 2; + + /* skip translucent line */ + ofs = 0; + do { + int run; + ofs += ((Uint16 *)srcbuf)[0]; + run = ((Uint16 *)srcbuf)[1]; + srcbuf += 4 * (run + 1); + ofs += run; + } while(ofs < w); + } while(--vskip); + } else { + /* the 32/32 interleaved format */ + vskip <<= 1; /* opaque and translucent have same format */ + do { + ofs = 0; + do { + int run; + ofs += ((Uint16 *)srcbuf)[0]; + run = ((Uint16 *)srcbuf)[1]; + srcbuf += 4; + if(run) { + srcbuf += 4 * run; + ofs += run; + } else if(!ofs) + goto done; + } while(ofs < w); + } while(--vskip); + } + } + } + + /* if left or right edge clipping needed, call clip blit */ + if(srcrect->x || srcrect->w != src->w) { + RLEAlphaClipBlit(w, srcbuf, dst, dstbuf, srcrect); + } else { + + /* + * non-clipped blitter. Ptype is the destination pixel type, + * Ctype the translucent count type, and do_blend the + * macro to blend one pixel. + */ +#define RLEALPHABLIT(Ptype, Ctype, do_blend) \ + do { \ + int linecount = srcrect->h; \ + do { \ + int ofs = 0; \ + /* blit opaque pixels on one line */ \ + do { \ + unsigned run; \ + ofs += ((Ctype *)srcbuf)[0]; \ + run = ((Ctype *)srcbuf)[1]; \ + srcbuf += 2 * sizeof(Ctype); \ + if(run) { \ + PIXEL_COPY(dstbuf + ofs * sizeof(Ptype), srcbuf, \ + run, sizeof(Ptype)); \ + srcbuf += run * sizeof(Ptype); \ + ofs += run; \ + } else if(!ofs) \ + goto done; \ + } while(ofs < w); \ + /* skip padding if necessary */ \ + if(sizeof(Ptype) == 2) \ + srcbuf += (unsigned long)srcbuf & 2; \ + /* blit translucent pixels on the same line */ \ + ofs = 0; \ + do { \ + unsigned run; \ + ofs += ((Uint16 *)srcbuf)[0]; \ + run = ((Uint16 *)srcbuf)[1]; \ + srcbuf += 4; \ + if(run) { \ + Ptype *dst = (Ptype *)dstbuf + ofs; \ + unsigned i; \ + for(i = 0; i < run; i++) { \ + Uint32 src = *(Uint32 *)srcbuf; \ + do_blend(src, *dst); \ + srcbuf += 4; \ + dst++; \ + } \ + ofs += run; \ + } \ + } while(ofs < w); \ + dstbuf += dst->pitch; \ + } while(--linecount); \ + } while(0) + + switch(df->BytesPerPixel) { + case 2: + if(df->Gmask == 0x07e0 || df->Rmask == 0x07e0 + || df->Bmask == 0x07e0) + RLEALPHABLIT(Uint16, Uint8, BLIT_TRANSL_565); + else + RLEALPHABLIT(Uint16, Uint8, BLIT_TRANSL_555); + break; + case 4: + RLEALPHABLIT(Uint32, Uint16, BLIT_TRANSL_888); + break; + } + } + + done: + /* Unlock the destination if necessary */ + if(dst->flags & (SDL_HWSURFACE|SDL_ASYNCBLIT)) { + SDL_VideoDevice *video = current_video; + SDL_VideoDevice *this = current_video; + video->UnlockHWSurface(this, dst); + } + return 0; +} + +/* + * Auxiliary functions: + * The encoding functions take 32bpp rgb + a, and + * return the number of bytes copied to the destination. + * The decoding functions copy to 32bpp rgb + a, and + * return the number of bytes copied from the source. + * These are only used in the encoder and un-RLE code and are therefore not + * highly optimised. + */ + +/* encode 32bpp rgb + a into 16bpp rgb, losing alpha */ +static int copy_opaque_16(void *dst, Uint32 *src, int n, + SDL_PixelFormat *sfmt, SDL_PixelFormat *dfmt) +{ + int i; + Uint16 *d = dst; + for(i = 0; i < n; i++) { + unsigned r, g, b; + RGB_FROM_PIXEL(*src, sfmt, r, g, b); + PIXEL_FROM_RGB(*d, dfmt, r, g, b); + src++; + d++; + } + return n * 2; +} + +/* decode opaque pixels from 16bpp to 32bpp rgb + a */ +static int uncopy_opaque_16(Uint32 *dst, void *src, int n, + RLEDestFormat *sfmt, SDL_PixelFormat *dfmt) +{ + int i; + Uint16 *s = src; + unsigned alpha = dfmt->Amask ? 255 : 0; + for(i = 0; i < n; i++) { + unsigned r, g, b; + RGB_FROM_PIXEL(*s, sfmt, r, g, b); + PIXEL_FROM_RGBA(*dst, dfmt, r, g, b, alpha); + s++; + dst++; + } + return n * 2; +} + + + +/* encode 32bpp rgb + a into 32bpp G0RAB format for blitting into 565 */ +static int copy_transl_565(void *dst, Uint32 *src, int n, + SDL_PixelFormat *sfmt, SDL_PixelFormat *dfmt) +{ + int i; + Uint32 *d = dst; + for(i = 0; i < n; i++) { + unsigned r, g, b, a; + Uint16 pix; + RGBA_FROM_8888(*src, sfmt, r, g, b, a); + PIXEL_FROM_RGB(pix, dfmt, r, g, b); + *d = ((pix & 0x7e0) << 16) | (pix & 0xf81f) | ((a << 2) & 0x7e0); + src++; + d++; + } + return n * 4; +} + +/* encode 32bpp rgb + a into 32bpp G0RAB format for blitting into 555 */ +static int copy_transl_555(void *dst, Uint32 *src, int n, + SDL_PixelFormat *sfmt, SDL_PixelFormat *dfmt) +{ + int i; + Uint32 *d = dst; + for(i = 0; i < n; i++) { + unsigned r, g, b, a; + Uint16 pix; + RGBA_FROM_8888(*src, sfmt, r, g, b, a); + PIXEL_FROM_RGB(pix, dfmt, r, g, b); + *d = ((pix & 0x3e0) << 16) | (pix & 0xfc1f) | ((a << 2) & 0x3e0); + src++; + d++; + } + return n * 4; +} + +/* decode translucent pixels from 32bpp GORAB to 32bpp rgb + a */ +static int uncopy_transl_16(Uint32 *dst, void *src, int n, + RLEDestFormat *sfmt, SDL_PixelFormat *dfmt) +{ + int i; + Uint32 *s = src; + for(i = 0; i < n; i++) { + unsigned r, g, b, a; + Uint32 pix = *s++; + a = (pix & 0x3e0) >> 2; + pix = (pix & ~0x3e0) | pix >> 16; + RGB_FROM_PIXEL(pix, sfmt, r, g, b); + PIXEL_FROM_RGBA(*dst, dfmt, r, g, b, a); + dst++; + } + return n * 4; +} + +/* encode 32bpp rgba into 32bpp rgba, keeping alpha (dual purpose) */ +static int copy_32(void *dst, Uint32 *src, int n, + SDL_PixelFormat *sfmt, SDL_PixelFormat *dfmt) +{ + int i; + Uint32 *d = dst; + for(i = 0; i < n; i++) { + unsigned r, g, b, a; + Uint32 pixel; + RGBA_FROM_8888(*src, sfmt, r, g, b, a); + PIXEL_FROM_RGB(pixel, dfmt, r, g, b); + *d++ = pixel | a << 24; + src++; + } + return n * 4; +} + +/* decode 32bpp rgba into 32bpp rgba, keeping alpha (dual purpose) */ +static int uncopy_32(Uint32 *dst, void *src, int n, + RLEDestFormat *sfmt, SDL_PixelFormat *dfmt) +{ + int i; + Uint32 *s = src; + for(i = 0; i < n; i++) { + unsigned r, g, b, a; + Uint32 pixel = *s++; + RGB_FROM_PIXEL(pixel, sfmt, r, g, b); + a = pixel >> 24; + PIXEL_FROM_RGBA(*dst, dfmt, r, g, b, a); + dst++; + } + return n * 4; +} + +#define ISOPAQUE(pixel, fmt) ((((pixel) & fmt->Amask) >> fmt->Ashift) == 255) + +#define ISTRANSL(pixel, fmt) \ + ((unsigned)((((pixel) & fmt->Amask) >> fmt->Ashift) - 1U) < 254U) + +/* convert surface to be quickly alpha-blittable onto dest, if possible */ +static int RLEAlphaSurface(SDL_Surface *surface) +{ + SDL_Surface *dest; + SDL_PixelFormat *df; + int maxsize = 0; + int max_opaque_run; + int max_transl_run = 65535; + unsigned masksum; + Uint8 *rlebuf, *dst; + int (*copy_opaque)(void *, Uint32 *, int, + SDL_PixelFormat *, SDL_PixelFormat *); + int (*copy_transl)(void *, Uint32 *, int, + SDL_PixelFormat *, SDL_PixelFormat *); + + dest = surface->map->dst; + if(!dest) + return -1; + df = dest->format; + if(surface->format->BitsPerPixel != 32) + return -1; /* only 32bpp source supported */ + + /* find out whether the destination is one we support, + and determine the max size of the encoded result */ + masksum = df->Rmask | df->Gmask | df->Bmask; + switch(df->BytesPerPixel) { + case 2: + /* 16bpp: only support 565 and 555 formats */ + switch(masksum) { + case 0xffff: + if(df->Gmask == 0x07e0 + || df->Rmask == 0x07e0 || df->Bmask == 0x07e0) { + copy_opaque = copy_opaque_16; + copy_transl = copy_transl_565; + } else + return -1; + break; + case 0x7fff: + if(df->Gmask == 0x03e0 + || df->Rmask == 0x03e0 || df->Bmask == 0x03e0) { + copy_opaque = copy_opaque_16; + copy_transl = copy_transl_555; + } else + return -1; + break; + default: + return -1; + } + max_opaque_run = 255; /* runs stored as bytes */ + + /* worst case is alternating opaque and translucent pixels, + with room for alignment padding between lines */ + maxsize = surface->h * (2 + (4 + 2) * (surface->w + 1)) + 2; + break; + case 4: + if(masksum != 0x00ffffff) + return -1; /* requires unused high byte */ + copy_opaque = copy_32; + copy_transl = copy_32; + max_opaque_run = 255; /* runs stored as short ints */ + + /* worst case is alternating opaque and translucent pixels */ + maxsize = surface->h * 2 * 4 * (surface->w + 1) + 4; + break; + default: + return -1; /* anything else unsupported right now */ + } + + maxsize += sizeof(RLEDestFormat); + rlebuf = (Uint8 *)malloc(maxsize); + if(!rlebuf) { + SDL_OutOfMemory(); + return -1; + } + { + /* save the destination format so we can undo the encoding later */ + RLEDestFormat *r = (RLEDestFormat *)rlebuf; + r->BytesPerPixel = df->BytesPerPixel; + r->Rloss = df->Rloss; + r->Gloss = df->Gloss; + r->Bloss = df->Bloss; + r->Rshift = df->Rshift; + r->Gshift = df->Gshift; + r->Bshift = df->Bshift; + r->Ashift = df->Ashift; + r->Rmask = df->Rmask; + r->Gmask = df->Gmask; + r->Bmask = df->Bmask; + r->Amask = df->Amask; + } + dst = rlebuf + sizeof(RLEDestFormat); + + /* Do the actual encoding */ + { + int x, y; + int h = surface->h, w = surface->w; + SDL_PixelFormat *sf = surface->format; + Uint32 *src = (Uint32 *)((Uint8 *)surface->pixels + surface->offset); + Uint8 *lastline = dst; /* end of last non-blank line */ + + /* opaque counts are 8 or 16 bits, depending on target depth */ +#define ADD_OPAQUE_COUNTS(n, m) \ + if(df->BytesPerPixel == 4) { \ + ((Uint16 *)dst)[0] = n; \ + ((Uint16 *)dst)[1] = m; \ + dst += 4; \ + } else { \ + dst[0] = n; \ + dst[1] = m; \ + dst += 2; \ + } + + /* translucent counts are always 16 bit */ +#define ADD_TRANSL_COUNTS(n, m) \ + (((Uint16 *)dst)[0] = n, ((Uint16 *)dst)[1] = m, dst += 4) + + for(y = 0; y < h; y++) { + int runstart, skipstart; + int blankline = 0; + /* First encode all opaque pixels of a scan line */ + x = 0; + do { + int run, skip, len; + skipstart = x; + while(x < w && !ISOPAQUE(src[x], sf)) + x++; + runstart = x; + while(x < w && ISOPAQUE(src[x], sf)) + x++; + skip = runstart - skipstart; + if(skip == w) + blankline = 1; + run = x - runstart; + while(skip > max_opaque_run) { + ADD_OPAQUE_COUNTS(max_opaque_run, 0); + skip -= max_opaque_run; + } + len = MIN(run, max_opaque_run); + ADD_OPAQUE_COUNTS(skip, len); + dst += copy_opaque(dst, src + runstart, len, sf, df); + runstart += len; + run -= len; + while(run) { + len = MIN(run, max_opaque_run); + ADD_OPAQUE_COUNTS(0, len); + dst += copy_opaque(dst, src + runstart, len, sf, df); + runstart += len; + run -= len; + } + } while(x < w); + + /* Make sure the next output address is 32-bit aligned */ + dst += (unsigned long)dst & 2; + + /* Next, encode all translucent pixels of the same scan line */ + x = 0; + do { + int run, skip, len; + skipstart = x; + while(x < w && !ISTRANSL(src[x], sf)) + x++; + runstart = x; + while(x < w && ISTRANSL(src[x], sf)) + x++; + skip = runstart - skipstart; + blankline &= (skip == w); + run = x - runstart; + while(skip > max_transl_run) { + ADD_TRANSL_COUNTS(max_transl_run, 0); + skip -= max_transl_run; + } + len = MIN(run, max_transl_run); + ADD_TRANSL_COUNTS(skip, len); + dst += copy_transl(dst, src + runstart, len, sf, df); + runstart += len; + run -= len; + while(run) { + len = MIN(run, max_transl_run); + ADD_TRANSL_COUNTS(0, len); + dst += copy_transl(dst, src + runstart, len, sf, df); + runstart += len; + run -= len; + } + if(!blankline) + lastline = dst; + } while(x < w); + + src += surface->pitch >> 2; + } + dst = lastline; /* back up past trailing blank lines */ + ADD_OPAQUE_COUNTS(0, 0); + } + +#undef ADD_OPAQUE_COUNTS +#undef ADD_TRANSL_COUNTS + + /* Now that we have it encoded, release the original pixels */ + if((surface->flags & SDL_PREALLOC) != SDL_PREALLOC + && (surface->flags & SDL_HWSURFACE) != SDL_HWSURFACE) { + free( surface->pixels ); + surface->pixels = NULL; + } + + /* realloc the buffer to release unused memory */ + { + Uint8 *p = realloc(rlebuf, dst - rlebuf); + if(!p) + p = rlebuf; + surface->map->sw_data->aux_data = p; + } + + return 0; +} + +static Uint32 getpix_8(Uint8 *srcbuf) +{ + return *srcbuf; +} + +static Uint32 getpix_16(Uint8 *srcbuf) +{ + return *(Uint16 *)srcbuf; +} + +static Uint32 getpix_24(Uint8 *srcbuf) +{ + if(SDL_BYTEORDER == SDL_LIL_ENDIAN) + return srcbuf[0] + (srcbuf[1] << 8) + (srcbuf[2] << 16); + else + return (srcbuf[0] << 16) + (srcbuf[1] << 8) + srcbuf[2]; +} + +static Uint32 getpix_32(Uint8 *srcbuf) +{ + return *(Uint32 *)srcbuf; +} + +typedef Uint32 (*getpix_func)(Uint8 *); + +static getpix_func getpixes[4] = { + getpix_8, getpix_16, getpix_24, getpix_32 +}; + +static int RLEColorkeySurface(SDL_Surface *surface) +{ + Uint8 *rlebuf, *dst; + int maxn; + int y; + Uint8 *srcbuf, *curbuf, *lastline; + int maxsize = 0; + int skip, run; + int bpp = surface->format->BytesPerPixel; + getpix_func getpix; + Uint32 ckey, rgbmask; + int w, h; + + /* calculate the worst case size for the compressed surface */ + switch(bpp) { + case 1: + /* worst case is alternating opaque and transparent pixels, + starting with an opaque pixel */ + maxsize = surface->h * 3 * (surface->w / 2 + 1) + 2; + break; + case 2: + case 3: + /* worst case is solid runs, at most 255 pixels wide */ + maxsize = surface->h * (2 * (surface->w / 255 + 1) + + surface->w * bpp) + 2; + break; + case 4: + /* worst case is solid runs, at most 65535 pixels wide */ + maxsize = surface->h * (4 * (surface->w / 65535 + 1) + + surface->w * 4) + 4; + break; + } + + rlebuf = (Uint8 *)malloc(maxsize); + if ( rlebuf == NULL ) { + SDL_OutOfMemory(); + return(-1); + } + + /* Set up the conversion */ + srcbuf = (Uint8 *)surface->pixels+surface->offset; + curbuf = srcbuf; + maxn = bpp == 4 ? 65535 : 255; + skip = run = 0; + dst = rlebuf; + rgbmask = ~surface->format->Amask; + ckey = surface->format->colorkey & rgbmask; + lastline = dst; + getpix = getpixes[bpp - 1]; + w = surface->w; + h = surface->h; + +#define ADD_COUNTS(n, m) \ + if(bpp == 4) { \ + ((Uint16 *)dst)[0] = n; \ + ((Uint16 *)dst)[1] = m; \ + dst += 4; \ + } else { \ + dst[0] = n; \ + dst[1] = m; \ + dst += 2; \ + } + + for(y = 0; y < h; y++) { + int x = 0; + int blankline = 0; + do { + int run, skip, len; + int runstart; + int skipstart = x; + + /* find run of transparent, then opaque pixels */ + while(x < w && (getpix(srcbuf + x * bpp) & rgbmask) == ckey) + x++; + runstart = x; + while(x < w && (getpix(srcbuf + x * bpp) & rgbmask) != ckey) + x++; + skip = runstart - skipstart; + if(skip == w) + blankline = 1; + run = x - runstart; + + /* encode segment */ + while(skip > maxn) { + ADD_COUNTS(maxn, 0); + skip -= maxn; + } + len = MIN(run, maxn); + ADD_COUNTS(skip, len); + memcpy(dst, srcbuf + runstart * bpp, len * bpp); + dst += len * bpp; + run -= len; + runstart += len; + while(run) { + len = MIN(run, maxn); + ADD_COUNTS(0, len); + memcpy(dst, srcbuf + runstart * bpp, len * bpp); + dst += len * bpp; + runstart += len; + run -= len; + } + if(!blankline) + lastline = dst; + } while(x < w); + + srcbuf += surface->pitch; + } + dst = lastline; /* back up bast trailing blank lines */ + ADD_COUNTS(0, 0); + +#undef ADD_COUNTS + + /* Now that we have it encoded, release the original pixels */ + if((surface->flags & SDL_PREALLOC) != SDL_PREALLOC + && (surface->flags & SDL_HWSURFACE) != SDL_HWSURFACE) { + free( surface->pixels ); + surface->pixels = NULL; + } + + /* realloc the buffer to release unused memory */ + { + /* If realloc returns NULL, the original block is left intact */ + Uint8 *p = realloc(rlebuf, dst - rlebuf); + if(!p) + p = rlebuf; + surface->map->sw_data->aux_data = p; + } + + return(0); +} + +int SDL_RLESurface(SDL_Surface *surface) +{ + int retcode; + + /* Clear any previous RLE conversion */ + if ( (surface->flags & SDL_RLEACCEL) == SDL_RLEACCEL ) { + SDL_UnRLESurface(surface, 1); + } + + /* We don't support RLE encoding of bitmaps */ + if ( surface->format->BitsPerPixel < 8 ) { + return(-1); + } + + /* Lock the surface if it's in hardware */ + if ( surface->flags & (SDL_HWSURFACE|SDL_ASYNCBLIT) ) { + SDL_VideoDevice *video = current_video; + SDL_VideoDevice *this = current_video; + if ( video->LockHWSurface(this, surface) < 0 ) { + return(-1); + } + } + + /* Encode */ + if((surface->flags & SDL_SRCCOLORKEY) == SDL_SRCCOLORKEY) { + retcode = RLEColorkeySurface(surface); + } else { + if((surface->flags & SDL_SRCALPHA) == SDL_SRCALPHA + && surface->format->Amask != 0) + retcode = RLEAlphaSurface(surface); + else + retcode = -1; /* no RLE for per-surface alpha sans ckey */ + } + + /* Unlock the surface if it's in hardware */ + if ( surface->flags & (SDL_HWSURFACE|SDL_ASYNCBLIT) ) { + SDL_VideoDevice *video = current_video; + SDL_VideoDevice *this = current_video; + video->UnlockHWSurface(this, surface); + } + + if(retcode < 0) + return -1; + + /* The surface is now accelerated */ + surface->flags |= SDL_RLEACCEL; + + return(0); +} + +/* + * Un-RLE a surface with pixel alpha + * This may not give back exactly the image before RLE-encoding; all + * completely transparent pixels will be lost, and colour and alpha depth + * may have been reduced (when encoding for 16bpp targets). + */ +static void UnRLEAlpha(SDL_Surface *surface) +{ + Uint8 *srcbuf; + Uint32 *dst; + SDL_PixelFormat *sf = surface->format; + RLEDestFormat *df = surface->map->sw_data->aux_data; + int (*uncopy_opaque)(Uint32 *, void *, int, + RLEDestFormat *, SDL_PixelFormat *); + int (*uncopy_transl)(Uint32 *, void *, int, + RLEDestFormat *, SDL_PixelFormat *); + int w = surface->w; + int bpp = df->BytesPerPixel; + + if(bpp == 2) { + uncopy_opaque = uncopy_opaque_16; + uncopy_transl = uncopy_transl_16; + } else { + uncopy_opaque = uncopy_transl = uncopy_32; + } + + surface->pixels = malloc(surface->h * surface->pitch); + /* fill background with transparent pixels */ + memset(surface->pixels, 0, surface->h * surface->pitch); + + dst = surface->pixels; + srcbuf = (Uint8 *)(df + 1); + for(;;) { + /* copy opaque pixels */ + int ofs = 0; + do { + unsigned run; + if(bpp == 2) { + ofs += srcbuf[0]; + run = srcbuf[1]; + srcbuf += 2; + } else { + ofs += ((Uint16 *)srcbuf)[0]; + run = ((Uint16 *)srcbuf)[1]; + srcbuf += 4; + } + if(run) { + srcbuf += uncopy_opaque(dst + ofs, srcbuf, run, df, sf); + ofs += run; + } else if(!ofs) + return; + } while(ofs < w); + + /* skip padding if needed */ + if(bpp == 2) + srcbuf += (unsigned long)srcbuf & 2; + + /* copy translucent pixels */ + ofs = 0; + do { + unsigned run; + ofs += ((Uint16 *)srcbuf)[0]; + run = ((Uint16 *)srcbuf)[1]; + srcbuf += 4; + if(run) { + srcbuf += uncopy_transl(dst + ofs, srcbuf, run, df, sf); + ofs += run; + } + } while(ofs < w); + dst += surface->pitch >> 2; + } +} + +void SDL_UnRLESurface(SDL_Surface *surface, int recode) +{ + if ( (surface->flags & SDL_RLEACCEL) == SDL_RLEACCEL ) { + surface->flags &= ~SDL_RLEACCEL; + + if(recode && (surface->flags & SDL_PREALLOC) != SDL_PREALLOC + && (surface->flags & SDL_HWSURFACE) != SDL_HWSURFACE) { + if((surface->flags & SDL_SRCCOLORKEY) == SDL_SRCCOLORKEY) { + SDL_Rect full; + unsigned alpha_flag; + + /* re-create the original surface */ + surface->pixels = malloc(surface->h * surface->pitch); + + /* fill it with the background colour */ + SDL_FillRect(surface, NULL, surface->format->colorkey); + + /* now render the encoded surface */ + full.x = full.y = 0; + full.w = surface->w; + full.h = surface->h; + alpha_flag = surface->flags & SDL_SRCALPHA; + surface->flags &= ~SDL_SRCALPHA; /* opaque blit */ + SDL_RLEBlit(surface, &full, surface, &full); + surface->flags |= alpha_flag; + } else + UnRLEAlpha(surface); + } + + if ( surface->map && surface->map->sw_data->aux_data ) { + free(surface->map->sw_data->aux_data); + surface->map->sw_data->aux_data = NULL; + } + } +} + + diff --git a/contrib/sdk/sources/SDL-1.2.2/src/video/SDL_RLEaccel_c.h b/contrib/sdk/sources/SDL-1.2.2/src/video/SDL_RLEaccel_c.h new file mode 100644 index 000000000..bdf272706 --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/src/video/SDL_RLEaccel_c.h @@ -0,0 +1,35 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997, 1998, 1999, 2000, 2001 Sam Lantinga + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the Free + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + Sam Lantinga + slouken@devolution.com +*/ + +#ifdef SAVE_RCSID +static char rcsid = + "@(#) $Id: SDL_RLEaccel_c.h,v 1.2 2001/04/26 16:50:18 hercules Exp $"; +#endif + +/* Useful functions and variables from SDL_RLEaccel.c */ + +extern int SDL_RLESurface(SDL_Surface *surface); +extern int SDL_RLEBlit(SDL_Surface *src, SDL_Rect *srcrect, + SDL_Surface *dst, SDL_Rect *dstrect); +extern int SDL_RLEAlphaBlit(SDL_Surface *src, SDL_Rect *srcrect, + SDL_Surface *dst, SDL_Rect *dstrect); +extern void SDL_UnRLESurface(SDL_Surface *surface, int recode); diff --git a/contrib/sdk/sources/SDL-1.2.2/src/video/SDL_blit.c b/contrib/sdk/sources/SDL-1.2.2/src/video/SDL_blit.c new file mode 100644 index 000000000..14b797ef9 --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/src/video/SDL_blit.c @@ -0,0 +1,289 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997, 1998, 1999, 2000, 2001 Sam Lantinga + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the Free + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + Sam Lantinga + slouken@devolution.com +*/ + +#include +#include +#include + +#include "SDL_error.h" +#include "SDL_video.h" +#include "SDL_sysvideo.h" +#include "SDL_blit.h" +#include "SDL_RLEaccel_c.h" +#include "SDL_pixels_c.h" +#include "SDL_memops.h" + +/* The general purpose software blit routine */ +static int SDL_SoftBlit(SDL_Surface *src, SDL_Rect *srcrect, + SDL_Surface *dst, SDL_Rect *dstrect) +{ + int okay; + int src_locked; + int dst_locked; + + /* Everything is okay at the beginning... */ + okay = 1; + + /* Lock the destination if it's in hardware */ + dst_locked = 0; + if ( dst->flags & (SDL_HWSURFACE|SDL_ASYNCBLIT) ) { + SDL_VideoDevice *video = current_video; + SDL_VideoDevice *this = current_video; + if ( video->LockHWSurface(this, dst) < 0 ) { + okay = 0; + } else { + dst_locked = 1; + } + } + /* Lock the source if it's in hardware */ + src_locked = 0; + if ( src->flags & (SDL_HWSURFACE|SDL_ASYNCBLIT) ) { + SDL_VideoDevice *video = current_video; + SDL_VideoDevice *this = current_video; + if ( video->LockHWSurface(this, src) < 0 ) { + okay = 0; + } else { + src_locked = 1; + } + } + + /* Unencode the destination if it's RLE encoded */ + if ( dst->flags & SDL_RLEACCEL ) { + SDL_UnRLESurface(dst, 1); + dst->flags |= SDL_RLEACCEL; /* save accel'd state */ + } + + /* Set up source and destination buffer pointers, and BLIT! */ + if ( okay && srcrect->w && srcrect->h ) { + SDL_BlitInfo info; + SDL_loblit RunBlit; + + /* Set up the blit information */ + info.s_pixels = (Uint8 *)src->pixels + src->offset + + (Uint16)srcrect->y*src->pitch + + (Uint16)srcrect->x*src->format->BytesPerPixel; + info.s_width = srcrect->w; + info.s_height = srcrect->h; + info.s_skip=src->pitch-info.s_width*src->format->BytesPerPixel; + info.d_pixels = (Uint8 *)dst->pixels + dst->offset + + (Uint16)dstrect->y*dst->pitch + + (Uint16)dstrect->x*dst->format->BytesPerPixel; + info.d_width = dstrect->w; + info.d_height = dstrect->h; + info.d_skip=dst->pitch-info.d_width*dst->format->BytesPerPixel; + info.aux_data = src->map->sw_data->aux_data; + info.src = src->format; + info.table = src->map->table; + info.dst = dst->format; + RunBlit = src->map->sw_data->blit; + + /* Run the actual software blit */ + RunBlit(&info); + } + + /* Re-encode the destination if it's RLE encoded */ + if ( dst->flags & SDL_RLEACCEL ) { + dst->flags &= ~SDL_RLEACCEL; /* stop lying */ + SDL_RLESurface(dst); + } + + /* We need to unlock the surfaces if they're locked */ + if ( dst_locked ) { + SDL_VideoDevice *video = current_video; + SDL_VideoDevice *this = current_video; + video->UnlockHWSurface(this, dst); + } else + if ( src_locked ) { + SDL_VideoDevice *video = current_video; + SDL_VideoDevice *this = current_video; + video->UnlockHWSurface(this, src); + } + /* Blit is done! */ + return(okay ? 0 : -1); +} + +static void SDL_BlitCopy(SDL_BlitInfo *info) +{ + Uint8 *src, *dst; + int w, h; + int srcskip, dstskip; + + w = info->d_width*info->dst->BytesPerPixel; + h = info->d_height; + src = info->s_pixels; + dst = info->d_pixels; + srcskip = w+info->s_skip; + dstskip = w+info->d_skip; + while ( h-- ) { + SDL_memcpy(dst, src, w); + src += srcskip; + dst += dstskip; + } +} + +static void SDL_BlitCopyOverlap(SDL_BlitInfo *info) +{ + Uint8 *src, *dst; + int w, h; + int srcskip, dstskip; + + w = info->d_width*info->dst->BytesPerPixel; + h = info->d_height; + src = info->s_pixels; + dst = info->d_pixels; + srcskip = w+info->s_skip; + dstskip = w+info->d_skip; + if ( dst < src ) { + while ( h-- ) { + SDL_memcpy(dst, src, w); + src += srcskip; + dst += dstskip; + } + } else { + src += ((h-1) * srcskip); + dst += ((h-1) * dstskip); + while ( h-- ) { + SDL_revcpy(dst, src, w); + src -= srcskip; + dst -= dstskip; + } + } +} + +/* Figure out which of many blit routines to set up on a surface */ +int SDL_CalculateBlit(SDL_Surface *surface) +{ + int blit_index; + + /* Clean everything out to start */ + if ( (surface->flags & SDL_RLEACCEL) == SDL_RLEACCEL ) { + SDL_UnRLESurface(surface, 1); + } + surface->map->sw_blit = NULL; + + /* Figure out if an accelerated hardware blit is possible */ + surface->flags &= ~SDL_HWACCEL; + if ( surface->map->identity ) { + int hw_blit_ok; + + if ( (surface->flags & SDL_HWSURFACE) == SDL_HWSURFACE ) { + /* We only support accelerated blitting to hardware */ + if ( surface->map->dst->flags & SDL_HWSURFACE ) { + hw_blit_ok = current_video->info.blit_hw; + } else { + hw_blit_ok = 0; + } + if (hw_blit_ok && (surface->flags & SDL_SRCCOLORKEY)) { + hw_blit_ok = current_video->info.blit_hw_CC; + } + if ( hw_blit_ok && (surface->flags & SDL_SRCALPHA) ) { + hw_blit_ok = current_video->info.blit_hw_A; + } + } else { + /* We only support accelerated blitting to hardware */ + if ( surface->map->dst->flags & SDL_HWSURFACE ) { + hw_blit_ok = current_video->info.blit_sw; + } else { + hw_blit_ok = 0; + } + if (hw_blit_ok && (surface->flags & SDL_SRCCOLORKEY)) { + hw_blit_ok = current_video->info.blit_sw_CC; + } + if ( hw_blit_ok && (surface->flags & SDL_SRCALPHA) ) { + hw_blit_ok = current_video->info.blit_sw_A; + } + } + if ( hw_blit_ok ) { + SDL_VideoDevice *video = current_video; + SDL_VideoDevice *this = current_video; + video->CheckHWBlit(this, surface, surface->map->dst); + } + } + + /* Get the blit function index, based on surface mode */ + /* { 0 = nothing, 1 = colorkey, 2 = alpha, 3 = colorkey+alpha } */ + blit_index = 0; + blit_index |= (!!(surface->flags & SDL_SRCCOLORKEY)) << 0; + if ( surface->flags & SDL_SRCALPHA + && (surface->format->alpha != SDL_ALPHA_OPAQUE + || surface->format->Amask) ) { + blit_index |= 2; + } + + /* Check for special "identity" case -- copy blit */ + if ( surface->map->identity && blit_index == 0 ) { + surface->map->sw_data->blit = SDL_BlitCopy; + + /* Handle overlapping blits on the same surface */ + if ( surface == surface->map->dst ) { + surface->map->sw_data->blit = SDL_BlitCopyOverlap; + } + } else { + if ( surface->format->BitsPerPixel < 8 ) { + surface->map->sw_data->blit = + SDL_CalculateBlit0(surface, blit_index); + } else { + switch ( surface->format->BytesPerPixel ) { + case 1: + surface->map->sw_data->blit = + SDL_CalculateBlit1(surface, blit_index); + break; + case 2: + case 3: + case 4: + surface->map->sw_data->blit = + SDL_CalculateBlitN(surface, blit_index); + break; + default: + surface->map->sw_data->blit = NULL; + break; + } + } + } + /* Make sure we have a blit function */ + if ( surface->map->sw_data->blit == NULL ) { + SDL_InvalidateMap(surface->map); + SDL_SetError("Blit combination not supported"); + return(-1); + } + + /* Choose software blitting function */ + if(surface->flags & SDL_RLEACCELOK + && (surface->flags & SDL_HWACCEL) != SDL_HWACCEL) { + + if(surface->map->identity + && (blit_index == 1 + || (blit_index == 3 && !surface->format->Amask))) { + if ( SDL_RLESurface(surface) == 0 ) + surface->map->sw_blit = SDL_RLEBlit; + } else if(blit_index == 2 && surface->format->Amask) { + if ( SDL_RLESurface(surface) == 0 ) + surface->map->sw_blit = SDL_RLEAlphaBlit; + } + } + + if ( surface->map->sw_blit == NULL ) { + surface->map->sw_blit = SDL_SoftBlit; + } + return(0); +} + diff --git a/contrib/sdk/sources/SDL-1.2.2/src/video/SDL_blit.h b/contrib/sdk/sources/SDL-1.2.2/src/video/SDL_blit.h new file mode 100644 index 000000000..261baedb1 --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/src/video/SDL_blit.h @@ -0,0 +1,437 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997, 1998, 1999, 2000, 2001 Sam Lantinga + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the Free + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + Sam Lantinga + slouken@devolution.com +*/ + +#ifdef SAVE_RCSID +static char rcsid = + "@(#) $Id: SDL_blit.h,v 1.3 2001/07/07 20:20:16 hercules Exp $"; +#endif + +#ifndef _SDL_blit_h +#define _SDL_blit_h + +#include "SDL_endian.h" + +/* The structure passed to the low level blit functions */ +typedef struct { + Uint8 *s_pixels; + int s_width; + int s_height; + int s_skip; + Uint8 *d_pixels; + int d_width; + int d_height; + int d_skip; + void *aux_data; + SDL_PixelFormat *src; + Uint8 *table; + SDL_PixelFormat *dst; +} SDL_BlitInfo; + +/* The type definition for the low level blit functions */ +typedef void (*SDL_loblit)(SDL_BlitInfo *info); + +/* This is the private info structure for software accelerated blits */ +struct private_swaccel { + SDL_loblit blit; + void *aux_data; +}; + +/* Blit mapping definition */ +typedef struct SDL_BlitMap { + SDL_Surface *dst; + int identity; + Uint8 *table; + SDL_blit hw_blit; + SDL_blit sw_blit; + struct private_hwaccel *hw_data; + struct private_swaccel *sw_data; + + /* the version count matches the destination; mismatch indicates + an invalid mapping */ + unsigned int format_version; +} SDL_BlitMap; + + +/* Definitions for special global blit functions */ +#include "SDL_blit_A.h" + +/* Functions found in SDL_blit.c */ +extern int SDL_CalculateBlit(SDL_Surface *surface); + +/* Functions found in SDL_blit_{0,1,N,A}.c */ +extern SDL_loblit SDL_CalculateBlit0(SDL_Surface *surface, int complex); +extern SDL_loblit SDL_CalculateBlit1(SDL_Surface *surface, int complex); +extern SDL_loblit SDL_CalculateBlitN(SDL_Surface *surface, int complex); +extern SDL_loblit SDL_CalculateAlphaBlit(SDL_Surface *surface, int complex); + +/* + * Useful macros for blitting routines + */ + +#define FORMAT_EQUAL(A, B) \ + ((A)->BitsPerPixel == (B)->BitsPerPixel \ + && ((A)->Rmask == (B)->Rmask) && ((A)->Amask == (B)->Amask)) + +/* Load pixel of the specified format from a buffer and get its R-G-B values */ +/* FIXME: rescale values to 0..255 here? */ +#define RGB_FROM_PIXEL(pixel, fmt, r, g, b) \ +{ \ + r = (((pixel&fmt->Rmask)>>fmt->Rshift)<Rloss); \ + g = (((pixel&fmt->Gmask)>>fmt->Gshift)<Gloss); \ + b = (((pixel&fmt->Bmask)>>fmt->Bshift)<Bloss); \ +} +#define RGB_FROM_RGB565(pixel, r, g, b) \ +{ \ + r = (((pixel&0xF800)>>11)<<3); \ + g = (((pixel&0x07E0)>>5)<<2); \ + b = ((pixel&0x001F)<<3); \ +} +#define RGB_FROM_RGB555(pixel, r, g, b) \ +{ \ + r = (((pixel&0x7C00)>>10)<<3); \ + g = (((pixel&0x03E0)>>5)<<3); \ + b = ((pixel&0x001F)<<3); \ +} +#define RGB_FROM_RGB888(pixel, r, g, b) \ +{ \ + r = ((pixel&0xFF0000)>>16); \ + g = ((pixel&0xFF00)>>8); \ + b = (pixel&0xFF); \ +} +#define RETRIEVE_RGB_PIXEL(buf, bpp, pixel) \ +do { \ + switch (bpp) { \ + case 2: \ + pixel = *((Uint16 *)(buf)); \ + break; \ + \ + case 3: { \ + Uint8 *B = (Uint8 *)(buf); \ + if(SDL_BYTEORDER == SDL_LIL_ENDIAN) { \ + pixel = B[0] + (B[1] << 8) + (B[2] << 16); \ + } else { \ + pixel = (B[0] << 16) + (B[1] << 8) + B[2]; \ + } \ + } \ + break; \ + \ + case 4: \ + pixel = *((Uint32 *)(buf)); \ + break; \ + \ + default: \ + pixel = 0; /* appease gcc */ \ + break; \ + } \ +} while(0) + +#define DISEMBLE_RGB(buf, bpp, fmt, pixel, r, g, b) \ +do { \ + switch (bpp) { \ + case 2: \ + pixel = *((Uint16 *)(buf)); \ + break; \ + \ + case 3: { \ + Uint8 *B = (Uint8 *)buf; \ + if(SDL_BYTEORDER == SDL_LIL_ENDIAN) { \ + pixel = B[0] + (B[1] << 8) + (B[2] << 16); \ + } else { \ + pixel = (B[0] << 16) + (B[1] << 8) + B[2]; \ + } \ + } \ + break; \ + \ + case 4: \ + pixel = *((Uint32 *)(buf)); \ + break; \ + \ + default: \ + pixel = 0; /* prevent gcc from complaining */ \ + break; \ + } \ + RGB_FROM_PIXEL(pixel, fmt, r, g, b); \ +} while(0) + +/* Assemble R-G-B values into a specified pixel format and store them */ +#define PIXEL_FROM_RGB(pixel, fmt, r, g, b) \ +{ \ + pixel = ((r>>fmt->Rloss)<Rshift)| \ + ((g>>fmt->Gloss)<Gshift)| \ + ((b>>fmt->Bloss)<Bshift); \ +} +#define RGB565_FROM_RGB(pixel, r, g, b) \ +{ \ + pixel = ((r>>3)<<11)|((g>>2)<<5)|(b>>3); \ +} +#define RGB555_FROM_RGB(pixel, r, g, b) \ +{ \ + pixel = ((r>>3)<<10)|((g>>3)<<5)|(b>>3); \ +} +#define RGB888_FROM_RGB(pixel, r, g, b) \ +{ \ + pixel = (r<<16)|(g<<8)|b; \ +} +#define ASSEMBLE_RGB(buf, bpp, fmt, r, g, b) \ +{ \ + switch (bpp) { \ + case 2: { \ + Uint16 pixel; \ + \ + PIXEL_FROM_RGB(pixel, fmt, r, g, b); \ + *((Uint16 *)(buf)) = pixel; \ + } \ + break; \ + \ + case 3: { \ + if(SDL_BYTEORDER == SDL_LIL_ENDIAN) { \ + *((buf)+fmt->Rshift/8) = r; \ + *((buf)+fmt->Gshift/8) = g; \ + *((buf)+fmt->Bshift/8) = b; \ + } else { \ + *((buf)+2-fmt->Rshift/8) = r; \ + *((buf)+2-fmt->Gshift/8) = g; \ + *((buf)+2-fmt->Bshift/8) = b; \ + } \ + } \ + break; \ + \ + case 4: { \ + Uint32 pixel; \ + \ + PIXEL_FROM_RGB(pixel, fmt, r, g, b); \ + *((Uint32 *)(buf)) = pixel; \ + } \ + break; \ + } \ +} +#define ASSEMBLE_RGB_AMASK(buf, bpp, fmt, r, g, b, Amask) \ +{ \ + switch (bpp) { \ + case 2: { \ + Uint16 *bufp; \ + Uint16 pixel; \ + \ + bufp = (Uint16 *)buf; \ + PIXEL_FROM_RGB(pixel, fmt, r, g, b); \ + *bufp = pixel | (*bufp & Amask); \ + } \ + break; \ + \ + case 3: { \ + if(SDL_BYTEORDER == SDL_LIL_ENDIAN) { \ + *((buf)+fmt->Rshift/8) = r; \ + *((buf)+fmt->Gshift/8) = g; \ + *((buf)+fmt->Bshift/8) = b; \ + } else { \ + *((buf)+2-fmt->Rshift/8) = r; \ + *((buf)+2-fmt->Gshift/8) = g; \ + *((buf)+2-fmt->Bshift/8) = b; \ + } \ + } \ + break; \ + \ + case 4: { \ + Uint32 *bufp; \ + Uint32 pixel; \ + \ + bufp = (Uint32 *)buf; \ + PIXEL_FROM_RGB(pixel, fmt, r, g, b); \ + *bufp = pixel | (*bufp & Amask); \ + } \ + break; \ + } \ +} + +/* FIXME: Should we rescale alpha into 0..255 here? */ +#define RGBA_FROM_PIXEL(pixel, fmt, r, g, b, a) \ +{ \ + r = ((pixel&fmt->Rmask)>>fmt->Rshift)<Rloss; \ + g = ((pixel&fmt->Gmask)>>fmt->Gshift)<Gloss; \ + b = ((pixel&fmt->Bmask)>>fmt->Bshift)<Bloss; \ + a = ((pixel&fmt->Amask)>>fmt->Ashift)<Aloss; \ +} +#define RGBA_FROM_8888(pixel, fmt, r, g, b, a) \ +{ \ + r = (pixel&fmt->Rmask)>>fmt->Rshift; \ + g = (pixel&fmt->Gmask)>>fmt->Gshift; \ + b = (pixel&fmt->Bmask)>>fmt->Bshift; \ + a = (pixel&fmt->Amask)>>fmt->Ashift; \ +} +#define RGBA_FROM_RGBA8888(pixel, r, g, b, a) \ +{ \ + r = (pixel>>24); \ + g = ((pixel>>16)&0xFF); \ + b = ((pixel>>8)&0xFF); \ + a = (pixel&0xFF); \ +} +#define RGBA_FROM_ARGB8888(pixel, r, g, b, a) \ +{ \ + r = ((pixel>>16)&0xFF); \ + g = ((pixel>>8)&0xFF); \ + b = (pixel&0xFF); \ + a = (pixel>>24); \ +} +#define RGBA_FROM_ABGR8888(pixel, r, g, b, a) \ +{ \ + r = (pixel&0xFF); \ + g = ((pixel>>8)&0xFF); \ + b = ((pixel>>16)&0xFF); \ + a = (pixel>>24); \ +} +#define DISEMBLE_RGBA(buf, bpp, fmt, pixel, r, g, b, a) \ +do { \ + switch (bpp) { \ + case 2: \ + pixel = *((Uint16 *)(buf)); \ + break; \ + \ + case 3: {/* FIXME: broken code (no alpha) */ \ + Uint8 *b = (Uint8 *)buf; \ + if(SDL_BYTEORDER == SDL_LIL_ENDIAN) { \ + pixel = b[0] + (b[1] << 8) + (b[2] << 16); \ + } else { \ + pixel = (b[0] << 16) + (b[1] << 8) + b[2]; \ + } \ + } \ + break; \ + \ + case 4: \ + pixel = *((Uint32 *)(buf)); \ + break; \ + \ + default: \ + pixel = 0; /* stop gcc complaints */ \ + break; \ + } \ + RGBA_FROM_PIXEL(pixel, fmt, r, g, b, a); \ + pixel &= ~fmt->Amask; \ +} while(0) + +/* FIXME: this isn't correct, especially for Alpha (maximum != 255) */ +#define PIXEL_FROM_RGBA(pixel, fmt, r, g, b, a) \ +{ \ + pixel = ((r>>fmt->Rloss)<Rshift)| \ + ((g>>fmt->Gloss)<Gshift)| \ + ((b>>fmt->Bloss)<Bshift)| \ + ((a<Aloss)<Ashift); \ +} +#define ASSEMBLE_RGBA(buf, bpp, fmt, r, g, b, a) \ +{ \ + switch (bpp) { \ + case 2: { \ + Uint16 pixel; \ + \ + PIXEL_FROM_RGBA(pixel, fmt, r, g, b, a); \ + *((Uint16 *)(buf)) = pixel; \ + } \ + break; \ + \ + case 3: { /* FIXME: broken code (no alpha) */ \ + if(SDL_BYTEORDER == SDL_LIL_ENDIAN) { \ + *((buf)+fmt->Rshift/8) = r; \ + *((buf)+fmt->Gshift/8) = g; \ + *((buf)+fmt->Bshift/8) = b; \ + } else { \ + *((buf)+2-fmt->Rshift/8) = r; \ + *((buf)+2-fmt->Gshift/8) = g; \ + *((buf)+2-fmt->Bshift/8) = b; \ + } \ + } \ + break; \ + \ + case 4: { \ + Uint32 pixel; \ + \ + PIXEL_FROM_RGBA(pixel, fmt, r, g, b, a); \ + *((Uint32 *)(buf)) = pixel; \ + } \ + break; \ + } \ +} + +/* Blend the RGB values of two pixels based on a source alpha value */ +#define ALPHA_BLEND(sR, sG, sB, A, dR, dG, dB) \ +do { \ + dR = (((sR-dR)*(A))>>8)+dR; \ + dG = (((sG-dG)*(A))>>8)+dG; \ + dB = (((sB-dB)*(A))>>8)+dB; \ +} while(0) + +/* This is a very useful loop for optimizing blitters */ +#define USE_DUFFS_LOOP +#ifdef USE_DUFFS_LOOP + +/* 8-times unrolled loop */ +#define DUFFS_LOOP8(pixel_copy_increment, width) \ +{ int n = (width+7)/8; \ + switch (width & 7) { \ + case 0: do { pixel_copy_increment; \ + case 7: pixel_copy_increment; \ + case 6: pixel_copy_increment; \ + case 5: pixel_copy_increment; \ + case 4: pixel_copy_increment; \ + case 3: pixel_copy_increment; \ + case 2: pixel_copy_increment; \ + case 1: pixel_copy_increment; \ + } while ( --n > 0 ); \ + } \ +} + +/* 4-times unrolled loop */ +#define DUFFS_LOOP4(pixel_copy_increment, width) \ +{ int n = (width+3)/4; \ + switch (width & 3) { \ + case 0: do { pixel_copy_increment; \ + case 3: pixel_copy_increment; \ + case 2: pixel_copy_increment; \ + case 1: pixel_copy_increment; \ + } while ( --n > 0 ); \ + } \ +} + +/* Use the 8-times version of the loop by default */ +#define DUFFS_LOOP(pixel_copy_increment, width) \ + DUFFS_LOOP8(pixel_copy_increment, width) + +#else + +/* Don't use Duff's device to unroll loops */ +#define DUFFS_LOOP(pixel_copy_increment, width) \ +{ int n; \ + for ( n=width; n > 0; --n ) { \ + pixel_copy_increment; \ + } \ +} +#define DUFFS_LOOP8(pixel_copy_increment, width) \ + DUFFS_LOOP(pixel_copy_increment, width) +#define DUFFS_LOOP4(pixel_copy_increment, width) \ + DUFFS_LOOP(pixel_copy_increment, width) + +#endif /* USE_DUFFS_LOOP */ + +/* Prevent Visual C++ 6.0 from printing out stupid warnings */ +#if defined(_MSC_VER) && (_MSC_VER >= 600) +#pragma warning(disable: 4550) +#endif + +#endif /* _SDL_blit_h */ diff --git a/contrib/sdk/sources/SDL-1.2.2/src/video/SDL_blit_0.c b/contrib/sdk/sources/SDL-1.2.2/src/video/SDL_blit_0.c new file mode 100644 index 000000000..f9877dd75 --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/src/video/SDL_blit_0.c @@ -0,0 +1,471 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997, 1998, 1999, 2000, 2001 Sam Lantinga + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the Free + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + Sam Lantinga + slouken@devolution.com +*/ + + +#include +#include + +#include "SDL_types.h" +#include "SDL_video.h" +#include "SDL_blit.h" + +/* Functions to blit from bitmaps to other surfaces */ + +static void BlitBto1(SDL_BlitInfo *info) +{ + int c; + int width, height; + Uint8 *src, *map, *dst; + int srcskip, dstskip; + + /* Set up some basic variables */ + width = info->d_width; + height = info->d_height; + src = info->s_pixels; + srcskip = info->s_skip; + dst = info->d_pixels; + dstskip = info->d_skip; + map = info->table; + srcskip += width-(width+7)/8; + + if ( map ) { + while ( height-- ) { + Uint8 byte = 0, bit; + for ( c=0; c>7; + if ( 1 ) { + *dst = map[bit]; + } + dst++; + byte <<= 1; + } + src += srcskip; + dst += dstskip; + } + } else { + while ( height-- ) { + Uint8 byte = 0, bit; + for ( c=0; c>7; + if ( 1 ) { + *dst = bit; + } + dst++; + byte <<= 1; + } + src += srcskip; + dst += dstskip; + } + } +} +static void BlitBto2(SDL_BlitInfo *info) +{ + int c; + int width, height; + Uint8 *src; + Uint16 *map, *dst; + int srcskip, dstskip; + + /* Set up some basic variables */ + width = info->d_width; + height = info->d_height; + src = info->s_pixels; + srcskip = info->s_skip; + dst = (Uint16 *)info->d_pixels; + dstskip = info->d_skip/2; + map = (Uint16 *)info->table; + srcskip += width-(width+7)/8; + + while ( height-- ) { + Uint8 byte = 0, bit; + for ( c=0; c>7; + if ( 1 ) { + *dst = map[bit]; + } + byte <<= 1; + dst++; + } + src += srcskip; + dst += dstskip; + } +} +static void BlitBto3(SDL_BlitInfo *info) +{ + int c, o; + int width, height; + Uint8 *src, *map, *dst; + int srcskip, dstskip; + + /* Set up some basic variables */ + width = info->d_width; + height = info->d_height; + src = info->s_pixels; + srcskip = info->s_skip; + dst = info->d_pixels; + dstskip = info->d_skip; + map = info->table; + srcskip += width-(width+7)/8; + + while ( height-- ) { + Uint8 byte = 0, bit; + for ( c=0; c>7; + if ( 1 ) { + o = bit * 4; + dst[0] = map[o++]; + dst[1] = map[o++]; + dst[2] = map[o++]; + } + byte <<= 1; + dst += 3; + } + src += srcskip; + dst += dstskip; + } +} +static void BlitBto4(SDL_BlitInfo *info) +{ + int width, height; + Uint8 *src; + Uint32 *map, *dst; + int srcskip, dstskip; + int c; + + /* Set up some basic variables */ + width = info->d_width; + height = info->d_height; + src = info->s_pixels; + srcskip = info->s_skip; + dst = (Uint32 *)info->d_pixels; + dstskip = info->d_skip/4; + map = (Uint32 *)info->table; + srcskip += width-(width+7)/8; + + while ( height-- ) { + Uint8 byte = 0, bit; + for ( c=0; c>7; + if ( 1 ) { + *dst = map[bit]; + } + byte <<= 1; + dst++; + } + src += srcskip; + dst += dstskip; + } +} + +static void BlitBto1Key(SDL_BlitInfo *info) +{ + int width = info->d_width; + int height = info->d_height; + Uint8 *src = info->s_pixels; + Uint8 *dst = info->d_pixels; + int srcskip = info->s_skip; + int dstskip = info->d_skip; + Uint32 ckey = info->src->colorkey; + Uint8 *palmap = info->table; + int c; + + /* Set up some basic variables */ + srcskip += width-(width+7)/8; + + if ( palmap ) { + while ( height-- ) { + Uint8 byte = 0, bit; + for ( c=0; c>7; + if ( bit != ckey ) { + *dst = palmap[bit]; + } + dst++; + byte <<= 1; + } + src += srcskip; + dst += dstskip; + } + } else { + while ( height-- ) { + Uint8 byte = 0, bit; + for ( c=0; c>7; + if ( bit != ckey ) { + *dst = bit; + } + dst++; + byte <<= 1; + } + src += srcskip; + dst += dstskip; + } + } +} + +static void BlitBto2Key(SDL_BlitInfo *info) +{ + int width = info->d_width; + int height = info->d_height; + Uint8 *src = info->s_pixels; + Uint16 *dstp = (Uint16 *)info->d_pixels; + int srcskip = info->s_skip; + int dstskip = info->d_skip; + Uint32 ckey = info->src->colorkey; + Uint8 *palmap = info->table; + int c; + + /* Set up some basic variables */ + srcskip += width-(width+7)/8; + dstskip /= 2; + + while ( height-- ) { + Uint8 byte = 0, bit; + for ( c=0; c>7; + if ( bit != ckey ) { + *dstp=((Uint16 *)palmap)[bit]; + } + byte <<= 1; + dstp++; + } + src += srcskip; + dstp += dstskip; + } +} + +static void BlitBto3Key(SDL_BlitInfo *info) +{ + int width = info->d_width; + int height = info->d_height; + Uint8 *src = info->s_pixels; + Uint8 *dst = info->d_pixels; + int srcskip = info->s_skip; + int dstskip = info->d_skip; + Uint32 ckey = info->src->colorkey; + Uint8 *palmap = info->table; + int c; + + /* Set up some basic variables */ + srcskip += width-(width+7)/8; + + while ( height-- ) { + Uint8 byte = 0, bit; + for ( c=0; c>7; + if ( bit != ckey ) { + memcpy(dst, &palmap[bit*4], 3); + } + byte <<= 1; + dst += 3; + } + src += srcskip; + dst += dstskip; + } +} + +static void BlitBto4Key(SDL_BlitInfo *info) +{ + int width = info->d_width; + int height = info->d_height; + Uint8 *src = info->s_pixels; + Uint32 *dstp = (Uint32 *)info->d_pixels; + int srcskip = info->s_skip; + int dstskip = info->d_skip; + Uint32 ckey = info->src->colorkey; + Uint8 *palmap = info->table; + int c; + + /* Set up some basic variables */ + srcskip += width-(width+7)/8; + dstskip /= 4; + + while ( height-- ) { + Uint8 byte = 0, bit; + for ( c=0; c>7; + if ( bit != ckey ) { + *dstp=((Uint32 *)palmap)[bit]; + } + byte <<= 1; + dstp++; + } + src += srcskip; + dstp += dstskip; + } +} + +static void BlitBtoNAlpha(SDL_BlitInfo *info) +{ + int width = info->d_width; + int height = info->d_height; + Uint8 *src = info->s_pixels; + Uint8 *dst = info->d_pixels; + int srcskip = info->s_skip; + int dstskip = info->d_skip; + const SDL_Color *srcpal = info->src->palette->colors; + SDL_PixelFormat *dstfmt = info->dst; + int dstbpp; + int c; + const int A = info->src->alpha; + + /* Set up some basic variables */ + dstbpp = dstfmt->BytesPerPixel; + srcskip += width-(width+7)/8; + + while ( height-- ) { + Uint8 byte = 0, bit; + for ( c=0; c>7; + if ( 1 ) { + Uint32 pixel; + unsigned sR, sG, sB; + unsigned dR, dG, dB; + sR = srcpal[bit].r; + sG = srcpal[bit].g; + sB = srcpal[bit].b; + DISEMBLE_RGB(dst, dstbpp, dstfmt, + pixel, dR, dG, dB); + ALPHA_BLEND(sR, sG, sB, A, dR, dG, dB); + ASSEMBLE_RGB(dst, dstbpp, dstfmt, dR, dG, dB); + } + byte <<= 1; + dst += dstbpp; + } + src += srcskip; + dst += dstskip; + } +} + +static void BlitBtoNAlphaKey(SDL_BlitInfo *info) +{ + int width = info->d_width; + int height = info->d_height; + Uint8 *src = info->s_pixels; + Uint8 *dst = info->d_pixels; + int srcskip = info->s_skip; + int dstskip = info->d_skip; + SDL_PixelFormat *srcfmt = info->src; + SDL_PixelFormat *dstfmt = info->dst; + const SDL_Color *srcpal = srcfmt->palette->colors; + int dstbpp; + int c; + const int A = srcfmt->alpha; + Uint32 ckey = srcfmt->colorkey; + + /* Set up some basic variables */ + dstbpp = dstfmt->BytesPerPixel; + srcskip += width-(width+7)/8; + + while ( height-- ) { + Uint8 byte = 0, bit; + for ( c=0; c>7; + if ( bit != ckey ) { + int sR, sG, sB; + int dR, dG, dB; + Uint32 pixel; + sR = srcpal[bit].r; + sG = srcpal[bit].g; + sB = srcpal[bit].b; + DISEMBLE_RGB(dst, dstbpp, dstfmt, + pixel, dR, dG, dB); + ALPHA_BLEND(sR, sG, sB, A, dR, dG, dB); + ASSEMBLE_RGB(dst, dstbpp, dstfmt, dR, dG, dB); + } + byte <<= 1; + dst += dstbpp; + } + src += srcskip; + dst += dstskip; + } +} + +static SDL_loblit bitmap_blit[] = { + NULL, BlitBto1, BlitBto2, BlitBto3, BlitBto4 +}; + +static SDL_loblit colorkey_blit[] = { + NULL, BlitBto1Key, BlitBto2Key, BlitBto3Key, BlitBto4Key +}; + +SDL_loblit SDL_CalculateBlit0(SDL_Surface *surface, int blit_index) +{ + int which; + + if ( surface->map->dst->format->BitsPerPixel < 8 ) { + which = 0; + } else { + which = surface->map->dst->format->BytesPerPixel; + } + switch(blit_index) { + case 0: /* copy */ + return bitmap_blit[which]; + + case 1: /* colorkey */ + return colorkey_blit[which]; + + case 2: /* alpha */ + return which >= 2 ? BlitBtoNAlpha : NULL; + + case 4: /* alpha + colorkey */ + return which >= 2 ? BlitBtoNAlphaKey : NULL; + } + return NULL; +} + diff --git a/contrib/sdk/sources/SDL-1.2.2/src/video/SDL_blit_1.c b/contrib/sdk/sources/SDL-1.2.2/src/video/SDL_blit_1.c new file mode 100644 index 000000000..870b85ed6 --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/src/video/SDL_blit_1.c @@ -0,0 +1,526 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997, 1998, 1999, 2000, 2001 Sam Lantinga + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the Free + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + Sam Lantinga + slouken@devolution.com +*/ + + +#include + +#include "SDL_types.h" +#include "SDL_video.h" +#include "SDL_blit.h" +#include "SDL_sysvideo.h" +#include "SDL_endian.h" + +/* Functions to blit from 8-bit surfaces to other surfaces */ + +static void Blit1to1(SDL_BlitInfo *info) +{ +#ifndef USE_DUFFS_LOOP + int c; +#endif + int width, height; + Uint8 *src, *map, *dst; + int srcskip, dstskip; + + /* Set up some basic variables */ + width = info->d_width; + height = info->d_height; + src = info->s_pixels; + srcskip = info->s_skip; + dst = info->d_pixels; + dstskip = info->d_skip; + map = info->table; + + while ( height-- ) { +#ifdef USE_DUFFS_LOOP + DUFFS_LOOP( + { + *dst = map[*src]; + } + dst++; + src++; + , width); +#else + for ( c=width; c; --c ) { + *dst = map[*src]; + dst++; + src++; + } +#endif + src += srcskip; + dst += dstskip; + } +} +/* This is now endian dependent */ +#if ( SDL_BYTEORDER == SDL_LIL_ENDIAN ) +#define HI 1 +#define LO 0 +#else /* ( SDL_BYTEORDER == SDL_BIG_ENDIAN ) */ +#define HI 0 +#define LO 1 +#endif +static void Blit1to2(SDL_BlitInfo *info) +{ +#ifndef USE_DUFFS_LOOP + int c; +#endif + int width, height; + Uint8 *src, *dst; + Uint16 *map; + int srcskip, dstskip; + + /* Set up some basic variables */ + width = info->d_width; + height = info->d_height; + src = info->s_pixels; + srcskip = info->s_skip; + dst = info->d_pixels; + dstskip = info->d_skip; + map = (Uint16 *)info->table; + +#ifdef USE_DUFFS_LOOP + while ( height-- ) { + DUFFS_LOOP( + { + *(Uint16 *)dst = map[*src++]; + dst += 2; + }, + width); + src += srcskip; + dst += dstskip; + } +#else + /* Memory align at 4-byte boundary, if necessary */ + if ( (long)dst & 0x03 ) { + /* Don't do anything if width is 0 */ + if ( width == 0 ) { + return; + } + --width; + + while ( height-- ) { + /* Perform copy alignment */ + *(Uint16 *)dst = map[*src++]; + dst += 2; + + /* Copy in 4 pixel chunks */ + for ( c=width/4; c; --c ) { + *(Uint32 *)dst = + (map[src[HI]]<<16)|(map[src[LO]]); + src += 2; + dst += 4; + *(Uint32 *)dst = + (map[src[HI]]<<16)|(map[src[LO]]); + src += 2; + dst += 4; + } + /* Get any leftovers */ + switch (width & 3) { + case 3: + *(Uint16 *)dst = map[*src++]; + dst += 2; + case 2: + *(Uint32 *)dst = + (map[src[HI]]<<16)|(map[src[LO]]); + src += 2; + dst += 4; + break; + case 1: + *(Uint16 *)dst = map[*src++]; + dst += 2; + break; + } + src += srcskip; + dst += dstskip; + } + } else { + while ( height-- ) { + /* Copy in 4 pixel chunks */ + for ( c=width/4; c; --c ) { + *(Uint32 *)dst = + (map[src[HI]]<<16)|(map[src[LO]]); + src += 2; + dst += 4; + *(Uint32 *)dst = + (map[src[HI]]<<16)|(map[src[LO]]); + src += 2; + dst += 4; + } + /* Get any leftovers */ + switch (width & 3) { + case 3: + *(Uint16 *)dst = map[*src++]; + dst += 2; + case 2: + *(Uint32 *)dst = + (map[src[HI]]<<16)|(map[src[LO]]); + src += 2; + dst += 4; + break; + case 1: + *(Uint16 *)dst = map[*src++]; + dst += 2; + break; + } + src += srcskip; + dst += dstskip; + } + } +#endif /* USE_DUFFS_LOOP */ +} +static void Blit1to3(SDL_BlitInfo *info) +{ +#ifndef USE_DUFFS_LOOP + int c; +#endif + int o; + int width, height; + Uint8 *src, *map, *dst; + int srcskip, dstskip; + + /* Set up some basic variables */ + width = info->d_width; + height = info->d_height; + src = info->s_pixels; + srcskip = info->s_skip; + dst = info->d_pixels; + dstskip = info->d_skip; + map = info->table; + + while ( height-- ) { +#ifdef USE_DUFFS_LOOP + DUFFS_LOOP( + { + o = *src * 4; + dst[0] = map[o++]; + dst[1] = map[o++]; + dst[2] = map[o++]; + } + src++; + dst += 3; + , width); +#else + for ( c=width; c; --c ) { + o = *src * 4; + dst[0] = map[o++]; + dst[1] = map[o++]; + dst[2] = map[o++]; + src++; + dst += 3; + } +#endif /* USE_DUFFS_LOOP */ + src += srcskip; + dst += dstskip; + } +} +static void Blit1to4(SDL_BlitInfo *info) +{ +#ifndef USE_DUFFS_LOOP + int c; +#endif + int width, height; + Uint8 *src; + Uint32 *map, *dst; + int srcskip, dstskip; + + /* Set up some basic variables */ + width = info->d_width; + height = info->d_height; + src = info->s_pixels; + srcskip = info->s_skip; + dst = (Uint32 *)info->d_pixels; + dstskip = info->d_skip/4; + map = (Uint32 *)info->table; + + while ( height-- ) { +#ifdef USE_DUFFS_LOOP + DUFFS_LOOP( + *dst++ = map[*src++]; + , width); +#else + for ( c=width/4; c; --c ) { + *dst++ = map[*src++]; + *dst++ = map[*src++]; + *dst++ = map[*src++]; + *dst++ = map[*src++]; + } + switch ( width & 3 ) { + case 3: + *dst++ = map[*src++]; + case 2: + *dst++ = map[*src++]; + case 1: + *dst++ = map[*src++]; + } +#endif /* USE_DUFFS_LOOP */ + src += srcskip; + dst += dstskip; + } +} + +static void Blit1to1Key(SDL_BlitInfo *info) +{ + int width = info->d_width; + int height = info->d_height; + Uint8 *src = info->s_pixels; + int srcskip = info->s_skip; + Uint8 *dst = info->d_pixels; + int dstskip = info->d_skip; + Uint8 *palmap = info->table; + Uint32 ckey = info->src->colorkey; + + if ( palmap ) { + while ( height-- ) { + DUFFS_LOOP( + { + if ( *src != ckey ) { + *dst = palmap[*src]; + } + dst++; + src++; + }, + width); + src += srcskip; + dst += dstskip; + } + } else { + while ( height-- ) { + DUFFS_LOOP( + { + if ( *src != ckey ) { + *dst = *src; + } + dst++; + src++; + }, + width); + src += srcskip; + dst += dstskip; + } + } +} + +static void Blit1to2Key(SDL_BlitInfo *info) +{ + int width = info->d_width; + int height = info->d_height; + Uint8 *src = info->s_pixels; + int srcskip = info->s_skip; + Uint16 *dstp = (Uint16 *)info->d_pixels; + int dstskip = info->d_skip; + Uint16 *palmap = (Uint16 *)info->table; + Uint32 ckey = info->src->colorkey; + + /* Set up some basic variables */ + dstskip /= 2; + + while ( height-- ) { + DUFFS_LOOP( + { + if ( *src != ckey ) { + *dstp=palmap[*src]; + } + src++; + dstp++; + }, + width); + src += srcskip; + dstp += dstskip; + } +} + +static void Blit1to3Key(SDL_BlitInfo *info) +{ + int width = info->d_width; + int height = info->d_height; + Uint8 *src = info->s_pixels; + int srcskip = info->s_skip; + Uint8 *dst = info->d_pixels; + int dstskip = info->d_skip; + Uint8 *palmap = info->table; + Uint32 ckey = info->src->colorkey; + int o; + + while ( height-- ) { + DUFFS_LOOP( + { + if ( *src != ckey ) { + o = *src * 4; + dst[0] = palmap[o++]; + dst[1] = palmap[o++]; + dst[2] = palmap[o++]; + } + src++; + dst += 3; + }, + width); + src += srcskip; + dst += dstskip; + } +} + +static void Blit1to4Key(SDL_BlitInfo *info) +{ + int width = info->d_width; + int height = info->d_height; + Uint8 *src = info->s_pixels; + int srcskip = info->s_skip; + Uint32 *dstp = (Uint32 *)info->d_pixels; + int dstskip = info->d_skip; + Uint32 *palmap = (Uint32 *)info->table; + Uint32 ckey = info->src->colorkey; + + /* Set up some basic variables */ + dstskip /= 4; + + while ( height-- ) { + DUFFS_LOOP( + { + if ( *src != ckey ) { + *dstp = palmap[*src]; + } + src++; + dstp++; + }, + width); + src += srcskip; + dstp += dstskip; + } +} + +static void Blit1toNAlpha(SDL_BlitInfo *info) +{ + int width = info->d_width; + int height = info->d_height; + Uint8 *src = info->s_pixels; + int srcskip = info->s_skip; + Uint8 *dst = info->d_pixels; + int dstskip = info->d_skip; + SDL_PixelFormat *dstfmt = info->dst; + const SDL_Color *srcpal = info->src->palette->colors; + int dstbpp; + const int A = info->src->alpha; + + /* Set up some basic variables */ + dstbpp = dstfmt->BytesPerPixel; + + while ( height-- ) { + int sR, sG, sB; + int dR, dG, dB; + DUFFS_LOOP4( + { + Uint32 pixel; + sR = srcpal[*src].r; + sG = srcpal[*src].g; + sB = srcpal[*src].b; + DISEMBLE_RGB(dst, dstbpp, dstfmt, + pixel, dR, dG, dB); + ALPHA_BLEND(sR, sG, sB, A, dR, dG, dB); + ASSEMBLE_RGB(dst, dstbpp, dstfmt, dR, dG, dB); + src++; + dst += dstbpp; + }, + width); + src += srcskip; + dst += dstskip; + } +} + +static void Blit1toNAlphaKey(SDL_BlitInfo *info) +{ + int width = info->d_width; + int height = info->d_height; + Uint8 *src = info->s_pixels; + int srcskip = info->s_skip; + Uint8 *dst = info->d_pixels; + int dstskip = info->d_skip; + SDL_PixelFormat *srcfmt = info->src; + SDL_PixelFormat *dstfmt = info->dst; + const SDL_Color *srcpal = info->src->palette->colors; + Uint32 ckey = srcfmt->colorkey; + int dstbpp; + const int A = srcfmt->alpha; + + /* Set up some basic variables */ + dstbpp = dstfmt->BytesPerPixel; + + while ( height-- ) { + int sR, sG, sB; + int dR, dG, dB; + DUFFS_LOOP( + { + if ( *src != ckey ) { + Uint32 pixel; + sR = srcpal[*src].r; + sG = srcpal[*src].g; + sB = srcpal[*src].b; + DISEMBLE_RGB(dst, dstbpp, dstfmt, + pixel, dR, dG, dB); + ALPHA_BLEND(sR, sG, sB, A, dR, dG, dB); + ASSEMBLE_RGB(dst, dstbpp, dstfmt, dR, dG, dB); + } + src++; + dst += dstbpp; + }, + width); + src += srcskip; + dst += dstskip; + } +} + +static SDL_loblit one_blit[] = { + NULL, Blit1to1, Blit1to2, Blit1to3, Blit1to4 +}; + +static SDL_loblit one_blitkey[] = { + NULL, Blit1to1Key, Blit1to2Key, Blit1to3Key, Blit1to4Key +}; + +SDL_loblit SDL_CalculateBlit1(SDL_Surface *surface, int blit_index) +{ + int which; + SDL_PixelFormat *dstfmt; + + dstfmt = surface->map->dst->format; + if ( dstfmt->BitsPerPixel < 8 ) { + which = 0; + } else { + which = dstfmt->BytesPerPixel; + } + switch(blit_index) { + case 0: /* copy */ + return one_blit[which]; + + case 1: /* colorkey */ + return one_blitkey[which]; + + case 2: /* alpha */ + /* Supporting 8bpp->8bpp alpha is doable but requires lots of + tables which consume space and takes time to precompute, + so is better left to the user */ + return which >= 2 ? Blit1toNAlpha : NULL; + + case 3: /* alpha + colorkey */ + return which >= 2 ? Blit1toNAlphaKey : NULL; + + } + return NULL; +} diff --git a/contrib/sdk/sources/SDL-1.2.2/src/video/SDL_blit_A.c b/contrib/sdk/sources/SDL-1.2.2/src/video/SDL_blit_A.c new file mode 100644 index 000000000..8a75c8b6d --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/src/video/SDL_blit_A.c @@ -0,0 +1,772 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997, 1998, 1999, 2000, 2001 Sam Lantinga + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the Free + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + Sam Lantinga + slouken@devolution.com +*/ + + +#include + +#include "SDL_types.h" +#include "SDL_video.h" +#include "SDL_blit.h" + +/* Functions to perform alpha blended blitting */ + +/* N->1 blending with per-surface alpha */ +static void BlitNto1SurfaceAlpha(SDL_BlitInfo *info) +{ + int width = info->d_width; + int height = info->d_height; + Uint8 *src = info->s_pixels; + int srcskip = info->s_skip; + Uint8 *dst = info->d_pixels; + int dstskip = info->d_skip; + Uint8 *palmap = info->table; + SDL_PixelFormat *srcfmt = info->src; + SDL_PixelFormat *dstfmt = info->dst; + int srcbpp = srcfmt->BytesPerPixel; + + const unsigned A = srcfmt->alpha; + + while ( height-- ) { + DUFFS_LOOP4( + { + Uint32 pixel; + unsigned sR; + unsigned sG; + unsigned sB; + unsigned dR; + unsigned dG; + unsigned dB; + DISEMBLE_RGB(src, srcbpp, srcfmt, pixel, sR, sG, sB); + dR = dstfmt->palette->colors[*dst].r; + dG = dstfmt->palette->colors[*dst].g; + dB = dstfmt->palette->colors[*dst].b; + ALPHA_BLEND(sR, sG, sB, A, dR, dG, dB); + dR &= 0xff; + dG &= 0xff; + dB &= 0xff; + /* Pack RGB into 8bit pixel */ + if ( palmap == NULL ) { + *dst =((dR>>5)<<(3+2))| + ((dG>>5)<<(2))| + ((dB>>6)<<(0)); + } else { + *dst = palmap[((dR>>5)<<(3+2))| + ((dG>>5)<<(2)) | + ((dB>>6)<<(0))]; + } + dst++; + src += srcbpp; + }, + width); + src += srcskip; + dst += dstskip; + } +} + +/* N->1 blending with pixel alpha */ +static void BlitNto1PixelAlpha(SDL_BlitInfo *info) +{ + int width = info->d_width; + int height = info->d_height; + Uint8 *src = info->s_pixels; + int srcskip = info->s_skip; + Uint8 *dst = info->d_pixels; + int dstskip = info->d_skip; + Uint8 *palmap = info->table; + SDL_PixelFormat *srcfmt = info->src; + SDL_PixelFormat *dstfmt = info->dst; + int srcbpp = srcfmt->BytesPerPixel; + + /* FIXME: fix alpha bit field expansion here too? */ + while ( height-- ) { + DUFFS_LOOP4( + { + Uint32 pixel; + unsigned sR; + unsigned sG; + unsigned sB; + unsigned sA; + unsigned dR; + unsigned dG; + unsigned dB; + DISEMBLE_RGBA(src,srcbpp,srcfmt,pixel,sR,sG,sB,sA); + dR = dstfmt->palette->colors[*dst].r; + dG = dstfmt->palette->colors[*dst].g; + dB = dstfmt->palette->colors[*dst].b; + ALPHA_BLEND(sR, sG, sB, sA, dR, dG, dB); + dR &= 0xff; + dG &= 0xff; + dB &= 0xff; + /* Pack RGB into 8bit pixel */ + if ( palmap == NULL ) { + *dst =((dR>>5)<<(3+2))| + ((dG>>5)<<(2))| + ((dB>>6)<<(0)); + } else { + *dst = palmap[((dR>>5)<<(3+2))| + ((dG>>5)<<(2)) | + ((dB>>6)<<(0)) ]; + } + dst++; + src += srcbpp; + }, + width); + src += srcskip; + dst += dstskip; + } +} + +/* colorkeyed N->1 blending with per-surface alpha */ +static void BlitNto1SurfaceAlphaKey(SDL_BlitInfo *info) +{ + int width = info->d_width; + int height = info->d_height; + Uint8 *src = info->s_pixels; + int srcskip = info->s_skip; + Uint8 *dst = info->d_pixels; + int dstskip = info->d_skip; + Uint8 *palmap = info->table; + SDL_PixelFormat *srcfmt = info->src; + SDL_PixelFormat *dstfmt = info->dst; + int srcbpp = srcfmt->BytesPerPixel; + Uint32 ckey = srcfmt->colorkey; + + const int A = srcfmt->alpha; + + while ( height-- ) { + DUFFS_LOOP( + { + Uint32 pixel; + unsigned sR; + unsigned sG; + unsigned sB; + unsigned dR; + unsigned dG; + unsigned dB; + DISEMBLE_RGB(src, srcbpp, srcfmt, pixel, sR, sG, sB); + if ( pixel != ckey ) { + dR = dstfmt->palette->colors[*dst].r; + dG = dstfmt->palette->colors[*dst].g; + dB = dstfmt->palette->colors[*dst].b; + ALPHA_BLEND(sR, sG, sB, A, dR, dG, dB); + dR &= 0xff; + dG &= 0xff; + dB &= 0xff; + /* Pack RGB into 8bit pixel */ + if ( palmap == NULL ) { + *dst =((dR>>5)<<(3+2))| + ((dG>>5)<<(2)) | + ((dB>>6)<<(0)); + } else { + *dst = palmap[((dR>>5)<<(3+2))| + ((dG>>5)<<(2)) | + ((dB>>6)<<(0)) ]; + } + } + dst++; + src += srcbpp; + }, + width); + src += srcskip; + dst += dstskip; + } +} + +/* fast RGB888->(A)RGB888 blending with surface alpha=128 special case */ +static void BlitRGBtoRGBSurfaceAlpha128(SDL_BlitInfo *info) +{ + int width = info->d_width; + int height = info->d_height; + Uint32 *srcp = (Uint32 *)info->s_pixels; + int srcskip = info->s_skip >> 2; + Uint32 *dstp = (Uint32 *)info->d_pixels; + int dstskip = info->d_skip >> 2; + + while(height--) { + DUFFS_LOOP4({ + Uint32 s = *srcp++; + Uint32 d = *dstp; + *dstp++ = ((((s & 0x00fefefe) + (d & 0x00fefefe)) >> 1) + + (s & d & 0x00010101)) | 0xff000000; + }, width); + srcp += srcskip; + dstp += dstskip; + } +} + +/* fast RGB888->(A)RGB888 blending with surface alpha */ +static void BlitRGBtoRGBSurfaceAlpha(SDL_BlitInfo *info) +{ + unsigned alpha = info->src->alpha; + if(alpha == 128) { + BlitRGBtoRGBSurfaceAlpha128(info); + } else { + int width = info->d_width; + int height = info->d_height; + Uint32 *srcp = (Uint32 *)info->s_pixels; + int srcskip = info->s_skip >> 2; + Uint32 *dstp = (Uint32 *)info->d_pixels; + int dstskip = info->d_skip >> 2; + + while(height--) { + DUFFS_LOOP4({ + Uint32 s; + Uint32 d; + Uint32 s1; + Uint32 d1; + s = *srcp; + d = *dstp; + s1 = s & 0xff00ff; + d1 = d & 0xff00ff; + d1 = (d1 + ((s1 - d1) * alpha >> 8)) + & 0xff00ff; + s &= 0xff00; + d &= 0xff00; + d = (d + ((s - d) * alpha >> 8)) & 0xff00; + *dstp = d1 | d | 0xff000000; + ++srcp; + ++dstp; + }, width); + srcp += srcskip; + dstp += dstskip; + } + } +} + +/* fast ARGB888->(A)RGB888 blending with pixel alpha */ +static void BlitRGBtoRGBPixelAlpha(SDL_BlitInfo *info) +{ + int width = info->d_width; + int height = info->d_height; + Uint32 *srcp = (Uint32 *)info->s_pixels; + int srcskip = info->s_skip >> 2; + Uint32 *dstp = (Uint32 *)info->d_pixels; + int dstskip = info->d_skip >> 2; + + while(height--) { + DUFFS_LOOP4({ + Uint32 dalpha; + Uint32 d; + Uint32 s1; + Uint32 d1; + Uint32 s = *srcp; + Uint32 alpha = s >> 24; + /* FIXME: Here we special-case opaque alpha since the + compositioning used (>>8 instead of /255) doesn't handle + it correctly. Also special-case alpha=0 for speed? + Benchmark this! */ + if(alpha == SDL_ALPHA_OPAQUE) { + *dstp = (s & 0x00ffffff) | (*dstp & 0xff000000); + } else { + /* + * take out the middle component (green), and process + * the other two in parallel. One multiply less. + */ + d = *dstp; + dalpha = d & 0xff000000; + s1 = s & 0xff00ff; + d1 = d & 0xff00ff; + d1 = (d1 + ((s1 - d1) * alpha >> 8)) & 0xff00ff; + s &= 0xff00; + d &= 0xff00; + d = (d + ((s - d) * alpha >> 8)) & 0xff00; + *dstp = d1 | d | dalpha; + } + ++srcp; + ++dstp; + }, width); + srcp += srcskip; + dstp += dstskip; + } +} + +/* 16bpp special case for per-surface alpha=50%: blend 2 pixels in parallel */ + +/* blend a single 16 bit pixel at 50% */ +#define BLEND16_50(d, s, mask) \ + ((((s & mask) + (d & mask)) >> 1) + (s & d & (~mask & 0xffff))) + +/* blend two 16 bit pixels at 50% */ +#define BLEND2x16_50(d, s, mask) \ + (((s & (mask | mask << 16)) >> 1) + ((d & (mask | mask << 16)) >> 1) \ + + (s & d & (~(mask | mask << 16)))) + +static void Blit16to16SurfaceAlpha128(SDL_BlitInfo *info, Uint16 mask) +{ + int width = info->d_width; + int height = info->d_height; + Uint16 *srcp = (Uint16 *)info->s_pixels; + int srcskip = info->s_skip >> 1; + Uint16 *dstp = (Uint16 *)info->d_pixels; + int dstskip = info->d_skip >> 1; + + while(height--) { + if(((unsigned long)srcp ^ (unsigned long)dstp) & 2) { + /* + * Source and destination not aligned, pipeline it. + * This is mostly a win for big blits but no loss for + * small ones + */ + Uint32 prev_sw; + int w = width; + + /* handle odd destination */ + if((unsigned long)dstp & 2) { + Uint16 d = *dstp, s = *srcp; + *dstp = BLEND16_50(d, s, mask); + dstp++; + srcp++; + w--; + } + srcp++; /* srcp is now 32-bit aligned */ + + /* bootstrap pipeline with first halfword */ + prev_sw = ((Uint32 *)srcp)[-1]; + + while(w > 1) { + Uint32 sw, dw, s; + sw = *(Uint32 *)srcp; + dw = *(Uint32 *)dstp; + if(SDL_BYTEORDER == SDL_BIG_ENDIAN) + s = (prev_sw << 16) + (sw >> 16); + else + s = (prev_sw >> 16) + (sw << 16); + prev_sw = sw; + *(Uint32 *)dstp = BLEND2x16_50(dw, s, mask); + dstp += 2; + srcp += 2; + w -= 2; + } + + /* final pixel if any */ + if(w) { + Uint16 d = *dstp, s; + if(SDL_BYTEORDER == SDL_BIG_ENDIAN) + s = prev_sw; + else + s = prev_sw >> 16; + *dstp = BLEND16_50(d, s, mask); + srcp++; + dstp++; + } + srcp += srcskip - 1; + dstp += dstskip; + } else { + /* source and destination are aligned */ + int w = width; + + /* first odd pixel? */ + if((unsigned long)srcp & 2) { + Uint16 d = *dstp, s = *srcp; + *dstp = BLEND16_50(d, s, mask); + srcp++; + dstp++; + w--; + } + /* srcp and dstp are now 32-bit aligned */ + + while(w > 1) { + Uint32 sw = *(Uint32 *)srcp; + Uint32 dw = *(Uint32 *)dstp; + *(Uint32 *)dstp = BLEND2x16_50(dw, sw, mask); + srcp += 2; + dstp += 2; + w -= 2; + } + + /* last odd pixel? */ + if(w) { + Uint16 d = *dstp, s = *srcp; + *dstp = BLEND16_50(d, s, mask); + srcp++; + dstp++; + } + srcp += srcskip; + dstp += dstskip; + } + } +} + +/* fast RGB565->RGB565 blending with surface alpha */ +static void Blit565to565SurfaceAlpha(SDL_BlitInfo *info) +{ + unsigned alpha = info->src->alpha; + if(alpha == 128) { + Blit16to16SurfaceAlpha128(info, 0xf7de); + } else { + int width = info->d_width; + int height = info->d_height; + Uint16 *srcp = (Uint16 *)info->s_pixels; + int srcskip = info->s_skip >> 1; + Uint16 *dstp = (Uint16 *)info->d_pixels; + int dstskip = info->d_skip >> 1; + alpha >>= 3; /* downscale alpha to 5 bits */ + + while(height--) { + DUFFS_LOOP4({ + Uint32 s = *srcp++; + Uint32 d = *dstp; + /* + * shift out the middle component (green) to + * the high 16 bits, and process all three RGB + * components at the same time. + */ + s = (s | s << 16) & 0x07e0f81f; + d = (d | d << 16) & 0x07e0f81f; + d += (s - d) * alpha >> 5; + d &= 0x07e0f81f; + *dstp++ = d | d >> 16; + }, width); + srcp += srcskip; + dstp += dstskip; + } + } +} + +/* fast RGB555->RGB555 blending with surface alpha */ +static void Blit555to555SurfaceAlpha(SDL_BlitInfo *info) +{ + unsigned alpha = info->src->alpha; /* downscale alpha to 5 bits */ + if(alpha == 128) { + Blit16to16SurfaceAlpha128(info, 0xfbde); + } else { + int width = info->d_width; + int height = info->d_height; + Uint16 *srcp = (Uint16 *)info->s_pixels; + int srcskip = info->s_skip >> 1; + Uint16 *dstp = (Uint16 *)info->d_pixels; + int dstskip = info->d_skip >> 1; + alpha >>= 3; /* downscale alpha to 5 bits */ + + while(height--) { + DUFFS_LOOP4({ + Uint32 s = *srcp++; + Uint32 d = *dstp; + /* + * shift out the middle component (green) to + * the high 16 bits, and process all three RGB + * components at the same time. + */ + s = (s | s << 16) & 0x03e07c1f; + d = (d | d << 16) & 0x03e07c1f; + d += (s - d) * alpha >> 5; + d &= 0x03e07c1f; + *dstp++ = d | d >> 16; + }, width); + srcp += srcskip; + dstp += dstskip; + } + } +} + +/* fast ARGB8888->RGB565 blending with pixel alpha */ +static void BlitARGBto565PixelAlpha(SDL_BlitInfo *info) +{ + int width = info->d_width; + int height = info->d_height; + Uint32 *srcp = (Uint32 *)info->s_pixels; + int srcskip = info->s_skip >> 2; + Uint16 *dstp = (Uint16 *)info->d_pixels; + int dstskip = info->d_skip >> 1; + + while(height--) { + DUFFS_LOOP4({ + Uint32 s = *srcp; + unsigned alpha = s >> 27; /* downscale alpha to 5 bits */ + /* FIXME: Here we special-case opaque alpha since the + compositioning used (>>8 instead of /255) doesn't handle + it correctly. Also special-case alpha=0 for speed? + Benchmark this! */ + if(alpha == (SDL_ALPHA_OPAQUE >> 3)) { + *dstp = (s >> 8 & 0xf800) + (s >> 5 & 0x7e0) + + (s >> 3 & 0x1f); + } else { + Uint32 d = *dstp; + /* + * convert source and destination to G0RAB65565 + * and blend all components at the same time + */ + s = ((s & 0xfc00) << 11) + (s >> 8 & 0xf800) + + (s >> 3 & 0x1f); + d = (d | d << 16) & 0x07e0f81f; + d += (s - d) * alpha >> 5; + d &= 0x07e0f81f; + *dstp = d | d >> 16; + } + srcp++; + dstp++; + }, width); + srcp += srcskip; + dstp += dstskip; + } +} + +/* fast ARGB8888->RGB555 blending with pixel alpha */ +static void BlitARGBto555PixelAlpha(SDL_BlitInfo *info) +{ + int width = info->d_width; + int height = info->d_height; + Uint32 *srcp = (Uint32 *)info->s_pixels; + int srcskip = info->s_skip >> 2; + Uint16 *dstp = (Uint16 *)info->d_pixels; + int dstskip = info->d_skip >> 1; + + while(height--) { + DUFFS_LOOP4({ + unsigned alpha; + Uint32 s = *srcp; + alpha = s >> 27; /* downscale alpha to 5 bits */ + /* FIXME: Here we special-case opaque alpha since the + compositioning used (>>8 instead of /255) doesn't handle + it correctly. Also special-case alpha=0 for speed? + Benchmark this! */ + if(alpha == (SDL_ALPHA_OPAQUE >> 3)) { + *dstp = (s >> 9 & 0x7c00) + (s >> 6 & 0x3e0) + + (s >> 3 & 0x1f); + } else { + Uint32 d = *dstp; + /* + * convert source and destination to G0RAB65565 + * and blend all components at the same time + */ + s = ((s & 0xf800) << 10) + (s >> 9 & 0x7c00) + + (s >> 3 & 0x1f); + d = (d | d << 16) & 0x03e07c1f; + d += (s - d) * alpha >> 5; + d &= 0x03e07c1f; + *dstp = d | d >> 16; + } + srcp++; + dstp++; + }, width); + srcp += srcskip; + dstp += dstskip; + } +} + +/* General (slow) N->N blending with per-surface alpha */ +static void BlitNtoNSurfaceAlpha(SDL_BlitInfo *info) +{ + int width = info->d_width; + int height = info->d_height; + Uint8 *src = info->s_pixels; + int srcskip = info->s_skip; + Uint8 *dst = info->d_pixels; + int dstskip = info->d_skip; + SDL_PixelFormat *srcfmt = info->src; + SDL_PixelFormat *dstfmt = info->dst; + int srcbpp = srcfmt->BytesPerPixel; + int dstbpp = dstfmt->BytesPerPixel; + unsigned sA = srcfmt->alpha; + unsigned dA = dstfmt->Amask ? SDL_ALPHA_OPAQUE : 0; + + while ( height-- ) { + DUFFS_LOOP4( + { + Uint32 pixel; + unsigned sR; + unsigned sG; + unsigned sB; + unsigned dR; + unsigned dG; + unsigned dB; + DISEMBLE_RGB(src, srcbpp, srcfmt, pixel, sR, sG, sB); + DISEMBLE_RGB(dst, dstbpp, dstfmt, pixel, dR, dG, dB); + ALPHA_BLEND(sR, sG, sB, sA, dR, dG, dB); + ASSEMBLE_RGBA(dst, dstbpp, dstfmt, dR, dG, dB, dA); + src += srcbpp; + dst += dstbpp; + }, + width); + src += srcskip; + dst += dstskip; + } +} + +/* General (slow) colorkeyed N->N blending with per-surface alpha */ +static void BlitNtoNSurfaceAlphaKey(SDL_BlitInfo *info) +{ + int width = info->d_width; + int height = info->d_height; + Uint8 *src = info->s_pixels; + int srcskip = info->s_skip; + Uint8 *dst = info->d_pixels; + int dstskip = info->d_skip; + SDL_PixelFormat *srcfmt = info->src; + SDL_PixelFormat *dstfmt = info->dst; + Uint32 ckey = srcfmt->colorkey; + int srcbpp = srcfmt->BytesPerPixel; + int dstbpp = dstfmt->BytesPerPixel; + unsigned sA = srcfmt->alpha; + unsigned dA = dstfmt->Amask ? SDL_ALPHA_OPAQUE : 0; + + while ( height-- ) { + DUFFS_LOOP4( + { + Uint32 pixel; + unsigned sR; + unsigned sG; + unsigned sB; + unsigned dR; + unsigned dG; + unsigned dB; + RETRIEVE_RGB_PIXEL(src, srcbpp, pixel); + if(pixel != ckey) { + RGB_FROM_PIXEL(pixel, srcfmt, sR, sG, sB); + DISEMBLE_RGB(dst, dstbpp, dstfmt, pixel, dR, dG, dB); + ALPHA_BLEND(sR, sG, sB, sA, dR, dG, dB); + ASSEMBLE_RGBA(dst, dstbpp, dstfmt, dR, dG, dB, dA); + } + src += srcbpp; + dst += dstbpp; + }, + width); + src += srcskip; + dst += dstskip; + } +} + +/* General (slow) N->N blending with pixel alpha */ +static void BlitNtoNPixelAlpha(SDL_BlitInfo *info) +{ + int width = info->d_width; + int height = info->d_height; + Uint8 *src = info->s_pixels; + int srcskip = info->s_skip; + Uint8 *dst = info->d_pixels; + int dstskip = info->d_skip; + SDL_PixelFormat *srcfmt = info->src; + SDL_PixelFormat *dstfmt = info->dst; + + int srcbpp; + int dstbpp; + + /* Set up some basic variables */ + srcbpp = srcfmt->BytesPerPixel; + dstbpp = dstfmt->BytesPerPixel; + + /* FIXME: for 8bpp source alpha, this doesn't get opaque values + quite right. for <8bpp source alpha, it gets them very wrong + (check all macros!) + It is unclear whether there is a good general solution that doesn't + need a branch (or a divide). */ + while ( height-- ) { + DUFFS_LOOP4( + { + Uint32 pixel; + unsigned sR; + unsigned sG; + unsigned sB; + unsigned dR; + unsigned dG; + unsigned dB; + unsigned sA; + unsigned dA; + DISEMBLE_RGBA(src, srcbpp, srcfmt, pixel, sR, sG, sB, sA); + DISEMBLE_RGBA(dst, dstbpp, dstfmt, pixel, dR, dG, dB, dA); + ALPHA_BLEND(sR, sG, sB, sA, dR, dG, dB); + ASSEMBLE_RGBA(dst, dstbpp, dstfmt, dR, dG, dB, dA); + src += srcbpp; + dst += dstbpp; + }, + width); + src += srcskip; + dst += dstskip; + } +} + + +SDL_loblit SDL_CalculateAlphaBlit(SDL_Surface *surface, int blit_index) +{ + SDL_PixelFormat *sf = surface->format; + SDL_PixelFormat *df = surface->map->dst->format; + + if(sf->Amask == 0) { + if((surface->flags & SDL_SRCCOLORKEY) == SDL_SRCCOLORKEY) { + if(df->BytesPerPixel == 1) + return BlitNto1SurfaceAlphaKey; + else + return BlitNtoNSurfaceAlphaKey; + } else { + /* Per-surface alpha blits */ + switch(df->BytesPerPixel) { + case 1: + return BlitNto1SurfaceAlpha; + + case 2: + if(surface->map->identity) { + if(df->Gmask == 0x7e0) + return Blit565to565SurfaceAlpha; + else if(df->Gmask == 0x3e0) + return Blit555to555SurfaceAlpha; + } + return BlitNtoNSurfaceAlpha; + + case 4: + if(sf->Rmask == df->Rmask + && sf->Gmask == df->Gmask + && sf->Bmask == df->Bmask + && (sf->Rmask | sf->Gmask | sf->Bmask) == 0xffffff + && sf->BytesPerPixel == 4) + return BlitRGBtoRGBSurfaceAlpha; + else + return BlitNtoNSurfaceAlpha; + + case 3: + default: + return BlitNtoNSurfaceAlpha; + } + } + } else { + /* Per-pixel alpha blits */ + switch(df->BytesPerPixel) { + case 1: + return BlitNto1PixelAlpha; + + case 2: + if(sf->BytesPerPixel == 4 && sf->Amask == 0xff000000 + && sf->Gmask == 0xff00 + && ((sf->Rmask == 0xff && df->Rmask == 0x1f) + || (sf->Bmask == 0xff && df->Bmask == 0x1f))) { + if(df->Gmask == 0x7e0) + return BlitARGBto565PixelAlpha; + else if(df->Gmask == 0x3e0) + return BlitARGBto555PixelAlpha; + } + return BlitNtoNPixelAlpha; + + case 4: + if(sf->Amask == 0xff000000 + && sf->Rmask == df->Rmask + && sf->Gmask == df->Gmask + && sf->Bmask == df->Bmask + && sf->BytesPerPixel == 4) + return BlitRGBtoRGBPixelAlpha; + return BlitNtoNPixelAlpha; + + case 3: + default: + return BlitNtoNPixelAlpha; + } + } +} + diff --git a/contrib/sdk/sources/SDL-1.2.2/src/video/SDL_blit_A.h b/contrib/sdk/sources/SDL-1.2.2/src/video/SDL_blit_A.h new file mode 100644 index 000000000..3a4d6953d --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/src/video/SDL_blit_A.h @@ -0,0 +1,30 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997, 1998, 1999, 2000, 2001 Sam Lantinga + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the Free + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + Sam Lantinga + slouken@devolution.com +*/ + +#ifdef SAVE_RCSID +static char rcsid = + "@(#) $Id: SDL_blit_A.h,v 1.2 2001/04/26 16:50:18 hercules Exp $"; +#endif + +/* Functions from SDL_blitalpha.c */ +extern void SDL_BlitAlpha(SDL_BlitInfo *info); + diff --git a/contrib/sdk/sources/SDL-1.2.2/src/video/SDL_blit_N.c b/contrib/sdk/sources/SDL-1.2.2/src/video/SDL_blit_N.c new file mode 100644 index 000000000..78d7fe0c3 --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/src/video/SDL_blit_N.c @@ -0,0 +1,1607 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997, 1998, 1999, 2000, 2001 Sam Lantinga + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the Free + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + Sam Lantinga + slouken@devolution.com +*/ + + +#include + +#include "SDL_types.h" +#include "SDL_video.h" +#include "SDL_blit.h" +#include "SDL_byteorder.h" + +/* Function to check the CPU flags */ +#define MMX_CPU 0x800000 +#ifdef USE_ASMBLIT +#define CPU_Flags() Hermes_X86_CPU() +#else +#define CPU_Flags() 0L +#endif + +/* Functions to blit from N-bit surfaces to other surfaces */ + +#ifdef USE_ASMBLIT + +/* Heheheh, we coerce Hermes into using SDL blit information */ +#define X86_ASSEMBLER +#define HermesConverterInterface SDL_BlitInfo +#define HermesClearInterface void +#define STACKCALL +typedef Uint32 int32; + +#include "HeadMMX.h" +#include "HeadX86.h" + +#else + +/* This is now endian dependent */ +#if ( SDL_BYTEORDER == SDL_LIL_ENDIAN ) +#define HI 1 +#define LO 0 +#else /* ( SDL_BYTEORDER == SDL_BIG_ENDIAN ) */ +#define HI 0 +#define LO 1 +#endif + +/* Special optimized blit for RGB 8-8-8 --> RGB 3-3-2 */ +#define RGB888_RGB332(dst, src) { \ + dst = (((src)&0x00E00000)>>16)| \ + (((src)&0x0000E000)>>11)| \ + (((src)&0x000000C0)>>6); \ +} +static void Blit_RGB888_index8(SDL_BlitInfo *info) +{ +#ifndef USE_DUFFS_LOOP + int c; +#endif + int width, height; + Uint32 *src; + const Uint8 *map; + Uint8 *dst; + int srcskip, dstskip; + + /* Set up some basic variables */ + width = info->d_width; + height = info->d_height; + src = (Uint32 *)info->s_pixels; + srcskip = info->s_skip/4; + dst = info->d_pixels; + dstskip = info->d_skip; + map = info->table; + + if ( map == NULL ) { + while ( height-- ) { +#ifdef USE_DUFFS_LOOP + DUFFS_LOOP( + RGB888_RGB332(*dst++, *src); + , width); +#else + for ( c=width/4; c; --c ) { + /* Pack RGB into 8bit pixel */ + ++src; + RGB888_RGB332(*dst++, *src); + ++src; + RGB888_RGB332(*dst++, *src); + ++src; + RGB888_RGB332(*dst++, *src); + ++src; + } + switch ( width & 3 ) { + case 3: + RGB888_RGB332(*dst++, *src); + ++src; + case 2: + RGB888_RGB332(*dst++, *src); + ++src; + case 1: + RGB888_RGB332(*dst++, *src); + ++src; + } +#endif /* USE_DUFFS_LOOP */ + src += srcskip; + dst += dstskip; + } + } else { + int pixel; + + while ( height-- ) { +#ifdef USE_DUFFS_LOOP + DUFFS_LOOP( + RGB888_RGB332(pixel, *src); + *dst++ = map[pixel]; + ++src; + , width); +#else + for ( c=width/4; c; --c ) { + /* Pack RGB into 8bit pixel */ + RGB888_RGB332(pixel, *src); + *dst++ = map[pixel]; + ++src; + RGB888_RGB332(pixel, *src); + *dst++ = map[pixel]; + ++src; + RGB888_RGB332(pixel, *src); + *dst++ = map[pixel]; + ++src; + RGB888_RGB332(pixel, *src); + *dst++ = map[pixel]; + ++src; + } + switch ( width & 3 ) { + case 3: + RGB888_RGB332(pixel, *src); + *dst++ = map[pixel]; + ++src; + case 2: + RGB888_RGB332(pixel, *src); + *dst++ = map[pixel]; + ++src; + case 1: + RGB888_RGB332(pixel, *src); + *dst++ = map[pixel]; + ++src; + } +#endif /* USE_DUFFS_LOOP */ + src += srcskip; + dst += dstskip; + } + } +} +/* Special optimized blit for RGB 8-8-8 --> RGB 5-5-5 */ +#define RGB888_RGB555(dst, src) { \ + *(Uint16 *)(dst) = (((*src)&0x00F80000)>>9)| \ + (((*src)&0x0000F800)>>6)| \ + (((*src)&0x000000F8)>>3); \ +} +#define RGB888_RGB555_TWO(dst, src) { \ + *(Uint32 *)(dst) = (((((src[HI])&0x00F80000)>>9)| \ + (((src[HI])&0x0000F800)>>6)| \ + (((src[HI])&0x000000F8)>>3))<<16)| \ + (((src[LO])&0x00F80000)>>9)| \ + (((src[LO])&0x0000F800)>>6)| \ + (((src[LO])&0x000000F8)>>3); \ +} +static void Blit_RGB888_RGB555(SDL_BlitInfo *info) +{ +#ifndef USE_DUFFS_LOOP + int c; +#endif + int width, height; + Uint32 *src; + Uint16 *dst; + int srcskip, dstskip; + + /* Set up some basic variables */ + width = info->d_width; + height = info->d_height; + src = (Uint32 *)info->s_pixels; + srcskip = info->s_skip/4; + dst = (Uint16 *)info->d_pixels; + dstskip = info->d_skip/2; + +#ifdef USE_DUFFS_LOOP + while ( height-- ) { + DUFFS_LOOP( + RGB888_RGB555(dst, src); + ++src; + ++dst; + , width); + src += srcskip; + dst += dstskip; + } +#else + /* Memory align at 4-byte boundary, if necessary */ + if ( (long)dst & 0x03 ) { + /* Don't do anything if width is 0 */ + if ( width == 0 ) { + return; + } + --width; + + while ( height-- ) { + /* Perform copy alignment */ + RGB888_RGB555(dst, src); + ++src; + ++dst; + + /* Copy in 4 pixel chunks */ + for ( c=width/4; c; --c ) { + RGB888_RGB555_TWO(dst, src); + src += 2; + dst += 2; + RGB888_RGB555_TWO(dst, src); + src += 2; + dst += 2; + } + /* Get any leftovers */ + switch (width & 3) { + case 3: + RGB888_RGB555(dst, src); + ++src; + ++dst; + case 2: + RGB888_RGB555_TWO(dst, src); + src += 2; + dst += 2; + break; + case 1: + RGB888_RGB555(dst, src); + ++src; + ++dst; + break; + } + src += srcskip; + dst += dstskip; + } + } else { + while ( height-- ) { + /* Copy in 4 pixel chunks */ + for ( c=width/4; c; --c ) { + RGB888_RGB555_TWO(dst, src); + src += 2; + dst += 2; + RGB888_RGB555_TWO(dst, src); + src += 2; + dst += 2; + } + /* Get any leftovers */ + switch (width & 3) { + case 3: + RGB888_RGB555(dst, src); + ++src; + ++dst; + case 2: + RGB888_RGB555_TWO(dst, src); + src += 2; + dst += 2; + break; + case 1: + RGB888_RGB555(dst, src); + ++src; + ++dst; + break; + } + src += srcskip; + dst += dstskip; + } + } +#endif /* USE_DUFFS_LOOP */ +} +/* Special optimized blit for RGB 8-8-8 --> RGB 5-6-5 */ +#define RGB888_RGB565(dst, src) { \ + *(Uint16 *)(dst) = (((*src)&0x00F80000)>>8)| \ + (((*src)&0x0000FC00)>>5)| \ + (((*src)&0x000000F8)>>3); \ +} +#define RGB888_RGB565_TWO(dst, src) { \ + *(Uint32 *)(dst) = (((((src[HI])&0x00F80000)>>8)| \ + (((src[HI])&0x0000FC00)>>5)| \ + (((src[HI])&0x000000F8)>>3))<<16)| \ + (((src[LO])&0x00F80000)>>8)| \ + (((src[LO])&0x0000FC00)>>5)| \ + (((src[LO])&0x000000F8)>>3); \ +} +static void Blit_RGB888_RGB565(SDL_BlitInfo *info) +{ +#ifndef USE_DUFFS_LOOP + int c; +#endif + int width, height; + Uint32 *src; + Uint16 *dst; + int srcskip, dstskip; + + /* Set up some basic variables */ + width = info->d_width; + height = info->d_height; + src = (Uint32 *)info->s_pixels; + srcskip = info->s_skip/4; + dst = (Uint16 *)info->d_pixels; + dstskip = info->d_skip/2; + +#ifdef USE_DUFFS_LOOP + while ( height-- ) { + DUFFS_LOOP( + RGB888_RGB565(dst, src); + ++src; + ++dst; + , width); + src += srcskip; + dst += dstskip; + } +#else + /* Memory align at 4-byte boundary, if necessary */ + if ( (long)dst & 0x03 ) { + /* Don't do anything if width is 0 */ + if ( width == 0 ) { + return; + } + --width; + + while ( height-- ) { + /* Perform copy alignment */ + RGB888_RGB565(dst, src); + ++src; + ++dst; + + /* Copy in 4 pixel chunks */ + for ( c=width/4; c; --c ) { + RGB888_RGB565_TWO(dst, src); + src += 2; + dst += 2; + RGB888_RGB565_TWO(dst, src); + src += 2; + dst += 2; + } + /* Get any leftovers */ + switch (width & 3) { + case 3: + RGB888_RGB565(dst, src); + ++src; + ++dst; + case 2: + RGB888_RGB565_TWO(dst, src); + src += 2; + dst += 2; + break; + case 1: + RGB888_RGB565(dst, src); + ++src; + ++dst; + break; + } + src += srcskip; + dst += dstskip; + } + } else { + while ( height-- ) { + /* Copy in 4 pixel chunks */ + for ( c=width/4; c; --c ) { + RGB888_RGB565_TWO(dst, src); + src += 2; + dst += 2; + RGB888_RGB565_TWO(dst, src); + src += 2; + dst += 2; + } + /* Get any leftovers */ + switch (width & 3) { + case 3: + RGB888_RGB565(dst, src); + ++src; + ++dst; + case 2: + RGB888_RGB565_TWO(dst, src); + src += 2; + dst += 2; + break; + case 1: + RGB888_RGB565(dst, src); + ++src; + ++dst; + break; + } + src += srcskip; + dst += dstskip; + } + } +#endif /* USE_DUFFS_LOOP */ +} + +#endif /* USE_ASMBLIT */ + + +/* Special optimized blit for RGB 5-6-5 --> 32-bit RGB surfaces */ +#if ( SDL_BYTEORDER == SDL_LIL_ENDIAN ) +#define RGB565_32(dst, src, map) (map[src[0]*2] + map[src[1]*2+1]) +#else /* ( SDL_BYTEORDER == SDL_BIG_ENDIAN ) */ +#define RGB565_32(dst, src, map) (map[src[1]*2] + map[src[0]*2+1]) +#endif +static void Blit_RGB565_32(SDL_BlitInfo *info, const Uint32 *map) +{ +#ifndef USE_DUFFS_LOOP + int c; +#endif + int width, height; + Uint8 *src; + Uint32 *dst; + int srcskip, dstskip; + + /* Set up some basic variables */ + width = info->d_width; + height = info->d_height; + src = (Uint8 *)info->s_pixels; + srcskip = info->s_skip; + dst = (Uint32 *)info->d_pixels; + dstskip = info->d_skip/4; + +#ifdef USE_DUFFS_LOOP + while ( height-- ) { + DUFFS_LOOP( + { + *dst++ = RGB565_32(dst, src, map); + src += 2; + }, + width); + src += srcskip; + dst += dstskip; + } +#else + while ( height-- ) { + /* Copy in 4 pixel chunks */ + for ( c=width/4; c; --c ) { + *dst++ = RGB565_32(dst, src, map); + src += 2; + *dst++ = RGB565_32(dst, src, map); + src += 2; + *dst++ = RGB565_32(dst, src, map); + src += 2; + *dst++ = RGB565_32(dst, src, map); + src += 2; + } + /* Get any leftovers */ + switch (width & 3) { + case 3: + *dst++ = RGB565_32(dst, src, map); + src += 2; + case 2: + *dst++ = RGB565_32(dst, src, map); + src += 2; + case 1: + *dst++ = RGB565_32(dst, src, map); + src += 2; + break; + } + src += srcskip; + dst += dstskip; + } +#endif /* USE_DUFFS_LOOP */ +} + +/* Special optimized blit for RGB 5-6-5 --> ARGB 8-8-8-8 */ +static const Uint32 RGB565_ARGB8888_LUT[512] = { + 0x00000000, 0xff000000, 0x00000008, 0xff002000, + 0x00000010, 0xff004000, 0x00000018, 0xff006100, + 0x00000020, 0xff008100, 0x00000029, 0xff00a100, + 0x00000031, 0xff00c200, 0x00000039, 0xff00e200, + 0x00000041, 0xff080000, 0x0000004a, 0xff082000, + 0x00000052, 0xff084000, 0x0000005a, 0xff086100, + 0x00000062, 0xff088100, 0x0000006a, 0xff08a100, + 0x00000073, 0xff08c200, 0x0000007b, 0xff08e200, + 0x00000083, 0xff100000, 0x0000008b, 0xff102000, + 0x00000094, 0xff104000, 0x0000009c, 0xff106100, + 0x000000a4, 0xff108100, 0x000000ac, 0xff10a100, + 0x000000b4, 0xff10c200, 0x000000bd, 0xff10e200, + 0x000000c5, 0xff180000, 0x000000cd, 0xff182000, + 0x000000d5, 0xff184000, 0x000000de, 0xff186100, + 0x000000e6, 0xff188100, 0x000000ee, 0xff18a100, + 0x000000f6, 0xff18c200, 0x000000ff, 0xff18e200, + 0x00000400, 0xff200000, 0x00000408, 0xff202000, + 0x00000410, 0xff204000, 0x00000418, 0xff206100, + 0x00000420, 0xff208100, 0x00000429, 0xff20a100, + 0x00000431, 0xff20c200, 0x00000439, 0xff20e200, + 0x00000441, 0xff290000, 0x0000044a, 0xff292000, + 0x00000452, 0xff294000, 0x0000045a, 0xff296100, + 0x00000462, 0xff298100, 0x0000046a, 0xff29a100, + 0x00000473, 0xff29c200, 0x0000047b, 0xff29e200, + 0x00000483, 0xff310000, 0x0000048b, 0xff312000, + 0x00000494, 0xff314000, 0x0000049c, 0xff316100, + 0x000004a4, 0xff318100, 0x000004ac, 0xff31a100, + 0x000004b4, 0xff31c200, 0x000004bd, 0xff31e200, + 0x000004c5, 0xff390000, 0x000004cd, 0xff392000, + 0x000004d5, 0xff394000, 0x000004de, 0xff396100, + 0x000004e6, 0xff398100, 0x000004ee, 0xff39a100, + 0x000004f6, 0xff39c200, 0x000004ff, 0xff39e200, + 0x00000800, 0xff410000, 0x00000808, 0xff412000, + 0x00000810, 0xff414000, 0x00000818, 0xff416100, + 0x00000820, 0xff418100, 0x00000829, 0xff41a100, + 0x00000831, 0xff41c200, 0x00000839, 0xff41e200, + 0x00000841, 0xff4a0000, 0x0000084a, 0xff4a2000, + 0x00000852, 0xff4a4000, 0x0000085a, 0xff4a6100, + 0x00000862, 0xff4a8100, 0x0000086a, 0xff4aa100, + 0x00000873, 0xff4ac200, 0x0000087b, 0xff4ae200, + 0x00000883, 0xff520000, 0x0000088b, 0xff522000, + 0x00000894, 0xff524000, 0x0000089c, 0xff526100, + 0x000008a4, 0xff528100, 0x000008ac, 0xff52a100, + 0x000008b4, 0xff52c200, 0x000008bd, 0xff52e200, + 0x000008c5, 0xff5a0000, 0x000008cd, 0xff5a2000, + 0x000008d5, 0xff5a4000, 0x000008de, 0xff5a6100, + 0x000008e6, 0xff5a8100, 0x000008ee, 0xff5aa100, + 0x000008f6, 0xff5ac200, 0x000008ff, 0xff5ae200, + 0x00000c00, 0xff620000, 0x00000c08, 0xff622000, + 0x00000c10, 0xff624000, 0x00000c18, 0xff626100, + 0x00000c20, 0xff628100, 0x00000c29, 0xff62a100, + 0x00000c31, 0xff62c200, 0x00000c39, 0xff62e200, + 0x00000c41, 0xff6a0000, 0x00000c4a, 0xff6a2000, + 0x00000c52, 0xff6a4000, 0x00000c5a, 0xff6a6100, + 0x00000c62, 0xff6a8100, 0x00000c6a, 0xff6aa100, + 0x00000c73, 0xff6ac200, 0x00000c7b, 0xff6ae200, + 0x00000c83, 0xff730000, 0x00000c8b, 0xff732000, + 0x00000c94, 0xff734000, 0x00000c9c, 0xff736100, + 0x00000ca4, 0xff738100, 0x00000cac, 0xff73a100, + 0x00000cb4, 0xff73c200, 0x00000cbd, 0xff73e200, + 0x00000cc5, 0xff7b0000, 0x00000ccd, 0xff7b2000, + 0x00000cd5, 0xff7b4000, 0x00000cde, 0xff7b6100, + 0x00000ce6, 0xff7b8100, 0x00000cee, 0xff7ba100, + 0x00000cf6, 0xff7bc200, 0x00000cff, 0xff7be200, + 0x00001000, 0xff830000, 0x00001008, 0xff832000, + 0x00001010, 0xff834000, 0x00001018, 0xff836100, + 0x00001020, 0xff838100, 0x00001029, 0xff83a100, + 0x00001031, 0xff83c200, 0x00001039, 0xff83e200, + 0x00001041, 0xff8b0000, 0x0000104a, 0xff8b2000, + 0x00001052, 0xff8b4000, 0x0000105a, 0xff8b6100, + 0x00001062, 0xff8b8100, 0x0000106a, 0xff8ba100, + 0x00001073, 0xff8bc200, 0x0000107b, 0xff8be200, + 0x00001083, 0xff940000, 0x0000108b, 0xff942000, + 0x00001094, 0xff944000, 0x0000109c, 0xff946100, + 0x000010a4, 0xff948100, 0x000010ac, 0xff94a100, + 0x000010b4, 0xff94c200, 0x000010bd, 0xff94e200, + 0x000010c5, 0xff9c0000, 0x000010cd, 0xff9c2000, + 0x000010d5, 0xff9c4000, 0x000010de, 0xff9c6100, + 0x000010e6, 0xff9c8100, 0x000010ee, 0xff9ca100, + 0x000010f6, 0xff9cc200, 0x000010ff, 0xff9ce200, + 0x00001400, 0xffa40000, 0x00001408, 0xffa42000, + 0x00001410, 0xffa44000, 0x00001418, 0xffa46100, + 0x00001420, 0xffa48100, 0x00001429, 0xffa4a100, + 0x00001431, 0xffa4c200, 0x00001439, 0xffa4e200, + 0x00001441, 0xffac0000, 0x0000144a, 0xffac2000, + 0x00001452, 0xffac4000, 0x0000145a, 0xffac6100, + 0x00001462, 0xffac8100, 0x0000146a, 0xffaca100, + 0x00001473, 0xffacc200, 0x0000147b, 0xfface200, + 0x00001483, 0xffb40000, 0x0000148b, 0xffb42000, + 0x00001494, 0xffb44000, 0x0000149c, 0xffb46100, + 0x000014a4, 0xffb48100, 0x000014ac, 0xffb4a100, + 0x000014b4, 0xffb4c200, 0x000014bd, 0xffb4e200, + 0x000014c5, 0xffbd0000, 0x000014cd, 0xffbd2000, + 0x000014d5, 0xffbd4000, 0x000014de, 0xffbd6100, + 0x000014e6, 0xffbd8100, 0x000014ee, 0xffbda100, + 0x000014f6, 0xffbdc200, 0x000014ff, 0xffbde200, + 0x00001800, 0xffc50000, 0x00001808, 0xffc52000, + 0x00001810, 0xffc54000, 0x00001818, 0xffc56100, + 0x00001820, 0xffc58100, 0x00001829, 0xffc5a100, + 0x00001831, 0xffc5c200, 0x00001839, 0xffc5e200, + 0x00001841, 0xffcd0000, 0x0000184a, 0xffcd2000, + 0x00001852, 0xffcd4000, 0x0000185a, 0xffcd6100, + 0x00001862, 0xffcd8100, 0x0000186a, 0xffcda100, + 0x00001873, 0xffcdc200, 0x0000187b, 0xffcde200, + 0x00001883, 0xffd50000, 0x0000188b, 0xffd52000, + 0x00001894, 0xffd54000, 0x0000189c, 0xffd56100, + 0x000018a4, 0xffd58100, 0x000018ac, 0xffd5a100, + 0x000018b4, 0xffd5c200, 0x000018bd, 0xffd5e200, + 0x000018c5, 0xffde0000, 0x000018cd, 0xffde2000, + 0x000018d5, 0xffde4000, 0x000018de, 0xffde6100, + 0x000018e6, 0xffde8100, 0x000018ee, 0xffdea100, + 0x000018f6, 0xffdec200, 0x000018ff, 0xffdee200, + 0x00001c00, 0xffe60000, 0x00001c08, 0xffe62000, + 0x00001c10, 0xffe64000, 0x00001c18, 0xffe66100, + 0x00001c20, 0xffe68100, 0x00001c29, 0xffe6a100, + 0x00001c31, 0xffe6c200, 0x00001c39, 0xffe6e200, + 0x00001c41, 0xffee0000, 0x00001c4a, 0xffee2000, + 0x00001c52, 0xffee4000, 0x00001c5a, 0xffee6100, + 0x00001c62, 0xffee8100, 0x00001c6a, 0xffeea100, + 0x00001c73, 0xffeec200, 0x00001c7b, 0xffeee200, + 0x00001c83, 0xfff60000, 0x00001c8b, 0xfff62000, + 0x00001c94, 0xfff64000, 0x00001c9c, 0xfff66100, + 0x00001ca4, 0xfff68100, 0x00001cac, 0xfff6a100, + 0x00001cb4, 0xfff6c200, 0x00001cbd, 0xfff6e200, + 0x00001cc5, 0xffff0000, 0x00001ccd, 0xffff2000, + 0x00001cd5, 0xffff4000, 0x00001cde, 0xffff6100, + 0x00001ce6, 0xffff8100, 0x00001cee, 0xffffa100, + 0x00001cf6, 0xffffc200, 0x00001cff, 0xffffe200 +}; +static void Blit_RGB565_ARGB8888(SDL_BlitInfo *info) +{ + Blit_RGB565_32(info, RGB565_ARGB8888_LUT); +} + +/* Special optimized blit for RGB 5-6-5 --> ABGR 8-8-8-8 */ +static const Uint32 RGB565_ABGR8888_LUT[512] = { + 0xff000000, 0x00000000, 0xff080000, 0x00002000, + 0xff100000, 0x00004000, 0xff180000, 0x00006100, + 0xff200000, 0x00008100, 0xff290000, 0x0000a100, + 0xff310000, 0x0000c200, 0xff390000, 0x0000e200, + 0xff410000, 0x00000008, 0xff4a0000, 0x00002008, + 0xff520000, 0x00004008, 0xff5a0000, 0x00006108, + 0xff620000, 0x00008108, 0xff6a0000, 0x0000a108, + 0xff730000, 0x0000c208, 0xff7b0000, 0x0000e208, + 0xff830000, 0x00000010, 0xff8b0000, 0x00002010, + 0xff940000, 0x00004010, 0xff9c0000, 0x00006110, + 0xffa40000, 0x00008110, 0xffac0000, 0x0000a110, + 0xffb40000, 0x0000c210, 0xffbd0000, 0x0000e210, + 0xffc50000, 0x00000018, 0xffcd0000, 0x00002018, + 0xffd50000, 0x00004018, 0xffde0000, 0x00006118, + 0xffe60000, 0x00008118, 0xffee0000, 0x0000a118, + 0xfff60000, 0x0000c218, 0xffff0000, 0x0000e218, + 0xff000400, 0x00000020, 0xff080400, 0x00002020, + 0xff100400, 0x00004020, 0xff180400, 0x00006120, + 0xff200400, 0x00008120, 0xff290400, 0x0000a120, + 0xff310400, 0x0000c220, 0xff390400, 0x0000e220, + 0xff410400, 0x00000029, 0xff4a0400, 0x00002029, + 0xff520400, 0x00004029, 0xff5a0400, 0x00006129, + 0xff620400, 0x00008129, 0xff6a0400, 0x0000a129, + 0xff730400, 0x0000c229, 0xff7b0400, 0x0000e229, + 0xff830400, 0x00000031, 0xff8b0400, 0x00002031, + 0xff940400, 0x00004031, 0xff9c0400, 0x00006131, + 0xffa40400, 0x00008131, 0xffac0400, 0x0000a131, + 0xffb40400, 0x0000c231, 0xffbd0400, 0x0000e231, + 0xffc50400, 0x00000039, 0xffcd0400, 0x00002039, + 0xffd50400, 0x00004039, 0xffde0400, 0x00006139, + 0xffe60400, 0x00008139, 0xffee0400, 0x0000a139, + 0xfff60400, 0x0000c239, 0xffff0400, 0x0000e239, + 0xff000800, 0x00000041, 0xff080800, 0x00002041, + 0xff100800, 0x00004041, 0xff180800, 0x00006141, + 0xff200800, 0x00008141, 0xff290800, 0x0000a141, + 0xff310800, 0x0000c241, 0xff390800, 0x0000e241, + 0xff410800, 0x0000004a, 0xff4a0800, 0x0000204a, + 0xff520800, 0x0000404a, 0xff5a0800, 0x0000614a, + 0xff620800, 0x0000814a, 0xff6a0800, 0x0000a14a, + 0xff730800, 0x0000c24a, 0xff7b0800, 0x0000e24a, + 0xff830800, 0x00000052, 0xff8b0800, 0x00002052, + 0xff940800, 0x00004052, 0xff9c0800, 0x00006152, + 0xffa40800, 0x00008152, 0xffac0800, 0x0000a152, + 0xffb40800, 0x0000c252, 0xffbd0800, 0x0000e252, + 0xffc50800, 0x0000005a, 0xffcd0800, 0x0000205a, + 0xffd50800, 0x0000405a, 0xffde0800, 0x0000615a, + 0xffe60800, 0x0000815a, 0xffee0800, 0x0000a15a, + 0xfff60800, 0x0000c25a, 0xffff0800, 0x0000e25a, + 0xff000c00, 0x00000062, 0xff080c00, 0x00002062, + 0xff100c00, 0x00004062, 0xff180c00, 0x00006162, + 0xff200c00, 0x00008162, 0xff290c00, 0x0000a162, + 0xff310c00, 0x0000c262, 0xff390c00, 0x0000e262, + 0xff410c00, 0x0000006a, 0xff4a0c00, 0x0000206a, + 0xff520c00, 0x0000406a, 0xff5a0c00, 0x0000616a, + 0xff620c00, 0x0000816a, 0xff6a0c00, 0x0000a16a, + 0xff730c00, 0x0000c26a, 0xff7b0c00, 0x0000e26a, + 0xff830c00, 0x00000073, 0xff8b0c00, 0x00002073, + 0xff940c00, 0x00004073, 0xff9c0c00, 0x00006173, + 0xffa40c00, 0x00008173, 0xffac0c00, 0x0000a173, + 0xffb40c00, 0x0000c273, 0xffbd0c00, 0x0000e273, + 0xffc50c00, 0x0000007b, 0xffcd0c00, 0x0000207b, + 0xffd50c00, 0x0000407b, 0xffde0c00, 0x0000617b, + 0xffe60c00, 0x0000817b, 0xffee0c00, 0x0000a17b, + 0xfff60c00, 0x0000c27b, 0xffff0c00, 0x0000e27b, + 0xff001000, 0x00000083, 0xff081000, 0x00002083, + 0xff101000, 0x00004083, 0xff181000, 0x00006183, + 0xff201000, 0x00008183, 0xff291000, 0x0000a183, + 0xff311000, 0x0000c283, 0xff391000, 0x0000e283, + 0xff411000, 0x0000008b, 0xff4a1000, 0x0000208b, + 0xff521000, 0x0000408b, 0xff5a1000, 0x0000618b, + 0xff621000, 0x0000818b, 0xff6a1000, 0x0000a18b, + 0xff731000, 0x0000c28b, 0xff7b1000, 0x0000e28b, + 0xff831000, 0x00000094, 0xff8b1000, 0x00002094, + 0xff941000, 0x00004094, 0xff9c1000, 0x00006194, + 0xffa41000, 0x00008194, 0xffac1000, 0x0000a194, + 0xffb41000, 0x0000c294, 0xffbd1000, 0x0000e294, + 0xffc51000, 0x0000009c, 0xffcd1000, 0x0000209c, + 0xffd51000, 0x0000409c, 0xffde1000, 0x0000619c, + 0xffe61000, 0x0000819c, 0xffee1000, 0x0000a19c, + 0xfff61000, 0x0000c29c, 0xffff1000, 0x0000e29c, + 0xff001400, 0x000000a4, 0xff081400, 0x000020a4, + 0xff101400, 0x000040a4, 0xff181400, 0x000061a4, + 0xff201400, 0x000081a4, 0xff291400, 0x0000a1a4, + 0xff311400, 0x0000c2a4, 0xff391400, 0x0000e2a4, + 0xff411400, 0x000000ac, 0xff4a1400, 0x000020ac, + 0xff521400, 0x000040ac, 0xff5a1400, 0x000061ac, + 0xff621400, 0x000081ac, 0xff6a1400, 0x0000a1ac, + 0xff731400, 0x0000c2ac, 0xff7b1400, 0x0000e2ac, + 0xff831400, 0x000000b4, 0xff8b1400, 0x000020b4, + 0xff941400, 0x000040b4, 0xff9c1400, 0x000061b4, + 0xffa41400, 0x000081b4, 0xffac1400, 0x0000a1b4, + 0xffb41400, 0x0000c2b4, 0xffbd1400, 0x0000e2b4, + 0xffc51400, 0x000000bd, 0xffcd1400, 0x000020bd, + 0xffd51400, 0x000040bd, 0xffde1400, 0x000061bd, + 0xffe61400, 0x000081bd, 0xffee1400, 0x0000a1bd, + 0xfff61400, 0x0000c2bd, 0xffff1400, 0x0000e2bd, + 0xff001800, 0x000000c5, 0xff081800, 0x000020c5, + 0xff101800, 0x000040c5, 0xff181800, 0x000061c5, + 0xff201800, 0x000081c5, 0xff291800, 0x0000a1c5, + 0xff311800, 0x0000c2c5, 0xff391800, 0x0000e2c5, + 0xff411800, 0x000000cd, 0xff4a1800, 0x000020cd, + 0xff521800, 0x000040cd, 0xff5a1800, 0x000061cd, + 0xff621800, 0x000081cd, 0xff6a1800, 0x0000a1cd, + 0xff731800, 0x0000c2cd, 0xff7b1800, 0x0000e2cd, + 0xff831800, 0x000000d5, 0xff8b1800, 0x000020d5, + 0xff941800, 0x000040d5, 0xff9c1800, 0x000061d5, + 0xffa41800, 0x000081d5, 0xffac1800, 0x0000a1d5, + 0xffb41800, 0x0000c2d5, 0xffbd1800, 0x0000e2d5, + 0xffc51800, 0x000000de, 0xffcd1800, 0x000020de, + 0xffd51800, 0x000040de, 0xffde1800, 0x000061de, + 0xffe61800, 0x000081de, 0xffee1800, 0x0000a1de, + 0xfff61800, 0x0000c2de, 0xffff1800, 0x0000e2de, + 0xff001c00, 0x000000e6, 0xff081c00, 0x000020e6, + 0xff101c00, 0x000040e6, 0xff181c00, 0x000061e6, + 0xff201c00, 0x000081e6, 0xff291c00, 0x0000a1e6, + 0xff311c00, 0x0000c2e6, 0xff391c00, 0x0000e2e6, + 0xff411c00, 0x000000ee, 0xff4a1c00, 0x000020ee, + 0xff521c00, 0x000040ee, 0xff5a1c00, 0x000061ee, + 0xff621c00, 0x000081ee, 0xff6a1c00, 0x0000a1ee, + 0xff731c00, 0x0000c2ee, 0xff7b1c00, 0x0000e2ee, + 0xff831c00, 0x000000f6, 0xff8b1c00, 0x000020f6, + 0xff941c00, 0x000040f6, 0xff9c1c00, 0x000061f6, + 0xffa41c00, 0x000081f6, 0xffac1c00, 0x0000a1f6, + 0xffb41c00, 0x0000c2f6, 0xffbd1c00, 0x0000e2f6, + 0xffc51c00, 0x000000ff, 0xffcd1c00, 0x000020ff, + 0xffd51c00, 0x000040ff, 0xffde1c00, 0x000061ff, + 0xffe61c00, 0x000081ff, 0xffee1c00, 0x0000a1ff, + 0xfff61c00, 0x0000c2ff, 0xffff1c00, 0x0000e2ff +}; +static void Blit_RGB565_ABGR8888(SDL_BlitInfo *info) +{ + Blit_RGB565_32(info, RGB565_ABGR8888_LUT); +} + +/* Special optimized blit for RGB 5-6-5 --> RGBA 8-8-8-8 */ +static const Uint32 RGB565_RGBA8888_LUT[512] = { + 0x000000ff, 0x00000000, 0x000008ff, 0x00200000, + 0x000010ff, 0x00400000, 0x000018ff, 0x00610000, + 0x000020ff, 0x00810000, 0x000029ff, 0x00a10000, + 0x000031ff, 0x00c20000, 0x000039ff, 0x00e20000, + 0x000041ff, 0x08000000, 0x00004aff, 0x08200000, + 0x000052ff, 0x08400000, 0x00005aff, 0x08610000, + 0x000062ff, 0x08810000, 0x00006aff, 0x08a10000, + 0x000073ff, 0x08c20000, 0x00007bff, 0x08e20000, + 0x000083ff, 0x10000000, 0x00008bff, 0x10200000, + 0x000094ff, 0x10400000, 0x00009cff, 0x10610000, + 0x0000a4ff, 0x10810000, 0x0000acff, 0x10a10000, + 0x0000b4ff, 0x10c20000, 0x0000bdff, 0x10e20000, + 0x0000c5ff, 0x18000000, 0x0000cdff, 0x18200000, + 0x0000d5ff, 0x18400000, 0x0000deff, 0x18610000, + 0x0000e6ff, 0x18810000, 0x0000eeff, 0x18a10000, + 0x0000f6ff, 0x18c20000, 0x0000ffff, 0x18e20000, + 0x000400ff, 0x20000000, 0x000408ff, 0x20200000, + 0x000410ff, 0x20400000, 0x000418ff, 0x20610000, + 0x000420ff, 0x20810000, 0x000429ff, 0x20a10000, + 0x000431ff, 0x20c20000, 0x000439ff, 0x20e20000, + 0x000441ff, 0x29000000, 0x00044aff, 0x29200000, + 0x000452ff, 0x29400000, 0x00045aff, 0x29610000, + 0x000462ff, 0x29810000, 0x00046aff, 0x29a10000, + 0x000473ff, 0x29c20000, 0x00047bff, 0x29e20000, + 0x000483ff, 0x31000000, 0x00048bff, 0x31200000, + 0x000494ff, 0x31400000, 0x00049cff, 0x31610000, + 0x0004a4ff, 0x31810000, 0x0004acff, 0x31a10000, + 0x0004b4ff, 0x31c20000, 0x0004bdff, 0x31e20000, + 0x0004c5ff, 0x39000000, 0x0004cdff, 0x39200000, + 0x0004d5ff, 0x39400000, 0x0004deff, 0x39610000, + 0x0004e6ff, 0x39810000, 0x0004eeff, 0x39a10000, + 0x0004f6ff, 0x39c20000, 0x0004ffff, 0x39e20000, + 0x000800ff, 0x41000000, 0x000808ff, 0x41200000, + 0x000810ff, 0x41400000, 0x000818ff, 0x41610000, + 0x000820ff, 0x41810000, 0x000829ff, 0x41a10000, + 0x000831ff, 0x41c20000, 0x000839ff, 0x41e20000, + 0x000841ff, 0x4a000000, 0x00084aff, 0x4a200000, + 0x000852ff, 0x4a400000, 0x00085aff, 0x4a610000, + 0x000862ff, 0x4a810000, 0x00086aff, 0x4aa10000, + 0x000873ff, 0x4ac20000, 0x00087bff, 0x4ae20000, + 0x000883ff, 0x52000000, 0x00088bff, 0x52200000, + 0x000894ff, 0x52400000, 0x00089cff, 0x52610000, + 0x0008a4ff, 0x52810000, 0x0008acff, 0x52a10000, + 0x0008b4ff, 0x52c20000, 0x0008bdff, 0x52e20000, + 0x0008c5ff, 0x5a000000, 0x0008cdff, 0x5a200000, + 0x0008d5ff, 0x5a400000, 0x0008deff, 0x5a610000, + 0x0008e6ff, 0x5a810000, 0x0008eeff, 0x5aa10000, + 0x0008f6ff, 0x5ac20000, 0x0008ffff, 0x5ae20000, + 0x000c00ff, 0x62000000, 0x000c08ff, 0x62200000, + 0x000c10ff, 0x62400000, 0x000c18ff, 0x62610000, + 0x000c20ff, 0x62810000, 0x000c29ff, 0x62a10000, + 0x000c31ff, 0x62c20000, 0x000c39ff, 0x62e20000, + 0x000c41ff, 0x6a000000, 0x000c4aff, 0x6a200000, + 0x000c52ff, 0x6a400000, 0x000c5aff, 0x6a610000, + 0x000c62ff, 0x6a810000, 0x000c6aff, 0x6aa10000, + 0x000c73ff, 0x6ac20000, 0x000c7bff, 0x6ae20000, + 0x000c83ff, 0x73000000, 0x000c8bff, 0x73200000, + 0x000c94ff, 0x73400000, 0x000c9cff, 0x73610000, + 0x000ca4ff, 0x73810000, 0x000cacff, 0x73a10000, + 0x000cb4ff, 0x73c20000, 0x000cbdff, 0x73e20000, + 0x000cc5ff, 0x7b000000, 0x000ccdff, 0x7b200000, + 0x000cd5ff, 0x7b400000, 0x000cdeff, 0x7b610000, + 0x000ce6ff, 0x7b810000, 0x000ceeff, 0x7ba10000, + 0x000cf6ff, 0x7bc20000, 0x000cffff, 0x7be20000, + 0x001000ff, 0x83000000, 0x001008ff, 0x83200000, + 0x001010ff, 0x83400000, 0x001018ff, 0x83610000, + 0x001020ff, 0x83810000, 0x001029ff, 0x83a10000, + 0x001031ff, 0x83c20000, 0x001039ff, 0x83e20000, + 0x001041ff, 0x8b000000, 0x00104aff, 0x8b200000, + 0x001052ff, 0x8b400000, 0x00105aff, 0x8b610000, + 0x001062ff, 0x8b810000, 0x00106aff, 0x8ba10000, + 0x001073ff, 0x8bc20000, 0x00107bff, 0x8be20000, + 0x001083ff, 0x94000000, 0x00108bff, 0x94200000, + 0x001094ff, 0x94400000, 0x00109cff, 0x94610000, + 0x0010a4ff, 0x94810000, 0x0010acff, 0x94a10000, + 0x0010b4ff, 0x94c20000, 0x0010bdff, 0x94e20000, + 0x0010c5ff, 0x9c000000, 0x0010cdff, 0x9c200000, + 0x0010d5ff, 0x9c400000, 0x0010deff, 0x9c610000, + 0x0010e6ff, 0x9c810000, 0x0010eeff, 0x9ca10000, + 0x0010f6ff, 0x9cc20000, 0x0010ffff, 0x9ce20000, + 0x001400ff, 0xa4000000, 0x001408ff, 0xa4200000, + 0x001410ff, 0xa4400000, 0x001418ff, 0xa4610000, + 0x001420ff, 0xa4810000, 0x001429ff, 0xa4a10000, + 0x001431ff, 0xa4c20000, 0x001439ff, 0xa4e20000, + 0x001441ff, 0xac000000, 0x00144aff, 0xac200000, + 0x001452ff, 0xac400000, 0x00145aff, 0xac610000, + 0x001462ff, 0xac810000, 0x00146aff, 0xaca10000, + 0x001473ff, 0xacc20000, 0x00147bff, 0xace20000, + 0x001483ff, 0xb4000000, 0x00148bff, 0xb4200000, + 0x001494ff, 0xb4400000, 0x00149cff, 0xb4610000, + 0x0014a4ff, 0xb4810000, 0x0014acff, 0xb4a10000, + 0x0014b4ff, 0xb4c20000, 0x0014bdff, 0xb4e20000, + 0x0014c5ff, 0xbd000000, 0x0014cdff, 0xbd200000, + 0x0014d5ff, 0xbd400000, 0x0014deff, 0xbd610000, + 0x0014e6ff, 0xbd810000, 0x0014eeff, 0xbda10000, + 0x0014f6ff, 0xbdc20000, 0x0014ffff, 0xbde20000, + 0x001800ff, 0xc5000000, 0x001808ff, 0xc5200000, + 0x001810ff, 0xc5400000, 0x001818ff, 0xc5610000, + 0x001820ff, 0xc5810000, 0x001829ff, 0xc5a10000, + 0x001831ff, 0xc5c20000, 0x001839ff, 0xc5e20000, + 0x001841ff, 0xcd000000, 0x00184aff, 0xcd200000, + 0x001852ff, 0xcd400000, 0x00185aff, 0xcd610000, + 0x001862ff, 0xcd810000, 0x00186aff, 0xcda10000, + 0x001873ff, 0xcdc20000, 0x00187bff, 0xcde20000, + 0x001883ff, 0xd5000000, 0x00188bff, 0xd5200000, + 0x001894ff, 0xd5400000, 0x00189cff, 0xd5610000, + 0x0018a4ff, 0xd5810000, 0x0018acff, 0xd5a10000, + 0x0018b4ff, 0xd5c20000, 0x0018bdff, 0xd5e20000, + 0x0018c5ff, 0xde000000, 0x0018cdff, 0xde200000, + 0x0018d5ff, 0xde400000, 0x0018deff, 0xde610000, + 0x0018e6ff, 0xde810000, 0x0018eeff, 0xdea10000, + 0x0018f6ff, 0xdec20000, 0x0018ffff, 0xdee20000, + 0x001c00ff, 0xe6000000, 0x001c08ff, 0xe6200000, + 0x001c10ff, 0xe6400000, 0x001c18ff, 0xe6610000, + 0x001c20ff, 0xe6810000, 0x001c29ff, 0xe6a10000, + 0x001c31ff, 0xe6c20000, 0x001c39ff, 0xe6e20000, + 0x001c41ff, 0xee000000, 0x001c4aff, 0xee200000, + 0x001c52ff, 0xee400000, 0x001c5aff, 0xee610000, + 0x001c62ff, 0xee810000, 0x001c6aff, 0xeea10000, + 0x001c73ff, 0xeec20000, 0x001c7bff, 0xeee20000, + 0x001c83ff, 0xf6000000, 0x001c8bff, 0xf6200000, + 0x001c94ff, 0xf6400000, 0x001c9cff, 0xf6610000, + 0x001ca4ff, 0xf6810000, 0x001cacff, 0xf6a10000, + 0x001cb4ff, 0xf6c20000, 0x001cbdff, 0xf6e20000, + 0x001cc5ff, 0xff000000, 0x001ccdff, 0xff200000, + 0x001cd5ff, 0xff400000, 0x001cdeff, 0xff610000, + 0x001ce6ff, 0xff810000, 0x001ceeff, 0xffa10000, + 0x001cf6ff, 0xffc20000, 0x001cffff, 0xffe20000, +}; +static void Blit_RGB565_RGBA8888(SDL_BlitInfo *info) +{ + Blit_RGB565_32(info, RGB565_RGBA8888_LUT); +} + +/* Special optimized blit for RGB 5-6-5 --> BGRA 8-8-8-8 */ +static const Uint32 RGB565_BGRA8888_LUT[512] = { + 0x00000000, 0x000000ff, 0x08000000, 0x002000ff, + 0x10000000, 0x004000ff, 0x18000000, 0x006100ff, + 0x20000000, 0x008100ff, 0x29000000, 0x00a100ff, + 0x31000000, 0x00c200ff, 0x39000000, 0x00e200ff, + 0x41000000, 0x000008ff, 0x4a000000, 0x002008ff, + 0x52000000, 0x004008ff, 0x5a000000, 0x006108ff, + 0x62000000, 0x008108ff, 0x6a000000, 0x00a108ff, + 0x73000000, 0x00c208ff, 0x7b000000, 0x00e208ff, + 0x83000000, 0x000010ff, 0x8b000000, 0x002010ff, + 0x94000000, 0x004010ff, 0x9c000000, 0x006110ff, + 0xa4000000, 0x008110ff, 0xac000000, 0x00a110ff, + 0xb4000000, 0x00c210ff, 0xbd000000, 0x00e210ff, + 0xc5000000, 0x000018ff, 0xcd000000, 0x002018ff, + 0xd5000000, 0x004018ff, 0xde000000, 0x006118ff, + 0xe6000000, 0x008118ff, 0xee000000, 0x00a118ff, + 0xf6000000, 0x00c218ff, 0xff000000, 0x00e218ff, + 0x00040000, 0x000020ff, 0x08040000, 0x002020ff, + 0x10040000, 0x004020ff, 0x18040000, 0x006120ff, + 0x20040000, 0x008120ff, 0x29040000, 0x00a120ff, + 0x31040000, 0x00c220ff, 0x39040000, 0x00e220ff, + 0x41040000, 0x000029ff, 0x4a040000, 0x002029ff, + 0x52040000, 0x004029ff, 0x5a040000, 0x006129ff, + 0x62040000, 0x008129ff, 0x6a040000, 0x00a129ff, + 0x73040000, 0x00c229ff, 0x7b040000, 0x00e229ff, + 0x83040000, 0x000031ff, 0x8b040000, 0x002031ff, + 0x94040000, 0x004031ff, 0x9c040000, 0x006131ff, + 0xa4040000, 0x008131ff, 0xac040000, 0x00a131ff, + 0xb4040000, 0x00c231ff, 0xbd040000, 0x00e231ff, + 0xc5040000, 0x000039ff, 0xcd040000, 0x002039ff, + 0xd5040000, 0x004039ff, 0xde040000, 0x006139ff, + 0xe6040000, 0x008139ff, 0xee040000, 0x00a139ff, + 0xf6040000, 0x00c239ff, 0xff040000, 0x00e239ff, + 0x00080000, 0x000041ff, 0x08080000, 0x002041ff, + 0x10080000, 0x004041ff, 0x18080000, 0x006141ff, + 0x20080000, 0x008141ff, 0x29080000, 0x00a141ff, + 0x31080000, 0x00c241ff, 0x39080000, 0x00e241ff, + 0x41080000, 0x00004aff, 0x4a080000, 0x00204aff, + 0x52080000, 0x00404aff, 0x5a080000, 0x00614aff, + 0x62080000, 0x00814aff, 0x6a080000, 0x00a14aff, + 0x73080000, 0x00c24aff, 0x7b080000, 0x00e24aff, + 0x83080000, 0x000052ff, 0x8b080000, 0x002052ff, + 0x94080000, 0x004052ff, 0x9c080000, 0x006152ff, + 0xa4080000, 0x008152ff, 0xac080000, 0x00a152ff, + 0xb4080000, 0x00c252ff, 0xbd080000, 0x00e252ff, + 0xc5080000, 0x00005aff, 0xcd080000, 0x00205aff, + 0xd5080000, 0x00405aff, 0xde080000, 0x00615aff, + 0xe6080000, 0x00815aff, 0xee080000, 0x00a15aff, + 0xf6080000, 0x00c25aff, 0xff080000, 0x00e25aff, + 0x000c0000, 0x000062ff, 0x080c0000, 0x002062ff, + 0x100c0000, 0x004062ff, 0x180c0000, 0x006162ff, + 0x200c0000, 0x008162ff, 0x290c0000, 0x00a162ff, + 0x310c0000, 0x00c262ff, 0x390c0000, 0x00e262ff, + 0x410c0000, 0x00006aff, 0x4a0c0000, 0x00206aff, + 0x520c0000, 0x00406aff, 0x5a0c0000, 0x00616aff, + 0x620c0000, 0x00816aff, 0x6a0c0000, 0x00a16aff, + 0x730c0000, 0x00c26aff, 0x7b0c0000, 0x00e26aff, + 0x830c0000, 0x000073ff, 0x8b0c0000, 0x002073ff, + 0x940c0000, 0x004073ff, 0x9c0c0000, 0x006173ff, + 0xa40c0000, 0x008173ff, 0xac0c0000, 0x00a173ff, + 0xb40c0000, 0x00c273ff, 0xbd0c0000, 0x00e273ff, + 0xc50c0000, 0x00007bff, 0xcd0c0000, 0x00207bff, + 0xd50c0000, 0x00407bff, 0xde0c0000, 0x00617bff, + 0xe60c0000, 0x00817bff, 0xee0c0000, 0x00a17bff, + 0xf60c0000, 0x00c27bff, 0xff0c0000, 0x00e27bff, + 0x00100000, 0x000083ff, 0x08100000, 0x002083ff, + 0x10100000, 0x004083ff, 0x18100000, 0x006183ff, + 0x20100000, 0x008183ff, 0x29100000, 0x00a183ff, + 0x31100000, 0x00c283ff, 0x39100000, 0x00e283ff, + 0x41100000, 0x00008bff, 0x4a100000, 0x00208bff, + 0x52100000, 0x00408bff, 0x5a100000, 0x00618bff, + 0x62100000, 0x00818bff, 0x6a100000, 0x00a18bff, + 0x73100000, 0x00c28bff, 0x7b100000, 0x00e28bff, + 0x83100000, 0x000094ff, 0x8b100000, 0x002094ff, + 0x94100000, 0x004094ff, 0x9c100000, 0x006194ff, + 0xa4100000, 0x008194ff, 0xac100000, 0x00a194ff, + 0xb4100000, 0x00c294ff, 0xbd100000, 0x00e294ff, + 0xc5100000, 0x00009cff, 0xcd100000, 0x00209cff, + 0xd5100000, 0x00409cff, 0xde100000, 0x00619cff, + 0xe6100000, 0x00819cff, 0xee100000, 0x00a19cff, + 0xf6100000, 0x00c29cff, 0xff100000, 0x00e29cff, + 0x00140000, 0x0000a4ff, 0x08140000, 0x0020a4ff, + 0x10140000, 0x0040a4ff, 0x18140000, 0x0061a4ff, + 0x20140000, 0x0081a4ff, 0x29140000, 0x00a1a4ff, + 0x31140000, 0x00c2a4ff, 0x39140000, 0x00e2a4ff, + 0x41140000, 0x0000acff, 0x4a140000, 0x0020acff, + 0x52140000, 0x0040acff, 0x5a140000, 0x0061acff, + 0x62140000, 0x0081acff, 0x6a140000, 0x00a1acff, + 0x73140000, 0x00c2acff, 0x7b140000, 0x00e2acff, + 0x83140000, 0x0000b4ff, 0x8b140000, 0x0020b4ff, + 0x94140000, 0x0040b4ff, 0x9c140000, 0x0061b4ff, + 0xa4140000, 0x0081b4ff, 0xac140000, 0x00a1b4ff, + 0xb4140000, 0x00c2b4ff, 0xbd140000, 0x00e2b4ff, + 0xc5140000, 0x0000bdff, 0xcd140000, 0x0020bdff, + 0xd5140000, 0x0040bdff, 0xde140000, 0x0061bdff, + 0xe6140000, 0x0081bdff, 0xee140000, 0x00a1bdff, + 0xf6140000, 0x00c2bdff, 0xff140000, 0x00e2bdff, + 0x00180000, 0x0000c5ff, 0x08180000, 0x0020c5ff, + 0x10180000, 0x0040c5ff, 0x18180000, 0x0061c5ff, + 0x20180000, 0x0081c5ff, 0x29180000, 0x00a1c5ff, + 0x31180000, 0x00c2c5ff, 0x39180000, 0x00e2c5ff, + 0x41180000, 0x0000cdff, 0x4a180000, 0x0020cdff, + 0x52180000, 0x0040cdff, 0x5a180000, 0x0061cdff, + 0x62180000, 0x0081cdff, 0x6a180000, 0x00a1cdff, + 0x73180000, 0x00c2cdff, 0x7b180000, 0x00e2cdff, + 0x83180000, 0x0000d5ff, 0x8b180000, 0x0020d5ff, + 0x94180000, 0x0040d5ff, 0x9c180000, 0x0061d5ff, + 0xa4180000, 0x0081d5ff, 0xac180000, 0x00a1d5ff, + 0xb4180000, 0x00c2d5ff, 0xbd180000, 0x00e2d5ff, + 0xc5180000, 0x0000deff, 0xcd180000, 0x0020deff, + 0xd5180000, 0x0040deff, 0xde180000, 0x0061deff, + 0xe6180000, 0x0081deff, 0xee180000, 0x00a1deff, + 0xf6180000, 0x00c2deff, 0xff180000, 0x00e2deff, + 0x001c0000, 0x0000e6ff, 0x081c0000, 0x0020e6ff, + 0x101c0000, 0x0040e6ff, 0x181c0000, 0x0061e6ff, + 0x201c0000, 0x0081e6ff, 0x291c0000, 0x00a1e6ff, + 0x311c0000, 0x00c2e6ff, 0x391c0000, 0x00e2e6ff, + 0x411c0000, 0x0000eeff, 0x4a1c0000, 0x0020eeff, + 0x521c0000, 0x0040eeff, 0x5a1c0000, 0x0061eeff, + 0x621c0000, 0x0081eeff, 0x6a1c0000, 0x00a1eeff, + 0x731c0000, 0x00c2eeff, 0x7b1c0000, 0x00e2eeff, + 0x831c0000, 0x0000f6ff, 0x8b1c0000, 0x0020f6ff, + 0x941c0000, 0x0040f6ff, 0x9c1c0000, 0x0061f6ff, + 0xa41c0000, 0x0081f6ff, 0xac1c0000, 0x00a1f6ff, + 0xb41c0000, 0x00c2f6ff, 0xbd1c0000, 0x00e2f6ff, + 0xc51c0000, 0x0000ffff, 0xcd1c0000, 0x0020ffff, + 0xd51c0000, 0x0040ffff, 0xde1c0000, 0x0061ffff, + 0xe61c0000, 0x0081ffff, 0xee1c0000, 0x00a1ffff, + 0xf61c0000, 0x00c2ffff, 0xff1c0000, 0x00e2ffff +}; +static void Blit_RGB565_BGRA8888(SDL_BlitInfo *info) +{ + Blit_RGB565_32(info, RGB565_BGRA8888_LUT); +} + +/* Special optimized blit for RGB 8-8-8 --> RGB 3-3-2 */ +#ifndef RGB888_RGB332 +#define RGB888_RGB332(dst, src) { \ + dst = (((src)&0x00E00000)>>16)| \ + (((src)&0x0000E000)>>11)| \ + (((src)&0x000000C0)>>6); \ +} +#endif +static void Blit_RGB888_index8_map(SDL_BlitInfo *info) +{ +#ifndef USE_DUFFS_LOOP + int c; +#endif + int pixel; + int width, height; + Uint32 *src; + const Uint8 *map; + Uint8 *dst; + int srcskip, dstskip; + + /* Set up some basic variables */ + width = info->d_width; + height = info->d_height; + src = (Uint32 *)info->s_pixels; + srcskip = info->s_skip/4; + dst = info->d_pixels; + dstskip = info->d_skip; + map = info->table; + +#ifdef USE_DUFFS_LOOP + while ( height-- ) { + DUFFS_LOOP( + RGB888_RGB332(pixel, *src); + *dst++ = map[pixel]; + ++src; + , width); + src += srcskip; + dst += dstskip; + } +#else + while ( height-- ) { + for ( c=width/4; c; --c ) { + /* Pack RGB into 8bit pixel */ + RGB888_RGB332(pixel, *src); + *dst++ = map[pixel]; + ++src; + RGB888_RGB332(pixel, *src); + *dst++ = map[pixel]; + ++src; + RGB888_RGB332(pixel, *src); + *dst++ = map[pixel]; + ++src; + RGB888_RGB332(pixel, *src); + *dst++ = map[pixel]; + ++src; + } + switch ( width & 3 ) { + case 3: + RGB888_RGB332(pixel, *src); + *dst++ = map[pixel]; + ++src; + case 2: + RGB888_RGB332(pixel, *src); + *dst++ = map[pixel]; + ++src; + case 1: + RGB888_RGB332(pixel, *src); + *dst++ = map[pixel]; + ++src; + } + src += srcskip; + dst += dstskip; + } +#endif /* USE_DUFFS_LOOP */ +} +static void BlitNto1(SDL_BlitInfo *info) +{ +#ifndef USE_DUFFS_LOOP + int c; +#endif + int width, height; + Uint8 *src; + const Uint8 *map; + Uint8 *dst; + int srcskip, dstskip; + int srcbpp; + Uint32 pixel; + int sR, sG, sB; + SDL_PixelFormat *srcfmt; + + /* Set up some basic variables */ + width = info->d_width; + height = info->d_height; + src = info->s_pixels; + srcskip = info->s_skip; + dst = info->d_pixels; + dstskip = info->d_skip; + map = info->table; + srcfmt = info->src; + srcbpp = srcfmt->BytesPerPixel; + + if ( map == NULL ) { + while ( height-- ) { +#ifdef USE_DUFFS_LOOP + DUFFS_LOOP( + DISEMBLE_RGB(src, srcbpp, srcfmt, pixel, + sR, sG, sB); + if ( 1 ) { + /* Pack RGB into 8bit pixel */ + *dst = ((sR>>5)<<(3+2))| + ((sG>>5)<<(2)) | + ((sB>>6)<<(0)) ; + } + dst++; + src += srcbpp; + , width); +#else + for ( c=width; c; --c ) { + DISEMBLE_RGB(src, srcbpp, srcfmt, pixel, + sR, sG, sB); + if ( 1 ) { + /* Pack RGB into 8bit pixel */ + *dst = ((sR>>5)<<(3+2))| + ((sG>>5)<<(2)) | + ((sB>>6)<<(0)) ; + } + dst++; + src += srcbpp; + } +#endif + src += srcskip; + dst += dstskip; + } + } else { + while ( height-- ) { +#ifdef USE_DUFFS_LOOP + DUFFS_LOOP( + DISEMBLE_RGB(src, srcbpp, srcfmt, pixel, + sR, sG, sB); + if ( 1 ) { + /* Pack RGB into 8bit pixel */ + *dst = map[((sR>>5)<<(3+2))| + ((sG>>5)<<(2)) | + ((sB>>6)<<(0)) ]; + } + dst++; + src += srcbpp; + , width); +#else + for ( c=width; c; --c ) { + DISEMBLE_RGB(src, srcbpp, srcfmt, pixel, + sR, sG, sB); + if ( 1 ) { + /* Pack RGB into 8bit pixel */ + *dst = map[((sR>>5)<<(3+2))| + ((sG>>5)<<(2)) | + ((sB>>6)<<(0)) ]; + } + dst++; + src += srcbpp; + } +#endif /* USE_DUFFS_LOOP */ + src += srcskip; + dst += dstskip; + } + } +} +static void BlitNtoN(SDL_BlitInfo *info) +{ + int width = info->d_width; + int height = info->d_height; + Uint8 *src = info->s_pixels; + int srcskip = info->s_skip; + Uint8 *dst = info->d_pixels; + int dstskip = info->d_skip; + SDL_PixelFormat *srcfmt = info->src; + int srcbpp = srcfmt->BytesPerPixel; + SDL_PixelFormat *dstfmt = info->dst; + int dstbpp = dstfmt->BytesPerPixel; + unsigned alpha = dstfmt->Amask ? SDL_ALPHA_OPAQUE : 0; + + while ( height-- ) { + DUFFS_LOOP( + { + Uint32 pixel; + unsigned sR; + unsigned sG; + unsigned sB; + DISEMBLE_RGB(src, srcbpp, srcfmt, pixel, sR, sG, sB); + ASSEMBLE_RGBA(dst, dstbpp, dstfmt, sR, sG, sB, alpha); + dst += dstbpp; + src += srcbpp; + }, + width); + src += srcskip; + dst += dstskip; + } +} + +static void BlitNtoNCopyAlpha(SDL_BlitInfo *info) +{ + int width = info->d_width; + int height = info->d_height; + Uint8 *src = info->s_pixels; + int srcskip = info->s_skip; + Uint8 *dst = info->d_pixels; + int dstskip = info->d_skip; + SDL_PixelFormat *srcfmt = info->src; + int srcbpp = srcfmt->BytesPerPixel; + SDL_PixelFormat *dstfmt = info->dst; + int dstbpp = dstfmt->BytesPerPixel; + int c; + + /* FIXME: should map alpha to [0..255] correctly! */ + while ( height-- ) { + for ( c=width; c; --c ) { + Uint32 pixel; + unsigned sR, sG, sB, sA; + DISEMBLE_RGBA(src, srcbpp, srcfmt, pixel, + sR, sG, sB, sA); + ASSEMBLE_RGBA(dst, dstbpp, dstfmt, + sR, sG, sB, sA); + dst += dstbpp; + src += srcbpp; + } + src += srcskip; + dst += dstskip; + } +} + +static void BlitNto1Key(SDL_BlitInfo *info) +{ + int width = info->d_width; + int height = info->d_height; + Uint8 *src = info->s_pixels; + int srcskip = info->s_skip; + Uint8 *dst = info->d_pixels; + int dstskip = info->d_skip; + SDL_PixelFormat *srcfmt = info->src; + const Uint8 *palmap = info->table; + Uint32 ckey = srcfmt->colorkey; + Uint32 rgbmask = ~srcfmt->Amask; + int srcbpp; + Uint32 pixel; + Uint8 sR, sG, sB; + + /* Set up some basic variables */ + srcbpp = srcfmt->BytesPerPixel; + ckey &= rgbmask; + + if ( palmap == NULL ) { + while ( height-- ) { + DUFFS_LOOP( + { + DISEMBLE_RGB(src, srcbpp, srcfmt, pixel, + sR, sG, sB); + if ( (pixel & rgbmask) != ckey ) { + /* Pack RGB into 8bit pixel */ + *dst = ((sR>>5)<<(3+2))| + ((sG>>5)<<(2)) | + ((sB>>6)<<(0)) ; + } + dst++; + src += srcbpp; + }, + width); + src += srcskip; + dst += dstskip; + } + } else { + while ( height-- ) { + DUFFS_LOOP( + { + DISEMBLE_RGB(src, srcbpp, srcfmt, pixel, + sR, sG, sB); + if ( (pixel & rgbmask) != ckey ) { + /* Pack RGB into 8bit pixel */ + *dst = palmap[((sR>>5)<<(3+2))| + ((sG>>5)<<(2)) | + ((sB>>6)<<(0)) ]; + } + dst++; + src += srcbpp; + }, + width); + src += srcskip; + dst += dstskip; + } + } +} + +static void Blit2to2Key(SDL_BlitInfo *info) +{ + int width = info->d_width; + int height = info->d_height; + Uint16 *srcp = (Uint16 *)info->s_pixels; + int srcskip = info->s_skip; + Uint16 *dstp = (Uint16 *)info->d_pixels; + int dstskip = info->d_skip; + Uint32 ckey = info->src->colorkey; + Uint32 rgbmask = ~info->src->Amask; + + /* Set up some basic variables */ + srcskip /= 2; + dstskip /= 2; + ckey &= rgbmask; + + while ( height-- ) { + DUFFS_LOOP( + { + if ( (*srcp & rgbmask) != ckey ) { + *dstp = *srcp; + } + dstp++; + srcp++; + }, + width); + srcp += srcskip; + dstp += dstskip; + } +} + +static void BlitNtoNKey(SDL_BlitInfo *info) +{ + int width = info->d_width; + int height = info->d_height; + Uint8 *src = info->s_pixels; + int srcskip = info->s_skip; + Uint8 *dst = info->d_pixels; + int dstskip = info->d_skip; + Uint32 ckey = info->src->colorkey; + SDL_PixelFormat *srcfmt = info->src; + SDL_PixelFormat *dstfmt = info->dst; + int srcbpp = srcfmt->BytesPerPixel; + int dstbpp = dstfmt->BytesPerPixel; + unsigned alpha = dstfmt->Amask ? SDL_ALPHA_OPAQUE : 0; + + while ( height-- ) { + DUFFS_LOOP( + { + Uint32 pixel; + unsigned sR; + unsigned sG; + unsigned sB; + RETRIEVE_RGB_PIXEL(src, srcbpp, pixel); + if ( pixel != ckey ) { + RGB_FROM_PIXEL(pixel, srcfmt, sR, sG, sB); + ASSEMBLE_RGBA(dst, dstbpp, dstfmt, + sR, sG, sB, alpha); + } + dst += dstbpp; + src += srcbpp; + }, + width); + src += srcskip; + dst += dstskip; + } +} + +static void BlitNtoNKeyCopyAlpha(SDL_BlitInfo *info) +{ + int width = info->d_width; + int height = info->d_height; + Uint8 *src = info->s_pixels; + int srcskip = info->s_skip; + Uint8 *dst = info->d_pixels; + int dstskip = info->d_skip; + Uint32 ckey = info->src->colorkey; + SDL_PixelFormat *srcfmt = info->src; + SDL_PixelFormat *dstfmt = info->dst; + Uint32 rgbmask = ~srcfmt->Amask; + + Uint8 srcbpp; + Uint8 dstbpp; + Uint32 pixel; + Uint8 sR, sG, sB, sA; + + /* Set up some basic variables */ + srcbpp = srcfmt->BytesPerPixel; + dstbpp = dstfmt->BytesPerPixel; + ckey &= rgbmask; + + /* FIXME: should map alpha to [0..255] correctly! */ + while ( height-- ) { + DUFFS_LOOP( + { + DISEMBLE_RGBA(src, srcbpp, srcfmt, pixel, + sR, sG, sB, sA); + if ( (pixel & rgbmask) != ckey ) { + ASSEMBLE_RGBA(dst, dstbpp, dstfmt, + sR, sG, sB, sA); + } + dst += dstbpp; + src += srcbpp; + }, + width); + src += srcskip; + dst += dstskip; + } +} + +/* Normal N to N optimized blitters */ +struct blit_table { + Uint32 srcR, srcG, srcB; + int dstbpp; + Uint32 dstR, dstG, dstB; + Uint32 cpu_flags; + void *aux_data; + SDL_loblit blitfunc; + enum { NO_ALPHA, SET_ALPHA, COPY_ALPHA } alpha; +}; +static const struct blit_table normal_blit_1[] = { + /* Default for 8-bit RGB source, an invalid combination */ + { 0,0,0, 0, 0,0,0, 0, NULL, NULL }, +}; +static const struct blit_table normal_blit_2[] = { +#ifdef USE_ASMBLIT + { 0x0000F800,0x000007E0,0x0000001F, 2, 0x0000001F,0x000007E0,0x0000F800, + 0, ConvertX86p16_16BGR565, ConvertX86, NO_ALPHA }, + { 0x0000F800,0x000007E0,0x0000001F, 2, 0x00007C00,0x000003E0,0x0000001F, + 0, ConvertX86p16_16RGB555, ConvertX86, NO_ALPHA }, + { 0x0000F800,0x000007E0,0x0000001F, 2, 0x0000001F,0x000003E0,0x00007C00, + 0, ConvertX86p16_16BGR555, ConvertX86, NO_ALPHA }, +#endif + { 0x0000F800,0x000007E0,0x0000001F, 4, 0x00FF0000,0x0000FF00,0x000000FF, + 0, NULL, Blit_RGB565_ARGB8888, SET_ALPHA }, + { 0x0000F800,0x000007E0,0x0000001F, 4, 0x000000FF,0x0000FF00,0x00FF0000, + 0, NULL, Blit_RGB565_ABGR8888, SET_ALPHA }, + { 0x0000F800,0x000007E0,0x0000001F, 4, 0xFF000000,0x00FF0000,0x0000FF00, + 0, NULL, Blit_RGB565_RGBA8888, SET_ALPHA }, + { 0x0000F800,0x000007E0,0x0000001F, 4, 0x0000FF00,0x00FF0000,0xFF000000, + 0, NULL, Blit_RGB565_BGRA8888, SET_ALPHA }, + + /* Default for 16-bit RGB source, used if no other blitter matches */ + { 0,0,0, 0, 0,0,0, 0, NULL, BlitNtoN, 0 } +}; +static const struct blit_table normal_blit_3[] = { + /* Default for 24-bit RGB source, never optimized */ + { 0,0,0, 0, 0,0,0, 0, NULL, BlitNtoN, 0 } +}; +static const struct blit_table normal_blit_4[] = { +#ifdef USE_ASMBLIT + { 0x00FF0000,0x0000FF00,0x000000FF, 2, 0x0000F800,0x000007E0,0x0000001F, + MMX_CPU, ConvertMMXpII32_16RGB565, ConvertMMX, NO_ALPHA }, + { 0x00FF0000,0x0000FF00,0x000000FF, 2, 0x0000F800,0x000007E0,0x0000001F, + 0, ConvertX86p32_16RGB565, ConvertX86, NO_ALPHA }, + { 0x00FF0000,0x0000FF00,0x000000FF, 2, 0x0000001F,0x000007E0,0x0000F800, + MMX_CPU, ConvertMMXpII32_16BGR565, ConvertMMX, NO_ALPHA }, + { 0x00FF0000,0x0000FF00,0x000000FF, 2, 0x0000001F,0x000007E0,0x0000F800, + 0, ConvertX86p32_16BGR565, ConvertX86, NO_ALPHA }, + { 0x00FF0000,0x0000FF00,0x000000FF, 2, 0x00007C00,0x000003E0,0x0000001F, + MMX_CPU, ConvertMMXpII32_16RGB555, ConvertMMX, NO_ALPHA }, + { 0x00FF0000,0x0000FF00,0x000000FF, 2, 0x00007C00,0x000003E0,0x0000001F, + 0, ConvertX86p32_16RGB555, ConvertX86, NO_ALPHA }, + { 0x00FF0000,0x0000FF00,0x000000FF, 2, 0x0000001F,0x000003E0,0x00007C00, + MMX_CPU, ConvertMMXpII32_16BGR555, ConvertMMX, NO_ALPHA }, + { 0x00FF0000,0x0000FF00,0x000000FF, 2, 0x0000001F,0x000003E0,0x00007C00, + 0, ConvertX86p32_16BGR555, ConvertX86, NO_ALPHA }, + { 0x00FF0000,0x0000FF00,0x000000FF, 3, 0x00FF0000,0x0000FF00,0x000000FF, + 0, ConvertX86p32_24RGB888, ConvertX86, NO_ALPHA }, + { 0x00FF0000,0x0000FF00,0x000000FF, 3, 0x000000FF,0x0000FF00,0x00FF0000, + 0, ConvertX86p32_24BGR888, ConvertX86, NO_ALPHA }, + { 0x00FF0000,0x0000FF00,0x000000FF, 4, 0x000000FF,0x0000FF00,0x00FF0000, + 0, ConvertX86p32_32BGR888, ConvertX86, NO_ALPHA }, + { 0x00FF0000,0x0000FF00,0x000000FF, 4, 0xFF000000,0x00FF0000,0x0000FF00, + 0, ConvertX86p32_32RGBA888, ConvertX86, NO_ALPHA }, + { 0x00FF0000,0x0000FF00,0x000000FF, 4, 0x0000FF00,0x00FF0000,0xFF000000, + 0, ConvertX86p32_32BGRA888, ConvertX86, NO_ALPHA }, +#else + { 0x00FF0000,0x0000FF00,0x000000FF, 2, 0x0000F800,0x000007E0,0x0000001F, + 0, NULL, Blit_RGB888_RGB565, NO_ALPHA }, + { 0x00FF0000,0x0000FF00,0x000000FF, 2, 0x00007C00,0x000003E0,0x0000001F, + 0, NULL, Blit_RGB888_RGB555, NO_ALPHA }, +#endif + /* Default for 32-bit RGB source, used if no other blitter matches */ + { 0,0,0, 0, 0,0,0, 0, NULL, BlitNtoN, 0 } +}; +static const struct blit_table *normal_blit[] = { + normal_blit_1, normal_blit_2, normal_blit_3, normal_blit_4 +}; + +SDL_loblit SDL_CalculateBlitN(SDL_Surface *surface, int blit_index) +{ + struct private_swaccel *sdata; + SDL_PixelFormat *srcfmt; + SDL_PixelFormat *dstfmt; + const struct blit_table *table; + int which; + SDL_loblit blitfun; + + /* Set up data for choosing the blit */ + sdata = surface->map->sw_data; + srcfmt = surface->format; + dstfmt = surface->map->dst->format; + + if ( blit_index & 2 ) { + /* alpha or alpha+colorkey */ + return SDL_CalculateAlphaBlit(surface, blit_index); + } + + /* We don't support destinations less than 8-bits */ + if ( dstfmt->BitsPerPixel < 8 ) { + return(NULL); + } + + if(blit_index == 1) { + /* colorkey blit: Here we don't have too many options, mostly + because RLE is the preferred fast way to deal with this. + If a particular case turns out to be useful we'll add it. */ + + if(srcfmt->BytesPerPixel == 2 + && surface->map->identity) + return Blit2to2Key; + else if(dstfmt->BytesPerPixel == 1) + return BlitNto1Key; + else { + if(srcfmt->Amask && dstfmt->Amask) + return BlitNtoNKeyCopyAlpha; + else + return BlitNtoNKey; + } + } + + blitfun = NULL; + if ( dstfmt->BitsPerPixel == 8 ) { + /* We assume 8-bit destinations are palettized */ + if ( (srcfmt->BytesPerPixel == 4) && + (srcfmt->Rmask == 0x00FF0000) && + (srcfmt->Gmask == 0x0000FF00) && + (srcfmt->Bmask == 0x000000FF) ) { + if ( surface->map->table ) { + blitfun = Blit_RGB888_index8_map; + } else { +#ifdef USE_ASMBLIT + sdata->aux_data = ConvertX86p32_8RGB332; + blitfun = ConvertX86; +#else + blitfun = Blit_RGB888_index8; +#endif + } + } else { + blitfun = BlitNto1; + } + } else { + /* Now the meat, choose the blitter we want */ + int a_need = 0; + if(dstfmt->Amask) + a_need = srcfmt->Amask ? COPY_ALPHA : SET_ALPHA; + table = normal_blit[srcfmt->BytesPerPixel-1]; + for ( which=0; table[which].srcR; ++which ) { + if ( srcfmt->Rmask == table[which].srcR && + srcfmt->Gmask == table[which].srcG && + srcfmt->Bmask == table[which].srcB && + dstfmt->BytesPerPixel == table[which].dstbpp && + dstfmt->Rmask == table[which].dstR && + dstfmt->Gmask == table[which].dstG && + dstfmt->Bmask == table[which].dstB && + (a_need & table[which].alpha) == a_need && + (CPU_Flags()&table[which].cpu_flags) == + table[which].cpu_flags ) + break; + } + sdata->aux_data = table[which].aux_data; + blitfun = table[which].blitfunc; + if(a_need == COPY_ALPHA && blitfun == BlitNtoN) + blitfun = BlitNtoNCopyAlpha; + } + +#ifdef DEBUG_ASM +#ifdef USE_ASMBLIT + if ( blitfun == ConvertMMX ) + SDL_printf("Using mmx blit\n"); + else + if ( blitfun == ConvertX86 ) + SDL_printf("Using asm blit\n"); + else +#endif + if ( (blitfun == SDL_BlitNtoN) || (blitfun == SDL_BlitNto1) ) + fprintf(stderr, "Using C blit\n"); + else + fprintf(stderr, "Using optimized C blit\n"); +#endif /* DEBUG_ASM */ + + return(blitfun); +} diff --git a/contrib/sdk/sources/SDL-1.2.2/src/video/SDL_bmp.c b/contrib/sdk/sources/SDL-1.2.2/src/video/SDL_bmp.c new file mode 100644 index 000000000..22b3dd6ee --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/src/video/SDL_bmp.c @@ -0,0 +1,523 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997, 1998, 1999, 2000, 2001 Sam Lantinga + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the Free + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + Sam Lantinga + slouken@devolution.com +*/ + + +#ifndef DISABLE_FILE + +/* + Code to load and save surfaces in Windows BMP format. + + Why support BMP format? Well, it's a native format for Windows, and + most image processing programs can read and write it. It would be nice + to be able to have at least one image format that we can natively load + and save, and since PNG is so complex that it would bloat the library, + BMP is a good alternative. + + This code currently supports Win32 DIBs in uncompressed 8 and 24 bpp. +*/ + +#include + +#include "SDL_error.h" +#include "SDL_video.h" +#include "SDL_endian.h" + +/* Compression encodings for BMP files */ +#ifndef BI_RGB +#define BI_RGB 0 +#define BI_RLE8 1 +#define BI_RLE4 2 +#define BI_BITFIELDS 3 +#endif + + +SDL_Surface * SDL_LoadBMP_RW (SDL_RWops *src, int freesrc) +{ + int was_error; + long fp_offset; + int bmpPitch; + int i, pad; + SDL_Surface *surface; + Uint32 Rmask; + Uint32 Gmask; + Uint32 Bmask; + SDL_Palette *palette; + Uint8 *bits; + int ExpandBMP; + + /* The Win32 BMP file header (14 bytes) */ + char magic[2]; + Uint32 bfSize; + Uint16 bfReserved1; + Uint16 bfReserved2; + Uint32 bfOffBits; + + /* The Win32 BITMAPINFOHEADER struct (40 bytes) */ + Uint32 biSize; + Sint32 biWidth; + Sint32 biHeight; + Uint16 biPlanes; + Uint16 biBitCount; + Uint32 biCompression; + Uint32 biSizeImage; + Sint32 biXPelsPerMeter; + Sint32 biYPelsPerMeter; + Uint32 biClrUsed; + Uint32 biClrImportant; + + /* Make sure we are passed a valid data source */ + surface = NULL; + was_error = 0; + if ( src == NULL ) { + was_error = 1; + goto done; + } + + /* Read in the BMP file header */ + fp_offset = SDL_RWtell(src); + SDL_ClearError(); + if ( SDL_RWread(src, magic, 1, 2) != 2 ) { + SDL_Error(SDL_EFREAD); + was_error = 1; + goto done; + } + if ( strncmp(magic, "BM", 2) != 0 ) { + SDL_SetError("File is not a Windows BMP file"); + was_error = 1; + goto done; + } + bfSize = SDL_ReadLE32(src); + bfReserved1 = SDL_ReadLE16(src); + bfReserved2 = SDL_ReadLE16(src); + bfOffBits = SDL_ReadLE32(src); + + /* Read the Win32 BITMAPINFOHEADER */ + biSize = SDL_ReadLE32(src); + if ( biSize == 12 ) { + biWidth = (Uint32)SDL_ReadLE16(src); + biHeight = (Uint32)SDL_ReadLE16(src); + biPlanes = SDL_ReadLE16(src); + biBitCount = SDL_ReadLE16(src); + biCompression = BI_RGB; + biSizeImage = 0; + biXPelsPerMeter = 0; + biYPelsPerMeter = 0; + biClrUsed = 0; + biClrImportant = 0; + } else { + biWidth = SDL_ReadLE32(src); + biHeight = SDL_ReadLE32(src); + biPlanes = SDL_ReadLE16(src); + biBitCount = SDL_ReadLE16(src); + biCompression = SDL_ReadLE32(src); + biSizeImage = SDL_ReadLE32(src); + biXPelsPerMeter = SDL_ReadLE32(src); + biYPelsPerMeter = SDL_ReadLE32(src); + biClrUsed = SDL_ReadLE32(src); + biClrImportant = SDL_ReadLE32(src); + } + + /* Check for read error */ + if ( strcmp(SDL_GetError(), "") != 0 ) { + was_error = 1; + goto done; + } + + /* Expand 1 and 4 bit bitmaps to 8 bits per pixel */ + switch (biBitCount) { + case 1: + case 4: + ExpandBMP = biBitCount; + biBitCount = 8; + break; + default: + ExpandBMP = 0; + break; + } + + /* We don't support any BMP compression right now */ + Rmask = Gmask = Bmask = 0; + switch (biCompression) { + case BI_RGB: + /* If there are no masks, use the defaults */ + if ( bfOffBits == (14+biSize) ) { + /* Default values for the BMP format */ + switch (biBitCount) { + case 15: + case 16: + Rmask = 0x7C00; + Gmask = 0x03E0; + Bmask = 0x001F; + break; + case 24: +#if SDL_BYTEORDER == SDL_BIG_ENDIAN + Rmask = 0x000000FF; + Gmask = 0x0000FF00; + Bmask = 0x00FF0000; + break; +#endif + case 32: + Rmask = 0x00FF0000; + Gmask = 0x0000FF00; + Bmask = 0x000000FF; + break; + default: + break; + } + break; + } + /* Fall through -- read the RGB masks */ + + case BI_BITFIELDS: + switch (biBitCount) { + case 15: + case 16: + case 32: + Rmask = SDL_ReadLE32(src); + Gmask = SDL_ReadLE32(src); + Bmask = SDL_ReadLE32(src); + break; + default: + break; + } + break; + default: + SDL_SetError("Compressed BMP files not supported"); + was_error = 1; + goto done; + } + + /* Create a compatible surface, note that the colors are RGB ordered */ + surface = SDL_CreateRGBSurface(SDL_SWSURFACE, + biWidth, biHeight, biBitCount, Rmask, Gmask, Bmask, 0); + if ( surface == NULL ) { + was_error = 1; + goto done; + } + + /* Load the palette, if any */ + palette = (surface->format)->palette; + if ( palette ) { + if ( biClrUsed == 0 ) { + biClrUsed = 1 << biBitCount; + } + if ( biSize == 12 ) { + for ( i = 0; i < (int)biClrUsed; ++i ) { + SDL_RWread(src, &palette->colors[i].b, 1, 1); + SDL_RWread(src, &palette->colors[i].g, 1, 1); + SDL_RWread(src, &palette->colors[i].r, 1, 1); + palette->colors[i].unused = 0; + } + } else { + for ( i = 0; i < (int)biClrUsed; ++i ) { + SDL_RWread(src, &palette->colors[i].b, 1, 1); + SDL_RWread(src, &palette->colors[i].g, 1, 1); + SDL_RWread(src, &palette->colors[i].r, 1, 1); + SDL_RWread(src, &palette->colors[i].unused, 1, 1); + } + } + palette->ncolors = biClrUsed; + } + + /* Read the surface pixels. Note that the bmp image is upside down */ + if ( SDL_RWseek(src, fp_offset+bfOffBits, SEEK_SET) < 0 ) { + SDL_Error(SDL_EFSEEK); + was_error = 1; + goto done; + } + bits = (Uint8 *)surface->pixels+(surface->h*surface->pitch); + switch (ExpandBMP) { + case 1: + bmpPitch = (biWidth + 7) >> 3; + pad = (((bmpPitch)%4) ? (4-((bmpPitch)%4)) : 0); + break; + case 4: + bmpPitch = (biWidth + 1) >> 1; + pad = (((bmpPitch)%4) ? (4-((bmpPitch)%4)) : 0); + break; + default: + pad = ((surface->pitch%4) ? + (4-(surface->pitch%4)) : 0); + break; + } + while ( bits > (Uint8 *)surface->pixels ) { + bits -= surface->pitch; + switch (ExpandBMP) { + case 1: + case 4: { + Uint8 pixel = 0; + int shift = (8-ExpandBMP); + for ( i=0; iw; ++i ) { + if ( i%(8/ExpandBMP) == 0 ) { + if ( !SDL_RWread(src, &pixel, 1, 1) ) { + SDL_SetError( + "Error reading from BMP"); + was_error = 1; + goto done; + } + } + *(bits+i) = (pixel>>shift); + pixel <<= ExpandBMP; + } } + break; + + default: + if ( SDL_RWread(src, bits, 1, surface->pitch) + != surface->pitch ) { + SDL_Error(SDL_EFREAD); + was_error = 1; + goto done; + } +#if SDL_BYTEORDER == SDL_BIG_ENDIAN + /* Byte-swap the pixels if needed. Note that the 24bpp + case has already been taken care of above. */ + switch(biBitCount) { + case 15: + case 16: { + Uint16 *pix = (Uint16 *)bits; + for(i = 0; i < surface->w; i++) + pix[i] = SDL_Swap16(pix[i]); + break; + } + + case 32: { + Uint32 *pix = (Uint32 *)bits; + for(i = 0; i < surface->w; i++) + pix[i] = SDL_Swap32(pix[i]); + break; + } + } +#endif + break; + } + /* Skip padding bytes, ugh */ + if ( pad ) { + Uint8 padbyte; + for ( i=0; iformat->palette ) { + if ( saveme->format->BitsPerPixel == 8 ) { + surface = saveme; + } else { + SDL_SetError("%d bpp BMP files not supported", + saveme->format->BitsPerPixel); + } + } + else if ( (saveme->format->BitsPerPixel == 24) && +#if SDL_BYTEORDER == SDL_LIL_ENDIAN + (saveme->format->Rmask == 0x00FF0000) && + (saveme->format->Gmask == 0x0000FF00) && + (saveme->format->Bmask == 0x000000FF) +#else + (saveme->format->Rmask == 0x000000FF) && + (saveme->format->Gmask == 0x0000FF00) && + (saveme->format->Bmask == 0x00FF0000) +#endif + ) { + surface = saveme; + } else { + SDL_Rect bounds; + + /* Convert to 24 bits per pixel */ + surface = SDL_CreateRGBSurface(SDL_SWSURFACE, + saveme->w, saveme->h, 24, +#if SDL_BYTEORDER == SDL_LIL_ENDIAN + 0x00FF0000, 0x0000FF00, 0x000000FF, +#else + 0x000000FF, 0x0000FF00, 0x00FF0000, +#endif + 0); + if ( surface != NULL ) { + bounds.x = 0; + bounds.y = 0; + bounds.w = saveme->w; + bounds.h = saveme->h; + if ( SDL_LowerBlit(saveme, &bounds, surface, + &bounds) < 0 ) { + SDL_FreeSurface(surface); + SDL_SetError( + "Couldn't convert image to 24 bpp"); + surface = NULL; + } + } + } + } + + if ( surface && (SDL_LockSurface(surface) == 0) ) { + /* Set the BMP file header values */ + bfSize = 0; /* We'll write this when we're done */ + bfReserved1 = 0; + bfReserved2 = 0; + bfOffBits = 0; /* We'll write this when we're done */ + + /* Write the BMP file header values */ + fp_offset = SDL_RWtell(dst); + SDL_ClearError(); + SDL_RWwrite(dst, magic, 2, 1); + SDL_WriteLE32(dst, bfSize); + SDL_WriteLE16(dst, bfReserved1); + SDL_WriteLE16(dst, bfReserved2); + SDL_WriteLE32(dst, bfOffBits); + + /* Set the BMP info values */ + biSize = 40; + biWidth = surface->w; + biHeight = surface->h; + biPlanes = 1; + biBitCount = surface->format->BitsPerPixel; + biCompression = BI_RGB; + biSizeImage = surface->h*surface->pitch; + biXPelsPerMeter = 0; + biYPelsPerMeter = 0; + if ( surface->format->palette ) { + biClrUsed = surface->format->palette->ncolors; + } else { + biClrUsed = 0; + } + biClrImportant = 0; + + /* Write the BMP info values */ + SDL_WriteLE32(dst, biSize); + SDL_WriteLE32(dst, biWidth); + SDL_WriteLE32(dst, biHeight); + SDL_WriteLE16(dst, biPlanes); + SDL_WriteLE16(dst, biBitCount); + SDL_WriteLE32(dst, biCompression); + SDL_WriteLE32(dst, biSizeImage); + SDL_WriteLE32(dst, biXPelsPerMeter); + SDL_WriteLE32(dst, biYPelsPerMeter); + SDL_WriteLE32(dst, biClrUsed); + SDL_WriteLE32(dst, biClrImportant); + + /* Write the palette (in BGR color order) */ + if ( surface->format->palette ) { + SDL_Color *colors; + int ncolors; + + colors = surface->format->palette->colors; + ncolors = surface->format->palette->ncolors; + for ( i=0; ipixels+(surface->h*surface->pitch); + pad = ((surface->pitch%4) ? (4-(surface->pitch%4)) : 0); + while ( bits > (Uint8 *)surface->pixels ) { + bits -= surface->pitch; + if ( SDL_RWwrite(dst, bits, 1, surface->pitch) + != surface->pitch) { + SDL_Error(SDL_EFWRITE); + break; + } + if ( pad ) { + const Uint8 padbyte = 0; + for ( i=0; i +#include +#include + +#include "SDL_mutex.h" +#include "SDL_error.h" +#include "SDL_video.h" +#include "SDL_mouse.h" +#include "SDL_blit.h" +#include "SDL_events_c.h" +#include "SDL_sysvideo.h" +#include "SDL_sysevents.h" +#include "SDL_cursor_c.h" +#include "SDL_pixels_c.h" +#include "default_cursor.h" + +/* These are static for our cursor handling code */ +volatile int SDL_cursorstate = 0; +SDL_Cursor *SDL_cursor = NULL; +static SDL_Cursor *SDL_defcursor = NULL; +SDL_mutex *SDL_cursorlock = NULL; + +/* Public functions */ +void SDL_CursorQuit(void) +{ + if ( SDL_cursor != NULL ) { + SDL_Cursor *cursor; + + SDL_cursorstate &= ~CURSOR_VISIBLE; + if ( SDL_cursor != SDL_defcursor ) { + SDL_FreeCursor(SDL_cursor); + } + SDL_cursor = NULL; + if ( SDL_defcursor != NULL ) { + cursor = SDL_defcursor; + SDL_defcursor = NULL; + SDL_FreeCursor(cursor); + } + } + if ( SDL_cursorlock != NULL ) { + SDL_DestroyMutex(SDL_cursorlock); + SDL_cursorlock = NULL; + } +} +int SDL_CursorInit(Uint32 multithreaded) +{ + /* We don't have mouse focus, and the cursor isn't drawn yet */ + SDL_cursorstate = CURSOR_VISIBLE; + + /* Create the default cursor */ + if ( SDL_defcursor == NULL ) { + SDL_defcursor = SDL_CreateCursor(default_cdata, default_cmask, + DEFAULT_CWIDTH, DEFAULT_CHEIGHT, + DEFAULT_CHOTX, DEFAULT_CHOTY); + SDL_SetCursor(SDL_defcursor); + } + + /* Create a lock if necessary */ + if ( multithreaded ) { + SDL_cursorlock = SDL_CreateMutex(); + } + + /* That's it! */ + return(0); +} + +/* Multi-thread support for cursors */ +#ifndef SDL_LockCursor +void SDL_LockCursor(void) +{ + if ( SDL_cursorlock ) { + SDL_mutexP(SDL_cursorlock); + } +} +#endif +#ifndef SDL_UnlockCursor +void SDL_UnlockCursor(void) +{ + if ( SDL_cursorlock ) { + SDL_mutexV(SDL_cursorlock); + } +} +#endif + +/* Software cursor drawing support */ +SDL_Cursor * SDL_CreateCursor (Uint8 *data, Uint8 *mask, + int w, int h, int hot_x, int hot_y) +{ + SDL_VideoDevice *video = current_video; + int savelen; + int i; + SDL_Cursor *cursor; + + /* Make sure the width is a multiple of 8 */ + w = ((w+7)&~7); + + /* Sanity check the hot spot */ + if ( (hot_x < 0) || (hot_y < 0) || (hot_x >= w) || (hot_y >= h) ) { + SDL_SetError("Cursor hot spot doesn't lie within cursor"); + return(NULL); + } + + /* Allocate memory for the cursor */ + cursor = (SDL_Cursor *)malloc(sizeof *cursor); + if ( cursor == NULL ) { + SDL_OutOfMemory(); + return(NULL); + } + savelen = (w*4)*h; + cursor->area.x = 0; + cursor->area.y = 0; + cursor->area.w = w; + cursor->area.h = h; + cursor->hot_x = hot_x; + cursor->hot_y = hot_y; + cursor->data = (Uint8 *)malloc((w/8)*h*2); + cursor->mask = cursor->data+((w/8)*h); + cursor->save[0] = (Uint8 *)malloc(savelen*2); + cursor->save[1] = cursor->save[0] + savelen; + cursor->wm_cursor = NULL; + if ( ! cursor->data || ! cursor->save[0] ) { + SDL_FreeCursor(cursor); + SDL_OutOfMemory(); + return(NULL); + } + for ( i=((w/8)*h)-1; i>=0; --i ) { + cursor->data[i] = data[i]; + cursor->mask[i] = mask[i] | data[i]; + } + memset(cursor->save[0], 0, savelen*2); + + /* If the window manager gives us a good cursor, we're done! */ + if ( video->CreateWMCursor ) { + cursor->wm_cursor = video->CreateWMCursor(video, data, mask, + w, h, hot_x, hot_y); + } else { + cursor->wm_cursor = NULL; + } + return(cursor); +} + +/* SDL_SetCursor(NULL) can be used to force the cursor redraw, + if this is desired for any reason. This is used when setting + the video mode and when the SDL window gains the mouse focus. + */ +void SDL_SetCursor (SDL_Cursor *cursor) +{ + SDL_VideoDevice *video = current_video; + SDL_VideoDevice *this = current_video; + + /* Make sure that the video subsystem has been initialized */ + if ( ! video ) { + return; + } + + /* Prevent the event thread from moving the mouse */ + SDL_LockCursor(); + + /* Set the new cursor */ + if ( cursor && (cursor != SDL_cursor) ) { + /* Erase the current mouse position */ + if ( SHOULD_DRAWCURSOR(SDL_cursorstate) ) { + SDL_EraseCursor(SDL_VideoSurface); + } else if ( video->MoveWMCursor ) { + /* If the video driver is moving the cursor directly, + it needs to hide the old cursor before (possibly) + showing the new one. (But don't erase NULL cursor) + */ + if ( SDL_cursor ) { + video->ShowWMCursor(this, NULL); + } + } + SDL_cursor = cursor; + } + + /* Draw the new mouse cursor */ + if ( SDL_cursor && (SDL_cursorstate&CURSOR_VISIBLE) ) { + /* Use window manager cursor if possible */ + if ( SDL_cursor->wm_cursor && + video->ShowWMCursor(this, SDL_cursor->wm_cursor) ) + SDL_cursorstate &= ~CURSOR_USINGSW; + else { + SDL_cursorstate |= CURSOR_USINGSW; + if ( video->ShowWMCursor ) { + video->ShowWMCursor(this, NULL); + } + { int x, y; + SDL_GetMouseState(&x, &y); + SDL_cursor->area.x = (x - SDL_cursor->hot_x); + SDL_cursor->area.y = (y - SDL_cursor->hot_y); + } + SDL_DrawCursor(SDL_VideoSurface); + } + } else { + /* Erase window manager mouse (cursor not visible) */ + if ( SDL_cursor && (SDL_cursorstate & CURSOR_USINGSW) ) { + SDL_EraseCursor(SDL_VideoSurface); + } else { + if ( video ) { + video->ShowWMCursor(this, NULL); + } + } + } + SDL_UnlockCursor(); +} + +SDL_Cursor * SDL_GetCursor (void) +{ + return(SDL_cursor); +} + +void SDL_FreeCursor (SDL_Cursor *cursor) +{ + if ( cursor ) { + if ( cursor == SDL_cursor ) { + SDL_SetCursor(SDL_defcursor); + } + if ( cursor != SDL_defcursor ) { + SDL_VideoDevice *video = current_video; + SDL_VideoDevice *this = current_video; + + if ( cursor->data ) { + free(cursor->data); + } + if ( cursor->save[0] ) { + free(cursor->save[0]); + } + if ( video && cursor->wm_cursor ) { + video->FreeWMCursor(this, cursor->wm_cursor); + } + free(cursor); + } + } +} + +int SDL_ShowCursor (int toggle) +{ + int showing; + + showing = (SDL_cursorstate & CURSOR_VISIBLE); + if ( toggle >= 0 ) { + SDL_LockCursor(); + if ( toggle ) { + SDL_cursorstate |= CURSOR_VISIBLE; + } else { + SDL_cursorstate &= ~CURSOR_VISIBLE; + } + SDL_UnlockCursor(); + if ( (SDL_cursorstate & CURSOR_VISIBLE) != showing ) { + SDL_VideoDevice *video = current_video; + SDL_VideoDevice *this = current_video; + + SDL_SetCursor(NULL); + if ( video && video->CheckMouseMode ) { + video->CheckMouseMode(this); + } + } + } else { + /* Query current state */ ; + } + return(showing ? 1 : 0); +} + +void SDL_WarpMouse (Uint16 x, Uint16 y) +{ + SDL_VideoDevice *video = current_video; + SDL_VideoDevice *this = current_video; + + /* This generates a mouse motion event */ + if ( video->WarpWMCursor ) { + video->WarpWMCursor(this, x, y); + } else { + x += (this->screen->offset % this->screen->pitch) / + this->screen->format->BytesPerPixel; + y += (this->screen->offset / this->screen->pitch); + SDL_PrivateMouseMotion(0, 0, x, y); + } +} + +void SDL_MoveCursor(int x, int y) +{ + SDL_VideoDevice *video = current_video; + + /* Erase and update the current mouse position */ + if ( SHOULD_DRAWCURSOR(SDL_cursorstate) ) { + /* Erase and redraw mouse cursor in new position */ + SDL_LockCursor(); + SDL_EraseCursor(SDL_VideoSurface); + SDL_cursor->area.x = (x - SDL_cursor->hot_x); + SDL_cursor->area.y = (y - SDL_cursor->hot_y); + SDL_DrawCursor(SDL_VideoSurface); + SDL_UnlockCursor(); + } else if ( video->MoveWMCursor ) { + video->MoveWMCursor(video, x, y); + } +} + +/* Keep track of the current cursor colors */ +static int palette_changed = 1; +static Uint32 pixels8[2]; + +void SDL_CursorPaletteChanged(void) +{ + palette_changed = 1; +} + +void SDL_MouseRect(SDL_Rect *area) +{ + int clip_diff; + + *area = SDL_cursor->area; + if ( area->x < 0 ) { + area->w += area->x; + area->x = 0; + } + if ( area->y < 0 ) { + area->h += area->y; + area->y = 0; + } + clip_diff = (area->x+area->w)-SDL_VideoSurface->w; + if ( clip_diff > 0 ) { + area->w = area->w < clip_diff ? 0 : area->w-clip_diff; + } + clip_diff = (area->y+area->h)-SDL_VideoSurface->h; + if ( clip_diff > 0 ) { + area->h = area->h < clip_diff ? 0 : area->h-clip_diff; + } +} + +static void SDL_DrawCursorFast(SDL_Surface *screen, SDL_Rect *area) +{ + const Uint32 pixels[2] = { 0xFFFFFFFF, 0x00000000 }; + int i, w, h; + Uint8 *data, datab; + Uint8 *mask, maskb; + + data = SDL_cursor->data + area->y * SDL_cursor->area.w/8; + mask = SDL_cursor->mask + area->y * SDL_cursor->area.w/8; + switch (screen->format->BytesPerPixel) { + + case 1: { + Uint8 *dst; + int dstskip; + + if ( palette_changed ) { + pixels8[0] = SDL_MapRGB(screen->format, 255, 255, 255); + pixels8[1] = SDL_MapRGB(screen->format, 0, 0, 0); + palette_changed = 0; + } + dst = (Uint8 *)screen->pixels + + (SDL_cursor->area.y+area->y)*screen->pitch + + SDL_cursor->area.x; + dstskip = screen->pitch-area->w; + + for ( h=area->h; h; h-- ) { + for ( w=area->w/8; w; w-- ) { + maskb = *mask++; + datab = *data++; + for ( i=0; i<8; ++i ) { + if ( maskb & 0x80 ) { + *dst = pixels8[datab>>7]; + } + maskb <<= 1; + datab <<= 1; + dst++; + } + } + dst += dstskip; + } + } + break; + + case 2: { + Uint16 *dst; + int dstskip; + + dst = (Uint16 *)screen->pixels + + (SDL_cursor->area.y+area->y)*screen->pitch/2 + + SDL_cursor->area.x; + dstskip = (screen->pitch/2)-area->w; + + for ( h=area->h; h; h-- ) { + for ( w=area->w/8; w; w-- ) { + maskb = *mask++; + datab = *data++; + for ( i=0; i<8; ++i ) { + if ( maskb & 0x80 ) { + *dst = pixels[datab>>7]; + } + maskb <<= 1; + datab <<= 1; + dst++; + } + } + dst += dstskip; + } + } + break; + + case 3: { + Uint8 *dst; + int dstskip; + + dst = (Uint8 *)screen->pixels + + (SDL_cursor->area.y+area->y)*screen->pitch + + SDL_cursor->area.x*3; + dstskip = screen->pitch-area->w*3; + + for ( h=area->h; h; h-- ) { + for ( w=area->w/8; w; w-- ) { + maskb = *mask++; + datab = *data++; + for ( i=0; i<8; ++i ) { + if ( maskb & 0x80 ) { + memset(dst,pixels[datab>>7],3); + } + maskb <<= 1; + datab <<= 1; + dst += 3; + } + } + dst += dstskip; + } + } + break; + + case 4: { + Uint32 *dst; + int dstskip; + + dst = (Uint32 *)screen->pixels + + (SDL_cursor->area.y+area->y)*screen->pitch/4 + + SDL_cursor->area.x; + dstskip = (screen->pitch/4)-area->w; + + for ( h=area->h; h; h-- ) { + for ( w=area->w/8; w; w-- ) { + maskb = *mask++; + datab = *data++; + for ( i=0; i<8; ++i ) { + if ( maskb & 0x80 ) { + *dst = pixels[datab>>7]; + } + maskb <<= 1; + datab <<= 1; + dst++; + } + } + dst += dstskip; + } + } + break; + } +} + +static void SDL_DrawCursorSlow(SDL_Surface *screen, SDL_Rect *area) +{ + const Uint32 pixels[2] = { 0xFFFFFF, 0x000000 }; + int h; + int x, minx, maxx; + Uint8 *data, datab = 0; + Uint8 *mask, maskb = 0; + Uint8 *dst; + int dstbpp, dstskip; + + data = SDL_cursor->data + area->y * SDL_cursor->area.w/8; + mask = SDL_cursor->mask + area->y * SDL_cursor->area.w/8; + dstbpp = screen->format->BytesPerPixel; + dst = (Uint8 *)screen->pixels + + (SDL_cursor->area.y+area->y)*screen->pitch + + SDL_cursor->area.x*dstbpp; + dstskip = screen->pitch-SDL_cursor->area.w*dstbpp; + + minx = area->x; + maxx = area->x+area->w; + if ( screen->format->BytesPerPixel == 1 ) { + if ( palette_changed ) { + pixels8[0] = SDL_MapRGB(screen->format, 255, 255, 255); + pixels8[1] = SDL_MapRGB(screen->format, 0, 0, 0); + palette_changed = 0; + } + for ( h=area->h; h; h-- ) { + for ( x=0; xarea.w; ++x ) { + if ( (x%8) == 0 ) { + maskb = *mask++; + datab = *data++; + } + if ( (x >= minx) && (x < maxx) ) { + if ( maskb & 0x80 ) { + memset(dst, pixels8[datab>>7], dstbpp); + } + } + maskb <<= 1; + datab <<= 1; + dst += dstbpp; + } + dst += dstskip; + } + } else { + for ( h=area->h; h; h-- ) { + for ( x=0; xarea.w; ++x ) { + if ( (x%8) == 0 ) { + maskb = *mask++; + datab = *data++; + } + if ( (x >= minx) && (x < maxx) ) { + if ( maskb & 0x80 ) { + memset(dst, pixels[datab>>7], dstbpp); + } + } + maskb <<= 1; + datab <<= 1; + dst += dstbpp; + } + dst += dstskip; + } + } +} + +/* This handles the ugly work of converting the saved cursor background from + the pixel format of the shadow surface to that of the video surface. + This is only necessary when blitting from a shadow surface of a different + pixel format than the video surface, and using a software rendered cursor. +*/ +static void SDL_ConvertCursorSave(SDL_Surface *screen, int w, int h) +{ + SDL_BlitInfo info; + SDL_loblit RunBlit; + + /* Make sure we can steal the blit mapping */ + if ( screen->map->dst != SDL_VideoSurface ) { + return; + } + + /* Set up the blit information */ + info.s_pixels = SDL_cursor->save[1]; + info.s_width = w; + info.s_height = h; + info.s_skip = 0; + info.d_pixels = SDL_cursor->save[0]; + info.d_width = w; + info.d_height = h; + info.d_skip = 0; + info.aux_data = screen->map->sw_data->aux_data; + info.src = screen->format; + info.table = screen->map->table; + info.dst = SDL_VideoSurface->format; + RunBlit = screen->map->sw_data->blit; + + /* Run the actual software blit */ + RunBlit(&info); +} + +void SDL_DrawCursorNoLock(SDL_Surface *screen) +{ + SDL_Rect area; + + /* Get the mouse rectangle, clipped to the screen */ + SDL_MouseRect(&area); + if ( (area.w == 0) || (area.h == 0) ) { + return; + } + + /* Copy mouse background */ + { int w, h, screenbpp; + Uint8 *src, *dst; + + /* Set up the copy pointers */ + screenbpp = screen->format->BytesPerPixel; + if ( (screen == SDL_VideoSurface) || + FORMAT_EQUAL(screen->format, SDL_VideoSurface->format) ) { + dst = SDL_cursor->save[0]; + } else { + dst = SDL_cursor->save[1]; + } + src = (Uint8 *)screen->pixels + area.y * screen->pitch + + area.x * screenbpp; + + /* Perform the copy */ + w = area.w*screenbpp; + h = area.h; + while ( h-- ) { + memcpy(dst, src, w); + dst += w; + src += screen->pitch; + } + } + + /* Draw the mouse cursor */ + area.x -= SDL_cursor->area.x; + area.y -= SDL_cursor->area.y; + if ( (area.x == 0) && (area.w == SDL_cursor->area.w) ) { + SDL_DrawCursorFast(screen, &area); + } else { + SDL_DrawCursorSlow(screen, &area); + } +} + +void SDL_DrawCursor(SDL_Surface *screen) +{ + /* Lock the screen if necessary */ + if ( screen == NULL ) { + return; + } + if ( SDL_MUSTLOCK(screen) ) { + if ( SDL_LockSurface(screen) < 0 ) { + return; + } + } + + SDL_DrawCursorNoLock(screen); + + /* Unlock the screen and update if necessary */ + if ( SDL_MUSTLOCK(screen) ) { + SDL_UnlockSurface(screen); + } + if ( (screen == SDL_VideoSurface) && + ((screen->flags & SDL_HWSURFACE) != SDL_HWSURFACE) ) { + SDL_VideoDevice *video = current_video; + SDL_VideoDevice *this = current_video; + SDL_Rect area; + + SDL_MouseRect(&area); + + /* This can be called before a video mode is set */ + if ( video->UpdateRects ) { + video->UpdateRects(this, 1, &area); + } + } +} + +void SDL_EraseCursorNoLock(SDL_Surface *screen) +{ + SDL_Rect area; + + /* Get the mouse rectangle, clipped to the screen */ + SDL_MouseRect(&area); + if ( (area.w == 0) || (area.h == 0) ) { + return; + } + + /* Copy mouse background */ + { int w, h, screenbpp; + Uint8 *src, *dst; + + /* Set up the copy pointers */ + screenbpp = screen->format->BytesPerPixel; + if ( (screen == SDL_VideoSurface) || + FORMAT_EQUAL(screen->format, SDL_VideoSurface->format) ) { + src = SDL_cursor->save[0]; + } else { + src = SDL_cursor->save[1]; + } + dst = (Uint8 *)screen->pixels + area.y * screen->pitch + + area.x * screenbpp; + + /* Perform the copy */ + w = area.w*screenbpp; + h = area.h; + while ( h-- ) { + memcpy(dst, src, w); + src += w; + dst += screen->pitch; + } + + /* Perform pixel conversion on cursor background */ + if ( src > SDL_cursor->save[1] ) { + SDL_ConvertCursorSave(screen, area.w, area.h); + } + } +} + +void SDL_EraseCursor(SDL_Surface *screen) +{ + /* Lock the screen if necessary */ + if ( screen == NULL ) { + return; + } + if ( SDL_MUSTLOCK(screen) ) { + if ( SDL_LockSurface(screen) < 0 ) { + return; + } + } + + SDL_EraseCursorNoLock(screen); + + /* Unlock the screen and update if necessary */ + if ( SDL_MUSTLOCK(screen) ) { + SDL_UnlockSurface(screen); + } + if ( (screen == SDL_VideoSurface) && + ((screen->flags & SDL_HWSURFACE) != SDL_HWSURFACE) ) { + SDL_VideoDevice *video = current_video; + SDL_VideoDevice *this = current_video; + SDL_Rect area; + + SDL_MouseRect(&area); + if ( video->UpdateRects ) { + video->UpdateRects(this, 1, &area); + } + } +} + +/* Reset the cursor on video mode change + FIXME: Keep track of all cursors, and reset them all. + */ +void SDL_ResetCursor(void) +{ + int savelen; + + if ( SDL_cursor ) { + savelen = SDL_cursor->area.w*4*SDL_cursor->area.h; + SDL_cursor->area.x = 0; + SDL_cursor->area.y = 0; + memset(SDL_cursor->save[0], 0, savelen); + } +} diff --git a/contrib/sdk/sources/SDL-1.2.2/src/video/SDL_cursor_c.h b/contrib/sdk/sources/SDL-1.2.2/src/video/SDL_cursor_c.h new file mode 100644 index 000000000..72c363186 --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/src/video/SDL_cursor_c.h @@ -0,0 +1,77 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997, 1998, 1999, 2000, 2001 Sam Lantinga + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the Free + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + Sam Lantinga + slouken@devolution.com +*/ + +#ifdef SAVE_RCSID +static char rcsid = + "@(#) $Id: SDL_cursor_c.h,v 1.2 2001/04/26 16:50:18 hercules Exp $"; +#endif + +/* Useful variables and functions from SDL_cursor.c */ +#include "SDL_mouse.h" + +extern int SDL_CursorInit(Uint32 flags); +extern void SDL_CursorPaletteChanged(void); +extern void SDL_DrawCursor(SDL_Surface *screen); +extern void SDL_DrawCursorNoLock(SDL_Surface *screen); +extern void SDL_EraseCursor(SDL_Surface *screen); +extern void SDL_EraseCursorNoLock(SDL_Surface *screen); +extern void SDL_UpdateCursor(SDL_Surface *screen); +extern void SDL_ResetCursor(void); +extern void SDL_MoveCursor(int x, int y); +extern void SDL_CursorQuit(void); + +#define INLINE_MOUSELOCK +#ifdef INLINE_MOUSELOCK +/* Inline (macro) versions of the mouse lock functions */ +#include "SDL_mutex.h" + +extern SDL_mutex *SDL_cursorlock; + +#define SDL_LockCursor() \ + do { \ + if ( SDL_cursorlock ) { \ + SDL_mutexP(SDL_cursorlock); \ + } \ + } while ( 0 ) +#define SDL_UnlockCursor() \ + do { \ + if ( SDL_cursorlock ) { \ + SDL_mutexV(SDL_cursorlock); \ + } \ + } while ( 0 ) +#else +extern void SDL_LockCursor(void); +extern void SDL_UnlockCursor(void); +#endif /* INLINE_MOUSELOCK */ + +/* Only for low-level mouse cursor drawing */ +extern SDL_Cursor *SDL_cursor; +extern void SDL_MouseRect(SDL_Rect *area); + +/* State definitions for the SDL cursor */ +#define CURSOR_VISIBLE 0x01 +#define CURSOR_USINGSW 0x10 +#define SHOULD_DRAWCURSOR(X) \ + (((X)&(CURSOR_VISIBLE|CURSOR_USINGSW)) == \ + (CURSOR_VISIBLE|CURSOR_USINGSW)) + +extern volatile int SDL_cursorstate; diff --git a/contrib/sdk/sources/SDL-1.2.2/src/video/SDL_gamma.c b/contrib/sdk/sources/SDL-1.2.2/src/video/SDL_gamma.c new file mode 100644 index 000000000..c847e1f48 --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/src/video/SDL_gamma.c @@ -0,0 +1,238 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997, 1998, 1999, 2000, 2001 Sam Lantinga + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the Free + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + Sam Lantinga + slouken@devolution.com +*/ + + +/* Gamma correction support */ + +#define USE_MATH_H /* Used for calculating gamma ramps */ + +#ifdef USE_MATH_H +#include +#endif +#include + +#include "SDL_error.h" +#include "SDL_sysvideo.h" + +#ifdef USE_MATH_H +static void CalculateGammaRamp(float gamma, Uint16 *ramp) +{ + int i; + + /* 0.0 gamma is all black */ + if ( gamma <= 0.0 ) { + for ( i=0; i<256; ++i ) { + ramp[i] = 0; + } + return; + } else + /* 1.0 gamma is identity */ + if ( gamma == 1.0 ) { + for ( i=0; i<256; ++i ) { + ramp[i] = (i << 8) | i; + } + return; + } else + /* Calculate a real gamma ramp */ + { int value; + gamma = 1.0f / gamma; + for ( i=0; i<256; ++i ) { + value = (int)(pow((double)i/256.0, gamma)*65535.0+0.5); + if ( value > 65535 ) { + value = 65535; + } + ramp[i] = (Uint16)value; + } + } +} +static void CalculateGammaFromRamp(float *gamma, Uint16 *ramp) +{ + /* The following is adapted from a post by Garrett Bass on OpenGL + Gamedev list, March 4, 2000. + */ + float sum = 0.0; + int i, count = 0; + + *gamma = 1.0; + for ( i = 1; i < 256; ++i ) { + if ( (ramp[i] != 0) && (ramp[i] != 65535) ) { + double B = (double)i / 256.0; + double A = ramp[i] / 65535.0; + sum += (float) ( log(A) / log(B) ); + count++; + } + } + if ( count && sum ) { + *gamma = 1.0f / (sum / count); + } +} +#endif /* USE_MATH_H */ + +int SDL_SetGamma(float red, float green, float blue) +{ + int succeeded; + SDL_VideoDevice *video = current_video; + SDL_VideoDevice *this = current_video; + + succeeded = -1; +#ifdef USE_MATH_H + /* Prefer using SetGammaRamp(), as it's more flexible */ + { + Uint16 ramp[3][256]; + + CalculateGammaRamp(red, ramp[0]); + CalculateGammaRamp(green, ramp[1]); + CalculateGammaRamp(blue, ramp[2]); + succeeded = SDL_SetGammaRamp(ramp[0], ramp[1], ramp[2]); + } +#else + SDL_SetError("Gamma correction not supported"); +#endif + if ( (succeeded < 0) && video->SetGamma ) { + SDL_ClearError(); + succeeded = video->SetGamma(this, red, green, blue); + } + return succeeded; +} + +/* Calculating the gamma by integrating the gamma ramps isn't exact, + so this function isn't officially supported. +*/ +int SDL_GetGamma(float *red, float *green, float *blue) +{ + int succeeded; + SDL_VideoDevice *video = current_video; + SDL_VideoDevice *this = current_video; + + succeeded = -1; +#ifdef USE_MATH_H + /* Prefer using GetGammaRamp(), as it's more flexible */ + { + Uint16 ramp[3][256]; + + succeeded = SDL_GetGammaRamp(ramp[0], ramp[1], ramp[2]); + if ( succeeded >= 0 ) { + CalculateGammaFromRamp(red, ramp[0]); + CalculateGammaFromRamp(green, ramp[1]); + CalculateGammaFromRamp(blue, ramp[2]); + } + } +#else + SDL_SetError("Gamma correction not supported"); +#endif + if ( (succeeded < 0) && video->GetGamma ) { + SDL_ClearError(); + succeeded = video->GetGamma(this, red, green, blue); + } + return succeeded; +} + +int SDL_SetGammaRamp(Uint16 *red, Uint16 *green, Uint16 *blue) +{ + int succeeded; + SDL_VideoDevice *video = current_video; + SDL_VideoDevice *this = current_video; + SDL_Surface *screen = SDL_PublicSurface; + + /* Verify the screen parameter */ + if ( !screen ) { + SDL_SetError("No video mode has been set"); + return -1; + } + + /* Lazily allocate the gamma tables */ + if ( ! video->gamma ) { + SDL_GetGammaRamp(0, 0, 0); + } + + /* Fill the gamma table with the new values */ + if ( red ) { + memcpy(&video->gamma[0*256], red, 256*sizeof(*video->gamma)); + } + if ( green ) { + memcpy(&video->gamma[1*256], green, 256*sizeof(*video->gamma)); + } + if ( blue ) { + memcpy(&video->gamma[2*256], blue, 256*sizeof(*video->gamma)); + } + + /* Gamma correction always possible on split palettes */ + if ( (screen->flags & SDL_HWPALETTE) == SDL_HWPALETTE ) { + SDL_Palette *pal = screen->format->palette; + + /* If physical palette has been set independently, use it */ + if(video->physpal) + pal = video->physpal; + + SDL_SetPalette(screen, SDL_PHYSPAL, + pal->colors, 0, pal->ncolors); + return 0; + } + + /* Try to set the gamma ramp in the driver */ + succeeded = -1; + if ( video->SetGammaRamp ) { + succeeded = video->SetGammaRamp(this, video->gamma); + } else { + SDL_SetError("Gamma ramp manipulation not supported"); + } + return succeeded; +} + +int SDL_GetGammaRamp(Uint16 *red, Uint16 *green, Uint16 *blue) +{ + SDL_VideoDevice *video = current_video; + SDL_VideoDevice *this = current_video; + + /* Lazily allocate the gamma table */ + if ( ! video->gamma ) { + video->gamma = malloc(3*256*sizeof(*video->gamma)); + if ( ! video->gamma ) { + SDL_OutOfMemory(); + return -1; + } + if ( video->GetGammaRamp ) { + /* Get the real hardware gamma */ + video->GetGammaRamp(this, video->gamma); + } else { + /* Assume an identity gamma */ + int i; + for ( i=0; i<256; ++i ) { + video->gamma[0*256+i] = (i << 8) | i; + video->gamma[1*256+i] = (i << 8) | i; + video->gamma[2*256+i] = (i << 8) | i; + } + } + } + + /* Just copy from our internal table */ + if ( red ) { + memcpy(red, &video->gamma[0*256], 256*sizeof(*red)); + } + if ( green ) { + memcpy(green, &video->gamma[1*256], 256*sizeof(*green)); + } + if ( blue ) { + memcpy(blue, &video->gamma[2*256], 256*sizeof(*blue)); + } + return 0; +} diff --git a/contrib/sdk/sources/SDL-1.2.2/src/video/SDL_glfuncs.h b/contrib/sdk/sources/SDL-1.2.2/src/video/SDL_glfuncs.h new file mode 100644 index 000000000..9acf4d57e --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/src/video/SDL_glfuncs.h @@ -0,0 +1,341 @@ +/* list of OpenGL functions sorted alphabetically + If you need to use a GL function from the SDL video subsystem, + change it's entry from SDL_PROC_UNUSED to SDL_PROC and rebuild. +*/ +#define SDL_PROC_UNUSED(ret,func,params) +SDL_PROC_UNUSED(void,glAccum,(GLenum,GLfloat)) +SDL_PROC_UNUSED(void,glAlphaFunc,(GLenum,GLclampf)) +SDL_PROC_UNUSED(GLboolean,glAreTexturesResident,(GLsizei,const GLuint*,GLboolean*)) +SDL_PROC_UNUSED(void,glArrayElement,(GLint)) +SDL_PROC(void,glBegin,(GLenum)) +SDL_PROC(void,glBindTexture,(GLenum,GLuint)) +SDL_PROC_UNUSED(void,glBitmap,(GLsizei,GLsizei,GLfloat,GLfloat,GLfloat,GLfloat,const GLubyte*)) +SDL_PROC(void,glBlendFunc,(GLenum,GLenum)) +SDL_PROC_UNUSED(void,glCallList,(GLuint)) +SDL_PROC_UNUSED(void,glCallLists,(GLsizei,GLenum,const GLvoid*)) +SDL_PROC_UNUSED(void,glClear,(GLbitfield)) +SDL_PROC_UNUSED(void,glClearAccum,(GLfloat,GLfloat,GLfloat,GLfloat)) +SDL_PROC_UNUSED(void,glClearColor,(GLclampf,GLclampf,GLclampf,GLclampf)) +SDL_PROC_UNUSED(void,glClearDepth,(GLclampd)) +SDL_PROC_UNUSED(void,glClearIndex,(GLfloat)) +SDL_PROC_UNUSED(void,glClearStencil,(GLint)) +SDL_PROC_UNUSED(void,glClipPlane,(GLenum,const GLdouble*)) +SDL_PROC_UNUSED(void,glColor3b,(GLbyte,GLbyte,GLbyte)) +SDL_PROC_UNUSED(void,glColor3bv,(const GLbyte*)) +SDL_PROC_UNUSED(void,glColor3d,(GLdouble,GLdouble,GLdouble)) +SDL_PROC_UNUSED(void,glColor3dv,(const GLdouble*)) +SDL_PROC_UNUSED(void,glColor3f,(GLfloat,GLfloat,GLfloat)) +SDL_PROC_UNUSED(void,glColor3fv,(const GLfloat*)) +SDL_PROC_UNUSED(void,glColor3i,(GLint,GLint,GLint)) +SDL_PROC_UNUSED(void,glColor3iv,(const GLint*)) +SDL_PROC_UNUSED(void,glColor3s,(GLshort,GLshort,GLshort)) +SDL_PROC_UNUSED(void,glColor3sv,(const GLshort*)) +SDL_PROC_UNUSED(void,glColor3ub,(GLubyte,GLubyte,GLubyte)) +SDL_PROC_UNUSED(void,glColor3ubv,(const GLubyte*)) +SDL_PROC_UNUSED(void,glColor3ui,(GLuint,GLuint,GLuint)) +SDL_PROC_UNUSED(void,glColor3uiv,(const GLuint*)) +SDL_PROC_UNUSED(void,glColor3us,(GLushort,GLushort,GLushort)) +SDL_PROC_UNUSED(void,glColor3usv,(const GLushort*)) +SDL_PROC_UNUSED(void,glColor4b,(GLbyte,GLbyte,GLbyte,GLbyte)) +SDL_PROC_UNUSED(void,glColor4bv,(const GLbyte*)) +SDL_PROC_UNUSED(void,glColor4d,(GLdouble,GLdouble,GLdouble,GLdouble)) +SDL_PROC_UNUSED(void,glColor4dv,(const GLdouble*)) +SDL_PROC(void,glColor4f,(GLfloat,GLfloat,GLfloat,GLfloat)) +SDL_PROC_UNUSED(void,glColor4fv,(const GLfloat*)) +SDL_PROC_UNUSED(void,glColor4i,(GLint,GLint,GLint,GLint)) +SDL_PROC_UNUSED(void,glColor4iv,(const GLint*)) +SDL_PROC_UNUSED(void,glColor4s,(GLshort,GLshort,GLshort,GLshort)) +SDL_PROC_UNUSED(void,glColor4sv,(const GLshort*)) +SDL_PROC_UNUSED(void,glColor4ub,(GLubyte red, GLubyte green, GLubyte blue, GLubyte alpha)) +SDL_PROC_UNUSED(void,glColor4ubv,(const GLubyte *v)) +SDL_PROC_UNUSED(void,glColor4ui,(GLuint red, GLuint green, GLuint blue, GLuint alpha)) +SDL_PROC_UNUSED(void,glColor4uiv,(const GLuint *v)) +SDL_PROC_UNUSED(void,glColor4us,(GLushort red, GLushort green, GLushort blue, GLushort alpha)) +SDL_PROC_UNUSED(void,glColor4usv,(const GLushort *v)) +SDL_PROC_UNUSED(void,glColorMask,(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha)) +SDL_PROC_UNUSED(void,glColorMaterial,(GLenum face, GLenum mode)) +SDL_PROC_UNUSED(void,glColorPointer,(GLint size, GLenum type, GLsizei stride, const GLvoid *pointer)) +SDL_PROC_UNUSED(void,glCopyPixels,(GLint x, GLint y, GLsizei width, GLsizei height, GLenum type)) +SDL_PROC(void,glCopyTexImage1D,(GLenum target, GLint level, GLenum internalFormat, GLint x, GLint y, GLsizei width, GLint border)) +SDL_PROC_UNUSED(void,glCopyTexImage2D,(GLenum target, GLint level, GLenum internalFormat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border)) +SDL_PROC_UNUSED(void,glCopyTexSubImage1D,(GLenum target, GLint level, GLint xoffset, GLint x, GLint y, GLsizei width)) +SDL_PROC_UNUSED(void,glCopyTexSubImage2D,(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height)) +SDL_PROC_UNUSED(void,glCullFace,(GLenum mode)) +SDL_PROC_UNUSED(void,glDeleteLists,(GLuint list, GLsizei range)) +SDL_PROC_UNUSED(void,glDeleteTextures,(GLsizei n, const GLuint *textures)) +SDL_PROC_UNUSED(void,glDepthFunc,(GLenum func)) +SDL_PROC_UNUSED(void,glDepthMask,(GLboolean flag)) +SDL_PROC_UNUSED(void,glDepthRange,(GLclampd zNear, GLclampd zFar)) +SDL_PROC(void,glDisable,(GLenum cap)) +SDL_PROC_UNUSED(void,glDisableClientState,(GLenum array)) +SDL_PROC_UNUSED(void,glDrawArrays,(GLenum mode, GLint first, GLsizei count)) +SDL_PROC_UNUSED(void,glDrawBuffer,(GLenum mode)) +SDL_PROC_UNUSED(void,glDrawElements,(GLenum mode, GLsizei count, GLenum type, const GLvoid *indices)) +SDL_PROC_UNUSED(void,glDrawPixels,(GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels)) +SDL_PROC_UNUSED(void,glEdgeFlag,(GLboolean flag)) +SDL_PROC_UNUSED(void,glEdgeFlagPointer,(GLsizei stride, const GLvoid *pointer)) +SDL_PROC_UNUSED(void,glEdgeFlagv,(const GLboolean *flag)) +SDL_PROC(void,glEnable,(GLenum cap)) +SDL_PROC_UNUSED(void,glEnableClientState,(GLenum array)) +SDL_PROC(void,glEnd,(void)) +SDL_PROC_UNUSED(void,glEndList,(void)) +SDL_PROC_UNUSED(void,glEvalCoord1d,(GLdouble u)) +SDL_PROC_UNUSED(void,glEvalCoord1dv,(const GLdouble *u)) +SDL_PROC_UNUSED(void,glEvalCoord1f,(GLfloat u)) +SDL_PROC_UNUSED(void,glEvalCoord1fv,(const GLfloat *u)) +SDL_PROC_UNUSED(void,glEvalCoord2d,(GLdouble u, GLdouble v)) +SDL_PROC_UNUSED(void,glEvalCoord2dv,(const GLdouble *u)) +SDL_PROC_UNUSED(void,glEvalCoord2f,(GLfloat u, GLfloat v)) +SDL_PROC_UNUSED(void,glEvalCoord2fv,(const GLfloat *u)) +SDL_PROC_UNUSED(void,glEvalMesh1,(GLenum mode, GLint i1, GLint i2)) +SDL_PROC_UNUSED(void,glEvalMesh2,(GLenum mode, GLint i1, GLint i2, GLint j1, GLint j2)) +SDL_PROC_UNUSED(void,glEvalPoint1,(GLint i)) +SDL_PROC_UNUSED(void,glEvalPoint2,(GLint i, GLint j)) +SDL_PROC_UNUSED(void,glFeedbackBuffer,(GLsizei size, GLenum type, GLfloat *buffer)) +SDL_PROC_UNUSED(void,glFinish,(void)) +SDL_PROC(void,glFlush,(void)) +SDL_PROC_UNUSED(void,glFogf,(GLenum pname, GLfloat param)) +SDL_PROC_UNUSED(void,glFogfv,(GLenum pname, const GLfloat *params)) +SDL_PROC_UNUSED(void,glFogi,(GLenum pname, GLint param)) +SDL_PROC_UNUSED(void,glFogiv,(GLenum pname, const GLint *params)) +SDL_PROC_UNUSED(void,glFrontFace,(GLenum mode)) +SDL_PROC_UNUSED(void,glFrustum,(GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble zNear, GLdouble zFar)) +SDL_PROC_UNUSED(GLuint,glGenLists,(GLsizei range)) +SDL_PROC(void,glGenTextures,(GLsizei n, GLuint *textures)) +SDL_PROC_UNUSED(void,glGetBooleanv,(GLenum pname, GLboolean *params)) +SDL_PROC_UNUSED(void,glGetClipPlane,(GLenum plane, GLdouble *equation)) +SDL_PROC_UNUSED(void,glGetDoublev,(GLenum pname, GLdouble *params)) +SDL_PROC_UNUSED(GLenum,glGetError,(void)) +SDL_PROC_UNUSED(void,glGetFloatv,(GLenum pname, GLfloat *params)) +SDL_PROC_UNUSED(void,glGetIntegerv,(GLenum pname, GLint *params)) +SDL_PROC_UNUSED(void,glGetLightfv,(GLenum light, GLenum pname, GLfloat *params)) +SDL_PROC_UNUSED(void,glGetLightiv,(GLenum light, GLenum pname, GLint *params)) +SDL_PROC_UNUSED(void,glGetMapdv,(GLenum target, GLenum query, GLdouble *v)) +SDL_PROC_UNUSED(void,glGetMapfv,(GLenum target, GLenum query, GLfloat *v)) +SDL_PROC_UNUSED(void,glGetMapiv,(GLenum target, GLenum query, GLint *v)) +SDL_PROC_UNUSED(void,glGetMaterialfv,(GLenum face, GLenum pname, GLfloat *params)) +SDL_PROC_UNUSED(void,glGetMaterialiv,(GLenum face, GLenum pname, GLint *params)) +SDL_PROC_UNUSED(void,glGetPixelMapfv,(GLenum map, GLfloat *values)) +SDL_PROC_UNUSED(void,glGetPixelMapuiv,(GLenum map, GLuint *values)) +SDL_PROC_UNUSED(void,glGetPixelMapusv,(GLenum map, GLushort *values)) +SDL_PROC_UNUSED(void,glGetPointerv,(GLenum pname, GLvoid* *params)) +SDL_PROC_UNUSED(void,glGetPolygonStipple,(GLubyte *mask)) +SDL_PROC(const GLubyte *,glGetString,(GLenum name)) +SDL_PROC_UNUSED(void,glGetTexEnvfv,(GLenum target, GLenum pname, GLfloat *params)) +SDL_PROC_UNUSED(void,glGetTexEnviv,(GLenum target, GLenum pname, GLint *params)) +SDL_PROC_UNUSED(void,glGetTexGendv,(GLenum coord, GLenum pname, GLdouble *params)) +SDL_PROC_UNUSED(void,glGetTexGenfv,(GLenum coord, GLenum pname, GLfloat *params)) +SDL_PROC_UNUSED(void,glGetTexGeniv,(GLenum coord, GLenum pname, GLint *params)) +SDL_PROC_UNUSED(void,glGetTexImage,(GLenum target, GLint level, GLenum format, GLenum type, GLvoid *pixels)) +SDL_PROC_UNUSED(void,glGetTexLevelParameterfv,(GLenum target, GLint level, GLenum pname, GLfloat *params)) +SDL_PROC_UNUSED(void,glGetTexLevelParameteriv,(GLenum target, GLint level, GLenum pname, GLint *params)) +SDL_PROC_UNUSED(void,glGetTexParameterfv,(GLenum target, GLenum pname, GLfloat *params)) +SDL_PROC_UNUSED(void,glGetTexParameteriv,(GLenum target, GLenum pname, GLint *params)) +SDL_PROC_UNUSED(void,glHint,(GLenum target, GLenum mode)) +SDL_PROC_UNUSED(void,glIndexMask,(GLuint mask)) +SDL_PROC_UNUSED(void,glIndexPointer,(GLenum type, GLsizei stride, const GLvoid *pointer)) +SDL_PROC_UNUSED(void,glIndexd,(GLdouble c)) +SDL_PROC_UNUSED(void,glIndexdv,(const GLdouble *c)) +SDL_PROC_UNUSED(void,glIndexf,(GLfloat c)) +SDL_PROC_UNUSED(void,glIndexfv,(const GLfloat *c)) +SDL_PROC_UNUSED(void,glIndexi,(GLint c)) +SDL_PROC_UNUSED(void,glIndexiv,(const GLint *c)) +SDL_PROC_UNUSED(void,glIndexs,(GLshort c)) +SDL_PROC_UNUSED(void,glIndexsv,(const GLshort *c)) +SDL_PROC_UNUSED(void,glIndexub,(GLubyte c)) +SDL_PROC_UNUSED(void,glIndexubv,(const GLubyte *c)) +SDL_PROC_UNUSED(void,glInitNames,(void)) +SDL_PROC_UNUSED(void,glInterleavedArrays,(GLenum format, GLsizei stride, const GLvoid *pointer)) +SDL_PROC_UNUSED(GLboolean,glIsEnabled,(GLenum cap)) +SDL_PROC_UNUSED(GLboolean,glIsList,(GLuint list)) +SDL_PROC_UNUSED(GLboolean,glIsTexture,(GLuint texture)) +SDL_PROC_UNUSED(void,glLightModelf,(GLenum pname, GLfloat param)) +SDL_PROC_UNUSED(void,glLightModelfv,(GLenum pname, const GLfloat *params)) +SDL_PROC_UNUSED(void,glLightModeli,(GLenum pname, GLint param)) +SDL_PROC_UNUSED(void,glLightModeliv,(GLenum pname, const GLint *params)) +SDL_PROC_UNUSED(void,glLightf,(GLenum light, GLenum pname, GLfloat param)) +SDL_PROC_UNUSED(void,glLightfv,(GLenum light, GLenum pname, const GLfloat *params)) +SDL_PROC_UNUSED(void,glLighti,(GLenum light, GLenum pname, GLint param)) +SDL_PROC_UNUSED(void,glLightiv,(GLenum light, GLenum pname, const GLint *params)) +SDL_PROC_UNUSED(void,glLineStipple,(GLint factor, GLushort pattern)) +SDL_PROC_UNUSED(void,glLineWidth,(GLfloat width)) +SDL_PROC_UNUSED(void,glListBase,(GLuint base)) +SDL_PROC(void,glLoadIdentity,(void)) +SDL_PROC_UNUSED(void,glLoadMatrixd,(const GLdouble *m)) +SDL_PROC_UNUSED(void,glLoadMatrixf,(const GLfloat *m)) +SDL_PROC_UNUSED(void,glLoadName,(GLuint name)) +SDL_PROC_UNUSED(void,glLogicOp,(GLenum opcode)) +SDL_PROC_UNUSED(void,glMap1d,(GLenum target, GLdouble u1, GLdouble u2, GLint stride, GLint order, const GLdouble *points)) +SDL_PROC_UNUSED(void,glMap1f,(GLenum target, GLfloat u1, GLfloat u2, GLint stride, GLint order, const GLfloat *points)) +SDL_PROC_UNUSED(void,glMap2d,(GLenum target, GLdouble u1, GLdouble u2, GLint ustride, GLint uorder, GLdouble v1, GLdouble v2, GLint vstride, GLint vorder, const GLdouble *points)) +SDL_PROC_UNUSED(void,glMap2f,(GLenum target, GLfloat u1, GLfloat u2, GLint ustride, GLint uorder, GLfloat v1, GLfloat v2, GLint vstride, GLint vorder, const GLfloat *points)) +SDL_PROC_UNUSED(void,glMapGrid1d,(GLint un, GLdouble u1, GLdouble u2)) +SDL_PROC_UNUSED(void,glMapGrid1f,(GLint un, GLfloat u1, GLfloat u2)) +SDL_PROC_UNUSED(void,glMapGrid2d,(GLint un, GLdouble u1, GLdouble u2, GLint vn, GLdouble v1, GLdouble v2)) +SDL_PROC_UNUSED(void,glMapGrid2f,(GLint un, GLfloat u1, GLfloat u2, GLint vn, GLfloat v1, GLfloat v2)) +SDL_PROC_UNUSED(void,glMaterialf,(GLenum face, GLenum pname, GLfloat param)) +SDL_PROC_UNUSED(void,glMaterialfv,(GLenum face, GLenum pname, const GLfloat *params)) +SDL_PROC_UNUSED(void,glMateriali,(GLenum face, GLenum pname, GLint param)) +SDL_PROC_UNUSED(void,glMaterialiv,(GLenum face, GLenum pname, const GLint *params)) +SDL_PROC(void,glMatrixMode,(GLenum mode)) +SDL_PROC_UNUSED(void,glMultMatrixd,(const GLdouble *m)) +SDL_PROC_UNUSED(void,glMultMatrixf,(const GLfloat *m)) +SDL_PROC_UNUSED(void,glNewList,(GLuint list, GLenum mode)) +SDL_PROC_UNUSED(void,glNormal3b,(GLbyte nx, GLbyte ny, GLbyte nz)) +SDL_PROC_UNUSED(void,glNormal3bv,(const GLbyte *v)) +SDL_PROC_UNUSED(void,glNormal3d,(GLdouble nx, GLdouble ny, GLdouble nz)) +SDL_PROC_UNUSED(void,glNormal3dv,(const GLdouble *v)) +SDL_PROC_UNUSED(void,glNormal3f,(GLfloat nx, GLfloat ny, GLfloat nz)) +SDL_PROC_UNUSED(void,glNormal3fv,(const GLfloat *v)) +SDL_PROC_UNUSED(void,glNormal3i,(GLint nx, GLint ny, GLint nz)) +SDL_PROC_UNUSED(void,glNormal3iv,(const GLint *v)) +SDL_PROC_UNUSED(void,glNormal3s,(GLshort nx, GLshort ny, GLshort nz)) +SDL_PROC_UNUSED(void,glNormal3sv,(const GLshort *v)) +SDL_PROC_UNUSED(void,glNormalPointer,(GLenum type, GLsizei stride, const GLvoid *pointer)) +SDL_PROC(void,glOrtho,(GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble zNear, GLdouble zFar)) +SDL_PROC_UNUSED(void,glPassThrough,(GLfloat token)) +SDL_PROC_UNUSED(void,glPixelMapfv,(GLenum map, GLsizei mapsize, const GLfloat *values)) +SDL_PROC_UNUSED(void,glPixelMapuiv,(GLenum map, GLsizei mapsize, const GLuint *values)) +SDL_PROC_UNUSED(void,glPixelMapusv,(GLenum map, GLsizei mapsize, const GLushort *values)) +SDL_PROC_UNUSED(void,glPixelStoref,(GLenum pname, GLfloat param)) +SDL_PROC(void,glPixelStorei,(GLenum pname, GLint param)) +SDL_PROC_UNUSED(void,glPixelTransferf,(GLenum pname, GLfloat param)) +SDL_PROC_UNUSED(void,glPixelTransferi,(GLenum pname, GLint param)) +SDL_PROC_UNUSED(void,glPixelZoom,(GLfloat xfactor, GLfloat yfactor)) +SDL_PROC_UNUSED(void,glPointSize,(GLfloat size)) +SDL_PROC_UNUSED(void,glPolygonMode,(GLenum face, GLenum mode)) +SDL_PROC_UNUSED(void,glPolygonOffset,(GLfloat factor, GLfloat units)) +SDL_PROC_UNUSED(void,glPolygonStipple,(const GLubyte *mask)) +SDL_PROC(void,glPopAttrib,(void)) +SDL_PROC(void,glPopClientAttrib,(void)) +SDL_PROC(void,glPopMatrix,(void)) +SDL_PROC_UNUSED(void,glPopName,(void)) +SDL_PROC_UNUSED(void,glPrioritizeTextures,(GLsizei n, const GLuint *textures, const GLclampf *priorities)) +SDL_PROC(void,glPushAttrib,(GLbitfield mask)) +SDL_PROC(void,glPushClientAttrib,(GLbitfield mask)) +SDL_PROC(void,glPushMatrix,(void)) +SDL_PROC_UNUSED(void,glPushName,(GLuint name)) +SDL_PROC_UNUSED(void,glRasterPos2d,(GLdouble x, GLdouble y)) +SDL_PROC_UNUSED(void,glRasterPos2dv,(const GLdouble *v)) +SDL_PROC_UNUSED(void,glRasterPos2f,(GLfloat x, GLfloat y)) +SDL_PROC_UNUSED(void,glRasterPos2fv,(const GLfloat *v)) +SDL_PROC_UNUSED(void,glRasterPos2i,(GLint x, GLint y)) +SDL_PROC_UNUSED(void,glRasterPos2iv,(const GLint *v)) +SDL_PROC_UNUSED(void,glRasterPos2s,(GLshort x, GLshort y)) +SDL_PROC_UNUSED(void,glRasterPos2sv,(const GLshort *v)) +SDL_PROC_UNUSED(void,glRasterPos3d,(GLdouble x, GLdouble y, GLdouble z)) +SDL_PROC_UNUSED(void,glRasterPos3dv,(const GLdouble *v)) +SDL_PROC_UNUSED(void,glRasterPos3f,(GLfloat x, GLfloat y, GLfloat z)) +SDL_PROC_UNUSED(void,glRasterPos3fv,(const GLfloat *v)) +SDL_PROC_UNUSED(void,glRasterPos3i,(GLint x, GLint y, GLint z)) +SDL_PROC_UNUSED(void,glRasterPos3iv,(const GLint *v)) +SDL_PROC_UNUSED(void,glRasterPos3s,(GLshort x, GLshort y, GLshort z)) +SDL_PROC_UNUSED(void,glRasterPos3sv,(const GLshort *v)) +SDL_PROC_UNUSED(void,glRasterPos4d,(GLdouble x, GLdouble y, GLdouble z, GLdouble w)) +SDL_PROC_UNUSED(void,glRasterPos4dv,(const GLdouble *v)) +SDL_PROC_UNUSED(void,glRasterPos4f,(GLfloat x, GLfloat y, GLfloat z, GLfloat w)) +SDL_PROC_UNUSED(void,glRasterPos4fv,(const GLfloat *v)) +SDL_PROC_UNUSED(void,glRasterPos4i,(GLint x, GLint y, GLint z, GLint w)) +SDL_PROC_UNUSED(void,glRasterPos4iv,(const GLint *v)) +SDL_PROC_UNUSED(void,glRasterPos4s,(GLshort x, GLshort y, GLshort z, GLshort w)) +SDL_PROC_UNUSED(void,glRasterPos4sv,(const GLshort *v)) +SDL_PROC_UNUSED(void,glReadBuffer,(GLenum mode)) +SDL_PROC_UNUSED(void,glReadPixels,(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid *pixels)) +SDL_PROC_UNUSED(void,glRectd,(GLdouble x1, GLdouble y1, GLdouble x2, GLdouble y2)) +SDL_PROC_UNUSED(void,glRectdv,(const GLdouble *v1, const GLdouble *v2)) +SDL_PROC_UNUSED(void,glRectf,(GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2)) +SDL_PROC_UNUSED(void,glRectfv,(const GLfloat *v1, const GLfloat *v2)) +SDL_PROC_UNUSED(void,glRecti,(GLint x1, GLint y1, GLint x2, GLint y2)) +SDL_PROC_UNUSED(void,glRectiv,(const GLint *v1, const GLint *v2)) +SDL_PROC_UNUSED(void,glRects,(GLshort x1, GLshort y1, GLshort x2, GLshort y2)) +SDL_PROC_UNUSED(void,glRectsv,(const GLshort *v1, const GLshort *v2)) +SDL_PROC_UNUSED(GLint,glRenderMode,(GLenum mode)) +SDL_PROC_UNUSED(void,glRotated,(GLdouble angle, GLdouble x, GLdouble y, GLdouble z)) +SDL_PROC_UNUSED(void,glRotatef,(GLfloat angle, GLfloat x, GLfloat y, GLfloat z)) +SDL_PROC_UNUSED(void,glScaled,(GLdouble x, GLdouble y, GLdouble z)) +SDL_PROC_UNUSED(void,glScalef,(GLfloat x, GLfloat y, GLfloat z)) +SDL_PROC_UNUSED(void,glScissor,(GLint x, GLint y, GLsizei width, GLsizei height)) +SDL_PROC_UNUSED(void,glSelectBuffer,(GLsizei size, GLuint *buffer)) +SDL_PROC_UNUSED(void,glShadeModel,(GLenum mode)) +SDL_PROC_UNUSED(void,glStencilFunc,(GLenum func, GLint ref, GLuint mask)) +SDL_PROC_UNUSED(void,glStencilMask,(GLuint mask)) +SDL_PROC_UNUSED(void,glStencilOp,(GLenum fail, GLenum zfail, GLenum zpass)) +SDL_PROC_UNUSED(void,glTexCoord1d,(GLdouble s)) +SDL_PROC_UNUSED(void,glTexCoord1dv,(const GLdouble *v)) +SDL_PROC_UNUSED(void,glTexCoord1f,(GLfloat s)) +SDL_PROC_UNUSED(void,glTexCoord1fv,(const GLfloat *v)) +SDL_PROC_UNUSED(void,glTexCoord1i,(GLint s)) +SDL_PROC_UNUSED(void,glTexCoord1iv,(const GLint *v)) +SDL_PROC_UNUSED(void,glTexCoord1s,(GLshort s)) +SDL_PROC_UNUSED(void,glTexCoord1sv,(const GLshort *v)) +SDL_PROC_UNUSED(void,glTexCoord2d,(GLdouble s, GLdouble t)) +SDL_PROC_UNUSED(void,glTexCoord2dv,(const GLdouble *v)) +SDL_PROC(void,glTexCoord2f,(GLfloat s, GLfloat t)) +SDL_PROC_UNUSED(void,glTexCoord2fv,(const GLfloat *v)) +SDL_PROC_UNUSED(void,glTexCoord2i,(GLint s, GLint t)) +SDL_PROC_UNUSED(void,glTexCoord2iv,(const GLint *v)) +SDL_PROC_UNUSED(void,glTexCoord2s,(GLshort s, GLshort t)) +SDL_PROC_UNUSED(void,glTexCoord2sv,(const GLshort *v)) +SDL_PROC_UNUSED(void,glTexCoord3d,(GLdouble s, GLdouble t, GLdouble r)) +SDL_PROC_UNUSED(void,glTexCoord3dv,(const GLdouble *v)) +SDL_PROC_UNUSED(void,glTexCoord3f,(GLfloat s, GLfloat t, GLfloat r)) +SDL_PROC_UNUSED(void,glTexCoord3fv,(const GLfloat *v)) +SDL_PROC_UNUSED(void,glTexCoord3i,(GLint s, GLint t, GLint r)) +SDL_PROC_UNUSED(void,glTexCoord3iv,(const GLint *v)) +SDL_PROC_UNUSED(void,glTexCoord3s,(GLshort s, GLshort t, GLshort r)) +SDL_PROC_UNUSED(void,glTexCoord3sv,(const GLshort *v)) +SDL_PROC_UNUSED(void,glTexCoord4d,(GLdouble s, GLdouble t, GLdouble r, GLdouble q)) +SDL_PROC_UNUSED(void,glTexCoord4dv,(const GLdouble *v)) +SDL_PROC_UNUSED(void,glTexCoord4f,(GLfloat s, GLfloat t, GLfloat r, GLfloat q)) +SDL_PROC_UNUSED(void,glTexCoord4fv,(const GLfloat *v)) +SDL_PROC_UNUSED(void,glTexCoord4i,(GLint s, GLint t, GLint r, GLint q)) +SDL_PROC_UNUSED(void,glTexCoord4iv,(const GLint *v)) +SDL_PROC_UNUSED(void,glTexCoord4s,(GLshort s, GLshort t, GLshort r, GLshort q)) +SDL_PROC_UNUSED(void,glTexCoord4sv,(const GLshort *v)) +SDL_PROC_UNUSED(void,glTexCoordPointer,(GLint size, GLenum type, GLsizei stride, const GLvoid *pointer)) +SDL_PROC(void,glTexEnvf,(GLenum target, GLenum pname, GLfloat param)) +SDL_PROC_UNUSED(void,glTexEnvfv,(GLenum target, GLenum pname, const GLfloat *params)) +SDL_PROC_UNUSED(void,glTexEnvi,(GLenum target, GLenum pname, GLint param)) +SDL_PROC_UNUSED(void,glTexEnviv,(GLenum target, GLenum pname, const GLint *params)) +SDL_PROC_UNUSED(void,glTexGend,(GLenum coord, GLenum pname, GLdouble param)) +SDL_PROC_UNUSED(void,glTexGendv,(GLenum coord, GLenum pname, const GLdouble *params)) +SDL_PROC_UNUSED(void,glTexGenf,(GLenum coord, GLenum pname, GLfloat param)) +SDL_PROC_UNUSED(void,glTexGenfv,(GLenum coord, GLenum pname, const GLfloat *params)) +SDL_PROC_UNUSED(void,glTexGeni,(GLenum coord, GLenum pname, GLint param)) +SDL_PROC_UNUSED(void,glTexGeniv,(GLenum coord, GLenum pname, const GLint *params)) +SDL_PROC_UNUSED(void,glTexImage1D,(GLenum target, GLint level, GLint internalformat, GLsizei width, GLint border, GLenum format, GLenum type, const GLvoid *pixels)) +SDL_PROC(void,glTexImage2D,(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid *pixels)) +SDL_PROC_UNUSED(void,glTexParameterf,(GLenum target, GLenum pname, GLfloat param)) +SDL_PROC_UNUSED(void,glTexParameterfv,(GLenum target, GLenum pname, const GLfloat *params)) +SDL_PROC(void,glTexParameteri,(GLenum target, GLenum pname, GLint param)) +SDL_PROC_UNUSED(void,glTexParameteriv,(GLenum target, GLenum pname, const GLint *params)) +SDL_PROC_UNUSED(void,glTexSubImage1D,(GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type, const GLvoid *pixels)) +SDL_PROC(void,glTexSubImage2D,(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels)) +SDL_PROC_UNUSED(void,glTranslated,(GLdouble x, GLdouble y, GLdouble z)) +SDL_PROC_UNUSED(void,glTranslatef,(GLfloat x, GLfloat y, GLfloat z)) +SDL_PROC_UNUSED(void,glVertex2d,(GLdouble x, GLdouble y)) +SDL_PROC_UNUSED(void,glVertex2dv,(const GLdouble *v)) +SDL_PROC_UNUSED(void,glVertex2f,(GLfloat x, GLfloat y)) +SDL_PROC_UNUSED(void,glVertex2fv,(const GLfloat *v)) +SDL_PROC(void,glVertex2i,(GLint x, GLint y)) +SDL_PROC_UNUSED(void,glVertex2iv,(const GLint *v)) +SDL_PROC_UNUSED(void,glVertex2s,(GLshort x, GLshort y)) +SDL_PROC_UNUSED(void,glVertex2sv,(const GLshort *v)) +SDL_PROC_UNUSED(void,glVertex3d,(GLdouble x, GLdouble y, GLdouble z)) +SDL_PROC_UNUSED(void,glVertex3dv,(const GLdouble *v)) +SDL_PROC_UNUSED(void,glVertex3f,(GLfloat x, GLfloat y, GLfloat z)) +SDL_PROC_UNUSED(void,glVertex3fv,(const GLfloat *v)) +SDL_PROC_UNUSED(void,glVertex3i,(GLint x, GLint y, GLint z)) +SDL_PROC_UNUSED(void,glVertex3iv,(const GLint *v)) +SDL_PROC_UNUSED(void,glVertex3s,(GLshort x, GLshort y, GLshort z)) +SDL_PROC_UNUSED(void,glVertex3sv,(const GLshort *v)) +SDL_PROC_UNUSED(void,glVertex4d,(GLdouble x, GLdouble y, GLdouble z, GLdouble w)) +SDL_PROC_UNUSED(void,glVertex4dv,(const GLdouble *v)) +SDL_PROC_UNUSED(void,glVertex4f,(GLfloat x, GLfloat y, GLfloat z, GLfloat w)) +SDL_PROC_UNUSED(void,glVertex4fv,(const GLfloat *v)) +SDL_PROC_UNUSED(void,glVertex4i,(GLint x, GLint y, GLint z, GLint w)) +SDL_PROC_UNUSED(void,glVertex4iv,(const GLint *v)) +SDL_PROC_UNUSED(void,glVertex4s,(GLshort x, GLshort y, GLshort z, GLshort w)) +SDL_PROC_UNUSED(void,glVertex4sv,(const GLshort *v)) +SDL_PROC_UNUSED(void,glVertexPointer,(GLint size, GLenum type, GLsizei stride, const GLvoid *pointer)) +SDL_PROC(void,glViewport,(GLint x, GLint y, GLsizei width, GLsizei height)) diff --git a/contrib/sdk/sources/SDL-1.2.2/src/video/SDL_leaks.h b/contrib/sdk/sources/SDL-1.2.2/src/video/SDL_leaks.h new file mode 100644 index 000000000..96aa18e9e --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/src/video/SDL_leaks.h @@ -0,0 +1,35 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997, 1998, 1999, 2000, 2001 Sam Lantinga + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the Free + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + Sam Lantinga + slouken@devolution.com +*/ + +#ifdef SAVE_RCSID +static char rcsid = + "@(#) $Id: SDL_leaks.h,v 1.2 2001/04/26 16:50:18 hercules Exp $"; +#endif + +/* Define this if you want surface leak detection code enabled */ +/*#define CHECK_LEAKS*/ + +/* Global variables used to check leaks in code using SDL */ + +#ifdef CHECK_LEAKS +extern int surfaces_allocated; +#endif diff --git a/contrib/sdk/sources/SDL-1.2.2/src/video/SDL_memops.h b/contrib/sdk/sources/SDL-1.2.2/src/video/SDL_memops.h new file mode 100644 index 000000000..b43384025 --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/src/video/SDL_memops.h @@ -0,0 +1,144 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997, 1998, 1999, 2000, 2001 Sam Lantinga + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the Free + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + Sam Lantinga + slouken@devolution.com +*/ + +#ifdef SAVE_RCSID +static char rcsid = + "@(#) $Id: SDL_memops.h,v 1.2 2001/04/26 16:50:18 hercules Exp $"; +#endif + +#ifndef _SDL_memops_h +#define _SDL_memops_h + +/* System dependent optimized memory manipulation routines: +*/ +#include + +#if defined(__GNUC__) && defined(i386) +/* Thanks to Brennan "Bas" Underwood, for the inspiration. :) + */ +#define SDL_memcpy(dst, src, len) \ +do { \ + int u0, u1, u2; \ + __asm__ __volatile__ ( \ + "cld\n\t" \ + "rep ; movsl\n\t" \ + "testb $2,%b4\n\t" \ + "je 1f\n\t" \ + "movsw\n" \ + "1:\ttestb $1,%b4\n\t" \ + "je 2f\n\t" \ + "movsb\n" \ + "2:" \ + : "=&c" (u0), "=&D" (u1), "=&S" (u2) \ + : "0" ((unsigned)(len)/4), "q" (len), "1" (dst),"2" (src) \ + : "memory" ); \ +} while(0) + +#define SDL_memcpy4(dst, src, len) \ +do { \ + int ecx, edi, esi; \ + __asm__ __volatile__ ( \ + "cld\n\t" \ + "rep ; movsl" \ + : "=&c" (ecx), "=&D" (edi), "=&S" (esi) \ + : "0" ((unsigned)(len)), "1" (dst), "2" (src) \ + : "memory" ); \ +} while(0) + +#define SDL_revcpy(dst, src, len) \ +do { \ + int u0, u1, u2; \ + char *dstp = (char *)(dst); \ + char *srcp = (char *)(src); \ + int n = (len); \ + if ( n >= 4 ) { \ + __asm__ __volatile__ ( \ + "std\n\t" \ + "rep ; movsl\n\t" \ + : "=&c" (u0), "=&D" (u1), "=&S" (u2) \ + : "0" (n >> 2), \ + "1" (dstp+(n-4)), "2" (srcp+(n-4)) \ + : "memory" ); \ + } \ + switch (n & 3) { \ + case 3: dstp[2] = srcp[2]; \ + case 2: dstp[1] = srcp[1]; \ + case 1: dstp[0] = srcp[0]; \ + break; \ + default: \ + break; \ + } \ +} while(0) + +#define SDL_memmove(dst, src, len) \ +do { \ + if ( (dst) < (src) ) { \ + SDL_memcpy((dst), (src), (len)); \ + } else { \ + SDL_revcpy((dst), (src), (len)); \ + } \ +} while(0) + +#define SDL_memset4(dst, val, len) \ +do { \ + int u0, u1, u2; \ + __asm__ __volatile__ ( \ + "cld\n\t" \ + "rep ; stosl\n\t" \ + : "=&D" (u0), "=&a" (u1), "=&c" (u2) \ + : "0" (dst), "1" (val), "2" ((Uint32)(len)) \ + : "memory" ); \ +} while(0) + +#endif /* GNU C and x86 */ + +/* If there are no optimized versions, define the normal versions */ +#ifndef SDL_memcpy +#define SDL_memcpy(dst, src, len) memcpy(dst, src, len) +#endif + +#ifndef SDL_memcpy4 +#define SDL_memcpy4(dst, src, len) memcpy(dst, src, (len) << 2) +#endif + +#ifndef SDL_revcpy +#define SDL_revcpy(dst, src, len) memmove(dst, src, len) +#endif + +#ifndef SDL_memset4 +#define SDL_memset4(dst, val, len) \ +do { \ + unsigned _count = (len); \ + unsigned _n = (_count + 3) / 4; \ + Uint32 *_p = (Uint32 *)(dst); \ + Uint32 _val = (val); \ + switch (_count % 4) { \ + case 0: do { *_p++ = _val; \ + case 3: *_p++ = _val; \ + case 2: *_p++ = _val; \ + case 1: *_p++ = _val; \ + } while ( --_n ); \ + } \ +} while(0) +#endif + +#endif /* _SDL_memops_h */ diff --git a/contrib/sdk/sources/SDL-1.2.2/src/video/SDL_pixels.c b/contrib/sdk/sources/SDL-1.2.2/src/video/SDL_pixels.c new file mode 100644 index 000000000..e83068e07 --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/src/video/SDL_pixels.c @@ -0,0 +1,615 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997, 1998, 1999, 2000, 2001 Sam Lantinga + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the Free + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + Sam Lantinga + slouken@devolution.com +*/ + + +/* General (mostly internal) pixel/color manipulation routines for SDL */ + +#include +#include +#include + +#include "SDL_error.h" +#include "SDL_endian.h" +#include "SDL_video.h" +#include "SDL_sysvideo.h" +#include "SDL_blit.h" +#include "SDL_pixels_c.h" +#include "SDL_RLEaccel_c.h" + +/* Helper functions */ +/* + * Allocate a pixel format structure and fill it according to the given info. + */ +SDL_PixelFormat *SDL_AllocFormat(int bpp, + Uint32 Rmask, Uint32 Gmask, Uint32 Bmask, Uint32 Amask) +{ + SDL_PixelFormat *format; + Uint32 mask; + + /* Allocate an empty pixel format structure */ + format = malloc(sizeof(*format)); + if ( format == NULL ) { + SDL_OutOfMemory(); + return(NULL); + } + memset(format, 0, sizeof(*format)); + format->alpha = SDL_ALPHA_OPAQUE; + + /* Set up the format */ + format->BitsPerPixel = bpp; + format->BytesPerPixel = (bpp+7)/8; + switch (bpp) { + case 1: + /* Create the 2 color black-white palette */ + format->palette = (SDL_Palette *)malloc( + sizeof(SDL_Palette)); + if ( format->palette == NULL ) { + SDL_FreeFormat(format); + SDL_OutOfMemory(); + return(NULL); + } + (format->palette)->ncolors = 2; + (format->palette)->colors = (SDL_Color *)malloc( + (format->palette)->ncolors*sizeof(SDL_Color)); + if ( (format->palette)->colors == NULL ) { + SDL_FreeFormat(format); + SDL_OutOfMemory(); + return(NULL); + } + format->palette->colors[0].r = 0xFF; + format->palette->colors[0].g = 0xFF; + format->palette->colors[0].b = 0xFF; + format->palette->colors[1].r = 0x00; + format->palette->colors[1].g = 0x00; + format->palette->colors[1].b = 0x00; + format->Rloss = 8; + format->Gloss = 8; + format->Bloss = 8; + format->Aloss = 8; + format->Rshift = 0; + format->Gshift = 0; + format->Bshift = 0; + format->Ashift = 0; + format->Rmask = 0; + format->Gmask = 0; + format->Bmask = 0; + format->Amask = 0; + break; + + case 4: + /* Create the 16 color VGA palette */ + format->palette = (SDL_Palette *)malloc( + sizeof(SDL_Palette)); + if ( format->palette == NULL ) { + SDL_FreeFormat(format); + SDL_OutOfMemory(); + return(NULL); + } + (format->palette)->ncolors = 16; + (format->palette)->colors = (SDL_Color *)malloc( + (format->palette)->ncolors*sizeof(SDL_Color)); + if ( (format->palette)->colors == NULL ) { + SDL_FreeFormat(format); + SDL_OutOfMemory(); + return(NULL); + } + /* Punt for now, will this ever be used? */ + memset((format->palette)->colors, 0, + (format->palette)->ncolors*sizeof(SDL_Color)); + + /* Palettized formats have no mask info */ + format->Rloss = 8; + format->Gloss = 8; + format->Bloss = 8; + format->Aloss = 8; + format->Rshift = 0; + format->Gshift = 0; + format->Bshift = 0; + format->Ashift = 0; + format->Rmask = 0; + format->Gmask = 0; + format->Bmask = 0; + format->Amask = 0; + break; + + case 8: + /* Create an empty 256 color palette */ + format->palette = (SDL_Palette *)malloc( + sizeof(SDL_Palette)); + if ( format->palette == NULL ) { + SDL_FreeFormat(format); + SDL_OutOfMemory(); + return(NULL); + } + (format->palette)->ncolors = 256; + (format->palette)->colors = (SDL_Color *)malloc( + (format->palette)->ncolors*sizeof(SDL_Color)); + if ( (format->palette)->colors == NULL ) { + SDL_FreeFormat(format); + SDL_OutOfMemory(); + return(NULL); + } + memset((format->palette)->colors, 0, + (format->palette)->ncolors*sizeof(SDL_Color)); + + /* Palettized formats have no mask info */ + format->Rloss = 8; + format->Gloss = 8; + format->Bloss = 8; + format->Aloss = 8; + format->Rshift = 0; + format->Gshift = 0; + format->Bshift = 0; + format->Ashift = 0; + format->Rmask = 0; + format->Gmask = 0; + format->Bmask = 0; + format->Amask = 0; + break; + + default: + /* No palette, just packed pixel info */ + format->palette = NULL; + format->Rshift = 0; + format->Rloss = 8; + if ( Rmask ) { + for ( mask = Rmask; !(mask&0x01); mask >>= 1 ) + ++format->Rshift; + for ( ; (mask&0x01); mask >>= 1 ) + --format->Rloss; + } + format->Gshift = 0; + format->Gloss = 8; + if ( Gmask ) { + for ( mask = Gmask; !(mask&0x01); mask >>= 1 ) + ++format->Gshift; + for ( ; (mask&0x01); mask >>= 1 ) + --format->Gloss; + } + format->Bshift = 0; + format->Bloss = 8; + if ( Bmask ) { + for ( mask = Bmask; !(mask&0x01); mask >>= 1 ) + ++format->Bshift; + for ( ; (mask&0x01); mask >>= 1 ) + --format->Bloss; + } + format->Ashift = 0; + format->Aloss = 8; + if ( Amask ) { + for ( mask = Amask; !(mask&0x01); mask >>= 1 ) + ++format->Ashift; + for ( ; (mask&0x01); mask >>= 1 ) + --format->Aloss; + } + format->Rmask = Rmask; + format->Gmask = Gmask; + format->Bmask = Bmask; + format->Amask = Amask; + break; + } + /* Calculate some standard bitmasks, if necessary + * Note: This could conflict with an alpha mask, if given. + */ + if ( (bpp > 8) && !format->Rmask && !format->Gmask && !format->Bmask ) { + /* R-G-B */ + if ( bpp > 24 ) + bpp = 24; + format->Rloss = 8-(bpp/3); + format->Gloss = 8-(bpp/3)-(bpp%3); + format->Bloss = 8-(bpp/3); + format->Rshift = ((bpp/3)+(bpp%3))+(bpp/3); + format->Gshift = (bpp/3); + format->Bshift = 0; + format->Rmask = ((0xFF>>format->Rloss)<Rshift); + format->Gmask = ((0xFF>>format->Gloss)<Gshift); + format->Bmask = ((0xFF>>format->Bloss)<Bshift); + } + return(format); +} +SDL_PixelFormat *SDL_ReallocFormat(SDL_Surface *surface, int bpp, + Uint32 Rmask, Uint32 Gmask, Uint32 Bmask, Uint32 Amask) +{ + if ( surface->format ) { + SDL_FreeFormat(surface->format); + SDL_FormatChanged(surface); + } + surface->format = SDL_AllocFormat(bpp, Rmask, Gmask, Bmask, Amask); + return surface->format; +} + +/* + * Change any previous mappings from/to the new surface format + */ +void SDL_FormatChanged(SDL_Surface *surface) +{ + surface->format_version++; + SDL_InvalidateMap(surface->map); +} +/* + * Free a previously allocated format structure + */ +void SDL_FreeFormat(SDL_PixelFormat *format) +{ + if ( format ) { + if ( format->palette ) { + if ( format->palette->colors ) { + free(format->palette->colors); + } + free(format->palette); + } + free(format); + } +} +/* + * Calculate an 8-bit (3 red, 3 green, 2 blue) dithered palette of colors + */ +void SDL_DitherColors(SDL_Color *colors, int bpp) +{ + int i; + if(bpp != 8) + return; /* only 8bpp supported right now */ + + for(i = 0; i < 256; i++) { + int r, g, b; + /* map each bit field to the full [0, 255] interval, + so 0 is mapped to (0, 0, 0) and 255 to (255, 255, 255) */ + r = i & 0xe0; + r |= r >> 3 | r >> 6; + colors[i].r = r; + g = (i << 3) & 0xe0; + g |= g >> 3 | g >> 6; + colors[i].g = g; + b = i & 0x3; + b |= b << 2; + b |= b << 4; + colors[i].b = b; + } +} +/* + * Calculate the pad-aligned scanline width of a surface + */ +Uint16 SDL_CalculatePitch(SDL_Surface *surface) +{ + Uint16 pitch; + + /* Surface should be 4-byte aligned for speed */ + pitch = surface->w*surface->format->BytesPerPixel; + switch (surface->format->BitsPerPixel) { + case 1: + pitch = (pitch+7)/8; + break; + case 4: + pitch = (pitch+1)/2; + break; + default: + break; + } + pitch = (pitch + 3) & ~3; /* 4-byte aligning */ + return(pitch); +} +/* + * Match an RGB value to a particular palette index + */ +Uint8 SDL_FindColor(SDL_Palette *pal, Uint8 r, Uint8 g, Uint8 b) +{ + /* Do colorspace distance matching */ + unsigned int smallest; + unsigned int distance; + int rd, gd, bd; + int i; + Uint8 pixel=0; + + smallest = ~0; + for ( i=0; incolors; ++i ) { + rd = pal->colors[i].r - r; + gd = pal->colors[i].g - g; + bd = pal->colors[i].b - b; + distance = (rd*rd)+(gd*gd)+(bd*bd); + if ( distance < smallest ) { + pixel = i; + if ( distance == 0 ) { /* Perfect match! */ + break; + } + smallest = distance; + } + } + return(pixel); +} + +/* Find the opaque pixel value corresponding to an RGB triple */ +Uint32 SDL_MapRGB(SDL_PixelFormat *format, Uint8 r, Uint8 g, Uint8 b) +{ + if ( format->palette == NULL ) { + return (r >> format->Rloss) << format->Rshift + | (g >> format->Gloss) << format->Gshift + | (b >> format->Bloss) << format->Bshift + | format->Amask; + } else { + return SDL_FindColor(format->palette, r, g, b); + } +} + +/* Find the pixel value corresponding to an RGBA quadruple */ +Uint32 SDL_MapRGBA(SDL_PixelFormat *format, Uint8 r, Uint8 g, Uint8 b, Uint8 a) +{ + if ( format->palette == NULL ) { + return (r >> format->Rloss) << format->Rshift + | (g >> format->Gloss) << format->Gshift + | (b >> format->Bloss) << format->Bshift + | ((a >> format->Aloss) << format->Ashift & format->Amask); + } else { + return SDL_FindColor(format->palette, r, g, b); + } +} + +void SDL_GetRGBA(Uint32 pixel, SDL_PixelFormat *fmt, + Uint8 *r, Uint8 *g, Uint8 *b, Uint8 *a) +{ + if ( fmt->palette == NULL ) { + /* + * This makes sure that the result is mapped to the + * interval [0..255], and the maximum value for each + * component is 255. This is important to make sure + * that white is indeed reported as (255, 255, 255), + * and that opaque alpha is 255. + * This only works for RGB bit fields at least 4 bit + * wide, which is almost always the case. + */ + unsigned rv, gv, bv, av; + rv = (pixel & fmt->Rmask) >> fmt->Rshift; + *r = (rv << fmt->Rloss) + (rv >> (8 - fmt->Rloss)); + gv = (pixel & fmt->Gmask) >> fmt->Gshift; + *g = (gv << fmt->Gloss) + (gv >> (8 - fmt->Gloss)); + bv = (pixel & fmt->Bmask) >> fmt->Bshift; + *b = (bv << fmt->Bloss) + (bv >> (8 - fmt->Bloss)); + if(fmt->Amask) { + av = (pixel & fmt->Amask) >> fmt->Ashift; + *a = (av << fmt->Aloss) + (av >> (8 - fmt->Aloss)); + } else + *a = SDL_ALPHA_OPAQUE; + } else { + *r = fmt->palette->colors[pixel].r; + *g = fmt->palette->colors[pixel].g; + *b = fmt->palette->colors[pixel].b; + *a = SDL_ALPHA_OPAQUE; + } +} + +void SDL_GetRGB(Uint32 pixel, SDL_PixelFormat *fmt, Uint8 *r,Uint8 *g,Uint8 *b) +{ + if ( fmt->palette == NULL ) { + /* the note for SDL_GetRGBA above applies here too */ + unsigned rv, gv, bv; + rv = (pixel & fmt->Rmask) >> fmt->Rshift; + *r = (rv << fmt->Rloss) + (rv >> (8 - fmt->Rloss)); + gv = (pixel & fmt->Gmask) >> fmt->Gshift; + *g = (gv << fmt->Gloss) + (gv >> (8 - fmt->Gloss)); + bv = (pixel & fmt->Bmask) >> fmt->Bshift; + *b = (bv << fmt->Bloss) + (bv >> (8 - fmt->Bloss)); + } else { + *r = fmt->palette->colors[pixel].r; + *g = fmt->palette->colors[pixel].g; + *b = fmt->palette->colors[pixel].b; + } +} + +/* Apply gamma to a set of colors - this is easy. :) */ +void SDL_ApplyGamma(Uint16 *gamma, SDL_Color *colors, SDL_Color *output, + int ncolors) +{ + int i; + + for ( i=0; i> 8; + output[i].g = gamma[1*256 + colors[i].g] >> 8; + output[i].b = gamma[2*256 + colors[i].b] >> 8; + } +} + +/* Map from Palette to Palette */ +static Uint8 *Map1to1(SDL_Palette *src, SDL_Palette *dst, int *identical) +{ + Uint8 *map; + int i; + + if ( identical ) { + if ( src->ncolors <= dst->ncolors ) { + /* If an identical palette, no need to map */ + if ( memcmp(src->colors, dst->colors, src->ncolors* + sizeof(SDL_Color)) == 0 ) { + *identical = 1; + return(NULL); + } + } + *identical = 0; + } + map = (Uint8 *)malloc(src->ncolors); + if ( map == NULL ) { + SDL_OutOfMemory(); + return(NULL); + } + for ( i=0; incolors; ++i ) { + map[i] = SDL_FindColor(dst, + src->colors[i].r, src->colors[i].g, src->colors[i].b); + } + return(map); +} +/* Map from Palette to BitField */ +static Uint8 *Map1toN(SDL_Palette *src, SDL_PixelFormat *dst) +{ + Uint8 *map; + int i; + int bpp; + unsigned alpha; + + bpp = ((dst->BytesPerPixel == 3) ? 4 : dst->BytesPerPixel); + map = (Uint8 *)malloc(src->ncolors*bpp); + if ( map == NULL ) { + SDL_OutOfMemory(); + return(NULL); + } + + alpha = dst->Amask ? SDL_ALPHA_OPAQUE : 0; + /* We memory copy to the pixel map so the endianness is preserved */ + for ( i=0; incolors; ++i ) { + ASSEMBLE_RGBA(&map[i*bpp], dst->BytesPerPixel, dst, + src->colors[i].r, src->colors[i].g, + src->colors[i].b, alpha); + } + return(map); +} +/* Map from BitField to Dithered-Palette to Palette */ +static Uint8 *MapNto1(SDL_PixelFormat *src, SDL_Palette *dst, int *identical) +{ + /* Generate a 256 color dither palette */ + SDL_Palette dithered; + SDL_Color colors[256]; + + dithered.ncolors = 256; + SDL_DitherColors(colors, 8); + dithered.colors = colors; + return(Map1to1(&dithered, dst, identical)); +} + +SDL_BlitMap *SDL_AllocBlitMap(void) +{ + SDL_BlitMap *map; + + /* Allocate the empty map */ + map = (SDL_BlitMap *)malloc(sizeof(*map)); + if ( map == NULL ) { + SDL_OutOfMemory(); + return(NULL); + } + memset(map, 0, sizeof(*map)); + + /* Allocate the software blit data */ + map->sw_data = (struct private_swaccel *)malloc(sizeof(*map->sw_data)); + if ( map->sw_data == NULL ) { + SDL_FreeBlitMap(map); + SDL_OutOfMemory(); + return(NULL); + } + memset(map->sw_data, 0, sizeof(*map->sw_data)); + + /* It's ready to go */ + return(map); +} +void SDL_InvalidateMap(SDL_BlitMap *map) +{ + if ( ! map ) { + return; + } + map->dst = NULL; + map->format_version = (unsigned int)-1; + if ( map->table ) { + free(map->table); + map->table = NULL; + } +} +int SDL_MapSurface (SDL_Surface *src, SDL_Surface *dst) +{ + SDL_PixelFormat *srcfmt; + SDL_PixelFormat *dstfmt; + SDL_BlitMap *map; + + /* Clear out any previous mapping */ + map = src->map; + if ( (src->flags & SDL_RLEACCEL) == SDL_RLEACCEL ) { + SDL_UnRLESurface(src, 1); + } + SDL_InvalidateMap(map); + + /* Figure out what kind of mapping we're doing */ + map->identity = 0; + srcfmt = src->format; + dstfmt = dst->format; + switch (srcfmt->BytesPerPixel) { + case 1: + switch (dstfmt->BytesPerPixel) { + case 1: + /* Palette --> Palette */ + /* If both SDL_HWSURFACE, assume have same palette */ + if ( ((src->flags & SDL_HWSURFACE) == SDL_HWSURFACE) && + ((dst->flags & SDL_HWSURFACE) == SDL_HWSURFACE) ) { + map->identity = 1; + } else { + map->table = Map1to1(srcfmt->palette, + dstfmt->palette, &map->identity); + } + if ( ! map->identity ) { + if ( map->table == NULL ) { + return(-1); + } + } + if (srcfmt->BitsPerPixel!=dstfmt->BitsPerPixel) + map->identity = 0; + break; + + default: + /* Palette --> BitField */ + map->table = Map1toN(srcfmt->palette, dstfmt); + if ( map->table == NULL ) { + return(-1); + } + break; + } + break; + default: + switch (dstfmt->BytesPerPixel) { + case 1: + /* BitField --> Palette */ + map->table = MapNto1(srcfmt, + dstfmt->palette, &map->identity); + if ( ! map->identity ) { + if ( map->table == NULL ) { + return(-1); + } + } + map->identity = 0; /* Don't optimize to copy */ + break; + default: + /* BitField --> BitField */ + if ( FORMAT_EQUAL(srcfmt, dstfmt) ) + map->identity = 1; + break; + } + break; + } + + map->dst = dst; + map->format_version = dst->format_version; + + /* Choose your blitters wisely */ + return(SDL_CalculateBlit(src)); +} +void SDL_FreeBlitMap(SDL_BlitMap *map) +{ + if ( map ) { + SDL_InvalidateMap(map); + if ( map->sw_data != NULL ) { + free(map->sw_data); + } + free(map); + } +} diff --git a/contrib/sdk/sources/SDL-1.2.2/src/video/SDL_pixels_c.h b/contrib/sdk/sources/SDL-1.2.2/src/video/SDL_pixels_c.h new file mode 100644 index 000000000..ea8ecb68a --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/src/video/SDL_pixels_c.h @@ -0,0 +1,50 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997, 1998, 1999, 2000, 2001 Sam Lantinga + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the Free + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + Sam Lantinga + slouken@devolution.com +*/ + +#ifdef SAVE_RCSID +static char rcsid = + "@(#) $Id: SDL_pixels_c.h,v 1.2 2001/04/26 16:50:18 hercules Exp $"; +#endif + +/* Useful functions and variables from SDL_pixel.c */ + +#include "SDL_blit.h" + +/* Pixel format functions */ +extern SDL_PixelFormat *SDL_AllocFormat(int bpp, + Uint32 Rmask, Uint32 Gmask, Uint32 Bmask, Uint32 Amask); +extern SDL_PixelFormat *SDL_ReallocFormat(SDL_Surface *surface, int bpp, + Uint32 Rmask, Uint32 Gmask, Uint32 Bmask, Uint32 Amask); +extern void SDL_FormatChanged(SDL_Surface *surface); +extern void SDL_FreeFormat(SDL_PixelFormat *format); + +/* Blit mapping functions */ +extern SDL_BlitMap *SDL_AllocBlitMap(void); +extern void SDL_InvalidateMap(SDL_BlitMap *map); +extern int SDL_MapSurface (SDL_Surface *src, SDL_Surface *dst); +extern void SDL_FreeBlitMap(SDL_BlitMap *map); + +/* Miscellaneous functions */ +extern Uint16 SDL_CalculatePitch(SDL_Surface *surface); +extern void SDL_DitherColors(SDL_Color *colors, int bpp); +extern Uint8 SDL_FindColor(SDL_Palette *pal, Uint8 r, Uint8 g, Uint8 b); +extern void SDL_ApplyGamma(Uint16 *gamma, SDL_Color *colors, SDL_Color *output, int ncolors); diff --git a/contrib/sdk/sources/SDL-1.2.2/src/video/SDL_stretch.c b/contrib/sdk/sources/SDL-1.2.2/src/video/SDL_stretch.c new file mode 100644 index 000000000..8d3b25f21 --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/src/video/SDL_stretch.c @@ -0,0 +1,305 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997, 1998, 1999, 2000, 2001 Sam Lantinga + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the Free + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + Sam Lantinga + slouken@devolution.com +*/ + +/* This a stretch blit implementation based on ideas given to me by + Tomasz Cejner - thanks! :) + + April 27, 2000 - Sam Lantinga +*/ + +#include "SDL_error.h" +#include "SDL_video.h" +#include "SDL_blit.h" + +/* This isn't ready for general consumption yet - it should be folded + into the general blitting mechanism. +*/ + +#if (defined(WIN32UNDEFINED) && !defined(_M_ALPHA) && !defined(_WIN32_WCE)) || \ + defined(i386) && defined(__GNUC__) && defined(USE_ASMBLIT) +#define USE_ASM_STRETCH +#endif + +#ifdef USE_ASM_STRETCH + +#if defined(WIN32UNDEFINED) || defined(i386) +#define PREFIX16 0x66 +#define STORE_BYTE 0xAA +#define STORE_WORD 0xAB +#define LOAD_BYTE 0xAC +#define LOAD_WORD 0xAD +#define RETURN 0xC3 +#else +#error Need assembly opcodes for this architecture +#endif + +#if defined(__ELF__) && defined(__GNUC__) +extern unsigned char _copy_row[4096] __attribute__ ((alias ("copy_row"))); +#endif +static unsigned char copy_row[4096]; + +static int generate_rowbytes(int src_w, int dst_w, int bpp) +{ + static struct { + int bpp; + int src_w; + int dst_w; + } last; + + int i; + int pos, inc; + unsigned char *eip; + unsigned char load, store; + + /* See if we need to regenerate the copy buffer */ + if ( (src_w == last.src_w) && + (dst_w == last.src_w) && (bpp == last.bpp) ) { + return(0); + } + last.bpp = bpp; + last.src_w = src_w; + last.dst_w = dst_w; + + switch (bpp) { + case 1: + load = LOAD_BYTE; + store = STORE_BYTE; + break; + case 2: + case 4: + load = LOAD_WORD; + store = STORE_WORD; + break; + default: + SDL_SetError("ASM stretch of %d bytes isn't supported\n", bpp); + return(-1); + } + pos = 0x10000; + inc = (src_w << 16) / dst_w; + eip = copy_row; + for ( i=0; i= 0x10000L ) { + if ( bpp == 2 ) { + *eip++ = PREFIX16; + } + *eip++ = load; + pos -= 0x10000L; + } + if ( bpp == 2 ) { + *eip++ = PREFIX16; + } + *eip++ = store; + pos += inc; + } + *eip++ = RETURN; + + /* Verify that we didn't overflow (too late) */ + if ( eip > (copy_row+sizeof(copy_row)) ) { + SDL_SetError("Copy buffer overflow"); + return(-1); + } + return(0); +} + +#else + +#define DEFINE_COPY_ROW(name, type) \ +void name(type *src, int src_w, type *dst, int dst_w) \ +{ \ + int i; \ + int pos, inc; \ + type pixel = 0; \ + \ + pos = 0x10000; \ + inc = (src_w << 16) / dst_w; \ + for ( i=dst_w; i>0; --i ) { \ + while ( pos >= 0x10000L ) { \ + pixel = *src++; \ + pos -= 0x10000L; \ + } \ + *dst++ = pixel; \ + pos += inc; \ + } \ +} +DEFINE_COPY_ROW(copy_row1, Uint8) +DEFINE_COPY_ROW(copy_row2, Uint16) +DEFINE_COPY_ROW(copy_row4, Uint32) + +#endif /* USE_ASM_STRETCH */ + +/* The ASM code doesn't handle 24-bpp stretch blits */ +void copy_row3(Uint8 *src, int src_w, Uint8 *dst, int dst_w) +{ + int i; + int pos, inc; + Uint8 pixel[3]; + + pos = 0x10000; + inc = (src_w << 16) / dst_w; + for ( i=dst_w; i>0; --i ) { + while ( pos >= 0x10000L ) { + pixel[0] = *src++; + pixel[1] = *src++; + pixel[2] = *src++; + pos -= 0x10000L; + } + *dst++ = pixel[0]; + *dst++ = pixel[1]; + *dst++ = pixel[2]; + pos += inc; + } +} + +/* Perform a stretch blit between two surfaces of the same format. + NOTE: This function is not safe to call from multiple threads! +*/ +int SDL_SoftStretch(SDL_Surface *src, SDL_Rect *srcrect, + SDL_Surface *dst, SDL_Rect *dstrect) +{ + int pos, inc; + int dst_width; + int dst_maxrow; + int src_row, dst_row; + Uint8 *srcp = NULL; + Uint8 *dstp; + SDL_Rect full_src; + SDL_Rect full_dst; +#if defined(USE_ASM_STRETCH) && defined(__GNUC__) + int u1, u2; +#endif + const int bpp = dst->format->BytesPerPixel; + + if ( src->format->BitsPerPixel != dst->format->BitsPerPixel ) { + SDL_SetError("Only works with same format surfaces"); + return(-1); + } + + /* Verify the blit rectangles */ + if ( srcrect ) { + if ( (srcrect->x < 0) || (srcrect->y < 0) || + ((srcrect->x+srcrect->w) > src->w) || + ((srcrect->y+srcrect->h) > src->h) ) { + SDL_SetError("Invalid source blit rectangle"); + return(-1); + } + } else { + full_src.x = 0; + full_src.y = 0; + full_src.w = src->w; + full_src.h = src->h; + srcrect = &full_src; + } + if ( dstrect ) { + if ( (dstrect->x < 0) || (dstrect->y < 0) || + ((dstrect->x+dstrect->w) > dst->w) || + ((dstrect->y+dstrect->h) > dst->h) ) { + SDL_SetError("Invalid destination blit rectangle"); + return(-1); + } + } else { + full_dst.x = 0; + full_dst.y = 0; + full_dst.w = dst->w; + full_dst.h = dst->h; + dstrect = &full_dst; + } + + /* Set up the data... */ + pos = 0x10000; + inc = (srcrect->h << 16) / dstrect->h; + src_row = srcrect->y; + dst_row = dstrect->y; + dst_width = dstrect->w*bpp; + +#ifdef USE_ASM_STRETCH + /* Write the opcodes for this stretch */ + if ( (bpp != 3) && + (generate_rowbytes(srcrect->w, dstrect->w, bpp) < 0) ) { + return(-1); + } +#endif + + /* Perform the stretch blit */ + for ( dst_maxrow = dst_row+dstrect->h; dst_rowpixels + (dst_row*dst->pitch) + + (dstrect->x*bpp); + while ( pos >= 0x10000L ) { + srcp = (Uint8 *)src->pixels + (src_row*src->pitch) + + (srcrect->x*bpp); + ++src_row; + pos -= 0x10000L; + } +#ifdef USE_ASM_STRETCH + switch (bpp) { + case 3: + copy_row3(srcp, srcrect->w, dstp, dstrect->w); + break; + default: +#ifdef __GNUC__ + __asm__ __volatile__ ("call _copy_row" + : "=&D" (u1), "=&S" (u2) + : "0" (dstp), "1" (srcp) + : "memory" ); +#else +#ifdef WIN32UNDEFINED + { void *code = ©_row; + __asm { + push edi + push esi + + mov edi, dstp + mov esi, srcp + call dword ptr code + + pop esi + pop edi + } + } +#else +#error Need inline assembly for this compiler +#endif +#endif /* __GNUC__ */ + break; + } +#else + switch (bpp) { + case 1: + copy_row1(srcp, srcrect->w, dstp, dstrect->w); + break; + case 2: + copy_row2((Uint16 *)srcp, srcrect->w, + (Uint16 *)dstp, dstrect->w); + break; + case 3: + copy_row3(srcp, srcrect->w, dstp, dstrect->w); + break; + case 4: + copy_row4((Uint32 *)srcp, srcrect->w, + (Uint32 *)dstp, dstrect->w); + break; + } +#endif + pos += inc; + } + return(0); +} + diff --git a/contrib/sdk/sources/SDL-1.2.2/src/video/SDL_stretch.c.BAK b/contrib/sdk/sources/SDL-1.2.2/src/video/SDL_stretch.c.BAK new file mode 100644 index 000000000..0040a9df5 --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/src/video/SDL_stretch.c.BAK @@ -0,0 +1,305 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997, 1998, 1999, 2000, 2001 Sam Lantinga + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the Free + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + Sam Lantinga + slouken@devolution.com +*/ + +/* This a stretch blit implementation based on ideas given to me by + Tomasz Cejner - thanks! :) + + April 27, 2000 - Sam Lantinga +*/ + +#include "SDL_error.h" +#include "SDL_video.h" +#include "SDL_blit.h" + +/* This isn't ready for general consumption yet - it should be folded + into the general blitting mechanism. +*/ + +#if (defined(WIN32) && !defined(_M_ALPHA) && !defined(_WIN32_WCE)) || \ + defined(i386) && defined(__GNUC__) && defined(USE_ASMBLIT) +#define USE_ASM_STRETCH +#endif + +#ifdef USE_ASM_STRETCH + +#if defined(WIN32) || defined(i386) +#define PREFIX16 0x66 +#define STORE_BYTE 0xAA +#define STORE_WORD 0xAB +#define LOAD_BYTE 0xAC +#define LOAD_WORD 0xAD +#define RETURN 0xC3 +#else +#error Need assembly opcodes for this architecture +#endif + +#if defined(__ELF__) && defined(__GNUC__) +extern unsigned char _copy_row[4096] __attribute__ ((alias ("copy_row"))); +#endif +static unsigned char copy_row[4096]; + +static int generate_rowbytes(int src_w, int dst_w, int bpp) +{ + static struct { + int bpp; + int src_w; + int dst_w; + } last; + + int i; + int pos, inc; + unsigned char *eip; + unsigned char load, store; + + /* See if we need to regenerate the copy buffer */ + if ( (src_w == last.src_w) && + (dst_w == last.src_w) && (bpp == last.bpp) ) { + return(0); + } + last.bpp = bpp; + last.src_w = src_w; + last.dst_w = dst_w; + + switch (bpp) { + case 1: + load = LOAD_BYTE; + store = STORE_BYTE; + break; + case 2: + case 4: + load = LOAD_WORD; + store = STORE_WORD; + break; + default: + SDL_SetError("ASM stretch of %d bytes isn't supported\n", bpp); + return(-1); + } + pos = 0x10000; + inc = (src_w << 16) / dst_w; + eip = copy_row; + for ( i=0; i= 0x10000L ) { + if ( bpp == 2 ) { + *eip++ = PREFIX16; + } + *eip++ = load; + pos -= 0x10000L; + } + if ( bpp == 2 ) { + *eip++ = PREFIX16; + } + *eip++ = store; + pos += inc; + } + *eip++ = RETURN; + + /* Verify that we didn't overflow (too late) */ + if ( eip > (copy_row+sizeof(copy_row)) ) { + SDL_SetError("Copy buffer overflow"); + return(-1); + } + return(0); +} + +#else + +#define DEFINE_COPY_ROW(name, type) \ +void name(type *src, int src_w, type *dst, int dst_w) \ +{ \ + int i; \ + int pos, inc; \ + type pixel = 0; \ + \ + pos = 0x10000; \ + inc = (src_w << 16) / dst_w; \ + for ( i=dst_w; i>0; --i ) { \ + while ( pos >= 0x10000L ) { \ + pixel = *src++; \ + pos -= 0x10000L; \ + } \ + *dst++ = pixel; \ + pos += inc; \ + } \ +} +DEFINE_COPY_ROW(copy_row1, Uint8) +DEFINE_COPY_ROW(copy_row2, Uint16) +DEFINE_COPY_ROW(copy_row4, Uint32) + +#endif /* USE_ASM_STRETCH */ + +/* The ASM code doesn't handle 24-bpp stretch blits */ +void copy_row3(Uint8 *src, int src_w, Uint8 *dst, int dst_w) +{ + int i; + int pos, inc; + Uint8 pixel[3]; + + pos = 0x10000; + inc = (src_w << 16) / dst_w; + for ( i=dst_w; i>0; --i ) { + while ( pos >= 0x10000L ) { + pixel[0] = *src++; + pixel[1] = *src++; + pixel[2] = *src++; + pos -= 0x10000L; + } + *dst++ = pixel[0]; + *dst++ = pixel[1]; + *dst++ = pixel[2]; + pos += inc; + } +} + +/* Perform a stretch blit between two surfaces of the same format. + NOTE: This function is not safe to call from multiple threads! +*/ +int SDL_SoftStretch(SDL_Surface *src, SDL_Rect *srcrect, + SDL_Surface *dst, SDL_Rect *dstrect) +{ + int pos, inc; + int dst_width; + int dst_maxrow; + int src_row, dst_row; + Uint8 *srcp = NULL; + Uint8 *dstp; + SDL_Rect full_src; + SDL_Rect full_dst; +#if defined(USE_ASM_STRETCH) && defined(__GNUC__) + int u1, u2; +#endif + const int bpp = dst->format->BytesPerPixel; + + if ( src->format->BitsPerPixel != dst->format->BitsPerPixel ) { + SDL_SetError("Only works with same format surfaces"); + return(-1); + } + + /* Verify the blit rectangles */ + if ( srcrect ) { + if ( (srcrect->x < 0) || (srcrect->y < 0) || + ((srcrect->x+srcrect->w) > src->w) || + ((srcrect->y+srcrect->h) > src->h) ) { + SDL_SetError("Invalid source blit rectangle"); + return(-1); + } + } else { + full_src.x = 0; + full_src.y = 0; + full_src.w = src->w; + full_src.h = src->h; + srcrect = &full_src; + } + if ( dstrect ) { + if ( (dstrect->x < 0) || (dstrect->y < 0) || + ((dstrect->x+dstrect->w) > dst->w) || + ((dstrect->y+dstrect->h) > dst->h) ) { + SDL_SetError("Invalid destination blit rectangle"); + return(-1); + } + } else { + full_dst.x = 0; + full_dst.y = 0; + full_dst.w = dst->w; + full_dst.h = dst->h; + dstrect = &full_dst; + } + + /* Set up the data... */ + pos = 0x10000; + inc = (srcrect->h << 16) / dstrect->h; + src_row = srcrect->y; + dst_row = dstrect->y; + dst_width = dstrect->w*bpp; + +#ifdef USE_ASM_STRETCH + /* Write the opcodes for this stretch */ + if ( (bpp != 3) && + (generate_rowbytes(srcrect->w, dstrect->w, bpp) < 0) ) { + return(-1); + } +#endif + + /* Perform the stretch blit */ + for ( dst_maxrow = dst_row+dstrect->h; dst_rowpixels + (dst_row*dst->pitch) + + (dstrect->x*bpp); + while ( pos >= 0x10000L ) { + srcp = (Uint8 *)src->pixels + (src_row*src->pitch) + + (srcrect->x*bpp); + ++src_row; + pos -= 0x10000L; + } +#ifdef USE_ASM_STRETCH + switch (bpp) { + case 3: + copy_row3(srcp, srcrect->w, dstp, dstrect->w); + break; + default: +#ifdef __GNUC__ + __asm__ __volatile__ ("call _copy_row" + : "=&D" (u1), "=&S" (u2) + : "0" (dstp), "1" (srcp) + : "memory" ); +#else +#ifdef WIN32 + { void *code = ©_row; + __asm { + push edi + push esi + + mov edi, dstp + mov esi, srcp + call dword ptr code + + pop esi + pop edi + } + } +#else +#error Need inline assembly for this compiler +#endif +#endif /* __GNUC__ */ + break; + } +#else + switch (bpp) { + case 1: + copy_row1(srcp, srcrect->w, dstp, dstrect->w); + break; + case 2: + copy_row2((Uint16 *)srcp, srcrect->w, + (Uint16 *)dstp, dstrect->w); + break; + case 3: + copy_row3(srcp, srcrect->w, dstp, dstrect->w); + break; + case 4: + copy_row4((Uint32 *)srcp, srcrect->w, + (Uint32 *)dstp, dstrect->w); + break; + } +#endif + pos += inc; + } + return(0); +} + diff --git a/contrib/sdk/sources/SDL-1.2.2/src/video/SDL_stretch_c.h b/contrib/sdk/sources/SDL-1.2.2/src/video/SDL_stretch_c.h new file mode 100644 index 000000000..c56e5a5cb --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/src/video/SDL_stretch_c.h @@ -0,0 +1,33 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997, 1998, 1999, 2000, 2001 Sam Lantinga + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the Free + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + Sam Lantinga + slouken@devolution.com +*/ + +#ifdef SAVE_RCSID +static char rcsid = + "@(#) $Id: SDL_stretch_c.h,v 1.2 2001/04/26 16:50:18 hercules Exp $"; +#endif + +/* Perform a stretch blit between two surfaces of the same format. + NOTE: This function is not safe to call from multiple threads! +*/ +extern int SDL_SoftStretch(SDL_Surface *src, SDL_Rect *srcrect, + SDL_Surface *dst, SDL_Rect *dstrect); + diff --git a/contrib/sdk/sources/SDL-1.2.2/src/video/SDL_surface.c b/contrib/sdk/sources/SDL-1.2.2/src/video/SDL_surface.c new file mode 100644 index 000000000..4d1c16ea8 --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/src/video/SDL_surface.c @@ -0,0 +1,816 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997, 1998, 1999, 2000, 2001 Sam Lantinga + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the Free + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + Sam Lantinga + slouken@devolution.com +*/ + + +#include +#include +#include + +#include "SDL_error.h" +#include "SDL_video.h" +#include "SDL_sysvideo.h" +#include "SDL_cursor_c.h" +#include "SDL_blit.h" +#include "SDL_RLEaccel_c.h" +#include "SDL_pixels_c.h" +#include "SDL_memops.h" +#include "SDL_leaks.h" + +/* Public routines */ +/* + * Create an empty RGB surface of the appropriate depth + */ +SDL_Surface * SDL_CreateRGBSurface (Uint32 flags, + int width, int height, int depth, + Uint32 Rmask, Uint32 Gmask, Uint32 Bmask, Uint32 Amask) +{ + SDL_VideoDevice *video = current_video; + SDL_VideoDevice *this = current_video; + SDL_Surface *screen; + SDL_Surface *surface; + + /* Check to see if we desire the surface in video memory */ + if ( video ) { + screen = SDL_PublicSurface; + } else { + screen = NULL; + } + if ( screen && ((screen->flags&SDL_HWSURFACE) == SDL_HWSURFACE) ) { + if ( (flags&(SDL_SRCCOLORKEY|SDL_SRCALPHA)) != 0 ) { + flags |= SDL_HWSURFACE; + } + if ( (flags & SDL_SRCCOLORKEY) == SDL_SRCCOLORKEY ) { + if ( ! current_video->info.blit_hw_CC ) { + flags &= ~SDL_HWSURFACE; + } + } + if ( (flags & SDL_SRCALPHA) == SDL_SRCALPHA ) { + if ( ! current_video->info.blit_hw_A ) { + flags &= ~SDL_HWSURFACE; + } + } + } else { + flags &= ~SDL_HWSURFACE; + } + + /* Allocate the surface */ + surface = (SDL_Surface *)malloc(sizeof(*surface)); + if ( surface == NULL ) { + SDL_OutOfMemory(); + return(NULL); + } + surface->flags = SDL_SWSURFACE; + if ( (flags & SDL_HWSURFACE) == SDL_HWSURFACE ) { + depth = screen->format->BitsPerPixel; + Rmask = screen->format->Rmask; + Gmask = screen->format->Gmask; + Bmask = screen->format->Bmask; + Amask = screen->format->Amask; + } + surface->format = SDL_AllocFormat(depth, Rmask, Gmask, Bmask, Amask); + if ( surface->format == NULL ) { + free(surface); + return(NULL); + } + if ( Amask ) { + surface->flags |= SDL_SRCALPHA; + } + surface->w = width; + surface->h = height; + surface->pitch = SDL_CalculatePitch(surface); + surface->pixels = NULL; + surface->offset = 0; + surface->hwdata = NULL; + surface->locked = 0; + surface->map = NULL; + surface->format_version = 0; + SDL_SetClipRect(surface, NULL); + + /* Get the pixels */ + if ( ((flags&SDL_HWSURFACE) == SDL_SWSURFACE) || + (video->AllocHWSurface(this, surface) < 0) ) { + if ( surface->w && surface->h ) { + surface->pixels = malloc(surface->h*surface->pitch); + if ( surface->pixels == NULL ) { + SDL_FreeSurface(surface); + SDL_OutOfMemory(); + return(NULL); + } + /* This is important for bitmaps */ + memset(surface->pixels, 0, surface->h*surface->pitch); + } + } + + /* Allocate an empty mapping */ + surface->map = SDL_AllocBlitMap(); + if ( surface->map == NULL ) { + SDL_FreeSurface(surface); + return(NULL); + } + + /* The surface is ready to go */ + surface->refcount = 1; +#ifdef CHECK_LEAKS + ++surfaces_allocated; +#endif + return(surface); +} +/* + * Create an RGB surface from an existing memory buffer + */ +SDL_Surface * SDL_CreateRGBSurfaceFrom (void *pixels, + int width, int height, int depth, int pitch, + Uint32 Rmask, Uint32 Gmask, Uint32 Bmask, Uint32 Amask) +{ + SDL_Surface *surface; + + surface = SDL_CreateRGBSurface(SDL_SWSURFACE, 0, 0, depth, + Rmask, Gmask, Bmask, Amask); + if ( surface != NULL ) { + surface->flags |= SDL_PREALLOC; + surface->pixels = pixels; + surface->w = width; + surface->h = height; + surface->pitch = pitch; + SDL_SetClipRect(surface, NULL); + } + return(surface); +} +/* + * Set the color key in a blittable surface + */ +int SDL_SetColorKey (SDL_Surface *surface, Uint32 flag, Uint32 key) +{ + /* Sanity check the flag as it gets passed in */ + if ( flag & SDL_SRCCOLORKEY ) { + if ( flag & (SDL_RLEACCEL|SDL_RLEACCELOK) ) { + flag = (SDL_SRCCOLORKEY | SDL_RLEACCELOK); + } else { + flag = SDL_SRCCOLORKEY; + } + } else { + flag = 0; + } + + /* Optimize away operations that don't change anything */ + if ( (flag == (surface->flags & (SDL_SRCCOLORKEY|SDL_RLEACCELOK))) && + (key == surface->format->colorkey) ) { + return(0); + } + + /* UnRLE surfaces before we change the colorkey */ + if ( surface->flags & SDL_RLEACCEL ) { + SDL_UnRLESurface(surface, 1); + } + + if ( flag ) { + SDL_VideoDevice *video = current_video; + SDL_VideoDevice *this = current_video; + + + surface->flags |= SDL_SRCCOLORKEY; + surface->format->colorkey = key; + if ( (surface->flags & SDL_HWACCEL) == SDL_HWACCEL ) { + if ( (video->SetHWColorKey == NULL) || + (video->SetHWColorKey(this, surface, key) < 0) ) { + surface->flags &= ~SDL_HWACCEL; + } + } + if ( flag & SDL_RLEACCELOK ) { + surface->flags |= SDL_RLEACCELOK; + } else { + surface->flags &= ~SDL_RLEACCELOK; + } + } else { + surface->flags &= ~(SDL_SRCCOLORKEY|SDL_RLEACCELOK); + surface->format->colorkey = 0; + } + SDL_InvalidateMap(surface->map); + return(0); +} +int SDL_SetAlpha (SDL_Surface *surface, Uint32 flag, Uint8 value) +{ + Uint32 oldflags = surface->flags; + Uint32 oldalpha = surface->format->alpha; + + /* Sanity check the flag as it gets passed in */ + if ( flag & SDL_SRCALPHA ) { + if ( flag & (SDL_RLEACCEL|SDL_RLEACCELOK) ) { + flag = (SDL_SRCALPHA | SDL_RLEACCELOK); + } else { + flag = SDL_SRCALPHA; + } + } else { + flag = 0; + } + + /* Optimize away operations that don't change anything */ + if ( (flag == (surface->flags & (SDL_SRCALPHA|SDL_RLEACCELOK))) && + (!flag || value == oldalpha) ) { + return(0); + } + + if(!(flag & SDL_RLEACCELOK) && (surface->flags & SDL_RLEACCEL)) + SDL_UnRLESurface(surface, 1); + + if ( flag ) { + SDL_VideoDevice *video = current_video; + SDL_VideoDevice *this = current_video; + + surface->flags |= SDL_SRCALPHA; + surface->format->alpha = value; + if ( (surface->flags & SDL_HWACCEL) == SDL_HWACCEL ) { + if ( (video->SetHWAlpha == NULL) || + (video->SetHWAlpha(this, surface, value) < 0) ) { + surface->flags &= ~SDL_HWACCEL; + } + } + if ( flag & SDL_RLEACCELOK ) { + surface->flags |= SDL_RLEACCELOK; + } else { + surface->flags &= ~SDL_RLEACCELOK; + } + } else { + surface->flags &= ~SDL_SRCALPHA; + surface->format->alpha = SDL_ALPHA_OPAQUE; + } + /* + * The representation for software surfaces is independent of + * per-surface alpha, so no need to invalidate the blit mapping + * if just the alpha value was changed. (If either is 255, we still + * need to invalidate.) + */ + if((surface->flags & SDL_HWACCEL) == SDL_HWACCEL + || oldflags != surface->flags + || (((oldalpha + 1) ^ (value + 1)) & 0x100)) + SDL_InvalidateMap(surface->map); + return(0); +} + +/* + * A function to calculate the intersection of two rectangles: + * return true if the rectangles intersect, false otherwise + */ +static __inline__ +SDL_bool SDL_IntersectRect(SDL_Rect *A, SDL_Rect *B, SDL_Rect *intersection) +{ + int Amin, Amax, Bmin, Bmax; + + /* Horizontal intersection */ + Amin = A->x; + Amax = Amin + A->w; + Bmin = B->x; + Bmax = Bmin + B->w; + if(Bmin > Amin) + Amin = Bmin; + intersection->x = Amin; + if(Bmax < Amax) + Amax = Bmax; + intersection->w = Amax - Amin > 0 ? Amax - Amin : 0; + + /* Vertical intersection */ + Amin = A->y; + Amax = Amin + A->h; + Bmin = B->y; + Bmax = Bmin + B->h; + if(Bmin > Amin) + Amin = Bmin; + intersection->y = Amin; + if(Bmax < Amax) + Amax = Bmax; + intersection->h = Amax - Amin > 0 ? Amax - Amin : 0; + + return (intersection->w && intersection->h); +} +/* + * Set the clipping rectangle for a blittable surface + */ +SDL_bool SDL_SetClipRect(SDL_Surface *surface, SDL_Rect *rect) +{ + SDL_Rect full_rect; + + /* Don't do anything if there's no surface to act on */ + if ( ! surface ) { + return SDL_FALSE; + } + + /* Set up the full surface rectangle */ + full_rect.x = 0; + full_rect.y = 0; + full_rect.w = surface->w; + full_rect.h = surface->h; + + /* Set the clipping rectangle */ + if ( ! rect ) { + surface->clip_rect = full_rect; + return 1; + } + return SDL_IntersectRect(rect, &full_rect, &surface->clip_rect); +} +void SDL_GetClipRect(SDL_Surface *surface, SDL_Rect *rect) +{ + if ( surface && rect ) { + *rect = surface->clip_rect; + } +} +/* + * Set up a blit between two surfaces -- split into three parts: + * The upper part, SDL_UpperBlit(), performs clipping and rectangle + * verification. The lower part is a pointer to a low level + * accelerated blitting function. + * + * These parts are separated out and each used internally by this + * library in the optimimum places. They are exported so that if + * you know exactly what you are doing, you can optimize your code + * by calling the one(s) you need. + */ +int SDL_LowerBlit (SDL_Surface *src, SDL_Rect *srcrect, + SDL_Surface *dst, SDL_Rect *dstrect) +{ + SDL_blit do_blit; + + /* Check to make sure the blit mapping is valid */ + if ( (src->map->dst != dst) || + (src->map->dst->format_version != src->map->format_version) ) { + if ( SDL_MapSurface(src, dst) < 0 ) { + return(-1); + } + } + + /* Figure out which blitter to use */ + if ( (src->flags & SDL_HWACCEL) == SDL_HWACCEL ) { + do_blit = src->map->hw_blit; + } else { + do_blit = src->map->sw_blit; + } + return(do_blit(src, srcrect, dst, dstrect)); +} + + +int SDL_UpperBlit (SDL_Surface *src, SDL_Rect *srcrect, + SDL_Surface *dst, SDL_Rect *dstrect) +{ + SDL_Rect fulldst; + int srcx, srcy, w, h; + + /* Make sure the surfaces aren't locked */ + if ( ! src || ! dst ) { + SDL_SetError("SDL_UpperBlit: passed a NULL surface"); + return(-1); + } + if ( src->locked || dst->locked ) { + SDL_SetError("Surfaces must not be locked during blit"); + return(-1); + } + + /* If the destination rectangle is NULL, use the entire dest surface */ + if ( dstrect == NULL ) { + fulldst.x = fulldst.y = 0; + dstrect = &fulldst; + } + + /* clip the source rectangle to the source surface */ + if(srcrect) { + int maxw, maxh; + + srcx = srcrect->x; + w = srcrect->w; + if(srcx < 0) { + w += srcx; + dstrect->x -= srcx; + srcx = 0; + } + maxw = src->w - srcx; + if(maxw < w) + w = maxw; + + srcy = srcrect->y; + h = srcrect->h; + if(srcy < 0) { + h += srcy; + dstrect->y -= srcy; + srcy = 0; + } + maxh = src->h - srcy; + if(maxh < h) + h = maxh; + + } else { + srcx = srcy = 0; + w = src->w; + h = src->h; + } + + /* clip the destination rectangle against the clip rectangle */ + { + SDL_Rect *clip = &dst->clip_rect; + int dx, dy; + + dx = clip->x - dstrect->x; + if(dx > 0) { + w -= dx; + dstrect->x += dx; + srcx += dx; + } + dx = dstrect->x + w - clip->x - clip->w; + if(dx > 0) + w -= dx; + + dy = clip->y - dstrect->y; + if(dy > 0) { + h -= dy; + dstrect->y += dy; + srcy += dy; + } + dy = dstrect->y + h - clip->y - clip->h; + if(dy > 0) + h -= dy; + } + + if(w > 0 && h > 0) { + SDL_Rect sr; + sr.x = srcx; + sr.y = srcy; + sr.w = dstrect->w = w; + sr.h = dstrect->h = h; + return SDL_LowerBlit(src, &sr, dst, dstrect); + } + dstrect->w = dstrect->h = 0; + return 0; +} + +/* + * This function performs a fast fill of the given rectangle with 'color' + */ +int SDL_FillRect(SDL_Surface *dst, SDL_Rect *dstrect, Uint32 color) +{ + SDL_VideoDevice *video = current_video; + SDL_VideoDevice *this = current_video; + int x, y; + Uint8 *row; + + /* If 'dstrect' == NULL, then fill the whole surface */ + if ( dstrect ) { + /* Perform clipping */ + if ( !SDL_IntersectRect(dstrect, &dst->clip_rect, dstrect) ) { + return(0); + } + } else { + dstrect = &dst->clip_rect; + } + + /* Check for hardware acceleration */ + if ( ((dst->flags & SDL_HWSURFACE) == SDL_HWSURFACE) && + video->info.blit_fill ) { + return(video->FillHWRect(this, dst, dstrect, color)); + } + + /* Perform software fill */ + if ( SDL_LockSurface(dst) != 0 ) { + return(-1); + } + row = (Uint8 *)dst->pixels+dstrect->y*dst->pitch+ + dstrect->x*dst->format->BytesPerPixel; + if ( dst->format->palette || (color == 0) ) { + x = dstrect->w*dst->format->BytesPerPixel; + if ( !color && !((long)row&3) && !(x&3) && !(dst->pitch&3) ) { + int n = x >> 2; + for ( y=dstrect->h; y; --y ) { + SDL_memset4(row, 0, n); + row += dst->pitch; + } + } else { +#ifdef __powerpc__ + /* + * memset() on PPC (both glibc and codewarrior) uses + * the dcbz (Data Cache Block Zero) instruction, which + * causes an alignment exception if the destination is + * uncachable, so only use it on software surfaces + */ + if((dst->flags & SDL_HWSURFACE) == SDL_HWSURFACE) { + if(dstrect->w >= 8) { + /* + * 64-bit stores are probably most + * efficient to uncached video memory + */ + double fill; + memset(&fill, color, (sizeof fill)); + for(y = dstrect->h; y; y--) { + Uint8 *d = row; + unsigned n = x; + unsigned nn; + Uint8 c = color; + double f = fill; + while((unsigned long)d + & (sizeof(double) - 1)) { + *d++ = c; + n--; + } + nn = n / (sizeof(double) * 4); + while(nn) { + ((double *)d)[0] = f; + ((double *)d)[1] = f; + ((double *)d)[2] = f; + ((double *)d)[3] = f; + d += 4*sizeof(double); + nn--; + } + n &= ~(sizeof(double) * 4 - 1); + nn = n / sizeof(double); + while(nn) { + *(double *)d = f; + d += sizeof(double); + nn--; + } + n &= ~(sizeof(double) - 1); + while(n) { + *d++ = c; + n--; + } + row += dst->pitch; + } + } else { + /* narrow boxes */ + for(y = dstrect->h; y; y--) { + Uint8 *d = row; + Uint8 c = color; + int n = x; + while(n) { + *d++ = c; + n--; + } + row += dst->pitch; + } + } + } else +#endif /* __powerpc__ */ + { + for(y = dstrect->h; y; y--) { + memset(row, color, x); + row += dst->pitch; + } + } + } + } else { + switch (dst->format->BytesPerPixel) { + case 2: + for ( y=dstrect->h; y; --y ) { + Uint16 *pixels = (Uint16 *)row; + Uint16 c = color; + Uint32 cc = (Uint32)c << 16 | c; + int n = dstrect->w; + if((unsigned long)pixels & 3) { + *pixels++ = c; + n--; + } + if(n >> 1) + SDL_memset4(pixels, cc, n >> 1); + if(n & 1) + pixels[n - 1] = c; + row += dst->pitch; + } + break; + + case 3: + if(SDL_BYTEORDER == SDL_BIG_ENDIAN) + color <<= 8; + for ( y=dstrect->h; y; --y ) { + Uint8 *pixels = row; + for ( x=dstrect->w; x; --x ) { + memcpy(pixels, &color, 3); + pixels += 3; + } + row += dst->pitch; + } + break; + + case 4: + for(y = dstrect->h; y; --y) { + SDL_memset4(row, color, dstrect->w); + row += dst->pitch; + } + break; + } + } + SDL_UnlockSurface(dst); + + /* We're done! */ + return(0); +} + +/* + * Lock a surface to directly access the pixels + * -- Do not call this from any blit function, as SDL_DrawCursor() may recurse + * Instead, use: + * if ( (surface->flags & SDL_HWSURFACE) == SDL_HWSURFACE ) + * video->LockHWSurface(video, surface); + */ +int SDL_LockSurface (SDL_Surface *surface) +{ + if ( ! surface->locked ) { + /* Perform the lock */ + if ( surface->flags & (SDL_HWSURFACE|SDL_ASYNCBLIT) ) { + SDL_VideoDevice *video = current_video; + SDL_VideoDevice *this = current_video; + if ( video->LockHWSurface(this, surface) < 0 ) { + return(-1); + } + } + if ( surface->flags & SDL_RLEACCEL ) { + SDL_UnRLESurface(surface, 1); + surface->flags |= SDL_RLEACCEL; /* save accel'd state */ + } + /* This needs to be done here in case pixels changes value */ + surface->pixels = (Uint8 *)surface->pixels + surface->offset; + } + + /* Increment the surface lock count, for recursive locks */ + ++surface->locked; + + /* Ready to go.. */ + return(0); +} +/* + * Unlock a previously locked surface + * -- Do not call this from any blit function, as SDL_DrawCursor() may recurse + * Instead, use: + * if ( (surface->flags & SDL_HWSURFACE) == SDL_HWSURFACE ) + * video->UnlockHWSurface(video, surface); + */ +void SDL_UnlockSurface (SDL_Surface *surface) +{ + /* Only perform an unlock if we are locked */ + if ( ! surface->locked || (--surface->locked > 0) ) { + return; + } + + /* Perform the unlock */ + surface->pixels = (Uint8 *)surface->pixels - surface->offset; + + /* Unlock hardware or accelerated surfaces */ + if ( surface->flags & (SDL_HWSURFACE|SDL_ASYNCBLIT) ) { + SDL_VideoDevice *video = current_video; + SDL_VideoDevice *this = current_video; + video->UnlockHWSurface(this, surface); + } else { + /* Update RLE encoded surface with new data */ + if ( (surface->flags & SDL_RLEACCEL) == SDL_RLEACCEL ) { + surface->flags &= ~SDL_RLEACCEL; /* stop lying */ + SDL_RLESurface(surface); + } + } +} + +/* + * Convert a surface into the specified pixel format. + */ +SDL_Surface * SDL_ConvertSurface (SDL_Surface *surface, + SDL_PixelFormat *format, Uint32 flags) +{ + SDL_Surface *convert; + Uint32 colorkey = 0; + Uint8 alpha = 0; + Uint32 surface_flags; + SDL_Rect bounds; + + /* Check for empty destination palette! (results in empty image) */ + if ( format->palette != NULL ) { + int i; + for ( i=0; ipalette->ncolors; ++i ) { + if ( (format->palette->colors[i].r != 0) || + (format->palette->colors[i].g != 0) || + (format->palette->colors[i].b != 0) ) + break; + } + if ( i == format->palette->ncolors ) { + SDL_SetError("Empty destination palette"); + return(NULL); + } + } + + /* Create a new surface with the desired format */ + convert = SDL_CreateRGBSurface(flags, + surface->w, surface->h, format->BitsPerPixel, + format->Rmask, format->Gmask, format->Bmask, format->Amask); + if ( convert == NULL ) { + return(NULL); + } + + /* Copy the palette if any */ + if ( format->palette && convert->format->palette ) { + memcpy(convert->format->palette->colors, + format->palette->colors, + format->palette->ncolors*sizeof(SDL_Color)); + convert->format->palette->ncolors = format->palette->ncolors; + } + + /* Save the original surface color key and alpha */ + surface_flags = surface->flags; + if ( (surface_flags & SDL_SRCCOLORKEY) == SDL_SRCCOLORKEY ) { + /* Convert colourkeyed surfaces to RGBA if requested */ + if((flags & SDL_SRCCOLORKEY) != SDL_SRCCOLORKEY + && format->Amask) { + surface_flags &= ~SDL_SRCCOLORKEY; + } else { + colorkey = surface->format->colorkey; + SDL_SetColorKey(surface, 0, 0); + } + } + if ( (surface_flags & SDL_SRCALPHA) == SDL_SRCALPHA ) { + alpha = surface->format->alpha; + SDL_SetAlpha(surface, 0, 0); + } + + /* Copy over the image data */ + bounds.x = 0; + bounds.y = 0; + bounds.w = surface->w; + bounds.h = surface->h; + SDL_LowerBlit(surface, &bounds, convert, &bounds); + + /* Clean up the original surface, and update converted surface */ + if ( convert != NULL ) { + SDL_SetClipRect(convert, &surface->clip_rect); + } + if ( (surface_flags & SDL_SRCCOLORKEY) == SDL_SRCCOLORKEY ) { + Uint32 cflags = surface_flags&(SDL_SRCCOLORKEY|SDL_RLEACCELOK); + if ( convert != NULL ) { + Uint8 keyR, keyG, keyB; + + SDL_GetRGB(colorkey,surface->format,&keyR,&keyG,&keyB); + SDL_SetColorKey(convert, cflags|(flags&SDL_RLEACCELOK), + SDL_MapRGB(convert->format, keyR, keyG, keyB)); + } + SDL_SetColorKey(surface, cflags, colorkey); + } + if ( (surface_flags & SDL_SRCALPHA) == SDL_SRCALPHA ) { + Uint32 aflags = surface_flags&(SDL_SRCALPHA|SDL_RLEACCELOK); + if ( convert != NULL ) { + SDL_SetAlpha(convert, aflags|(flags&SDL_RLEACCELOK), + alpha); + } + SDL_SetAlpha(surface, aflags, alpha); + } + + /* We're ready to go! */ + return(convert); +} + +/* + * Free a surface created by the above function. + */ +void SDL_FreeSurface (SDL_Surface *surface) +{ + /* Free anything that's not NULL, and not the screen surface */ + if ((surface == NULL) || + (current_video && + ((surface == SDL_ShadowSurface)||(surface == SDL_VideoSurface)))) { + return; + } + if ( --surface->refcount > 0 ) { + return; + } + if ( (surface->flags & SDL_RLEACCEL) == SDL_RLEACCEL ) { + SDL_UnRLESurface(surface, 0); + } + if ( surface->format ) { + SDL_FreeFormat(surface->format); + surface->format = NULL; + } + if ( surface->map != NULL ) { + SDL_FreeBlitMap(surface->map); + surface->map = NULL; + } + if ( (surface->flags & SDL_HWSURFACE) == SDL_HWSURFACE ) { + SDL_VideoDevice *video = current_video; + SDL_VideoDevice *this = current_video; + video->FreeHWSurface(this, surface); + } + if ( surface->pixels && + ((surface->flags & SDL_PREALLOC) != SDL_PREALLOC) ) { + free(surface->pixels); + } + free(surface); +#ifdef CHECK_LEAKS + --surfaces_allocated; +#endif +} diff --git a/contrib/sdk/sources/SDL-1.2.2/src/video/SDL_sysvideo.h b/contrib/sdk/sources/SDL-1.2.2/src/video/SDL_sysvideo.h new file mode 100644 index 000000000..3490eea4b --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/src/video/SDL_sysvideo.h @@ -0,0 +1,399 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997, 1998, 1999, 2000, 2001 Sam Lantinga + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the Free + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + Sam Lantinga + slouken@devolution.com +*/ + +#ifdef SAVE_RCSID +static char rcsid = + "@(#) $Id: SDL_sysvideo.h,v 1.6 2001/06/19 13:33:53 hercules Exp $"; +#endif + +#ifndef _SDL_sysvideo_h +#define _SDL_sysvideo_h + +#include "SDL_mouse.h" +#define SDL_PROTOTYPES_ONLY +#include "SDL_syswm.h" +#undef SDL_PROTOTYPES_ONLY + +/* This file prototypes the video driver implementation. + This is designed to be easily converted to C++ in the future. + */ + +/* OpenGL is pretty much available on all Windows systems */ +#ifdef WIN32UNDEFINED +#ifndef _WIN32_WCE +#define HAVE_OPENGL +#endif +#include +#endif + +#ifdef HAVE_OPENGL +#ifdef MACOSX +#include /* OpenGL.framework */ +#else +#include +#endif /* MACOSX */ +#endif /* HAVE_OPENGL */ + +/* The SDL video driver */ +typedef struct SDL_VideoDevice SDL_VideoDevice; + +/* Define the SDL video driver structure */ +#define _THIS SDL_VideoDevice *_this +#ifndef _STATUS +#define _STATUS SDL_status *status +#endif +struct SDL_VideoDevice { + /* * * */ + /* The name of this video driver */ + const char *name; + + /* * * */ + /* Initialization/Query functions */ + + /* Initialize the native video subsystem, filling 'vformat' with the + "best" display pixel format, returning 0 or -1 if there's an error. + */ + int (*VideoInit)(_THIS, SDL_PixelFormat *vformat); + + /* List the available video modes for the given pixel format, sorted + from largest to smallest. + */ + SDL_Rect **(*ListModes)(_THIS, SDL_PixelFormat *format, Uint32 flags); + + /* Set the requested video mode, returning a surface which will be + set to the SDL_VideoSurface. The width and height will already + be verified by ListModes(), and the video subsystem is free to + set the mode to a supported bit depth different from the one + specified -- the desired bpp will be emulated with a shadow + surface if necessary. If a new mode is returned, this function + should take care of cleaning up the current mode. + */ + SDL_Surface *(*SetVideoMode)(_THIS, SDL_Surface *current, + int width, int height, int bpp, Uint32 flags); + + /* Toggle the fullscreen mode */ + int (*ToggleFullScreen)(_THIS, int on); + + /* This is called after the video mode has been set, to get the + initial mouse state. It should queue events as necessary to + properly represent the current mouse focus and position. + */ + void (*UpdateMouse)(_THIS); + + /* Create a YUV video surface (possibly overlay) of the given + format. The hardware should be able to perform at least 2x + scaling on display. + */ + SDL_Overlay *(*CreateYUVOverlay)(_THIS, int width, int height, + Uint32 format, SDL_Surface *display); + + /* Sets the color entries { firstcolor .. (firstcolor+ncolors-1) } + of the physical palette to those in 'colors'. If the device is + using a software palette (SDL_HWPALETTE not set), then the + changes are reflected in the logical palette of the screen + as well. + The return value is 1 if all entries could be set properly + or 0 otherwise. + */ + int (*SetColors)(_THIS, int firstcolor, int ncolors, + SDL_Color *colors); + + /* This pointer should exist in the native video subsystem and should + point to an appropriate update function for the current video mode + */ + void (*UpdateRects)(_THIS, int numrects, SDL_Rect *rects); + + /* Reverse the effects VideoInit() -- called if VideoInit() fails + or if the application is shutting down the video subsystem. + */ + void (*VideoQuit)(_THIS); + + /* * * */ + /* Hardware acceleration functions */ + + /* Information about the video hardware */ + SDL_VideoInfo info; + + /* Allocates a surface in video memory */ + int (*AllocHWSurface)(_THIS, SDL_Surface *surface); + + /* Sets the hardware accelerated blit function, if any, based + on the current flags of the surface (colorkey, alpha, etc.) + */ + int (*CheckHWBlit)(_THIS, SDL_Surface *src, SDL_Surface *dst); + + /* Fills a surface rectangle with the given color */ + int (*FillHWRect)(_THIS, SDL_Surface *dst, SDL_Rect *rect, Uint32 color); + + /* Sets video mem colorkey and accelerated blit function */ + int (*SetHWColorKey)(_THIS, SDL_Surface *surface, Uint32 key); + + /* Sets per surface hardware alpha value */ + int (*SetHWAlpha)(_THIS, SDL_Surface *surface, Uint8 value); + + /* Returns a readable/writable surface */ + int (*LockHWSurface)(_THIS, SDL_Surface *surface); + void (*UnlockHWSurface)(_THIS, SDL_Surface *surface); + + /* Performs hardware flipping */ + int (*FlipHWSurface)(_THIS, SDL_Surface *surface); + + /* Frees a previously allocated video surface */ + void (*FreeHWSurface)(_THIS, SDL_Surface *surface); + + /* * * */ + /* Gamma support */ + + Uint16 *gamma; + + /* Set the gamma correction directly (emulated with gamma ramps) */ + int (*SetGamma)(_THIS, float red, float green, float blue); + + /* Get the gamma correction directly (emulated with gamma ramps) */ + int (*GetGamma)(_THIS, float *red, float *green, float *blue); + + /* Set the gamma ramp */ + int (*SetGammaRamp)(_THIS, Uint16 *ramp); + + /* Get the gamma ramp */ + int (*GetGammaRamp)(_THIS, Uint16 *ramp); + + /* * * */ + /* OpenGL support */ + + /* Sets the dll to use for OpenGL and loads it */ + int (*GL_LoadLibrary)(_THIS, const char *path); + + /* Retrieves the address of a function in the gl library */ + void* (*GL_GetProcAddress)(_THIS, const char *proc); + + /* Get attribute information from the windowing system. */ + int (*GL_GetAttribute)(_THIS, SDL_GLattr attrib, int* value); + + /* Make the context associated with this driver current */ + int (*GL_MakeCurrent)(_THIS); + + /* Swap the current buffers in double buffer mode. */ + void (*GL_SwapBuffers)(_THIS); + + /* OpenGL functions for SDL_OPENGLBLIT */ +#ifdef HAVE_OPENGL +#ifndef WIN32UNDEFINED +#define WINAPI +#endif +#define SDL_PROC(ret,func,params) ret (WINAPI *func) params; +#include "SDL_glfuncs.h" +#undef SDL_PROC + + /* Texture id */ + GLuint texture; +#endif + int is_32bit; + + /* * * */ + /* Window manager functions */ + + /* Set the title and icon text */ + void (*SetCaption)(_THIS, const char *title, const char *icon); + + /* Set the window icon image */ + void (*SetIcon)(_THIS, SDL_Surface *icon, Uint8 *mask); + + /* Iconify the window. + This function returns 1 if there is a window manager and the + window was actually iconified, it returns 0 otherwise. + */ + int (*IconifyWindow)(_THIS); + + /* Grab or ungrab keyboard and mouse input */ + SDL_GrabMode (*GrabInput)(_THIS, SDL_GrabMode mode); + + /* Get some platform dependent window information */ + int (*GetWMInfo)(_THIS, SDL_SysWMinfo *info); + + /* * * */ + /* Cursor manager functions */ + + /* Free a window manager cursor + This function can be NULL if CreateWMCursor is also NULL. + */ + void (*FreeWMCursor)(_THIS, WMcursor *cursor); + + /* If not NULL, create a black/white window manager cursor */ + WMcursor *(*CreateWMCursor)(_THIS, + Uint8 *data, Uint8 *mask, int w, int h, int hot_x, int hot_y); + + /* Show the specified cursor, or hide if cursor is NULL */ + int (*ShowWMCursor)(_THIS, WMcursor *cursor); + + /* Warp the window manager cursor to (x,y) + If NULL, a mouse motion event is posted internally. + */ + void (*WarpWMCursor)(_THIS, Uint16 x, Uint16 y); + + /* If not NULL, this is called when a mouse motion event occurs */ + void (*MoveWMCursor)(_THIS, int x, int y); + + /* Determine whether the mouse should be in relative mode or not. + This function is called when the input grab state or cursor + visibility state changes. + If the cursor is not visible, and the input is grabbed, the + driver can place the mouse in relative mode, which may result + in higher accuracy sampling of the pointer motion. + */ + void (*CheckMouseMode)(_THIS); + + /* * * */ + /* Event manager functions */ + + /* Initialize keyboard mapping for this driver */ + void (*InitOSKeymap)(_THIS); + + /* Handle any queued OS events */ + void (*PumpEvents)(_THIS); + + /* * * */ + /* Data common to all drivers */ + SDL_Surface *screen; + SDL_Surface *shadow; + SDL_Surface *visible; + SDL_Palette *physpal; /* physical palette, if != logical palette */ + SDL_Color *gammacols; /* gamma-corrected colours, or NULL */ + char *wm_title; + char *wm_icon; + int offset_x; + int offset_y; + SDL_GrabMode input_grab; + + /* Driver information flags */ + int handles_any_size; /* Driver handles any size video mode */ + + /* * * */ + /* Data used by the GL drivers */ + struct { + int red_size; + int green_size; + int blue_size; + int alpha_size; + int depth_size; + int buffer_size; + int stencil_size; + int double_buffer; + int accum_red_size; + int accum_green_size; + int accum_blue_size; + int accum_alpha_size; + int driver_loaded; + char driver_path[256]; + void* dll_handle; + } gl_config; + + /* * * */ + /* Data private to this driver */ + struct SDL_PrivateVideoData *hidden; + struct SDL_PrivateGLData *gl_data; + + /* * * */ + /* The function used to dispose of this structure */ + void (*free)(_THIS); +}; +#undef _THIS + +typedef struct VideoBootStrap { + const char *name; + const char *desc; + int (*available)(void); + SDL_VideoDevice *(*create)(int devindex); +} VideoBootStrap; + +#ifdef ENABLE_X11 +extern VideoBootStrap X11_bootstrap; +#endif +#ifdef ENABLE_DGA +extern VideoBootStrap DGA_bootstrap; +#endif +#ifdef ENABLE_NANOX +extern VideoBootStrap NX_bootstrap; +#endif +#ifdef ENABLE_FBCON +extern VideoBootStrap FBCON_bootstrap; +#endif +#ifdef ENABLE_PS2GS +extern VideoBootStrap PS2GS_bootstrap; +#endif +#ifdef ENABLE_GGI +extern VideoBootStrap GGI_bootstrap; +#endif +#ifdef ENABLE_VGL +extern VideoBootStrap VGL_bootstrap; +#endif +#ifdef ENABLE_SVGALIB +extern VideoBootStrap SVGALIB_bootstrap; +#endif +#ifdef ENABLE_AALIB +extern VideoBootStrap AALIB_bootstrap; +#endif +#ifdef ENABLE_WINDIB +extern VideoBootStrap WINDIB_bootstrap; +#endif +#ifdef ENABLE_DIRECTX +extern VideoBootStrap DIRECTX_bootstrap; +#endif +#ifdef ENABLE_BWINDOW +extern VideoBootStrap BWINDOW_bootstrap; +#endif +#ifdef ENABLE_DUMMYVIDEO +extern VideoBootStrap DUMMY_bootstrap; +#endif +#ifdef ENABLE_PHOTON +extern VideoBootStrap ph_bootstrap; +#endif +/* MacOS X gets the proper defines from configure */ +#if defined(macintosh) && !defined(MACOSX) +#define ENABLE_TOOLBOX +#if !TARGET_API_MAC_CARBON +#define ENABLE_DRAWSPROCKET +#endif +#endif +#ifdef ENABLE_TOOLBOX +extern VideoBootStrap TOOLBOX_bootstrap; +#endif +#ifdef ENABLE_DRAWSPROCKET +extern VideoBootStrap DSp_bootstrap; +#endif +#ifdef ENABLE_QUARTZ +extern VideoBootStrap QZ_bootstrap; +#endif +#ifdef ENABLE_CYBERGRAPHICS +extern VideoBootStrap CGX_bootstrap; +#endif +#ifdef ENABLE_MENUETOS +extern VideoBootStrap mosvideo_bootstrab; +#endif +/* This is the current video device */ +extern SDL_VideoDevice *current_video; + +#define SDL_VideoSurface (current_video->screen) +#define SDL_ShadowSurface (current_video->shadow) +#define SDL_PublicSurface (current_video->visible) + +#endif /* _SDL_sysvideo_h */ diff --git a/contrib/sdk/sources/SDL-1.2.2/src/video/SDL_sysvideo.h.BAK b/contrib/sdk/sources/SDL-1.2.2/src/video/SDL_sysvideo.h.BAK new file mode 100644 index 000000000..566199c7b --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/src/video/SDL_sysvideo.h.BAK @@ -0,0 +1,399 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997, 1998, 1999, 2000, 2001 Sam Lantinga + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the Free + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + Sam Lantinga + slouken@devolution.com +*/ + +#ifdef SAVE_RCSID +static char rcsid = + "@(#) $Id: SDL_sysvideo.h,v 1.6 2001/06/19 13:33:53 hercules Exp $"; +#endif + +#ifndef _SDL_sysvideo_h +#define _SDL_sysvideo_h + +#include "SDL_mouse.h" +#define SDL_PROTOTYPES_ONLY +#include "SDL_syswm.h" +#undef SDL_PROTOTYPES_ONLY + +/* This file prototypes the video driver implementation. + This is designed to be easily converted to C++ in the future. + */ + +/* OpenGL is pretty much available on all Windows systems */ +#ifdef WIN32 +#ifndef _WIN32_WCE +#define HAVE_OPENGL +#endif +#include +#endif + +#ifdef HAVE_OPENGL +#ifdef MACOSX +#include /* OpenGL.framework */ +#else +#include +#endif /* MACOSX */ +#endif /* HAVE_OPENGL */ + +/* The SDL video driver */ +typedef struct SDL_VideoDevice SDL_VideoDevice; + +/* Define the SDL video driver structure */ +#define _THIS SDL_VideoDevice *_this +#ifndef _STATUS +#define _STATUS SDL_status *status +#endif +struct SDL_VideoDevice { + /* * * */ + /* The name of this video driver */ + const char *name; + + /* * * */ + /* Initialization/Query functions */ + + /* Initialize the native video subsystem, filling 'vformat' with the + "best" display pixel format, returning 0 or -1 if there's an error. + */ + int (*VideoInit)(_THIS, SDL_PixelFormat *vformat); + + /* List the available video modes for the given pixel format, sorted + from largest to smallest. + */ + SDL_Rect **(*ListModes)(_THIS, SDL_PixelFormat *format, Uint32 flags); + + /* Set the requested video mode, returning a surface which will be + set to the SDL_VideoSurface. The width and height will already + be verified by ListModes(), and the video subsystem is free to + set the mode to a supported bit depth different from the one + specified -- the desired bpp will be emulated with a shadow + surface if necessary. If a new mode is returned, this function + should take care of cleaning up the current mode. + */ + SDL_Surface *(*SetVideoMode)(_THIS, SDL_Surface *current, + int width, int height, int bpp, Uint32 flags); + + /* Toggle the fullscreen mode */ + int (*ToggleFullScreen)(_THIS, int on); + + /* This is called after the video mode has been set, to get the + initial mouse state. It should queue events as necessary to + properly represent the current mouse focus and position. + */ + void (*UpdateMouse)(_THIS); + + /* Create a YUV video surface (possibly overlay) of the given + format. The hardware should be able to perform at least 2x + scaling on display. + */ + SDL_Overlay *(*CreateYUVOverlay)(_THIS, int width, int height, + Uint32 format, SDL_Surface *display); + + /* Sets the color entries { firstcolor .. (firstcolor+ncolors-1) } + of the physical palette to those in 'colors'. If the device is + using a software palette (SDL_HWPALETTE not set), then the + changes are reflected in the logical palette of the screen + as well. + The return value is 1 if all entries could be set properly + or 0 otherwise. + */ + int (*SetColors)(_THIS, int firstcolor, int ncolors, + SDL_Color *colors); + + /* This pointer should exist in the native video subsystem and should + point to an appropriate update function for the current video mode + */ + void (*UpdateRects)(_THIS, int numrects, SDL_Rect *rects); + + /* Reverse the effects VideoInit() -- called if VideoInit() fails + or if the application is shutting down the video subsystem. + */ + void (*VideoQuit)(_THIS); + + /* * * */ + /* Hardware acceleration functions */ + + /* Information about the video hardware */ + SDL_VideoInfo info; + + /* Allocates a surface in video memory */ + int (*AllocHWSurface)(_THIS, SDL_Surface *surface); + + /* Sets the hardware accelerated blit function, if any, based + on the current flags of the surface (colorkey, alpha, etc.) + */ + int (*CheckHWBlit)(_THIS, SDL_Surface *src, SDL_Surface *dst); + + /* Fills a surface rectangle with the given color */ + int (*FillHWRect)(_THIS, SDL_Surface *dst, SDL_Rect *rect, Uint32 color); + + /* Sets video mem colorkey and accelerated blit function */ + int (*SetHWColorKey)(_THIS, SDL_Surface *surface, Uint32 key); + + /* Sets per surface hardware alpha value */ + int (*SetHWAlpha)(_THIS, SDL_Surface *surface, Uint8 value); + + /* Returns a readable/writable surface */ + int (*LockHWSurface)(_THIS, SDL_Surface *surface); + void (*UnlockHWSurface)(_THIS, SDL_Surface *surface); + + /* Performs hardware flipping */ + int (*FlipHWSurface)(_THIS, SDL_Surface *surface); + + /* Frees a previously allocated video surface */ + void (*FreeHWSurface)(_THIS, SDL_Surface *surface); + + /* * * */ + /* Gamma support */ + + Uint16 *gamma; + + /* Set the gamma correction directly (emulated with gamma ramps) */ + int (*SetGamma)(_THIS, float red, float green, float blue); + + /* Get the gamma correction directly (emulated with gamma ramps) */ + int (*GetGamma)(_THIS, float *red, float *green, float *blue); + + /* Set the gamma ramp */ + int (*SetGammaRamp)(_THIS, Uint16 *ramp); + + /* Get the gamma ramp */ + int (*GetGammaRamp)(_THIS, Uint16 *ramp); + + /* * * */ + /* OpenGL support */ + + /* Sets the dll to use for OpenGL and loads it */ + int (*GL_LoadLibrary)(_THIS, const char *path); + + /* Retrieves the address of a function in the gl library */ + void* (*GL_GetProcAddress)(_THIS, const char *proc); + + /* Get attribute information from the windowing system. */ + int (*GL_GetAttribute)(_THIS, SDL_GLattr attrib, int* value); + + /* Make the context associated with this driver current */ + int (*GL_MakeCurrent)(_THIS); + + /* Swap the current buffers in double buffer mode. */ + void (*GL_SwapBuffers)(_THIS); + + /* OpenGL functions for SDL_OPENGLBLIT */ +#ifdef HAVE_OPENGL +#ifndef WIN32 +#define WINAPI +#endif +#define SDL_PROC(ret,func,params) ret (WINAPI *func) params; +#include "SDL_glfuncs.h" +#undef SDL_PROC + + /* Texture id */ + GLuint texture; +#endif + int is_32bit; + + /* * * */ + /* Window manager functions */ + + /* Set the title and icon text */ + void (*SetCaption)(_THIS, const char *title, const char *icon); + + /* Set the window icon image */ + void (*SetIcon)(_THIS, SDL_Surface *icon, Uint8 *mask); + + /* Iconify the window. + This function returns 1 if there is a window manager and the + window was actually iconified, it returns 0 otherwise. + */ + int (*IconifyWindow)(_THIS); + + /* Grab or ungrab keyboard and mouse input */ + SDL_GrabMode (*GrabInput)(_THIS, SDL_GrabMode mode); + + /* Get some platform dependent window information */ + int (*GetWMInfo)(_THIS, SDL_SysWMinfo *info); + + /* * * */ + /* Cursor manager functions */ + + /* Free a window manager cursor + This function can be NULL if CreateWMCursor is also NULL. + */ + void (*FreeWMCursor)(_THIS, WMcursor *cursor); + + /* If not NULL, create a black/white window manager cursor */ + WMcursor *(*CreateWMCursor)(_THIS, + Uint8 *data, Uint8 *mask, int w, int h, int hot_x, int hot_y); + + /* Show the specified cursor, or hide if cursor is NULL */ + int (*ShowWMCursor)(_THIS, WMcursor *cursor); + + /* Warp the window manager cursor to (x,y) + If NULL, a mouse motion event is posted internally. + */ + void (*WarpWMCursor)(_THIS, Uint16 x, Uint16 y); + + /* If not NULL, this is called when a mouse motion event occurs */ + void (*MoveWMCursor)(_THIS, int x, int y); + + /* Determine whether the mouse should be in relative mode or not. + This function is called when the input grab state or cursor + visibility state changes. + If the cursor is not visible, and the input is grabbed, the + driver can place the mouse in relative mode, which may result + in higher accuracy sampling of the pointer motion. + */ + void (*CheckMouseMode)(_THIS); + + /* * * */ + /* Event manager functions */ + + /* Initialize keyboard mapping for this driver */ + void (*InitOSKeymap)(_THIS); + + /* Handle any queued OS events */ + void (*PumpEvents)(_THIS); + + /* * * */ + /* Data common to all drivers */ + SDL_Surface *screen; + SDL_Surface *shadow; + SDL_Surface *visible; + SDL_Palette *physpal; /* physical palette, if != logical palette */ + SDL_Color *gammacols; /* gamma-corrected colours, or NULL */ + char *wm_title; + char *wm_icon; + int offset_x; + int offset_y; + SDL_GrabMode input_grab; + + /* Driver information flags */ + int handles_any_size; /* Driver handles any size video mode */ + + /* * * */ + /* Data used by the GL drivers */ + struct { + int red_size; + int green_size; + int blue_size; + int alpha_size; + int depth_size; + int buffer_size; + int stencil_size; + int double_buffer; + int accum_red_size; + int accum_green_size; + int accum_blue_size; + int accum_alpha_size; + int driver_loaded; + char driver_path[256]; + void* dll_handle; + } gl_config; + + /* * * */ + /* Data private to this driver */ + struct SDL_PrivateVideoData *hidden; + struct SDL_PrivateGLData *gl_data; + + /* * * */ + /* The function used to dispose of this structure */ + void (*free)(_THIS); +}; +#undef _THIS + +typedef struct VideoBootStrap { + const char *name; + const char *desc; + int (*available)(void); + SDL_VideoDevice *(*create)(int devindex); +} VideoBootStrap; + +#ifdef ENABLE_X11 +extern VideoBootStrap X11_bootstrap; +#endif +#ifdef ENABLE_DGA +extern VideoBootStrap DGA_bootstrap; +#endif +#ifdef ENABLE_NANOX +extern VideoBootStrap NX_bootstrap; +#endif +#ifdef ENABLE_FBCON +extern VideoBootStrap FBCON_bootstrap; +#endif +#ifdef ENABLE_PS2GS +extern VideoBootStrap PS2GS_bootstrap; +#endif +#ifdef ENABLE_GGI +extern VideoBootStrap GGI_bootstrap; +#endif +#ifdef ENABLE_VGL +extern VideoBootStrap VGL_bootstrap; +#endif +#ifdef ENABLE_SVGALIB +extern VideoBootStrap SVGALIB_bootstrap; +#endif +#ifdef ENABLE_AALIB +extern VideoBootStrap AALIB_bootstrap; +#endif +#ifdef ENABLE_WINDIB +extern VideoBootStrap WINDIB_bootstrap; +#endif +#ifdef ENABLE_DIRECTX +extern VideoBootStrap DIRECTX_bootstrap; +#endif +#ifdef ENABLE_BWINDOW +extern VideoBootStrap BWINDOW_bootstrap; +#endif +#ifdef ENABLE_DUMMYVIDEO +extern VideoBootStrap DUMMY_bootstrap; +#endif +#ifdef ENABLE_PHOTON +extern VideoBootStrap ph_bootstrap; +#endif +/* MacOS X gets the proper defines from configure */ +#if defined(macintosh) && !defined(MACOSX) +#define ENABLE_TOOLBOX +#if !TARGET_API_MAC_CARBON +#define ENABLE_DRAWSPROCKET +#endif +#endif +#ifdef ENABLE_TOOLBOX +extern VideoBootStrap TOOLBOX_bootstrap; +#endif +#ifdef ENABLE_DRAWSPROCKET +extern VideoBootStrap DSp_bootstrap; +#endif +#ifdef ENABLE_QUARTZ +extern VideoBootStrap QZ_bootstrap; +#endif +#ifdef ENABLE_CYBERGRAPHICS +extern VideoBootStrap CGX_bootstrap; +#endif +#ifdef ENABLE_MENUETOS +extern VideoBootStrap mosvideo_bootstrab; +#endif +/* This is the current video device */ +extern SDL_VideoDevice *current_video; + +#define SDL_VideoSurface (current_video->screen) +#define SDL_ShadowSurface (current_video->shadow) +#define SDL_PublicSurface (current_video->visible) + +#endif /* _SDL_sysvideo_h */ diff --git a/contrib/sdk/sources/SDL-1.2.2/src/video/SDL_video.c b/contrib/sdk/sources/SDL-1.2.2/src/video/SDL_video.c new file mode 100644 index 000000000..28950262a --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/src/video/SDL_video.c @@ -0,0 +1,1802 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997, 1998, 1999, 2000, 2001 Sam Lantinga + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the Free + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + Sam Lantinga + slouken@devolution.com +*/ + + +/* The high-level video driver subsystem */ + +#include +#include +#include + +#include "SDL.h" +#include "SDL_error.h" +#include "SDL_video.h" +#include "SDL_events.h" +#include "SDL_mutex.h" +#include "SDL_sysvideo.h" +#include "SDL_sysevents.h" +#include "SDL_blit.h" +#include "SDL_pixels_c.h" +#include "SDL_events_c.h" +#include "SDL_cursor_c.h" + +/* Available video drivers */ +static VideoBootStrap *bootstrap[] = { +#ifdef ENABLE_X11 + &X11_bootstrap, +#endif +#ifdef ENABLE_DGA + &DGA_bootstrap, +#endif +#ifdef ENABLE_NANOX + &NX_bootstrap, +#endif +#ifdef ENABLE_FBCON + &FBCON_bootstrap, +#endif +#ifdef ENABLE_PS2GS + &PS2GS_bootstrap, +#endif +#ifdef ENABLE_GGI + &GGI_bootstrap, +#endif +#ifdef ENABLE_VGL + &VGL_bootstrap, +#endif +#ifdef ENABLE_SVGALIB + &SVGALIB_bootstrap, +#endif +#ifdef ENABLE_AALIB + &AALIB_bootstrap, +#endif +#ifdef ENABLE_DIRECTX + &DIRECTX_bootstrap, +#endif +#ifdef ENABLE_WINDIB + &WINDIB_bootstrap, +#endif +#ifdef ENABLE_BWINDOW + &BWINDOW_bootstrap, +#endif +#ifdef ENABLE_TOOLBOX + &TOOLBOX_bootstrap, +#endif +#ifdef ENABLE_DRAWSPROCKET + &DSp_bootstrap, +#endif +#ifdef ENABLE_QUARTZ + &QZ_bootstrap, +#endif +#ifdef ENABLE_CYBERGRAPHICS + &CGX_bootstrap, +#endif +#ifdef ENABLE_DUMMYVIDEO + &DUMMY_bootstrap, +#endif +#ifdef ENABLE_PHOTON + &ph_bootstrap, +#endif +#ifdef ENABLE_MENUETOS + &mosvideo_bootstrab, +#endif + NULL +}; + +SDL_VideoDevice *current_video = NULL; + +/* Various local functions */ +int SDL_VideoInit(const char *driver_name, Uint32 flags); +void SDL_VideoQuit(void); +void SDL_GL_UpdateRectsLock(SDL_VideoDevice* this, int numrects, SDL_Rect* rects); + +static SDL_GrabMode SDL_WM_GrabInputOff(void); +#ifdef HAVE_OPENGL +static int lock_count = 0; +#endif + + +/* + * Initialize the video and event subsystems -- determine native pixel format + */ +int SDL_VideoInit (const char *driver_name, Uint32 flags) +{ + SDL_VideoDevice *video; + int index; + int i; + SDL_PixelFormat vformat; + Uint32 video_flags; + + /* Toggle the event thread flags, based on OS requirements */ +#if defined(MUST_THREAD_EVENTS) + flags |= SDL_INIT_EVENTTHREAD; +#elif defined(CANT_THREAD_EVENTS) + if ( (flags & SDL_INIT_EVENTTHREAD) == SDL_INIT_EVENTTHREAD ) { + SDL_SetError("OS doesn't support threaded events"); + return(-1); + } +#endif + + /* Check to make sure we don't overwrite 'current_video' */ + if ( current_video != NULL ) { + SDL_VideoQuit(); + } + + /* Select the proper video driver */ + index = 0; + video = NULL; + if ( driver_name != NULL ) { + for ( i=0; bootstrap[i]; ++i ) { + if ( strncmp(bootstrap[i]->name, driver_name, + strlen(bootstrap[i]->name)) == 0 ) { + if ( bootstrap[i]->available() ) { + video = bootstrap[i]->create(index); + break; + } + } + } + } else { + for ( i=0; bootstrap[i]; ++i ) { + if ( bootstrap[i]->available() ) { + video = bootstrap[i]->create(index); + if ( video != NULL ) { + break; + } + } + } + } + if ( video == NULL ) { + SDL_SetError("No available video device"); + return(-1); + } + current_video = video; + current_video->name = bootstrap[i]->name; + + /* Do some basic variable initialization */ + video->screen = NULL; + video->shadow = NULL; + video->visible = NULL; + video->physpal = NULL; + video->gammacols = NULL; + video->gamma = NULL; + video->wm_title = NULL; + video->wm_icon = NULL; + video->offset_x = 0; + video->offset_y = 0; + memset(&video->info, 0, (sizeof video->info)); + + /* Set some very sane GL defaults */ + video->gl_config.driver_loaded = 0; + video->gl_config.dll_handle = NULL; + video->gl_config.red_size = 5; +#if 1 /* This seems to work on more video cards, as a default */ + video->gl_config.green_size = 5; +#else + video->gl_config.green_size = 6; +#endif + video->gl_config.blue_size = 5; + video->gl_config.alpha_size = 0; + video->gl_config.buffer_size = 0; + video->gl_config.depth_size = 16; + video->gl_config.stencil_size = 0; + video->gl_config.double_buffer = 1; + video->gl_config.accum_red_size = 0; + video->gl_config.accum_green_size = 0; + video->gl_config.accum_blue_size = 0; + video->gl_config.accum_alpha_size = 0; + + /* Initialize the video subsystem */ + memset(&vformat, 0, sizeof(vformat)); + if ( video->VideoInit(video, &vformat) < 0 ) { + SDL_VideoQuit(); + return(-1); + } + + /* Create a zero sized video surface of the appropriate format */ + video_flags = SDL_SWSURFACE; + SDL_VideoSurface = SDL_CreateRGBSurface(video_flags, 0, 0, + vformat.BitsPerPixel, + vformat.Rmask, vformat.Gmask, vformat.Bmask, 0); + if ( SDL_VideoSurface == NULL ) { + SDL_VideoQuit(); + return(-1); + } + SDL_PublicSurface = NULL; /* Until SDL_SetVideoMode() */ + +#if 0 /* Don't change the current palette - may be used by other programs. + * The application can't do anything with the display surface until + * a video mode has been set anyway. :) + */ + /* If we have a palettized surface, create a default palette */ + if ( SDL_VideoSurface->format->palette ) { + SDL_PixelFormat *vf = SDL_VideoSurface->format; + SDL_DitherColors(vf->palette->colors, vf->BitsPerPixel); + video->SetColors(video, + 0, vf->palette->ncolors, vf->palette->colors); + } +#endif + video->info.vfmt = SDL_VideoSurface->format; + + /* Start the event loop */ + if ( SDL_StartEventLoop(flags) < 0 ) { + SDL_VideoQuit(); + return(-1); + } + SDL_CursorInit(flags & SDL_INIT_EVENTTHREAD); + + /* We're ready to go! */ + return(0); +} + +char *SDL_VideoDriverName(char *namebuf, int maxlen) +{ + if ( current_video != NULL ) { + strncpy(namebuf, current_video->name, maxlen-1); + namebuf[maxlen-1] = '\0'; + return(namebuf); + } + return(NULL); +} + +/* + * Get the current display surface + */ +SDL_Surface *SDL_GetVideoSurface(void) +{ + SDL_Surface *visible; + + visible = NULL; + if ( current_video ) { + visible = current_video->visible; + } + return(visible); +} + +/* + * Get the current information about the video hardware + */ +const SDL_VideoInfo *SDL_GetVideoInfo(void) +{ + const SDL_VideoInfo *info; + + info = NULL; + if ( current_video ) { + info = ¤t_video->info; + } + return(info); +} + +/* + * Return a pointer to an array of available screen dimensions for the + * given format, sorted largest to smallest. Returns NULL if there are + * no dimensions available for a particular format, or (SDL_Rect **)-1 + * if any dimension is okay for the given format. If 'format' is NULL, + * the mode list will be for the format given by SDL_GetVideoInfo()->vfmt + */ +SDL_Rect ** SDL_ListModes (SDL_PixelFormat *format, Uint32 flags) +{ + SDL_VideoDevice *video = current_video; + SDL_VideoDevice *this = current_video; + SDL_Rect **modes; + + modes = NULL; + if ( SDL_VideoSurface ) { + if ( format == NULL ) { + format = SDL_VideoSurface->format; + } + modes = video->ListModes(this, format, flags); + } + return(modes); +} + +/* + * Check to see if a particular video mode is supported. + * It returns 0 if the requested mode is not supported under any bit depth, + * or returns the bits-per-pixel of the closest available mode with the + * given width and height. If this bits-per-pixel is different from the + * one used when setting the video mode, SDL_SetVideoMode() will succeed, + * but will emulate the requested bits-per-pixel with a shadow surface. + */ +static Uint8 SDL_closest_depths[4][8] = { + /* 8 bit closest depth ordering */ + { 0, 8, 16, 15, 32, 24, 0, 0 }, + /* 15,16 bit closest depth ordering */ + { 0, 16, 15, 32, 24, 8, 0, 0 }, + /* 24 bit closest depth ordering */ + { 0, 24, 32, 16, 15, 8, 0, 0 }, + /* 32 bit closest depth ordering */ + { 0, 32, 16, 15, 24, 8, 0, 0 } +}; + +int SDL_VideoModeOK (int width, int height, int bpp, Uint32 flags) +{ + int table, b, i; + int supported; + SDL_PixelFormat format; + SDL_Rect **sizes; + + /* Currently 1 and 4 bpp are not supported */ + if ( bpp < 8 || bpp > 32 ) { + return(0); + } + if ( (width == 0) || (height == 0) ) { + return(0); + } + + /* Search through the list valid of modes */ + memset(&format, 0, sizeof(format)); + supported = 0; + table = ((bpp+7)/8)-1; + SDL_closest_depths[table][0] = bpp; + SDL_closest_depths[table][7] = 0; + for ( b = 0; !supported && SDL_closest_depths[table][b]; ++b ) { + format.BitsPerPixel = SDL_closest_depths[table][b]; + sizes = SDL_ListModes(&format, flags); + if ( sizes == (SDL_Rect **)0 ) { + /* No sizes supported at this bit-depth */ + continue; + } else +#ifdef macintosh /* MPW optimization bug? */ + if ( (sizes == (SDL_Rect **)0xFFFFFFFF) || +#else + if ( (sizes == (SDL_Rect **)-1) || +#endif + current_video->handles_any_size ) { + /* Any size supported at this bit-depth */ + supported = 1; + continue; + } else + for ( i=0; sizes[i]; ++i ) { + if ((sizes[i]->w == width) && (sizes[i]->h == height)) { + supported = 1; + break; + } + } + } + if ( supported ) { + --b; + return(SDL_closest_depths[table][b]); + } else { + return(0); + } +} + +/* + * Get the closest non-emulated video mode to the one requested + */ +static int SDL_GetVideoMode (int *w, int *h, int *BitsPerPixel, Uint32 flags) +{ + int table, b, i; + int supported; + int native_bpp; + SDL_PixelFormat format; + SDL_Rect **sizes; + + /* Try the original video mode, get the closest depth */ + native_bpp = SDL_VideoModeOK(*w, *h, *BitsPerPixel, flags); + if ( native_bpp == *BitsPerPixel ) { + return(1); + } + if ( native_bpp > 0 ) { + *BitsPerPixel = native_bpp; + return(1); + } + + /* No exact size match at any depth, look for closest match */ + memset(&format, 0, sizeof(format)); + supported = 0; + table = ((*BitsPerPixel+7)/8)-1; + SDL_closest_depths[table][0] = *BitsPerPixel; + SDL_closest_depths[table][7] = SDL_VideoSurface->format->BitsPerPixel; + for ( b = 0; !supported && SDL_closest_depths[table][b]; ++b ) { + format.BitsPerPixel = SDL_closest_depths[table][b]; + sizes = SDL_ListModes(&format, flags); + if ( sizes == (SDL_Rect **)0 ) { + /* No sizes supported at this bit-depth */ + continue; + } + for ( i=0; sizes[i]; ++i ) { + if ((sizes[i]->w < *w) || (sizes[i]->h < *h)) { + if ( i > 0 ) { + --i; + *w = sizes[i]->w; + *h = sizes[i]->h; + *BitsPerPixel = SDL_closest_depths[table][b]; + supported = 1; + } else { + /* Largest mode too small... */; + } + break; + } + } + if ( (i > 0) && ! sizes[i] ) { + /* The smallest mode was larger than requested, OK */ + --i; + *w = sizes[i]->w; + *h = sizes[i]->h; + *BitsPerPixel = SDL_closest_depths[table][b]; + supported = 1; + } + } + if ( ! supported ) { + SDL_SetError("No video mode large enough for %dx%d", *w, *h); + } + return(supported); +} + +/* This should probably go somewhere else -- like SDL_surface.c */ +static void SDL_ClearSurface(SDL_Surface *surface) +{ + Uint32 black; + + black = SDL_MapRGB(surface->format, 0, 0, 0); + SDL_FillRect(surface, NULL, black); + if ((surface->flags&SDL_HWSURFACE) && (surface->flags&SDL_DOUBLEBUF)) { + SDL_Flip(surface); + SDL_FillRect(surface, NULL, black); + } + SDL_Flip(surface); +} + +/* + * Create a shadow surface suitable for fooling the app. :-) + */ +static void SDL_CreateShadowSurface(int depth) +{ + Uint32 Rmask, Gmask, Bmask; + + /* Allocate the shadow surface */ + if ( depth == (SDL_VideoSurface->format)->BitsPerPixel ) { + Rmask = (SDL_VideoSurface->format)->Rmask; + Gmask = (SDL_VideoSurface->format)->Gmask; + Bmask = (SDL_VideoSurface->format)->Bmask; + } else { + Rmask = Gmask = Bmask = 0; + } + SDL_ShadowSurface = SDL_CreateRGBSurface(SDL_SWSURFACE, + SDL_VideoSurface->w, SDL_VideoSurface->h, + depth, Rmask, Gmask, Bmask, 0); + if ( SDL_ShadowSurface == NULL ) { + return; + } + + /* 8-bit shadow surfaces report that they have exclusive palette */ + if ( SDL_ShadowSurface->format->palette ) { + SDL_ShadowSurface->flags |= SDL_HWPALETTE; + if ( depth == (SDL_VideoSurface->format)->BitsPerPixel ) { + memcpy(SDL_ShadowSurface->format->palette->colors, + SDL_VideoSurface->format->palette->colors, + SDL_VideoSurface->format->palette->ncolors* + sizeof(SDL_Color)); + } else { + SDL_DitherColors( + SDL_ShadowSurface->format->palette->colors, depth); + } + } + + /* If the video surface is resizable, the shadow should say so */ + if ( (SDL_VideoSurface->flags & SDL_RESIZABLE) == SDL_RESIZABLE ) { + SDL_ShadowSurface->flags |= SDL_RESIZABLE; + } + /* If the video surface has no frame, the shadow should say so */ + if ( (SDL_VideoSurface->flags & SDL_NOFRAME) == SDL_NOFRAME ) { + SDL_ShadowSurface->flags |= SDL_NOFRAME; + } + /* If the video surface is fullscreen, the shadow should say so */ + if ( (SDL_VideoSurface->flags & SDL_FULLSCREEN) == SDL_FULLSCREEN ) { + SDL_ShadowSurface->flags |= SDL_FULLSCREEN; + } + /* If the video surface is flippable, the shadow should say so */ + if ( (SDL_VideoSurface->flags & SDL_DOUBLEBUF) == SDL_DOUBLEBUF ) { + SDL_ShadowSurface->flags |= SDL_DOUBLEBUF; + } + return; +} + +/* + * Set the requested video mode, allocating a shadow buffer if necessary. + */ +SDL_Surface * SDL_SetVideoMode (int width, int height, int bpp, Uint32 flags) +{ + SDL_VideoDevice *video, *this; + SDL_Surface *prev_mode, *mode; + int video_w; + int video_h; + int video_bpp; + int is_opengl; + SDL_GrabMode saved_grab; + + /* Start up the video driver, if necessary.. + WARNING: This is the only function protected this way! + */ + if ( ! current_video ) { + if ( SDL_Init(SDL_INIT_VIDEO|SDL_INIT_NOPARACHUTE) < 0 ) { + return(NULL); + } + } + this = video = current_video; + + /* Default to the current video bpp */ + if ( bpp == 0 ) { + flags |= SDL_ANYFORMAT; + bpp = SDL_VideoSurface->format->BitsPerPixel; + } + + /* Get a good video mode, the closest one possible */ + video_w = width; + video_h = height; + video_bpp = bpp; + if ( ! SDL_GetVideoMode(&video_w, &video_h, &video_bpp, flags) ) { + return(NULL); + } + + /* Check the requested flags */ + /* There's no palette in > 8 bits-per-pixel mode */ + if ( video_bpp > 8 ) { + flags &= ~SDL_HWPALETTE; + } +#if 0 + if ( (flags&SDL_FULLSCREEN) != SDL_FULLSCREEN ) { + /* There's no windowed double-buffering */ + flags &= ~SDL_DOUBLEBUF; + } +#endif + if ( (flags&SDL_DOUBLEBUF) == SDL_DOUBLEBUF ) { + /* Use hardware surfaces when double-buffering */ + flags |= SDL_HWSURFACE; + } + + is_opengl = ( ( flags & SDL_OPENGL ) == SDL_OPENGL ); + if ( is_opengl ) { + /* These flags are for 2D video modes only */ + flags &= ~(SDL_HWSURFACE|SDL_DOUBLEBUF); + } + + /* Reset the keyboard here so event callbacks can run */ + SDL_ResetKeyboard(); + + /* Clean up any previous video mode */ + if ( SDL_PublicSurface != NULL ) { + SDL_PublicSurface = NULL; + } + if ( SDL_ShadowSurface != NULL ) { + SDL_Surface *ready_to_go; + ready_to_go = SDL_ShadowSurface; + SDL_ShadowSurface = NULL; + SDL_FreeSurface(ready_to_go); + } + if ( video->physpal ) { + free(video->physpal->colors); + free(video->physpal); + video->physpal = NULL; + } + if( video->gammacols) { + free(video->gammacols); + video->gammacols = NULL; + } + + /* Save the previous grab state and turn off grab for mode switch */ + saved_grab = SDL_WM_GrabInputOff(); + + /* Try to set the video mode, along with offset and clipping */ + prev_mode = SDL_VideoSurface; + SDL_LockCursor(); + SDL_VideoSurface = NULL; /* In case it's freed by driver */ + mode = video->SetVideoMode(this, prev_mode,video_w,video_h,video_bpp,flags); + if ( mode ) { /* Prevent resize events from mode change */ + SDL_PrivateResize(mode->w, mode->h); + } + /* + * rcg11292000 + * If you try to set an SDL_OPENGL surface, and fail to find a + * matching visual, then the next call to SDL_SetVideoMode() + * will segfault, since we no longer point to a dummy surface, + * but rather NULL. + * Sam 11/29/00 + * WARNING, we need to make sure that the previous mode hasn't + * already been freed by the video driver. What do we do in + * that case? Should we call SDL_VideoInit() again? + */ + SDL_VideoSurface = (mode != NULL) ? mode : prev_mode; + + if ( (mode != NULL) && (!is_opengl) ) { + /* Sanity check */ + if ( (mode->w < width) || (mode->h < height) ) { + SDL_SetError("Video mode smaller than requested"); + return(NULL); + } + + /* If we have a palettized surface, create a default palette */ + if ( mode->format->palette ) { + SDL_PixelFormat *vf = mode->format; + SDL_DitherColors(vf->palette->colors, vf->BitsPerPixel); + video->SetColors(this, 0, vf->palette->ncolors, + vf->palette->colors); + } + + /* Clear the surface to black */ + video->offset_x = 0; + video->offset_y = 0; + mode->offset = 0; + SDL_SetClipRect(mode, NULL); + SDL_ClearSurface(mode); + + /* Now adjust the offsets to match the desired mode */ + video->offset_x = (mode->w-width)/2; + video->offset_y = (mode->h-height)/2; + mode->offset = video->offset_y*mode->pitch + + video->offset_x*mode->format->BytesPerPixel; +#ifdef DEBUG_VIDEO + SDL_printf("Requested mode: %dx%dx%d, obtained mode %dx%dx%d (offset %d)\n", + width, height, bpp, + mode->w, mode->h, mode->format->BitsPerPixel, mode->offset); +#endif + mode->w = width; + mode->h = height; + SDL_SetClipRect(mode, NULL); + } + SDL_ResetCursor(); + SDL_UnlockCursor(); + + /* If we failed setting a video mode, return NULL... (Uh Oh!) */ + if ( mode == NULL ) { + return(NULL); + } + + /* If there is no window manager, set the SDL_NOFRAME flag */ + if ( ! video->info.wm_available ) { + mode->flags |= SDL_NOFRAME; + } + + /* Reset the mouse cursor and grab for new video mode */ + SDL_SetCursor(NULL); + if ( video->UpdateMouse ) { + video->UpdateMouse(this); + } + SDL_WM_GrabInput(saved_grab); + SDL_GetRelativeMouseState(NULL, NULL); /* Clear first large delta */ + + /* If we're running OpenGL, make the context current */ + if ( (video->screen->flags & SDL_OPENGL) && + video->GL_MakeCurrent ) { + if ( video->GL_MakeCurrent(this) < 0 ) { + return(NULL); + } + } + + /* Set up a fake SDL surface for OpenGL "blitting" */ + if ( (flags & SDL_OPENGLBLIT) == SDL_OPENGLBLIT ) { + /* Load GL functions for performing the texture updates */ +#ifdef HAVE_OPENGL +#define SDL_PROC(ret,func,params) \ +do { \ + video->func = SDL_GL_GetProcAddress(#func); \ + if ( ! video->func ) { \ + SDL_SetError("Couldn't load GL function: %s\n", #func); \ + return(NULL); \ + } \ +} while ( 0 ); +#include "SDL_glfuncs.h" +#undef SDL_PROC + + /* Create a software surface for blitting */ +#ifdef GL_VERSION_1_2 + /* If the implementation either supports the packed pixels + extension, or implements the core OpenGL 1.2 API, it will + support the GL_UNSIGNED_SHORT_5_6_5 texture format. + */ + if ( (bpp == 16) && + (strstr((const char *)video->glGetString(GL_EXTENSIONS), + "GL_EXT_packed_pixels") || + (strncmp((const char *)video->glGetString(GL_VERSION), + "1.2", 3) == 0)) ) + { + video->is_32bit = 0; + SDL_VideoSurface = SDL_CreateRGBSurface( + flags, + width, + height, + 16, + 31 << 11, + 63 << 5, + 31, + 0 + ); + } + else +#endif /* OpenGL 1.2 */ + { + video->is_32bit = 1; + SDL_VideoSurface = SDL_CreateRGBSurface( + flags, + width, + height, + 32, +#if SDL_BYTEORDER == SDL_LIL_ENDIAN + 0x000000FF, + 0x0000FF00, + 0x00FF0000, + 0xFF000000 +#else + 0xFF000000, + 0x00FF0000, + 0x0000FF00, + 0x000000FF +#endif + ); + } + if ( ! SDL_VideoSurface ) { + return(NULL); + } + SDL_VideoSurface->flags = mode->flags | SDL_OPENGLBLIT; + + /* Free the original video mode surface (is this safe?) */ + SDL_FreeSurface(mode); + + /* Set the surface completely opaque & white by default */ + memset( SDL_VideoSurface->pixels, 255, SDL_VideoSurface->h * SDL_VideoSurface->pitch ); + video->glGenTextures( 1, &video->texture ); + video->glBindTexture( GL_TEXTURE_2D, video->texture ); + video->glTexImage2D( + GL_TEXTURE_2D, + 0, + video->is_32bit ? GL_RGBA : GL_RGB, + 256, + 256, + 0, + video->is_32bit ? GL_RGBA : GL_RGB, +#ifdef GL_VERSION_1_2 + video->is_32bit ? GL_UNSIGNED_BYTE : GL_UNSIGNED_SHORT_5_6_5, +#else + GL_UNSIGNED_BYTE, +#endif + NULL); + + video->UpdateRects = SDL_GL_UpdateRectsLock; +#else + SDL_SetError("Somebody forgot to #define HAVE_OPENGL"); + return(NULL); +#endif + } + + /* Create a shadow surface if necessary */ + /* There are three conditions under which we create a shadow surface: + 1. We need a particular bits-per-pixel that we didn't get. + 2. We need a hardware palette and didn't get one. + 3. We need a software surface and got a hardware surface. + */ + if ( !(SDL_VideoSurface->flags & SDL_OPENGL) && + ( + ( !(flags&SDL_ANYFORMAT) && + (SDL_VideoSurface->format->BitsPerPixel != bpp)) || + ( (flags&SDL_HWPALETTE) && + !(SDL_VideoSurface->flags&SDL_HWPALETTE)) || + /* If the surface is in hardware, video writes are visible + as soon as they are performed, so we need to buffer them + */ + ( ((flags&SDL_HWSURFACE) == SDL_SWSURFACE) && + (SDL_VideoSurface->flags&SDL_HWSURFACE)) + ) ) { + SDL_CreateShadowSurface(bpp); + if ( SDL_ShadowSurface == NULL ) { + SDL_SetError("Couldn't create shadow surface"); + return(NULL); + } + SDL_PublicSurface = SDL_ShadowSurface; + } else { + SDL_PublicSurface = SDL_VideoSurface; + } + video->info.vfmt = SDL_VideoSurface->format; + + /* We're done! */ + return(SDL_PublicSurface); +} + +/* + * Convert a surface into the video pixel format. + */ +SDL_Surface * SDL_DisplayFormat (SDL_Surface *surface) +{ + Uint32 flags; + + if ( ! SDL_PublicSurface ) { + SDL_SetError("No video mode has been set"); + return(NULL); + } + /* Set the flags appropriate for copying to display surface */ + flags = (SDL_PublicSurface->flags&SDL_HWSURFACE); +#ifdef AUTORLE_DISPLAYFORMAT + flags |= (surface->flags & (SDL_SRCCOLORKEY|SDL_SRCALPHA)); + flags |= SDL_RLEACCELOK; +#else + flags |= surface->flags & (SDL_SRCCOLORKEY|SDL_SRCALPHA|SDL_RLEACCELOK); +#endif + return(SDL_ConvertSurface(surface, SDL_PublicSurface->format, flags)); +} + +/* + * Convert a surface into a format that's suitable for blitting to + * the screen, but including an alpha channel. + */ +SDL_Surface *SDL_DisplayFormatAlpha(SDL_Surface *surface) +{ + SDL_PixelFormat *vf; + SDL_PixelFormat *format; + SDL_Surface *converted; + Uint32 flags; + /* default to ARGB8888 */ + Uint32 amask = 0xff000000; + Uint32 rmask = 0x00ff0000; + Uint32 gmask = 0x0000ff00; + Uint32 bmask = 0x000000ff; + + if ( ! SDL_PublicSurface ) { + SDL_SetError("No video mode has been set"); + return(NULL); + } + vf = SDL_PublicSurface->format; + + switch(vf->BytesPerPixel) { + case 2: + /* For XGY5[56]5, use, AXGY8888, where {X, Y} = {R, B}. + For anything else (like ARGB4444) it doesn't matter + since we have no special code for it anyway */ + if ( (vf->Rmask == 0x1f) && + (vf->Bmask == 0xf800 || vf->Bmask == 0x7c00)) { + rmask = 0xff; + bmask = 0xff0000; + } + break; + + case 3: + case 4: + /* Keep the video format, as long as the high 8 bits are + unused or alpha */ + if ( (vf->Rmask == 0xff) && (vf->Bmask == 0xff0000) ) { + rmask = 0xff; + bmask = 0xff0000; + } + break; + + default: + /* We have no other optimised formats right now. When/if a new + optimised alpha format is written, add the converter here */ + break; + } + format = SDL_AllocFormat(32, rmask, gmask, bmask, amask); + flags = SDL_PublicSurface->flags & SDL_HWSURFACE; + flags |= surface->flags & (SDL_SRCALPHA | SDL_RLEACCELOK); + converted = SDL_ConvertSurface(surface, format, flags); + SDL_FreeFormat(format); + return(converted); +} + +/* + * Update a specific portion of the physical screen + */ +void SDL_UpdateRect(SDL_Surface *screen, Sint32 x, Sint32 y, Uint32 w, Uint32 h) +{ + if ( screen ) { + SDL_Rect rect; + + /* Perform some checking */ + if ( w == 0 ) + w = screen->w; + if ( h == 0 ) + h = screen->h; + if ( (int)(x+w) > screen->w ) + return; + if ( (int)(y+h) > screen->h ) + return; + + /* Fill the rectangle */ + rect.x = x; + rect.y = y; + rect.w = w; + rect.h = h; + SDL_UpdateRects(screen, 1, &rect); + } +} +void SDL_UpdateRects (SDL_Surface *screen, int numrects, SDL_Rect *rects) +{ + int i; + SDL_VideoDevice *video = current_video; + SDL_VideoDevice *this = current_video; + + if ( screen == SDL_ShadowSurface ) { + /* Blit the shadow surface using saved mapping */ + SDL_Palette *pal = screen->format->palette; + SDL_Color *saved_colors = NULL; + if ( pal && !(SDL_VideoSurface->flags & SDL_HWPALETTE) ) { + /* simulated 8bpp, use correct physical palette */ + saved_colors = pal->colors; + if ( video->gammacols ) { + /* gamma-corrected palette */ + pal->colors = video->gammacols; + } else if ( video->physpal ) { + /* physical palette different from logical */ + pal->colors = video->physpal->colors; + } + } + if ( SHOULD_DRAWCURSOR(SDL_cursorstate) ) { + SDL_LockCursor(); + SDL_DrawCursor(SDL_ShadowSurface); + for ( i=0; icolors = saved_colors; + + /* Fall through to video surface update */ + screen = SDL_VideoSurface; + } + if ( screen == SDL_VideoSurface ) { + /* Update the video surface */ + if ( screen->offset ) { + for ( i=0; ioffset_x; + rects[i].y += video->offset_y; + } + video->UpdateRects(this, numrects, rects); + for ( i=0; ioffset_x; + rects[i].y -= video->offset_y; + } + } else { + video->UpdateRects(this, numrects, rects); + } + } +} + +/* + * Performs hardware double buffering, if possible, or a full update if not. + */ +int SDL_Flip(SDL_Surface *screen) +{ + SDL_VideoDevice *video = current_video; + /* Copy the shadow surface to the video surface */ + if ( screen == SDL_ShadowSurface ) { + SDL_Rect rect; + SDL_Palette *pal = screen->format->palette; + SDL_Color *saved_colors = NULL; + if ( pal && !(SDL_VideoSurface->flags & SDL_HWPALETTE) ) { + /* simulated 8bpp, use correct physical palette */ + saved_colors = pal->colors; + if ( video->gammacols ) { + /* gamma-corrected palette */ + pal->colors = video->gammacols; + } else if ( video->physpal ) { + /* physical palette different from logical */ + pal->colors = video->physpal->colors; + } + } + + rect.x = 0; + rect.y = 0; + rect.w = screen->w; + rect.h = screen->h; + SDL_LowerBlit(SDL_ShadowSurface,&rect, SDL_VideoSurface,&rect); + + if ( saved_colors ) + pal->colors = saved_colors; + screen = SDL_VideoSurface; + } + if ( (screen->flags & SDL_DOUBLEBUF) == SDL_DOUBLEBUF ) { + SDL_VideoDevice *this = current_video; + return(video->FlipHWSurface(this, SDL_VideoSurface)); + } else { + SDL_UpdateRect(screen, 0, 0, 0, 0); + } + return(0); +} + +static void SetPalette_logical(SDL_Surface *screen, SDL_Color *colors, + int firstcolor, int ncolors) +{ + SDL_Palette *pal = screen->format->palette; + SDL_Palette *vidpal; + + if ( colors != (pal->colors + firstcolor) ) { + memcpy(pal->colors + firstcolor, colors, + ncolors * sizeof(*colors)); + } + + vidpal = SDL_VideoSurface->format->palette; + if ( (screen == SDL_ShadowSurface) && vidpal ) { + /* + * This is a shadow surface, and the physical + * framebuffer is also indexed. Propagate the + * changes to its logical palette so that + * updates are always identity blits + */ + memcpy(vidpal->colors + firstcolor, colors, + ncolors * sizeof(*colors)); + } + SDL_FormatChanged(screen); +} + +static int SetPalette_physical(SDL_Surface *screen, + SDL_Color *colors, int firstcolor, int ncolors) +{ + SDL_VideoDevice *video = current_video; + int gotall = 1; + + if ( video->physpal ) { + /* We need to copy the new colors, since we haven't + * already done the copy in the logical set above. + */ + memcpy(video->physpal->colors + firstcolor, + colors, ncolors * sizeof(*colors)); + } + if ( screen == SDL_ShadowSurface ) { + if ( SDL_VideoSurface->flags & SDL_HWPALETTE ) { + /* + * The real screen is also indexed - set its physical + * palette. The physical palette does not include the + * gamma modification, we apply it directly instead, + * but this only happens if we have hardware palette. + */ + screen = SDL_VideoSurface; + } else { + /* + * The video surface is not indexed - invalidate any + * active shadow-to-video blit mappings. + */ + if ( screen->map->dst == SDL_VideoSurface ) { + SDL_InvalidateMap(screen->map); + } + if ( video->gamma ) { + if( ! video->gammacols ) { + SDL_Palette *pp = video->physpal; + if(!pp) + pp = screen->format->palette; + video->gammacols = malloc(pp->ncolors + * sizeof(SDL_Color)); + SDL_ApplyGamma(video->gamma, + pp->colors, + video->gammacols, + pp->ncolors); + } else { + SDL_ApplyGamma(video->gamma, colors, + video->gammacols + + firstcolor, + ncolors); + } + } + SDL_UpdateRect(screen, 0, 0, 0, 0); + } + } + + if ( screen == SDL_VideoSurface ) { + SDL_Color gcolors[256]; + + if ( video->gamma ) { + SDL_ApplyGamma(video->gamma, colors, gcolors, ncolors); + colors = gcolors; + } + gotall = video->SetColors(video, firstcolor, ncolors, colors); + if ( ! gotall ) { + /* The video flags shouldn't have SDL_HWPALETTE, and + the video driver is responsible for copying back the + correct colors into the video surface palette. + */ + ; + } + SDL_CursorPaletteChanged(); + } + return gotall; +} + +/* + * Set the physical and/or logical colormap of a surface: + * Only the screen has a physical colormap. It determines what is actually + * sent to the display. + * The logical colormap is used to map blits to/from the surface. + * 'which' is one or both of SDL_LOGPAL, SDL_PHYSPAL + * + * Return nonzero if all colours were set as requested, or 0 otherwise. + */ +int SDL_SetPalette(SDL_Surface *screen, int which, + SDL_Color *colors, int firstcolor, int ncolors) +{ + SDL_Palette *pal; + int gotall; + int palsize; + + if ( ! current_video ) { + return 0; + } + if ( screen != SDL_PublicSurface ) { + /* only screens have physical palettes */ + which &= ~SDL_PHYSPAL; + } else if( (screen->flags & SDL_HWPALETTE) != SDL_HWPALETTE ) { + /* hardware palettes required for split colormaps */ + which |= SDL_PHYSPAL | SDL_LOGPAL; + } + + /* Verify the parameters */ + pal = screen->format->palette; + if( !pal ) { + return 0; /* not a palettized surface */ + } + gotall = 1; + palsize = 1 << screen->format->BitsPerPixel; + if ( ncolors > (palsize - firstcolor) ) { + ncolors = (palsize - firstcolor); + gotall = 0; + } + + if ( which & SDL_LOGPAL ) { + /* + * Logical palette change: The actual screen isn't affected, + * but the internal colormap is altered so that the + * interpretation of the pixel values (for blits etc) is + * changed. + */ + SetPalette_logical(screen, colors, firstcolor, ncolors); + } + if ( which & SDL_PHYSPAL ) { + SDL_VideoDevice *video = current_video; + /* + * Physical palette change: This doesn't affect the + * program's idea of what the screen looks like, but changes + * its actual appearance. + */ + if(!video) + return gotall; /* video not yet initialized */ + if(!video->physpal && !(which & SDL_LOGPAL) ) { + /* Lazy physical palette allocation */ + int size; + SDL_Palette *pp = malloc(sizeof(*pp)); + current_video->physpal = pp; + pp->ncolors = pal->ncolors; + size = pp->ncolors * sizeof(SDL_Color); + pp->colors = malloc(size); + memcpy(pp->colors, pal->colors, size); + } + if ( ! SetPalette_physical(screen, + colors, firstcolor, ncolors) ) { + gotall = 0; + } + } + return gotall; +} + +int SDL_SetColors(SDL_Surface *screen, SDL_Color *colors, int firstcolor, + int ncolors) +{ + return SDL_SetPalette(screen, SDL_LOGPAL | SDL_PHYSPAL, + colors, firstcolor, ncolors); +} + +/* + * Clean up the video subsystem + */ +void SDL_VideoQuit (void) +{ + SDL_Surface *ready_to_go; + + if ( current_video ) { + SDL_VideoDevice *video = current_video; + SDL_VideoDevice *this = current_video; + + /* Halt event processing before doing anything else */ + SDL_StopEventLoop(); + + /* Clean up allocated window manager items */ + if ( SDL_PublicSurface ) { + SDL_PublicSurface = NULL; + } + SDL_CursorQuit(); + + /* Just in case... */ + SDL_WM_GrabInputOff(); + + /* Clean up the system video */ + video->VideoQuit(this); + + /* Free any lingering surfaces */ + ready_to_go = SDL_ShadowSurface; + SDL_ShadowSurface = NULL; + SDL_FreeSurface(ready_to_go); + if ( SDL_VideoSurface != NULL ) { + ready_to_go = SDL_VideoSurface; + SDL_VideoSurface = NULL; + SDL_FreeSurface(ready_to_go); + } + SDL_PublicSurface = NULL; + + /* Clean up miscellaneous memory */ + if ( video->physpal ) { + free(video->physpal->colors); + free(video->physpal); + video->physpal = NULL; + } + if ( video->gammacols ) { + free(video->gammacols); + video->gammacols = NULL; + } + if ( video->gamma ) { + free(video->gamma); + video->gamma = NULL; + } + if ( video->wm_title != NULL ) { + free(video->wm_title); + video->wm_title = NULL; + } + if ( video->wm_icon != NULL ) { + free(video->wm_icon); + video->wm_icon = NULL; + } + + /* Finish cleaning up video subsystem */ + video->free(this); + current_video = NULL; + } + return; +} + +/* Load the GL driver library */ +int SDL_GL_LoadLibrary(const char *path) +{ + SDL_VideoDevice *video = current_video; + SDL_VideoDevice *this = current_video; + int retval; + + retval = -1; + if ( video && video->GL_LoadLibrary ) { + retval = video->GL_LoadLibrary(this, path); + } else { + SDL_SetError("No dynamic GL support in video driver"); + } + return(retval); +} + +void *SDL_GL_GetProcAddress(const char* proc) +{ + SDL_VideoDevice *video = current_video; + SDL_VideoDevice *this = current_video; + void *func; + + func = NULL; + if ( video->GL_GetProcAddress ) { + if ( video->gl_config.driver_loaded ) { + func = video->GL_GetProcAddress(this, proc); + } else { + SDL_SetError("No GL driver has been loaded"); + } + } else { + SDL_SetError("No dynamic GL support in video driver"); + } + return func; +} + +/* Set the specified GL attribute for setting up a GL video mode */ +int SDL_GL_SetAttribute( SDL_GLattr attr, int value ) +{ + int retval; + SDL_VideoDevice *video = current_video; + + retval = 0; + switch (attr) { + case SDL_GL_RED_SIZE: + video->gl_config.red_size = value; + break; + case SDL_GL_GREEN_SIZE: + video->gl_config.green_size = value; + break; + case SDL_GL_BLUE_SIZE: + video->gl_config.blue_size = value; + break; + case SDL_GL_ALPHA_SIZE: + video->gl_config.alpha_size = value; + break; + case SDL_GL_DOUBLEBUFFER: + video->gl_config.double_buffer = value; + break; + case SDL_GL_BUFFER_SIZE: + video->gl_config.buffer_size = value; + break; + case SDL_GL_DEPTH_SIZE: + video->gl_config.depth_size = value; + break; + case SDL_GL_STENCIL_SIZE: + video->gl_config.stencil_size = value; + break; + case SDL_GL_ACCUM_RED_SIZE: + video->gl_config.accum_red_size = value; + break; + case SDL_GL_ACCUM_GREEN_SIZE: + video->gl_config.accum_green_size = value; + break; + case SDL_GL_ACCUM_BLUE_SIZE: + video->gl_config.accum_blue_size = value; + break; + case SDL_GL_ACCUM_ALPHA_SIZE: + video->gl_config.accum_alpha_size = value; + break; + default: + SDL_SetError("Unknown OpenGL attribute"); + retval = -1; + break; + } + return(retval); +} + +/* Retrieve an attribute value from the windowing system. */ +int SDL_GL_GetAttribute(SDL_GLattr attr, int* value) +{ + int retval = -1; + SDL_VideoDevice* video = current_video; + SDL_VideoDevice* this = current_video; + + if ( video->GL_GetAttribute ) { + retval = this->GL_GetAttribute(this, attr, value); + } else { + *value = 0; + SDL_SetError("GL_GetAttribute not supported"); + } + return retval; +} + +/* Perform a GL buffer swap on the current GL context */ +void SDL_GL_SwapBuffers(void) +{ + SDL_VideoDevice *video = current_video; + SDL_VideoDevice *this = current_video; + + if ( video->screen->flags & SDL_OPENGL ) { + video->GL_SwapBuffers( this ); + } +} + +/* Update rects with locking */ +void SDL_GL_UpdateRectsLock(SDL_VideoDevice* this, int numrects, SDL_Rect *rects) +{ + SDL_GL_Lock(); + SDL_GL_UpdateRects(numrects, rects); + SDL_GL_Unlock(); +} + +/* Update rects without state setting and changing (the caller is responsible for it) */ +void SDL_GL_UpdateRects(int numrects, SDL_Rect *rects) +{ +#ifdef HAVE_OPENGL + SDL_VideoDevice *this = current_video; + SDL_Rect update, tmp; + int x, y, i; + + for ( i = 0; i < numrects; i++ ) + { + tmp.y = rects[i].y; + tmp.h = rects[i].h; + for ( y = 0; y <= rects[i].h / 256; y++ ) + { + tmp.x = rects[i].x; + tmp.w = rects[i].w; + for ( x = 0; x <= rects[i].w / 256; x++ ) + { + update.x = tmp.x; + update.y = tmp.y; + update.w = tmp.w; + update.h = tmp.h; + + if ( update.w > 256 ) + update.w = 256; + + if ( update.h > 256 ) + update.h = 256; + + this->glFlush(); + this->glTexSubImage2D( + GL_TEXTURE_2D, + 0, + 0, + 0, + update.w, + update.h, + this->is_32bit? GL_RGBA : GL_RGB, +#ifdef GL_VERSION_1_2 + this->is_32bit ? GL_UNSIGNED_BYTE : GL_UNSIGNED_SHORT_5_6_5, +#else + GL_UNSIGNED_BYTE, +#endif + (Uint8 *)this->screen->pixels + + this->screen->format->BytesPerPixel * update.x + + update.y * this->screen->pitch ); + + this->glFlush(); + /* + * Note the parens around the function name: + * This is because some OpenGL implementations define glTexCoord etc + * as macros, and we don't want them expanded here. + */ + this->glBegin(GL_TRIANGLE_STRIP); + (this->glTexCoord2f)( 0.0, 0.0 ); + (this->glVertex2i)( update.x, update.y ); + (this->glTexCoord2f)( (float)(update.w / 256.0), 0.0 ); + (this->glVertex2i)( update.x + update.w, update.y ); + (this->glTexCoord2f)( 0.0, (float)(update.h / 256.0) ); + (this->glVertex2i)( update.x, update.y + update.h ); + (this->glTexCoord2f)( (float)(update.w / 256.0), (float)(update.h / 256.0) ); + (this->glVertex2i)( update.x + update.w , update.y + update.h ); + this->glEnd(); + + tmp.x += 256; + tmp.w -= 256; + } + tmp.y += 256; + tmp.h -= 256; + } + } +#endif +} + +/* Lock == save current state */ +void SDL_GL_Lock() +{ +#ifdef HAVE_OPENGL + lock_count--; + if (lock_count==-1) + { + SDL_VideoDevice *this = current_video; + + this->glPushAttrib( GL_ALL_ATTRIB_BITS ); /* TODO: narrow range of what is saved */ + this->glPushClientAttrib( GL_CLIENT_PIXEL_STORE_BIT ); + + this->glEnable(GL_TEXTURE_2D); + this->glEnable(GL_BLEND); + this->glDisable(GL_FOG); + this->glDisable(GL_ALPHA_TEST); + this->glDisable(GL_DEPTH_TEST); + this->glDisable(GL_SCISSOR_TEST); + this->glDisable(GL_STENCIL_TEST); + this->glDisable(GL_CULL_FACE); + + this->glBindTexture( GL_TEXTURE_2D, this->texture ); + this->glTexEnvf( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE ); + this->glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST ); + this->glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST ); + this->glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT ); + this->glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT ); + + this->glPixelStorei( GL_UNPACK_ROW_LENGTH, this->screen->pitch / this->screen->format->BytesPerPixel ); + this->glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + (this->glColor4f)(1.0, 1.0, 1.0, 1.0); /* Solaris workaround */ + + this->glViewport(0, 0, this->screen->w, this->screen->h); + this->glMatrixMode(GL_PROJECTION); + this->glPushMatrix(); + this->glLoadIdentity(); + + this->glOrtho(0.0, (GLdouble) this->screen->w, (GLdouble) this->screen->h, 0.0, 0.0, 1.0); + + this->glMatrixMode(GL_MODELVIEW); + this->glPushMatrix(); + this->glLoadIdentity(); + } +#endif +} + +/* Unlock == restore saved state */ +void SDL_GL_Unlock() +{ +#ifdef HAVE_OPENGL + lock_count++; + if (lock_count==0) + { + SDL_VideoDevice *this = current_video; + + this->glPopMatrix(); + this->glMatrixMode(GL_PROJECTION); + this->glPopMatrix(); + + this->glPopClientAttrib(); + this->glPopAttrib(); + } +#endif +} + +/* + * Sets/Gets the title and icon text of the display window, if any. + */ +void SDL_WM_SetCaption (const char *title, const char *icon) +{ + SDL_VideoDevice *video = current_video; + SDL_VideoDevice *this = current_video; + + if ( video ) { + if ( title ) { + if ( video->wm_title ) { + free(video->wm_title); + } + video->wm_title = (char *)malloc(strlen(title)+1); + if ( video->wm_title != NULL ) { + strcpy(video->wm_title, title); + } + } + if ( icon ) { + if ( video->wm_icon ) { + free(video->wm_icon); + } + video->wm_icon = (char *)malloc(strlen(icon)+1); + if ( video->wm_icon != NULL ) { + strcpy(video->wm_icon, icon); + } + } + if ( (title || icon) && (video->SetCaption != NULL) ) { + video->SetCaption(this, video->wm_title,video->wm_icon); + } + } +} +void SDL_WM_GetCaption (char **title, char **icon) +{ + SDL_VideoDevice *video = current_video; + + if ( video ) { + if ( title ) { + *title = video->wm_title; + } + if ( icon ) { + *icon = video->wm_icon; + } + } +} + +/* Utility function used by SDL_WM_SetIcon() */ +static void CreateMaskFromColorKey(SDL_Surface *icon, Uint8 *mask) +{ + int x, y; + Uint32 colorkey; +#define SET_MASKBIT(icon, x, y, mask) \ + mask[(y*((icon->w+7)/8))+(x/8)] &= ~(0x01<<(7-(x%8))) + + colorkey = icon->format->colorkey; + switch (icon->format->BytesPerPixel) { + case 1: { Uint8 *pixels; + for ( y=0; yh; ++y ) { + pixels = (Uint8 *)icon->pixels + y*icon->pitch; + for ( x=0; xw; ++x ) { + if ( *pixels++ == colorkey ) { + SET_MASKBIT(icon, x, y, mask); + } + } + } + } + break; + + case 2: { Uint16 *pixels; + for ( y=0; yh; ++y ) { + pixels = (Uint16 *)icon->pixels + + y*icon->pitch/2; + for ( x=0; xw; ++x ) { + if ( *pixels++ == colorkey ) { + SET_MASKBIT(icon, x, y, mask); + } + } + } + } + break; + + case 4: { Uint32 *pixels; + for ( y=0; yh; ++y ) { + pixels = (Uint32 *)icon->pixels + + y*icon->pitch/4; + for ( x=0; xw; ++x ) { + if ( *pixels++ == colorkey ) { + SET_MASKBIT(icon, x, y, mask); + } + } + } + } + break; + } +} + +/* + * Sets the window manager icon for the display window. + */ +void SDL_WM_SetIcon (SDL_Surface *icon, Uint8 *mask) +{ + SDL_VideoDevice *video = current_video; + SDL_VideoDevice *this = current_video; + + if ( icon && video->SetIcon ) { + /* Generate a mask if necessary, and create the icon! */ + if ( mask == NULL ) { + int mask_len = icon->h*(icon->w+7)/8; + mask = (Uint8 *)malloc(mask_len); + if ( mask == NULL ) { + return; + } + memset(mask, ~0, mask_len); + if ( icon->flags & SDL_SRCCOLORKEY ) { + CreateMaskFromColorKey(icon, mask); + } + video->SetIcon(video, icon, mask); + free(mask); + } else { + video->SetIcon(this, icon, mask); + } + } +} + +/* + * Grab or ungrab the keyboard and mouse input. + * This function returns the final grab mode after calling the + * driver dependent function. + */ +static SDL_GrabMode SDL_WM_GrabInputRaw(SDL_GrabMode mode) +{ + SDL_VideoDevice *video = current_video; + SDL_VideoDevice *this = current_video; + + /* Only do something if we have support for grabs */ + /*if ( video->GrabInput == NULL ) { + return(video->input_grab); + }*/ + + /* If the final grab mode if off, only then do we actually grab */ +#ifdef DEBUG_GRAB + SDL_printf("SDL_WM_GrabInputRaw(%d) ... ", mode); +#endif + /*if ( mode == SDL_GRAB_OFF ) { + if ( video->input_grab != SDL_GRAB_OFF ) { + mode = video->GrabInput(this, mode); + } + } else { + if ( video->input_grab == SDL_GRAB_OFF ) { + mode = video->GrabInput(this, mode); + } + }*/ + if ( mode != video->input_grab ) { + video->input_grab = mode; + if ( video->CheckMouseMode ) { + video->CheckMouseMode(this); + } + } +#ifdef DEBUG_GRAB + SDL_printf("Final mode %d\n", video->input_grab); +#endif + + /* Return the final grab state */ + if ( mode >= SDL_GRAB_FULLSCREEN ) { + mode -= SDL_GRAB_FULLSCREEN; + } + return(mode); +} +SDL_GrabMode SDL_WM_GrabInput(SDL_GrabMode mode) +{ + SDL_VideoDevice *video = current_video; + + /* If the video isn't initialized yet, we can't do anything */ + if ( ! video ) { + return SDL_GRAB_OFF; + } + + /* Return the current mode on query */ + if ( mode == SDL_GRAB_QUERY ) { + mode = video->input_grab; + if ( mode >= SDL_GRAB_FULLSCREEN ) { + mode -= SDL_GRAB_FULLSCREEN; + } + return(mode); + } + +#ifdef DEBUG_GRAB + SDL_printf("SDL_WM_GrabInput(%d) ... ", mode); +#endif + /* If the video surface is fullscreen, we always grab */ + if ( mode >= SDL_GRAB_FULLSCREEN ) { + mode -= SDL_GRAB_FULLSCREEN; + } + if ( SDL_VideoSurface && (SDL_VideoSurface->flags & SDL_FULLSCREEN) ) { + mode += SDL_GRAB_FULLSCREEN; + } + return(SDL_WM_GrabInputRaw(mode)); +} +static SDL_GrabMode SDL_WM_GrabInputOff(void) +{ + SDL_GrabMode mode; + + /* First query the current grab state */ + mode = SDL_WM_GrabInput(SDL_GRAB_QUERY); + + /* Now explicitly turn off input grab */ + SDL_WM_GrabInputRaw(SDL_GRAB_OFF); + + /* Return the old state */ + return(mode); +} + +/* + * Iconify the window in window managed environments. + * A successful iconification will result in an SDL_APPACTIVE loss event. + */ +int SDL_WM_IconifyWindow(void) +{ + SDL_VideoDevice *video = current_video; + SDL_VideoDevice *this = current_video; + int retval; + + retval = 0; + if ( video->IconifyWindow ) { + retval = video->IconifyWindow(this); + } + return(retval); +} + +/* + * Toggle fullscreen mode + */ +int SDL_WM_ToggleFullScreen(SDL_Surface *surface) +{ + SDL_VideoDevice *video = current_video; + SDL_VideoDevice *this = current_video; + int toggled; + + toggled = 0; + if ( SDL_PublicSurface && (surface == SDL_PublicSurface) && + video->ToggleFullScreen ) { + if ( surface->flags & SDL_FULLSCREEN ) { + toggled = video->ToggleFullScreen(this, 0); + if ( toggled ) { + SDL_VideoSurface->flags &= ~SDL_FULLSCREEN; + SDL_PublicSurface->flags &= ~SDL_FULLSCREEN; + } + } else { + toggled = video->ToggleFullScreen(this, 1); + if ( toggled ) { + SDL_VideoSurface->flags |= SDL_FULLSCREEN; + SDL_PublicSurface->flags |= SDL_FULLSCREEN; + } + } + /* Double-check the grab state inside SDL_WM_GrabInput() */ + if ( toggled ) { + SDL_WM_GrabInput(video->input_grab); + } + } + return(toggled); +} + +/* + * Get some platform dependent window manager information + */ +int SDL_GetWMInfo (SDL_SysWMinfo *info) +{ + SDL_VideoDevice *video = current_video; + SDL_VideoDevice *this = current_video; + + if ( video && video->GetWMInfo ) { + return(video->GetWMInfo(this, info)); + } else { + return(0); + } +} diff --git a/contrib/sdk/sources/SDL-1.2.2/src/video/SDL_yuv.c b/contrib/sdk/sources/SDL-1.2.2/src/video/SDL_yuv.c new file mode 100644 index 000000000..ae93d9c55 --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/src/video/SDL_yuv.c @@ -0,0 +1,89 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997, 1998, 1999, 2000, 2001 Sam Lantinga + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the Free + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + Sam Lantinga + slouken@devolution.com +*/ + + +/* This is the implementation of the YUV video surface support */ + +#include +#include + +#include "SDL_getenv.h" +#include "SDL_video.h" +#include "SDL_sysvideo.h" +#include "SDL_yuvfuncs.h" +#include "SDL_yuv_sw_c.h" + + +SDL_Overlay *SDL_CreateYUVOverlay(int w, int h, Uint32 format, + SDL_Surface *display) +{ + SDL_VideoDevice *video = current_video; + SDL_VideoDevice *this = current_video; + const char *yuv_hwaccel; + SDL_Overlay *overlay; + + overlay = NULL; + + /* Display directly on video surface, if possible */ + if ( getenv("SDL_VIDEO_YUV_DIRECT") ) { + if ( (display == SDL_PublicSurface) && + ((SDL_VideoSurface->format->BytesPerPixel == 2) || + (SDL_VideoSurface->format->BytesPerPixel == 4)) ) { + display = SDL_VideoSurface; + } + } + yuv_hwaccel = getenv("SDL_VIDEO_YUV_HWACCEL"); + if ( ((display == SDL_VideoSurface) && video->CreateYUVOverlay) && + (!yuv_hwaccel || (atoi(yuv_hwaccel) > 0)) ) { + overlay = video->CreateYUVOverlay(this, w, h, format, display); + } + /* If hardware YUV overlay failed ... */ + if ( overlay == NULL ) { + overlay = SDL_CreateYUV_SW(this, w, h, format, display); + } + return overlay; +} + +int SDL_LockYUVOverlay(SDL_Overlay *overlay) +{ + return overlay->hwfuncs->Lock(current_video, overlay); +} + +void SDL_UnlockYUVOverlay(SDL_Overlay *overlay) +{ + overlay->hwfuncs->Unlock(current_video, overlay); +} + +int SDL_DisplayYUVOverlay(SDL_Overlay *overlay, SDL_Rect *dstrect) +{ + return overlay->hwfuncs->Display(current_video, overlay, dstrect); +} + +void SDL_FreeYUVOverlay(SDL_Overlay *overlay) +{ + if ( overlay ) { + if ( overlay->hwfuncs ) { + overlay->hwfuncs->FreeHW(current_video, overlay); + } + free(overlay); + } +} diff --git a/contrib/sdk/sources/SDL-1.2.2/src/video/SDL_yuv_mmx.c b/contrib/sdk/sources/SDL-1.2.2/src/video/SDL_yuv_mmx.c new file mode 100644 index 000000000..651076372 --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/src/video/SDL_yuv_mmx.c @@ -0,0 +1,418 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997, 1998, 1999, 2000, 2001 Sam Lantinga + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the Free + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + Sam Lantinga + slouken@devolution.com +*/ + + + +#if defined(i386) && defined(__GNUC__) && defined(USE_ASMBLIT) + +#include "SDL_types.h" + +#ifdef __ELF__ +#define ASM_VAR(X) _##X +#else +#define ASM_VAR(X) X +#endif + +#define static +static unsigned int ASM_VAR(MMX_0080w)[] = {0x00800080, 0x00800080}; +static unsigned int ASM_VAR(MMX_00FFw)[] = {0x00ff00ff, 0x00ff00ff}; +static unsigned int ASM_VAR(MMX_FF00w)[] = {0xff00ff00, 0xff00ff00}; + +static unsigned short ASM_VAR(MMX_Ycoeff)[] = {0x004a, 0x004a, 0x004a, 0x004a}; + +static unsigned short ASM_VAR(MMX_UbluRGB)[] = {0x0072, 0x0072, 0x0072, 0x0072}; +static unsigned short ASM_VAR(MMX_VredRGB)[] = {0x0059, 0x0059, 0x0059, 0x0059}; +static unsigned short ASM_VAR(MMX_UgrnRGB)[] = {0xffea, 0xffea, 0xffea, 0xffea}; +static unsigned short ASM_VAR(MMX_VgrnRGB)[] = {0xffd2, 0xffd2, 0xffd2, 0xffd2}; + +static unsigned short ASM_VAR(MMX_Ublu5x5)[] = {0x0081, 0x0081, 0x0081, 0x0081}; +static unsigned short ASM_VAR(MMX_Vred5x5)[] = {0x0066, 0x0066, 0x0066, 0x0066}; +static unsigned short ASM_VAR(MMX_Ugrn555)[] = {0xffe7, 0xffe7, 0xffe7, 0xffe7}; +static unsigned short ASM_VAR(MMX_Vgrn555)[] = {0xffcc, 0xffcc, 0xffcc, 0xffcc}; +static unsigned short ASM_VAR(MMX_Ugrn565)[] = {0xffe8, 0xffe8, 0xffe8, 0xffe8}; +static unsigned short ASM_VAR(MMX_Vgrn565)[] = {0xffcd, 0xffcd, 0xffcd, 0xffcd}; + +static unsigned short ASM_VAR(MMX_red555)[] = {0x7c00, 0x7c00, 0x7c00, 0x7c00}; +static unsigned short ASM_VAR(MMX_red565)[] = {0xf800, 0xf800, 0xf800, 0xf800}; +static unsigned short ASM_VAR(MMX_grn555)[] = {0x03e0, 0x03e0, 0x03e0, 0x03e0}; +static unsigned short ASM_VAR(MMX_grn565)[] = {0x07e0, 0x07e0, 0x07e0, 0x07e0}; +static unsigned short ASM_VAR(MMX_blu5x5)[] = {0x001f, 0x001f, 0x001f, 0x001f}; + +/** + This MMX assembler is my first assembler/MMX program ever. + Thus it maybe buggy. + Send patches to: + mvogt@rhrk.uni-kl.de + + After it worked fine I have "obfuscated" the code a bit to have + more parallism in the MMX units. This means I moved + initilisation around and delayed other instruction. + Performance measurement did not show that this brought any advantage + but in theory it _should_ be faster this way. + + The overall performanve gain to the C based dither was 30%-40%. + The MMX routine calculates 256bit=8RGB values in each cycle + (4 for row1 & 4 for row2) + + The red/green/blue.. coefficents are taken from the mpeg_play + player. They look nice, but I dont know if you can have + better values, to avoid integer rounding errors. + + + IMPORTANT: + ========== + + It is a requirement that the cr/cb/lum are 8 byte aligned and + the out are 16byte aligned or you will/may get segfaults + +*/ + +void ColorRGBDitherYV12MMX1X( int *colortab, Uint32 *rgb_2_pix, + unsigned char *lum, unsigned char *cr, + unsigned char *cb, unsigned char *out, + int rows, int cols, int mod ) +{ + Uint32 *row1; + Uint32 *row2; + + unsigned char* y = lum +cols*rows; // Pointer to the end + int x=0; + row1 = (Uint32 *)out; // 32 bit target + row2 = (Uint32 *)out+cols+mod; // start of second row + mod = (mod+cols+mod)*4; // increment for row1 in byte + + __asm__ __volatile__ ( +/* We don't really care about PIC - the code should be rewritten to use + relative addressing for the static tables, so right now we take the + COW hit on the pages this code resides. Big deal. + This spill is just to reduce register pressure in the PIC case. */ + "pushl %%ebx\n" + "movl %0, %%ebx\n" + + ".align 8\n" + "1:\n" + + // create Cr (result in mm1) + "movd (%%ebx), %%mm1\n" // 0 0 0 0 v3 v2 v1 v0 + "pxor %%mm7,%%mm7\n" // 00 00 00 00 00 00 00 00 + "movd (%2), %%mm2\n" // 0 0 0 0 l3 l2 l1 l0 + "punpcklbw %%mm7,%%mm1\n" // 0 v3 0 v2 00 v1 00 v0 + "punpckldq %%mm1,%%mm1\n" // 00 v1 00 v0 00 v1 00 v0 + "psubw _MMX_0080w,%%mm1\n" // mm1-128:r1 r1 r0 r0 r1 r1 r0 r0 + + // create Cr_g (result in mm0) + "movq %%mm1,%%mm0\n" // r1 r1 r0 r0 r1 r1 r0 r0 + "pmullw _MMX_VgrnRGB,%%mm0\n"// red*-46dec=0.7136*64 + "pmullw _MMX_VredRGB,%%mm1\n"// red*89dec=1.4013*64 + "psraw $6, %%mm0\n" // red=red/64 + "psraw $6, %%mm1\n" // red=red/64 + + // create L1 L2 (result in mm2,mm4) + // L2=lum+cols + "movq (%2,%4),%%mm3\n" // 0 0 0 0 L3 L2 L1 L0 + "punpckldq %%mm3,%%mm2\n" // L3 L2 L1 L0 l3 l2 l1 l0 + "movq %%mm2,%%mm4\n" // L3 L2 L1 L0 l3 l2 l1 l0 + "pand _MMX_FF00w,%%mm2\n" // L3 0 L1 0 l3 0 l1 0 + "pand _MMX_00FFw,%%mm4\n" // 0 L2 0 L0 0 l2 0 l0 + "psrlw $8,%%mm2\n" // 0 L3 0 L1 0 l3 0 l1 + + // create R (result in mm6) + "movq %%mm2,%%mm5\n" // 0 L3 0 L1 0 l3 0 l1 + "movq %%mm4,%%mm6\n" // 0 L2 0 L0 0 l2 0 l0 + "paddsw %%mm1, %%mm5\n" // lum1+red:x R3 x R1 x r3 x r1 + "paddsw %%mm1, %%mm6\n" // lum1+red:x R2 x R0 x r2 x r0 + "packuswb %%mm5,%%mm5\n" // R3 R1 r3 r1 R3 R1 r3 r1 + "packuswb %%mm6,%%mm6\n" // R2 R0 r2 r0 R2 R0 r2 r0 + "pxor %%mm7,%%mm7\n" // 00 00 00 00 00 00 00 00 + "punpcklbw %%mm5,%%mm6\n" // R3 R2 R1 R0 r3 r2 r1 r0 + + // create Cb (result in mm1) + "movd (%1), %%mm1\n" // 0 0 0 0 u3 u2 u1 u0 + "punpcklbw %%mm7,%%mm1\n" // 0 u3 0 u2 00 u1 00 u0 + "punpckldq %%mm1,%%mm1\n" // 00 u1 00 u0 00 u1 00 u0 + "psubw _MMX_0080w,%%mm1\n" // mm1-128:u1 u1 u0 u0 u1 u1 u0 u0 + // create Cb_g (result in mm5) + "movq %%mm1,%%mm5\n" // u1 u1 u0 u0 u1 u1 u0 u0 + "pmullw _MMX_UgrnRGB,%%mm5\n" // blue*-109dec=1.7129*64 + "pmullw _MMX_UbluRGB,%%mm1\n" // blue*114dec=1.78125*64 + "psraw $6, %%mm5\n" // blue=red/64 + "psraw $6, %%mm1\n" // blue=blue/64 + + // create G (result in mm7) + "movq %%mm2,%%mm3\n" // 0 L3 0 L1 0 l3 0 l1 + "movq %%mm4,%%mm7\n" // 0 L2 0 L0 0 l2 0 l1 + "paddsw %%mm5, %%mm3\n" // lum1+Cb_g:x G3t x G1t x g3t x g1t + "paddsw %%mm5, %%mm7\n" // lum1+Cb_g:x G2t x G0t x g2t x g0t + "paddsw %%mm0, %%mm3\n" // lum1+Cr_g:x G3 x G1 x g3 x g1 + "paddsw %%mm0, %%mm7\n" // lum1+blue:x G2 x G0 x g2 x g0 + "packuswb %%mm3,%%mm3\n" // G3 G1 g3 g1 G3 G1 g3 g1 + "packuswb %%mm7,%%mm7\n" // G2 G0 g2 g0 G2 G0 g2 g0 + "punpcklbw %%mm3,%%mm7\n" // G3 G2 G1 G0 g3 g2 g1 g0 + + // create B (result in mm5) + "movq %%mm2,%%mm3\n" // 0 L3 0 L1 0 l3 0 l1 + "movq %%mm4,%%mm5\n" // 0 L2 0 L0 0 l2 0 l1 + "paddsw %%mm1, %%mm3\n" // lum1+blue:x B3 x B1 x b3 x b1 + "paddsw %%mm1, %%mm5\n" // lum1+blue:x B2 x B0 x b2 x b0 + "packuswb %%mm3,%%mm3\n" // B3 B1 b3 b1 B3 B1 b3 b1 + "packuswb %%mm5,%%mm5\n" // B2 B0 b2 b0 B2 B0 b2 b0 + "punpcklbw %%mm3,%%mm5\n" // B3 B2 B1 B0 b3 b2 b1 b0 + + // fill destination row1 (needed are mm6=Rr,mm7=Gg,mm5=Bb) + + "pxor %%mm2,%%mm2\n" // 0 0 0 0 0 0 0 0 + "pxor %%mm4,%%mm4\n" // 0 0 0 0 0 0 0 0 + "movq %%mm6,%%mm1\n" // R3 R2 R1 R0 r3 r2 r1 r0 + "movq %%mm5,%%mm3\n" // B3 B2 B1 B0 b3 b2 b1 b0 + // process lower lum + "punpcklbw %%mm4,%%mm1\n" // 0 r3 0 r2 0 r1 0 r0 + "punpcklbw %%mm4,%%mm3\n" // 0 b3 0 b2 0 b1 0 b0 + "movq %%mm1,%%mm2\n" // 0 r3 0 r2 0 r1 0 r0 + "movq %%mm3,%%mm0\n" // 0 b3 0 b2 0 b1 0 b0 + "punpcklwd %%mm1,%%mm3\n" // 0 r1 0 b1 0 r0 0 b0 + "punpckhwd %%mm2,%%mm0\n" // 0 r3 0 b3 0 r2 0 b2 + + "pxor %%mm2,%%mm2\n" // 0 0 0 0 0 0 0 0 + "movq %%mm7,%%mm1\n" // G3 G2 G1 G0 g3 g2 g1 g0 + "punpcklbw %%mm1,%%mm2\n" // g3 0 g2 0 g1 0 g0 0 + "punpcklwd %%mm4,%%mm2\n" // 0 0 g1 0 0 0 g0 0 + "por %%mm3, %%mm2\n" // 0 r1 g1 b1 0 r0 g0 b0 + "movq %%mm2,(%3)\n" // wrote out ! row1 + + "pxor %%mm2,%%mm2\n" // 0 0 0 0 0 0 0 0 + "punpcklbw %%mm1,%%mm4\n" // g3 0 g2 0 g1 0 g0 0 + "punpckhwd %%mm2,%%mm4\n" // 0 0 g3 0 0 0 g2 0 + "por %%mm0, %%mm4\n" // 0 r3 g3 b3 0 r2 g2 b2 + "movq %%mm4,8(%3)\n" // wrote out ! row1 + + // fill destination row2 (needed are mm6=Rr,mm7=Gg,mm5=Bb) + // this can be done "destructive" + "pxor %%mm2,%%mm2\n" // 0 0 0 0 0 0 0 0 + "punpckhbw %%mm2,%%mm6\n" // 0 R3 0 R2 0 R1 0 R0 + "punpckhbw %%mm1,%%mm5\n" // G3 B3 G2 B2 G1 B1 G0 B0 + "movq %%mm5,%%mm1\n" // G3 B3 G2 B2 G1 B1 G0 B0 + "punpcklwd %%mm6,%%mm1\n" // 0 R1 G1 B1 0 R0 G0 B0 + "movq %%mm1,(%5)\n" // wrote out ! row2 + "punpckhwd %%mm6,%%mm5\n" // 0 R3 G3 B3 0 R2 G2 B2 + "movq %%mm5,8(%5)\n" // wrote out ! row2 + + "addl $4,%2\n" // lum+4 + "leal 16(%3),%3\n" // row1+16 + "leal 16(%5),%5\n" // row2+16 + "addl $2, %%ebx\n" // cr+2 + "addl $2, %1\n" // cb+2 + + "addl $4,%6\n" // x+4 + "cmpl %4,%6\n" + + "jl 1b\n" + "addl %4, %2\n" // lum += cols + "addl %8, %3\n" // row1+= mod + "addl %8, %5\n" // row2+= mod + "movl $0, %6\n" // x=0 + "cmpl %7, %2\n" + "jl 1b\n" + "emms\n" + "popl %%ebx\n" + : + : "m" (cr), "r"(cb),"r"(lum), + "r"(row1),"r"(cols),"r"(row2),"m"(x),"m"(y),"m"(mod) + : "%ebx" + ); +} + +void Color565DitherYV12MMX1X( int *colortab, Uint32 *rgb_2_pix, + unsigned char *lum, unsigned char *cr, + unsigned char *cb, unsigned char *out, + int rows, int cols, int mod ) +{ + Uint16 *row1; + Uint16 *row2; + + unsigned char* y = lum +cols*rows; /* Pointer to the end */ + int x=0; + row1 = (Uint16 *)out; /* 16 bit target */ + row2 = (Uint16 *)out+cols+mod; /* start of second row */ + mod = (mod+cols+mod)*2; /* increment for row1 in byte */ + + + __asm__ __volatile__( + "pushl %%ebx\n" + "movl %0, %%ebx\n" + + ".align 8\n" + "1:\n" + "movd (%1), %%mm0\n" // 4 Cb 0 0 0 0 u3 u2 u1 u0 + "pxor %%mm7, %%mm7\n" + "movd (%%ebx), %%mm1\n" // 4 Cr 0 0 0 0 v3 v2 v1 v0 + "punpcklbw %%mm7, %%mm0\n" // 4 W cb 0 u3 0 u2 0 u1 0 u0 + "punpcklbw %%mm7, %%mm1\n" // 4 W cr 0 v3 0 v2 0 v1 0 v0 + "psubw _MMX_0080w, %%mm0\n" + "psubw _MMX_0080w, %%mm1\n" + "movq %%mm0, %%mm2\n" // Cb 0 u3 0 u2 0 u1 0 u0 + "movq %%mm1, %%mm3\n" // Cr + "pmullw _MMX_Ugrn565, %%mm2\n" // Cb2green 0 R3 0 R2 0 R1 0 R0 + "movq (%2), %%mm6\n" // L1 l7 L6 L5 L4 L3 L2 L1 L0 + "pmullw _MMX_Ublu5x5, %%mm0\n" // Cb2blue + "pand _MMX_00FFw, %%mm6\n" // L1 00 L6 00 L4 00 L2 00 L0 + "pmullw _MMX_Vgrn565, %%mm3\n" // Cr2green + "movq (%2), %%mm7\n" // L2 + "pmullw _MMX_Vred5x5, %%mm1\n" // Cr2red + "psrlw $8, %%mm7\n" // L2 00 L7 00 L5 00 L3 00 L1 + "pmullw _MMX_Ycoeff, %%mm6\n" // lum1 + "paddw %%mm3, %%mm2\n" // Cb2green + Cr2green == green + "pmullw _MMX_Ycoeff, %%mm7\n" // lum2 + + "movq %%mm6, %%mm4\n" // lum1 + "paddw %%mm0, %%mm6\n" // lum1 +blue 00 B6 00 B4 00 B2 00 B0 + "movq %%mm4, %%mm5\n" // lum1 + "paddw %%mm1, %%mm4\n" // lum1 +red 00 R6 00 R4 00 R2 00 R0 + "paddw %%mm2, %%mm5\n" // lum1 +green 00 G6 00 G4 00 G2 00 G0 + "psraw $6, %%mm4\n" // R1 0 .. 64 + "movq %%mm7, %%mm3\n" // lum2 00 L7 00 L5 00 L3 00 L1 + "psraw $6, %%mm5\n" // G1 - .. + + "paddw %%mm0, %%mm7\n" // Lum2 +blue 00 B7 00 B5 00 B3 00 B1 + "psraw $6, %%mm6\n" // B1 0 .. 64 + "packuswb %%mm4, %%mm4\n" // R1 R1 + "packuswb %%mm5, %%mm5\n" // G1 G1 + "packuswb %%mm6, %%mm6\n" // B1 B1 + "punpcklbw %%mm4, %%mm4\n" + "punpcklbw %%mm5, %%mm5\n" + + "pand _MMX_red565, %%mm4\n" + "psllw $3, %%mm5\n" // GREEN 1 + "punpcklbw %%mm6, %%mm6\n" + "pand _MMX_grn565, %%mm5\n" + "pand _MMX_red565, %%mm6\n" + "por %%mm5, %%mm4\n" // + "psrlw $11, %%mm6\n" // BLUE 1 + "movq %%mm3, %%mm5\n" // lum2 + "paddw %%mm1, %%mm3\n" // lum2 +red 00 R7 00 R5 00 R3 00 R1 + "paddw %%mm2, %%mm5\n" // lum2 +green 00 G7 00 G5 00 G3 00 G1 + "psraw $6, %%mm3\n" // R2 + "por %%mm6, %%mm4\n" // MM4 + "psraw $6, %%mm5\n" // G2 + "movq (%2, %4), %%mm6\n" // L3 load lum2 + "psraw $6, %%mm7\n" + "packuswb %%mm3, %%mm3\n" + "packuswb %%mm5, %%mm5\n" + "packuswb %%mm7, %%mm7\n" + "pand _MMX_00FFw, %%mm6\n" // L3 + "punpcklbw %%mm3, %%mm3\n" + "punpcklbw %%mm5, %%mm5\n" + "pmullw _MMX_Ycoeff, %%mm6\n" // lum3 + "punpcklbw %%mm7, %%mm7\n" + "psllw $3, %%mm5\n" // GREEN 2 + "pand _MMX_red565, %%mm7\n" + "pand _MMX_red565, %%mm3\n" + "psrlw $11, %%mm7\n" // BLUE 2 + "pand _MMX_grn565, %%mm5\n" + "por %%mm7, %%mm3\n" + "movq (%2,%4), %%mm7\n" // L4 load lum2 + "por %%mm5, %%mm3\n" // + "psrlw $8, %%mm7\n" // L4 + "movq %%mm4, %%mm5\n" + "punpcklwd %%mm3, %%mm4\n" + "pmullw _MMX_Ycoeff, %%mm7\n" // lum4 + "punpckhwd %%mm3, %%mm5\n" + + "movq %%mm4, (%3)\n" // write row1 + "movq %%mm5, 8(%3)\n" // write row1 + + "movq %%mm6, %%mm4\n" // Lum3 + "paddw %%mm0, %%mm6\n" // Lum3 +blue + + "movq %%mm4, %%mm5\n" // Lum3 + "paddw %%mm1, %%mm4\n" // Lum3 +red + "paddw %%mm2, %%mm5\n" // Lum3 +green + "psraw $6, %%mm4\n" + "movq %%mm7, %%mm3\n" // Lum4 + "psraw $6, %%mm5\n" + "paddw %%mm0, %%mm7\n" // Lum4 +blue + "psraw $6, %%mm6\n" // Lum3 +blue + "movq %%mm3, %%mm0\n" // Lum4 + "packuswb %%mm4, %%mm4\n" + "paddw %%mm1, %%mm3\n" // Lum4 +red + "packuswb %%mm5, %%mm5\n" + "paddw %%mm2, %%mm0\n" // Lum4 +green + "packuswb %%mm6, %%mm6\n" + "punpcklbw %%mm4, %%mm4\n" + "punpcklbw %%mm5, %%mm5\n" + "punpcklbw %%mm6, %%mm6\n" + "psllw $3, %%mm5\n" // GREEN 3 + "pand _MMX_red565, %%mm4\n" + "psraw $6, %%mm3\n" // psr 6 + "psraw $6, %%mm0\n" + "pand _MMX_red565, %%mm6\n" // BLUE + "pand _MMX_grn565, %%mm5\n" + "psrlw $11, %%mm6\n" // BLUE 3 + "por %%mm5, %%mm4\n" + "psraw $6, %%mm7\n" + "por %%mm6, %%mm4\n" + "packuswb %%mm3, %%mm3\n" + "packuswb %%mm0, %%mm0\n" + "packuswb %%mm7, %%mm7\n" + "punpcklbw %%mm3, %%mm3\n" + "punpcklbw %%mm0, %%mm0\n" + "punpcklbw %%mm7, %%mm7\n" + "pand _MMX_red565, %%mm3\n" + "pand _MMX_red565, %%mm7\n" // BLUE + "psllw $3, %%mm0\n" // GREEN 4 + "psrlw $11, %%mm7\n" + "pand _MMX_grn565, %%mm0\n" + "por %%mm7, %%mm3\n" + "por %%mm0, %%mm3\n" + + "movq %%mm4, %%mm5\n" + + "punpcklwd %%mm3, %%mm4\n" + "punpckhwd %%mm3, %%mm5\n" + + "movq %%mm4, (%5)\n" + "movq %%mm5, 8(%5)\n" + + "addl $8, %6\n" + "addl $8, %2\n" + "addl $4, %%ebx\n" + "addl $4, %1\n" + "cmpl %4, %6\n" + "leal 16(%3), %3\n" + "leal 16(%5),%5\n" // row2+16 + + + "jl 1b\n" + "addl %4, %2\n" // lum += cols + "addl %8, %3\n" // row1+= mod + "addl %8, %5\n" // row2+= mod + "movl $0, %6\n" // x=0 + "cmpl %7, %2\n" + "jl 1b\n" + "emms\n" + "popl %%ebx\n" + : + :"m" (cr), "r"(cb),"r"(lum), + "r"(row1),"r"(cols),"r"(row2),"m"(x),"m"(y),"m"(mod) + : "%ebx" + ); +} + +#endif /* GCC i386 inline assembly */ diff --git a/contrib/sdk/sources/SDL-1.2.2/src/video/SDL_yuv_sw.c b/contrib/sdk/sources/SDL-1.2.2/src/video/SDL_yuv_sw.c new file mode 100644 index 000000000..00e82a56c --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/src/video/SDL_yuv_sw.c @@ -0,0 +1,1316 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997, 1998, 1999, 2000, 2001 Sam Lantinga + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the Free + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + Sam Lantinga + slouken@devolution.com +*/ + +#ifdef SAVE_RCSID +static char rcsid = + "@(#) $Id: SDL_yuv_sw.c,v 1.3 2001/04/27 20:25:25 hercules Exp $"; +#endif + +/* This is the software implementation of the YUV video overlay support */ + +/* This code was derived from code carrying the following copyright notices: + + * Copyright (c) 1995 The Regents of the University of California. + * All rights reserved. + * + * Permission to use, copy, modify, and distribute this software and its + * documentation for any purpose, without fee, and without written agreement is + * hereby granted, provided that the above copyright notice and the following + * two paragraphs appear in all copies of this software. + * + * IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR + * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT + * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF + * CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS + * ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATION TO + * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + + * Copyright (c) 1995 Erik Corry + * All rights reserved. + * + * Permission to use, copy, modify, and distribute this software and its + * documentation for any purpose, without fee, and without written agreement is + * hereby granted, provided that the above copyright notice and the following + * two paragraphs appear in all copies of this software. + * + * IN NO EVENT SHALL ERIK CORRY BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, + * SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OF + * THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF ERIK CORRY HAS BEEN ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * + * ERIK CORRY SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" + * BASIS, AND ERIK CORRY HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, + * UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + + * Portions of this software Copyright (c) 1995 Brown University. + * All rights reserved. + * + * Permission to use, copy, modify, and distribute this software and its + * documentation for any purpose, without fee, and without written agreement + * is hereby granted, provided that the above copyright notice and the + * following two paragraphs appear in all copies of this software. + * + * IN NO EVENT SHALL BROWN UNIVERSITY BE LIABLE TO ANY PARTY FOR + * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT + * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF BROWN + * UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * BROWN UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS" + * BASIS, AND BROWN UNIVERSITY HAS NO OBLIGATION TO PROVIDE MAINTENANCE, + * SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + */ + +#include +#include + +#include "SDL_error.h" +#include "SDL_video.h" +#include "SDL_stretch_c.h" +#include "SDL_yuvfuncs.h" +#include "SDL_yuv_sw_c.h" + +/* Function to check the CPU flags */ +#define MMX_CPU 0x800000 +#ifdef USE_ASMBLIT +#define CPU_Flags() Hermes_X86_CPU() +#else +#define CPU_Flags() 0L +#endif + +#ifdef USE_ASMBLIT +#define X86_ASSEMBLER +#define HermesConverterInterface void +#define HermesClearInterface void +#define STACKCALL +typedef Uint32 int32; + +#include "HeadX86.h" +#endif + +/* The functions used to manipulate software video overlays */ +static struct private_yuvhwfuncs sw_yuvfuncs = { + SDL_LockYUV_SW, + SDL_UnlockYUV_SW, + SDL_DisplayYUV_SW, + SDL_FreeYUV_SW +}; + +/* RGB conversion lookup tables */ +struct private_yuvhwdata { + SDL_Surface *stretch; + SDL_Surface *display; + Uint8 *pixels; + int *colortab; + Uint32 *rgb_2_pix; + void (*Display1X)(int *colortab, Uint32 *rgb_2_pix, + unsigned char *lum, unsigned char *cr, + unsigned char *cb, unsigned char *out, + int rows, int cols, int mod ); + void (*Display2X)(int *colortab, Uint32 *rgb_2_pix, + unsigned char *lum, unsigned char *cr, + unsigned char *cb, unsigned char *out, + int rows, int cols, int mod ); + + /* These are just so we don't have to allocate them separately */ + Uint16 pitches[3]; + Uint8 *planes[3]; +}; + + +/* The colorspace conversion functions */ + +extern void Color565DitherYV12MMX1X( int *colortab, Uint32 *rgb_2_pix, + unsigned char *lum, unsigned char *cr, + unsigned char *cb, unsigned char *out, + int rows, int cols, int mod ); +extern void ColorRGBDitherYV12MMX1X( int *colortab, Uint32 *rgb_2_pix, + unsigned char *lum, unsigned char *cr, + unsigned char *cb, unsigned char *out, + int rows, int cols, int mod ); + +static void Color16DitherYV12Mod1X( int *colortab, Uint32 *rgb_2_pix, + unsigned char *lum, unsigned char *cr, + unsigned char *cb, unsigned char *out, + int rows, int cols, int mod ) +{ + unsigned short* row1; + unsigned short* row2; + unsigned char* lum2; + int x, y; + int cr_r; + int crb_g; + int cb_b; + int cols_2 = cols / 2; + + row1 = (unsigned short*) out; + row2 = row1 + cols + mod; + lum2 = lum + cols; + + mod += cols + mod; + + y = rows / 2; + while( y-- ) + { + x = cols_2; + while( x-- ) + { + register int L; + + cr_r = 0*768+256 + colortab[ *cr + 0*256 ]; + crb_g = 1*768+256 + colortab[ *cr + 1*256 ] + + colortab[ *cb + 2*256 ]; + cb_b = 2*768+256 + colortab[ *cb + 3*256 ]; + ++cr; ++cb; + + L = *lum++; + *row1++ = (rgb_2_pix[ L + cr_r ] | + rgb_2_pix[ L + crb_g ] | + rgb_2_pix[ L + cb_b ]); + + L = *lum++; + *row1++ = (rgb_2_pix[ L + cr_r ] | + rgb_2_pix[ L + crb_g ] | + rgb_2_pix[ L + cb_b ]); + + + /* Now, do second row. */ + + L = *lum2++; + *row2++ = (rgb_2_pix[ L + cr_r ] | + rgb_2_pix[ L + crb_g ] | + rgb_2_pix[ L + cb_b ]); + + L = *lum2++; + *row2++ = (rgb_2_pix[ L + cr_r ] | + rgb_2_pix[ L + crb_g ] | + rgb_2_pix[ L + cb_b ]); + } + + /* + * These values are at the start of the next line, (due + * to the ++'s above),but they need to be at the start + * of the line after that. + */ + lum += cols; + lum2 += cols; + row1 += mod; + row2 += mod; + } +} + +static void Color24DitherYV12Mod1X( int *colortab, Uint32 *rgb_2_pix, + unsigned char *lum, unsigned char *cr, + unsigned char *cb, unsigned char *out, + int rows, int cols, int mod ) +{ + unsigned int value; + unsigned char* row1; + unsigned char* row2; + unsigned char* lum2; + int x, y; + int cr_r; + int crb_g; + int cb_b; + int cols_2 = cols / 2; + + row1 = out; + row2 = row1 + cols*3 + mod*3; + lum2 = lum + cols; + + mod += cols + mod; + mod *= 3; + + y = rows / 2; + while( y-- ) + { + x = cols_2; + while( x-- ) + { + register int L; + + cr_r = 0*768+256 + colortab[ *cr + 0*256 ]; + crb_g = 1*768+256 + colortab[ *cr + 1*256 ] + + colortab[ *cb + 2*256 ]; + cb_b = 2*768+256 + colortab[ *cb + 3*256 ]; + ++cr; ++cb; + + L = *lum++; + value = (rgb_2_pix[ L + cr_r ] | + rgb_2_pix[ L + crb_g ] | + rgb_2_pix[ L + cb_b ]); + *row1++ = (value ) & 0xFF; + *row1++ = (value >> 8) & 0xFF; + *row1++ = (value >> 16) & 0xFF; + + L = *lum++; + value = (rgb_2_pix[ L + cr_r ] | + rgb_2_pix[ L + crb_g ] | + rgb_2_pix[ L + cb_b ]); + *row1++ = (value ) & 0xFF; + *row1++ = (value >> 8) & 0xFF; + *row1++ = (value >> 16) & 0xFF; + + + /* Now, do second row. */ + + L = *lum2++; + value = (rgb_2_pix[ L + cr_r ] | + rgb_2_pix[ L + crb_g ] | + rgb_2_pix[ L + cb_b ]); + *row2++ = (value ) & 0xFF; + *row2++ = (value >> 8) & 0xFF; + *row2++ = (value >> 16) & 0xFF; + + L = *lum2++; + value = (rgb_2_pix[ L + cr_r ] | + rgb_2_pix[ L + crb_g ] | + rgb_2_pix[ L + cb_b ]); + *row2++ = (value ) & 0xFF; + *row2++ = (value >> 8) & 0xFF; + *row2++ = (value >> 16) & 0xFF; + } + + /* + * These values are at the start of the next line, (due + * to the ++'s above),but they need to be at the start + * of the line after that. + */ + lum += cols; + lum2 += cols; + row1 += mod; + row2 += mod; + } +} + +static void Color32DitherYV12Mod1X( int *colortab, Uint32 *rgb_2_pix, + unsigned char *lum, unsigned char *cr, + unsigned char *cb, unsigned char *out, + int rows, int cols, int mod ) +{ + unsigned int* row1; + unsigned int* row2; + unsigned char* lum2; + int x, y; + int cr_r; + int crb_g; + int cb_b; + int cols_2 = cols / 2; + + row1 = (unsigned int*) out; + row2 = row1 + cols + mod; + lum2 = lum + cols; + + mod += cols + mod; + + y = rows / 2; + while( y-- ) + { + x = cols_2; + while( x-- ) + { + register int L; + + cr_r = 0*768+256 + colortab[ *cr + 0*256 ]; + crb_g = 1*768+256 + colortab[ *cr + 1*256 ] + + colortab[ *cb + 2*256 ]; + cb_b = 2*768+256 + colortab[ *cb + 3*256 ]; + ++cr; ++cb; + + L = *lum++; + *row1++ = (rgb_2_pix[ L + cr_r ] | + rgb_2_pix[ L + crb_g ] | + rgb_2_pix[ L + cb_b ]); + + L = *lum++; + *row1++ = (rgb_2_pix[ L + cr_r ] | + rgb_2_pix[ L + crb_g ] | + rgb_2_pix[ L + cb_b ]); + + + /* Now, do second row. */ + + L = *lum2++; + *row2++ = (rgb_2_pix[ L + cr_r ] | + rgb_2_pix[ L + crb_g ] | + rgb_2_pix[ L + cb_b ]); + + L = *lum2++; + *row2++ = (rgb_2_pix[ L + cr_r ] | + rgb_2_pix[ L + crb_g ] | + rgb_2_pix[ L + cb_b ]); + } + + /* + * These values are at the start of the next line, (due + * to the ++'s above),but they need to be at the start + * of the line after that. + */ + lum += cols; + lum2 += cols; + row1 += mod; + row2 += mod; + } +} + +/* + * In this function I make use of a nasty trick. The tables have the lower + * 16 bits replicated in the upper 16. This means I can write ints and get + * the horisontal doubling for free (almost). + */ +static void Color16DitherYV12Mod2X( int *colortab, Uint32 *rgb_2_pix, + unsigned char *lum, unsigned char *cr, + unsigned char *cb, unsigned char *out, + int rows, int cols, int mod ) +{ + unsigned int* row1 = (unsigned int*) out; + const int next_row = cols+(mod/2); + unsigned int* row2 = row1 + 2*next_row; + unsigned char* lum2; + int x, y; + int cr_r; + int crb_g; + int cb_b; + int cols_2 = cols / 2; + + lum2 = lum + cols; + + mod = (next_row * 3) + (mod/2); + + y = rows / 2; + while( y-- ) + { + x = cols_2; + while( x-- ) + { + register int L; + + cr_r = 0*768+256 + colortab[ *cr + 0*256 ]; + crb_g = 1*768+256 + colortab[ *cr + 1*256 ] + + colortab[ *cb + 2*256 ]; + cb_b = 2*768+256 + colortab[ *cb + 3*256 ]; + ++cr; ++cb; + + L = *lum++; + row1[0] = row1[next_row] = (rgb_2_pix[ L + cr_r ] | + rgb_2_pix[ L + crb_g ] | + rgb_2_pix[ L + cb_b ]); + row1++; + + L = *lum++; + row1[0] = row1[next_row] = (rgb_2_pix[ L + cr_r ] | + rgb_2_pix[ L + crb_g ] | + rgb_2_pix[ L + cb_b ]); + row1++; + + + /* Now, do second row. */ + + L = *lum2++; + row2[0] = row2[next_row] = (rgb_2_pix[ L + cr_r ] | + rgb_2_pix[ L + crb_g ] | + rgb_2_pix[ L + cb_b ]); + row2++; + + L = *lum2++; + row2[0] = row2[next_row] = (rgb_2_pix[ L + cr_r ] | + rgb_2_pix[ L + crb_g ] | + rgb_2_pix[ L + cb_b ]); + row2++; + } + + /* + * These values are at the start of the next line, (due + * to the ++'s above),but they need to be at the start + * of the line after that. + */ + lum += cols; + lum2 += cols; + row1 += mod; + row2 += mod; + } +} + +static void Color24DitherYV12Mod2X( int *colortab, Uint32 *rgb_2_pix, + unsigned char *lum, unsigned char *cr, + unsigned char *cb, unsigned char *out, + int rows, int cols, int mod ) +{ + unsigned int value; + unsigned char* row1 = out; + const int next_row = (cols*2 + mod) * 3; + unsigned char* row2 = row1 + 2*next_row; + unsigned char* lum2; + int x, y; + int cr_r; + int crb_g; + int cb_b; + int cols_2 = cols / 2; + + lum2 = lum + cols; + + mod = next_row*3 + mod*3; + + y = rows / 2; + while( y-- ) + { + x = cols_2; + while( x-- ) + { + register int L; + + cr_r = 0*768+256 + colortab[ *cr + 0*256 ]; + crb_g = 1*768+256 + colortab[ *cr + 1*256 ] + + colortab[ *cb + 2*256 ]; + cb_b = 2*768+256 + colortab[ *cb + 3*256 ]; + ++cr; ++cb; + + L = *lum++; + value = (rgb_2_pix[ L + cr_r ] | + rgb_2_pix[ L + crb_g ] | + rgb_2_pix[ L + cb_b ]); + row1[0+0] = row1[3+0] = row1[next_row+0] = row1[next_row+3+0] = + (value ) & 0xFF; + row1[0+1] = row1[3+1] = row1[next_row+1] = row1[next_row+3+1] = + (value >> 8) & 0xFF; + row1[0+2] = row1[3+2] = row1[next_row+2] = row1[next_row+3+2] = + (value >> 16) & 0xFF; + row1 += 2*3; + + L = *lum++; + value = (rgb_2_pix[ L + cr_r ] | + rgb_2_pix[ L + crb_g ] | + rgb_2_pix[ L + cb_b ]); + row1[0+0] = row1[3+0] = row1[next_row+0] = row1[next_row+3+0] = + (value ) & 0xFF; + row1[0+1] = row1[3+1] = row1[next_row+1] = row1[next_row+3+1] = + (value >> 8) & 0xFF; + row1[0+2] = row1[3+2] = row1[next_row+2] = row1[next_row+3+2] = + (value >> 16) & 0xFF; + row1 += 2*3; + + + /* Now, do second row. */ + + L = *lum2++; + value = (rgb_2_pix[ L + cr_r ] | + rgb_2_pix[ L + crb_g ] | + rgb_2_pix[ L + cb_b ]); + row2[0+0] = row2[3+0] = row2[next_row+0] = row2[next_row+3+0] = + (value ) & 0xFF; + row2[0+1] = row2[3+1] = row2[next_row+1] = row2[next_row+3+1] = + (value >> 8) & 0xFF; + row2[0+2] = row2[3+2] = row2[next_row+2] = row2[next_row+3+2] = + (value >> 16) & 0xFF; + row2 += 2*3; + + L = *lum2++; + value = (rgb_2_pix[ L + cr_r ] | + rgb_2_pix[ L + crb_g ] | + rgb_2_pix[ L + cb_b ]); + row2[0+0] = row2[3+0] = row2[next_row+0] = row2[next_row+3+0] = + (value ) & 0xFF; + row2[0+1] = row2[3+1] = row2[next_row+1] = row2[next_row+3+1] = + (value >> 8) & 0xFF; + row2[0+2] = row2[3+2] = row2[next_row+2] = row2[next_row+3+2] = + (value >> 16) & 0xFF; + row2 += 2*3; + } + + /* + * These values are at the start of the next line, (due + * to the ++'s above),but they need to be at the start + * of the line after that. + */ + lum += cols; + lum2 += cols; + row1 += mod; + row2 += mod; + } +} + +static void Color32DitherYV12Mod2X( int *colortab, Uint32 *rgb_2_pix, + unsigned char *lum, unsigned char *cr, + unsigned char *cb, unsigned char *out, + int rows, int cols, int mod ) +{ + unsigned int* row1 = (unsigned int*) out; + const int next_row = cols*2+mod; + unsigned int* row2 = row1 + 2*next_row; + unsigned char* lum2; + int x, y; + int cr_r; + int crb_g; + int cb_b; + int cols_2 = cols / 2; + + lum2 = lum + cols; + + mod = (next_row * 3) + mod; + + y = rows / 2; + while( y-- ) + { + x = cols_2; + while( x-- ) + { + register int L; + + cr_r = 0*768+256 + colortab[ *cr + 0*256 ]; + crb_g = 1*768+256 + colortab[ *cr + 1*256 ] + + colortab[ *cb + 2*256 ]; + cb_b = 2*768+256 + colortab[ *cb + 3*256 ]; + ++cr; ++cb; + + L = *lum++; + row1[0] = row1[1] = row1[next_row] = row1[next_row+1] = + (rgb_2_pix[ L + cr_r ] | + rgb_2_pix[ L + crb_g ] | + rgb_2_pix[ L + cb_b ]); + row1 += 2; + + L = *lum++; + row1[0] = row1[1] = row1[next_row] = row1[next_row+1] = + (rgb_2_pix[ L + cr_r ] | + rgb_2_pix[ L + crb_g ] | + rgb_2_pix[ L + cb_b ]); + row1 += 2; + + + /* Now, do second row. */ + + L = *lum2++; + row2[0] = row2[1] = row2[next_row] = row2[next_row+1] = + (rgb_2_pix[ L + cr_r ] | + rgb_2_pix[ L + crb_g ] | + rgb_2_pix[ L + cb_b ]); + row2 += 2; + + L = *lum2++; + row2[0] = row2[1] = row2[next_row] = row2[next_row+1] = + (rgb_2_pix[ L + cr_r ] | + rgb_2_pix[ L + crb_g ] | + rgb_2_pix[ L + cb_b ]); + row2 += 2; + } + + /* + * These values are at the start of the next line, (due + * to the ++'s above),but they need to be at the start + * of the line after that. + */ + lum += cols; + lum2 += cols; + row1 += mod; + row2 += mod; + } +} + +static void Color16DitherYUY2Mod1X( int *colortab, Uint32 *rgb_2_pix, + unsigned char *lum, unsigned char *cr, + unsigned char *cb, unsigned char *out, + int rows, int cols, int mod ) +{ + unsigned short* row; + int x, y; + int cr_r; + int crb_g; + int cb_b; + int cols_2 = cols / 2; + + row = (unsigned short*) out; + + y = rows; + while( y-- ) + { + x = cols_2; + while( x-- ) + { + register int L; + + cr_r = 0*768+256 + colortab[ *cr + 0*256 ]; + crb_g = 1*768+256 + colortab[ *cr + 1*256 ] + + colortab[ *cb + 2*256 ]; + cb_b = 2*768+256 + colortab[ *cb + 3*256 ]; + cr += 4; cb += 4; + + L = *lum; lum += 2; + *row++ = (rgb_2_pix[ L + cr_r ] | + rgb_2_pix[ L + crb_g ] | + rgb_2_pix[ L + cb_b ]); + + L = *lum; lum += 2; + *row++ = (rgb_2_pix[ L + cr_r ] | + rgb_2_pix[ L + crb_g ] | + rgb_2_pix[ L + cb_b ]); + + } + + row += mod; + } +} + +static void Color24DitherYUY2Mod1X( int *colortab, Uint32 *rgb_2_pix, + unsigned char *lum, unsigned char *cr, + unsigned char *cb, unsigned char *out, + int rows, int cols, int mod ) +{ + unsigned int value; + unsigned char* row; + int x, y; + int cr_r; + int crb_g; + int cb_b; + int cols_2 = cols / 2; + + row = (unsigned char*) out; + mod *= 3; + y = rows; + while( y-- ) + { + x = cols_2; + while( x-- ) + { + register int L; + + cr_r = 0*768+256 + colortab[ *cr + 0*256 ]; + crb_g = 1*768+256 + colortab[ *cr + 1*256 ] + + colortab[ *cb + 2*256 ]; + cb_b = 2*768+256 + colortab[ *cb + 3*256 ]; + cr += 4; cb += 4; + + L = *lum; lum += 2; + value = (rgb_2_pix[ L + cr_r ] | + rgb_2_pix[ L + crb_g ] | + rgb_2_pix[ L + cb_b ]); + *row++ = (value ) & 0xFF; + *row++ = (value >> 8) & 0xFF; + *row++ = (value >> 16) & 0xFF; + + L = *lum; lum += 2; + value = (rgb_2_pix[ L + cr_r ] | + rgb_2_pix[ L + crb_g ] | + rgb_2_pix[ L + cb_b ]); + *row++ = (value ) & 0xFF; + *row++ = (value >> 8) & 0xFF; + *row++ = (value >> 16) & 0xFF; + + } + row += mod; + } +} + +static void Color32DitherYUY2Mod1X( int *colortab, Uint32 *rgb_2_pix, + unsigned char *lum, unsigned char *cr, + unsigned char *cb, unsigned char *out, + int rows, int cols, int mod ) +{ + unsigned int* row; + int x, y; + int cr_r; + int crb_g; + int cb_b; + int cols_2 = cols / 2; + + row = (unsigned int*) out; + y = rows; + while( y-- ) + { + x = cols_2; + while( x-- ) + { + register int L; + + cr_r = 0*768+256 + colortab[ *cr + 0*256 ]; + crb_g = 1*768+256 + colortab[ *cr + 1*256 ] + + colortab[ *cb + 2*256 ]; + cb_b = 2*768+256 + colortab[ *cb + 3*256 ]; + cr += 4; cb += 4; + + L = *lum; lum += 2; + *row++ = (rgb_2_pix[ L + cr_r ] | + rgb_2_pix[ L + crb_g ] | + rgb_2_pix[ L + cb_b ]); + + L = *lum; lum += 2; + *row++ = (rgb_2_pix[ L + cr_r ] | + rgb_2_pix[ L + crb_g ] | + rgb_2_pix[ L + cb_b ]); + + + } + row += mod; + } +} + +/* + * In this function I make use of a nasty trick. The tables have the lower + * 16 bits replicated in the upper 16. This means I can write ints and get + * the horisontal doubling for free (almost). + */ +static void Color16DitherYUY2Mod2X( int *colortab, Uint32 *rgb_2_pix, + unsigned char *lum, unsigned char *cr, + unsigned char *cb, unsigned char *out, + int rows, int cols, int mod ) +{ + unsigned int* row = (unsigned int*) out; + const int next_row = cols+(mod/2); + int x, y; + int cr_r; + int crb_g; + int cb_b; + int cols_2 = cols / 2; + + y = rows; + while( y-- ) + { + x = cols_2; + while( x-- ) + { + register int L; + + cr_r = 0*768+256 + colortab[ *cr + 0*256 ]; + crb_g = 1*768+256 + colortab[ *cr + 1*256 ] + + colortab[ *cb + 2*256 ]; + cb_b = 2*768+256 + colortab[ *cb + 3*256 ]; + cr += 4; cb += 4; + + L = *lum; lum += 2; + row[0] = row[next_row] = (rgb_2_pix[ L + cr_r ] | + rgb_2_pix[ L + crb_g ] | + rgb_2_pix[ L + cb_b ]); + row++; + + L = *lum; lum += 2; + row[0] = row[next_row] = (rgb_2_pix[ L + cr_r ] | + rgb_2_pix[ L + crb_g ] | + rgb_2_pix[ L + cb_b ]); + row++; + + } + row += next_row; + } +} + +static void Color24DitherYUY2Mod2X( int *colortab, Uint32 *rgb_2_pix, + unsigned char *lum, unsigned char *cr, + unsigned char *cb, unsigned char *out, + int rows, int cols, int mod ) +{ + unsigned int value; + unsigned char* row = out; + const int next_row = (cols*2 + mod) * 3; + int x, y; + int cr_r; + int crb_g; + int cb_b; + int cols_2 = cols / 2; + y = rows; + while( y-- ) + { + x = cols_2; + while( x-- ) + { + register int L; + + cr_r = 0*768+256 + colortab[ *cr + 0*256 ]; + crb_g = 1*768+256 + colortab[ *cr + 1*256 ] + + colortab[ *cb + 2*256 ]; + cb_b = 2*768+256 + colortab[ *cb + 3*256 ]; + cr += 4; cb += 4; + + L = *lum; lum += 2; + value = (rgb_2_pix[ L + cr_r ] | + rgb_2_pix[ L + crb_g ] | + rgb_2_pix[ L + cb_b ]); + row[0+0] = row[3+0] = row[next_row+0] = row[next_row+3+0] = + (value ) & 0xFF; + row[0+1] = row[3+1] = row[next_row+1] = row[next_row+3+1] = + (value >> 8) & 0xFF; + row[0+2] = row[3+2] = row[next_row+2] = row[next_row+3+2] = + (value >> 16) & 0xFF; + row += 2*3; + + L = *lum; lum += 2; + value = (rgb_2_pix[ L + cr_r ] | + rgb_2_pix[ L + crb_g ] | + rgb_2_pix[ L + cb_b ]); + row[0+0] = row[3+0] = row[next_row+0] = row[next_row+3+0] = + (value ) & 0xFF; + row[0+1] = row[3+1] = row[next_row+1] = row[next_row+3+1] = + (value >> 8) & 0xFF; + row[0+2] = row[3+2] = row[next_row+2] = row[next_row+3+2] = + (value >> 16) & 0xFF; + row += 2*3; + + } + row += next_row; + } +} + +static void Color32DitherYUY2Mod2X( int *colortab, Uint32 *rgb_2_pix, + unsigned char *lum, unsigned char *cr, + unsigned char *cb, unsigned char *out, + int rows, int cols, int mod ) +{ + unsigned int* row = (unsigned int*) out; + const int next_row = cols*2+mod; + int x, y; + int cr_r; + int crb_g; + int cb_b; + int cols_2 = cols / 2; + mod+=mod; + y = rows; + while( y-- ) + { + x = cols_2; + while( x-- ) + { + register int L; + + cr_r = 0*768+256 + colortab[ *cr + 0*256 ]; + crb_g = 1*768+256 + colortab[ *cr + 1*256 ] + + colortab[ *cb + 2*256 ]; + cb_b = 2*768+256 + colortab[ *cb + 3*256 ]; + cr += 4; cb += 4; + + L = *lum; lum += 2; + row[0] = row[1] = row[next_row] = row[next_row+1] = + (rgb_2_pix[ L + cr_r ] | + rgb_2_pix[ L + crb_g ] | + rgb_2_pix[ L + cb_b ]); + row += 2; + + L = *lum; lum += 2; + row[0] = row[1] = row[next_row] = row[next_row+1] = + (rgb_2_pix[ L + cr_r ] | + rgb_2_pix[ L + crb_g ] | + rgb_2_pix[ L + cb_b ]); + row += 2; + + + } + + row += next_row; + } +} + +/* + * How many 1 bits are there in the Uint32. + * Low performance, do not call often. + */ +static int number_of_bits_set( Uint32 a ) +{ + if(!a) return 0; + if(a & 1) return 1 + number_of_bits_set(a >> 1); + return(number_of_bits_set(a >> 1)); +} + +/* + * How many 0 bits are there at least significant end of Uint32. + * Low performance, do not call often. + */ +static int free_bits_at_bottom( Uint32 a ) +{ + /* assume char is 8 bits */ + if(!a) return sizeof(Uint32) * 8; + if(((Sint32)a) & 1l) return 0; + return 1 + free_bits_at_bottom ( a >> 1); +} + + +SDL_Overlay *SDL_CreateYUV_SW(_THIS, int width, int height, Uint32 format, SDL_Surface *display) +{ + SDL_Overlay *overlay; + struct private_yuvhwdata *swdata; + int *Cr_r_tab; + int *Cr_g_tab; + int *Cb_g_tab; + int *Cb_b_tab; + Uint32 *r_2_pix_alloc; + Uint32 *g_2_pix_alloc; + Uint32 *b_2_pix_alloc; + int i, cpu_mmx; + int CR, CB; + Uint32 Rmask, Gmask, Bmask; + + /* Only RGB packed pixel conversion supported */ + if ( (display->format->BytesPerPixel != 2) && + (display->format->BytesPerPixel != 3) && + (display->format->BytesPerPixel != 4) ) { + SDL_SetError("Can't use YUV data on non 16/24/32 bit surfaces"); + return(NULL); + } + + /* Verify that we support the format */ + switch (format) { + case SDL_YV12_OVERLAY: + case SDL_IYUV_OVERLAY: + case SDL_YUY2_OVERLAY: + case SDL_UYVY_OVERLAY: + case SDL_YVYU_OVERLAY: + break; + default: + SDL_SetError("Unsupported YUV format"); + return(NULL); + } + + /* Create the overlay structure */ + overlay = (SDL_Overlay *)malloc(sizeof *overlay); + if ( overlay == NULL ) { + SDL_OutOfMemory(); + return(NULL); + } + memset(overlay, 0, (sizeof *overlay)); + + /* Fill in the basic members */ + overlay->format = format; + overlay->w = width; + overlay->h = height; + + /* Set up the YUV surface function structure */ + overlay->hwfuncs = &sw_yuvfuncs; + + /* Create the pixel data and lookup tables */ + swdata = (struct private_yuvhwdata *)malloc(sizeof *swdata); + overlay->hwdata = swdata; + if ( swdata == NULL ) { + SDL_OutOfMemory(); + SDL_FreeYUVOverlay(overlay); + return(NULL); + } + swdata->stretch = NULL; + swdata->display = display; + swdata->pixels = (Uint8 *) malloc(width*height*2); + swdata->colortab = (int *)malloc(4*256*sizeof(int)); + Cr_r_tab = &swdata->colortab[0*256]; + Cr_g_tab = &swdata->colortab[1*256]; + Cb_g_tab = &swdata->colortab[2*256]; + Cb_b_tab = &swdata->colortab[3*256]; + swdata->rgb_2_pix = (Uint32 *)malloc(3*768*sizeof(Uint32)); + r_2_pix_alloc = &swdata->rgb_2_pix[0*768]; + g_2_pix_alloc = &swdata->rgb_2_pix[1*768]; + b_2_pix_alloc = &swdata->rgb_2_pix[2*768]; + if ( ! swdata->pixels || ! swdata->colortab || ! swdata->rgb_2_pix ) { + SDL_OutOfMemory(); + SDL_FreeYUVOverlay(overlay); + return(NULL); + } + + /* Generate the tables for the display surface */ + for (i=0; i<256; i++) { + /* Gamma correction (luminescence table) and chroma correction + would be done here. See the Berkeley mpeg_play sources. + */ + CB = CR = (i-128); + Cr_r_tab[i] = (int) ( (0.419/0.299) * CR); + Cr_g_tab[i] = (int) (-(0.299/0.419) * CR); + Cb_g_tab[i] = (int) (-(0.114/0.331) * CB); + Cb_b_tab[i] = (int) ( (0.587/0.331) * CB); + } + + /* + * Set up entries 0-255 in rgb-to-pixel value tables. + */ + Rmask = display->format->Rmask; + Gmask = display->format->Gmask; + Bmask = display->format->Bmask; + for ( i=0; i<256; ++i ) { + r_2_pix_alloc[i+256] = i >> (8 - number_of_bits_set(Rmask)); + r_2_pix_alloc[i+256] <<= free_bits_at_bottom(Rmask); + g_2_pix_alloc[i+256] = i >> (8 - number_of_bits_set(Gmask)); + g_2_pix_alloc[i+256] <<= free_bits_at_bottom(Gmask); + b_2_pix_alloc[i+256] = i >> (8 - number_of_bits_set(Bmask)); + b_2_pix_alloc[i+256] <<= free_bits_at_bottom(Bmask); + } + + /* + * If we have 16-bit output depth, then we double the value + * in the top word. This means that we can write out both + * pixels in the pixel doubling mode with one op. It is + * harmless in the normal case as storing a 32-bit value + * through a short pointer will lose the top bits anyway. + */ + if( display->format->BytesPerPixel == 2 ) { + for ( i=0; i<256; ++i ) { + r_2_pix_alloc[i+256] |= (r_2_pix_alloc[i+256]) << 16; + g_2_pix_alloc[i+256] |= (g_2_pix_alloc[i+256]) << 16; + b_2_pix_alloc[i+256] |= (b_2_pix_alloc[i+256]) << 16; + } + } + + /* + * Spread out the values we have to the rest of the array so that + * we do not need to check for overflow. + */ + for ( i=0; i<256; ++i ) { + r_2_pix_alloc[i] = r_2_pix_alloc[256]; + r_2_pix_alloc[i+512] = r_2_pix_alloc[511]; + g_2_pix_alloc[i] = g_2_pix_alloc[256]; + g_2_pix_alloc[i+512] = g_2_pix_alloc[511]; + b_2_pix_alloc[i] = b_2_pix_alloc[256]; + b_2_pix_alloc[i+512] = b_2_pix_alloc[511]; + } + + /* You have chosen wisely... */ + switch (format) { + case SDL_YV12_OVERLAY: + case SDL_IYUV_OVERLAY: + cpu_mmx = CPU_Flags() & MMX_CPU; + if ( display->format->BytesPerPixel == 2 ) { +#if defined(i386) && defined(__GNUC__) && defined(USE_ASMBLIT) + /* inline assembly functions */ + if ( cpu_mmx && (Rmask == 0xF800) && + (Gmask == 0x07E0) && + (Bmask == 0x001F) && + (width & 15) == 0) { +/*printf("Using MMX 16-bit 565 dither\n");*/ + swdata->Display1X = Color565DitherYV12MMX1X; + } else { +/*printf("Using C 16-bit dither\n");*/ + swdata->Display1X = Color16DitherYV12Mod1X; + } +#else + swdata->Display1X = Color16DitherYV12Mod1X; +#endif + swdata->Display2X = Color16DitherYV12Mod2X; + } + if ( display->format->BytesPerPixel == 3 ) { + swdata->Display1X = Color24DitherYV12Mod1X; + swdata->Display2X = Color24DitherYV12Mod2X; + } + if ( display->format->BytesPerPixel == 4 ) { +#if defined(i386) && defined(__GNUC__) && defined(USE_ASMBLIT) + /* inline assembly functions */ + if ( cpu_mmx && (Rmask == 0x00FF0000) && + (Gmask == 0x0000FF00) && + (Bmask == 0x000000FF) && + (width & 15) == 0) { +/*printf("Using MMX 32-bit dither\n");*/ + swdata->Display1X = ColorRGBDitherYV12MMX1X; + } else { +/*printf("Using C 32-bit dither\n");*/ + swdata->Display1X = Color32DitherYV12Mod1X; + } +#else + swdata->Display1X = Color32DitherYV12Mod1X; +#endif + swdata->Display2X = Color32DitherYV12Mod2X; + } + break; + case SDL_YUY2_OVERLAY: + case SDL_UYVY_OVERLAY: + case SDL_YVYU_OVERLAY: + if ( display->format->BytesPerPixel == 2 ) { + swdata->Display1X = Color16DitherYUY2Mod1X; + swdata->Display2X = Color16DitherYUY2Mod2X; + } + if ( display->format->BytesPerPixel == 3 ) { + swdata->Display1X = Color24DitherYUY2Mod1X; + swdata->Display2X = Color24DitherYUY2Mod2X; + } + if ( display->format->BytesPerPixel == 4 ) { + swdata->Display1X = Color32DitherYUY2Mod1X; + swdata->Display2X = Color32DitherYUY2Mod2X; + } + break; + default: + /* We should never get here (caught above) */ + break; + } + + /* Find the pitch and offset values for the overlay */ + overlay->pitches = swdata->pitches; + overlay->pixels = swdata->planes; + switch (format) { + case SDL_YV12_OVERLAY: + case SDL_IYUV_OVERLAY: + overlay->pitches[0] = overlay->w; + overlay->pitches[1] = overlay->pitches[0] / 2; + overlay->pitches[2] = overlay->pitches[0] / 2; + overlay->pixels[0] = swdata->pixels; + overlay->pixels[1] = overlay->pixels[0] + + overlay->pitches[0] * overlay->h; + overlay->pixels[2] = overlay->pixels[1] + + overlay->pitches[1] * overlay->h / 2; + overlay->planes = 3; + break; + case SDL_YUY2_OVERLAY: + case SDL_UYVY_OVERLAY: + case SDL_YVYU_OVERLAY: + overlay->pitches[0] = overlay->w*2; + overlay->pixels[0] = swdata->pixels; + overlay->planes = 1; + break; + default: + /* We should never get here (caught above) */ + break; + } + + /* We're all done.. */ + return(overlay); +} + +int SDL_LockYUV_SW(_THIS, SDL_Overlay *overlay) +{ + return(0); +} + +void SDL_UnlockYUV_SW(_THIS, SDL_Overlay *overlay) +{ + return; +} + +int SDL_DisplayYUV_SW(_THIS, SDL_Overlay *overlay, SDL_Rect *dstrect) +{ + struct private_yuvhwdata *swdata; + SDL_Surface *stretch; + SDL_Surface *display; + int scale_2x; + Uint8 *lum, *Cr, *Cb; + Uint8 *dst; + int mod; + + swdata = overlay->hwdata; + scale_2x = 0; + stretch = 0; + if ( (overlay->w != dstrect->w) || (overlay->h != dstrect->h) ) { + if ( (dstrect->w == 2*overlay->w) && + (dstrect->h == 2*overlay->h) ) { + scale_2x = 1; + } else { + if ( ! swdata->stretch ) { + display = swdata->display; + swdata->stretch = SDL_CreateRGBSurface( + SDL_SWSURFACE, + overlay->w, overlay->h, + display->format->BitsPerPixel, + display->format->Rmask, + display->format->Gmask, + display->format->Bmask, 0); + if ( ! swdata->stretch ) { + return(-1); + } + } + stretch = swdata->stretch; + } + } + + if ( stretch ) { + display = stretch; + } else { + display = swdata->display; + } + switch (overlay->format) { + case SDL_YV12_OVERLAY: + lum = overlay->pixels[0]; + Cr = overlay->pixels[1]; + Cb = overlay->pixels[2]; + break; + case SDL_IYUV_OVERLAY: + lum = overlay->pixels[0]; + Cr = overlay->pixels[2]; + Cb = overlay->pixels[1]; + break; + case SDL_YUY2_OVERLAY: + lum = overlay->pixels[0]; + Cr = lum + 3; + Cb = lum + 1; + break; + case SDL_UYVY_OVERLAY: + lum = overlay->pixels[0]+1; + Cr = lum + 1; + Cb = lum - 1; + break; + case SDL_YVYU_OVERLAY: + lum = overlay->pixels[0]; + Cr = lum + 1; + Cb = lum + 3; + break; + default: + SDL_SetError("Unsupported YUV format in blit (??)"); + return(-1); + } + if ( SDL_MUSTLOCK(display) ) { + if ( SDL_LockSurface(display) < 0 ) { + return(-1); + } + } + if ( stretch ) { + dst = (Uint8 *)stretch->pixels; + } else { + dst = (Uint8 *)display->pixels + + dstrect->x * display->format->BytesPerPixel + + dstrect->y * display->pitch; + } + mod = (display->pitch / display->format->BytesPerPixel); + + if ( scale_2x ) { + mod -= (overlay->w * 2); + swdata->Display2X(swdata->colortab, swdata->rgb_2_pix, + lum, Cr, Cb, dst, overlay->h, overlay->w,mod); + } else { + mod -= overlay->w; + swdata->Display1X(swdata->colortab, swdata->rgb_2_pix, + lum, Cr, Cb, dst, overlay->h, overlay->w,mod); + } + if ( SDL_MUSTLOCK(display) ) { + SDL_UnlockSurface(display); + } + if ( stretch ) { + display = swdata->display; + SDL_SoftStretch(stretch, NULL, display, dstrect); + } + SDL_UpdateRects(display, 1, dstrect); + + return(0); +} + +void SDL_FreeYUV_SW(_THIS, SDL_Overlay *overlay) +{ + struct private_yuvhwdata *swdata; + + swdata = overlay->hwdata; + if ( swdata ) { + if ( swdata->stretch ) { + SDL_FreeSurface(swdata->stretch); + } + if ( swdata->pixels ) { + free(swdata->pixels); + } + if ( swdata->colortab ) { + free(swdata->colortab); + } + if ( swdata->rgb_2_pix ) { + free(swdata->rgb_2_pix); + } + free(swdata); + } +} diff --git a/contrib/sdk/sources/SDL-1.2.2/src/video/SDL_yuv_sw_c.h b/contrib/sdk/sources/SDL-1.2.2/src/video/SDL_yuv_sw_c.h new file mode 100644 index 000000000..3930d9521 --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/src/video/SDL_yuv_sw_c.h @@ -0,0 +1,41 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997, 1998, 1999, 2000, 2001 Sam Lantinga + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the Free + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + Sam Lantinga + slouken@devolution.com +*/ + +#ifdef SAVE_RCSID +static char rcsid = + "@(#) $Id: SDL_yuv_sw_c.h,v 1.2 2001/04/26 16:50:18 hercules Exp $"; +#endif + +#include "SDL_video.h" +#include "SDL_sysvideo.h" + +/* This is the software implementation of the YUV video overlay support */ + +extern SDL_Overlay *SDL_CreateYUV_SW(_THIS, int width, int height, Uint32 format, SDL_Surface *display); + +extern int SDL_LockYUV_SW(_THIS, SDL_Overlay *overlay); + +extern void SDL_UnlockYUV_SW(_THIS, SDL_Overlay *overlay); + +extern int SDL_DisplayYUV_SW(_THIS, SDL_Overlay *overlay, SDL_Rect *dstrect); + +extern void SDL_FreeYUV_SW(_THIS, SDL_Overlay *overlay); diff --git a/contrib/sdk/sources/SDL-1.2.2/src/video/SDL_yuvfuncs.h b/contrib/sdk/sources/SDL-1.2.2/src/video/SDL_yuvfuncs.h new file mode 100644 index 000000000..34b6a45f6 --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/src/video/SDL_yuvfuncs.h @@ -0,0 +1,41 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997, 1998, 1999, 2000, 2001 Sam Lantinga + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the Free + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + Sam Lantinga + slouken@devolution.com +*/ + +#ifdef SAVE_RCSID +static char rcsid = + "@(#) $Id: SDL_yuvfuncs.h,v 1.2 2001/04/26 16:50:18 hercules Exp $"; +#endif + +/* This is the definition of the YUV video surface function structure */ + +#include "SDL_video.h" +#include "SDL_sysvideo.h" + +#ifndef _THIS +#define _THIS SDL_VideoDevice *_this +#endif +struct private_yuvhwfuncs { + int (*Lock)(_THIS, SDL_Overlay *overlay); + void (*Unlock)(_THIS, SDL_Overlay *overlay); + int (*Display)(_THIS, SDL_Overlay *overlay, SDL_Rect *dstrect); + void (*FreeHW)(_THIS, SDL_Overlay *overlay); +}; diff --git a/contrib/sdk/sources/SDL-1.2.2/src/video/blank_cursor.h b/contrib/sdk/sources/SDL-1.2.2/src/video/blank_cursor.h new file mode 100644 index 000000000..09fe68b9e --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/src/video/blank_cursor.h @@ -0,0 +1,38 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997, 1998, 1999, 2000, 2001 Sam Lantinga + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the Free + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + Sam Lantinga + slouken@devolution.com +*/ + +#ifdef SAVE_RCSID +static char rcsid = + "@(#) $Id: blank_cursor.h,v 1.2 2001/04/26 16:50:18 hercules Exp $"; +#endif + +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * A default blank 8x8 cursor */ + +#define BLANK_CWIDTH 8 +#define BLANK_CHEIGHT 8 +#define BLANK_CHOTX 0 +#define BLANK_CHOTY 0 + +static unsigned char blank_cdata[8] = { 0, 0, 0, 0, 0, 0, 0, 0 }; +static unsigned char blank_cmask[8] = { 0, 0, 0, 0, 0, 0, 0, 0 }; + diff --git a/contrib/sdk/sources/SDL-1.2.2/src/video/default_cursor.h b/contrib/sdk/sources/SDL-1.2.2/src/video/default_cursor.h new file mode 100644 index 000000000..0f6f10801 --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/src/video/default_cursor.h @@ -0,0 +1,121 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997, 1998, 1999, 2000, 2001 Sam Lantinga + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the Free + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + Sam Lantinga + slouken@devolution.com +*/ + +#ifdef SAVE_RCSID +static char rcsid = + "@(#) $Id: default_cursor.h,v 1.3 2001/05/10 20:13:28 hercules Exp $"; +#endif + +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * Default cursor - it happens to be the Mac cursor, but could be anything */ + +#define DEFAULT_CWIDTH 16 +#define DEFAULT_CHEIGHT 16 +#define DEFAULT_CHOTX 0 +#define DEFAULT_CHOTY 0 + +/* Added a real MacOS cursor, at the request of Luc-Olivier de Charrière */ +#define USE_MACOS_CURSOR + +#ifdef USE_MACOS_CURSOR + +static unsigned char default_cdata[] = +{ + 0x00,0x00, + 0x40,0x00, + 0x60,0x00, + 0x70,0x00, + 0x78,0x00, + 0x7C,0x00, + 0x7E,0x00, + 0x7F,0x00, + 0x7F,0x80, + 0x7C,0x00, + 0x6C,0x00, + 0x46,0x00, + 0x06,0x00, + 0x03,0x00, + 0x03,0x00, + 0x00,0x00 +}; +static unsigned char default_cmask[] = +{ + 0xC0,0x00, + 0xE0,0x00, + 0xF0,0x00, + 0xF8,0x00, + 0xFC,0x00, + 0xFE,0x00, + 0xFF,0x00, + 0xFF,0x80, + 0xFF,0xC0, + 0xFF,0xE0, + 0xFE,0x00, + 0xEF,0x00, + 0xCF,0x00, + 0x87,0x80, + 0x07,0x80, + 0x03,0x00 +}; + +#else + +static unsigned char default_cdata[] = +{ + 0x00,0x00, + 0x40,0x00, + 0x60,0x00, + 0x70,0x00, + 0x78,0x00, + 0x7C,0x00, + 0x7E,0x00, + 0x7F,0x00, + 0x7F,0x80, + 0x7C,0x00, + 0x6C,0x00, + 0x46,0x00, + 0x06,0x00, + 0x03,0x00, + 0x03,0x00, + 0x00,0x00 +}; +static unsigned char default_cmask[] = +{ + 0x40,0x00, + 0xE0,0x00, + 0xF0,0x00, + 0xF8,0x00, + 0xFC,0x00, + 0xFE,0x00, + 0xFF,0x00, + 0xFF,0x80, + 0xFF,0xC0, + 0xFF,0x80, + 0xFE,0x00, + 0xEF,0x00, + 0x4F,0x00, + 0x07,0x80, + 0x07,0x80, + 0x03,0x00 +}; + +#endif /* TRUE_MACINTOSH_CURSOR */ diff --git a/contrib/sdk/sources/SDL-1.2.2/src/video/menuetos/SDL_menuetevents.c b/contrib/sdk/sources/SDL-1.2.2/src/video/menuetos/SDL_menuetevents.c new file mode 100644 index 000000000..a4e94e89d --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/src/video/menuetos/SDL_menuetevents.c @@ -0,0 +1,244 @@ +#include +#include +#include +#include "SDL.h" +#include "SDL_sysevents.h" +#include "SDL_sysvideo.h" +#include "SDL_events_c.h" +#include "SDL_menuetvideo.h" + +extern void MenuetOS_SDL_RepaintWnd(void); + +void MenuetOS_InitOSKeymap(_THIS) +{ + __asm__("int $0x40"::"a"(66),"b"(1),"c"(1)); +} + +#define LSHIFT 1 +#define RSHIFT 2 +#define LCTRL 4 +#define RCTRL 8 +#define LALT 0x10 +#define RALT 0x20 +#define CAPS 0x40 +#define NUML 0x80 +#define SCRL 0x100 + +#define SHIFT (LSHIFT+RSHIFT) +#define CTRL (LCTRL+RCTRL) +#define ALT (LALT+RALT) + +static SDLMod GetModState(void) +{ + unsigned controlstate; + __asm__("int $0x40":"=a"(controlstate):"a"(66),"b"(3)); + SDLMod res = 0; + if (controlstate & LSHIFT) + res |= KMOD_LSHIFT; + if (controlstate & RSHIFT) + res |= KMOD_RSHIFT; + if (controlstate & LCTRL) + res |= KMOD_LCTRL; + if (controlstate & RCTRL) + res |= KMOD_RCTRL; + if (controlstate & LALT) + res |= KMOD_LALT; + if (controlstate & RALT) + res |= KMOD_RALT; + if (controlstate & CAPS) + res |= KMOD_CAPS; + if (controlstate & NUML) + res |= KMOD_NUM; + return res; +} + +/*static __u8 scan2ascii(__u8 n,SDLMod mod) +{ + __u8 layout[128]; + int layouttype; + int bControlLayout = 0; + if (mod & KMOD_ALT) + layouttype = 3; + else if (mod & KMOD_SHIFT) + layouttype = 2; + else + { + if (mod & KMOD_CTRL) + bControlLayout = 1; + layouttype = 1; + } + __asm__("int $0x40" :: "a"(26),"b"(2),"c"(layouttype),"d"(layout)); + __u8 res = layout[n]; + if (bControlLayout) + res -= 0x60; + return res; +}*/ +static SDLKey sdlkeys[0x80] = +{ + // 0x0* + 0, SDLK_ESCAPE, SDLK_1, SDLK_2, SDLK_3, SDLK_4, SDLK_5, SDLK_6, + SDLK_7, SDLK_8, SDLK_9, SDLK_0, SDLK_MINUS, SDLK_EQUALS, SDLK_BACKSPACE, SDLK_TAB, + // 0x1* + SDLK_q, SDLK_w, SDLK_e, SDLK_r, SDLK_t, SDLK_y, SDLK_u, SDLK_i, + SDLK_o, SDLK_p, SDLK_LEFTBRACKET, SDLK_RIGHTBRACKET, SDLK_RETURN, SDLK_LCTRL, SDLK_a, SDLK_s, + // 0x2* + SDLK_d, SDLK_f, SDLK_g, SDLK_h, SDLK_j, SDLK_k, SDLK_l, SDLK_SEMICOLON, + SDLK_QUOTE, SDLK_BACKQUOTE, SDLK_LSHIFT, SDLK_BACKSLASH, SDLK_z, SDLK_x, SDLK_c, SDLK_v, + // 0x3* + SDLK_b, SDLK_n, SDLK_m, SDLK_COMMA, SDLK_PERIOD, SDLK_SLASH, SDLK_RSHIFT, SDLK_KP_MULTIPLY, + SDLK_LALT, SDLK_SPACE, SDLK_CAPSLOCK, SDLK_F1, SDLK_F2, SDLK_F3, SDLK_F4, SDLK_F5, + // 0x4* + SDLK_F6, SDLK_F7, SDLK_F8, SDLK_F9, SDLK_F10, SDLK_NUMLOCK, SDLK_SCROLLOCK, SDLK_KP7, + SDLK_KP8, SDLK_KP9, SDLK_KP_MINUS, SDLK_KP4, SDLK_KP5, SDLK_KP6, SDLK_KP_PLUS, SDLK_KP1, + // 0x5* + SDLK_KP2, SDLK_KP3, SDLK_KP0, SDLK_KP_PERIOD, 0, 0, 0, SDLK_F11, + SDLK_F12, 0, 0, 0, 0, 0, 0, 0, + // 0x6* + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + // 0x7* + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0 +}; +static SDLKey sdlkeys_shift[0x80] = +{ + // 0x0* + 0, SDLK_ESCAPE, SDLK_EXCLAIM, SDLK_AT, SDLK_HASH, SDLK_DOLLAR, '%', SDLK_CARET, + SDLK_AMPERSAND, SDLK_ASTERISK, SDLK_LEFTPAREN, SDLK_RIGHTPAREN, SDLK_UNDERSCORE, SDLK_PLUS, SDLK_BACKSPACE, SDLK_TAB, + // 0x1* + SDLK_q, SDLK_w, SDLK_e, SDLK_r, SDLK_t, SDLK_y, SDLK_u, SDLK_i, + SDLK_o, SDLK_p, '{', '}', SDLK_RETURN, SDLK_LCTRL, SDLK_a, SDLK_s, + // 0x2* + SDLK_d, SDLK_f, SDLK_g, SDLK_h, SDLK_j, SDLK_k, SDLK_l, SDLK_COLON, + SDLK_QUOTEDBL, '~', SDLK_LSHIFT, '|', SDLK_z, SDLK_x, SDLK_c, SDLK_v, + // 0x3* + SDLK_b, SDLK_n, SDLK_m, SDLK_LESS, SDLK_GREATER, SDLK_QUESTION, SDLK_RSHIFT, SDLK_KP_MULTIPLY, + SDLK_LALT, SDLK_SPACE, SDLK_CAPSLOCK, SDLK_F1, SDLK_F2, SDLK_F3, SDLK_F4, SDLK_F5, + // 0x4* + SDLK_F6, SDLK_F7, SDLK_F8, SDLK_F9, SDLK_F10, SDLK_NUMLOCK, SDLK_SCROLLOCK, SDLK_KP7, + SDLK_KP8, SDLK_KP9, SDLK_KP_MINUS, SDLK_KP4, SDLK_KP5, SDLK_KP6, SDLK_KP_PLUS, SDLK_KP1, + // 0x5* + SDLK_KP2, SDLK_KP3, SDLK_KP0, SDLK_KP_PERIOD, 0, 0, 0, SDLK_F11, + SDLK_F12, 0, 0, 0, 0, 0, 0, 0, + // 0x6* + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + // 0x7* + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0 +}; +static SDLKey sdlkeys_e0[0x80] = +{ + // 0x0* + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + // 0x1* + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, SDLK_KP_ENTER, SDLK_RCTRL, 0, 0, + // 0x2* + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + // 0x3* + 0, 0, 0, 0, 0, SDLK_KP_DIVIDE, 0, SDLK_PRINT, + SDLK_RALT, 0, 0, 0, 0, 0, 0, 0, + // 0x4* + 0, 0, 0, 0, 0, 0, 0, SDLK_HOME, + SDLK_UP, SDLK_PAGEUP, 0, SDLK_LEFT, 0, SDLK_RIGHT, 0, SDLK_END, + // 0x5* + SDLK_DOWN, SDLK_PAGEDOWN, SDLK_INSERT, SDLK_DELETE, 0, 0, 0, 0, + 0, 0, 0, SDLK_LSUPER, SDLK_RSUPER, SDLK_MENU, 0, 0, + // 0x6* + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + // 0x7* + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, +}; + +extern void KolibriOS_CheckMouseMode(_THIS); +void MenuetOS_PumpEvents(_THIS) +{ + int i; + SDL_keysym key; + static int ext_code=0; + static __u8 old_mode=0; + for (;;) { + i=__menuet__check_for_event(); + switch(i) + { + case 0: + return; + case 1: + MenuetOS_SDL_RepaintWnd(); + break; + case 2: + key.scancode = __menuet__getkey(); + if (key.scancode == 0xE0 || key.scancode == 0xE1) + {ext_code=key.scancode;break;} + if (ext_code == 0xE1 && (key.scancode & 0x7F) == 0x1D) break; + if (ext_code == 0xE1 && key.scancode == 0xC5) {ext_code=0;break;} + key.mod = GetModState(); + if (ext_code == 0xE1) key.mod &= ~KMOD_CTRL; + if (!(key.scancode&0x80)) + old_mode = key.mod; + SDL_SetModState(key.mod); + int code = (key.scancode & 0x80) ? SDL_RELEASED : SDL_PRESSED; + key.scancode &= 0x7F; +// key.sym = scan2ascii(key.scancode,key.mod); + if (ext_code == 0xE1 && key.scancode == 0x45) + key.sym = SDLK_PAUSE; + else if (ext_code == 0xE0) + key.sym = sdlkeys_e0[key.scancode]; + else if (old_mode & KMOD_SHIFT) + key.sym = sdlkeys_shift[key.scancode]; + else + key.sym = sdlkeys[key.scancode]; + ext_code = 0; + if (!key.sym) break; + SDL_PrivateKeyboard(code,&key); + break; + case 3: + if(__menuet__get_button_id()==1) exit(0); + break; + case 6: { + int __tmp,mx,my; + static int oldmousestate = 0; + __asm__("int $0x40":"=a"(__tmp):"a"(37),"b"(1)); + mx=(__tmp>>16); + my=(__tmp&0xffff); + if(mx>=0 && mxhidden->win_size_x && + my>=0 && myhidden->win_size_y || this->input_grab != SDL_GRAB_OFF) + { + if (this->input_grab != SDL_GRAB_OFF) + { + int dx=mx-this->hidden->win_size_x/2; + int dy=my-this->hidden->win_size_y/2; + if (dx||dy) + { + SDL_PrivateMouseMotion(0,1,dx,dy); + KolibriOS_CheckMouseMode(this); + } + } + else + SDL_PrivateMouseMotion(0,0,mx,my); + __asm__("int $0x40":"=a"(__tmp):"a"(37),"b"(2)); + if ((__tmp^oldmousestate)&1) { + if(__tmp&1) + { + SDL_PrivateMouseButton(SDL_PRESSED,SDL_BUTTON_LMASK,0,0); + } else { + SDL_PrivateMouseButton(SDL_RELEASED,SDL_BUTTON_LMASK,0,0); + } } + if ((__tmp^oldmousestate)&2) { + if(__tmp&2) + { + SDL_PrivateMouseButton(SDL_PRESSED,SDL_BUTTON_RMASK,0,0); + } else { + SDL_PrivateMouseButton(SDL_RELEASED,SDL_BUTTON_RMASK,0,0); + } } + oldmousestate = __tmp; + } + } + } + } +} diff --git a/contrib/sdk/sources/SDL-1.2.2/src/video/menuetos/SDL_menuetvideo.c b/contrib/sdk/sources/SDL-1.2.2/src/video/menuetos/SDL_menuetvideo.c new file mode 100644 index 000000000..da9908fb7 --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/src/video/menuetos/SDL_menuetvideo.c @@ -0,0 +1,324 @@ +#include +#include +#include +#include "SDL.h" +#include "SDL_error.h" +#include "SDL_video.h" +#include "SDL_mouse.h" +#include "SDL_sysvideo.h" +#include "SDL_pixels_c.h" +#include "SDL_events_c.h" +#include "SDL_menuetvideo.h" +#include + +static SDL_VideoDevice * vm_suf=NULL; +static int was_initialized=0; + +static int has_null_cursor=0; +static int null_cursor; + +inline int get_skinh(void) +{ + int res; + __asm__ ("int $0x40" : "=a"(res) : "a"(48),"b"(4)); + return res; +} + +//#define KEEP_OBSOLETE_STYLE3 + +#ifdef KEEP_OBSOLETE_STYLE3 +static int IsStyle4Available=0; +#endif + +void MenuetOS_SDL_RepaintWnd(void) +{ + __menuet__window_redraw(1); + __menuet__define_window(1,1,vm_suf->hidden->win_size_x+9,vm_suf->hidden->win_size_y+get_skinh()+4, +#ifdef KEEP_OBSOLETE_STYLE3 + IsStyle4Available?0x34000000:0x33000000 +#else + 0x34000000 +#endif + ,0,(int)vm_suf->hidden->__title); + if(vm_suf && vm_suf->hidden->__video_buffer) + __menuet__putimage(0,0, + vm_suf->hidden->win_size_x,vm_suf->hidden->win_size_y, + vm_suf->hidden->__video_buffer); + __menuet__window_redraw(2); +} + +static int MenuetOS_AllocHWSurface(_THIS,SDL_Surface * surface) +{ + return -1; +} + +static void MenuetOS_FreeHWSurface(_THIS,SDL_Surface * surface) +{ +} + +static int MenuetOS_LockHWSurface(_THIS,SDL_Surface * surface) +{ + return 0; +} + +static void MenuetOS_UnlockHWSurface(_THIS,SDL_Surface * surface) +{ +} + +static void MenuetOS_DirectUpdate(_THIS,int numrects,SDL_Rect * rects) +{ + if(numrects) + { + __menuet__putimage(0,0, + vm_suf->hidden->win_size_x,vm_suf->hidden->win_size_y, + this->hidden->__video_buffer); + } +} + +int MenuetOS_SetColors(_THIS, int firstcolor, int ncolors, SDL_Color *colors) +{ + return 0; +} + +void MenuetOS_VideoQuit(_THIS) +{ + if (has_null_cursor) + { + __asm__("int $0x40"::"a"(37),"b"(6),"c"(null_cursor)); + has_null_cursor = 0; + } +} + +void MenuetOS_FinalQuit(void) +{ +} + +void MenuetOS_SetCaption(_THIS,const char * title,const char * icon) +{ + this->hidden->__title=(char *)title; + if(was_initialized) __asm__("int $0x40"::"a"(71),"b"(1),"c"(title)); +} + +SDL_Surface * MenuetOS_SetVideoMode(_THIS, SDL_Surface *current, int width, int height, int bpp, Uint32 flags) +{ + int ly; + char * lx; + if(bpp!=24) return NULL; + current->flags=flags; + current->w=width; + current->h=height; + current->pitch=width*(bpp>>3); + current->pixels=this->hidden->__video_buffer=realloc(this->hidden->__video_buffer, + current->pitch*current->h); + this->hidden->__lines=(unsigned char **)realloc(this->hidden->__lines, + sizeof(unsigned char *)*current->h); + for(ly=0,lx=current->pixels;lyh;ly++,lx+=current->pitch) + this->hidden->__lines[ly]=lx; + this->UpdateRects=MenuetOS_DirectUpdate; + this->hidden->win_size_x=width; + this->hidden->win_size_y=height; + vm_suf=this; + if (was_initialized) + { + unsigned newheight = height+get_skinh()+4; + unsigned newwidth = width+9; + __asm__("int $0x40"::"a"(67),"b"(-1),"c"(-1),"d"(newwidth),"S"(newheight)); + } + else + { + __menuet__set_bitfield_for_wanted_events(0x27); + was_initialized=1; + MenuetOS_SDL_RepaintWnd(); + } + return current; +} + +/*static SDL_Rect video_mode[4]; +static SDL_Rect * SDL_modelist[4]={NULL,NULL,NULL,NULL};*/ + +static SDL_Rect ** MenuetOS_ListModes(_THIS,SDL_PixelFormat * fmt,Uint32 flags) +{ +// return (&SDL_modelist[((fmt->BitsPerPixel+7)/8)-1]); + if (fmt->BitsPerPixel==24) + return (SDL_Rect**)-1; + else + return NULL; +} + +static int MenuetOS_Available(void) +{ + return 1; +} + +static void MenuetOS_DeleteDevice(_THIS) +{ +// free(this->hidden->__video_buffer); // it will be freed as current->pixels + free(this->hidden->__lines); +} + +static int MenuetOS_VideoInit(_THIS,SDL_PixelFormat * vformat) +{ +#ifdef KEEP_OBSOLETE_STYLE3 + char buf[16]; + __asm__("int $0x40"::"a"(18),"b"(13),"c"(buf)); + if (buf[5]=='K' && buf[6]=='o' && buf[7]=='l' && buf[8]=='i') + /* kernels up to 0.7.0.0 do not support style 4 */; + else if (*(unsigned*)(buf+5) >= 549) + /* window style 4 was introduced in revision 549 */ + IsStyle4Available = 1; +#endif + vformat->BitsPerPixel=24; + vformat->BytesPerPixel=3; + this->info.wm_available=1; + this->info.hw_available=0; + this->info.video_mem=0x200000; +/* video_mode[3].x=0; + video_mode[3].y=0; + video_mode[3].w=320; + video_mode[3].h=200; + video_mode[2].x=0; + video_mode[2].y=0; + video_mode[2].w=640; + video_mode[2].h=400; + video_mode[1].x=0; + video_mode[1].y=0; + video_mode[1].w=320; + video_mode[1].h=240; + video_mode[0].x=0; + video_mode[0].y=0; + video_mode[0].w=640; + video_mode[0].h=480; + SDL_modelist[2]=video_mode+0;*/ + return 0; +} + +static int MenuetOS_FlipHWSurface(_THIS,SDL_Surface * surface) +{ + __menuet__putimage(0,0,surface->w,surface->h, + surface->pixels); + return 0; +} + +WMcursor* KolibriOS_CreateWMCursor(_THIS, + Uint8* data, Uint8* mask, int w, int h, int hot_x, int hot_y) +{ + int i,j; + Uint32* cursor; + WMcursor* res; + + if (w>32 || h>32) return NULL; + if (w%8 || h%8) return NULL; + cursor = (Uint32*)malloc(32*32*4); + if (!cursor) return NULL; + for (i=0;i<32;i++) + for (j=0;j<32;j++) + { + if (i>=h || j>=w) + { + cursor[i*32+j] = 0x00000000; + continue; + } + if (mask[i*w/8+j/8] & (0x80>>(j&7))) + cursor[i*32+j] = (data[i*w/8+j/8] & (0x80>>(j&7)))?0xFF000000:0xFFFFFFFF; + else + cursor[i*32+j] = 0x00000000; + } + __asm__ ("int $0x40" : "=a"(res) : "a"(37),"b"(4), + "c"(cursor),"d"((hot_x<<24)+(hot_y<<16)+2)); + free(cursor); + return res; +} +int KolibriOS_ShowWMCursor(_THIS,WMcursor*cursor) +{ + if (!cursor) + { + if (!has_null_cursor) + { + unsigned* u = malloc(32*32*4); + if (!u) return 1; + memset(u,0,32*32*4); + __asm__("int $0x40":"=a"(null_cursor): + "a"(37),"b"(4),"c"(u),"d"(2)); + free(u); + has_null_cursor = 1; + } + cursor = (WMcursor*)null_cursor; + } + __asm__("int $0x40" : : "a"(37),"b"(5),"c"(cursor)); + return 1; +} +void KolibriOS_FreeWMCursor(_THIS,WMcursor*cursor) +{ + __asm__("int $0x40" : : "a"(37),"b"(6),"c"(cursor)); +} +void KolibriOS_CheckMouseMode(_THIS) +{ + if (this->input_grab == SDL_GRAB_OFF) + return; + struct process_table_entry buf; + int res; + __asm__ volatile("int $0x40" : "=a"(res): "a"(9), "b"(&buf), "c"(-1)); + if (res == buf.pos_in_windowing_stack) + { + int x = buf.winx_start + buf.client_left + this->hidden->win_size_x/2; + int y = buf.winy_start + buf.client_top + this->hidden->win_size_y/2; + __asm__("int $0x40" : : "a"(18),"b"(19),"c"(4), + "d"(x*65536+y)); + } +} + +char def_title[] = "KolibriOS SDL App"; +static SDL_VideoDevice * MenuetOS_CreateDevice(int indx) +{ + SDL_VideoDevice * dev; + dev=(SDL_VideoDevice *)malloc(sizeof(SDL_VideoDevice)); + if(dev) + { + memset(dev,0,(sizeof *dev)); + dev->hidden = (struct SDL_PrivateVideoData *)malloc((sizeof *dev->hidden)); + } + if((dev==NULL) || (dev->hidden==NULL)) + { + SDL_OutOfMemory(); + if(dev) + { + free(dev); + } + return(0); + } + memset(dev->hidden,0,(sizeof *dev->hidden)); + dev->hidden->__title = def_title; + dev->VideoInit=MenuetOS_VideoInit; + dev->ListModes=MenuetOS_ListModes; + dev->SetVideoMode=MenuetOS_SetVideoMode; + dev->SetColors=MenuetOS_SetColors; + dev->UpdateRects=NULL; + dev->VideoQuit=MenuetOS_VideoQuit; + dev->AllocHWSurface=MenuetOS_AllocHWSurface; + dev->CheckHWBlit=NULL; + dev->FillHWRect=NULL; + dev->SetHWColorKey=NULL; + dev->SetHWAlpha=NULL; + dev->LockHWSurface=MenuetOS_LockHWSurface; + dev->UnlockHWSurface=MenuetOS_UnlockHWSurface; + dev->FlipHWSurface=MenuetOS_FlipHWSurface; + dev->FreeHWSurface=MenuetOS_FreeHWSurface; + dev->SetCaption=MenuetOS_SetCaption; + dev->SetIcon=NULL; + dev->IconifyWindow=NULL; + dev->GrabInput=NULL; + dev->GetWMInfo=NULL; + dev->InitOSKeymap=MenuetOS_InitOSKeymap; + dev->PumpEvents=MenuetOS_PumpEvents; + dev->free=MenuetOS_DeleteDevice; + dev->CreateWMCursor = KolibriOS_CreateWMCursor; + dev->FreeWMCursor = KolibriOS_FreeWMCursor; + dev->ShowWMCursor = KolibriOS_ShowWMCursor; + dev->CheckMouseMode = KolibriOS_CheckMouseMode; + return dev; +} + +VideoBootStrap mosvideo_bootstrab={ + "menuetos","MenuetOS Device Driver", + MenuetOS_Available,MenuetOS_CreateDevice, +}; diff --git a/contrib/sdk/sources/SDL-1.2.2/src/video/menuetos/SDL_menuetvideo.h b/contrib/sdk/sources/SDL-1.2.2/src/video/menuetos/SDL_menuetvideo.h new file mode 100644 index 000000000..7f1eafb1e --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/src/video/menuetos/SDL_menuetvideo.h @@ -0,0 +1,20 @@ +#ifndef _SDL_menuetvideo_h +#define _SDL_menuetvideo_h + +#include "SDL_mouse.h" +#include "SDL_sysvideo.h" + +#define _THIS SDL_VideoDevice *this + +struct SDL_PrivateVideoData { + unsigned char * __video_buffer; + char * __title; + int win_size_x,win_size_y; + int vx_ofs,vy_ofs; + unsigned char** __lines; +}; + +void MenuetOS_InitOSKeymap(_THIS); +void MenuetOS_PumpEvents(_THIS); + +#endif diff --git a/contrib/sdk/sources/SDL-1.2.2/test/Makefile.bmp b/contrib/sdk/sources/SDL-1.2.2/test/Makefile.bmp new file mode 100644 index 000000000..2aa505cc2 --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/test/Makefile.bmp @@ -0,0 +1,6 @@ +OUTFILE = sdltestb +OBJS = testbitmap.o +CFLAGS = -I../include +LIBS = -L../src -lSDL + +include $(MENUETDEV)/makefiles/Makefile_for_program diff --git a/contrib/sdk/sources/SDL-1.2.2/test/Makefile.test b/contrib/sdk/sources/SDL-1.2.2/test/Makefile.test new file mode 100644 index 000000000..ade372d82 --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/test/Makefile.test @@ -0,0 +1,5 @@ +OUTFILE = SDLtest +OBJS = sdltest.o +LIBS = -lSDL + +include $(MENUETDEV)/makefiles/Makefile_for_program diff --git a/contrib/sdk/sources/SDL-1.2.2/test/picture.xbm b/contrib/sdk/sources/SDL-1.2.2/test/picture.xbm new file mode 100644 index 000000000..c873a60a1 --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/test/picture.xbm @@ -0,0 +1,14 @@ +#define picture_width 32 +#define picture_height 32 +static char picture_bits[] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x80, 0x01, 0x18, + 0x64, 0x6f, 0xf6, 0x26, 0x0a, 0x00, 0x00, 0x50, 0xf2, 0xff, 0xff, 0x4f, + 0x14, 0x04, 0x00, 0x28, 0x14, 0x0e, 0x00, 0x28, 0x10, 0x32, 0x00, 0x08, + 0x94, 0x03, 0x00, 0x08, 0xf4, 0x04, 0x00, 0x08, 0xb0, 0x08, 0x00, 0x08, + 0x34, 0x01, 0x00, 0x28, 0x34, 0x01, 0x00, 0x28, 0x12, 0x00, 0x40, 0x48, + 0x12, 0x20, 0xa6, 0x48, 0x14, 0x50, 0x11, 0x29, 0x14, 0x50, 0x48, 0x2a, + 0x10, 0x27, 0xac, 0x0e, 0xd4, 0x71, 0xe8, 0x0a, 0x74, 0x20, 0xa8, 0x0a, + 0x14, 0x20, 0x00, 0x08, 0x10, 0x50, 0x00, 0x08, 0x14, 0x00, 0x00, 0x28, + 0x14, 0x00, 0x00, 0x28, 0xf2, 0xff, 0xff, 0x4f, 0x0a, 0x00, 0x00, 0x50, + 0x64, 0x6f, 0xf6, 0x26, 0x18, 0x80, 0x01, 0x18, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; diff --git a/contrib/sdk/sources/SDL-1.2.2/test/sdltest.c b/contrib/sdk/sources/SDL-1.2.2/test/sdltest.c new file mode 100644 index 000000000..84eb4a28c --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/test/sdltest.c @@ -0,0 +1,28 @@ +#include"SDL.h" +#include + +SDL_Surface * screen; +static int done=0; + +void app_main(void) +{ + SDL_Event event; + if(SDL_Init(SDL_INIT_VIDEO)<0) __menuet__sys_exit(); + atexit(SDL_Quit); + screen=SDL_SetVideoMode(320,200,8,SDL_SWSURFACE); + while(!done) + { + while(SDL_PollEvent(&event)) + { + switch(event.type) + { + case SDL_KEYDOWN: + case SDL_QUIT: + done=1; + break; + default: + break; + } + } + } +} diff --git a/contrib/sdk/sources/SDL-1.2.2/test/testbitmap.c b/contrib/sdk/sources/SDL-1.2.2/test/testbitmap.c new file mode 100644 index 000000000..0f9a8e645 --- /dev/null +++ b/contrib/sdk/sources/SDL-1.2.2/test/testbitmap.c @@ -0,0 +1,125 @@ + +/* Simple program: Test bitmap blits */ + +#include +#include +#include + +#include "SDL.h" +#include "picture.xbm" + +SDL_Surface *LoadXBM(SDL_Surface *screen, int w, int h, Uint8 *bits) +{ + SDL_Surface *bitmap; + Uint8 *line; + + /* Allocate the bitmap */ + bitmap = SDL_CreateRGBSurface(SDL_SWSURFACE, w, h, 1, 0, 0, 0, 0); + if ( bitmap == NULL ) { + fprintf(stderr, "Couldn't allocate bitmap: %s\n", + SDL_GetError()); + return(NULL); + } + + /* Copy the pixels */ + line = (Uint8 *)bitmap->pixels; + w = (w+7)/8; + while ( h-- ) { + memcpy(line, bits, w); + /* X11 Bitmap images have the bits reversed */ + { int i, j; Uint8 *buf, byte; + for ( buf=line, i=0; i=0; --j ) { + *buf |= (byte&0x01)<>= 1; + } + } + } + line += bitmap->pitch; + bits += w; + } + return(bitmap); +} + +void app_main(int argc, char *argv[]) +{ + SDL_Surface *screen; + SDL_Surface *bitmap; + Uint8 video_bpp; + Uint32 videoflags; + Uint8 *buffer; + int i, done; + SDL_Event event; + + /* Initialize SDL */ + if ( SDL_Init(SDL_INIT_VIDEO) < 0 ) { + fprintf(stderr, "Couldn't initialize SDL: %s\n",SDL_GetError()); + exit(1); + } + atexit(SDL_Quit); + + video_bpp = 0; + videoflags = SDL_SWSURFACE; + /* Set 640x480 video mode */ + if ( (screen=SDL_SetVideoMode(640,480,video_bpp,videoflags)) == NULL ) { + fprintf(stderr, "Couldn't set 640x480x%d video mode: %s\n", + video_bpp, SDL_GetError()); + exit(2); + } + + /* Set the surface pixels and refresh! */ + if ( SDL_LockSurface(screen) < 0 ) { + fprintf(stderr, "Couldn't lock the display surface: %s\n", + SDL_GetError()); + exit(2); + } + buffer=(Uint8 *)screen->pixels; + for ( i=0; ih; ++i ) { + memset(buffer,(i*255)/screen->h, screen->pitch); + buffer += screen->pitch; + } + SDL_UnlockSurface(screen); + SDL_UpdateRect(screen, 0, 0, 0, 0); + + /* Load the bitmap */ + bitmap = LoadXBM(screen, picture_width, picture_height, + (Uint8 *)picture_bits); + if ( bitmap == NULL ) { + exit(1); + } + + /* Wait for a keystroke */ + done = 0; + while ( !done ) { + /* Check for events */ + while ( SDL_PollEvent(&event) ) { + switch (event.type) { + case SDL_MOUSEBUTTONDOWN: { + SDL_Rect dst; + + dst.x = event.button.x - bitmap->w/2; + dst.y = event.button.y - bitmap->h/2; + dst.w = bitmap->w; + dst.h = bitmap->h; + SDL_BlitSurface(bitmap, NULL, + screen, &dst); + SDL_UpdateRects(screen,1,&dst); + } + break; + case SDL_KEYDOWN: + /* Any key press quits the app... */ + done = 1; + break; + case SDL_QUIT: + done = 1; + break; + default: + break; + } + } + } + SDL_FreeSurface(bitmap); + return(0); +} diff --git a/data/Tupfile.lua b/data/Tupfile.lua index cc785c270..9ab5a1bee 100644 --- a/data/Tupfile.lua +++ b/data/Tupfile.lua @@ -131,7 +131,6 @@ extra_files = { {"kolibrios/games/doom/", "common/games/doom/*"}, {"kolibrios/games/fara/fara.gfx", "common/games/fara.gfx"}, {"kolibrios/games/jumpbump/", "common/games/jumpbump/*"}, - {"kolibrios/games/quake/", "common/games/quake/*"}, {"kolibrios/games/lrl/", "common/games/lrl/*"}, {"kolibrios/lib/avcodec-55.dll", "common/lib/avcodec-55.dll"}, {"kolibrios/lib/avdevice-55.dll", "common/lib/avdevice-55.dll"}, @@ -461,6 +460,8 @@ tup.append_table(img_files, { }) tup.append_table(extra_files, { {"kolibrios/emul/e80/e80", PROGS .. "/emulator/e80/trunk/e80"}, + {"kolibrios/games/quake/", "common/games/quake/*"}, -- not really gcc, but no sense without sdlquake + {"kolibrios/games/quake/", "../contrib/other/sdlquake-1.0.9/sdlquake"}, }) end -- tup.getconfig('NO_GCC') ~= 'full' diff --git a/data/common/games/quake/sdlquake b/data/common/games/quake/sdlquake deleted file mode 100644 index 5e2edec8c..000000000 Binary files a/data/common/games/quake/sdlquake and /dev/null differ diff --git a/programs/develop/libraries/menuetlibc/src/libc/ansi/stdlib/malloc.c b/programs/develop/libraries/menuetlibc/src/libc/ansi/stdlib/malloc.c index e91706351..7dc20aa2f 100644 --- a/programs/develop/libraries/menuetlibc/src/libc/ansi/stdlib/malloc.c +++ b/programs/develop/libraries/menuetlibc/src/libc/ansi/stdlib/malloc.c @@ -5,7 +5,6 @@ #include #include #include -#include typedef struct BLOCK { size_t size; @@ -23,7 +22,7 @@ typedef struct BLOCK { #define ALIGN 8 #define SMALL (NUMSMALL*ALIGN) -DECLARE_STATIC_SEM(malloc_mutex) +static int malloc_mutex = 0; static BLOCK *slop = 0; static BLOCK *freelist[30]; @@ -33,12 +32,13 @@ static BLOCK *smallblocks[NUMSMALL]; static inline void malloc_lock(void) { - sem_lock(&malloc_mutex); + while (__sync_lock_test_and_set(&malloc_mutex, 1)) + __menuet__delay100(1); } static inline void malloc_unlock(void) { - sem_unlock(&malloc_mutex); + __sync_lock_release(&malloc_mutex); } #define MIN_SAVE_EXTRA 64 diff --git a/programs/develop/libraries/menuetlibc/stub/Tupfile.lua b/programs/develop/libraries/menuetlibc/stub/Tupfile.lua index 1e2113701..e91451bb6 100644 --- a/programs/develop/libraries/menuetlibc/stub/Tupfile.lua +++ b/programs/develop/libraries/menuetlibc/stub/Tupfile.lua @@ -1,2 +1,3 @@ if tup.getconfig("NO_FASM") ~= "" then return end tup.rule("crt0_coff.asm", "fasm %f %o", "crt0.o") +tup.rule("crt0_coff_dynstack.asm", "fasm %f %o", "crt0_dynstack.o") diff --git a/programs/develop/libraries/menuetlibc/stub/crt0_coff_dynstack.asm b/programs/develop/libraries/menuetlibc/stub/crt0_coff_dynstack.asm new file mode 100644 index 000000000..ef73d46f4 --- /dev/null +++ b/programs/develop/libraries/menuetlibc/stub/crt0_coff_dynstack.asm @@ -0,0 +1,63 @@ +CATCH_NULL_CALL = 0 + +format MS COFF +section '.text' code readable executable +public start +;EXTRN _edata +EXTRN ___menuet__app_param_area +EXTRN ___menuet__app_path_area +EXTRN ___crt1_startup +EXTRN ___memsize +start: +public ___menuet__app_header +public ___menuet__memsize +section '.A' code readable executable +___menuet__app_header: + db 'MENUET01' + dd 0x01 + dd do_start +; dd _edata + dd 0 +___menuet__memsize: + dd ___memsize + dd app_stack + dd ___menuet__app_param_area + dd ___menuet__app_path_area + +do_start: + push 68 + pop eax + push 11 + pop ebx + push eax + int 0x40 + pop eax + inc ebx + mov ecx, 0x100000 + int 0x40 + lea esp, [eax+ecx] +if CATCH_NULL_CALL + mov byte [0], 0xE9 + mov dword [1], _libc_null_call-5 +end if + jmp ___crt1_startup + +if CATCH_NULL_CALL +EXTRN ___libc_null_call + +_libc_null_call: + push eax + push ebx + push ecx + push edx + push esi + push edi + push ebp + call ___libc_null_call + mov eax,-1 + int 0x40 +end if + +section '.bss' readable writeable +rb 0x100 +app_stack: diff --git a/programs/use_gcc.lua b/programs/use_gcc.lua index c1b02f489..b8716109f 100644 --- a/programs/use_gcc.lua +++ b/programs/use_gcc.lua @@ -16,6 +16,10 @@ end function link_gcc(input, output) if not output then input,output = OBJS,input end + if STARTUP then + table.insert(LIBDEPS, STARTUP) + LDFLAGS = LDFLAGS .. " " .. STARTUP + end if tup.getconfig("HELPERDIR") == "" and #LIBDEPS then if type(input) == "string" then input = {input} end if not input.extra_inputs then input.extra_inputs = {} end diff --git a/programs/use_menuetlibc.lua b/programs/use_menuetlibc.lua index 4a6675096..c135e8a18 100644 --- a/programs/use_menuetlibc.lua +++ b/programs/use_menuetlibc.lua @@ -1,6 +1,11 @@ MELIBC = tup.getcwd() .. "/develop/libraries/menuetlibc" INCLUDES = INCLUDES .. " -I" .. MELIBC .. "/include" -LDFLAGS = LDFLAGS .. string.gsub(" -T$/include/scripts/menuetos_app_v01.ld -L$/lib $/stub/crt0.o", "%$", MELIBC) -tup.append_table(LIBDEPS, {MELIBC .. "/stub/crt0.o", MELIBC .. "/", MELIBC .. "/", MELIBC .. "/"}) +STARTUP = MELIBC .. "/stub/crt0.o" +LDFLAGS = LDFLAGS .. string.gsub(" -T$/include/scripts/menuetos_app_v01.ld -L$/lib", "%$", MELIBC) +tup.append_table(LIBDEPS, {MELIBC .. "/", MELIBC .. "/", MELIBC .. "/"}) LIBS = LIBS .. " -lcpp -lm -lc" + +function use_dynamic_stack() + STARTUP = MELIBC .. "/stub/crt0_dynstack.o" +end diff --git a/programs/use_sdl.lua b/programs/use_sdl.lua new file mode 100644 index 000000000..796dc4d24 --- /dev/null +++ b/programs/use_sdl.lua @@ -0,0 +1,8 @@ +SDL_INCLUDE = tup.getcwd() .. "/../contrib/sdk/sources/SDL-1.2.2/include" +SDL_LIB = tup.getcwd() .. "/../contrib/sdk/lib" + +tup.include("use_sound.lua") + +INCLUDES = INCLUDES .. " -I" .. SDL_INCLUDE +table.insert(LIBDEPS, SDL_LIB .. "/") +LIBS = SDL_LIB .. "/libSDL.a " .. LIBS diff --git a/programs/use_sound.lua b/programs/use_sound.lua new file mode 100644 index 000000000..f0c4104ea --- /dev/null +++ b/programs/use_sound.lua @@ -0,0 +1,5 @@ +SOUND = tup.getcwd() .. "/develop/sdk/trunk/sound" + +INCLUDES = INCLUDES .. " -I" .. SOUND .. "/include" +table.insert(LIBDEPS, SOUND .. "/src/sound.lib") +LIBS = SOUND .. "/src/sound.lib " .. LIBS