pax_global_header00006660000000000000000000000064151621631500014512gustar00rootroot0000000000000052 comment=85323d872116ee45fdc5eaab63f945914ea4ad5e CheeseCutter-2.10/000077500000000000000000000000001516216315000140175ustar00rootroot00000000000000CheeseCutter-2.10/AUTHORS000066400000000000000000000000001516216315000150550ustar00rootroot00000000000000CheeseCutter-2.10/ChangeLog000066400000000000000000000000711516216315000155670ustar00rootroot00000000000000See http://theyamo.kapsi.fi/ccutter/ for latest changes CheeseCutter-2.10/INSTALL000066400000000000000000000000621516216315000150460ustar00rootroot00000000000000make -- build binary using ldc2 CheeseCutter-2.10/LICENSE.md000066400000000000000000000431101516216315000154220ustar00rootroot00000000000000 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. GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you". Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does. 1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change. b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License. c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program. In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following: a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.) The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. 4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it. 6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. 7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation. 10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Also add information on how to contact you by electronic and paper mail. If the program is interactive, make it output a short notice like this when it starts in an interactive mode: Gnomovision version 69, Copyright (C) year name of author Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than `show w' and `show c'; they could even be mouse-clicks or menu items--whatever suits your program. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the program, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' (which makes passes at compilers) written by James Hacker. , 1 April 1989 Ty Coon, President of Vice This General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Library General Public License instead of this License. CheeseCutter-2.10/Makefile000066400000000000000000000034761516216315000154710ustar00rootroot00000000000000PREFIX ?= /usr/local DESTDIR ?= EXAMPLESDIR ?= $(PREFIX)/share/examples/ccutter VERSION := $(shell cat Version 2>/dev/null || echo "unknown") DLIBS=-L-ldl -L-lstdc++ -L-lSDL2 DFLAGS=-d-version=DerelictSDL2_Static -I./src -J./src/c64 -J./src/font CFLAGS=-O2 -std=c99 CXXFLAGS=-O2 -I./src COMPILE.d = $(DC) $(DFLAGS) -c DC=ldc2 TARGET=ccutter include Makefile.objects.mk .PHONY: install release dist clean dclean tar %.o: %.d $(DC) $(DFLAGS) -c -of=$@ $< %.o: %.c $(CC) $(CFLAGS) -c -o $@ $< %.o: %.cpp $(CXX) $(CXXFLAGS) -c -o $@ $< all: ct2util ccutter ccutter: $(C64OBJS) $(OBJS) $(CXX_OBJS) $(DC) -of=$@ $(OBJS) $(CXX_OBJS) $(DLIBS) ct: $(C64OBJS) $(CTOBJS) ct2util: $(C64OBJS) $(UTILOBJS) $(DC) -of=$@ $(UTILOBJS) c64: $(C64OBJS) install: all strip ccutter strip ct2util install -D -m 755 ccutter $(DESTDIR)$(PREFIX)/bin/ccutter install -D -m 755 ct2util $(DESTDIR)$(PREFIX)/bin/ct2util install -d $(DESTDIR)$(EXAMPLESDIR)/example_tunes cp -r tunes/* $(DESTDIR)$(EXAMPLESDIR)/example_tunes/ # release version with additional optimizations release: DFLAGS += -frelease -fno-bounds-check release: all strip ccutter strip ct2util # tarred release dist: release tar --transform 's,^\.,cheesecutter-$(VERSION),' -czf cheesecutter-$(VERSION)-linux-x86.tar.gz $(DIST_FILES) clean: rm -f *.o *~ resid/*.o resid-fp/*.o ccutter ct2util \ $(C64OBJS) $(OBJS) $(CTOBJS) $(CXX_OBJS) $(UTILOBJS) $(C_OBJS) dclean: clean rm -f cheesecutter-$(VERSION)-linux-x86.tar.gz # tarred source from master tar: git archive master --prefix=cheesecutter-$(VERSION)/ | bzip2 > cheesecutter-$(VERSION)-src.tar.bz2 # -------------------------------------------------------------------------------- src/c64/player.bin: src/c64/player_v4.acme acme -f cbm -Wno-old-for --outfile $@ $< src/ct/base.o: src/c64/player.bin src/ui/ui.o: src/ui/help.o CheeseCutter-2.10/Makefile.mac000066400000000000000000000040171516216315000162200ustar00rootroot00000000000000#LIBS=/opt/ldc/build/lib/libphobos-ldc.a /opt/ldc/build/lib/libdruntime-ldc.a -lstdc++ #LIBS=/opt/ldc2/lib/libphobos-ldc.a /opt/ldc2/lib/libdruntime-ldc.a -lstdc++ LIBS=/usr/local/lib/libphobos2-ldc.a /usr/local/lib/libdruntime-ldc.a -lstdc++ -lsdl2 FRAMEWORKS=-framework Foundation COMFLAGS= -mmacosx-version-min=11.0 -g VERSION=$(shell cat Version) DLINK=$(COMFLAGS) DFLAGS=-d-version=DerelictSDL2_Static -I./src -J./src/c64 -J./src/font CFLAGS=$(COMFLAGS) CXXFLAGS=$(CFLAGS) -I./src -O2 LDFLAGS=-rpath,@executable_path/../Frameworks COMPILE.d = $(DC) $(DFLAGS) -d -O2 -c -of=$@ DC=ldc2 EXE= TARGET=ccutter include Makefile.objects.mk $(TARGET): $(C64OBJS) $(OBJS) $(CXX_OBJS) $(CC) $(DLINK) -Wl,$(LDFLAGS) -o $(TARGET) $(OBJS) $(CXX_OBJS) $(LIBS) $(FRAMEWORKS) .cpp.o : $(CXX_SRCS) $(CXX) $(CXXFLAGS) -c $< -o $@ .c.o : $(C_SRCS) $(CC) -c $< -o $@ ct: $(C64OBJS) $(CTOBJS) ct2util: $(C64OBJS) $(UTILOBJS) $(CC) $(DLINK) -o $@ $(UTILOBJS) $(LIBS) c64: $(C64OBJS) all: c64 $(OBJS) $(CXX_OBJS) ct2util ct $(TARGET) release: all strip ccutter$(EXE) strip ct2util$(EXE) rm -rf CheeseCutter.app mkdir -p CheeseCutter.app/Contents/Frameworks mkdir -p CheeseCutter.app/Contents/MacOS cp -r arch/MacOS/Contents CheeseCutter.app cp -r /Library/Frameworks/SDL.framework CheeseCutter.app/Contents/Frameworks cp $(TARGET) CheeseCutter.app/Contents/MacOS cp ct2util CheeseCutter.app/Contents/MacOS dist: release rm -rf dist rm -rf CheeseCutter_$(VERSION).dmg arch/makedmg.sh clean: rm -f *.o *~ resid/*.o resid-fp/*.o ccutter ct2util \ $(C64OBJS) $(OBJS) $(CTOBJS) $(CXX_OBJS) $(UTILOBJS) dclean: clean rm -rf dist rm -rf CheeseCutter.app rm -rf CheeseCutter_$(VERSION).dmg tar: git archive master --prefix=cheesecutter-$(VERSION)/ | bzip2 > cheesecutter-$(VERSION)-macosx-src.tar.bz2 # -------------------------------------------------------------------------------- src/c64/player.bin: src/c64/player_v4.acme acme -f cbm --outfile $@ $< src/ct/base.o: src/c64/player.bin src/ui/ui.o: src/ui/help.o %.o: %.d $(COMPILE.d) $< CheeseCutter-2.10/Makefile.objects.mk000066400000000000000000000033701516216315000175200ustar00rootroot00000000000000 OBJS= \ src/derelict/sdl2/internal/sdl_types.o \ src/audio/audio.o \ src/audio/player.o \ src/audio/timer.o \ src/audio/callback.o \ src/ct/purge.o \ src/ct/base.o \ src/com/fb.o \ src/com/cpu.o \ src/com/kbd.o \ src/com/session.o \ src/com/util.o \ src/main.o \ src/ui/tables.o \ src/ui/dialogs.o \ src/ui/ui.o \ src/ui/input.o \ src/ui/help.o \ src/seq/seqtable.o \ src/seq/tracktable.o \ src/seq/trackmap.o \ src/seq/fplay.o \ src/seq/sequencer.o \ src/audio/resid/filter.o CXX_SRCS = src/audio/resid/residctrl.cpp \ src/resid/envelope.cpp \ src/resid/extfilt.cpp \ src/resid/filter.cpp \ src/resid/w6_ps_.cpp \ src/resid/w6_pst.cpp \ src/resid/w6_p_t.cpp \ src/resid/w6__st.cpp \ src/resid/w8_ps_.cpp \ src/resid/w8_pst.cpp \ src/resid/w8_p_t.cpp \ src/resid/w8__st.cpp \ src/resid/pot.cpp \ src/resid/sid.cpp \ src/resid/voice.cpp \ src/resid/wave.cpp \ src/resid-fp/envelopefp.cpp \ src/resid-fp/extfiltfp.cpp \ src/resid-fp/filterfp.cpp \ src/resid-fp/potfp.cpp \ src/resid-fp/sidfp.cpp \ src/resid-fp/versionfp.cpp \ src/resid-fp/voicefp.cpp \ src/resid-fp/wavefp.cpp CXX_OBJS = $(CXX_SRCS:.cpp=.o) C_SRCS = \ src/asm/acme.c \ src/asm/alu.c \ src/asm/basics.c \ src/asm/cpu.c \ src/asm/dynabuf.c \ src/asm/encoding.c \ src/asm/flow.c \ src/asm/global.c \ src/asm/input.c src/asm/label.c \ src/asm/macro.c \ src/asm/mnemo.c \ src/asm/output.c \ src/asm/platform.c \ src/asm/section.c \ src/asm/tree.c C_OBJS = $(C_SRCS:.c=.o) UTILOBJS = src/ct2util.o \ src/ct/base.o \ src/com/cpu.o \ src/com/util.o \ src/ct/purge.o \ src/ct/dump.o \ src/ct/build.o \ $(C_OBJS) C64OBJS = src/c64/player.bin CTOBJS = DIST_FILES = \ ./ChangeLog \ ./LICENSE.md \ ./README.md \ ./ccutter \ ./ct2util \ ./tunes/* CheeseCutter-2.10/NEWS000066400000000000000000000000001516216315000145040ustar00rootroot00000000000000CheeseCutter-2.10/README.md000066400000000000000000000015101516216315000152730ustar00rootroot00000000000000CheeseCutter 2 As of 2026/3, SDL2 port has been merged to master. http://theyamo.kapsi.fi/ccutter Programmed by abaddon 2009-2017. Mac OSX and D2 port by Ruk 2013. reSID engine by Dag Lem & A. Lankila. Parts of reSID interface (sid.cpp) by Cadaver / CovertBitops. Includes Acme Assembler 0.91 by Marco Baye libSDL by the SDL team. derelict, http://www.dsource.org/projects/derelict Special thanks to Vent/Triad, Blackspawn, Mr Ammo, Scarzix/Offence, SuperNoise, Wisdom/Crescent and the forgotten ones... Licensed under GNU General Public License (see the file COPYING for details). Binary packages are available for some distributions via: https://repology.org/metapackage/cheesecutter/versions NOTE: authors of CheeseCutter take no responsibility of binaries downloaded from any third party website, including the one above. CheeseCutter-2.10/Version000066400000000000000000000000051516216315000153620ustar00rootroot000000000000002.10 CheeseCutter-2.10/arch/000077500000000000000000000000001516216315000147345ustar00rootroot00000000000000CheeseCutter-2.10/arch/MacOS/000077500000000000000000000000001516216315000156765ustar00rootroot00000000000000CheeseCutter-2.10/arch/MacOS/Contents/000077500000000000000000000000001516216315000174735ustar00rootroot00000000000000CheeseCutter-2.10/arch/MacOS/Contents/Info.plist000066400000000000000000000025241516216315000214460ustar00rootroot00000000000000 CFBundleDevelopmentRegion English CFBundleDocumentTypes CFBundleTypeExtensions ct CFBundleTypeIconFile ct.icns CFBundleTypeName ChesseCutter song file CFBundleTypeOSTypes SONG CFBundleTypeRole Editor LSTypeIsPackage NSPersistentStoreTypeKey Binary CFBundleExecutable ccutter CFBundleGetInfoString Version 2.5.0 CFBundleIconFile ct.icns CFBundleIdentifier fi.kapsi.theyamo.ct CFBundleInfoDictionaryVersion 6.0 CFBundleName CheeseCutter CFBundlePackageType APPL CFBundleSignature CT CFBundleVersion 2.5.0 NSHighResolutionCapable CheeseCutter-2.10/arch/MacOS/Contents/Resources/000077500000000000000000000000001516216315000214455ustar00rootroot00000000000000CheeseCutter-2.10/arch/MacOS/Contents/Resources/ct.icns000066400000000000000000001235531516216315000227420ustar00rootroot00000000000000icnskic08c jP ftypjp2 jp2 Ojp2hihdrcolr"cdefjp2cOQ2d#Creator: JasPer Version 1.900.1R \@@HHPHHPHHPHHPHHP]@@HHPHHPHHPHHPHHP]@@HHPHHPHHPHHPHHP]@@HHPHHPHHPHHPHHP "߂G힒ǐOp J+M#ME%cWown~kn [*_t9߂G=XsW̉uk=Q" kb6-szhIf`u[ɹghpW߂ GQS>QEE<€HaK{H#{BPg=P4WcBIyKZ1܌Q&ϴ\Yi> D-qv=/9kL2jX۞Q g(B3ԳjR 4edmKo ԘՂϥE\ĩ)G6aw#ҕO>&3WŜ^ YV6,(MB3Yi~D-qB{eBe2O{#bVVJҵR r1 4z**$iYں<6hhMf# )LqKɬ"̪m"VTK9q8n«T<%%a[]? D*1U`, JdVldf1W=/KKhj`&oe#$<𞩘3 R?)LqKK71uxKSh :Szۯ>? o"Mci<ٯl EY⣊dKK2]P t{~XҠ&82I6B[+p߆y |icČ8`$MeHm=]ٿj seD3ZοQҽ̭m ke- T[hf[2,juEH5Hk]'m~M-z߱m?' S> I~it#D-IѧKSXqSW2Bs$pŇd"`R]PN 1c4,Nvrb[Y*-gz'roS2/L\eډi 0pb>.? o"McjᳶK{wNGGEReYe4+-8BL;u&䒝(5,!09ƮH8Hk3\3oVK!Vxw}0OIW.j%/ ?Fk:#a[$X?KSyZuy_,4|ﶮT2 |n *w0ZӒhM'*XN<9Ib h RJG,</~7-A V9' S>!D;` uS#pƪ;*)opwΐ?E6t! J֫It,etG'|xq7C~6oViKN{sEF91IetI0C~l~Xoٺd6gzDP^妁PpVV&3Rpi ׸tV"OKS/8 ?ᣆ8~5ǯu?&ڎC4}j)Մu?QZ2]%ܞSO~-Z2[\6_MYcȩv~NU7&Y'I&ć>/%f>*%]J)}-%YM S!^\_3L-{&V.xÏA0ۇ )PJ~*l65N”1ׂ1dR٩hPok7L0>5Kv)U"eZ0L˿=|*3W!?)叺qHBf}yVpJJyYQl F9qR҂;0)d\j -ul/I~Gf&Wok;->g4U_Y/>~뜲#-ýUBxd9ËgB]atRӝÂo6 tݪ9`5M*vx~߳(J8JfqrHEiJƅnu2{asд>WqWc~؈XR>8u,GnHdOs}t@]U:(5&z*YPMم&KL)X(;v,:^* ?`#ĭ##Êׅ}N0[P^1ޡl{ VgЁ8Rd s I&ԩb&p-Y.TXw<2:c.э*̛ʀ1=ˊd% 4V-T3yn[vmZBib}4~t%fY-¹hXN.%P"@x asoMיR`ur+cSak֧PE"ab=S`7d:èP J(f*T bZ+D7, ({w VvV;#Yru_\NhgM3x)/F20s?T$BɊA&,% ;hH YaBi=hE5(Tb _YǨ%9˭JK+Q) S@V~Zu 45:rE3FR"5|@WG2G 4"^&a]<_҇[e")EQ<|X5qdeѦAF702R&-mH]AqD)oѲ^u}6ׯykk2xvGz[6i(O0ݴ7 hUlE#Mr=: )&5mcz;JA19Yx62M2ek=Pwz޿v9!i8n[vX-5 ?MS#ɸ(mPvuzqM:6J37c߃^Qq5so`nr[gᲑl F9JWecgL2QRSԀy6cvN!3|Fp!Uz'w@LX9+56T&G +KU!sW WO^ ^Dbn$423ԋ-8]*J4S @F=Y"jms oKt"A7*2eE:ʠ*\.U45&;T\cuSIpReM9$WWFj[tÜib[>d_}C;}ڄH mܨf|eb[<m.y]?[ iz2kQLSI;(rˊIg5#Ё8Rd s \,y>q'N PPcwDucwfuنXB35fEL^=6P9 dTPV} pufvkàl ĮlA0'SE\w EObIieL`9mf(Db!"ÏC[ZWbtjrqyU {vԋm˲9_v~o|^@Hݥ> \8nuWGi:!FoدS1e19mRLvJ,ISv }c@ aؕ:ct6UA4 F'1m h]82 ]@ۨCzT QgB>Jv"%S}T%19'40DY*ї<8p E"2˭JK+Q) S?4D @_zXSr+xh+l&l*-!ˆ1 ~RղUf/|80.Km$Gδ>Z]D92gbAFR!/_>ВRRu̠%dq_( ґ*6 )2^n^yP/e=h^]J=_]x҉2Jh?'e{HTc_;uQCʯ%^謞M?>2WuXyӁ/-۪ iхC9U6&LDkXؼSlAN B9B gat*;YGA4JZFk@^qh8([R@wU1Tc"W{~4sB!سY9B:sǐoiS#z~> ]wD (5 g)rt A`Rdd(~|U,#z.P%0=mf ve@b2Lb?9%s˭JK+Q)o@3mgvuzf_ C u-sbBD" VE@7Scw82W࿋iwvNkWp2Odp47\Ѕq|b_gnl";〈 '1ݏ7B 骕!웎GYK_d9F8z')5AbD2=ż< s[{6="(AeD-`yIZU,IP+/TUrPt^7of$mq ?t՗>q%0Vesgq8IxŒ6Ve/3TLZF/RY6} &q?% ge-N u3YH6۞6>յ .d6,e]w놢wwdMltv~ߜ #e3Ml:vlg|$[,!sp2#js=AS,_d܈,R1M2`O^蔘7m@1S.Cs%LxEQ H|GR< cꜟঈ߃emI%$ NG/Ktw%>l/8,5j}֏y^Ȓx=>_U9 ׾锳8#@=3vf'5K_`#^whD$gܕq5RJܠ\ޠ,ʧ5G5͙bmƞ"4݇:x3 +{'vq~ ).ǼZb.+Jcdw/-Dӑ ҕFAb2U\&s%Ԗ?{ڀ(|PgϤ_/@pqe+|6(N3.G 'F^T PzD*/'S Gs{Zq js~]g/d i}淈~50@fkԓvet{˪΅L`ˤ?rARL`5Z2lVWZT05Flf2 Q lt6e4~L&Uꓶ h|Y\.xCbN`sČ6_aCRϒ0P2 <96)bxUV>G-#IRFiшGc/ool"BK'}vS@nOʸAʳRϱdOƃkOrpBnF^5UUR\+ [@)hc~9m83S#y@&R[/uYh|%F7<H_ s}W 8ej`DxB&7*g4Pus@T'5Wp$ l(w TȖwZ<;椮 kwY_өieܝmjW78pt\œىY?jTS<&&˓7+] yEIi۔yv.H*xFrm#My(Dd$6x(9d6 K̓L$%QjٚHY@ي ;T\H83ɏYn2~g]Xh?S(`wuX14?D.Tnvtw)-el64L2"ggk\~ٿbO>,zL6'PI]_$juMw*7=x= ҽHJ\帻!,|:E~Aj fۓE@VX,2|IP\[EuKK׏f) a"hWYmYB_p=˺+xMoZs+Ch{5,o#%FEvYީ5Rִ"2%ύТ~zMkKRD\Xʞ?yCckХ9tC Dc4k^䪍h=ŕ nFzo>ځ2 ͇nuo#wx)}&#h !@3z?6F"9:Qgz`'F ^K ~4)\w"R-Ѿe-FxѨ*gP2E?.ߍJ[ZHŒ·C+@w_(gSY{& ݚI g]e! eQ ZQGTu9&hvP xku֝k 4ZhlT]z)TF"w.XuC vj0A+-yk]y.dbz35"II=lW Ihy Ci 8X+kIvkdFE)̾ceQWr49-f&3 UΥe|#Kbsq&8`y>/0_$" ?[~CT+NL]]1=l_FV -} F'N8yl6 @6le:`Lǚ+jO8"ޅP냷JxO םcjOh-RBKmi5 fi(?PPnN˰hQeٰ9_ĢMG2}vR%:,$K@jܿ"$I}enå+:졤j&hAiT^GlF@͘H哕?m*ʛd^ύs!Jqi5J d %!ԁ3h3!cBr۲N3t$Ǒۥ:#n|8OA$qEiu[aIPD*g)w>nO/"~CZ+H @= MGߒUG3:[%8O?zQbTC47,.O~}rxG.$퀢E|4i'e^7Z`ϸh(gthMO(kӞ|=s:mn؞"OܑJe$\ ?t՗>q%0Vesgq8IxȦ Pm;B,ձ]d ^::T#8s9P _QLNL,DŽt?x̎YjYAAn$e|!h.i ,"+>y BOn4Co %b o҆$\E8gd=,zg|%k$t4)nd(9EV jkQDY:zvNRI\ CLټts(5B}yz!t:[9A.;Vq[mQ)fko atbn|J"9*P24y *CsV.?ME3VqiŦ8ǂ(2S2 HC?  ܩvV0|c??1.Oҵ8 3)ֿpEGL,~N`A.gmUIye eAiȰG)λ~@/\/y:5|aEP x )Ym*:s@*bςR2Ƕeڛ1]zQ3:?2~?~Բ:PB '~4`g[fW#׼[_{ta_zk;2BIWlk0 [۾&h3'j~QReTP}oưOeIR!αo\u[P"!vwfN>k};Tf$%HQHd?O+`iUـF3(3NkcC`Jy AQ&LnPzaIS+ec'IX˥[;uG<x3F}=w/AC1SZ :٣{شA nZOV#pX@vca=(#o V/^qw n@]:EGU(5L0i'dU?!_!;ĩmJ>fͼ)IٱZFR.sMX ,yKR^T. z>w߾qlAÚD) 6i4l_<>I+=MY܂/c8ƛI{ctoSuHoG݅A)x.[Jb=w3S;c\ur},B">Ĝ[pMFIW-̳ex{gBU\q&P>G?.(2cHQ`rʚ_\ &.vI#P=U~NHȡ3#6 ;MBӥ"wK9Š'}G~8Tn,i`ZbL?뉹 a1'o8CT냎by@_pK%))_ Q?KC{xօj9{hZqͅ!_4bW쵢eu%Njy>zpEZ M x_̋gW32ɉĈ_J_~*Eg'Ld!k{jD'^2h!e\++ 5@ɘjt}aX7W[Sם`P lGcx\%9emT6744մz a=ng&p#6/i\3zjg2 }2ۯ-΃ϯ7fIV @[JHzP]Ch9p˖[:8g<%CзPr<0'yLO['ؖ3=Mޱ:v_4\ï:)Z5Ś̠dLN _2 +b27[ȉ~- *7dqQ,/ffJj9m25?wwYuZK]rJߏFq k7ӄDr0c=yD|@NH(שׁinTR~?<OVXDSK,.0i_ؿ^Y0:ObfX`2ɰ;OR+`(m<( Y>ZE,4[ߊ>I 6jM 62zf,-Ԡs 1 7օ=N4Ξm(Fin\Z<[$@ɎxިfLϸݴr̓WJI OmoKdF{e )Opc^c⒉UwjQ):^BObN΀}kel fnUIC=!m* 1_,U6v񕃥*M v0PZ5,Y.I'UVooԜ9v/J"ւ:M. b8{fsѻH -^nRaBH RIAB<nN5G R >5=?AA](#˻і / 3Y3<&Q ߿AWC)9~ Z :۹DW{˕ګf0tyhf .(YX i#9CJK80|־u1_^$kЛR/7N,&%*0+@*'Z~@A+' Xl {@"5cIANu = pUlJg IεchԌkB]1(MEP%"1^(#z`iq y %ηwiǍ?NSqb x7:O퍷 Bq lQ߬E!SV'%+fI-624k vYy#l%ߕR SuZ&UMy5N!U ȿ"n)@ @î%61fJ`O-qr%Wnof))Gd]k@e1<եKv]ɳrl4h-ͦЈ1?jg<뉍7ީ)8RԆPE J9$z7b%)‵΄<7\ǚ,Խ N9ˑWPSlR6HICLNZO-Fw4Jy黆\-X*aeN\4RIܝpxF*]0$ٽ~;oLm$9r( "#0_듢Xqz9wF$FRZelnxp]Oi5xgݯ7֞Z^po;O ;/=Pn/p3?J$ݬv2''&Ϸ>[+zsΤiuĒ'F@=l2pS P!\7g\=$P0Q]#SSnSI-.BCG?g{qxǚEiDcs/ֲpy.Vsbқga&k0Qyu3}e%02BiުpCΑZXSl6VDEzbxHdtnb^ŨW~]ǓN]$P~I\!S[dqHzD9-YooPx^N%iJ9ОK_yyԌ>R4"H qH)"@m^R IzI%Pt&}Q.>\9#o [,=(4`W)&r]`pd)T񣖁YU!(~P,ss_K"ߦSp%"! Nin=ڄpVdxpqoŁ!$.qU,5A֪H-#+nBD ?]r07>:Y)` )ǵ|K J6p|H!?;M*Y сJ<, $lFe.zk9 _w FN"aWiu_P=z:IlVۤL:^\06M_Z^sONk.o?\"IT!ˍ S=fa-G9'>y#Gs>֜<̥{k3TAvd#bDFJ/}l%Yjt|O0Auhevne"aMbB&G@yBr Sa4arAOVǶ7R1h%QjOH;,-ר(:>kD\`>H:Q`Qƹ-iCb?Y3~g+vdrq˪WE'~h'"=' 9Qo,S6$ `̜viO2`_R8#5+6&Ae!E5,G-Ȅ'&d_; T_U3LtwH6e"f@¶ʒ- P'>Ct0R$7/'ěRBd=t~%0Ё7A6ՃogP<9JvޔSiN9( ,QL=b&粌sȴiG;~56ok^G`;Ȅ-v3sˆ\o[k(<6Ě23Ě vr55BqD2ke+XGj*b yhv\pA^2שv7#,x<4@&TAr%8HB`qGcͨ<^\^CJ WA{NlzxKX0_ic>]2BMsxVj*0|sz=be-z9 ̀li͊iGpL L]KV58-QfI')dÆ\_,v!i(̒x`4$XHO  YE7Ynwen&@1 @|hG-K? )Q_t$mK*`ҙi {2gVf~᣻48 w(p_%CZPBE.1TW6S;/Y3 gƴ&s 6quݱ z\+̫vu0Qv%0]] [B|#;r~\Hu.S'' qW6eox&5>D"IBUq=&CaU @Һ}_2WK[8lîDž# kɭP2X1bZͨ}c:Xl绱Mdd,Vr}[A!TCyArK(]WMQ]bu4k ?ҫ^{R8䏿4y'͸D(~+!vN;yXN{2ZlIwo 7c^ǥӾ!9Uc vI,}VO57)MP(EC]3xqId 7LĖ ږý~mtI(l:msB N5TK@b" ;Ն+E 'u8& !KЃ>쯑itk+ٮuM˭"y ֦";09ы2Vv?4{zN'S=s&*[gLF8WqP [p .hť\ۍiy=mH!8m4@Y Q+JU-==`a[z.;|,S5 _iTa?{pVNydDX̛[62`nى>u7">AFJ3 @k|TXҶLhIΙiG\r\ G]n{wTS+ ՞ϧo7V6EjBM\5¯IٝUZF)o1Y֏id I* Pڤp*Km n}O@~Tw.Ncs!wuWdGf17v:yL^jolK4%V=g臒GrVǰt(}O񔒻|_QL]Af7JIS5Yãg!I!˵ {_Mh3 MXб$-ok%<d攇L3ѩPEZf ^{%-TXI^ E)ѡ "n)"M:e@}nJ s_jo|Ifߘ%RDʩL4ۭXIzy!Lvv?]ȬX_]Hv S9Nw(Sx%zΌ>vJPj2ɨ'h1٥ K7%nQ -Á )"рQ $$8-T a,̏>Ăpoxt CNPEֹ*usQ*:?&q*rF|6pzkZezi#pžmՌ& 3&Pŵ#ҽhoCː9$C4ot\;A2k{WHȀ lmͿkJ:S= z:L$L{ 6F% rDBաc'žAt)M*rLI]M8{INlqw^I ﶴjj,xg b(+Õқ;1QЏU04{eڂ' k<'*$!m57J塧Ծw' h0p xuJc%١r[]'k޳\dٓtUHuY'J$QD-!"*oMJUYVKEĀ(2ҕ([Bʓ{&7KiM7Ϲb 2M6>#H/ٺuEUt'l[y~n3 kaRš#R 2?r끎¼糰!b<5d/ Y'vl2Ѧm eœ9U?EoNPа4cH\.+ʻ"S)Bo^L)͘1u|Jc}׾G$U/NK%ÙdO KS8bBCp}K8JawDZ#70ĮЙpMM;ؐ?,"aqe8#)VFJz!'9AɞQr@T& /aaJOy@GN.< V$SEWQ~۷XNPDc9s3 # -9Eh'(XH!P$^C;-qN6oI}Ac\uq@'Huf6!.^Uݬ-]tuڧC $*2LZ!VZˀzB9J ORK_\䰄rUT3n cR1m`NcePk?եChJ V26ɖ 0r`d{_w|`6wy e?`١PaNJ`gQ䤠yQwSM: k-W& J?SYGu!Xf+R6Ρ#8iakPkqK^dN ( 81 9~[pH=Ց_oHr%kĘk2'aHM0M}BE)wN]MX'!!NRr4ee)}o*Tհ-_,a[dltZˬF]`#zB<%˒poU,lԗqs`0&F`"zhѓ.%3x]1ik K2r^Nf̼ܢ֝;5gȋa{{c5ϷdLKre̙"ۇw ғ"@{rc 8'ݸ$YnlהC,)'o ;OJA pK]`"%Mq3BUC%>]ϏT+?qit8133L"tCd %$l]]0|a7M% ' 5ji<HeXX 7A#§ .V, :baۨ_؟?փozHVFŜ.|m^RrvU.{vo}ҹ=} ▶K=wF|v"NI*JeGOЮu?B]Ć+Z8^]Rocx.HNp>(BGOcdrS=l|RfWGWFldwxz--TDz Tqo舫9syۂαKĤnX:^ʛ%w."8j|0!rSdAOwFּWJ Z{$vQ r|e M1CRp⥺Dtp3XR6^ jDUvtZR$3ˤ"$7]^"|_!>1U]uġ}Cő9~ײeUD7PҢGrh&qg-9Pt6}c bb."T{qR,SS7+IP+?dZ+=? "H(9c8<]F1(AiC:7DzH*J'O+ؾ{[ .`_Y.Tr9,(4~imdگ_)](á1 Ur|܌9X /ǬaB-(HJh"kUcbp]|uR,$,²_ Oi2 xD\ue-}E6iiN b֯jb#TcZqE&(Va-MĞ9Γw7r=NrXyaO~ 5%+sO{!?9C(pꋼ2b/nCnAG%=/,g@0ETtMmWǁL"8p9A/H9'5,/c jm9U)+nju3\S;VI )ily+lxenjP "fvHz3S2&?qijm9Vg(d7*B{OPq;I\L 6r⥮32KQ4ȵ 穝}sZ@zz\3xqpJe ? 4=? FE:fіw6[}z'H9w *_2Kd˞nID}MFamu DS14DZa<}ժ`qu 1\]3~}73Y)I̞<{T9;zI Ě܌9P?{D~=^nxbcc ?UB0i}H%~J3~,YltQ{b|i{,CGU 0P4y c>+TK@^U ew,@H-8 Sc&2dAp]j ` :ũDhG7 Nf 9BER]P `/l,Q!+k_bgJ *܄ʃjϬB Fa5ĩ(Q֝]AI )f_oN܌ s|:sMȲū^8\aIh3Ն`8)q{`|A%\FO)rPlK7{~I{w:¾E:%vfg3zټ;B.B"_!| [ҭ!\Vj֯iJy UԪza4vvۥZA>hL#%S`Q!5 5A'fzc Ϟct!bG~6,NChEg57%I.(V+EBܣ+1PrXAF^^?nx= :Tŀ>Kx\B{dh؆h˰ׂ1$䧹/M\Nx(}ٓ#T Na"HȦXy&@1˥nb/mT9L8s?G)Oc =O+=Ih \<쨮ؐt[_3hZ՜bA8Q51~lFrF\w8Y2]njD&+&"'!5n"MH>Z+܋k 0+.=&*F-c47eZ:6}S v)^=ǟuc1$߲ R#l x՚ra OXsg^JR6ċuw׌it/9͊S5apo~ fmRY,ivzƥToW['ZXޭJ qos ̌.!aP'UD~ó 7Oψؗb%lF<( \WrDV.b+y``\dAP$=X+G&P PIwǐ4`; 4KyMZB9m,M|~cieA/;A`Wv)OWc|:{ _vl5if\tz[x,W0;yA4aM*1qJ ;`Q'iRXH 9g K5"=F{ ރsY|¿oTvʼno?zO|Ѡ b3'eBcm sFf𜉸tƈ!Dl'1m zVaǁ ,ƳTNevI_jkEW{݀{,*廿o %o g.MUfl[#@I0Ȓ?gɞ39]rr:5q~ΰmC PA2 := aV=o "^t߿rÅؗ&>Sf&KPG(!<Mef9ԡFuU)&܁-;m^?gH;^`K*oag{(eu'KOw'%ž^vϢ>pd&MPDoꈩfMՎ[`g^$u,p0J ѭChB\&sȒxZ%Dw}YBo0Y "hҏBp:$Gv`]㾋m+`5yҘpÁb(_s_MccopbA֕| ̦&)[] PD0![9d)ay}-Yw<݄*jả`z(j9Wx{Y.4fISk4u*s7ռ:8UJvhM R2w1$zkgk+QM֤O*%:O;Bp7-ǩH^6j1,^2"㏋ t&%1[%K' d؄6g.Q|93Ψ HS9yրΎ}a$rHP_PɈ(\GX tY3)ymnS|fhvSdQj}]aX&mWKVV`vv`)}VA:%cy4MD']LO[뫱Lu)1w}`K1rOzmܼo"e~pvzA/s _ֽzdžPF iTԮO+MWضDnܘjiZf؇bj)<0Ϯܳi;H1DS}p:ȎqmG3}D=' @ 3280dgznl b4\yʕkh9̀Ωl f䜼ɘ<>`VimG w\tO@0uc`[&ęlA`FܱWw)D{sDo;Dief{,~XPz_ `G,wL✍ \ Аʁ&c6洖}N=RcǗɳ &g'v3g[~o#}TuV~h_f4W<zy?_"3'<daX qJG)bzmMĶ".Q2c~ղjQa?{L%XtS i]$ͩ iTa?{pVNkZK(~05q6P0uUf^OBzKx6T! ϡ]4?s,#aR\]x*86A;mtbY^8DSTِhҰY|- S?%?/͖<36)rcwJ#v_ <}ϧ2mOp7~ ln՟d: `EV.b/DJy/x"~ͧIݣ ì6q[tIHv9i}ލY0mfGg.">|/ *4Xl*#Οȓz tKV^W i%* W`19 IWH``@Pd^l GR|ؤ%Jveb |h_ G@tk3_\j1:-tcz@8QȧpzJLn0Ĉ.Ije;?(iIꍱ >MHGyYP7$aʫ;_ :}+χ-Sop,~oZ|&o+Y뢇&z:/ ;*UJȬ%&['.૳.ÛawL% Kr^Z%{לq)S* 2߄BouE|%~~O"l|;(sEN>OWHȘdHJ f^hj1Ȍo'43OeM{'j4| ڝ.h9_^~$s`,xZNH,,pmb{0bMCɅIMdP?C5u5 X]Owxkn>kX2=**]=5%^wH6 7ZPtxŀb2X%m"P} .-"ùϦXw0Lg >^7W[lyx3ek=Ip]F5.=OpK5)8?ԭ}]po$|dWJ۹J]I#42x#BGs +F9CaM#݂;O]\ĩWL Bb9[ASΣOu1jD A2,w]UQ`u=tO4BUkR`6 :tśWV {ϵFWW-u jb }9DJZ֜="5Sk)l&IgG0=_9NHHN${.{, oºMh}F8γrnT\|46Mwy?/2X2!xխ . P7ږlM l>d/OFIgɉ&.|q8c_x{rЮu?B]Ć+Z8^]Rh8s2|6+G+Hnl9N7 ѱqs]|;m:#j`xdW>dg&E0c%ƒZ#UQnX:m}yVˤk !z4U ׹V|{#-+ "™V]GZ#`9=z'Vwc)p-GaLµ?2sac`NPPKi')wN\BWζt~I;Mȃ Z5`VMAXέ ~SACV[Ht,.T#/~@%)Z0Xyeuh:7 ( ?ѕםT1eÝl!•ԩ6HB5=LJ˲ұ7|pP\ـW8żELs$STK3\&P»l^?~U )t@EqI)& %tRDzr򅼱X_,#1_,~uLH^ 1QPqu0W!CBk\3i7`ݤ4?ǕxK.j#N&4_WXHfD TE ,%uK?I~ 6ݠ 6 0ĕUōI\6.{CS>z 'aRQ0pgȤ_㻥t~۱Z'%!xP1*jR@Pbܼ9qKt 2[?mB Xev~cY?+Gi| 2TrW۾JŐI\)G=JV*aRceT.H+֭ ,Ċ<5k B&ħQTA'jkPtj CdΣ H\ht|or:_?j^\8^Zjsߢܼ2&d> Z(ѶV~4'S*]!&?Xɥ|\]2 ̫xgJΜREHx9xjw\~`(њzL&FB&[&f܈Ǒ F<Q|[UϤU܀A,0fdyQ؛Yok5#L =c3S>BPlji mƽa\1"3'Oq0W2;E>e K5沔QPLF:Y RcWW?VsEq1K=!.2L&nո $.~*jNs"b( uױ$E0fREe,&[l(_ nh/S{! z@Amds- *?I"EuϚ\.Ч T~x/ul1=/יPv6][[?.NzOfg%y۫̎5d~Jn/$g4\^w9 dGfn0pod|g 3Ն(eu;`&V+*0k;Ta 'wx0Y$g %m -LnD~@.UϐܬmDe"f 3wgD(" : є=o&;{~ ؾE6(;ȏ`{o~ Y`9A tJ(n:nDYHsej|X7'&׾$2I g/6c%B|ڲ- IJcCsd~_C*5YGRN\S8 :K- Pw{J(E`!F#`yd_n ֐'Nٸ4\ήVQ R8dL7x=rXW.2 =GIA$DĆ@0q;Zbgxt2t8v džF++efBZYSN/hVGz}S0@DF]|;@h@CFR  GOE^RGbfAAD'*G yrxn<{l\Yf:{<=<#y{֗Hz"7>3VP ` 92d1F0M˶U^}VHdͅB=]>jv-=oLRKTTs.Ƹ>lTWs;%э\ 'H):gvQ6퀎WL_i068z$X_s]0]] [B|#;rѻ$W2V2 BD c}G9OBʣOUjBmgx У3?=ܗ2 @Q D爈 (uȴ_>=^ş.}|v {Z9/J"!"u=x47(7*i幮`\eC1K4Ӻ$}$ei ԫw.w6q2#h UjI]DUٸz#^F%Bl>V`rD]~Tʕ#L`_a_9103a%xٞ\;̵(B,>9,9PJ0#| cKv>Ntn4>#.5&`fkC Ox?1kԱn.g <;TFʕ|`h]ޱLxbրåˡdF틴(ǟ>N5[ @S§\[oF*F OWedn$%ٷI^$ū(?`CG) D"2!)W* 6@?pqZVyZlf}D ҂cXӸQhC7 {"q $*XH??A(hAkxm)pR~b䠂EϾ<]cb5A/:l ,tpF# #M'gZ!L%I $ =Kfβ4R}2C,y9=GbwN.sd/&I-t m tE(UЂz1`a xap!scgν#2GwՋ[UXeힿW~T9"]VBUhSk; Q԰1 9h`nC t-vH+G~y)!o? owi%'ɺq'qX'T ٺgnf-Q3@cV{lVGRk4q7BsG*ܘ1?^7MReu/OVGYA&(&1xx;R-Lx ).C;oAVRbS6XZ^ >IjIOnn|HQx/|N,_}O]~W&*WﯖkbNpe1hRWtLw6[-zMMËP[(.}UP5Jb/⹢+$JTW׵[f~ P^nR=K̳r!YJ($:-\ :Ņ.$CR y9{e*_w=z֝V,lɻ0ieF5+V&_U:FdFn!uF52GC l͓Pk)̃( ڸId(F à K\)#aB 3t㭓ۏ("9'[9TJx莽^y2eCfIC/W-:TjWOic ]k!tˏ;[ (]SB^&I両$n}]!@(sG:eNj\SeQ -X% 6:A].puu+xa iO 4ٰ.!86*PKy3#8j_a".j?ˆ/8zęߣ!)E+WN|:Q.‹}7[-h4 wZh *-_V0#׼ݫG 6ݴ/k ѧʀ>K)qz`j59#:vPl L6i"qj/.vy$Ix/Ypf2Q$f@Au(o#L 9uxxGְGш̸w:=WsxptaO_l7`3gd3tS ;n4f#cb&O΀{W.cI8` @&֍ٲQ+7CRy2@-Ƥ0Yt9Imb!o ?R`+ƆR']X.ą ?(s/LElƮ3߯mwf{gU x͡۹H&[TO-(pzè5MW83w=m"V&ۖd"&7Sya+ (Rcrc-`ĔbߏSI(EY[jkRu/>Z񉪏yTNV2DgX-AGyPd6KR˜S @~c\J. w2pC_;7] `'wKJj5Ÿ9<0I-e[JhzeUv*3†?3yśQw.D&P9wF[=d 3cH/v'~U'ВX#FFas_»KA-u~H tQ 8Wٝ?a';o)-ǚާpo7u}ҠvWyY?V|+ЮuHV_s닞5?̒JTc/Ct KS= q3B*uhmGaY>ߛC5Ւ>)aBB~kĥ/$/4tT{FnS5{A43"I!@uӷ TcyL~EQ>K'@4s#1iցn,-_Ή\`}Ǐ!ąO②:aTKБ_.VG!毼]{ =<㐭SeA/GS ' ǎUMc+,NVKu.BO&z`k/\Ndšv3kF x52Lr(mP^Je kkӣڌͤQ:/>Oo`P;y@q9~ ә_1{7KwF.v>>[[vV62 ,}# 5,}c\go|qI`;:.?+؃Ird5O~ m` l[6P:@qjǗ0X 1;Z'-8Po'3JL3Ukq@"vQ8^Ar?F2xuw4Xz{.x4x?.jO9杍rl><#u}.=oj5,;>q8e]|?Uu] -CH^*uF2ҏMj.&y.6ݛH,CR)p|j>KH0)g?Usi Tվ`:`Cu{3YڧzJ4YaΔ `=6>&&[鯾qF!DrXXQ!96F;aضX/tNjEຝIZ b!l-WmEQێ:[͙+HGRY`9C(pӑ>$vpB2(S <cnyHs=>"+FSQ%-Bҁ] |uYğu[uUc`b $7u۽L8z.>b!OiTo'`.ƽ6Dv+n!+QfR !傘lfHXi9M*&^8ͩ0qaD#Xu 2 o(P dT 8tiT =Y{-΋{w|BW63zkCw1\ D.koe^ Y;>#w}s#V]ե zc>휅ܦW!+k_bgE6m)}{f5ܧ Sa(,ac" #;t\wxMP)\߄JV7x4€5((ys$Vcy6g Wb@uoWNV`P>Ǎ>Ahڈr\S2:'&!͘H`4'8rk(:&GlsK4$l ȷ5rb>+FEoYGЬ VD`~1J j%mE::nen*7Zv=rd/,zw5gs~Xlȁm5%:e6P%oXN.x-9,24 wue;t*g@^w2]ɴ_@i4SCs .)bX'gϛ^*%n[.Iq+K{Z'E ҊZ2#0jR)adց7Ԃ _}?S;) d7|zDX[4#B]'tKo *$5@b9rkvPHi~X$2mɰʗEv 8&XDoRԖ2r $+QeaJ6< Wޡo;j|`u*E& H )a X FkD\/U PC#\sDT4!#;vζSf{0wk@9r)La@k`D/*Av6ԯWS$ ` Gfވ=By?P!D}Kb]sGaQf21:+$k:AqEd hW%:ŢT35P5|ANHYLb㎹FJ2.|:qwy$2E4lѧrVC,Al8I]@fCheeseCutter-2.10/arch/background.png000066400000000000000000000264461516216315000175750ustar00rootroot00000000000000PNG  IHDR#iCCPICC ProfileX Yy~ѾnPnKħ f@!.āMq7<Гɔ@s.0c ! " ydlL%}%'_L[&7k-p$88:2 zaK` nqd9!>oa^I5MoZ8B yŘ;1NBZM~h'g-,FAo΅RKrtcol1"+eX? #?!fd D[6+TM=7&&}?zkQ!fR7yѼCЊA?tȰcюM;BiMzxӶ&B` Ȁ3@X#`H{@P`?`oϱhpo> KֿCHTg6 7F>(c40zߺ±re>J\L{d C PVQ\3Lp8s)N }}݅nE?B7 ݈AĿ3 R6ih` bE?7o //)1y-o0кC31 0۠ 0zs5r `ڱ[k :©qTKhOd<%80*hwKYA_yYAeE%n`"Oc}?4 @X4i%9C0/, ]p~ $E0@8x/HI dS 8@ W A+ݠ<`LY0UA!!\" ʈ V=x#H$")HC.!u6Ҋ}9} D"QOt'R'v+<Azόbso2>eceg2b"3`*`4̴LbVbegdb~<͂gg1acIe)aigyGBDHF$_R AdűJZf^eegcaVvm.n~ ?1eNN}NtZ+\\&\\Y\ \ni{/pwphyɋ[ûgɗ7ίŸF$+,#"QM@0L0OP%^Ua a'dZqHHHȼhhK1Z1 b]b.Għ%8%,$$%$zQŒϤpRRRQҪAOeP2j22eeŲrrrrro?+*+d)t)RTU S,UUbQڡԤMYZW@ QTJm2]6JRV=ڦFQQQUV/T`հx4<٬SKMuC닶vvvK!\ҙֽ;'G+{/_?e ebpೡ!Ბ~hc3t^'s&LMMMT7ǚ[g[YZTZP߱KzKso(VM(֧ll"lliq; (;;q;v`dh@rrrhxqI)Ʃ͙ùy%eUuk[[;ٽ}iɮ3&=T=<<%<<7Ż{lK.&/X  <84l|.kyHQrmhyFKXm8MwЈ{鏔LҊ:5OE#ўэTVHy[cޛqqq=L.ז(fK>L=8yPE!)4IbrvbKJS*_wW1Q҆h):9|ʱcg(ffef>>t<Ɖ'N^8;qj(K/"9;!i999g<ݖ[tp6DU^chsA+\>w~"G.]//-Ė|(u.q,l<|¾AzeeojTuL+}W6\e͸\x m75nԉ"JG&o֤tf悻lwO#Kђвt?\k`6vgv>xiePa#Gk4Uk׵jwyv&S??N LUN+O7Ϙ}qr6rvu.ϒwJ-sk|qbےҫWpkeeju~-o]j寱H2 a [9 @`6.y f?T`~@p` .\^?Hs֛ O{EȨ´9:iݍ,O$=~F@{\"f 5Hr闲x99y8$*RwjHkb4_i㤫ǣҟ360e\nRhmnlo2*og}qS En==vwzu{?% +,bv4JDߞ(F5.&3`{ 3tzJIJLu?MQcG2J39w>+3;Snٱ|sg ._T[<]*|٣R~TeqUcR7Rwn6]vyݯVZ6ZmvB'skaߣǔn'O&z  =yP0yDoF]O{`wbEbM(:rLǺs>\boK?D؀\q;1F"(T jVm03nZa'qj4i=B9Y$ʬbOakbd2sw_LWPwQn1m]ђǤeJd/ȝOVSWڦLRR #LIzFzCG\nQ}O CV/F0RM},Fw4Y[YيvXBq%9RdM{k{gwo4`,p~\dHrXaDKQ1qWS&a<לks&cħK_~XU-c`i0!H> A۠0* [hL^&y[59xfŲ9x8ŹTMxy}\- K0Œ[xO[Rb2eeˑRs9l%M7**oTUU;nI#_Ds^@L{a{R={ zQqɲiY,Uu-]@{C?g >Ϯ-n}axy^}[L"w?&-P'H(<$zؙ=2Q\by$lv ]}+c-47jZ!<臈1(TfFIz 9k[64/U<.u!XN&|XX:!n~ 3Qh1q[ vQ")iQ2!rro(USURw/w0Sbzz_48e`zm-OۤR|w;(;;;sq Pm;sܷϟ"#!,3={D3p Xɽ1q <4&q$g?"v>8c8RU9Ew \мSUYQ[}j5 cE4l!vTv}{lswh0yWaIo_97{~]\. _C[PXq[H:J eAanNDWG1t\ك) axl=v ca]19GLF{ C(c;NJ(ClfcbLb`jeg!4nUT>Ue;IBLB"TQ#16i{Rv2DOrY TE7%]e1>RTѪ٤uK+:zee况Fw N T2v y޾¡αiˊ.#Oݹ 0$R:a@wlT'q! ͉L;đܓ*q8%mα ' r=k7~nO!|^%ҟeOZ\QQWVd߬rej=uH=e[xi(s%hxkĵ&çӧ?f-}r~~R ?cVW~nmh;G}$t!_὎%ǩBXU{ /ynqQvxQ)e"FSi"FW&VWk%;ԸyxxI|Z넪DJEŮ7HtJHJoȲI)8))V.RmBF]YK=y]L6FƻMrM̉6;-_XmlPlnWXrg? ਐ0𘈁H35L^}r8peciG0̼t9wQ3 g{Ws]Ŋ%.ʎWR>] | SU{?cgÊǮ='O֞5 Ex:;w~?p*( 652 159 LxIDATx6Fura,&'b 7EH^$?UBw7^ @ E\{ Ф?Iй_(n+ΗL -7zqjo*T$  Фl>Wz=B;ܫ|,/@&!  E&Ez=1 z|j}xL%@ <tͷo{)ie xCp20/A&1  [} ,(AҁfYuWOާS38OnqujqZ/^+:P-T5dtΪzpx6o ۻO[Gʡ]D8@INV@.MZ~$S]S Yz)Y-NJ_UW}Ʋ'z3Iq @x-MZ> ܏?^|j/[7^)j:^ur+kt 6]k5TsqZgp=Nkz{ < 99n\@ %yI ^-ήJ^uUu;)NI\g' ls|?j>*^|j'[^/32VsW]>1z3I+g !0gl~ȭ>pg5>j_TIU - 7I Ώ{Y-NKW]Eq | o[5ɋtY @ %pEFZ[Kjqr{՚7珞wV.=eoSM|B I`xfy⤕XtzR&VT2٬&]>oV!@ۤ{Y-̸W]g44<|XX/z'{}il.4 $׏!(풱֫.(^ZHv}5hOQ輹UJautlޔ3n 5onYqZ067A=ȳ,=&, rAMG7am2l::o. =8I @(I@H`llhV^u3qV;r-E L6i_$c@mz Ҥis/=EW]E%q %| o3ޱM|ҬB P 0I?W]θi =e\)ǔzR&6>ޤ2 @Mz^zVSe^uԯD~< du=ּͨi՟UW.~=B¸;N-GkuG ǮKuM U>n 5onYqZ067A=ȳ,=&, rAMG7am2l::o. =8I @(I@H&=>!@%4 @ Ф''5 @D&] @`"D ФKtX L$@ tk h P"@.a  0Mz"|RCJh%:A&IOOj@@MD5@Ds1O~ӊtjՙ],|68I͘J-a韆 m-aZY]q[+UߧcL;tDAGrF'&)_}fc5uR2'g,?g,Ƿbb6}ؖM{0JTOmc1MaTona͘ :%N[4)BMHoe{>;핀ҩEe S[ҩ:T-~vY:Juj]_-aie.g.~pi.o(Syy2` pM4\J`gFԮ&Enk1dl}X|4O7)4SSLEg'Adq7iȾM1fA\25>t3H胋 v iqo)nG&}#COz`A^:6pb SsfOWo܌ mj\ok\- djK:|8b20˖B  {O=Co'@~p}%oX ع 2(lZ,B&A k.4yE7gmI  O+tbFHIzw! X3mf}e(-AqgWl2V4N+XK1Qq0c _xlU H7 izFǟKE2OҽBWD8Z ФoxhH9]9gtPS<8Ӥ@xuo.&|*(jlW*`\ Q!MmaT}l7 }@1'8ܬ%9½~38o1Xm✋=]@Y C Фz@'?C*#wsv) hlܒ ]EدZ0] $Xv#F+b I/x(HI@{e*/dUf 9u]?G3V_B*og  @>-f |]G4l }x8!>gfk¥j T&hRnI* tR Ф?#6!#t7bw>_Mz5z$@R@ >DxS0H)J-+ۓm>/'gץ\/Ǒf 5:-NN6}0p֥r|4XlmcqȀ e~e@ 4ǃ8@x3O!@`i4饏q f47>ChK @ho>}j Ф>A Ф|@KI/}< 7I&@^x@o&@~S; ,M& L&ӧv@XMzA MͧO 4ǃ8@x3O!@`i4饏q f47>C>Lݯ|1@Iz  @nEfVIENDB`CheeseCutter-2.10/arch/fd/000077500000000000000000000000001516216315000153255ustar00rootroot00000000000000CheeseCutter-2.10/arch/fd/ccutter.desktop000066400000000000000000000004031516216315000203660ustar00rootroot00000000000000[Desktop Entry] # Actions=Play; Name=CheeseCutter Comment=SID music editor Comment[fr]=Éditeur de musique SID Terminal=false Exec=ccutter %f Type=Application Icon=cheesecutter Categories=GNOME;Application;AudioVideo;Audio;Video; MimeType=audio/ct;audio/sid; CheeseCutter-2.10/arch/makedmg.sh000077500000000000000000000035451516216315000167070ustar00rootroot00000000000000#!/bin/bash VERSION="2.6" applicationName="CheeseCutter.app" backgroundPictureName="background.png" source="dist" title="CheeseCutter ${VERSION}" size=20000 finalDMGName="CheeseCutter_${VERSION}.dmg" mkdir "${source}" cp -r "${applicationName}" "${source}" hdiutil create -srcfolder "${source}" -volname "${title}" -fs HFS+ \ -fsargs "-c c=64,a=16,e=16" -format UDRW -size ${size}k pack.temp.dmg device=$(hdiutil attach -readwrite -noverify -noautoopen "pack.temp.dmg" | \ egrep '^/dev/' | sed 1q | awk '{print $1}') sleep 5 mkdir /Volumes/"${title}"/.background cp arch/background.png /Volumes/"${title}"/.background cp -r tunes README COPYING Changelog /Volumes/"${title}"/ pushd /Volumes/"${title}" ln -s /Applications popd echo ' tell application "Finder" tell disk "'${title}'" open set current view of container window to icon view set toolbar visible of container window to false set statusbar visible of container window to false set the bounds of container window to {400, 100, 885, 430} set theViewOptions to the icon view options of container window set arrangement of theViewOptions to not arranged set icon size of theViewOptions to 72 set background picture of theViewOptions to file ".background:'${backgroundPictureName}'" delay 1 set position of item "'${applicationName}'" of container window to {100, 100} set position of item "Applications" of container window to {375, 100} update without registering applications close open delay 5 eject end tell end tell ' | osascript chmod -Rf go-w /Volumes/"${title}" sync sync hdiutil detach ${device} hdiutil convert pack.temp.dmg -format UDZO -imagekey zlib-level=9 -o ${finalDMGName} rm pack.temp.dmg CheeseCutter-2.10/doc/000077500000000000000000000000001516216315000145645ustar00rootroot00000000000000CheeseCutter-2.10/doc/README000066400000000000000000000001271516216315000154440ustar00rootroot00000000000000Visit the website at: http://theyamo.kapsi.fi/ccutter for instructions on program use. CheeseCutter-2.10/doc/ccutter.1000066400000000000000000000013151516216315000163170ustar00rootroot00000000000000.TH ccutter "1" "November 2018" "User Commands" .SH NAME ccutter \- SID music editor .SH SYNOPSIS .B ccutter [\fI\,OPTION\/\fR]... [\fI\,FILE\/\fR] .SH DESCRIPTION CheeseCutter (C) 2009\-17 Abaddon Released under GNU GPL. .SH OPTIONS .TP \fB\-b\fR [value] Set playback buffer size (def=2048) .TP \fB\-f\fR Start in fullscreen mode .TP \fB\-nofp\fR Do not use resid\-fp emulation .TP \fB\-fpr\fR [x] Specify filter preset. x = 0..16 for 6581 and 0..1 for 8580 .TP \fB\-i\fR Disable resid interpolation (use fast mode instead) .TP \fB\-m\fR [0|1] Specify SID model for reSID (6581/8580) (def=0) .TP \fB\-n\fR Enable NTSC mode .TP \fB\-r\fR [value] Set playback frequency (def=48000) .TP \fB\-y\fR Use YUV video overlay CheeseCutter-2.10/doc/ccutter.fr.1000066400000000000000000000020561516216315000167300ustar00rootroot00000000000000.TH ccutter "1" "Novembre 2018" "Commandes utilisateur" .SH NOM ccutter \- éditeur de musique SID .SH SYNOPSIS .B ccutter [\fI\,OPTION\/\fR]... [\fI\,FICHIER\/\fR] .SH DESCRIPTION CheeseCutter (C) 2009\-17 Abaddon Publié sous GNU GPL. .SH OPTIONS .TP \fB\-b\fR [valeur] Définir la taille du tampon de lecture (déf=2048) .TP \fB\-f\fR Démarrer en mode plein écran .TP \fB\-nofp\fR Ne pas utiliser l'émulation resid\-fp .TP \fB\-fpr\fR [x] Spécifie le préréglage de filtre. x = 0..16 pour 6581 et 0..1 pour 8580 .TP \fB\-i\fR Désactive l'interpolation resid (utilise le mode rapide à la place) .TP \fB\-m\fR [0|1] Spécifie le modèle SID pour reSID (6581/8580) (déf=0) .TP \fB\-n\fR Active le mode NTSC .TP \fB\-r\fR [value] Paramètre la fréquence de lecture (déf=48000) .TP \fB\-y\fR Utiliser la superposition vidéo YUV .SH AUTEUR Michel Vergnaud \- Copyright 2015\-2016. .PP Cette page de manuel a été traduite par Olivier Humbert "trebmuh" le 24 avril 2019 pour le projet LibraZiK et peut être utilisée par tout un chacun. CheeseCutter-2.10/doc/ct2util.1000066400000000000000000000022641516216315000162400ustar00rootroot00000000000000.TH ct2util "1" "November 2018" "CheeseCutter 2 utilities (Nov 12 2018)" "User Commands" .SH NAME ct2util \- manual page for CheeseCutter 2 utilities (Nov 12 2018) .SH SYNOPSIS .B ct2util \fI\, <-o outfile>\/\fR .SH DESCRIPTION CheeseCutter 2 utilities (Nov 12 2018) .IP ct2util import <\-o outfile> ct2util init <\-o outfile> .SS "Commands:" .TP prg Export song (.ct) to PRG file .TP sid Export song (.ct) to SID file .TP dump Dump song data to assembler source (BETA) .TP import Copy data from another song without overwriting the player .TP init Create a fresh .ct from player binary .SS "General options:" .TP \fB\-o\fR Set output filename (by default gathered from input filename) .SS "Export options:" .TP \fB\-r\fR Relocate output to address (default = ) .TP \fB\-d\fR Set the default subtune (1\-32) .TP \fB\-s\fR Export single subtune (1\-32) (disables \fB\-d\fR) .TP \fB\-zp\fR Relocate zero page (valid range 2\-) .TP \fB\-q\fR Don't output information .PP Prefix value options with '0x' or '$' to indicate a hexadecimal value. .SH "SEE ALSO" .BR ccutter(1), .BR klystrack(1), .BR goattracker (1). CheeseCutter-2.10/doc/ct2util.fr.1000066400000000000000000000033341516216315000166450ustar00rootroot00000000000000.TH ct2util "1" "Novembre 2018" "utilitaires CheeseCutter 2 (12 nov 2018)" "Commandes utilisateur" .SH NOM ct2util \- page de manuel pour les utilitaires de CheeseCutter 2 utilities (12 nov 2018) .SH SYNOPSIS .B ct2util \fI\, <-o fichier_en_sortie>\/\fR .SH DESCRIPTION Utilitaires CheeseCutter 2 (12 nov 2018) .IP ct2util import <\-o fichier_en_sortie> ct2util init <\-o fichier_en_sortie> .SS "Commandes :" .TP prg Exporter le morceau (.ct) en un fichier PRG .TP sid Exporter le morceau (.ct) en un fichier SID .TP dump Déverser les données du morceau dans une source assembleur (BETA) .TP import Copier les données depuis un autre morceau sans écraser le lecteur .TP init Créer un .ct frais depuis le lecteur binaire .SS "Options générales :" .TP \fB\-o\fR Paramètrer le nom de fichier de sortie (par défaut recueilli à partir du nom du fichier d'entrée) .SS "Options d'export :" .TP \fB\-r\fR Relocaliser la sortie à l'adresse (par défaut = ) .TP \fB\-d\fR Définir les sous-réglages par défaut (1\-32) .TP \fB\-s\fR Export une sub-tonalité unique (1\-32) (désactive \fB\fB\-d\fR) .TP \fB\-zp\fR Relocaliser la page zéro (plage valide 2\-) .TP \fB\-q\fR Ne pas afficher d'informations .PP Préfixer les options de valeur par'0x' ou '$' pour indiquer une valeur hexadécimale. .SH "VOIR ÉGALEMENT" .BR ccutter(1), .BR klystrack(1), .BR goattracker (1). .SH AUTEUR Michel Vergnaud \- Copyright 2015\-2016. .PP Cette page de manuel a été traduite par Olivier Humbert "trebmuh" le 24 avril 2019 pour le projet LibraZiK et peut être utilisée par tout un chacun. CheeseCutter-2.10/icons/000077500000000000000000000000001516216315000151325ustar00rootroot00000000000000CheeseCutter-2.10/icons/cc32.png000066400000000000000000000010131516216315000163650ustar00rootroot00000000000000PNG  IHDR TggAMA asRGB cHRMz&u0`:pQ<-PLTEDDD@8(@ 4X@llllL$Є4(xdXl\bKGDo0OIDAT(c``%E€ *+;iiiI` aiiil@U RC#g.h```T K)1s{Zj(HTL@ЀЙfN  \S#gXr̙S V(ѸIibOFM w3p+It30p an!Hi7T[I tȀ #fQD%tEXtdate:create2014-05-17T11:04:43+03:00hQC%tEXtdate:modify2014-05-17T11:04:43+03:005IENDB`CheeseCutter-2.10/icons/cc48.png000066400000000000000000000017001516216315000163770ustar00rootroot00000000000000PNG  IHDR00` gAMA asRGB cHRMz&u0`:pQ<TPLTE " 4(@2P%,-G!?d-9[*Kw6Fo3_EU>hL4(xDDD@8X@llllL$ЄdXl\f6bKGD`ԤoIDATHUێ 4` &!$)Ha% Ɔb (OJ(I! T'f0fz%2ùsrzTri(P2vreRr?S܈0fc%aΖM0'5v`ګfH@!)Aa9gYET;#AS}20/RVE1ΓA_ 4=PyyǺ7fX~r=m {w$MP-9% oC8Rz>֋#ANw`WJkG u]z P!q5qq /G4~+u""?8̐+PsGU)q\Jg=@(< 鋶,<'~B:ڷϹdHBdn.t㖎jk8Ƭ{C]\7"y}CI.m|j?SF:!&]HŻAI!I?{Now.)[CI7 U`<܅[{rRKe ]tћ/rF/C=hex]^Ԩk!q2ZƎ>y6Ӛ%tEXtdate:create2014-05-17T10:57:24+03:00V%tEXtdate:modify2014-05-11T22:47:25+03:00^=2IENDB`CheeseCutter-2.10/icons/cc96.png000066400000000000000000000310261516216315000164060ustar00rootroot00000000000000PNG  IHDR``mo pHYs   OiCCPPhotoshop ICC profilexڝSgTS=BKKoR RB&*! J!QEEȠQ, !{kּ> H3Q5 B.@ $pd!s#~<<+"x M0B\t8K@zB@F&S`cbP-`'{[! eDh;VEX0fK9-0IWfH  0Q){`##xFW<+*x<$9E[-qWW.(I+6aa@.y24x6_-"bbϫp@t~,/;m%h^ uf@Wp~<5j>{-]cK'Xto(hw?G%fIq^D$.Tʳ?D*A, `6B$BB dr`)B(Ͱ*`/@4Qhp.U=pa( Aa!ڈbX#!H$ ɈQ"K5H1RT UH=r9\F;2G1Q= C7F dt1r=6Ыhڏ>C03l0.B8, c˱" VcϱwE 6wB aAHXLXNH $4 7 Q'"K&b21XH,#/{C7$C2'ITFnR#,4H#dk9, +ȅ3![ b@qS(RjJ4e2AURݨT5ZBRQ4u9̓IKhhitݕNWGw Ljg(gwLӋT071oUX**| J&*/Tު UUT^S}FU3S ԖUPSSg;goT?~YYLOCQ_ cx,!k u5&|v*=9C3J3WRf?qtN (~))4L1e\kXHQG6EYAJ'\'GgSSݧ M=:.kDwn^Loy}/TmG X $ <5qo</QC]@Caaᄑ.ȽJtq]zۯ6iܟ4)Y3sCQ? 0k߬~OCOg#/c/Wװwa>>r><72Y_7ȷOo_C#dz%gA[z|!?:eAAA!h쐭!ΑiP~aa~ 'W?pX15wCsDDDޛg1O9-J5*>.j<74?.fYXXIlK9.*6nl {/]py.,:@LN8A*%w% yg"/6шC\*NH*Mz쑼5y$3,幄'L Lݛ:v m2=:1qB!Mggfvˬen/kY- BTZ(*geWf͉9+̳ې7ᒶKW-X潬j9(xoʿܔĹdff-[n ڴ VE/(ۻCɾUUMfeI?m]Nmq#׹=TR+Gw- 6 U#pDy  :v{vg/jBFS[b[O>zG499?rCd&ˮ/~јѡ򗓿m|x31^VwwO| (hSЧc3- cHRMz%u0`:o_F'AIDATx}ityWU=='f  H8xoHӲۦC֚oCfcyx g7c'N)qhϖHL"dER @ 035h4zzegvřBfm}aa ?S\~y!<\$;(!aם7$ [(" ىSHb}9ċDt8UAkh\P[#rE ו$# rJRMO $FFu͸8sy&hE.X aN$l KB!mxN a1k(AU+GNE|En%^<|1p]]MOt%l `y#3)Nv)`dȒ`:7B( BJ2P8Sf[@ՊpR55HEGFXV8s 1WClzի97zm*XYB̹P/>f@bg`(!;P o)D_VBH_Tp )Yͦ'Íc&M@jyXUtDЍÅs゗`"#n.r3"AE7=&&FQ, !#z0vd21!eS 'MmnciͅE5NTm,s["nLs[Ҥak^O4 3e*Cnnnz0SC o+<:ϘԠlF`XXUU˥, "cd2iSs U ՘u)cCiMqrBe[1E.+ʇb A+ ZR-t9|BiC؍(Tgp.)9à1Dd(#mx\$TW.+yjYR`/Ad5cY )O62} .@@(o ]=\6\˽ &!<06B̪*˥(J._&NM+./;(dhsEOodn7+,~fӣpi]bpx/;r;:J7 xpBt8@(3gaQQƒalB2Ee),G& 'PapyK5ڀmFˑ\yuK?.W꒭D HK1A_"1\XVDŽAW.$Bg P9 -g"Ƭ&$qbP$sF?. f͛GL)za}WGoD~ ub)(vGz9L' ոrhrf.G/}|jJmkVuA%" 9j+wȕȘGYyvn0vx#cIbZ] r[O@ !Q9 =7_wyݒ֩Nw62୎\ݤa{Uɱ+- !EB #W'Kq2aF3o<SAAA</,,F1Uu}``w崺M#%u?L>TUwy+7%Go<ם?#xyW@Pe}Jk':O۴}tMXVf15UWEjZQjEs͓NZ芎 DVY:e0O)**J&7o4Y)K .;F:pPd*CрGŃWw/^ztթ':r7L8p ;L-Tǿ& "KV(  / 8>,EPWrԧJ=))]ש]ɚ*))8.J b1f(rWWWG /tPCSw͎/\l*΅WAHT; I8zpr]vqd5v坿vzvx_6~}đ~Փ 72bdk ;*^; WT8N9O &%mgzmj |.%)MShAEd2| W|ա 7E%sC?7 [XV*赩Zg٪4&e}_>GtUw֮)> CWo!IARjTĸ2bFMLLD"H$iwϓˏ{#hHbEʙ-ONI.?"fvj;mXza럮8t{¾ y]嚏?뭾ksڊw<.=uo?akJI8s9t_1^'onU#&w^$qB(PĘ0!A,1g=A(,,u]~Ѷ k׮e6'^Uիׄ?;͖[Y=̙=u|j ;>Vw?BҴ|~|Ĺ3ś+>ԝwn;{r4?|['t1_Uq9㪚N ?|+P6C&Ś9_zԩSlAjjj`F졿Xp;cMdcgYtczN =;õwv /NArR_z;nO' \~dHMIԠ鶧Or"^P87Xf4n6&D0Xd2`ߺx[o;lF7Y@ͥl '3,Dp͚{XβTW.b;/\Tsl_%y<"ooIEgqCCO% H3Y 8 l+@4}wCXJC. f6xoa>AS'9qiZ9͓#'`ĕײ}뭁_;YXprAܲ_@ \#U/O-XS̻K5SGӦ1S^^>666444::zȑ<˨]=Ë lZvVnQѼw Tx~ߏ@2{,{v{+Ό dD*]k>JabfstMW7D97 %b:tݦ~B ڞ=mMqmunϧ2񳷷8ʱp"ǴXq]%Yx2\JKK>lΊ#Mc8`bl$ ][:=B6&ҋ/VWW[0XئljwsKK\+F:|&(Zm!xs9`3,k֬ikkcNlM_ />;|U'D[KK s"!P0F&c?Zv`?x#MS}Nu_cRoYZ~GP;ldRW_ZCjZ%vZkfc9zڨ&8N8sޚ{TQ?566No6cZZaT`4LXꑦL콩) Èaddbbё҆m 1y$:&]p-,]kkkWWhc\Vֹ֊r Mj+^ֿmU- Ŧ,omme[<_AYΰ7)JJJ;HjX Xo +ڤV;+M&ڤ\aӦ3)~2e9QW#W&7xMǢ`رArO/V4m:Akk qd| VNlBچl?7iJ6Zg0ZPcCId֒faDĔceVȬ1g6-\fd50ߵY¶- =#2I>`Jhtr< :zIs[m#? zj?sZ`Ϟ=-t͡)}60ěp0Ym5b5 MA&o2mVh6mޖNژ^BC3,M ڹ˦]q\aV+^laxdؠV|Yz3)1S(:f٤߻ fs+CP^aMwɥn Gw!z[XMzҬi-Ʋ>56cSkiiaDdFԨػw/c:jbj%/a.jQM.dՎ#+?sb |5IHiF>7ls}惑)|jY{UuU>ez,bZ#agU{iiiyo>3L ݭ-_YTZwjن'վ ;V,x/{ ,P)8O4?T*yݥAPau& 37~?4H`GFF{셝I\~7Ԝi`h{ }/쫾3,۞O] d"04zސVcvy @%bMDGԔ1A}gl$#MXC Ct]ti4e0 466={VeE)0@Oki.)itK0Z^ɇ^?585M֏pq94}5Bp{ο䲃O\7%#JQ}gl_1tCS) ܜPd p8Ú0 B$IaTTTx9$ݎJMI:՘AA ,9H`ƱG)^~7|`r|͕?S9?1v@7y y7" a_Lcxw{CɇfϞ:SK~ěgCK!;S*z"*|t#^@8wn] M 0u<ϳQjEQʢ[7w^]\}kC>Ԡ`TZA5T;FA+_]+]QrZ_|Ưށ̬0栔#<j0eyzz:0 RUurr2Cu.~aHПV}N[j/MFsDArtPtS{y+պj&s/w#Ʀz>$ >M1RQ)PENĩ JR5 ]623s^${BB@+"'#{*֙^bk05(]RPTWj*"MO}_}BLjB'׶ZXK T!&(4U'$JaZbyШ]=:lS>?/ K’-?;lZ.hU=e1媡)%]=<(`ܱg=kX;/\TMga3#u-&|}t5m*|5h+ 79I9{Wy0$Ibٕ|>c.V%ӣE~@!M3$!W,NKrR5Z$(5$.\WuxP+Q +M[ =2ߵ kg+ }[ն?6WR%wJۙZfo={%I]YBb}dLV% s ؐH{k}P%w^T$5od%]<կW$.3}TqJ=yjd}VḅfFrBacZ4p"B oX5mtQ5E-"}Ԕ<\VH7OHj͚srdžv,]SIC!'Jdl8)Qma| G"C͙1VD68 H`tjp(Pil$й͒޺0Z]1Dzto7ߚi`~'er%kIDO,T퓧Tpjd_}>58Y@&=X2'("ax/qqihMFO,qlS$XJB Av;_ ro>a"Pڍ9c+ɯtHU҇ :K K-s_5"x- 第lJ<!SJ)3bMӘjR)=\2*D$U7D ۪ǥ+m}/{Fr)^Xz4[㉦;Jd502T)䔬kqlcS͚ ^^+D ]SQEr3X+*,l {C,fEEr==.e2KbbI)%+[Y̤&T#R R^$JJcqk0sI%nU֕+z;58 C71|7$DP79y7D$i#4c/9yDO O% 9_B0i0L*uE]qM:zgP@W#!& 83Uf3w-KE}AIENDB`CheeseCutter-2.10/make-wintest.cmd000066400000000000000000000007071516216315000171200ustar00rootroot00000000000000@echo off REM Expecting directory ..\DLL to contain SDL.dll set /p VER= #include "dynabuf.h" // Variables char *AnyOS_lib_prefix = NULL; // header string of library tree // Functions // used as PLATFORM_INIT: reads "ACME" environment variable void AnyOS_entry(void) { char *env_var; // Find out the path of ACME's library env_var = getenv("ACME"); // if environment variable was found, make a copy if(env_var) { DYNABUF_CLEAR(GlobalDynaBuf); // copy environment variable to global dynamic buffer DynaBuf_add_string(GlobalDynaBuf, env_var); DynaBuf_append(GlobalDynaBuf, '/'); // add dir separator DynaBuf_append(GlobalDynaBuf, '\0'); // add terminator AnyOS_lib_prefix = DynaBuf_get_copy(GlobalDynaBuf); } } #endif CheeseCutter-2.10/src/asm/_std.h000066400000000000000000000026171516216315000164760ustar00rootroot00000000000000// // ACME - a crossassembler for producing 6502/65c02/65816 code. // Copyright (C) 1998-2006 Marco Baye // Have a look at "acme.c" for further info // // Platform specific stuff (in this case, for unknown OSes) #ifndef platform_H #define platform_H // Symbolic constants and macros // Called once on program startup (could register exit handler, if needed) #define PLATFORM_INIT AnyOS_entry() // Convert UNIX-style pathname to AnyOS-style pathname (no change) #define PLATFORM_CONVERTPATHCHAR(a) (a) // String containing the prefix for accessing files from the library tree #define PLATFORM_LIBPREFIX AnyOS_lib_prefix // Setting the created files' types #define PLATFORM_SETFILETYPE_CBM(a) #define PLATFORM_SETFILETYPE_PLAIN(a) #define PLATFORM_SETFILETYPE_TEXT(a) // Platform specific message output #define PLATFORM_WARNING(a) #define PLATFORM_ERROR(a) #define PLATFORM_SERIOUS(a) // Integer-to-character conversion #define PLATFORM_UINT2CHAR(x) do {\ x ^= x >> 16;\ x ^= x >> 8;\ x &= 255;\ } while(0) // Output of platform-specific command line switches #define PLATFORM_OPTION_HELP // Processing of platform-specific command line switches #define PLATFORM_SHORTOPTION_CODE #define PLATFORM_LONGOPTION_CODE // Variables extern char *AnyOS_lib_prefix; // header string of library tree // Prototypes // used as PLATFORM_INIT: reads "ACME" environment variable extern void AnyOS_entry(void); #endif CheeseCutter-2.10/src/asm/acme.c000066400000000000000000000121021516216315000164330ustar00rootroot00000000000000// // ACME - a crossassembler for producing 6502/65c02/65816 code. // Copyright (C) 1998-2006 Marco Baye // // Modified by abaddon 2013 // // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; either version 2 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA #define RELEASE "0.93" // update before release (FIXME) #define CODENAME "Zarquon" // update before release #define CHANGE_DATE "11 Oct" // update before release #define CHANGE_YEAR "2006" // update before release #define HOME_PAGE "http://home.pages.de/~mac_bacon/smorbrod/acme/" #include #include #include #include #include "acme.h" #include "alu.h" #include "basics.h" #include "config.h" #include "cpu.h" #include "dynabuf.h" #include "encoding.h" #include "flow.h" #include "global.h" #include "input.h" #include "label.h" #include "macro.h" #include "mnemo.h" #include "output.h" #include "platform.h" #include "section.h" // Constants static const char FILE_WRITETEXT[] = "w"; static const char FILE_WRITEBINARY[] = "wb"; // names for error messages static const char name_outfile[] = "output filename"; static const char name_dumpfile[] = "label dump filename"; // long options #define OPTION_HELP "help" #define OPTION_FORMAT "format" #define OPTION_OUTFILE "outfile" #define OPTION_LABELDUMP "labeldump" #define OPTION_SETPC "setpc" #define OPTION_CPU "cpu" #define OPTION_INITMEM "initmem" #define OPTION_MAXERRORS "maxerrors" #define OPTION_MAXDEPTH "maxdepth" #define OPTION_USE_STDOUT "use-stdout" #define OPTION_VERSION "version" // Variables static signed long start_addr = -1; // <0 is illegal static signed long fill_value = MEMINIT_USE_DEFAULT; static struct cpu_t *default_cpu = NULL; const char* labeldump_filename = NULL; const char* output_filename = NULL; const char* source = NULL; // maximum recursion depth for macro calls and "!source" signed long macro_recursions_left = MAX_NESTING; signed long source_recursions_left = MAX_NESTING; // Perform a single pass. Returns number of "NeedValue" type errors. static int perform_pass(void) { // call modules' "pass init" functions CPU_passinit(default_cpu);// set default cpu values (PC undefined) Output_passinit(start_addr);// call after CPU_passinit(), to define PC Encoding_passinit(); // set default encoding Section_passinit(); // set initial zone (untitled) // init variables pass_undefined_count = 0; // no "NeedValue" errors yet pass_real_errors = 0; // no real errors yet Parse_source(source); if(pass_real_errors) { longjmp(exception_env, 0); } else Output_end_segment(); return(pass_undefined_count); } // do passes until done (or errors occured). Return whether output is ready. static bool do_actual_work(void) { int undefined_prev, // "NeedValue" errors of previous pass undefined_curr; // "NeedValue" errors of current pass if(Process_verbosity > 1) puts("First pass."); pass_count = 0; undefined_curr = perform_pass(); // First pass // now pretend there has been a pass before the first one undefined_prev = undefined_curr + 1; // As long as the number of "NeedValue" errors is decreasing but // non-zero, keep doing passes. while(undefined_curr && (undefined_curr < undefined_prev)) { pass_count++; undefined_prev = undefined_curr; if(Process_verbosity > 1) puts("Further pass."); undefined_curr = perform_pass(); } // If still errors (unsolvable by doing further passes), // perform additional pass to find and show them if(undefined_curr == 0) return(TRUE); if(Process_verbosity > 1) puts("Further pass needed to find error."); ALU_throw_errors(); // activate error output (CAUTION - one-way!) pass_count++; perform_pass(); // perform pass, but now show "value undefined" return(FALSE); } char* acme_assemble(const char* src, const int *length, char *error) { error_message = error; source = src; msg_stream = stdout; DynaBuf_init();// inits *global* dynamic buffer - important, so first // Init platform-specific stuff. // For example, this could read the library path from an // environment variable, which in turn may need DynaBuf already. PLATFORM_INIT; // init some keyword trees needed for argument handling CPUtype_init(); Outputfile_init(); // Init modules (most of them will just build keyword trees) ALU_init(); Basics_init(); CPU_init(); Encoding_init(); Flow_init(); Input_init(); Label_init(); Macro_init(); Mnemo_init(); Output_init(fill_value); Section_init(); if(!setjmp(exception_env)) { if(do_actual_work()) { return Output_get_final_data(length); } } return NULL; } CheeseCutter-2.10/src/asm/acme.h000066400000000000000000000010711516216315000164430ustar00rootroot00000000000000// // ACME - a crossassembler for producing 6502/65c02/65816 code. // Copyright (C) 1998-2006 Marco Baye // Have a look at "acme.c" for further info // // Main definitions #ifndef acme_H #define acme_H #include "config.h" // Variables extern const char* labeldump_filename; extern const char* output_filename; // maximum recursion depth for macro calls and "!source" extern signed long macro_recursions_left; extern signed long source_recursions_left; // Prototypes // Tidy up before exiting by saving label dump extern int ACME_finalize(int exit_code); #endif CheeseCutter-2.10/src/asm/alu.c000066400000000000000000001230521516216315000163160ustar00rootroot00000000000000// // ACME - a crossassembler for producing 6502/65c02/65816 code. // Copyright (C) 1998-2006 Marco Baye // Have a look at "acme.c" for further info // // Arithmetic/logic unit // 11 Oct 006 Improved float reading in parse_decimal_value() #include #include // only for experimental fp support #include "platform.h" // done first in case "inline" is redefined #include "alu.h" #include "cpu.h" #include "dynabuf.h" #include "encoding.h" #include "global.h" #include "input.h" #include "label.h" #include "section.h" #include "tree.h" // Constants #define FUNCION_DYNABUF_INITIALSIZE 8 // enough for "arctan" #define HALF_INITIAL_STACK_SIZE 8 static const char exception_div_by_zero[] = "Division by zero."; static const char exception_no_value[] = "No value given."; static const char exception_paren_open[] = "Too many '('."; static const char exception_undefined[] = "Value not defined."; #define s_or (s_eor+1) // Yes, I know I'm sick #define s_xor (s_scrxor+3) // Yes, I know I'm sick static const char s_arcsin[] = "arcsin"; #define s_sin (s_arcsin+3) // Yes, I know I'm sick static const char s_arccos[] = "arccos"; #define s_cos (s_arccos+3) // Yes, I know I'm sick static const char s_arctan[] = "arctan"; #define s_tan (s_arctan+3) // Yes, I know I'm sick // Operator handles (FIXME - use function pointers instead? or too slow?) enum op_handle_t { // special values (pseudo operators) OPHANDLE_END, // "reached end of expression" OPHANDLE_RETURN, // "return value to caller" // functions OPHANDLE_INT, // int(v) OPHANDLE_FLOAT, // float(v) OPHANDLE_SIN, // sin(v) OPHANDLE_COS, // cos(v) OPHANDLE_TAN, // tan(v) OPHANDLE_ARCSIN, // arcsin(v) OPHANDLE_ARCCOS, // arccos(v) OPHANDLE_ARCTAN, // arctan(v) // monadic operators OPHANDLE_OPENING, // (v '(', starts subexpression OPHANDLE_NOT, // !v NOT v bit-wise NOT OPHANDLE_NEGATE, // -v Negate OPHANDLE_LOWBYTEOF, // v Highbyte of OPHANDLE_BANKBYTEOF, // ^v Bankbyte of // dyadic operators OPHANDLE_CLOSING, // v) ')', ends subexpression OPHANDLE_POWEROF, // v^w OPHANDLE_MULTIPLY, // v*w OPHANDLE_DIVIDE, // v/w (Integer) Division OPHANDLE_INTDIV, // v/w v DIV w Integer Division OPHANDLE_MODULO, // v%w v MOD w Remainder OPHANDLE_SL, // v<>w v ASR w Arithmetic shift right OPHANDLE_LSR, // v>>>w v LSR w Logical shift right OPHANDLE_ADD, // v+w OPHANDLE_SUBTRACT, // v-w OPHANDLE_EQUALS, // v=w OPHANDLE_LE, // v<=w OPHANDLE_LESSTHAN, // v< w OPHANDLE_GE, // v>=w OPHANDLE_GREATERTHAN, // v> w OPHANDLE_NOTEQUAL, // v!=w v<>w v>>= 1; } return(result); } // arithmetic shift right (works even if C compiler does not support it) static inline intval_t my_asr(intval_t left, intval_t right) { intval_t result = left >> right; // perform shift right // if left operand >= 0, then ASR and LSR are equivalent, so ok // if result < 0, then ASR has been performed, so ok if((left >= 0) || (result < 0)) return(result); // otherwise, correct result and return that return(result | (-1L << (8 * sizeof(intval_t) - right))); } // Lookup (and create, if necessary) label tree item and return its value. // DynaBuf holds the label's name and "zone" its zone. // This function is not allowed to change DynaBuf because that's where the // label name is stored! static void get_label_value(zone_t zone) { label_t* label; // If the label gets created now, mark it as unsure label = Label_find(zone, MVALUE_UNSURE); // in first pass, count usage if(pass_count == 0) label->usage++; // push operand, regardless of whether int or float operand_stack[operand_sp] = label->result; operand_stack[operand_sp++].flags |= MVALUE_EXISTS; } // Parse quoted character. // The character will be converted using the current encoding. static inline void parse_quoted_character(char closing_quote) { intval_t value; // read character to parse - make sure not at end of statement if(GetQuotedByte() == CHAR_EOS) return; // on empty string, complain if(GotByte == closing_quote) { Throw_error(exception_missing_string); Input_skip_remainder(); return; } // parse character value = (intval_t) Encoding_encode_char(GotByte); // Read closing quote (hopefully) if(GetQuotedByte() == closing_quote) GetByte();// If length == 1, proceed with next byte else if(GotByte) { // If longer than one character Throw_error("There's more than one character."); Input_skip_remainder(); } PUSH_INTOPERAND(value, MVALUE_GIVEN | MVALUE_ISBYTE); // Now GotByte = char following closing quote (or CHAR_EOS on error) } // Parse hexadecimal value. It accepts "0" to "9", "a" to "f" and "A" to "F". // Capital letters will be converted to lowercase letters using the flagtable. // The current value is stored as soon as a character is read that is none of // those given above. static void parse_hexadecimal_value(void) {// Now GotByte = "$" or "x" char byte; bool go_on; // continue loop flag int digits = -1, // digit counter flags = MVALUE_GIVEN; intval_t value = 0; do { digits++; go_on = FALSE; byte = GetByte(); // first, convert "A-F" to "a-f" byte |= (BYTEFLAGS(byte) & BYTEIS_UPCASE); // if digit, add digit value if((byte >= '0') && (byte <= '9')) { value = (value << 4) + (byte - '0'); go_on = TRUE;// keep going } // if legal ("a-f") character, add character value if((byte >= 'a') && (byte <= 'f')) { value = (value << 4) + (byte - 'a') + 10; go_on = TRUE;// keep going } } while(go_on); // set force bits if(digits > 2) { if(digits > 4) { if(value < 65536) flags |= MVALUE_FORCE24; } else { if(value < 256) flags |= MVALUE_FORCE16; } } PUSH_INTOPERAND(value, flags); // Now GotByte = non-hexadecimal char } // Parse a decimal value. As decimal values don't use any prefixes, this // function expects the first digit to be read already. If the first two digits // are "0x", this function branches to the one for parsing hexadecimal values. // This function accepts '0' through '9' and one dot ('.') as the decimal // point. The current value is stored as soon as a character is read that is // none of those given above. Float usage is only activated when a decimal // point has been found, so don't expect "100000000000000000000" to work. static inline void parse_decimal_value(void) {// Now GotByte = first digit double fpval, denominator; intval_t intval = (GotByte & 15);// this works. it's ASCII. GetByte(); if((intval == 0) && (GotByte == 'x')) return(parse_hexadecimal_value()); // parse digits until no more while((GotByte >= '0') && (GotByte <= '9')) { intval *= 10; intval += (GotByte & 15);// this works. it's ASCII. GetByte(); } // check whether it's a float if(GotByte == '.') { // read fractional part and store as fp value GetByte(); fpval = intval; denominator = 1; // parse digits until no more while((GotByte >= '0') && (GotByte <= '9')) { fpval *= 10; fpval += (GotByte & 15);// this works. it' ASCII. denominator *= 10; GetByte(); } fpval /= denominator; PUSH_FPOPERAND(fpval, MVALUE_GIVEN); } else { // integer PUSH_INTOPERAND(intval, MVALUE_GIVEN); } // Now GotByte = non-decimal char } // Parse octal value. It accepts "0" to "7". The current value is stored as // soon as a character is read that is none of those given above. static inline void parse_octal_value(void) {// Now GotByte = "&" intval_t value = 0; int flags = MVALUE_GIVEN, digits = 0; // digit counter GetByte(); while((GotByte >= '0') && (GotByte <= '7')) { value = (value << 3) + (GotByte & 7);// this works. it's ASCII. digits++; GetByte(); } // set force bits if(digits > 3) { if(digits > 6) { if(value < 65536) flags |= MVALUE_FORCE24; } else { if(value < 256) flags |= MVALUE_FORCE16; } } PUSH_INTOPERAND(value, flags); // Now GotByte = non-octal char } // Parse binary value. Apart from '0' and '1', it also accepts the characters // '.' and '#', this is much more readable. The current value is stored as soon // as a character is read that is none of those given above. static inline void parse_binary_value(void) {// Now GotByte = "%" intval_t value = 0; bool go_on = TRUE; // continue loop flag int flags = MVALUE_GIVEN, digits = -1; // digit counter do { digits++; switch(GetByte()) { case '0': case '.': value <<= 1; break; case '1': case '#': value = (value << 1) | 1; break; default: go_on = FALSE; } } while(go_on); // set force bits if(digits > 8) { if(digits > 16) { if(value < 65536) flags |= MVALUE_FORCE24; } else { if(value < 256) flags |= MVALUE_FORCE16; } } PUSH_INTOPERAND(value, flags); // Now GotByte = non-binary char } // Parse function call (sin(), cos(), arctan(), ...) static inline void parse_function_call(void) { void* node_body; // make lower case version of name in local dynamic buffer DynaBuf_to_lower(function_dyna_buf, GlobalDynaBuf); // search for tree item if(Tree_easy_scan(function_tree, &node_body, function_dyna_buf)) PUSH_OPERATOR((op_t*) node_body); else Throw_error("Unknown function."); } // Expect operand or monadic operator (hopefully inlined) static inline void expect_operand_or_monadic_operator(void) { op_t* operator; bool perform_negation; SKIPSPACE(); switch(GotByte) { case '+':// anonymous forward label // count plus signs to build name of anonymous label DYNABUF_CLEAR(GlobalDynaBuf); do DYNABUF_APPEND(GlobalDynaBuf, '+'); while(GetByte() == '+'); Label_fix_forward_name(); get_label_value(Section_now->zone); goto now_expect_dyadic; case '-':// NEGATION operator or anonymous backward label // count minus signs in case it's an anonymous backward label perform_negation = FALSE; DYNABUF_CLEAR(GlobalDynaBuf); do { DYNABUF_APPEND(GlobalDynaBuf, '-'); perform_negation = !perform_negation; } while(GetByte() == '-'); SKIPSPACE(); if(BYTEFLAGS(GotByte) & FOLLOWS_ANON) { DynaBuf_append(GlobalDynaBuf, '\0'); get_label_value(Section_now->zone); goto now_expect_dyadic; } // goto means we don't need an "else {" here if(perform_negation) PUSH_OPERATOR(&ops_negate); // State doesn't change break; // Real monadic operators (state doesn't change, still ExpectMonadic) case '!':// NOT operator operator = &ops_not; goto get_byte_and_push_monadic; case '<':// LOWBYTE operator operator = &ops_lowbyteof; goto get_byte_and_push_monadic; case '>':// HIGHBYTE operator operator = &ops_highbyteof; goto get_byte_and_push_monadic; case '^':// BANKBYTE operator operator = &ops_bankbyteof; goto get_byte_and_push_monadic; // Faked monadic operators case '(':// left parenthesis operator = &ops_opening; goto get_byte_and_push_monadic; case ')':// right parenthesis // this makes "()" also throw a syntax error Throw_error(exception_syntax); alu_state = STATE_ERROR; break; // Operands (values, state changes to ExpectDyadic) // Quoted character case '"': case '\'': // Character will be converted using current encoding parse_quoted_character(GotByte); // Now GotByte = char following closing quote goto now_expect_dyadic; // Binary value case '%': parse_binary_value();// Now GotByte = non-binary char goto now_expect_dyadic; // Octal value case '&': parse_octal_value();// Now GotByte = non-octal char goto now_expect_dyadic; // Hexadecimal value case '$': parse_hexadecimal_value(); // Now GotByte = non-hexadecimal char goto now_expect_dyadic; // Program counter case '*': GetByte();// proceed with next char PUSH_INTOPERAND(CPU_pc.intval, CPU_pc.flags | MVALUE_EXISTS); // Now GotByte = char after closing quote goto now_expect_dyadic; // Local label case '.': GetByte();// start after '.' if(Input_read_keyword()) { // Now GotByte = illegal char get_label_value(Section_now->zone); goto now_expect_dyadic; } // goto means we don't need an "else {" here alu_state = STATE_ERROR; break; // Decimal values and global labels default:// (all other characters) if((GotByte >= '0') && (GotByte <= '9')) { parse_decimal_value(); // Now GotByte = non-decimal char goto now_expect_dyadic; } // goto means we don't need an "else {" here if(BYTEFLAGS(GotByte) & STARTS_KEYWORD) { register int length; // Read global label (or "NOT") length = Input_read_keyword(); // Now GotByte = illegal char // Check for NOT. Okay, it's hardcoded, // but so what? Sue me... if((length == 3) && ((GlobalDynaBuf->buffer[0] | 32) == 'n') && ((GlobalDynaBuf->buffer[1] | 32) == 'o') && ((GlobalDynaBuf->buffer[2] | 32) == 't')) { PUSH_OPERATOR(&ops_not); // state doesn't change } else { if(GotByte == '(') parse_function_call(); else { get_label_value(ZONE_GLOBAL); goto now_expect_dyadic; } } } else { // illegal character read - so don't go on PUSH_INTOPERAND(0, 0); // push pseudo value, EXISTS flag is clear if(operator_stack[operator_sp-1] == &ops_return) { PUSH_OPERATOR(&ops_end); alu_state = STATE_TRY_TO_REDUCE_STACKS; } else { Throw_error(exception_syntax); alu_state = STATE_ERROR; } } break; // no other possibilities, so here are the shared endings get_byte_and_push_monadic: GetByte(); PUSH_OPERATOR(operator); // State doesn't change break; now_expect_dyadic: alu_state = STATE_EXPECT_DYADIC_OPERATOR; break; } } // Expect dyadic operator (hopefully inlined) static inline void expect_dyadic_operator(void) { void* node_body; op_t* operator; SKIPSPACE(); switch(GotByte) { // Single-character dyadic operators case '^':// "to the power of" operator = &ops_powerof; goto get_byte_and_push_dyadic; case '+':// add operator = &ops_add; goto get_byte_and_push_dyadic; case '-':// subtract operator = &ops_subtract; goto get_byte_and_push_dyadic; case '*':// multiply operator = &ops_multiply; goto get_byte_and_push_dyadic; case '/':// divide operator = &ops_divide; goto get_byte_and_push_dyadic; case '%':// modulo operator = &ops_modulo; goto get_byte_and_push_dyadic; case '&':// bitwise AND operator = &ops_and; goto get_byte_and_push_dyadic; case '|':// bitwise OR operator = &ops_or; goto get_byte_and_push_dyadic; // This part is commented out because there is no XOR character defined // case ???:// bitwise exclusive OR // operator = &ops_xor; // goto get_byte_and_push_dyadic; case '=':// is equal operator = &ops_equals; goto get_byte_and_push_dyadic; case ')':// closing parenthesis operator = &ops_closing; goto get_byte_and_push_dyadic; // Multi-character dyadic operators // "!=" case '!': if(GetByte() == '=') { operator = &ops_notequal; goto get_byte_and_push_dyadic; } // goto means we don't need an "else {" here Throw_error(exception_syntax); alu_state = STATE_ERROR; break; // "<", "<=", "<<" and "<>" case '<': switch(GetByte()) { case '=':// "<=", less or equal operator = &ops_le; goto get_byte_and_push_dyadic; case '<':// "<<", shift left operator = &ops_sl; goto get_byte_and_push_dyadic; case '>':// "<>", not equal operator = &ops_notequal; goto get_byte_and_push_dyadic; default:// "<", less than operator = &ops_lessthan; goto push_dyadic; } break; // ">", ">=", ">>", ">>>" and "><" case '>': switch(GetByte()) { case '=':// ">=", greater or equal operator = &ops_ge; goto get_byte_and_push_dyadic; case '<':// "><", not equal operator = &ops_notequal; goto get_byte_and_push_dyadic; case '>':// ">>" or ">>>", shift right operator = &ops_asr;// arithmetic shift right if(GetByte() != '>') goto push_dyadic; operator = &ops_lsr;// logical shift right goto get_byte_and_push_dyadic; default:// ">", greater than operator = &ops_greaterthan; goto push_dyadic; } break; // end of expression or text version of dyadic operator default: // check string version of operators if(BYTEFLAGS(GotByte) & STARTS_KEYWORD) { Input_read_and_lower_keyword(); // Now GotByte = illegal char // search for tree item if(Tree_easy_scan(operator_tree, &node_body, GlobalDynaBuf)) { operator = node_body; goto push_dyadic; } // goto means we don't need an "else {" here Throw_error("Unknown operator."); alu_state = STATE_ERROR; } else { operator = &ops_end; goto push_dyadic; } break; // no other possibilities, so here are the shared endings get_byte_and_push_dyadic: GetByte(); push_dyadic: PUSH_OPERATOR(operator); alu_state = STATE_TRY_TO_REDUCE_STACKS; break; } } // call C's sin/cos/tan function static void perform_fp(double (*fn)(double)) { if((RIGHT_FLAGS & MVALUE_IS_FP) == 0) { RIGHT_FPVAL = RIGHT_INTVAL; RIGHT_FLAGS |= MVALUE_IS_FP; } RIGHT_FPVAL = fn(RIGHT_FPVAL); } // make sure arg is in [-1, 1] range before calling function static void perform_ranged_fp(double (*fn)(double)) { if((RIGHT_FLAGS & MVALUE_IS_FP) == 0) { RIGHT_FPVAL = RIGHT_INTVAL; RIGHT_FLAGS |= MVALUE_IS_FP; } if((RIGHT_FPVAL >= -1) && (RIGHT_FPVAL <= 1)) RIGHT_FPVAL = fn(RIGHT_FPVAL); else { if(RIGHT_FLAGS & MVALUE_DEFINED) Throw_error("Argument out of range."); RIGHT_FPVAL = 0; } } // convert right-hand value from fp to int static void right_fp_to_int() { RIGHT_INTVAL = RIGHT_FPVAL; RIGHT_FLAGS &= ~MVALUE_IS_FP; } // check both left-hand and right-hand values. if float, convert to int. // in first pass, throw warning static void both_ensure_int(bool warn) { if(LEFT_FLAGS & MVALUE_IS_FP) { LEFT_INTVAL = LEFT_FPVAL; LEFT_FLAGS &= ~MVALUE_IS_FP; } if(RIGHT_FLAGS & MVALUE_IS_FP) { RIGHT_INTVAL = RIGHT_FPVAL; RIGHT_FLAGS &= ~MVALUE_IS_FP; } Throw_first_pass_warning("Converted to integer for binary logic operator."); } // check both left-hand and right-hand values. if int, convert to float. static void both_ensure_fp() { if((LEFT_FLAGS & MVALUE_IS_FP) == 0) { LEFT_FPVAL = LEFT_INTVAL; LEFT_FLAGS |= MVALUE_IS_FP; } if((RIGHT_FLAGS & MVALUE_IS_FP) == 0) { RIGHT_FPVAL = RIGHT_INTVAL; RIGHT_FLAGS |= MVALUE_IS_FP; } } // make sure both values are float, but mark left one as int (will become one) static void ensure_int_from_fp() { both_ensure_fp(); LEFT_FLAGS &= ~MVALUE_IS_FP; } // Try to reduce stacks by performing high-priority operations static inline void try_to_reduce_stacks(int* open_parentheses) { if(operator_sp < 2) { alu_state = STATE_EXPECT_OPERAND_OR_MONADIC_OPERATOR; return; } if(operator_stack[operator_sp-2]->priority < operator_stack[operator_sp-1]->priority) { alu_state = STATE_EXPECT_OPERAND_OR_MONADIC_OPERATOR; return; } switch(operator_stack[operator_sp-2]->handle) { // special (pseudo) operators case OPHANDLE_RETURN: // don't touch indirect_flag; needed for INDIRECT flag operator_sp--;// decrement operator stack pointer alu_state = STATE_END; break; case OPHANDLE_OPENING: indirect_flag = MVALUE_INDIRECT;// parentheses found switch(operator_stack[operator_sp-1]->handle) { case OPHANDLE_CLOSING:// matching parentheses operator_sp -= 2;// remove both of them alu_state = STATE_EXPECT_DYADIC_OPERATOR; break; case OPHANDLE_END:// unmatched parenthesis (*open_parentheses)++;// count goto RNTLObutDontTouchIndirectFlag; default: Bug_found("StrangeParenthesis", operator_stack[operator_sp-1]->handle); } break; case OPHANDLE_CLOSING: Throw_error("Too many ')'."); goto remove_next_to_last_operator; // functions case OPHANDLE_INT: if(RIGHT_FLAGS & MVALUE_IS_FP) right_fp_to_int(); goto remove_next_to_last_operator; case OPHANDLE_FLOAT: // convert right-hand value from int to fp if((RIGHT_FLAGS & MVALUE_IS_FP) == 0) { RIGHT_FPVAL = RIGHT_INTVAL; RIGHT_FLAGS |= MVALUE_IS_FP; } goto remove_next_to_last_operator; case OPHANDLE_SIN: perform_fp(sin); goto remove_next_to_last_operator; case OPHANDLE_COS: perform_fp(cos); goto remove_next_to_last_operator; case OPHANDLE_TAN: perform_fp(tan); goto remove_next_to_last_operator; case OPHANDLE_ARCSIN: perform_ranged_fp(asin); goto remove_next_to_last_operator; case OPHANDLE_ARCCOS: perform_ranged_fp(acos); goto remove_next_to_last_operator; case OPHANDLE_ARCTAN: perform_fp(atan); goto remove_next_to_last_operator; // monadic operators case OPHANDLE_NOT: // different operations for fp and int if(RIGHT_FLAGS & MVALUE_IS_FP) right_fp_to_int(); RIGHT_INTVAL = ~(RIGHT_INTVAL); RIGHT_FLAGS &= ~MVALUE_ISBYTE; goto remove_next_to_last_operator; case OPHANDLE_NEGATE: // different operations for fp and int if(RIGHT_FLAGS & MVALUE_IS_FP) RIGHT_FPVAL = -(RIGHT_FPVAL); else RIGHT_INTVAL = -(RIGHT_INTVAL); RIGHT_FLAGS &= ~MVALUE_ISBYTE; goto remove_next_to_last_operator; case OPHANDLE_LOWBYTEOF: // fp becomes int if(RIGHT_FLAGS & MVALUE_IS_FP) right_fp_to_int(); RIGHT_INTVAL = (RIGHT_INTVAL) & 255; RIGHT_FLAGS |= MVALUE_ISBYTE; RIGHT_FLAGS &= ~MVALUE_FORCEBITS; goto remove_next_to_last_operator; case OPHANDLE_HIGHBYTEOF: // fp becomes int if(RIGHT_FLAGS & MVALUE_IS_FP) right_fp_to_int(); RIGHT_INTVAL = ((RIGHT_INTVAL) >> 8) & 255; RIGHT_FLAGS |= MVALUE_ISBYTE; RIGHT_FLAGS &= ~MVALUE_FORCEBITS; goto remove_next_to_last_operator; case OPHANDLE_BANKBYTEOF: // fp becomes int if(RIGHT_FLAGS & MVALUE_IS_FP) right_fp_to_int(); RIGHT_INTVAL = ((RIGHT_INTVAL) >> 16) & 255; RIGHT_FLAGS |= MVALUE_ISBYTE; RIGHT_FLAGS &= ~MVALUE_FORCEBITS; goto remove_next_to_last_operator; // dyadic operators case OPHANDLE_POWEROF: if((RIGHT_FLAGS | LEFT_FLAGS) & MVALUE_IS_FP) { both_ensure_fp(); LEFT_FPVAL = pow(LEFT_FPVAL, RIGHT_FPVAL); goto handle_flags_and_dec_stacks; } if(RIGHT_INTVAL >= 0) LEFT_INTVAL = my_pow(LEFT_INTVAL, RIGHT_INTVAL); else { if(RIGHT_FLAGS & MVALUE_DEFINED) Throw_error("Exponent is negative."); LEFT_INTVAL = 0; } goto handle_flags_and_dec_stacks; case OPHANDLE_MULTIPLY: if((RIGHT_FLAGS | LEFT_FLAGS) & MVALUE_IS_FP) { both_ensure_fp(); LEFT_FPVAL *= RIGHT_FPVAL; } else LEFT_INTVAL *= RIGHT_INTVAL; goto handle_flags_and_dec_stacks; case OPHANDLE_DIVIDE: if((RIGHT_FLAGS | LEFT_FLAGS) & MVALUE_IS_FP) { both_ensure_fp(); if(RIGHT_FPVAL) LEFT_FPVAL /= RIGHT_FPVAL; else { if(RIGHT_FLAGS & MVALUE_DEFINED) Throw_error(exception_div_by_zero); LEFT_FPVAL = 0; } } else { if(RIGHT_INTVAL) LEFT_INTVAL /= RIGHT_INTVAL; else { if(RIGHT_FLAGS & MVALUE_DEFINED) Throw_error(exception_div_by_zero); LEFT_INTVAL = 0; } } goto handle_flags_and_dec_stacks; case OPHANDLE_INTDIV: if((RIGHT_FLAGS | LEFT_FLAGS) & MVALUE_IS_FP) { both_ensure_fp(); if(RIGHT_FPVAL) LEFT_INTVAL = LEFT_FPVAL / RIGHT_FPVAL; else { if(RIGHT_FLAGS & MVALUE_DEFINED) Throw_error(exception_div_by_zero); LEFT_INTVAL = 0; } LEFT_FLAGS &= ~MVALUE_IS_FP; } else { if(RIGHT_INTVAL) LEFT_INTVAL /= RIGHT_INTVAL; else { if(RIGHT_FLAGS & MVALUE_DEFINED) Throw_error(exception_div_by_zero); LEFT_INTVAL = 0; } } goto handle_flags_and_dec_stacks; case OPHANDLE_MODULO: if((RIGHT_FLAGS | LEFT_FLAGS) & MVALUE_IS_FP) both_ensure_int(FALSE); if(RIGHT_INTVAL) LEFT_INTVAL %= RIGHT_INTVAL; else { if(RIGHT_FLAGS & MVALUE_DEFINED) Throw_error(exception_div_by_zero); LEFT_INTVAL = 0; } goto handle_flags_and_dec_stacks; case OPHANDLE_ADD: if((RIGHT_FLAGS | LEFT_FLAGS) & MVALUE_IS_FP) { both_ensure_fp(); LEFT_FPVAL += RIGHT_FPVAL; } else LEFT_INTVAL += RIGHT_INTVAL; goto handle_flags_and_dec_stacks; case OPHANDLE_SUBTRACT: if((RIGHT_FLAGS | LEFT_FLAGS) & MVALUE_IS_FP) { both_ensure_fp(); LEFT_FPVAL -= RIGHT_FPVAL; } else LEFT_INTVAL -= RIGHT_INTVAL; goto handle_flags_and_dec_stacks; case OPHANDLE_SL: if(RIGHT_FLAGS & MVALUE_IS_FP) right_fp_to_int(); if(LEFT_FLAGS & MVALUE_IS_FP) LEFT_FPVAL *= (1 << RIGHT_INTVAL); else LEFT_INTVAL <<= RIGHT_INTVAL; goto handle_flags_and_dec_stacks; case OPHANDLE_ASR: if(RIGHT_FLAGS & MVALUE_IS_FP) right_fp_to_int(); if(LEFT_FLAGS & MVALUE_IS_FP) LEFT_FPVAL /= (1 << RIGHT_INTVAL); else LEFT_INTVAL = my_asr(LEFT_INTVAL, RIGHT_INTVAL); goto handle_flags_and_dec_stacks; case OPHANDLE_LSR: if((RIGHT_FLAGS | LEFT_FLAGS) & MVALUE_IS_FP) both_ensure_int(TRUE); LEFT_INTVAL = ((uintval_t) LEFT_INTVAL) >> RIGHT_INTVAL; goto handle_flags_and_dec_stacks; case OPHANDLE_LE: if((RIGHT_FLAGS | LEFT_FLAGS) & MVALUE_IS_FP) { ensure_int_from_fp(); LEFT_INTVAL = (LEFT_FPVAL <= RIGHT_FPVAL); } else LEFT_INTVAL = (LEFT_INTVAL <= RIGHT_INTVAL); goto handle_flags_and_dec_stacks; case OPHANDLE_LESSTHAN: if((RIGHT_FLAGS | LEFT_FLAGS) & MVALUE_IS_FP) { ensure_int_from_fp(); LEFT_INTVAL = (LEFT_FPVAL < RIGHT_FPVAL); } else LEFT_INTVAL = (LEFT_INTVAL < RIGHT_INTVAL); goto handle_flags_and_dec_stacks; case OPHANDLE_GE: if((RIGHT_FLAGS | LEFT_FLAGS) & MVALUE_IS_FP) { ensure_int_from_fp(); LEFT_INTVAL = (LEFT_FPVAL >= RIGHT_FPVAL); } else LEFT_INTVAL = (LEFT_INTVAL >= RIGHT_INTVAL); goto handle_flags_and_dec_stacks; case OPHANDLE_GREATERTHAN: if((RIGHT_FLAGS | LEFT_FLAGS) & MVALUE_IS_FP) { ensure_int_from_fp(); LEFT_INTVAL = (LEFT_FPVAL > RIGHT_FPVAL); } else LEFT_INTVAL = (LEFT_INTVAL > RIGHT_INTVAL); goto handle_flags_and_dec_stacks; case OPHANDLE_NOTEQUAL: if((RIGHT_FLAGS | LEFT_FLAGS) & MVALUE_IS_FP) { ensure_int_from_fp(); LEFT_INTVAL = (LEFT_FPVAL != RIGHT_FPVAL); } else LEFT_INTVAL = (LEFT_INTVAL != RIGHT_INTVAL); goto handle_flags_and_dec_stacks; case OPHANDLE_EQUALS: if((RIGHT_FLAGS | LEFT_FLAGS) & MVALUE_IS_FP) { ensure_int_from_fp(); LEFT_INTVAL = (LEFT_FPVAL == RIGHT_FPVAL); } else LEFT_INTVAL = (LEFT_INTVAL == RIGHT_INTVAL); goto handle_flags_and_dec_stacks; case OPHANDLE_AND: if((RIGHT_FLAGS | LEFT_FLAGS) & MVALUE_IS_FP) both_ensure_int(TRUE); LEFT_INTVAL &= RIGHT_INTVAL; goto handle_flags_and_dec_stacks; case OPHANDLE_EOR: Throw_first_pass_warning("\"EOR\" is deprecated; use \"XOR\" instead."); /*FALLTHROUGH*/ case OPHANDLE_XOR: if((RIGHT_FLAGS | LEFT_FLAGS) & MVALUE_IS_FP) both_ensure_int(TRUE); LEFT_INTVAL ^= RIGHT_INTVAL; goto handle_flags_and_dec_stacks; case OPHANDLE_OR: if((RIGHT_FLAGS | LEFT_FLAGS) & MVALUE_IS_FP) both_ensure_int(TRUE); LEFT_INTVAL |= RIGHT_INTVAL; goto handle_flags_and_dec_stacks; default: Bug_found("IllegalOperatorHandle", operator_stack[operator_sp-2]->handle); break; // no other possibilities, so here are the shared endings // entry point for dyadic operators handle_flags_and_dec_stacks: // Handle flags and decrement value stack pointer // "OR" EXISTS, UNSURE and FORCEBIT flags LEFT_FLAGS |= RIGHT_FLAGS & (MVALUE_EXISTS|MVALUE_UNSURE|MVALUE_FORCEBITS); // "AND" DEFINED flag LEFT_FLAGS &= (RIGHT_FLAGS | ~MVALUE_DEFINED); LEFT_FLAGS &= ~MVALUE_ISBYTE;// clear ISBYTE flag operand_sp--; /*FALLTHROUGH*/ // entry point for monadic operators remove_next_to_last_operator: // toplevel operation was something other than parentheses indirect_flag = 0; /*FALLTHROUGH*/ // entry point for '(' operator (has set indirect_flag, so don't clear now) RNTLObutDontTouchIndirectFlag: // Remove operator and shift down next one operator_stack[operator_sp-2] = operator_stack[operator_sp-1]; operator_sp--;// decrement operator stack pointer break; } } // The core of it. Returns number of parentheses left open. // FIXME - make state machine using function pointers? or too slow? static int parse_expression(result_t* result) { int open_parentheses = 0; operator_sp = 0; // operator stack pointer operand_sp = 0; // value stack pointer // begin by reading value (or monadic operator) alu_state = STATE_EXPECT_OPERAND_OR_MONADIC_OPERATOR; indirect_flag = 0; // Contains either 0 or MVALUE_INDIRECT PUSH_OPERATOR(&ops_return); do { // check stack sizes. enlarge if needed if(operator_sp >= operator_stk_size) enlarge_operator_stack(); if(operand_sp >= operand_stk_size) enlarge_operand_stack(); switch(alu_state) { case STATE_EXPECT_OPERAND_OR_MONADIC_OPERATOR: expect_operand_or_monadic_operator(); break; case STATE_EXPECT_DYADIC_OPERATOR: expect_dyadic_operator(); break;// no fallthrough; state might // have been changed to END or ERROR case STATE_TRY_TO_REDUCE_STACKS: try_to_reduce_stacks(&open_parentheses); break; case STATE_MAX_GO_ON: // suppress case STATE_ERROR: // compiler case STATE_END: // warnings break; } } while(alu_state < STATE_MAX_GO_ON); // done. check state. if(alu_state == STATE_END) { // check for bugs if(operand_sp != 1) Bug_found("OperandStackNotEmpty", operand_sp); if(operator_sp != 1) Bug_found("OperatorStackNotEmpty", operator_sp); // copy result *result = operand_stack[0]; result->flags |= indirect_flag; // OR indirect flag // only allow *one* force bit if(result->flags & MVALUE_FORCE24) result->flags &= ~(MVALUE_FORCE16 | MVALUE_FORCE08); else if(result->flags & MVALUE_FORCE16) result->flags &= ~MVALUE_FORCE08; // if there was nothing to parse, mark as undefined // (so ALU_defined_int() can react) if((result->flags & MVALUE_EXISTS) == 0) result->flags &= ~MVALUE_DEFINED; // do some checks depending on int/float if(result->flags & MVALUE_IS_FP) { /*float*/ // if undefined, return zero if((result->flags & MVALUE_DEFINED) == 0) result->val.fpval = 0; // if value is sure, check to set ISBYTE else if(((result->flags & MVALUE_UNSURE) == 0) && (result->val.fpval <= 255.0) && (result->val.fpval >= -128.0)) result->flags |= MVALUE_ISBYTE; } else { /*int*/ // if undefined, return zero if((result->flags & MVALUE_DEFINED) == 0) result->val.intval = 0; // if value is sure, check to set ISBYTE else if(((result->flags & MVALUE_UNSURE) == 0) && (result->val.intval <= 255) && (result->val.intval >= -128)) result->flags |= MVALUE_ISBYTE; } } else { // State is STATE_ERROR. But actually, nobody cares. // ...errors have already been reported anyway. :) } // return number of open (unmatched) parentheses return(open_parentheses); } // These functions handle numerical expressions. There are operators for // arithmetic, logic, shift and comparison operations. // There are several different ways to call the core function: // intval_t ALU_any_int(void); // returns int value (0 if result was undefined) // intval_t ALU_defined_int(void); // returns int value // if result was undefined, serious error is thrown // void ALU_int_result(result_int_t*); // stores int value and flags (floats are transformed to int) // void ALU_any_result(result_t*); // stores value and flags (result may be either int or float) // int ALU_liberal_int(result_int_t*); // stores int value and flags. allows one '(' too many (for x- // indirect addressing). returns number of additional '(' (1 or 0). // bool ALU_optional_defined_int(intval_t*); // stores int value if given. Returns whether stored. // Throws error if undefined. // return int value (if result is undefined, returns zero) // It the result's "exists" flag is clear (=empty expression), it throws an // error. // If the result's "defined" flag is clear, result_is_undefined() is called. intval_t ALU_any_int(void) { result_t result; if(parse_expression(&result)) Throw_error(exception_paren_open); if((result.flags & MVALUE_EXISTS) == 0) Throw_error(exception_no_value); else if((result.flags & MVALUE_DEFINED) == 0) result_is_undefined(); if(result.flags & MVALUE_IS_FP) return(result.val.fpval); else return(result.val.intval); } // return int value (if result is undefined, serious error is thrown) intval_t ALU_defined_int(void) { result_t result; if(parse_expression(&result)) Throw_error(exception_paren_open); if((result.flags & MVALUE_DEFINED) == 0) Throw_serious_error(exception_undefined); if(result.flags & MVALUE_IS_FP) return(result.val.fpval); else return(result.val.intval); } // Store int value if given. Returns whether stored. Throws error if undefined. // This function needs either a defined value or no expression at all. So // empty expressions are accepted, but undefined ones are not. // If the result's "defined" flag is clear and the "exists" flag is set, it // throws a serious error and therefore stops assembly. bool ALU_optional_defined_int(intval_t* target) { result_t result; if(parse_expression(&result)) Throw_error(exception_paren_open); if((result.flags & MVALUE_GIVEN) == MVALUE_EXISTS) Throw_serious_error(exception_undefined); if((result.flags & MVALUE_EXISTS) == 0) return(FALSE); // something was given, so store if(result.flags & MVALUE_IS_FP) *target = result.val.fpval; else *target = result.val.intval; return(TRUE); } // Store int value and flags (floats are transformed to int) // It the result's "exists" flag is clear (=empty expression), it throws an // error. // If the result's "defined" flag is clear, result_is_undefined() is called. void ALU_int_result(result_int_t* intresult) { result_t result; if(parse_expression(&result)) Throw_error(exception_paren_open); if((result.flags & MVALUE_EXISTS) == 0) Throw_error(exception_no_value); else if((result.flags & MVALUE_DEFINED) == 0) result_is_undefined(); if(result.flags & MVALUE_IS_FP) { intresult->intval = result.val.fpval; intresult->flags = result.flags & ~MVALUE_IS_FP; } else { intresult->intval = result.val.intval; intresult->flags = result.flags; } } // Store int value and flags. // This function allows for one '(' too many. Needed when parsing indirect // addressing modes where internal indices have to be possible. Returns number // of parentheses still open (either 0 or 1). int ALU_liberal_int(result_int_t* intresult) { result_t result; int parentheses_still_open; parentheses_still_open = parse_expression(&result); if(parentheses_still_open > 1) { parentheses_still_open = 0; Throw_error(exception_paren_open); } if((result.flags & MVALUE_EXISTS) && ((result.flags & MVALUE_DEFINED) == 0)) result_is_undefined(); if(result.flags & MVALUE_IS_FP) { intresult->intval = result.val.fpval; intresult->flags = result.flags & ~MVALUE_IS_FP; } else { intresult->intval = result.val.intval; intresult->flags = result.flags; } return(parentheses_still_open); } // Store value and flags (result may be either int or float) // It the result's "exists" flag is clear (=empty expression), it throws an // error. // If the result's "defined" flag is clear, result_is_undefined() is called. void ALU_any_result(result_t* result) { if(parse_expression(result)) Throw_error(exception_paren_open); if((result->flags & MVALUE_EXISTS) == 0) Throw_error(exception_no_value); else if((result->flags & MVALUE_DEFINED) == 0) result_is_undefined(); } CheeseCutter-2.10/src/asm/alu.h000066400000000000000000000044531516216315000163260ustar00rootroot00000000000000// // ACME - a crossassembler for producing 6502/65c02/65816 code. // Copyright (C) 1998-2006 Marco Baye // Have a look at "acme.c" for further info // // ALU stuff (the expression parser) #ifndef alu_H #define alu_H #include "config.h" // Constants // Meaning of bits in "flags" of result_t and result_int_t structures: #define MVALUE_IS_FP (1u << 8) // Floating point value (never set in result_int_t) #define MVALUE_INDIRECT (1u << 7) // Needless parentheses indicate use of indirect addressing modes #define MVALUE_EXISTS (1u << 6) // 0: expression was empty. 1: there was *something* to parse. #define MVALUE_UNSURE (1u << 5) // Value once was related to undefined expression. Needed for producing // the same addresses in all passes; because in the first pass there // will almost for sure be labels that are undefined, you can't simply // get the addressing mode from looking at the parameter's value. #define MVALUE_DEFINED (1u << 4) // 0: undefined expression (value will be zero). 1: known result #define MVALUE_ISBYTE (1u << 3) // Value is guaranteed to fit in one byte #define MVALUE_FORCE24 (1u << 2) // Value usage forces 24-bit usage #define MVALUE_FORCE16 (1u << 1) // Value usage forces 16-bit usage #define MVALUE_FORCE08 (1u << 0) // Value usage forces 8-bit usage #define MVALUE_FORCEBITS (MVALUE_FORCE08|MVALUE_FORCE16|MVALUE_FORCE24) #define MVALUE_GIVEN (MVALUE_DEFINED | MVALUE_EXISTS) // Bit mask for fixed values (defined and existing) // Prototypes // create dynamic buffer, operator/function trees and operator/operand stacks extern void ALU_init(void); // Activate error output for "value undefined" extern void ALU_throw_errors(void); // returns int value (0 if result was undefined) extern intval_t ALU_any_int(void); // returns int value (if result was undefined, serious error is thrown) extern intval_t ALU_defined_int(void); // stores int value if given. Returns whether stored. Throws error if undefined. extern bool ALU_optional_defined_int(intval_t*); // stores int value and flags (floats are transformed to int) extern void ALU_int_result(result_int_t*); // stores int value and flags, allowing for one '(' too many (x-indirect addr) extern int ALU_liberal_int(result_int_t*); // stores value and flags (result may be either int or float) extern void ALU_any_result(result_t*); #endif CheeseCutter-2.10/src/asm/basics.c000066400000000000000000000130311516216315000167740ustar00rootroot00000000000000// // ACME - a crossassembler for producing 6502/65c02/65816 code. // Copyright (C) 1998-2006 Marco Baye // Have a look at "acme.c" for further info // // basic assembly stuff #include #include #include "config.h" #include "cpu.h" #include "basics.h" #include "alu.h" #include "dynabuf.h" #include "input.h" #include "global.h" #include "output.h" #include "tree.h" // Constants #define USERMSG_DYNABUF_INITIALSIZE 80 static const char s_08[] = "08"; #define s_8 (s_08+1) // Yes, I know I'm sick #define s_16 (s_65816+3) // Yes, I know I'm sick // Variables static dynabuf_t* user_message; // dynamic buffer (!warn/error/serious) // Functions // Helper function for !8, !16, !24 and !32 pseudo opcodes static enum eos_t output_objects(void (*fn)(intval_t)) { do fn(ALU_any_int()); while(Input_accept_comma()); return(ENSURE_EOS); } // Insert 8-bit values ("!08" / "!8" / "!by" / "!byte" pseudo opcode) static enum eos_t PO_08(void) { return(output_objects(Output_8b)); } // Insert 16-bit values ("!16" / "!wo" / "!word" pseudo opcode) static enum eos_t PO_16(void) { return(output_objects(Output_16b)); } // Insert 24-bit values ("!24" pseudo opcode) static enum eos_t PO_24(void) { return(output_objects(Output_24b)); } // Insert 32-bit values ("!32" pseudo opcode) static enum eos_t PO_32(void) { return(output_objects(Output_32b)); } // Include binary file static enum eos_t PO_binary(void) { FILE* fd; int byte; intval_t size = -1, // means "not given" => "until EOF" skip = 0; // if file name is missing, don't bother continuing if(Input_read_filename(TRUE)) return(SKIP_REMAINDER); // try to open file fd = fopen(GLOBALDYNABUF_CURRENT, FILE_READBINARY); if(fd == NULL) { Throw_error(exception_cannot_open_input_file); return(SKIP_REMAINDER); } // read optional arguments if(Input_accept_comma()) { if(ALU_optional_defined_int(&size) && (size <0)) Throw_serious_error("Negative size argument."); if(Input_accept_comma()) ALU_optional_defined_int(&skip);// read skip } // check whether including is a waste of time if((size >= 0) && (pass_undefined_count || pass_real_errors)) Output_fake(size); // really including is useless anyway else { // really insert file fseek(fd, skip, SEEK_SET); // set read pointer // if "size" non-negative, read "size" bytes. // otherwise, read until EOF. while(size != 0) { byte = getc(fd); if(byte == EOF) break; Output_byte(byte); size--; } // if more should have been read, warn and add padding if(size > 0) { Throw_warning("Padding with zeroes."); do Output_byte(0); while(--size); } } fclose(fd); // if verbose, produce some output if((pass_count == 0) && (Process_verbosity > 1)) printf("Loaded %d ($%x) bytes from file offset %ld ($%lx).\n", CPU_2add, CPU_2add, skip, skip); return(ENSURE_EOS); } // Reserve space by sending bytes of given value ("!fi" / "!fill" pseudo opcode) static enum eos_t PO_fill(void) { intval_t fill = FILLVALUE_FILL, size = ALU_defined_int(); if(Input_accept_comma()) fill = ALU_any_int(); while(size--) Output_8b(fill); return(ENSURE_EOS); } // show user-defined message static enum eos_t throw_string(const char prefix[], void (*fn)(const char*)) { result_t result; DYNABUF_CLEAR(user_message); DynaBuf_add_string(user_message, prefix); do { if(GotByte == '"') { // parse string GetQuotedByte(); // read initial character // send characters until closing quote is reached while(GotByte && (GotByte != '"')) { DYNABUF_APPEND(user_message, GotByte); GetQuotedByte(); } if(GotByte == CHAR_EOS) return(AT_EOS_ANYWAY); // after closing quote, proceed with next char GetByte(); } else { // parse value ALU_any_result(&result); if(result.flags & MVALUE_IS_FP) { // floating point if(result.flags & MVALUE_DEFINED) DynaBuf_add_double( user_message, result.val.fpval); else DynaBuf_add_string( user_message, ""); } else { // integer if(result.flags & MVALUE_DEFINED) DynaBuf_add_signed_long( user_message, result.val.intval); else DynaBuf_add_string( user_message, ""); } } } while(Input_accept_comma()); DynaBuf_append(user_message, '\0'); fn(user_message->buffer); return(ENSURE_EOS); } //// //static enum eos_t PO_print(void) { // return(throw_string()); //} // throw warning as given in source code static enum eos_t PO_warn(void) { return(throw_string("!warn: ", Throw_warning)); } // throw error as given in source code static enum eos_t PO_error(void) { return(throw_string("!error: ", Throw_error)); } // throw serious error as given in source code static enum eos_t PO_serious(void) { return(throw_string("!serious: ", Throw_serious_error)); } // pseudo ocpode table static node_t pseudo_opcodes[] = { PREDEFNODE(s_08, PO_08), PREDEFNODE(s_8, PO_08), PREDEFNODE("by", PO_08), PREDEFNODE("byte", PO_08), PREDEFNODE(s_16, PO_16), PREDEFNODE("wo", PO_16), PREDEFNODE("word", PO_16), PREDEFNODE("24", PO_24), PREDEFNODE("32", PO_32), PREDEFNODE("bin", PO_binary), PREDEFNODE("binary", PO_binary), PREDEFNODE("fi", PO_fill), PREDEFNODE("fill", PO_fill), // PREDEFNODE("print", PO_print), PREDEFNODE("warn", PO_warn), PREDEFNODE(s_error, PO_error), PREDEFLAST("serious", PO_serious), // ^^^^ this marks the last element }; // register pseudo opcodes and create dynamic buffer void Basics_init(void) { user_message = DynaBuf_create(USERMSG_DYNABUF_INITIALSIZE); Tree_add_table(&pseudo_opcode_tree, pseudo_opcodes); } CheeseCutter-2.10/src/asm/basics.h000066400000000000000000000005251516216315000170050ustar00rootroot00000000000000// // ACME - a crossassembler for producing 6502/65c02/65816 code. // Copyright (C) 1998-2006 Marco Baye // Have a look at "acme.c" for further info // // basic assembly stuff #ifndef basics_H #define basics_H #include "config.h" // Prototypes // register pseudo opcodes and create dynamic buffer extern void Basics_init(void); #endif CheeseCutter-2.10/src/asm/config.h000066400000000000000000000027701516216315000170120ustar00rootroot00000000000000// // ACME - a crossassembler for producing 6502/65c02/65816 code. // Copyright (C) 1998-2006 Marco Baye // Have a look at "acme.c" for further info // // Configuration #ifndef config_H #define config_H // types typedef unsigned int zone_t; typedef signed long intval_t; // at least 32 bits #define INTVAL_MAXCHARACTERS 11 // -2^32 takes 11 characters typedef unsigned long uintval_t; // just for logical shift right typedef struct node_ra_t node_ra_t; typedef struct node_t node_t; typedef struct label_t label_t; // result structure type definition with support for floating point struct result_t { int flags; // Expression flags union { intval_t intval; // integer value double fpval; // floating point value } val; // Expression value }; typedef struct result_t result_t; // either int or float // result structure type definition for int struct result_int_t { int flags; // Expression flags intval_t intval; // Expression value }; typedef struct result_int_t result_int_t; // always int, never float // Debugging flag, should be undefined in release version // #define FDEBUG // Maximum nesting depth of "!src" and macro calls // Is not actually a limitation, but a means of finding recursions #define MAX_NESTING 64 // Default value for output buffer #define FILLVALUE_INITIAL 0 // Default value for "!fill" #define FILLVALUE_FILL 0 // Nullpointer definition #ifndef NULL #define NULL ((void *)0) #endif // Boolean values #ifndef FALSE typedef int bool; #define FALSE 0 #define TRUE 1 #endif #endif CheeseCutter-2.10/src/asm/cpu.c000066400000000000000000000161761516216315000163340ustar00rootroot00000000000000// // ACME - a crossassembler for producing 6502/65c02/65816 code. // Copyright (C) 1998-2006 Marco Baye // Have a look at "acme.c" for further info // // CPU stuff #include "config.h" #include "alu.h" #include "cpu.h" #include "dynabuf.h" #include "global.h" #include "input.h" #include "mnemo.h" #include "output.h" #include "tree.h" // Constants static struct cpu_t CPU_6502 = { keyword_is_6502mnemo, NULL, // no long registers CPUFLAG_INDJMPBUGGY, // JMP ($xxFF) is buggy 234 // !align fills with "NOP" }; static struct cpu_t CPU_6510 = { keyword_is_6510mnemo, NULL, // no long registers CPUFLAG_INDJMPBUGGY, // JMP ($xxFF) is buggy 234 // !align fills with "NOP" }; static struct cpu_t CPU_65c02= { keyword_is_65c02mnemo, NULL, // no long registers 0, // no flags 234 // !align fills with "NOP" }; /* static struct cpu_t CPU_Rockwell65c02 = { keyword_is_Rockwell65c02mnemo, NULL, // no long registers 0, // no flags 234 // !align fills with "NOP" }; static struct cpu_t CPU_WDC65c02 = { keyword_is_WDC65c02mnemo, NULL, // no long registers 0, // no flags 234 // !align fills with "NOP" }; */ static bool long_of_65816[2]; // 65816 struct needs array of 2 bools static struct cpu_t CPU_65816 = { keyword_is_65816mnemo, long_of_65816, // two booleans for long accu/long regs 0, // no flags 234 // !align fills with "NOP" }; #define s_rl (s_brl+1) // Yes, I know I'm sick // Variables struct cpu_t *CPU_now; // Struct of current CPU type (default 6502) result_int_t CPU_pc; // (Pseudo) program counter at start of statement int CPU_2add; // Increase PC by this after statement static intval_t current_offset; // PseudoPC - MemIndex static bool uses_pseudo_pc; // offset assembly active? // predefined stuff static node_t* CPU_tree = NULL;// tree to hold CPU types static node_t CPUs[] = { // PREDEFNODE("z80", &CPU_Z80), PREDEFNODE("6502", &CPU_6502), PREDEFNODE("6510", &CPU_6510), PREDEFNODE("65c02", &CPU_65c02), // PREDEFNODE("Rockwell65c02", &CPU_Rockwell65c02), // PREDEFNODE("WDC65c02", &CPU_WDC65c02), PREDEFLAST(s_65816, &CPU_65816), // ^^^^ this marks the last element }; // Insert byte until PC fits condition static enum eos_t PO_align(void) { intval_t and, equal, fill, test = CPU_pc.intval; // make sure PC is defined. if((CPU_pc.flags & MVALUE_DEFINED) == 0) { Throw_error(exception_pc_undefined); CPU_pc.flags |= MVALUE_DEFINED; // do not complain again return(SKIP_REMAINDER); } and = ALU_defined_int(); if(!Input_accept_comma()) Throw_error(exception_syntax); equal = ALU_defined_int(); if(Input_accept_comma()) fill = ALU_any_int(); else fill = CPU_now->default_align_value; while((test++ & and) != equal) Output_8b(fill); return(ENSURE_EOS); } // Try to find CPU type held in DynaBuf. Returns whether succeeded. bool CPU_find_cpu_struct(struct cpu_t** target) { void* node_body; if(!Tree_easy_scan(CPU_tree, &node_body, GlobalDynaBuf)) return(FALSE); *target = node_body; return(TRUE); } // Select CPU ("!cpu" pseudo opcode) static enum eos_t PO_cpu(void) { struct cpu_t* cpu_buffer = CPU_now; // remember current cpu if(Input_read_and_lower_keyword()) if(!CPU_find_cpu_struct(&CPU_now)) Throw_error("Unknown processor."); // If there's a block, parse that and then restore old value! if(Parse_optional_block()) CPU_now = cpu_buffer; return(ENSURE_EOS); } static const char Warning_old_offset_assembly[] = "\"!pseudopc/!realpc\" is deprecated; use \"!pseudopc {}\" instead."; // Start offset assembly static enum eos_t PO_pseudopc(void) { bool outer_state = uses_pseudo_pc; intval_t new_pc, outer_offset = current_offset; int outer_flags = CPU_pc.flags; // set new new_pc = ALU_defined_int(); current_offset = (current_offset + new_pc - CPU_pc.intval) & 0xffff; CPU_pc.intval = new_pc; CPU_pc.flags |= MVALUE_DEFINED; uses_pseudo_pc = TRUE; // If there's a block, parse that and then restore old value! if(Parse_optional_block()) { // restore old uses_pseudo_pc = outer_state; CPU_pc.flags = outer_flags; CPU_pc.intval = (outer_offset + CPU_pc.intval - current_offset) & 0xffff; current_offset = outer_offset; } else Throw_first_pass_warning(Warning_old_offset_assembly); return(ENSURE_EOS); } // End offset assembly static enum eos_t PO_realpc(void) { Throw_first_pass_warning(Warning_old_offset_assembly); // deactivate offset assembly CPU_pc.intval = (CPU_pc.intval - current_offset) & 0xffff; current_offset = 0; uses_pseudo_pc = FALSE; return(ENSURE_EOS); } // return whether offset assembly is active bool CPU_uses_pseudo_pc(void) { return(uses_pseudo_pc); } // If cpu type and value match, set register length variable to value. // If cpu type and value don't match, complain instead. static void check_and_set_reg_length(bool *var, bool long_reg) { if(long_reg && ((CPU_now->long_regs) == NULL)) Throw_error("Chosen CPU does not support long registers."); else *var = long_reg; } // Set register length, block-wise if needed. static enum eos_t set_register_length(bool *var, bool long_reg) { bool buffer = *var; // Set new register length (or complain - whichever is more fitting) check_and_set_reg_length(var, long_reg); // If there's a block, parse that and then restore old value! if(Parse_optional_block()) check_and_set_reg_length(var, buffer);// restore old length return(ENSURE_EOS); } // Switch to long accu ("!al" pseudo opcode) static enum eos_t PO_al(void) { return(set_register_length(CPU_now->long_regs + LONGREG_IDX_A, TRUE)); } // Switch to short accu ("!as" pseudo opcode) static enum eos_t PO_as(void) { return(set_register_length(CPU_now->long_regs + LONGREG_IDX_A, FALSE)); } // Switch to long index registers ("!rl" pseudo opcode) static enum eos_t PO_rl(void) { return(set_register_length(CPU_now->long_regs + LONGREG_IDX_R, TRUE)); } // Switch to short index registers ("!rs" pseudo opcode) static enum eos_t PO_rs(void) { return(set_register_length(CPU_now->long_regs + LONGREG_IDX_R, FALSE)); } // pseudo opcode table static node_t pseudo_opcodes[] = { PREDEFNODE("align", PO_align), PREDEFNODE("cpu", PO_cpu), PREDEFNODE("pseudopc", PO_pseudopc), PREDEFNODE("realpc", PO_realpc), PREDEFNODE("al", PO_al), PREDEFNODE("as", PO_as), PREDEFNODE(s_rl, PO_rl), PREDEFLAST("rs", PO_rs), // ^^^^ this marks the last element }; // Set default values for pass void CPU_passinit(struct cpu_t* cpu_type) { // handle cpu type (default is 6502) CPU_now = cpu_type ? cpu_type : &CPU_6502; CPU_pc.flags = 0; // not defined yet CPU_pc.intval = 512; // actually, there should be no need to init CPU_2add = 0; // Increase PC by this at end of statement CPU_65816.long_regs[LONGREG_IDX_A] = FALSE; // short accu CPU_65816.long_regs[LONGREG_IDX_R] = FALSE; // short index regs uses_pseudo_pc = FALSE; // offset assembly is not active, current_offset = 0; // so offset is 0 } // create cpu type tree (is done early) void CPUtype_init(void) { Tree_add_table(&CPU_tree, CPUs); } // register pseudo opcodes (done later) void CPU_init(void) { Tree_add_table(&pseudo_opcode_tree, pseudo_opcodes); } // set program counter to defined value void CPU_set_pc(intval_t new_pc) { CPU_pc.flags |= MVALUE_DEFINED; CPU_pc.intval = new_pc; } CheeseCutter-2.10/src/asm/cpu.h000066400000000000000000000025711516216315000163330ustar00rootroot00000000000000// // ACME - a crossassembler for producing 6502/65c02/65816 code. // Copyright (C) 1998-2006 Marco Baye // Have a look at "acme.c" for further info // // CPU stuff #ifndef cpu_H #define cpu_H #include "config.h" // CPU type structure definition struct cpu_t { // This function is not allowed to change GlobalDynaBuf // because that's where the mnemonic is stored! bool (*keyword_is_mnemonic)(int); bool* long_regs; // pointer to array of bool: #define LONGREG_IDX_A 0 // array index for "long accu" bool #define LONGREG_IDX_R 1 // array index for "long index regs" bool int flags; char default_align_value; }; #define CPUFLAG_INDJMPBUGGY (1u << 0) // Variables extern struct cpu_t *CPU_now;// Struct of current CPU type (default 6502) extern result_int_t CPU_pc; // Current program counter (pseudo value) extern int CPU_2add; // add to PC after statement // Prototypes // create cpu type tree (is done early) extern void CPUtype_init(void); // register pseudo opcodes (done later) extern void CPU_init(void); // Set default values for pass extern void CPU_passinit(struct cpu_t* cpu_type); // set program counter to defined value extern void CPU_set_pc(intval_t new_pc); // Try to find CPU type held in DynaBuf. Returns whether succeeded. extern bool CPU_find_cpu_struct(struct cpu_t** target); // return whether offset assembly is active extern bool CPU_uses_pseudo_pc(void); #endif CheeseCutter-2.10/src/asm/dynabuf.c000066400000000000000000000077431516216315000171750ustar00rootroot00000000000000// // ACME - a crossassembler for producing 6502/65c02/65816 code. // Copyright (C) 1998-2006 Marco Baye // Have a look at "acme.c" for further info // // Dynamic buffer stuff #include #include #include #include "acme.h" #include "global.h" #include "dynabuf.h" #include "input.h" // Constants and macros // macro to grow dynabuf (CAUTION - fails if a < 1) #define MAKE_LARGER_THAN(a) (2*(a)) // if someone requests a dynabuf smaller than this, use this size instead #define DYNABUF_MINIMUM_INITIALSIZE 128 // should be >0 (see above) // initial size for global dynabuf // (as it holds macros, loop bodies, etc., make it large to begin with) #define GLOBALDYNABUF_INITIALSIZE 1024 // should be >0 (see above) // Variables dynabuf_t* GlobalDynaBuf; // global dynamic buffer // Functions // get new buffer of given size static void resize(dynabuf_t* db, size_t new_size) { char* new_buf; new_buf = realloc(db->buffer, new_size); if(new_buf == NULL) Throw_serious_error(exception_no_memory_left); db->reserved = new_size; db->buffer = new_buf; } // Exported functions // Create and init a dynamic buffer and return pointer dynabuf_t* DynaBuf_create(int initial_size) { dynabuf_t* db; if(initial_size < DYNABUF_MINIMUM_INITIALSIZE) initial_size = DYNABUF_MINIMUM_INITIALSIZE; if((db = malloc(sizeof(dynabuf_t)))) { db->size = 0; db->reserved = initial_size; db->buffer = malloc(initial_size); if(db->buffer) return(db);// if both pointers are != NULL, no error } // otherwise, complain fputs("Error: No memory for dynamic buffer.\n", stderr); exit(EXIT_FAILURE); } // Enlarge buffer void DynaBuf_enlarge(dynabuf_t* db) { resize(db, MAKE_LARGER_THAN(db->reserved)); } // Claim enough memory to hold a copy of the current buffer contents, // make that copy and return it. // The copy must be released by calling free(). char* DynaBuf_get_copy(dynabuf_t* db) { char *copy; copy = safe_malloc(db->size); memcpy(copy, db->buffer, db->size); return(copy); } // add char to buffer void DynaBuf_append(dynabuf_t* db, char byte) { DYNABUF_APPEND(db, byte); } // Append string to buffer (without terminator) void DynaBuf_add_string(dynabuf_t* db, const char* string) { char byte; while((byte = *string++)) DYNABUF_APPEND(db, byte); } // make sure DynaBuf is large enough to take "size" more bytes // return pointer to end of current contents static char* ensure_free_space(dynabuf_t* db, int size) { while((db->reserved - db->size) < size) resize(db, MAKE_LARGER_THAN(db->reserved)); return(db->buffer + db->size); } // add string version of int to buffer (without terminator) void DynaBuf_add_signed_long(dynabuf_t* db, signed long value) { char *write = ensure_free_space(db, INTVAL_MAXCHARACTERS + 1); db->size += sprintf(write, "%ld", value); } // add string version of float to buffer (without terminator) void DynaBuf_add_double(dynabuf_t* db, double value) { char *write = ensure_free_space(db, 40); // reserve 40 chars // write up to 30 significant characters. remaining 10 should suffice // for sign, decimal point, exponent, terminator etc. db->size += sprintf(write, "%.30g", value); } // Convert buffer contents to lower case (target and source may be identical) void DynaBuf_to_lower(dynabuf_t* target, dynabuf_t* source) { char *read, *write; // make sure target can take it if(source->size > target->reserved) resize(target, source->size); // convert to lower case read = source->buffer;// CAUTION - ptr may change when buf grows! write = target->buffer;// CAUTION - ptr may change when buf grows! while(*read) *write++ = (*read++) | 32; // Okay, so this method of converting to lowercase is lousy. // But actually it doesn't matter, because only pre-defined // keywords are converted, and all of those are plain // old-fashioned 7-bit ASCII anyway. So I guess it'll do. *write = '\0'; // terminate } // Initialisation - allocate global dynamic buffer void DynaBuf_init(void) { GlobalDynaBuf = DynaBuf_create(GLOBALDYNABUF_INITIALSIZE); } CheeseCutter-2.10/src/asm/dynabuf.h000066400000000000000000000034671516216315000172010ustar00rootroot00000000000000// // ACME - a crossassembler for producing 6502/65c02/65816 code. // Copyright (C) 1998-2006 Marco Baye // Have a look at "acme.c" for further info // // Dynamic buffer stuff #ifndef dynabuf_H #define dynabuf_H #include "config.h" // Macros #define DYNABUF_CLEAR(db) {db->size = 0;} #define DYNABUF_APPEND(db, byte) do {\ if(db->size == db->reserved)\ DynaBuf_enlarge(db);\ db->buffer[(db->size)++] = byte;\ } while(0) // The next one is dangerous - the buffer location can change when a character // is appended. So after calling this, don't change the buffer as long as you // use the address. #define GLOBALDYNABUF_CURRENT (GlobalDynaBuf->buffer) // dynamic buffer structure struct dynabuf_t { char* buffer; // pointer to buffer int size; // size of buffer's used portion int reserved; // total size of buffer }; typedef struct dynabuf_t dynabuf_t; // Variables extern dynabuf_t* GlobalDynaBuf; // global dynamic buffer // Prototypes // create global DynaBuf (call once on program startup) extern void DynaBuf_init(void); // create (private) DynaBuf extern dynabuf_t* DynaBuf_create(int initial_size); // call whenever buffer is too small extern void DynaBuf_enlarge(dynabuf_t* db); // return malloc'd copy of buffer contents extern char* DynaBuf_get_copy(dynabuf_t* db); // copy string to buffer (without terminator) extern void DynaBuf_add_string(dynabuf_t* db, const char*); // add string version of int to buffer (without terminator) extern void DynaBuf_add_signed_long(dynabuf_t* db, signed long value); // add string version of float to buffer (without terminator) extern void DynaBuf_add_double(dynabuf_t* db, double value); // converts buffer contents to lower case extern void DynaBuf_to_lower(dynabuf_t* target, dynabuf_t* source); // add char to buffer extern void DynaBuf_append(dynabuf_t* db, char); #endif CheeseCutter-2.10/src/asm/encoding.c000066400000000000000000000147541516216315000173330ustar00rootroot00000000000000// // ACME - a crossassembler for producing 6502/65c02/65816 code. // Copyright (C) 1998-2006 Marco Baye // Have a look at "acme.c" for further info // // Character encoding stuff #include #include #include "alu.h" #include "acme.h" #include "dynabuf.h" #include "encoding.h" #include "global.h" #include "output.h" #include "input.h" #include "tree.h" // Encoder function type definition typedef char (*encoder_t)(char) ; // Constants static const char s_pet[] = "pet"; static const char s_raw[] = "raw"; static const char s_scr[] = "scr"; // Variables static char outermost_table[256]; // space for encoding table... static char* loaded_table = outermost_table; // ...loaded from file // predefined stuff static node_t* encoder_tree = NULL; // tree to hold encoders // Functions // convert character using current encoding // Conversion function pointer. No init needed: gets set before each pass. char (*Encoding_encode_char)(char); // Insert string(s) static enum eos_t encode_string(encoder_t inner_encoder, char eor) { encoder_t outer_encoder = Encoding_encode_char;// buffer encoder // make given encoder the current one (for ALU-parsed values) Encoding_encode_char = inner_encoder; do { if(GotByte == '"') { // read initial character GetQuotedByte(); // send characters until closing quote is reached while(GotByte && (GotByte != '"')) { Output_8b(eor ^ Encoding_encode_char(GotByte)); GetQuotedByte(); } if(GotByte == CHAR_EOS) return(AT_EOS_ANYWAY); // after closing quote, proceed with next char GetByte(); } else { // Parse value. No problems with single characters // because the current encoding is // temporarily set to the given one. Output_8b(ALU_any_int()); } } while(Input_accept_comma()); Encoding_encode_char = outer_encoder; // reactivate buffered encoder return(ENSURE_EOS); } // Insert text string (default format) static enum eos_t PO_text(void) { return(encode_string(Encoding_encode_char, 0)); } // convert raw to raw (do not convert at all) static char encoder_raw(char byte) { return(byte); } // Insert raw string static enum eos_t PO_raw(void) { return(encode_string(encoder_raw, 0)); } // convert raw to petscii static char encoder_pet(char byte) { if((byte >= 'A') && (byte <= 'Z')) return((char) (byte | 0x80)); // FIXME - check why SAS-C if((byte >= 'a') && (byte <= 'z')) // wants these casts. return((char)(byte - 32)); // There are more below. return(byte); } // Insert PetSCII string static enum eos_t PO_pet(void) { return(encode_string(encoder_pet, 0)); } // convert raw to C64 screencode static char encoder_scr(char byte) { if((byte >= 'a') && (byte <= 'z')) return((char)(byte - 96)); // shift uppercase down if((byte >= '[') && (byte <= '_')) return((char)(byte - 64)); // shift [\]^_ down if(byte == '`') return(64); // shift ` down if(byte == '@') return(0); // shift @ down return(byte); } // Insert screencode string static enum eos_t PO_scr(void) { return(encode_string(encoder_scr, 0)); } // Insert screencode string, EOR'd static enum eos_t PO_scrxor(void) { intval_t num = ALU_any_int(); if(Input_accept_comma()) return(encode_string(encoder_scr, num)); Throw_error(exception_syntax); return(SKIP_REMAINDER); } // Switch to CBM mode ("!cbm" pseudo opcode) static enum eos_t PO_cbm(void) { Encoding_encode_char = encoder_pet; // output deprecation warning Throw_first_pass_warning("\"!cbm\" is deprecated; use \"!ct pet\" instead."); return(ENSURE_EOS); } // static char encoder_file(char byte) { return(loaded_table[(unsigned char) byte]); } // read encoding table from file static enum eos_t user_defined_encoding(void) { FILE* fd; char local_table[256], *buffered_table = loaded_table; encoder_t buffered_encoder = Encoding_encode_char; // if file name is missing, don't bother continuing if(Input_read_filename(TRUE)) return(SKIP_REMAINDER); fd = fopen(GLOBALDYNABUF_CURRENT, FILE_READBINARY); if(fd) { if(fread(local_table, sizeof(char), 256, fd) != 256) Throw_error("Conversion table incomplete."); fclose(fd); } else Throw_error(exception_cannot_open_input_file); Encoding_encode_char = encoder_file; // activate new encoding loaded_table = local_table; // activate local table // If there's a block, parse that and then restore old values if(Parse_optional_block()) Encoding_encode_char = buffered_encoder; else // if there's *no* block, the table must be used from now on. // copy the local table to the "outer" table memcpy(buffered_table, local_table, 256); // re-activate "outer" table (it might have been changed by memcpy()) loaded_table = buffered_table; return(ENSURE_EOS); } // use one of the pre-defined encodings (raw, pet, scr) static enum eos_t predefined_encoding(void) { void* node_body; char local_table[256], *buffered_table = loaded_table; encoder_t buffered_encoder = Encoding_encode_char; // use one of the pre-defined encodings if(Input_read_and_lower_keyword()) { // search for tree item if(Tree_easy_scan(encoder_tree, &node_body, GlobalDynaBuf)) Encoding_encode_char = (encoder_t) node_body;// activate new encoder else Throw_error("Unknown encoding."); } loaded_table = local_table; // activate local table // If there's a block, parse that and then restore old values if(Parse_optional_block()) Encoding_encode_char = buffered_encoder; // re-activate "outer" table loaded_table = buffered_table; return(ENSURE_EOS); } // Set current encoding ("!convtab" pseudo opcode) static enum eos_t PO_convtab(void) { if((GotByte == '<') || (GotByte == '"')) return(user_defined_encoding()); else return(predefined_encoding()); } // pseudo opcode table static node_t pseudo_opcodes[] = { PREDEFNODE(s_cbm, PO_cbm), PREDEFNODE("ct", PO_convtab), PREDEFNODE("convtab", PO_convtab), PREDEFNODE(s_pet, PO_pet), PREDEFNODE(s_raw, PO_raw), PREDEFNODE(s_scr, PO_scr), PREDEFNODE(s_scrxor, PO_scrxor), PREDEFNODE("text", PO_text), PREDEFLAST("tx", PO_text), // ^^^^ this marks the last element }; // keywords for "!convtab" pseudo opcode static node_t encoders[] = { PREDEFNODE(s_pet, encoder_pet), PREDEFNODE(s_raw, encoder_raw), PREDEFLAST(s_scr, encoder_scr), // ^^^^ this marks the last element }; // Exported functions // register pseudo opcodes and build keyword tree for encoders void Encoding_init(void) { Tree_add_table(&encoder_tree, encoders); Tree_add_table(&pseudo_opcode_tree, pseudo_opcodes); } // Set "raw" as default encoding void Encoding_passinit(void) { Encoding_encode_char = encoder_raw; } CheeseCutter-2.10/src/asm/encoding.h000066400000000000000000000007611516216315000173310ustar00rootroot00000000000000// // ACME - a crossassembler for producing 6502/65c02/65816 code. // Copyright (C) 1998-2006 Marco Baye // Have a look at "acme.c" for further info // // Character encoding stuff #ifndef encoding_H #define encoding_H // Prototypes // register pseudo opcodes and build keyword tree for encoders extern void Encoding_init(void); // convert character using current encoding extern char (*Encoding_encode_char)(char); // Set "raw" as default encoding extern void Encoding_passinit(void); #endif CheeseCutter-2.10/src/asm/flow.c000066400000000000000000000300231516216315000164770ustar00rootroot00000000000000// // ACME - a crossassembler for producing 6502/65c02/65816 code. // Copyright (C) 1998-2006 Marco Baye // Have a look at "acme.c" for further info // // Flow control stuff (loops, conditional assembly etc.) // // Macros, conditional assembly, loops and sourcefile-includes are all based on // parsing blocks of code. When defining macros or using loops or conditional // assembly, the block starts with "{" and ends with "}". In the case of // "!source", the given file is treated like a block - the outermost assembler // function uses the same technique to parse the top level file. #include #include "acme.h" #include "alu.h" #include "config.h" #include "dynabuf.h" #include "global.h" #include "input.h" #include "label.h" #include "macro.h" #include "mnemo.h" #include "tree.h" // type definitions enum cond_key_t { ID_UNTIL, // Handles to store instead of ID_WHILE, // the UNTIL and WHILE keywords }; typedef struct { enum cond_key_t type; // either ID_UNTIL or ID_WHILE int line; // original line number char* body; // pointer to actual expression } loopcond_t; // Variables // predefined stuff static node_t* condkey_tree = NULL;// tree to hold UNTIL and WHILE static node_t condkeys[] = { PREDEFNODE("until", ID_UNTIL), PREDEFLAST("while", ID_WHILE), // ^^^^ this marks the last element }; // Helper functions for "!for" and "!do" // Parse a loop body (could also be used for macro body) static void parse_ram_block(int line_number, char* body) { Input_now->line_number = line_number;// set line number to loop start Input_now->src.ram_ptr = body;// set RAM read pointer to loop // Parse loop body Parse_until_eob_or_eof(); if(GotByte != CHAR_EOB) Bug_found("IllegalBlockTerminator", GotByte); } // Try to read a condition into DynaBuf and store copy pointer in // given loopcond_t structure. // If no condition given, NULL is written to structure. // Call with GotByte = first interesting character static void store_condition(loopcond_t* condition, char terminator) { void* node_body; // write line number condition->line = Input_now->line_number; // Check for empty condition if(GotByte == terminator) { // Write NULL condition, then return condition->body = NULL; return; } // Seems as if there really *is* a condition. // Read UNTIL/WHILE keyword if(Input_read_and_lower_keyword()) { // Search for new tree item if(!Tree_easy_scan(condkey_tree, &node_body, GlobalDynaBuf)) { Throw_error(exception_syntax); condition->body = NULL; return; } condition->type = (enum cond_key_t) node_body; // Write given condition into buffer SKIPSPACE(); DYNABUF_CLEAR(GlobalDynaBuf); Input_until_terminator(terminator); DynaBuf_append(GlobalDynaBuf, CHAR_EOS);// ensure terminator condition->body = DynaBuf_get_copy(GlobalDynaBuf); } return; } // Check a condition expression static bool check_condition(loopcond_t* condition) { intval_t expression; // First, check whether there actually *is* a condition if(condition->body == NULL) return(TRUE); // non-existant conditions are always true // set up input for expression evaluation Input_now->line_number = condition->line; Input_now->src.ram_ptr = condition->body; GetByte(); // proceed with next char expression = ALU_defined_int(); if(GotByte) Throw_serious_error(exception_syntax); if(condition->type == ID_UNTIL) return(!expression); return(!!expression); } // Looping assembly ("!do"). Has to be re-entrant. static enum eos_t PO_do(void) { // Now GotByte = illegal char loopcond_t condition1, condition2; input_t loop_input, *outer_input; char* loop_body; bool go_on; int loop_start;// line number of loop pseudo opcode // Read head condition to buffer SKIPSPACE(); store_condition(&condition1, CHAR_SOB); if(GotByte != CHAR_SOB) Throw_serious_error(exception_no_left_brace); // Remember line number of loop body, // then read block and get copy loop_start = Input_now->line_number; loop_body = Input_skip_or_store_block(TRUE); // changes line number! // now GotByte = '}' NEXTANDSKIPSPACE();// Now GotByte = first non-blank char after block // Read tail condition to buffer store_condition(&condition2, CHAR_EOS); // now GotByte = CHAR_EOS // set up new input loop_input = *Input_now;// copy current input structure into new loop_input.source_is_ram = TRUE; // set new byte source // remember old input outer_input = Input_now; // activate new input (not useable yet, as pointer and // line number are not yet set up) Input_now = &loop_input; do { // Check head condition go_on = check_condition(&condition1); if(go_on) { parse_ram_block(loop_start, loop_body); // Check tail condition go_on = check_condition(&condition2); } } while(go_on); // Free memory free(condition1.body); free(loop_body); free(condition2.body); // restore previous input: Input_now = outer_input; GotByte = CHAR_EOS; // CAUTION! Very ugly kluge. // But by switching input, we lost the outer input's GotByte. We know // it was CHAR_EOS. We could just call GetByte() to get real input, but // then the main loop could choke on unexpected bytes. So we pretend // that we got the outer input's GotByte value magically back. return(AT_EOS_ANYWAY); } // Looping assembly ("!for"). Has to be re-entrant. static enum eos_t PO_for(void) {// Now GotByte = illegal char input_t loop_input, *outer_input; result_t loop_counter; intval_t maximum; char* loop_body;// pointer to loop's body block label_t* label; zone_t zone; int force_bit, loop_start;// line number of "!for" pseudo opcode if(Input_read_zone_and_keyword(&zone) == 0) // skips spaces before return(SKIP_REMAINDER); // Now GotByte = illegal char force_bit = Input_get_force_bit(); // skips spaces after label = Label_find(zone, force_bit); if(Input_accept_comma() == FALSE) { Throw_error(exception_syntax); return(SKIP_REMAINDER); } maximum = ALU_defined_int(); if(maximum < 0) Throw_serious_error("Loop count is negative."); if(GotByte != CHAR_SOB) Throw_serious_error(exception_no_left_brace); // remember line number of loop pseudo opcode loop_start = Input_now->line_number; // read loop body into DynaBuf and get copy loop_body = Input_skip_or_store_block(TRUE); // changes line number! // switching input makes us lose GotByte. But we know it's '}' anyway! // set up new input loop_input = *Input_now;// copy current input structure into new loop_input.source_is_ram = TRUE; // set new byte source // remember old input outer_input = Input_now; // activate new input // (not yet useable; pointer and line number are still missing) Input_now = &loop_input; // init counter loop_counter.flags = MVALUE_DEFINED | MVALUE_EXISTS; loop_counter.val.intval = 0; // if count == 0, skip loop if(maximum) { do { loop_counter.val.intval++;// increment counter Label_set_value(label, &loop_counter, TRUE); parse_ram_block(loop_start, loop_body); } while(loop_counter.val.intval < maximum); } else Label_set_value(label, &loop_counter, TRUE); // Free memory free(loop_body); // restore previous input: Input_now = outer_input; // GotByte of OuterInput would be '}' (if it would still exist) GetByte(); // fetch next byte return(ENSURE_EOS); } // Helper functions for "!if" and "!ifdef" // Parse or skip a block. Returns whether block's '}' terminator was missing. // Afterwards: GotByte = '}' static bool skip_or_parse_block(bool parse) { if(!parse) { Input_skip_or_store_block(FALSE); return(FALSE); } // if block was correctly terminated, return FALSE Parse_until_eob_or_eof(); // if block isn't correctly terminated, complain and exit if(GotByte != CHAR_EOB) Throw_serious_error(exception_no_right_brace); return(FALSE); } // Parse {block} [else {block}] static void parse_block_else_block(bool parse_first) { // Parse first block. // If it's not correctly terminated, return immediately (because // in that case, there's no use in checking for an "else" part). if(skip_or_parse_block(parse_first)) return; // now GotByte = '}'. Check for "else" part. // If end of statement, return immediately. NEXTANDSKIPSPACE(); if(GotByte == CHAR_EOS) return; // read keyword and check whether really "else" if(Input_read_and_lower_keyword()) { if(strcmp(GlobalDynaBuf->buffer, "else")) Throw_error(exception_syntax); else { SKIPSPACE(); if(GotByte != CHAR_SOB) Throw_serious_error(exception_no_left_brace); skip_or_parse_block(!parse_first); // now GotByte = '}' GetByte(); } } Input_ensure_EOS(); } // Conditional assembly ("!if"). Has to be re-entrant. static enum eos_t PO_if(void) {// Now GotByte = illegal char intval_t cond; cond = ALU_defined_int(); if(GotByte != CHAR_SOB) Throw_serious_error(exception_no_left_brace); parse_block_else_block(!!cond); return(ENSURE_EOS); } // Conditional assembly ("!ifdef"). Has to be re-entrant. static enum eos_t PO_ifdef(void) {// Now GotByte = illegal char node_ra_t* node; label_t* label; zone_t zone; bool defined = FALSE; if(Input_read_zone_and_keyword(&zone) == 0) // skips spaces before return(SKIP_REMAINDER); Tree_hard_scan(&node, Label_forest, zone, FALSE); if(node) { label = (label_t*) node->body; // in first pass, count usage if(pass_count == 0) label->usage++; if(label->result.flags & MVALUE_DEFINED) defined = TRUE; } SKIPSPACE(); if(GotByte == CHAR_SOB) parse_block_else_block(defined); else { if(defined) return(PARSE_REMAINDER); return(SKIP_REMAINDER); } return(ENSURE_EOS); } // Macro definition ("!macro"). static enum eos_t PO_macro(void) {// Now GotByte = illegal char // In first pass, parse. In all other passes, skip. if(pass_count == 0) Macro_parse_definition(); // now GotByte = '}' else { // skip until CHAR_SOB ('{') is found. // no need to check for end-of-statement, because such an // error would already have been detected in first pass. // for the same reason, there is no need to check for quotes. while(GotByte != CHAR_SOB) GetByte(); Input_skip_or_store_block(FALSE); // now GotByte = '}' } GetByte(); // Proceed with next character return(ENSURE_EOS); } // Parse a whole source code file void Parse_source(char *source) { // be verbose if(Process_verbosity > 2) printf("Parsing source file!\n"); // set up new input Input_new_file(source); // Parse block and check end reason Parse_until_eob_or_eof(); if(GotByte != CHAR_EOF) Throw_error("Found '}' instead of end-of-file."); // close sublevel src //fclose(Input_now->src.fd); } // Include source file ("!source" or "!src"). Has to be re-entrant. static enum eos_t PO_source(void) {// Now GotByte = illegal char Throw_error("PO_SOURCE not implemented"); return 0; } /* static enum eos_t X_PO_source(void) {// Now GotByte = illegal char FILE* fd; char local_gotbyte; input_t new_input, *outer_input; // Enter new nesting level. // Quit program if recursion too deep. if(--source_recursions_left < 0) Throw_serious_error("Too deeply nested. Recursive \"!source\"?"); // Read file name. Quit function on error. if(Input_read_filename(TRUE)) return(SKIP_REMAINDER); // If file could be opened, parse it. Otherwise, complain. if((fd = fopen(GLOBALDYNABUF_CURRENT, FILE_READBINARY))) { char filename[GlobalDynaBuf->size]; strcpy(filename, GLOBALDYNABUF_CURRENT); outer_input = Input_now;// remember old input local_gotbyte = GotByte;// CAUTION - ugly kluge Input_now = &new_input;// activate new input Parse_and_close_file(fd, filename); Input_now = outer_input;// restore previous input GotByte = local_gotbyte;// CAUTION - ugly kluge } else Throw_error(exception_cannot_open_input_file); // Leave nesting level source_recursions_left++; return(ENSURE_EOS); } */ // pseudo opcode table static node_t pseudo_opcodes[] = { PREDEFNODE("do", PO_do), PREDEFNODE("for", PO_for), PREDEFNODE("if", PO_if), PREDEFNODE("ifdef", PO_ifdef), PREDEFNODE("macro", PO_macro), PREDEFNODE("source", PO_source), PREDEFLAST("src", PO_source), // ^^^^ this marks the last element }; // register pseudo opcodes and build keyword tree for until/while void Flow_init(void) { Tree_add_table(&condkey_tree, condkeys); Tree_add_table(&pseudo_opcode_tree, pseudo_opcodes); } CheeseCutter-2.10/src/asm/flow.h000066400000000000000000000007311516216315000165070ustar00rootroot00000000000000// // ACME - a crossassembler for producing 6502/65c02/65816 code. // Copyright (C) 1998-2006 Marco Baye // Have a look at "acme.c" for further info // // Flow control stuff (loops, conditional assembly etc.) #ifndef flow_H #define flow_H #include #include "config.h" // Prototypes // register pseudo opcodes and build keyword tree for until/while extern void Flow_init(void); // Parse a whole source code file extern void Parse_source(const char*); #endif CheeseCutter-2.10/src/asm/global.c000066400000000000000000000305621516216315000170000ustar00rootroot00000000000000// // ACME - a crossassembler for producing 6502/65c02/65816 code. // Copyright (C) 1998-2006 Marco Baye // Have a look at "acme.c" for further info // // Global stuff - things that are needed by several modules // 4 Oct 2006 Fixed a typo in a comment #include #include #include "platform.h" // done first in case "inline" is redefined #include "acme.h" #include "cpu.h" #include "dynabuf.h" #include "global.h" #include "input.h" #include "label.h" #include "macro.h" #include "output.h" #include "section.h" #include "tree.h" // Constants const char s_65816[] = "65816"; const char s_and[] = "and"; const char s_asl[] = "asl"; const char s_asr[] = "asr"; const char s_brl[] = "brl"; const char s_cbm[] = "cbm"; const char s_eor[] = "eor"; const char s_error[] = "error"; const char s_lsr[] = "lsr"; const char s_scrxor[] = "scrxor"; // Exception messages during assembly const char exception_cannot_open_input_file[] = "Cannot open input file."; const char exception_missing_string[] = "No string given."; const char exception_no_left_brace[] = "Missing '{'."; const char exception_no_memory_left[] = "Out of memory."; const char exception_no_right_brace[]= "Found end-of-file instead of '}'."; //const char exception_not_yet[] = "Sorry, feature not yet implemented."; const char exception_number_out_of_range[] = "Number out of range."; const char exception_pc_undefined[] = "Program counter undefined."; const char exception_syntax[] = "Syntax error."; // default value for number of errors before exiting #define MAXERRORS 10 // Flag table: // This table contains flags for all the 256 possible byte values. The // assembler reads the table whenever it needs to know whether a byte is // allowed to be in a label name, for example. // Bits Meaning when set // 7....... Byte allowed to start keyword // .6...... Byte allowed in keyword // ..5..... Byte is upper case, can be lowercased by OR-ing this bit(!) // ...4.... special character for input syntax: 0x00 TAB LF CR SPC : ; } // ....3... preceding sequence of '-' characters is anonymous backward // label. Currently only set for ')', ',' and CHAR_EOS. // .....210 unused const char Byte_flags[256] = { /*$00*/ 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,// control characters 0x00, 0x10, 0x10, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /*$20*/ 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,// " !"#$%&'" 0x00, 0x08, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,// "()*+,-./" 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,// "01234567" 0x40, 0x40, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00,// "89:;<=>?" /*$40*/ 0x00, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0,// "@ABCDEFG" 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0,// "HIJKLMNO" 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0,// "PQRSTUVW" 0xe0, 0xe0, 0xe0, 0x00, 0x00, 0x00, 0x00, 0xc0,// "XYZ[\]^_" /*$60*/ 0x00, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0,// "`abcdefg" 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0,// "hijklmno" 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0,// "pqrstuvw" 0xc0, 0xc0, 0xc0, 0x00, 0x00, 0x10, 0x00, 0x00,// "xyz{|}~" BACKSPACE /*$80*/ 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0,// umlauts etc. ... 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, /*$a0*/ 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, /*$c0*/ 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, /*$e0*/ 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, }; // Variables node_t* pseudo_opcode_tree = NULL; // tree to hold pseudo opcodes int pass_count; // number of current pass (starts 0) char GotByte; // Last byte read (processed) int Process_verbosity = 0; // Level of additional output // Global counters int pass_undefined_count; // "NeedValue" type errors int pass_real_errors; // Errors yet signed long max_errors = MAXERRORS;// errors before giving up FILE* msg_stream = NULL;// set to stdout by --use-stdout jmp_buf exception_env; char* error_message; //int cbm_load_address = 0; // Functions // Memory allocation stuff // Allocate memory and die if not available void* safe_malloc(size_t size) { void* block; if((block = malloc(size)) == NULL) Throw_serious_error(exception_no_memory_left); return(block); } // Parser stuff // Parse (re-)definitions of program counter static void parse_pc_def(void) {// Now GotByte = "*" NEXTANDSKIPSPACE(); // proceed with next char // re-definitions of program counter change segment if(GotByte == '=') { GetByte();// proceed with next char Output_start_segment(); Input_ensure_EOS(); } else { Throw_error(exception_syntax); Input_skip_remainder(); } } // Parse pseudo opcodes. Has to be re-entrant. static inline void parse_pseudo_opcode(void) {// Now GotByte = "!" void* node_body; enum eos_t (*fn)(void); enum eos_t then = SKIP_REMAINDER; // prepare for errors GetByte();// read next byte // on missing keyword, return (complaining will have been done) if(Input_read_and_lower_keyword()) { // search for tree item if((Tree_easy_scan(pseudo_opcode_tree, &node_body, GlobalDynaBuf)) && node_body) { fn = (enum eos_t (*)(void)) node_body; SKIPSPACE(); // call function then = fn(); } else Throw_error("Unknown pseudo opcode."); } if(then == SKIP_REMAINDER) Input_skip_remainder(); else if(then == ENSURE_EOS) Input_ensure_EOS(); // the other two possibilities (PARSE_REMAINDER and AT_EOS_ANYWAY) // will lead to the remainder of the line being parsed by the mainloop. } // Check and return whether first label of statement. Complain if not. static bool first_label_of_statement(int *statement_flags) { if((*statement_flags) & SF_IMPLIED_LABEL) { Throw_error(exception_syntax); Input_skip_remainder(); return(FALSE); } (*statement_flags) |= SF_IMPLIED_LABEL; // now there has been one return(TRUE); } // Parse global label definition or assembler mnemonic static void parse_mnemo_or_global_label_def(int *statement_flags) { // It is only a label if it isn't a mnemonic if((CPU_now->keyword_is_mnemonic(Input_read_keyword()) == FALSE) && first_label_of_statement(statement_flags)) { // Now GotByte = illegal char // 04 Jun 2005 - this fix should help to // explain "strange" error messages. if(*GLOBALDYNABUF_CURRENT == '') Throw_first_pass_warning("Label name starts with a shift-space character."); Label_parse_definition(ZONE_GLOBAL, *statement_flags); } } // Parse local label definition static void parse_local_label_def(int *statement_flags) { if(!first_label_of_statement(statement_flags)) return; GetByte();// start after '.' if(Input_read_keyword()) Label_parse_definition(Section_now->zone, *statement_flags); } // Parse anonymous backward label definition. Called with GotByte == '-' static void parse_backward_anon_def(int *statement_flags) { if(!first_label_of_statement(statement_flags)) return; DYNABUF_CLEAR(GlobalDynaBuf); do DYNABUF_APPEND(GlobalDynaBuf, '-'); while(GetByte() == '-'); DynaBuf_append(GlobalDynaBuf, '\0'); Label_implicit_definition(Section_now->zone, *statement_flags, 0, TRUE); } // Parse anonymous forward label definition. Called with GotByte == ? static void parse_forward_anon_def(int *statement_flags) { label_t* counter_label; if(!first_label_of_statement(statement_flags)) return; DYNABUF_CLEAR(GlobalDynaBuf); DynaBuf_append(GlobalDynaBuf, '+'); while(GotByte == '+') { DYNABUF_APPEND(GlobalDynaBuf, '+'); GetByte(); } counter_label = Label_fix_forward_name(); counter_label->result.val.intval++; DynaBuf_append(GlobalDynaBuf, '\0'); Label_implicit_definition(Section_now->zone, *statement_flags, 0, TRUE); } // Parse block, beginning with next byte. // End reason (either CHAR_EOB or CHAR_EOF) can be found in GotByte afterwards // Has to be re-entrant. void Parse_until_eob_or_eof(void) { int statement_flags; // // start with next byte, don't care about spaces // NEXTANDSKIPSPACE(); // start with next byte GetByte(); // loop until end of block or end of file while((GotByte != CHAR_EOB) && (GotByte != CHAR_EOF)) { // process one statement statement_flags = 0;// no "label = pc" definition yet // Parse until end of statement. Only loops if statement // contains "label = pc" definition and something else; or // if "!ifdef" is true. do { switch(GotByte) { case CHAR_EOS: // end of statement // Ignore now, act later // (stops from being "default") break; case ' ': // space statement_flags |= SF_FOUND_BLANK; /*FALLTHROUGH*/ case CHAR_SOL: // start of line GetByte();// skip break; case '-': parse_backward_anon_def(&statement_flags); break; case '+': GetByte(); if((GotByte == '.') || (BYTEFLAGS(GotByte) & CONTS_KEYWORD)) Macro_parse_call(); else parse_forward_anon_def(&statement_flags); break; case '!': parse_pseudo_opcode(); break; case '*': parse_pc_def(); break; case '.': parse_local_label_def(&statement_flags); break; default: if(BYTEFLAGS(GotByte) & STARTS_KEYWORD) { parse_mnemo_or_global_label_def(&statement_flags); } else { Throw_error(exception_syntax); Input_skip_remainder(); } } } while(GotByte != CHAR_EOS); // until end-of-statement // adjust program counter CPU_pc.intval = (CPU_pc.intval + CPU_2add) & 0xffff; CPU_2add = 0; // go on with next byte GetByte();//NEXTANDSKIPSPACE(); } } // Skip space. If GotByte is CHAR_SOB ('{'), parse block and return TRUE. // Otherwise (if there is no block), return FALSE. // Don't forget to call EnsureEOL() afterwards. bool Parse_optional_block(void) { SKIPSPACE(); if(GotByte != CHAR_SOB) return(FALSE); Parse_until_eob_or_eof(); if(GotByte != CHAR_EOB) Throw_serious_error(exception_no_right_brace); GetByte(); return(TRUE); } // Error handling // This function will do the actual output for warnings, errors and serious // errors. It shows the given message string, as well as the current // context: file name, line number, source type and source title. static void throw_message(const char* message, const char* type) { snprintf(error_message, 100, "assembler: %s - line %d (%s %s): %s\n", type, Input_now->line_number, Section_now->type, Section_now->title, message ); error_message += strlen(error_message); //fprintf(stdout, "%d ",strlen(error_message)); // fprintf(stdout, error_message); } // Output a warning. // This means the produced code looks as expected. But there has been a // situation that should be reported to the user, for example ACME may have // assembled a 16-bit parameter with an 8-bit value. void Throw_warning(const char* message) { PLATFORM_WARNING(message); throw_message(message, "Warning"); } // Output a warning if in first pass. See above. void Throw_first_pass_warning(const char* message) { if(pass_count == 0) Throw_warning(message); } // Output an error. // This means something went wrong in a way that implies that the output // almost for sure won't look like expected, for example when there was a // syntax error. The assembler will try to go on with the assembly though, so // the user gets to know about more than one of his typos at a time. void Throw_error(const char* message) { PLATFORM_ERROR(message); throw_message(message, "Error"); pass_real_errors++; if(pass_real_errors >= max_errors) longjmp(exception_env, 0); //exit(ACME_finalize(EXIT_FAILURE)); } // Output a serious error, stopping assembly. // Serious errors are those that make it impossible to go on with the // assembly. Example: "!fill" without a parameter - the program counter cannot // be set correctly in this case, so proceeding would be of no use at all. void Throw_serious_error(const char* message) { PLATFORM_SERIOUS(message); throw_message(message, "Serious error"); longjmp(exception_env, 0); //exit(ACME_finalize(EXIT_FAILURE)); } // Handle bugs void Bug_found(const char* message, int code) { Throw_warning("Bug in ACME, code follows"); fprintf(stderr, "(0x%x:)", code); Throw_serious_error(message); } CheeseCutter-2.10/src/asm/global.h000066400000000000000000000103221516216315000167750ustar00rootroot00000000000000// // ACME - a crossassembler for producing 6502/65c02/65816 code. // Copyright (C) 1998-2006 Marco Baye // Have a look at "acme.c" for further info // // Global stuff - things that are needed by several modules #ifndef global_H #define global_H #include #include #include #include "config.h" // Constants #define SF_FOUND_BLANK (1u) // statement had space or tab #define SF_IMPLIED_LABEL (2u) // statement had implied label def extern const char s_65816[]; extern const char s_and[]; extern const char s_asl[]; extern const char s_asr[]; extern const char s_brl[]; extern const char s_cbm[]; extern const char s_eor[]; extern const char s_error[]; extern const char s_lsr[]; extern const char s_scrxor[]; // Error messages during assembly extern const char exception_cannot_open_input_file[]; extern const char exception_missing_string[]; extern const char exception_no_left_brace[]; extern const char exception_no_memory_left[]; extern const char exception_no_right_brace[]; //extern const char exception_not_yet[]; extern const char exception_number_out_of_range[]; extern const char exception_pc_undefined[]; extern const char exception_syntax[]; // Byte flags table extern const char Byte_flags[]; #define BYTEFLAGS(c) (Byte_flags[(unsigned char) c]) #define STARTS_KEYWORD (1u << 7) // Byte is allowed to start a keyword #define CONTS_KEYWORD (1u << 6) // Byte is allowed in a keyword #define BYTEIS_UPCASE (1u << 5) // Byte is upper case and can be // converted to lower case by OR-ing this bit(!) #define BYTEIS_SYNTAX (1u << 4) // special character for input syntax #define FOLLOWS_ANON (1u << 3) // preceding '-' are backward label // bits 2, 1 and 0 are unused // Variables extern node_t* pseudo_opcode_tree;// tree to hold pseudo opcodes // structures enum eos_t { SKIP_REMAINDER, // skip remainder of line - (after errors) ENSURE_EOS, // make sure there's nothing left in statement PARSE_REMAINDER, // parse what's left AT_EOS_ANYWAY, // actually, same as PARSE_REMAINDER }; extern int pass_count; extern int Process_verbosity;// Level of additional output extern char GotByte;// Last byte read (processed) // Global counters extern int pass_undefined_count;// "NeedValue" type errors in current pass extern int pass_real_errors; // Errors yet extern signed long max_errors; // errors before giving up extern FILE* msg_stream; // set to stdout by --errors_to_stdout extern jmp_buf exception_env; extern char* error_message; //extern int cbm_load_address; // Macros for skipping a single space character #define SKIPSPACE() do {if(GotByte == ' ') GetByte();} while(0) #define NEXTANDSKIPSPACE() do {if(GetByte() == ' ') GetByte();} while(0) // Prototypes // Allocate memory and die if not available extern inline void* safe_malloc(size_t); // Parse block, beginning with next byte. // End reason (either CHAR_EOB or CHAR_EOF) can be found in GotByte afterwards // Has to be re-entrant. extern void Parse_until_eob_or_eof(void); // Skip space. If GotByte is CHAR_SOB ('{'), parse block and return TRUE. // Otherwise (if there is no block), return FALSE. // Don't forget to call EnsureEOL() afterwards. extern int Parse_optional_block(void); // Output a warning. // This means the produced code looks as expected. But there has been a // situation that should be reported to the user, for example ACME may have // assembled a 16-bit parameter with an 8-bit value. extern void Throw_warning(const char*); // Output a warning if in first pass. See above. extern void Throw_first_pass_warning(const char*); // Output an error. // This means something went wrong in a way that implies that the output // almost for sure won't look like expected, for example when there was a // syntax error. The assembler will try to go on with the assembly though, so // the user gets to know about more than one of his typos at a time. extern void Throw_error(const char*); // Output a serious error, stopping assembly. // Serious errors are those that make it impossible to go on with the // assembly. Example: "!fill" without a parameter - the program counter cannot // be set correctly in this case, so proceeding would be of no use at all. extern void Throw_serious_error(const char*); // Handle bugs extern void Bug_found(const char*, int); #endif CheeseCutter-2.10/src/asm/input.c000066400000000000000000000363161516216315000167020ustar00rootroot00000000000000// // ACME - a crossassembler for producing 6502/65c02/65816 code. // Copyright (C) 1998-2006 Marco Baye // Have a look at "acme.c" for further info // // Input stuff #include "config.h" #include "alu.h" #include "dynabuf.h" #include "global.h" #include "input.h" #include "platform.h" #include "section.h" #include "tree.h" // Constants const char FILE_READBINARY[] = "rb"; #define CHAR_TAB (9) // Tab character #define CHAR_LF (10) // line feed (in file) // (10) // start of line (in high-level format) #define CHAR_CR (13) // carriage return (in file) // (13) // end of file (in high-level format) #define CHAR_STATEMENT_DELIMITER ':' #define CHAR_COMMENT_SEPARATOR ';' // If the characters above are changed, don't forget to adjust ByteFlags[]! // fake input structure (for error msgs before any real input is established) static input_t outermost = { "", // file name 0, // line number FALSE, // Faked file access, so no RAM read INPUTSTATE_EOF, // state of input { NULL // RAM read pointer or file handle } }; // Variables input_t* Input_now = &outermost; // current input structure // End of source file ("!endoffile" or "!eof") static enum eos_t PO_eof(void) { // Well, it doesn't end right here and now, but at end-of-line! :-) Input_ensure_EOS(); Input_now->state = INPUTSTATE_EOF; return(AT_EOS_ANYWAY); } // predefined stuff static node_t pseudo_opcodes[] = { PREDEFNODE("eof", PO_eof), PREDEFLAST("endoffile", PO_eof), // ^^^^ this marks the last element }; // Functions // register pseudo opcodes void Input_init(void) { Tree_add_table(&pseudo_opcode_tree, pseudo_opcodes); } // Let current input point to start of file void Input_new_file(char *src) { /* Input_now->original_filename = ""; //filename; Input_now->line_number = 1; Input_now->source_is_ram = FALSE; Input_now->state = INPUTSTATE_NORMAL; Input_now->src.fd = NULL; */ Input_now->original_filename = ""; //filename; Input_now->line_number = 1; Input_now->source_is_ram = FALSE; Input_now->state = INPUTSTATE_NORMAL; Input_now->src.fd = NULL; Input_now->string_source = src; Input_now->string_source_length = strlen(src); Input_now->string_source_position = 0; } int hacked_getc(input_t *Input) { if(Input->string_source_position >= Input->string_source_length) return EOF; int byte = *(Input->string_source++); Input->string_source_position++; return byte; } // Deliver source code from current file (!) in shortened high-level format static char get_processed_from_file(void) { int from_file; do { switch(Input_now->state) { case INPUTSTATE_NORMAL: // fetch a fresh byte from the current source file //from_file = getc(Input_now->src.fd); from_file = hacked_getc(Input_now); // now process it /*FALLTHROUGH*/ case INPUTSTATE_AGAIN: // Process the latest byte again. Of course, this only // makes sense if the loop has executed at least once, // otherwise the contents of from_file are undefined. // If the source is changed so there is a possibility // to enter INPUTSTATE_AGAIN mode without first having // defined "from_file", trouble may arise... Input_now->state = INPUTSTATE_NORMAL; // EOF must be checked first because it cannot be used // as an index into Byte_flags[] if(from_file == EOF) { // remember to send an end-of-file Input_now->state = INPUTSTATE_EOF; return(CHAR_EOS);// end of statement } // check whether character is special one // if not, everything's cool and froody, so return it if((BYTEFLAGS(from_file) & BYTEIS_SYNTAX) == 0) return((char) from_file); // check special characters ("0x00 TAB LF CR SPC :;}") switch(from_file) { case CHAR_TAB:// TAB character case ' ': // remember to skip all following blanks Input_now->state = INPUTSTATE_SKIPBLANKS; return(' '); case CHAR_LF:// LF character // remember to send a start-of-line Input_now->state = INPUTSTATE_LF; return(CHAR_EOS);// end of statement case CHAR_CR:// CR character // remember to check CRLF + send start-of-line Input_now->state = INPUTSTATE_CR; return(CHAR_EOS);// end of statement case CHAR_EOB: // remember to send an end-of-block Input_now->state = INPUTSTATE_EOB; return(CHAR_EOS);// end of statement case CHAR_STATEMENT_DELIMITER: // just deliver an EOS instead return(CHAR_EOS);// end of statement case CHAR_COMMENT_SEPARATOR: // remember to skip remainder of line Input_now->state = INPUTSTATE_COMMENT; return(CHAR_EOS);// end of statement default: // complain if byte is 0 Throw_error("Source file contains illegal character."); return((char) from_file); } case INPUTSTATE_SKIPBLANKS: // read until non-blank, then deliver that do { // from_file = getc(Input_now->src.fd); from_file = hacked_getc(Input_now); } while((from_file == CHAR_TAB) || (from_file == ' ')); // re-process last byte Input_now->state = INPUTSTATE_AGAIN; break; case INPUTSTATE_LF: // return start-of-line, then continue in normal mode Input_now->state = INPUTSTATE_NORMAL; return(CHAR_SOL);// new line case INPUTSTATE_CR: // return start-of-line, remember to check for LF Input_now->state = INPUTSTATE_SKIPLF; return(CHAR_SOL);// new line case INPUTSTATE_SKIPLF: from_file = hacked_getc(Input_now); // if LF, ignore it and fetch another byte // otherwise, process current byte if(from_file == CHAR_LF) Input_now->state = INPUTSTATE_NORMAL; else Input_now->state = INPUTSTATE_AGAIN; break; case INPUTSTATE_COMMENT: // read until end-of-line or end-of-file do from_file = hacked_getc(Input_now); while((from_file != EOF) && (from_file != CHAR_CR) && (from_file != CHAR_LF)); // re-process last byte Input_now->state = INPUTSTATE_AGAIN; break; case INPUTSTATE_EOB: // deliver EOB Input_now->state = INPUTSTATE_NORMAL; return(CHAR_EOB);// end of block case INPUTSTATE_EOF: // deliver EOF Input_now->state = INPUTSTATE_NORMAL; return(CHAR_EOF);// end of file default: Bug_found("StrangeInputMode", Input_now->state); } } while(TRUE); } // This function delivers the next byte from the currently active byte source // in shortened high-level format. FIXME - use fn ptr? // When inside quotes, use GetQuotedByte() instead! char GetByte(void) { // do { // If byte source is RAM, then no conversions are // necessary, because in RAM the source already has // high-level format // Otherwise, the source is a file. This means we will call // GetFormatted() which will do a shit load of conversions. if(Input_now->source_is_ram) GotByte = *(Input_now->src.ram_ptr++); else GotByte = get_processed_from_file(); // // if start-of-line was read, increment line counter and repeat // if(GotByte != CHAR_SOL) // return(GotByte); // Input_now->line_number++; // } while(TRUE); if(GotByte == CHAR_SOL) Input_now->line_number++; return(GotByte); } // This function delivers the next byte from the currently active byte source // in un-shortened high-level format. // This function complains if CHAR_EOS (end of statement) is read. char GetQuotedByte(void) { int from_file; // must be an int to catch EOF // If byte source is RAM, then no conversion is necessary, // because in RAM the source already has high-level format if(Input_now->source_is_ram) GotByte = *(Input_now->src.ram_ptr++); // Otherwise, the source is a file. else { // fetch a fresh byte from the current source file from_file = hacked_getc(Input_now); switch(from_file) { case EOF: // remember to send an end-of-file Input_now->state = INPUTSTATE_EOF; GotByte = CHAR_EOS; // end of statement break; case CHAR_LF:// LF character // remember to send a start-of-line Input_now->state = INPUTSTATE_LF; GotByte = CHAR_EOS; // end of statement break; case CHAR_CR:// CR character // remember to check for CRLF + send a start-of-line Input_now->state = INPUTSTATE_CR; GotByte = CHAR_EOS; // end of statement break; default: GotByte = from_file; } } // now check for end of statement if(GotByte == CHAR_EOS) Throw_error("Quotes still open at end of line."); return(GotByte); } // Skip remainder of statement, for example on error void Input_skip_remainder(void) { while(GotByte) GetByte();// Read characters until end-of-statement } // Ensure that the remainder of the current statement is empty, for example // after mnemonics using implied addressing. void Input_ensure_EOS(void) {// Now GotByte = first char to test SKIPSPACE(); if(GotByte) { Throw_error("Garbage data at end of statement."); Input_skip_remainder(); } } // Skip or store block (starting with next byte, so call directly after // reading opening brace). // If "Store" is TRUE, the block is read into GlobalDynaBuf, then a copy // is made and a pointer to that is returned. // If "Store" is FALSE, NULL is returned. // After calling this function, GotByte holds '}'. Unless EOF was found first, // but then a serious error would have been thrown. char* Input_skip_or_store_block(bool store) { char byte; int depth = 1; // to find matching block end // prepare global dynamic buffer DYNABUF_CLEAR(GlobalDynaBuf); do { byte = GetByte(); // if wanted, store if(store) DYNABUF_APPEND(GlobalDynaBuf, byte); // now check for some special characters switch(byte) { case CHAR_EOF: // End-of-file in block? Sorry, no way. Throw_serious_error(exception_no_right_brace); case '"': // Quotes? Okay, read quoted stuff. case '\'': do { GetQuotedByte(); // if wanted, store if(store) DYNABUF_APPEND(GlobalDynaBuf, GotByte); } while((GotByte != CHAR_EOS) && (GotByte != byte)); break; case CHAR_SOB: depth++; break; case CHAR_EOB: depth--; break; } } while(depth); // in case of skip, return now if(!store) return(NULL); // otherwise, prepare to return copy of block // add EOF, just to make sure block is never read too far DynaBuf_append(GlobalDynaBuf, CHAR_EOS); DynaBuf_append(GlobalDynaBuf, CHAR_EOF); // return pointer to copy return(DynaBuf_get_copy(GlobalDynaBuf)); } // Read bytes and add to GlobalDynaBuf until the given terminator (or CHAR_EOS) // is found. Act upon single and double quotes by entering (and leaving) quote // mode as needed (So the terminator does not terminate when inside quotes). void Input_until_terminator(char terminator) { char byte = GotByte; do { // Terminator? Exit. EndOfStatement? Exit. if((byte == terminator) || (byte == CHAR_EOS)) return; // otherwise, append to GlobalDynaBuf and check for quotes DYNABUF_APPEND(GlobalDynaBuf, byte); if((byte == '"') || (byte == '\'')) { do { // Okay, read quoted stuff. GetQuotedByte();// throws error on EOS DYNABUF_APPEND(GlobalDynaBuf, GotByte); } while((GotByte != CHAR_EOS) && (GotByte != byte)); // on error, exit now, before calling GetByte() if(GotByte != byte) return; } byte = GetByte(); } while(TRUE); } // Append to GlobalDynaBuf while characters are legal for keywords. // Throws "missing string" error if none. // Returns number of characters added. int Input_append_keyword_to_global_dynabuf(void) { int length = 0; // add characters to buffer until an illegal one comes along while(BYTEFLAGS(GotByte) & CONTS_KEYWORD) { DYNABUF_APPEND(GlobalDynaBuf, GotByte); length++; GetByte(); } if(length == 0) Throw_error(exception_missing_string); return(length); } // Check whether GotByte is a dot. // If not, store global zone value. // If yes, store current zone value and read next byte. // Then jump to Input_read_keyword(), which returns length of keyword. int Input_read_zone_and_keyword(zone_t *zone) { SKIPSPACE(); if(GotByte == '.') { GetByte(); *zone = Section_now->zone; } else *zone = ZONE_GLOBAL; return(Input_read_keyword()); } // Clear dynamic buffer, then append to it until an illegal (for a keyword) // character is read. Zero-terminate the string. Return its length (without // terminator). // Zero lengths will produce a "missing string" error. int Input_read_keyword(void) { int length; DYNABUF_CLEAR(GlobalDynaBuf); length = Input_append_keyword_to_global_dynabuf(); // add terminator to buffer (increments buffer's length counter) DynaBuf_append(GlobalDynaBuf, '\0'); return(length); } // Clear dynamic buffer, then append to it until an illegal (for a keyword) // character is read. Zero-terminate the string, then convert to lower case. // Return its length (without terminator). // Zero lengths will produce a "missing string" error. int Input_read_and_lower_keyword(void) { int length; DYNABUF_CLEAR(GlobalDynaBuf); length = Input_append_keyword_to_global_dynabuf(); // add terminator to buffer (increments buffer's length counter) DynaBuf_append(GlobalDynaBuf, '\0'); DynaBuf_to_lower(GlobalDynaBuf, GlobalDynaBuf);// convert to lower case return(length); } // Try to read a file name. If "allow_library" is TRUE, library access by using // <...> quoting is possible as well. The file name given in the assembler // source code is converted from UNIX style to platform style. // Returns whether error occurred (TRUE on error). Filename in GlobalDynaBuf. // Errors are handled and reported, but caller should call // Input_skip_remainder() then. bool Input_read_filename(bool allow_library) { char *lib_prefix, end_quote; DYNABUF_CLEAR(GlobalDynaBuf); SKIPSPACE(); // check for library access if(GotByte == '<') { // if library access forbidden, complain if(allow_library == FALSE) { Throw_error("Writing to library not supported."); return(TRUE); } // read platform's lib prefix lib_prefix = PLATFORM_LIBPREFIX; #ifndef NO_NEED_FOR_ENV_VAR // if lib prefix not set, complain if(lib_prefix == NULL) { Throw_error("\"ACME\" environment variable not found."); return(TRUE); } #endif // copy lib path and set quoting char DynaBuf_add_string(GlobalDynaBuf, lib_prefix); end_quote = '>'; } else { if(GotByte == '"') end_quote = '"'; else { Throw_error("File name quotes not found (\"\" or <>)."); return(TRUE); } } // read first character, complain if closing quote if(GetQuotedByte() == end_quote) { Throw_error("No file name given."); return(TRUE); } // read characters until closing quote (or EOS) is reached // append platform-converted characters to current string while((GotByte != CHAR_EOS) && (GotByte != end_quote)) { DYNABUF_APPEND(GlobalDynaBuf, PLATFORM_CONVERTPATHCHAR(GotByte)); GetQuotedByte(); } // on error, return if(GotByte == CHAR_EOS) return(TRUE); GetByte(); // fetch next to forget closing quote // terminate string DynaBuf_append(GlobalDynaBuf, '\0'); // add terminator return(FALSE); // no error } // Try to read a comma, skipping spaces before and after. Return TRUE if comma // found, otherwise FALSE. bool Input_accept_comma(void) { SKIPSPACE(); if(GotByte != ',') return(FALSE); NEXTANDSKIPSPACE(); return(TRUE); } // read optional info about parameter length int Input_get_force_bit(void) { char byte; int force_bit = 0; if(GotByte == '+') { byte = GetByte(); if(byte == '1') force_bit = MVALUE_FORCE08; else if(byte == '2') force_bit = MVALUE_FORCE16; else if(byte == '3') force_bit = MVALUE_FORCE24; if(force_bit) GetByte(); else Throw_error("Illegal postfix."); } SKIPSPACE(); return(force_bit); } CheeseCutter-2.10/src/asm/input.h000066400000000000000000000115111516216315000166750ustar00rootroot00000000000000// // ACME - a crossassembler for producing 6502/65c02/65816 code. // Copyright (C) 1998-2006 Marco Baye // Have a look at "acme.c" for further info // // Input stuff #ifndef input_H #define input_H #include #include // type definitions // values for input_t component "Src.State" enum inputstate_t { INPUTSTATE_NORMAL, // everything's fine INPUTSTATE_AGAIN, // re-process last byte INPUTSTATE_SKIPBLANKS, // shrink multiple spaces INPUTSTATE_LF, // send start-of-line after end-of-statement INPUTSTATE_CR, // same, but also remember to skip LF INPUTSTATE_SKIPLF, // skip LF if that's next INPUTSTATE_COMMENT, // skip characters until newline or EOF INPUTSTATE_EOB, // send end-of-block after end-of-statement INPUTSTATE_EOF, // send end-of-file after end-of-statement }; typedef struct { const char* original_filename;// during RAM reads, too int line_number; // in file (on RAM reads, too) bool source_is_ram; // TRUE if RAM, FALSE if file enum inputstate_t state; // state of input union { FILE* fd; // file descriptor char* ram_ptr; // RAM read ptr (loop or macro block) } src; char *string_source; int string_source_length; int string_source_position; } input_t; // Constants extern const char FILE_READBINARY[]; // Special characters // The program *heavily* relies on CHAR_EOS (end of statement) being 0x00! #define CHAR_EOS (0) // end of statement (in high-level format) #define CHAR_SOB '{' // start of block #define CHAR_EOB '}' // end of block #define CHAR_SOL (10) // start of line (in high-level format) #define CHAR_EOF (13) // end of file (in high-level format) // If the characters above are changed, don't forget to adjust Byte_flags[]! // Variables extern input_t* Input_now; // current input structure // Prototypes // register pseudo opcodes extern void Input_init(void); // Let current input point to start of file extern void Input_new_file(char *); // get next byte from currently active byte source in shortened high-level // format. When inside quotes, use GetQuotedByte() instead! extern char GetByte(void); // get next byte from currently active byte source in un-shortened high-level // format. Complains if CHAR_EOS (end of statement) is read. extern char GetQuotedByte(void); // Skip remainder of statement, for example on error extern void Input_skip_remainder(void); // Ensure that the remainder of the current statement is empty, for example // after mnemonics using implied addressing. extern void Input_ensure_EOS(void); // Skip or store block (starting with next byte, so call directly after // reading opening brace). // If "Store" is TRUE, the block is read into GlobalDynaBuf, then a copy // is made and a pointer to that is returned. // If "Store" is FALSE, NULL is returned. // After calling this function, GotByte holds '}'. Unless EOF was found first, // but then a serious error would have been thrown. extern char* Input_skip_or_store_block(bool store); // Read bytes and add to GlobalDynaBuf until the given terminator (or CHAR_EOS) // is found. Act upon single and double quotes by entering (and leaving) quote // mode as needed (So the terminator does not terminate when inside quotes). extern void Input_until_terminator(char terminator); // Append to GlobalDynaBuf while characters are legal for keywords. // Throws "missing string" error if none. Returns number of characters added. extern int Input_append_keyword_to_global_dynabuf(void); // Check whether GotByte is a dot. // If not, store global zone value. // If yes, store current zone value and read next byte. // Then jump to Input_read_keyword(), which returns length of keyword. extern int Input_read_zone_and_keyword(zone_t*); // Clear dynamic buffer, then append to it until an illegal (for a keyword) // character is read. Zero-terminate the string. Return its length (without // terminator). // Zero lengths will produce a "missing string" error. extern int Input_read_keyword(void); // Clear dynamic buffer, then append to it until an illegal (for a keyword) // character is read. Zero-terminate the string, then convert to lower case. // Return its length (without terminator). // Zero lengths will produce a "missing string" error. extern int Input_read_and_lower_keyword(void); // Try to read a file name. If "allow_library" is TRUE, library access by using // <...> quoting is possible as well. The file name given in the assembler // source code is converted from UNIX style to platform style. // Returns whether error occurred (TRUE on error). Filename in GlobalDynaBuf. // Errors are handled and reported, but caller should call // Input_skip_remainder() then. extern bool Input_read_filename(bool library_allowed); // Try to read a comma, skipping spaces before and after. Return TRUE if comma // found, otherwise FALSE. extern bool Input_accept_comma(void); // read optional info about parameter length extern int Input_get_force_bit(void); #endif CheeseCutter-2.10/src/asm/label.c000066400000000000000000000174321516216315000166200ustar00rootroot00000000000000// // ACME - a crossassembler for producing 6502/65c02/65816 code. // Copyright (C) 1998-2006 Marco Baye // Have a look at "acme.c" for further info // // Label stuff #include #include "acme.h" #include "alu.h" #include "cpu.h" #include "dynabuf.h" #include "global.h" #include "input.h" #include "label.h" #include "platform.h" #include "section.h" #include "tree.h" // Constants #define WARN_IF_LABEL_INDENTED 1 // FIXME - use CLI switch? #define s_sl (s_asl+1) // Yes, I know I'm sick // Variables node_ra_t* Label_forest[256];// ... (because of 8-bit hash) // Dump label value and flags to dump file static void dump_one_label(node_ra_t* node, FILE* fd) { label_t* label = node->body; // output name fprintf(fd, "%s", node->id_string); switch(label->result.flags & MVALUE_FORCEBITS) { case MVALUE_FORCE16: fprintf(fd, "+2="); break; case MVALUE_FORCE16 | MVALUE_FORCE24: /*FALLTHROUGH*/ case MVALUE_FORCE24: fprintf(fd, "+3="); break; default: fprintf(fd, " ="); } if(label->result.flags & MVALUE_DEFINED) { if(label->result.flags & MVALUE_IS_FP) fprintf(fd, "%.30f", label->result.val.fpval);//FIXME %g else fprintf(fd, "$%x", (unsigned) label->result.val.intval); } else fprintf(fd, " ?"); if(label->result.flags & MVALUE_UNSURE) fprintf(fd, "; ?"); if(label->usage == 0) fprintf(fd, "; unused"); fprintf(fd, "\n"); } // Search for label. Create if nonexistant. If created, give it flags "Flags". // The label name must be held in GlobalDynaBuf. label_t* Label_find(zone_t zone, int flags) { node_ra_t* node; label_t* label; bool node_created; int force_bits = flags & MVALUE_FORCEBITS; node_created = Tree_hard_scan(&node, Label_forest, zone, TRUE); // if node has just been created, create label as well if(node_created) { // Create new label structure label = safe_malloc(sizeof(label_t)); // Finish empty label item label->result.flags = flags; if(flags & MVALUE_IS_FP) label->result.val.fpval = 0; else label->result.val.intval = 0; label->usage = 0;// usage count label->pass = pass_count; node->body = label; } else label = node->body; // make sure the force bits don't clash if((node_created == FALSE) && force_bits) if((label->result.flags & MVALUE_FORCEBITS) != force_bits) Throw_error("Too late for postfix."); return(label); } // Assign value to label. The function acts upon the label's flag bits and // produces an error if needed. void Label_set_value(label_t* label, result_t* new, bool change_allowed) { int oldflags = label->result.flags; // value stuff if((oldflags & MVALUE_DEFINED) && (change_allowed == FALSE)) { // Label is already defined, so compare new and old values // if different type OR same type but different value, complain if(((oldflags ^ new->flags) & MVALUE_IS_FP) || ((oldflags & MVALUE_IS_FP) ? (label->result.val.fpval != new->val.fpval) : (label->result.val.intval != new->val.intval))) Throw_error("Label already defined."); } else // Label is not defined yet OR redefinitions are allowed label->result = *new; // flags stuff // Ensure that "unsure" labels without "isByte" state don't get that if((oldflags & (MVALUE_UNSURE | MVALUE_ISBYTE)) == MVALUE_UNSURE) new->flags &= ~MVALUE_ISBYTE; if(change_allowed) oldflags = (oldflags & MVALUE_UNSURE) | new->flags; else { if((oldflags & MVALUE_FORCEBITS) == 0) if((oldflags & (MVALUE_UNSURE | MVALUE_DEFINED)) == 0) oldflags |= new->flags & MVALUE_FORCEBITS; oldflags |= new->flags & ~MVALUE_FORCEBITS; } label->result.flags = oldflags; } // (Re)set label static enum eos_t PO_set(void) {// Now GotByte = illegal char result_t result; int force_bit; label_t* label; zone_t zone; if(Input_read_zone_and_keyword(&zone) == 0) // skips spaces before // Now GotByte = illegal char return(SKIP_REMAINDER); force_bit = Input_get_force_bit();// skips spaces after label = Label_find(zone, force_bit); if(GotByte != '=') { Throw_error(exception_syntax); return(SKIP_REMAINDER); } // label = parsed value GetByte();// proceed with next char ALU_any_result(&result); // clear label's force bits and set new ones label->result.flags &= ~(MVALUE_FORCEBITS | MVALUE_ISBYTE); if(force_bit) { label->result.flags |= force_bit; result.flags &= ~(MVALUE_FORCEBITS | MVALUE_ISBYTE); } Label_set_value(label, &result, TRUE); return(ENSURE_EOS); } // Select dump file static enum eos_t PO_sl(void) { // only process this pseudo opcode in the first pass if(pass_count) return(SKIP_REMAINDER); // if label dump file already chosen, complain and exit if(labeldump_filename) { Throw_warning("Label dump file already chosen."); return(SKIP_REMAINDER); } // read filename to global dynamic buffer // if no file name given, exit (complaining will have been done) if(Input_read_filename(FALSE)) return(SKIP_REMAINDER); // get malloc'd copy of filename labeldump_filename = DynaBuf_get_copy(GlobalDynaBuf); // ensure there's no garbage at end of line return(ENSURE_EOS); } // predefined stuff static node_t pseudo_opcodes[] = { PREDEFNODE("set", PO_set), PREDEFLAST(s_sl, PO_sl), // ^^^^ this marks the last element }; // Parse implicit label definition (can be either global or local). // GlobalDynaBuf holds the label name. void Label_implicit_definition(zone_t zone, int stat_flags, int force_bit, bool change) { result_t result; label_t* label; label = Label_find(zone, force_bit); // implicit label definition (label) if((stat_flags & SF_FOUND_BLANK) && WARN_IF_LABEL_INDENTED) Throw_first_pass_warning("Implicit label definition not in leftmost column."); result.flags = CPU_pc.flags & MVALUE_DEFINED; result.val.intval = CPU_pc.intval; Label_set_value(label, &result, change); } // Parse label definition (can be either global or local). // GlobalDynaBuf holds the label name. void Label_parse_definition(zone_t zone, int stat_flags) { result_t result; label_t* label; int force_bit = Input_get_force_bit();// skips spaces after // FIXME - force bit is allowed for implicit label defs?! if(GotByte == '=') { // explicit label definition (label = ) label = Label_find(zone, force_bit); // label = parsed value GetByte(); // skip '=' ALU_any_result(&result); Label_set_value(label, &result, FALSE); Input_ensure_EOS(); } else Label_implicit_definition(zone, stat_flags, force_bit, FALSE); } // Dump global labels to file void Label_dump_all(FILE* fd) { Tree_dump_forest(Label_forest, ZONE_GLOBAL, dump_one_label, fd); PLATFORM_SETFILETYPE_TEXT(labeldump_filename); } // register pseudo opcodes and clear label forest void Label_init(void) { node_ra_t** ptr; int i; Tree_add_table(&pseudo_opcode_tree, pseudo_opcodes); // Cut down all the trees (clear pointer table) ptr = Label_forest; // Clear pointertable for(i = 255; i >= 0; i--) *ptr++ = NULL; } // Fix name of anonymous forward label (held in DynaBuf, NOT TERMINATED!) so it // references the *next* anonymous forward label definition. The tricky bit is, // each name length would need its own counter. But hey, ACME's real quick in // finding labels, so I'll just abuse the label system to store those counters. label_t* Label_fix_forward_name(void) { label_t* counter_label; unsigned long number; // terminate name, find "counter" label and read value DynaBuf_append(GlobalDynaBuf, '\0'); counter_label = Label_find(Section_now->zone, 0); // make sure it gets reset to zero in each new pass if(counter_label->pass != pass_count) { counter_label->pass = pass_count; counter_label->result.val.intval = 0; } number = (unsigned long) counter_label->result.val.intval; // now append to the name to make it unique GlobalDynaBuf->size--; // forget terminator, we want to append do { DYNABUF_APPEND(GlobalDynaBuf, 'a' + (number & 15)); number >>= 4; } while(number); DynaBuf_append(GlobalDynaBuf, '\0'); return(counter_label); } CheeseCutter-2.10/src/asm/label.h000066400000000000000000000027741516216315000166300ustar00rootroot00000000000000// // ACME - a crossassembler for producing 6502/65c02/65816 code. // Copyright (C) 1998-2006 Marco Baye // Have a look at "acme.c" for further info // // Label stuff #ifndef label_H #define label_H #include // "label" structure type definition struct label_t { struct result_t result; // Expression flags and value int usage; // usage count int pass; // pass of creation (for anon counters) }; // Variables extern node_ra_t* Label_forest[]; // trees (because of 8-bit hash) // Prototypes // register pseudo opcodes and clear label forest extern void Label_init(void); // function acts upon the label's flag bits and produces an error if needed. extern void Label_set_value(label_t*, result_t*, bool change_allowed); // Parse implicit label definition (can be either global or local). // Name must be held in GlobalDynaBuf. extern void Label_implicit_definition(zone_t zone, int stat_flags, int force_bit, bool change); // Parse label definition (can be either global or local). // Name must be held in GlobalDynaBuf. extern void Label_parse_definition(zone_t zone, int stat_flags); // Search for label. Create if nonexistant. If created, assign flags. // Name must be held in GlobalDynaBuf. extern label_t* Label_find(zone_t, int flags); // Dump global labels to file extern void Label_dump_all(FILE* fd); // Fix name of anonymous forward label (held in GlobalDynaBuf, NOT TERMINATED!) // so it references the *next* anonymous forward label definition. extern label_t* Label_fix_forward_name(void); #endif CheeseCutter-2.10/src/asm/macro.c000066400000000000000000000304661516216315000166440ustar00rootroot00000000000000// // ACME - a crossassembler for producing 6502/65c02/65816 code. // Copyright (C) 1998-2006 Marco Baye // Have a look at "acme.c" for further info // // Macro stuff #include // needs strlen() + memcpy() #include "config.h" #include "platform.h" // done first in case "inline" is redefined #include "acme.h" #include "alu.h" #include "dynabuf.h" #include "global.h" #include "input.h" #include "label.h" #include "section.h" #include "tree.h" #include "macro.h" // Constants #define MACRONAME_DYNABUF_INITIALSIZE 128 #define ARG_SEPARATOR ' ' // separates macro title from arg types #define ARGTYPE_NUM_VAL 'v' #define ARGTYPE_NUM_REF 'V' //#define ARGTYPE_STR_VAL 's' //#define ARGTYPE_STR_REF 'S' #define REFERENCE_CHAR '~' // prefix for call-by-reference #define HALF_INITIAL_ARG_TABLE_SIZE 4 static const char exception_macro_twice[] = "Macro already defined."; // macro struct type definition struct macro_t { int def_line_number;// line number of definition for error msgs char* def_filename; // file name of definition for error msgs char* original_name; // user-supplied name for error msgs char* parameter_list; // parameters (whole line) char* body; // RAM block containing macro body }; // there's no need to make this a struct and add a type component: // when the macro has been found, accessing its parameter_list component // gives us the possibility to find out which args are call-by-value and // which ones are call-by-reference. union macro_arg_t { result_t result; // value and flags (call by value) label_t* label; // pointer to label struct (call by reference) }; // Variables static dynabuf_t* user_macro_name; // original macro title static dynabuf_t* internal_name; // plus param type chars static node_ra_t* macro_forest[256]; // trees (because of 8b hash) // Dynamic argument table static union macro_arg_t* arg_table = NULL; static int argtable_size = HALF_INITIAL_ARG_TABLE_SIZE; // Functions // Enlarge the argument table static void enlarge_arg_table(void) { argtable_size *= 2; arg_table = realloc(arg_table, argtable_size * sizeof(union macro_arg_t)); if(arg_table == NULL) Throw_serious_error(exception_no_memory_left); } // create dynamic buffers and arg table void Macro_init(void) { user_macro_name = DynaBuf_create(MACRONAME_DYNABUF_INITIALSIZE); internal_name = DynaBuf_create(MACRONAME_DYNABUF_INITIALSIZE); enlarge_arg_table(); } // Read macro zone and title. Title is read to GlobalDynaBuf and then copied // over to internal_name DynaBuf, where ARG_SEPARATOR is added. // In user_macro_name DynaBuf, the original name is reconstructed (even with // '.' prefix) so a copy can be linked to the resulting macro struct. static zone_t get_zone_and_title(void) { zone_t macro_zone; Input_read_zone_and_keyword(¯o_zone); // skips spaces before // now GotByte = illegal character after title // copy macro title to private dynabuf and add separator character DYNABUF_CLEAR(user_macro_name); DYNABUF_CLEAR(internal_name); if(macro_zone != ZONE_GLOBAL) DynaBuf_append(user_macro_name, '.'); DynaBuf_add_string(user_macro_name, GLOBALDYNABUF_CURRENT); DynaBuf_add_string(internal_name, GLOBALDYNABUF_CURRENT); DynaBuf_append(user_macro_name, '\0'); DynaBuf_append(internal_name, ARG_SEPARATOR); SKIPSPACE();// done here once so it's not necessary at two callers return(macro_zone); } // Check for comma. If there, append to GlobalDynaBuf. static inline bool pipe_comma(void) { bool result; result = Input_accept_comma(); if(result) DYNABUF_APPEND(GlobalDynaBuf, ','); return(result); } // Return malloc'd copy of string static char* get_string_copy(const char* original) { size_t size; char* copy; size = strlen(original) + 1; copy = safe_malloc(size); memcpy(copy, original, size); return(copy); } // This function is called from both macro definition and macro call. // Terminate macro name and copy from internal_name to GlobalDynaBuf // (because that's where Tree_hard_scan() looks for the search string). // Then try to find macro and return whether it was created. static bool search_for_macro(node_ra_t** result, zone_t zone, bool create) { DynaBuf_append(internal_name, '\0'); // terminate macro name // now internal_name = macro_title SPC argument_specifiers NUL DYNABUF_CLEAR(GlobalDynaBuf); DynaBuf_add_string(GlobalDynaBuf, internal_name->buffer); DynaBuf_append(GlobalDynaBuf, '\0'); return(Tree_hard_scan(result, macro_forest, zone, create)); } // This function is called when an already existing macro is re-defined. // It first outputs a warning and then a serious error, stopping assembly. // Showing the first message as a warning guarantees that ACME does not reach // the maximum error limit inbetween. static void report_redefinition(node_ra_t* macro_node) { struct macro_t* original_macro = macro_node->body; // show warning with location of current definition Throw_warning(exception_macro_twice); // CAUTION, ugly kluge: fiddle with Input_now and Section_now // data to generate helpful error messages Input_now->original_filename = original_macro->def_filename; Input_now->line_number = original_macro->def_line_number; Section_now->type = "original"; Section_now->title = "definition"; // show serious error with location of original definition Throw_serious_error(exception_macro_twice); } // This function is only called during the first pass, so there's no need to // check whether to skip the definition or not. // Return with GotByte = '}' void Macro_parse_definition(void) {// Now GotByte = illegal char after "!macro" char* formal_parameters; node_ra_t* macro_node; struct macro_t* new_macro; zone_t macro_zone = get_zone_and_title(); // now GotByte = first non-space after title DYNABUF_CLEAR(GlobalDynaBuf); // prepare to hold formal parameters // GlobalDynaBuf = "" (will hold formal parameter list) // user_macro_name = ['.'] MacroTitle NUL // internal_name = MacroTitle ARG_SEPARATOR (grows to signature) // Accept n>=0 comma-separated formal parameters before CHAR_SOB ('{'). // Valid argument formats are: // .LOCAL_LABEL_BY_VALUE // ~.LOCAL_LABEL_BY_REFERENCE // GLOBAL_LABEL_BY_VALUE global args are very uncommon, // ~GLOBAL_LABEL_BY_REFERENCE but not forbidden // now GotByte = non-space if(GotByte != CHAR_SOB) { // any at all? do { // handle call-by-reference character ('~') if(GotByte != REFERENCE_CHAR) DynaBuf_append(internal_name, ARGTYPE_NUM_VAL); else { DynaBuf_append(internal_name, ARGTYPE_NUM_REF); DynaBuf_append(GlobalDynaBuf, REFERENCE_CHAR); GetByte(); } // handle prefix for local labels ('.') if(GotByte == '.') { DynaBuf_append(GlobalDynaBuf, '.'); GetByte(); } // handle label name Input_append_keyword_to_global_dynabuf(); } while(pipe_comma()); // ensure CHAR_SOB ('{') if(GotByte != CHAR_SOB) Throw_serious_error(exception_no_left_brace); } DynaBuf_append(GlobalDynaBuf, CHAR_EOS); // terminate param list // now GlobalDynaBuf = comma-separated parameter list without spaces, // but terminated with CHAR_EOS. formal_parameters = DynaBuf_get_copy(GlobalDynaBuf); // now GlobalDynaBuf = unused // Reading the macro body would change the line number. To have correct // error messages, we're checking for "macro twice" *now*. // Search for macro. Create if not found. // But if found, complain (macro twice). if(search_for_macro(¯o_node, macro_zone, TRUE) == FALSE) report_redefinition(macro_node);// quits with serious error // Create new macro struct and set it up. Finally we'll read the body. new_macro = safe_malloc(sizeof(struct macro_t)); new_macro->def_line_number = Input_now->line_number; new_macro->def_filename = get_string_copy(Input_now->original_filename); new_macro->original_name = get_string_copy(user_macro_name->buffer); new_macro->parameter_list = formal_parameters; new_macro->body = Input_skip_or_store_block(TRUE);// changes LineNumber macro_node->body = new_macro; // link macro struct to tree node // and that about sums it up } // Parse macro call ("+MACROTITLE"). Has to be re-entrant. void Macro_parse_call(void) { // Now GotByte = dot or first char of macro name char local_gotbyte; label_t* label; section_t new_section, *outer_section; input_t new_input, *outer_input; struct macro_t* actual_macro; node_ra_t *macro_node, *label_node; zone_t macro_zone, label_zone; int arg_count = 0; // Enter deeper nesting level // Quit program if recursion too deep. if(--macro_recursions_left < 0) Throw_serious_error("Too deeply nested. Recursive macro calls?"); macro_zone = get_zone_and_title(); // now GotByte = first non-space after title // internal_name = MacroTitle ARG_SEPARATOR (grows to signature) // Accept n>=0 comma-separated arguments before CHAR_EOS. // Valid argument formats are: // EXPRESSION (everything that does NOT start with '~' // ~.LOCAL_LABEL_BY_REFERENCE // ~GLOBAL_LABEL_BY_REFERENCE // now GotByte = non-space if(GotByte != CHAR_EOS) { // any at all? do { // if arg table cannot take another element, enlarge if(argtable_size <= arg_count) enlarge_arg_table(); // Decide whether call-by-reference or call-by-value // In both cases, GlobalDynaBuf may be used. if(GotByte == REFERENCE_CHAR) { // read call-by-reference arg DynaBuf_append(internal_name, ARGTYPE_NUM_REF); GetByte(); // skip '~' character Input_read_zone_and_keyword(&label_zone); // GotByte = illegal char arg_table[arg_count].label = Label_find(label_zone, 0); } else { // read call-by-value arg DynaBuf_append(internal_name, ARGTYPE_NUM_VAL); ALU_any_result(&(arg_table[arg_count].result)); } arg_count++; } while(Input_accept_comma()); } // now arg_table contains the arguments // now GlobalDynaBuf = unused // check for "unknown macro" // Search for macro. Do not create if not found. search_for_macro(¯o_node, macro_zone, FALSE); if(macro_node == NULL) { Throw_error("Macro not defined (or wrong signature)."); Input_skip_remainder(); } else { // make macro_node point to the macro struct actual_macro = macro_node->body; local_gotbyte = GotByte;// CAUTION - ugly kluge // set up new input new_input.original_filename = actual_macro->def_filename; new_input.line_number = actual_macro->def_line_number; new_input.source_is_ram = TRUE; new_input.state = INPUTSTATE_NORMAL; // FIXME - fix others! new_input.src.ram_ptr = actual_macro->parameter_list; // remember old input outer_input = Input_now; // activate new input Input_now = &new_input; // remember old section outer_section = Section_now; // start new section (with new zone) // FALSE = title mustn't be freed Section_new_zone(&new_section, "Macro", actual_macro->original_name, FALSE); GetByte(); // fetch first byte of parameter list // assign arguments if(GotByte != CHAR_EOS) { // any at all? arg_count = 0; do { // Decide whether call-by-reference // or call-by-value // In both cases, GlobalDynaBuf may be used. if(GotByte == REFERENCE_CHAR) { // assign call-by-reference arg GetByte(); // skip '~' character Input_read_zone_and_keyword(&label_zone); if((Tree_hard_scan(&label_node, Label_forest, label_zone, TRUE) == FALSE) && (pass_count == 0)) Throw_error("Macro parameter twice."); label_node->body = arg_table[arg_count].label; } else { // assign call-by-value arg Input_read_zone_and_keyword(&label_zone); label = Label_find(label_zone, 0); // FIXME - add a possibility to Label_find to make it possible to find out // whether label was just created. Then check for the same error message here // as above ("Macro parameter twice."). label->result = arg_table[arg_count].result; } arg_count++; } while(Input_accept_comma()); } // and now, finally, parse the actual macro body Input_now->state = INPUTSTATE_NORMAL; // FIXME - fix others! // maybe call parse_ram_block(actual_macro->def_line_number, actual_macro->body) Input_now->src.ram_ptr = actual_macro->body; Parse_until_eob_or_eof(); if(GotByte != CHAR_EOB) Bug_found("IllegalBlockTerminator", GotByte); // end section (free title memory, if needed) Section_finalize(&new_section); // restore previous section Section_now = outer_section; // restore previous input: Input_now = outer_input; // restore old Gotbyte context GotByte = local_gotbyte;// CAUTION - ugly kluge Input_ensure_EOS(); } macro_recursions_left++; // leave this nesting level } CheeseCutter-2.10/src/asm/macro.h000066400000000000000000000010051516216315000166340ustar00rootroot00000000000000// // ACME - a crossassembler for producing 6502/65c02/65816 code. // Copyright (C) 1998-2006 Marco Baye // Have a look at "acme.c" for further info // // Macro stuff #ifndef macro_H #define macro_H #include "config.h" // Prototypes // create dynamic buffers and arg table extern void Macro_init(void); // create private dynabuf // only call once (during first pass) extern void Macro_parse_definition(void); // Parse macro call ("+MACROTITLE"). Has to be re-entrant. extern void Macro_parse_call(void); #endif CheeseCutter-2.10/src/asm/mnemo.c000066400000000000000000001137651516216315000166620ustar00rootroot00000000000000// // ACME - a crossassembler for producing 6502/65c02/65816 code. // Copyright (C) 1998-2006 Marco Baye // Have a look at "acme.c" for further info // // Mnemonics stuff #include "config.h" #include "alu.h" #include "cpu.h" #include "dynabuf.h" #include "global.h" #include "input.h" #include "output.h" #include "tree.h" // Constants #define s_ror (s_error+2) // Yes, I know I'm sick #define MNEMO_DYNABUF_INITIALSIZE 8 // 4+terminator should suffice // These values are needed to recognize addressing modes. // Bits: // 7....... "Implied" no value given // .6...... "Immediate" "#" at start // ..5..... "IndirectLong" "[" at start and "]" after value // ...4.... "Indirect" Value has at least one unnecessary pair of "()" // ....32.. "Indexed-Int" Index given inside of "()" // ......10 "Indexed-Ext" Index given outside of (or without any) "()" // // Index bits: // 00 = no index // 01 = ",s" (Stack-indexed) // 10 = ",x" (X-indexed) // 11 = ",y" (Y-indexed) // Components (Values for indices) #define HAM__ (0u << 0) // No index #define HAM_S (1u << 0) // Stack-indexed #define HAM_X (2u << 0) // X-indexed #define HAM_Y (3u << 0) // Y-indexed // End values base value internal index external index #define HAM_IMP (1u << 7) #define HAM_IMM (1u << 6) #define HAM_ABS 0 #define HAM_ABSS (1u << 0) #define HAM_ABSX (2u << 0) #define HAM_ABSY (3u << 0) #define HAM_IND (1u << 4) #define HAM_XIND ((1u << 4)| (2u << 2)) #define HAM_INDY ((1u << 4)| (3u << 0)) #define HAM_SINDY ((1u << 4)| (1u << 2)| (3u << 0)) #define HAM_LIND (1u << 5) #define HAM_LINDY ((1u << 5)| (3u << 0)) // Values of internal indices equal values of external indices, shifted left // by two bits. The program relies on this ! // Constant values, used to mark the possible parameter lengths of commands. // Not all of the eight values are actually used, however (because of the // supported CPUs). #define MAYBE______ (0) #define MAYBE_1____ (MVALUE_FORCE08) #define MAYBE___2__ (MVALUE_FORCE16) #define MAYBE_1_2__ (MVALUE_FORCE08 | MVALUE_FORCE16) #define MAYBE_____3 (MVALUE_FORCE24) #define MAYBE_1___3 (MVALUE_FORCE08 | MVALUE_FORCE24) #define MAYBE___2_3 (MVALUE_FORCE16 | MVALUE_FORCE24) #define MAYBE_1_2_3 (MVALUE_FORCE08 | MVALUE_FORCE16 | MVALUE_FORCE24) // The mnemonics are split up into groups, each group has its own function to // be dealt with: // G_IMPLIED Mnemonics using only implied addressing. Byte value = opcode // G_MAIN The main accumulator stuff (plus PEI) Byte value = table index // G_MISC Most of the other opcodes Byte value = table index // G_REL_SHORT The short branch instructions. Byte value = opcode // G_REL_LONG Mnemonics with 16bit relative addressing. Byte value = opcode // G_JUMP The jump instructions Byte value = table index // G_MOVE The "move" commands. Byte value = opcode enum mnemogroup_t { G_IMPLIED, // only implied addressing G_MAIN, // main accumulator stuff (plus PEI) G_MISC, // misc G_REL_SHORT, // short relative G_REL_LONG, // long relative G_JUMP, // jump G_MOVE // MVP, MVN }; // save some space #define SCB static const unsigned char #define SCS static const unsigned short #define SCL static const unsigned long // Code tables for group G_MAIN: // These tables are used for the main accumulator-related mnemonics. By reading // the mnemonic's byte value (from the mnemotable), the assembler finds out the // column to use here. The row depends on the used addressing mode. A zero // entry in these tables means that the combination of mnemonic and addressing // mode is illegal. enum { IDX_ORA, IDX_AND, IDX_EOR, IDX_ADC, IDX_STA, IDX_LDA, IDX_CMP, IDX_SBC, IDXC_ORA, IDXC_AND, IDXC_EOR, IDXC_ADC, IDXC_STA, IDXC_LDA, IDXC_CMP, IDXC_SBC, IDX8_ORA, IDX8_AND, IDX8_EOR, IDX8_ADC, IDX8_STA, IDX8_LDA, IDX8_CMP, IDX8_SBC, IDX8_PEI, IDXI_SLO, IDXI_RLA, IDXI_SRE, IDXI_RRA, IDXI_SAX, IDXI_LAX, IDXI_DCP, IDXI_ISC}; // | 6502 | 65c02 | 65816 | 6510 | // | ora and eor adc sta lda cmp sbc| ora and eor adc sta lda cmp sbc| ora and eor adc sta lda cmp sbc pei| slo rla sre rra sax lax dcp isc| SCB accu_imm[] = { 0x09, 0x29, 0x49, 0x69, 0, 0xa9, 0xc9, 0xe9, 0x09, 0x29, 0x49, 0x69, 0, 0xa9, 0xc9, 0xe9, 0x09, 0x29, 0x49, 0x69, 0, 0xa9, 0xc9, 0xe9, 0, 0, 0, 0, 0, 0, 0, 0, 0};// #$ff/#$ffff SCB accu_sabs8[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x03, 0x23, 0x43, 0x63, 0x83, 0xa3, 0xc3, 0xe3, 0, 0, 0, 0, 0, 0, 0, 0, 0};// $ff,s SCB accu_xind8[] = { 0x01, 0x21, 0x41, 0x61, 0x81, 0xa1, 0xc1, 0xe1, 0x01, 0x21, 0x41, 0x61, 0x81, 0xa1, 0xc1, 0xe1, 0x01, 0x21, 0x41, 0x61, 0x81, 0xa1, 0xc1, 0xe1, 0, 0x03, 0x23, 0x43, 0x63, 0x83, 0xa3, 0xc3, 0xe3};// ($ff,x) SCB accu_sindy8[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x13, 0x33, 0x53, 0x73, 0x93, 0xb3, 0xd3, 0xf3, 0, 0, 0, 0, 0, 0, 0, 0, 0};// ($ff,s),y SCB accu_ind8[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0x12, 0x32, 0x52, 0x72, 0x92, 0xb2, 0xd2, 0xf2, 0x12, 0x32, 0x52, 0x72, 0x92, 0xb2, 0xd2, 0xf2,0xd4, 0, 0, 0, 0, 0, 0, 0, 0};// ($ff) SCB accu_indy8[] = { 0x11, 0x31, 0x51, 0x71, 0x91, 0xb1, 0xd1, 0xf1, 0x11, 0x31, 0x51, 0x71, 0x91, 0xb1, 0xd1, 0xf1, 0x11, 0x31, 0x51, 0x71, 0x91, 0xb1, 0xd1, 0xf1, 0, 0x13, 0x33, 0x53, 0x73, 0, 0xb3, 0xd3, 0xf3};// ($ff),y SCB accu_lind8[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x07, 0x27, 0x47, 0x67, 0x87, 0xa7, 0xc7, 0xe7, 0, 0, 0, 0, 0, 0, 0, 0, 0};// [$ff] SCB accu_lindy8[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x17, 0x37, 0x57, 0x77, 0x97, 0xb7, 0xd7, 0xf7, 0, 0, 0, 0, 0, 0, 0, 0, 0};// [$ff],y SCL accu_abs[] = {0x0d05,0x2d25,0x4d45,0x6d65,0x8d85,0xada5,0xcdc5,0xede5,0x0d05,0x2d25,0x4d45,0x6d65,0x8d85,0xada5,0xcdc5,0xede5,0x0f0d05,0x2f2d25,0x4f4d45,0x6f6d65,0x8f8d85,0xafada5,0xcfcdc5,0xefede5, 0,0x0f07,0x2f27,0x4f47,0x6f67,0x8f87,0xafa7,0xcfc7,0xefe7};// $ff /$ffff /$ffffff SCL accu_xabs[] = {0x1d15,0x3d35,0x5d55,0x7d75,0x9d95,0xbdb5,0xddd5,0xfdf5,0x1d15,0x3d35,0x5d55,0x7d75,0x9d95,0xbdb5,0xddd5,0xfdf5,0x1f1d15,0x3f3d35,0x5f5d55,0x7f7d75,0x9f9d95,0xbfbdb5,0xdfddd5,0xfffdf5, 0,0x1f17,0x3f37,0x5f57,0x7f77, 0, 0,0xdfd7,0xfff7};// $ff,x/$ffff,x/$ffffff,x SCS accu_yabs[] = {0x1900,0x3900,0x5900,0x7900,0x9900,0xb900,0xd900,0xf900,0x1900,0x3900,0x5900,0x7900,0x9900,0xb900,0xd900,0xf900, 0x1900, 0x3900, 0x5900, 0x7900, 0x9900, 0xb900, 0xd900, 0xf900, 0,0x1b00,0x3b00,0x5b00,0x7b00, 0x97,0xbfb7,0xdb00,0xfb00};// $ff,y/$ffff,y // Code tables for group G_MISC: // These tables are needed for finding out the correct code in cases when // there are no general rules. By reading the mnemonic's byte value (from the // mnemotable), the assembler finds out the column to use here. The row // depends on the used addressing mode. A zero entry in these tables means // that the combination of mnemonic and addressing mode is illegal. enum { IDX_BIT, IDX_ASL, IDX_ROL, IDX_LSR, IDX_ROR, IDX_STY, IDX_STX, IDX_LDY, IDX_LDX, IDX_CPY, IDX_CPX, IDX_DEC, IDX_INC, IDXC_TSB, IDXC_TRB, IDXC_BIT, IDXC_DEC, IDXC_INC, IDXC_STZ, IDX8_COP, IDX8_REP, IDX8_SEP, IDX8_PEA, IDXI_ANC, IDXI_ASR, IDXI_ARR, IDXI_SBX, IDXI_DOP, IDXI_TOP, IDXI_JAM}; // | 6502 | 65c02 | 65816 | 6510 | // | bit asl rol lsr ror sty stx ldy ldx cpy cpx dec inc| tsb trb bit dec inc stz| cop rep sep pea| anc asr arr sbx dop top jam| SCB misc_impl[] = { 0, 0x0a, 0x2a, 0x4a, 0x6a, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x3a, 0x1a, 0, 0, 0, 0, 0, 0, 0, 0, 0,0x80, 0x0c,0x02};// implied/accu SCB misc_imm[] = { 0, 0, 0, 0, 0, 0, 0, 0xa0, 0xa2, 0xc0, 0xe0, 0, 0, 0, 0, 0x89, 0, 0, 0, 0,0xc2,0xe2, 0,0x2b,0x4b,0x6b,0xcb,0x80, 0, 0};// #$ff SCS misc_abs[] = {0x2c24,0x0e06,0x2e26,0x4e46,0x6e66,0x8c84,0x8e86,0xaca4,0xaea6,0xccc4,0xece4,0xcec6,0xeee6,0x0c04,0x1c14,0x2c24,0xcec6,0xeee6,0x9c64,0x02, 0, 0,0xf400, 0, 0, 0, 0,0x04,0x0c00, 0};// $ff/$ffff SCS misc_xabs[] = { 0,0x1e16,0x3e36,0x5e56,0x7e76, 0x94, 0,0xbcb4, 0, 0, 0,0xded6,0xfef6, 0, 0,0x3c34,0xded6,0xfef6,0x9e74, 0, 0, 0, 0, 0, 0, 0, 0,0x14,0x1c00, 0};// $ff,x/$ffff,x SCS misc_yabs[] = { 0, 0, 0, 0, 0, 0, 0x96, 0,0xbeb6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};// $ff,y/$ffff,y // Code tables for group G_JUMP: // // These tables are needed for finding out the correct code when the mnemonic // is "jmp" or "jsr" (or the long versions "jml" and "jsl"). // By reading the mnemonic's byte value (from the mnemotable), the assembler // finds out the column to use here. The row depends on the used addressing // mode. A zero entry in these tables means that the combination of mnemonic // and addressing mode is illegal. enum { IDX_JMP, IDX_JSR, IDXC_JMP, IDX8_JMP, IDX8_JML, IDX8_JSR, IDX8_JSL}; // | 6502 | 65c02| 65816 | // | jmp jsr | jmp | jmp jml jsr jsl | SCL jump_abs[] = {0x4c00,0x2000,0x4c00,0x5c4c00,0x5c0000,0x222000,0x220000};// $ffff/$ffffff SCS jump_ind[] = {0x6c00, 0,0x6c00, 0x6c00, 0, 0, 0};// ($ffff) SCS jump_xind[] = { 0, 0,0x7c00, 0x7c00, 0, 0xfc00, 0};// ($ffff,x) SCS jump_lind[] = { 0, 0, 0, 0xdc00, 0xdc00, 0, 0};// [$ffff] #undef SCB #undef SCS #undef SCL // error message strings static const char exception_illegal_combination[] = "Illegal combination of command and addressing mode."; static const char exception_highbyte_zero[]= "Using oversized addressing mode."; static const char exception_too_far[] = "Target out of range."; // Variables static dynabuf_t* mnemo_dyna_buf; // dynamic buffer for mnemonics // predefined stuff static node_t* mnemo_6502_tree = NULL;// holds 6502 mnemonics static node_t* mnemo_6510_tree = NULL;// holds 6510 extensions static node_t* mnemo_65c02_tree= NULL;// holds 65c02 extensions //static node_t* mnemo_Rockwell65c02_tree = NULL;// Rockwell static node_t* mnemo_WDC65c02_tree = NULL;// WDC's "stp"/"wai" static node_t* mnemo_65816_tree = NULL;// holds 65816 extensions // Command's code and group values are stored together in a single integer. // To extract the code, use "& CODEMASK". // To extract the group, use ">> GROUPSHIFT" #define CODEMASK 0xff // opcode or table index #define FLAGSMASK 0x300 // flags concerning immediate addressing: #define IMM_ACCU 0x100 // ...depends on accumulator length #define IMM_IDX 0x200 // ...depends on index register length #define GROUPSHIFT 10 // shift right by this to extract group #define MERGE(g, v) ((g << GROUPSHIFT) | v) static node_t mnemos_6502[] = { PREDEFNODE("ora", MERGE(G_MAIN , IDX_ORA | IMM_ACCU)), PREDEFNODE(s_and, MERGE(G_MAIN , IDX_AND | IMM_ACCU)), PREDEFNODE(s_eor, MERGE(G_MAIN , IDX_EOR | IMM_ACCU)), PREDEFNODE("adc", MERGE(G_MAIN , IDX_ADC | IMM_ACCU)), PREDEFNODE("sta", MERGE(G_MAIN , IDX_STA)), PREDEFNODE("lda", MERGE(G_MAIN , IDX_LDA | IMM_ACCU)), PREDEFNODE("cmp", MERGE(G_MAIN , IDX_CMP | IMM_ACCU)), PREDEFNODE("sbc", MERGE(G_MAIN , IDX_SBC | IMM_ACCU)), PREDEFNODE("bit", MERGE(G_MISC , IDX_BIT | IMM_ACCU)), PREDEFNODE(s_asl, MERGE(G_MISC , IDX_ASL)), PREDEFNODE("rol", MERGE(G_MISC , IDX_ROL)), PREDEFNODE(s_lsr, MERGE(G_MISC , IDX_LSR)), PREDEFNODE(s_ror, MERGE(G_MISC , IDX_ROR)), PREDEFNODE("sty", MERGE(G_MISC , IDX_STY)), PREDEFNODE("stx", MERGE(G_MISC , IDX_STX)), PREDEFNODE("ldy", MERGE(G_MISC , IDX_LDY | IMM_IDX)), PREDEFNODE("ldx", MERGE(G_MISC , IDX_LDX | IMM_IDX)), PREDEFNODE("cpy", MERGE(G_MISC , IDX_CPY | IMM_IDX)), PREDEFNODE("cpx", MERGE(G_MISC , IDX_CPX | IMM_IDX)), PREDEFNODE("dec", MERGE(G_MISC , IDX_DEC)), PREDEFNODE("inc", MERGE(G_MISC , IDX_INC)), PREDEFNODE("bpl", MERGE(G_REL_SHORT , 16)), PREDEFNODE("bmi", MERGE(G_REL_SHORT , 48)), PREDEFNODE("bvc", MERGE(G_REL_SHORT , 80)), PREDEFNODE("bvs", MERGE(G_REL_SHORT , 112)), PREDEFNODE("bcc", MERGE(G_REL_SHORT , 144)), PREDEFNODE("bcs", MERGE(G_REL_SHORT , 176)), PREDEFNODE("bne", MERGE(G_REL_SHORT , 208)), PREDEFNODE("beq", MERGE(G_REL_SHORT , 240)), PREDEFNODE("jmp", MERGE(G_JUMP , IDX_JMP)), PREDEFNODE("jsr", MERGE(G_JUMP , IDX_JSR)), PREDEFNODE("brk", MERGE(G_IMPLIED , 0)), PREDEFNODE("php", MERGE(G_IMPLIED , 8)), PREDEFNODE("clc", MERGE(G_IMPLIED , 24)), PREDEFNODE("plp", MERGE(G_IMPLIED , 40)), PREDEFNODE("sec", MERGE(G_IMPLIED , 56)), PREDEFNODE("rti", MERGE(G_IMPLIED , 64)), PREDEFNODE("pha", MERGE(G_IMPLIED , 72)), PREDEFNODE("cli", MERGE(G_IMPLIED , 88)), PREDEFNODE("rts", MERGE(G_IMPLIED , 96)), PREDEFNODE("pla", MERGE(G_IMPLIED , 104)), PREDEFNODE("sei", MERGE(G_IMPLIED , 120)), PREDEFNODE("dey", MERGE(G_IMPLIED , 136)), PREDEFNODE("txa", MERGE(G_IMPLIED , 138)), PREDEFNODE("tya", MERGE(G_IMPLIED , 152)), PREDEFNODE("txs", MERGE(G_IMPLIED , 154)), PREDEFNODE("tay", MERGE(G_IMPLIED , 168)), PREDEFNODE("tax", MERGE(G_IMPLIED , 170)), PREDEFNODE("clv", MERGE(G_IMPLIED , 184)), PREDEFNODE("tsx", MERGE(G_IMPLIED , 186)), PREDEFNODE("iny", MERGE(G_IMPLIED , 200)), PREDEFNODE("dex", MERGE(G_IMPLIED , 202)), PREDEFNODE("cld", MERGE(G_IMPLIED , 216)), PREDEFNODE("inx", MERGE(G_IMPLIED , 232)), PREDEFNODE("nop", MERGE(G_IMPLIED , 234)), PREDEFLAST("sed", MERGE(G_IMPLIED , 248)), // ^^^^ this marks the last element }; static node_t mnemos_6510[] = { PREDEFNODE("slo", MERGE(G_MAIN, IDXI_SLO)),// ASL+ORA, ASO PREDEFNODE("rla", MERGE(G_MAIN, IDXI_RLA)),// ROL+AND PREDEFNODE("sre", MERGE(G_MAIN, IDXI_SRE)),// LSR+EOR, LSE PREDEFNODE("rra", MERGE(G_MAIN, IDXI_RRA)),// ROR+ADC PREDEFNODE("sax", MERGE(G_MAIN, IDXI_SAX)),// STX+STA, AAX, AXS PREDEFNODE("lax", MERGE(G_MAIN, IDXI_LAX)),// LDX+LDA PREDEFNODE("dcp", MERGE(G_MAIN, IDXI_DCP)),// DEC+CMP, DCM PREDEFNODE("isc", MERGE(G_MAIN, IDXI_ISC)),// INC+SBC, ISB, INS PREDEFNODE("anc", MERGE(G_MISC, IDXI_ANC)),// ROL+AND, ASL+ORA, AAC PREDEFNODE(s_asr, MERGE(G_MISC, IDXI_ASR)),// LSR+EOR, ALR PREDEFNODE("arr", MERGE(G_MISC, IDXI_ARR)),// ROR+ADC PREDEFNODE("sbx", MERGE(G_MISC, IDXI_SBX)),// DEX+CMP, AXS, SAX PREDEFNODE("dop", MERGE(G_MISC, IDXI_DOP)),// skip next byte PREDEFNODE("top", MERGE(G_MISC, IDXI_TOP)),// skip next two bytes PREDEFLAST("jam", MERGE(G_MISC, IDXI_JAM)),// jam/crash/halt/kill // ^^^^ this marks the last element }; static node_t mnemos_65c02[] = { PREDEFNODE("ora", MERGE(G_MAIN , IDXC_ORA | IMM_ACCU)), PREDEFNODE(s_and, MERGE(G_MAIN , IDXC_AND | IMM_ACCU)), PREDEFNODE(s_eor, MERGE(G_MAIN , IDXC_EOR | IMM_ACCU)), PREDEFNODE("adc", MERGE(G_MAIN , IDXC_ADC | IMM_ACCU)), PREDEFNODE("sta", MERGE(G_MAIN , IDXC_STA)), PREDEFNODE("lda", MERGE(G_MAIN , IDXC_LDA | IMM_ACCU)), PREDEFNODE("cmp", MERGE(G_MAIN , IDXC_CMP | IMM_ACCU)), PREDEFNODE("sbc", MERGE(G_MAIN , IDXC_SBC | IMM_ACCU)), PREDEFNODE("jmp", MERGE(G_JUMP , IDXC_JMP)), PREDEFNODE("bit", MERGE(G_MISC , IDXC_BIT | IMM_ACCU)), PREDEFNODE("dec", MERGE(G_MISC , IDXC_DEC)), PREDEFNODE("inc", MERGE(G_MISC , IDXC_INC)), PREDEFNODE("bra", MERGE(G_REL_SHORT , 128)), PREDEFNODE("phy", MERGE(G_IMPLIED , 90)), PREDEFNODE("ply", MERGE(G_IMPLIED , 122)), PREDEFNODE("phx", MERGE(G_IMPLIED , 218)), PREDEFNODE("plx", MERGE(G_IMPLIED , 250)), PREDEFNODE("tsb", MERGE(G_MISC , IDXC_TSB)), PREDEFNODE("trb", MERGE(G_MISC , IDXC_TRB)), PREDEFLAST("stz", MERGE(G_MISC , IDXC_STZ)), // ^^^^ this marks the last element }; //static node_t mnemos_Rockwell65c02[] = { // PREDEFNODE("rmb0", MERGE(G_ , 0x07)), // PREDEFNODE("rmb1", MERGE(G_ , 0x17)), // PREDEFNODE("rmb2", MERGE(G_ , 0x27)), // PREDEFNODE("rmb3", MERGE(G_ , 0x37)), // PREDEFNODE("rmb4", MERGE(G_ , 0x47)), // PREDEFNODE("rmb5", MERGE(G_ , 0x57)), // PREDEFNODE("rmb6", MERGE(G_ , 0x67)), // PREDEFNODE("rmb7", MERGE(G_ , 0x77)), // PREDEFNODE("smb0", MERGE(G_ , 0x87)), // PREDEFNODE("smb1", MERGE(G_ , 0x97)), // PREDEFNODE("smb2", MERGE(G_ , 0xa7)), // PREDEFNODE("smb3", MERGE(G_ , 0xb7)), // PREDEFNODE("smb4", MERGE(G_ , 0xc7)), // PREDEFNODE("smb5", MERGE(G_ , 0xd7)), // PREDEFNODE("smb6", MERGE(G_ , 0xe7)), // PREDEFNODE("smb7", MERGE(G_ , 0xf7)), // PREDEFNODE("bbr0", MERGE(G_ , 0x0f)), // PREDEFNODE("bbr1", MERGE(G_ , 0x1f)), // PREDEFNODE("bbr2", MERGE(G_ , 0x2f)), // PREDEFNODE("bbr3", MERGE(G_ , 0x3f)), // PREDEFNODE("bbr4", MERGE(G_ , 0x4f)), // PREDEFNODE("bbr5", MERGE(G_ , 0x5f)), // PREDEFNODE("bbr6", MERGE(G_ , 0x6f)), // PREDEFNODE("bbr7", MERGE(G_ , 0x7f)), // PREDEFNODE("bbs0", MERGE(G_ , 0x8f)), // PREDEFNODE("bbs1", MERGE(G_ , 0x9f)), // PREDEFNODE("bbs2", MERGE(G_ , 0xaf)), // PREDEFNODE("bbs3", MERGE(G_ , 0xbf)), // PREDEFNODE("bbs4", MERGE(G_ , 0xcf)), // PREDEFNODE("bbs5", MERGE(G_ , 0xdf)), // PREDEFNODE("bbs6", MERGE(G_ , 0xef)), // PREDEFLAST("bbs7", MERGE(G_ , 0xff)), // // ^^^^ this marks the last element //}; static node_t mnemos_WDC65c02[] = { PREDEFNODE("stp", MERGE(G_IMPLIED , 219)), PREDEFLAST("wai", MERGE(G_IMPLIED , 203)), // ^^^^ this marks the last element }; static node_t mnemos_65816[] = { PREDEFNODE("ora", MERGE(G_MAIN , IDX8_ORA | IMM_ACCU)), PREDEFNODE(s_and, MERGE(G_MAIN , IDX8_AND | IMM_ACCU)), PREDEFNODE(s_eor, MERGE(G_MAIN , IDX8_EOR | IMM_ACCU)), PREDEFNODE("adc", MERGE(G_MAIN , IDX8_ADC | IMM_ACCU)), PREDEFNODE("sta", MERGE(G_MAIN , IDX8_STA)), PREDEFNODE("lda", MERGE(G_MAIN , IDX8_LDA | IMM_ACCU)), PREDEFNODE("cmp", MERGE(G_MAIN , IDX8_CMP | IMM_ACCU)), PREDEFNODE("sbc", MERGE(G_MAIN , IDX8_SBC | IMM_ACCU)), PREDEFNODE("pei", MERGE(G_MAIN , IDX8_PEI)), PREDEFNODE("jmp", MERGE(G_JUMP , IDX8_JMP)), PREDEFNODE("jsr", MERGE(G_JUMP , IDX8_JSR)), PREDEFNODE("jml", MERGE(G_JUMP , IDX8_JML)), PREDEFNODE("jsl", MERGE(G_JUMP , IDX8_JSL)), PREDEFNODE("mvp", MERGE(G_MOVE , 0x44)), PREDEFNODE("mvn", MERGE(G_MOVE , 0x54)), PREDEFNODE("per", MERGE(G_REL_LONG , 98)), PREDEFNODE(s_brl, MERGE(G_REL_LONG , 130)), PREDEFNODE("cop", MERGE(G_MISC , IDX8_COP)), PREDEFNODE("rep", MERGE(G_MISC , IDX8_REP)), PREDEFNODE("sep", MERGE(G_MISC , IDX8_SEP)), PREDEFNODE("pea", MERGE(G_MISC , IDX8_PEA)), PREDEFNODE("phd", MERGE(G_IMPLIED , 11)), PREDEFNODE("tcs", MERGE(G_IMPLIED , 27)), PREDEFNODE("pld", MERGE(G_IMPLIED , 43)), PREDEFNODE("tsc", MERGE(G_IMPLIED , 59)), PREDEFNODE("wdm", MERGE(G_IMPLIED , 66)), PREDEFNODE("phk", MERGE(G_IMPLIED , 75)), PREDEFNODE("tcd", MERGE(G_IMPLIED , 91)), PREDEFNODE("rtl", MERGE(G_IMPLIED , 107)), PREDEFNODE("tdc", MERGE(G_IMPLIED , 123)), PREDEFNODE("phb", MERGE(G_IMPLIED , 139)), PREDEFNODE("txy", MERGE(G_IMPLIED , 155)), PREDEFNODE("plb", MERGE(G_IMPLIED , 171)), PREDEFNODE("tyx", MERGE(G_IMPLIED , 187)), PREDEFNODE("xba", MERGE(G_IMPLIED , 235)), PREDEFLAST("xce", MERGE(G_IMPLIED , 251)), // ^^^^ this marks the last element }; // Functions // create dynamic buffer, build keyword trees void Mnemo_init(void) { mnemo_dyna_buf = DynaBuf_create(MNEMO_DYNABUF_INITIALSIZE); Tree_add_table(&mnemo_6502_tree, mnemos_6502); Tree_add_table(&mnemo_6510_tree, mnemos_6510); Tree_add_table(&mnemo_65c02_tree, mnemos_65c02); // Tree_add_table(&mnemo_Rockwell65c02_tree, mnemos_Rockwell65c02); Tree_add_table(&mnemo_WDC65c02_tree, mnemos_WDC65c02); Tree_add_table(&mnemo_65816_tree, mnemos_65816); } // Address mode parsing // Utility function for parsing indices. static int get_index(bool next) { int addressing_mode = HAM__; if(next) GetByte(); if(!Input_accept_comma()) return(addressing_mode); switch(GotByte) { case 's': case 'S': addressing_mode = HAM_S; break; case 'x': case 'X': addressing_mode = HAM_X; break; case 'y': case 'Y': addressing_mode = HAM_Y; break; default: Throw_error(exception_syntax); } if(addressing_mode != HAM__) NEXTANDSKIPSPACE(); return(addressing_mode); } // This function stores the command's argument in the given result_int_t // structure (using the valueparser). The addressing mode is returned. static int get_argument(result_int_t* result) { int open_paren, addressing_mode = HAM_ABS; SKIPSPACE(); switch(GotByte) { case '[': GetByte();// proceed with next char ALU_int_result(result); if(GotByte == ']') addressing_mode |= HAM_LIND | get_index(TRUE); else Throw_error(exception_syntax); break; case '#': GetByte();// proceed with next char addressing_mode |= HAM_IMM; ALU_int_result(result); break; default: // liberal, to allow for "(...," open_paren = ALU_liberal_int(result); // check for implied addressing if((result->flags & MVALUE_EXISTS) == 0) addressing_mode |= HAM_IMP; // check for indirect addressing if(result->flags & MVALUE_INDIRECT) addressing_mode |= HAM_IND; // check for internal index (before closing parenthesis) if(open_paren) { // in case there are still open parentheses, // read internal index addressing_mode |= (get_index(FALSE) << 2); if(GotByte == ')') GetByte();// go on with next char else Throw_error(exception_syntax); } // check for external index (after closing parenthesis) addressing_mode |= get_index(FALSE); break; } // ensure end of line Input_ensure_EOS(); //printf("AM: %x\n", addressing_mode); return(addressing_mode); } // Helper function for calc_arg_size() // Only call with "size_bit = MVALUE_FORCE16" or "size_bit = MVALUE_FORCE24" static int check_oversize(int size_bit, result_int_t* argument) { // only check if value is *defined* if((argument->flags & MVALUE_DEFINED) == 0) return(size_bit);// pass on result // value is defined, so check if(size_bit == MVALUE_FORCE16) { // check 16-bit argument for high byte zero if((argument->intval <= 255) && (argument->intval >= -128)) Throw_warning(exception_highbyte_zero); } else // check 24-bit argument for bank byte zero if((argument->intval <= 65535) && (argument->intval >= -32768)) Throw_warning(exception_highbyte_zero); return(size_bit);// pass on result } // Utility function for comparing force bits, argument value, argument size, // "unsure"-flag and possible addressing modes. Returns force bit matching // number of parameter bytes to send. If it returns zero, an error occurred // (and has already been delivered). // force_bit none, 8b, 16b, 24b // argument value and flags of parameter // addressing_modes adressing modes (8b, 16b, 24b or any combination) // Return value = force bit for number of parameter bytes to send (0 = error) static int calc_arg_size(int force_bit, result_int_t* argument, int addressing_modes) { // If there are no possible addressing modes, complain if(addressing_modes == MAYBE______) { Throw_error(exception_illegal_combination); return(0); } // If command has force bit, act upon it if(force_bit) { // If command allows this force bit, return it if(addressing_modes & force_bit) return(force_bit); // If not, complain Throw_error("Illegal combination of command and postfix."); return(0); } // Command has no force bit. Check whether value has one // If value has force bit, act upon it if(argument->flags & MVALUE_FORCEBITS) { // Value has force bit set, so return this or bigger size if(MVALUE_FORCE08 & addressing_modes & argument->flags) return(MVALUE_FORCE08); if(MVALUE_FORCE16 & addressing_modes & argument->flags) return(MVALUE_FORCE16); if(MVALUE_FORCE24 & addressing_modes) return(MVALUE_FORCE24); Throw_error(exception_number_out_of_range);// else error return(0); } // Value has no force bit. Check whether there's only one addr mode // If only one addressing mode, use that if((addressing_modes == MVALUE_FORCE08) || (addressing_modes == MVALUE_FORCE16) || (addressing_modes == MVALUE_FORCE24)) return(addressing_modes);// There's only one, so use it // There's more than one addressing mode. Check whether value is sure // If value is unsure, use default size if(argument->flags & MVALUE_UNSURE) { // If there is an 8-bit addressing mode *and* the value // is sure to fit into 8 bits, use the 8-bit mode if((addressing_modes & MVALUE_FORCE08) && (argument->flags & MVALUE_ISBYTE)) return(MVALUE_FORCE08); // If there is a 16-bit addressing, use that // Call helper function for "oversized addr mode" warning if(MVALUE_FORCE16 & addressing_modes) return(check_oversize(MVALUE_FORCE16, argument)); // If there is a 24-bit addressing, use that // Call helper function for "oversized addr mode" warning if(MVALUE_FORCE24 & addressing_modes) return(check_oversize(MVALUE_FORCE24, argument)); // otherwise, use 8-bit-addressing, which will raise an // error later on if the value won't fit return(MVALUE_FORCE08); } // Value is sure, so use its own size // If value is negative, size cannot be chosen. Complain! if(argument->intval < 0) { Throw_error("Negative value - cannot choose addressing mode."); return(0); } // Value is positive or zero. Check size ranges // If there is an 8-bit addressing mode and value fits, use 8 bits if((addressing_modes & MVALUE_FORCE08) && (argument->intval < 256)) return(MVALUE_FORCE08); // If there is a 16-bit addressing mode and value fits, use 16 bits if((addressing_modes & MVALUE_FORCE16) && (argument->intval < 65536)) return(MVALUE_FORCE16); // If there is a 24-bit addressing mode, use that. In case the // value doesn't fit, the output function will do the complaining. if(addressing_modes & MVALUE_FORCE24) return(MVALUE_FORCE24); // Value is too big for all possible addressing modes Throw_error(exception_number_out_of_range); return(0); } // Mnemonics using only implied addressing. static void group_only_implied_addressing(int opcode) { Output_byte(opcode); Input_ensure_EOS(); } // Mnemonics using only 8bit relative addressing (short branch instructions). static void group_only_relative8_addressing(int opcode) { result_int_t result; ALU_int_result(&result); if(result.flags & MVALUE_DEFINED) { result.intval -= (CPU_pc.intval + 2); if((result.intval > 127) || (result.intval < -128)) Throw_error(exception_too_far); } Output_byte(opcode); // this fn has its own range check (see above). // No reason to irritate the user with another error message, // so use Output_byte() instead of Output_8b() //Output_8b(result.value); Output_byte(result.intval); Input_ensure_EOS(); } // Mnemonics using only 16bit relative addressing (BRL and PER). static void group_only_relative16_addressing(int opcode) { result_int_t result; ALU_int_result(&result); if(result.flags & MVALUE_DEFINED) { result.intval -= (CPU_pc.intval + 3); if((result.intval > 32767) || (result.intval < -32768)) Throw_error(exception_too_far); } Output_byte(opcode); // this fn has its own range check (see above). // No reason to irritate the user with another error message, // so use Output_byte() instead of Output_16b() //Output_16b(result.value); Output_byte(result.intval); Output_byte(result.intval >> 8); Input_ensure_EOS(); } // set addressing mode bits depending on which opcodes exist, then calculate // argument size and output both opcode and argument static void make_command(int force_bit, result_int_t* result, unsigned long opcodes) { int addressing_modes = MAYBE______; if(opcodes & 0x0000ff) addressing_modes |= MAYBE_1____; if(opcodes & 0x00ff00) addressing_modes |= MAYBE___2__; if(opcodes & 0xff0000) addressing_modes |= MAYBE_____3; switch(calc_arg_size(force_bit, result, addressing_modes)) { case MVALUE_FORCE08: Output_byte(opcodes & 255); Output_8b(result->intval); break; case MVALUE_FORCE16: Output_byte((opcodes >> 8) & 255); Output_16b(result->intval); break; case MVALUE_FORCE24: Output_byte((opcodes >> 16) & 255); Output_24b(result->intval); break; } } // check whether 16bit immediate addressing is allowed. If not, return given // opcode. If it is allowed, set force bits according to CPU register length // and return given opcode for both 8- and 16-bit mode. static unsigned int imm_ops(int *force_bit, unsigned char opcode, int imm_flag) { // if the CPU does not allow 16bit immediate addressing (or if the // opcode does not allow it), return immediately. if((CPU_now->long_regs == NULL) || (imm_flag == 0)) return(opcode); // check force bits (if no force bits given, use relevant flag) if(*force_bit == 0) *force_bit = ((imm_flag & IMM_ACCU) ? CPU_now->long_regs[LONGREG_IDX_A] : CPU_now->long_regs[LONGREG_IDX_R]) ? MVALUE_FORCE16 : MVALUE_FORCE08; // return identical opcodes for 8bit and 16bit args! return((((unsigned int) opcode) << 8) | opcode); } // The main accumulator stuff (ADC, AND, CMP, EOR, LDA, ORA, SBC, STA) // plus PEI. static void group_main(int index, int imm_flag) { unsigned long imm_opcodes; result_int_t result; int force_bit = Input_get_force_bit();// skips spaces after switch(get_argument(&result)) { // #$ff or #$ffff (depending on accu length) case HAM_IMM: imm_opcodes = imm_ops(&force_bit, accu_imm[index], imm_flag); // CAUTION - do not incorporate the line above into the line // below - "fb" might be undefined (depends on compiler). make_command(force_bit, &result, imm_opcodes); break; // $ff, $ffff, $ffffff case HAM_ABS: make_command(force_bit, &result, accu_abs[index]); break; // $ff,x, $ffff,x, $ffffff,x case HAM_ABSX: make_command(force_bit, &result, accu_xabs[index]); break; // $ffff,y (in theory, "$ff,y" as well) case HAM_ABSY: make_command(force_bit, &result, accu_yabs[index]); break; // $ff,s case HAM_ABSS: make_command(force_bit, &result, accu_sabs8[index]); break; // ($ff,x) case HAM_XIND: make_command(force_bit, &result, accu_xind8[index]); break; // ($ff) case HAM_IND: make_command(force_bit, &result, accu_ind8[index]); break; // ($ff),y case HAM_INDY: make_command(force_bit, &result, accu_indy8[index]); break; // [$ff] case HAM_LIND: make_command(force_bit, &result, accu_lind8[index]); break; // [$ff],y case HAM_LINDY: make_command(force_bit, &result, accu_lindy8[index]); break; // ($ff,s),y case HAM_SINDY: make_command(force_bit, &result, accu_sindy8[index]); break; // other combinations are illegal default: Throw_error(exception_illegal_combination); } } // Various mnemonics with different addressing modes. static void group_misc(int index, int imm_flag) { unsigned long imm_opcodes; result_int_t result; int force_bit = Input_get_force_bit();// skips spaces after switch(get_argument(&result)) { // implied addressing case HAM_IMP: if(misc_impl[index]) Output_byte(misc_impl[index]); else Throw_error(exception_illegal_combination); break; // #$ff or #$ffff (depending on index register length) case HAM_IMM: imm_opcodes = imm_ops(&force_bit, misc_imm[index], imm_flag); // CAUTION - do not incorporate the line above into the line // below - force_bit might be undefined (depends on compiler). make_command(force_bit, &result, imm_opcodes); break; // $ff or $ffff case HAM_ABS: make_command(force_bit, &result, misc_abs[index]); break; // $ff,x or $ffff,x case HAM_ABSX: make_command(force_bit, &result, misc_xabs[index]); break; // $ff,y or $ffff,y case HAM_ABSY: make_command(force_bit, &result, misc_yabs[index]); break; // other combinations are illegal default: Throw_error(exception_illegal_combination); } } // Mnemonics using "8bit, 8bit" addressing. Only applies to "MVN" and "MVP". static void group_move(int opcode) { intval_t source, target; // assembler syntax: "opcode source, target" source = ALU_any_int(); if(Input_accept_comma()) { target = ALU_any_int(); // machine language: Output_byte(opcode); // opcode Output_8b(target); // target Output_8b(source); // source Input_ensure_EOS(); } else Throw_error(exception_syntax); } // The jump instructions. static void group_jump(int index) { result_int_t result; int force_bit = Input_get_force_bit();// skips spaces after switch(get_argument(&result)) { // absolute16 or absolute24 case HAM_ABS: make_command(force_bit, &result, jump_abs[index]); break; // ($ffff) case HAM_IND: make_command(force_bit, &result, jump_ind[index]); // check whether to warn about 6502's JMP() bug if(((result.intval & 0xff) == 0xff) && (result.flags & MVALUE_DEFINED) && (CPU_now->flags & CPUFLAG_INDJMPBUGGY)) Throw_warning("Assembling buggy JMP($xxff) instruction"); break; // ($ffff,x) case HAM_XIND: make_command(force_bit, &result, jump_xind[index]); break; // [$ffff] case HAM_LIND: make_command(force_bit, &result, jump_lind[index]); break; // other combinations are illegal default: Throw_error(exception_illegal_combination); } } // Work function static bool check_mnemo_tree(node_t* tree, dynabuf_t* dyna_buf) { void* node_body; int code, imm_flag; // flag for immediate addressing // search for tree item if(!Tree_easy_scan(tree, &node_body, dyna_buf)) return(FALSE); code = ((int) node_body) & CODEMASK; // get opcode or table index imm_flag = ((int) node_body) & FLAGSMASK; // get flag switch(((long) node_body) >> GROUPSHIFT) { // mnemonics with only implied addressing case G_IMPLIED: group_only_implied_addressing(code); break; // main accumulator stuff case G_MAIN: group_main(code, imm_flag); break; // misc case G_MISC: group_misc(code, imm_flag); break; // short relative case G_REL_SHORT: group_only_relative8_addressing(code); break; // long relative case G_REL_LONG: group_only_relative16_addressing(code); break; // the jump instructions case G_JUMP: group_jump(code); break; // "mvp" and "mvn" case G_MOVE: group_move(code); break; // others indicate bugs default: Bug_found("IllegalGroupIndex", code); } return(TRUE); } // Check whether mnemonic in GlobalDynaBuf is supported by 6502 cpu. bool keyword_is_6502mnemo(int length) { if(length != 3) return(FALSE); // make lower case version of mnemonic in local dynamic buffer DynaBuf_to_lower(mnemo_dyna_buf, GlobalDynaBuf); if(check_mnemo_tree(mnemo_6502_tree, mnemo_dyna_buf)) return(TRUE); return(FALSE); } // Check whether mnemonic in GlobalDynaBuf is supported by 6510 cpu. bool keyword_is_6510mnemo(int length) { if(length != 3) return(FALSE); // make lower case version of mnemonic in local dynamic buffer DynaBuf_to_lower(mnemo_dyna_buf, GlobalDynaBuf); // first check extensions... if(check_mnemo_tree(mnemo_6510_tree, mnemo_dyna_buf)) return(TRUE); // ...then check original opcodes if(check_mnemo_tree(mnemo_6502_tree, mnemo_dyna_buf)) return(TRUE); return(FALSE); } // Check whether mnemonic in GlobalDynaBuf is supported by 65c02 cpu. bool keyword_is_65c02mnemo(int length) { if(length != 3) return(FALSE); // make lower case version of mnemonic in local dynamic buffer DynaBuf_to_lower(mnemo_dyna_buf, GlobalDynaBuf); // first check extensions... if(check_mnemo_tree(mnemo_65c02_tree, mnemo_dyna_buf)) return(TRUE); // ...then check original opcodes if(check_mnemo_tree(mnemo_6502_tree, mnemo_dyna_buf)) return(TRUE); return(FALSE); } //// Check whether mnemonic in GlobalDynaBuf is supported by Rockwell 65c02 cpu. //bool keyword_is_Rockwell65c02mnemo(int length) { // if((length != 3) && (length != 4)) // return(FALSE); // // make lower case version of mnemonic in local dynamic buffer // DynaBuf_to_lower(mnemo_dyna_buf, GlobalDynaBuf); // // first check 65c02 extensions... // if(check_mnemo_tree(mnemo_65c02_tree, mnemo_dyna_buf)) // return(TRUE); // // ...then check original opcodes... // if(check_mnemo_tree(mnemo_6502_tree, mnemo_dyna_buf)) // return(TRUE); // // ...then check Rockwell/WDC extensions (rmb, smb, bbr, bbs) // if(check_mnemo_tree(mnemo_Rockwell65c02_tree, mnemo_dyna_buf)) // return(TRUE); // return(FALSE); //} //// Check whether mnemonic in GlobalDynaBuf is supported by WDC 65c02 cpu. //bool keyword_is_WDC65c02mnemo(int length) { // if((length != 3) && (length != 4)) // return(FALSE); // // make lower case version of mnemonic in local dynamic buffer // DynaBuf_to_lower(mnemo_dyna_buf, GlobalDynaBuf); // // first check 65c02 extensions... // if(check_mnemo_tree(mnemo_65c02_tree, mnemo_dyna_buf)) // return(TRUE); // // ...then check original opcodes... // if(check_mnemo_tree(mnemo_6502_tree, mnemo_dyna_buf)) // return(TRUE); // // ...then check Rockwell/WDC extensions (rmb, smb, bbr, bbs)... // if(check_mnemo_tree(mnemo_Rockwell65c02_tree, mnemo_dyna_buf)) // return(TRUE); // // ...then check WDC extensions (only two mnemonics, so do last) // if(check_mnemo_tree(mnemo_WDC65c02_tree, mnemo_dyna_buf)) // return(TRUE); // return(FALSE); //} // Check whether mnemonic in GlobalDynaBuf is supported by 65816 cpu. bool keyword_is_65816mnemo(int length) { if(length != 3) return(FALSE); // make lower case version of mnemonic in local dynamic buffer DynaBuf_to_lower(mnemo_dyna_buf, GlobalDynaBuf); // first check "new" extensions... if(check_mnemo_tree(mnemo_65816_tree, mnemo_dyna_buf)) return(TRUE); // ...then "old" extensions... if(check_mnemo_tree(mnemo_65c02_tree, mnemo_dyna_buf)) return(TRUE); // ...then check original opcodes... if(check_mnemo_tree(mnemo_6502_tree, mnemo_dyna_buf)) return(TRUE); // ...then check WDC extensions "stp" and "wai" if(check_mnemo_tree(mnemo_WDC65c02_tree, mnemo_dyna_buf)) return(TRUE); return(FALSE); } CheeseCutter-2.10/src/asm/mnemo.h000066400000000000000000000020141516216315000166470ustar00rootroot00000000000000// // ACME - a crossassembler for producing 6502/65c02/65816 code. // Copyright (C) 1998-2006 Marco Baye // Have a look at "acme.c" for further info // // Mnemonic definitions #ifndef mnemo_H #define mnemo_H // Prototypes // create dynamic buffer, build keyword trees extern void Mnemo_init(void); // Check whether mnemonic in GlobalDynaBuf is supported by 6502 cpu. extern bool keyword_is_6502mnemo(int length); // Check whether mnemonic in GlobalDynaBuf is supported by 6510 cpu. extern bool keyword_is_6510mnemo(int length); // Check whether mnemonic in GlobalDynaBuf is supported by 65c02 cpu. extern bool keyword_is_65c02mnemo(int length); // Check whether mnemonic in GlobalDynaBuf is supported by Rockwell 65c02 cpu. //extern bool keyword_is_Rockwell65c02mnemo(int length); // Check whether mnemonic in GlobalDynaBuf is supported by WDC 65c02 cpu. //extern bool keyword_is_WDC65c02mnemo(int length); // Check whether mnemonic in GlobalDynaBuf is supported by 65816 cpu. extern bool keyword_is_65816mnemo(int length); #endif CheeseCutter-2.10/src/asm/output.c000066400000000000000000000311321516216315000170720ustar00rootroot00000000000000// // ACME - a crossassembler for producing 6502/65c02/65816 code. // Copyright (C) 1998-2006 Marco Baye // Have a look at "acme.c" for further info // // Output stuff #include //#include #include // for memset() #include "acme.h" #include "alu.h" #include "config.h" #include "cpu.h" #include "dynabuf.h" #include "global.h" #include "input.h" #include "output.h" #include "platform.h" #include "tree.h" // Structure for linked list of segment data struct segment_t { struct segment_t* next; // struct segment_t* prev; intval_t start; intval_t length; }; // Constants #define OUTBUFFERSIZE 65536 enum out_format_t { OUTPUT_FORMAT_UNSPECIFIED, // default (uses "plain" actually) OUTPUT_FORMAT_PLAIN, OUTPUT_FORMAT_CBM, // default for "!to" pseudo opcode }; // Variables // segment stuff static struct segment_t* segment_list = NULL;// linked list static intval_t segment_start;// Start of current segment static intval_t segment_max;// Highest address segment may use // misc static intval_t lowest_idx; // Smallest address program uses static intval_t highest_idx; // End address of program plus one // output buffer stuff static char* output_buffer = NULL; // to hold assembled code static char* write_ptr = NULL; // points into output_buffer intval_t write_idx; // index in output buffer static bool memory_initialised = FALSE; // chosen file format static enum out_format_t output_format = OUTPUT_FORMAT_CBM; // predefined stuff static node_t* file_format_tree = NULL;// tree to hold output formats // possible file formats static node_t file_formats[] = { PREDEFNODE(s_cbm, OUTPUT_FORMAT_CBM), // PREDEFNODE("o65", OUTPUT_FORMAT_O65), PREDEFLAST("plain", OUTPUT_FORMAT_PLAIN), // ^^^^ this marks the last element }; // Functions // Fill output buffer with given byte value static void fill_completely(char value) { memset(output_buffer, value, OUTBUFFERSIZE); } // Set up new segment_max value according to the given address. Just // find the next segment start and subtract 1. static void find_segment_max(intval_t new_pc) { struct segment_t* test_segment; // may be faster if list is ordered! segment_max = OUTBUFFERSIZE;// will be decremented later! test_segment = segment_list; while(test_segment) { if((test_segment->start > new_pc) && (test_segment->start < segment_max)) segment_max = test_segment->start; test_segment = test_segment->next; } segment_max--;// last free address available } // static void border_crossed(int current_offset) { if(current_offset >= OUTBUFFERSIZE) Throw_serious_error("Produced too much code."); if(pass_count == 0) { Throw_warning("Segment reached another one, overwriting it."); find_segment_max(current_offset + 1); } } // Send low byte to output buffer void (*Output_byte)(intval_t byte); static void real_output(intval_t byte); // fn for actual output static void no_output(intval_t byte); // fn when output impossible // set output pointer (negative values deactivate output) static void set_mem_ptr(signed long index) { if(index < 0) { Output_byte = no_output; write_ptr = output_buffer; write_idx = 0; } else { Output_byte = real_output; write_ptr = output_buffer + index; write_idx = index; } } // Send low byte to output buffer, automatically increasing program counter static void real_output(intval_t byte) { if(write_idx > segment_max) border_crossed(write_idx); *write_ptr++ = byte & 0xff; write_idx++; CPU_2add++; } // fail to write to output buffer static void no_output(intval_t byte) { Throw_error(exception_pc_undefined); // set ptr to not complain again. as we have thrown an error, assembly // fails, so don't care about actual value. set_mem_ptr(512); // 512 to not garble zero page and stack. ;) CPU_2add++; } // call this if really calling Output_byte would be a waste of time void Output_fake(int size) { // check whether ptr undefined if(Output_byte == no_output) { no_output(0); size--; } if(write_idx + size - 1 > segment_max) border_crossed(write_idx + size - 1); write_ptr += size; write_idx += size; CPU_2add += size; } // Output 8-bit value with range check void Output_8b(intval_t value) { if((value <= 0xff) && (value >= -0x80)) Output_byte(value); else Throw_error(exception_number_out_of_range); } // Output 16-bit value with range check void Output_16b(intval_t value) { if((value <= 0xffff) && (value >= -0x8000)) { Output_byte(value); Output_byte(value >> 8); } else Throw_error(exception_number_out_of_range); } // Output 24-bit value with range check void Output_24b(intval_t value) { if((value <= 0xffffff) && (value >= -0x800000)) { Output_byte(value); Output_byte(value >> 8); Output_byte(value >> 16); } else Throw_error(exception_number_out_of_range); } // Output 32-bit value (without range check) void Output_32b(intval_t value) { // if((Value <= 0x7fffffff) && (Value >= -0x80000000)) { Output_byte(value); Output_byte(value >> 8); Output_byte(value >> 16); Output_byte(value >> 24); // } else // Throw_error(exception_number_out_of_range); } // Define default value for empty memory ("!initmem" pseudo opcode) static enum eos_t PO_initmem(void) { intval_t content; // ignore in all passes but in first if(pass_count) return(SKIP_REMAINDER); // if MemInit flag is already set, complain if(memory_initialised) { Throw_warning("Memory already initialised."); return(SKIP_REMAINDER); } // set MemInit flag memory_initialised = TRUE; // get value and init memory content = ALU_defined_int(); if((content > 0xff) || (content < -0x80)) Throw_error(exception_number_out_of_range); // init memory fill_completely(content); // enforce another pass if(pass_undefined_count == 0) pass_undefined_count = 1; // FIXME - enforcing another pass is not needed if there hasn't been any // output yet. But that's tricky to detect without too much overhead. // The old solution was to add &&(lowest_idx < highest_idx) to "if" above return(ENSURE_EOS); } // Try to set output format held in DynaBuf. Returns whether succeeded. bool Output_set_output_format(void) { void* node_body; if(!Tree_easy_scan(file_format_tree, &node_body, GlobalDynaBuf)) return(FALSE); output_format = (enum out_format_t) node_body; return(TRUE); } // Select output file and format ("!to" pseudo opcode) static enum eos_t PO_to(void) { // only act upon this pseudo opcode in first pass if(pass_count) return(SKIP_REMAINDER); // if output file already chosen, complain and exit if(output_filename) { Throw_warning("Output file already chosen."); return(SKIP_REMAINDER); } // read filename to global dynamic buffer // if no file name given, exit (complaining will have been done) if(Input_read_filename(FALSE)) return(SKIP_REMAINDER); // get malloc'd copy of filename output_filename = DynaBuf_get_copy(GlobalDynaBuf); // select output format // if no comma found, use default file format if(Input_accept_comma() == FALSE) { if(output_format == OUTPUT_FORMAT_UNSPECIFIED) { output_format = OUTPUT_FORMAT_CBM; // output deprecation warning Throw_warning("Used \"!to\" without file format indicator. Defaulting to \"cbm\"."); } return(ENSURE_EOS); } // parse output format name // if no keyword given, give up if(Input_read_and_lower_keyword() == 0) return(SKIP_REMAINDER); if(Output_set_output_format()) return(ENSURE_EOS); // success // error occurred Throw_error("Unknown output format."); return(SKIP_REMAINDER); } // pseudo ocpode table static node_t pseudo_opcodes[] = { PREDEFNODE("initmem", PO_initmem), PREDEFLAST("to", PO_to), // ^^^^ this marks the last element }; // Init file format tree (is done early) void Outputfile_init(void) { Tree_add_table(&file_format_tree, file_formats); } // alloc and init mem buffer, register pseudo opcodes (done later) void Output_init(signed long fill_value) { output_buffer = safe_malloc(OUTBUFFERSIZE); write_ptr = output_buffer; if(fill_value == MEMINIT_USE_DEFAULT) fill_value = FILLVALUE_INITIAL; else memory_initialised = TRUE; // init output buffer (fill memory with initial value) fill_completely(fill_value & 0xff); Tree_add_table(&pseudo_opcode_tree, pseudo_opcodes); } // Dump memory buffer into output file void Output_save_file(FILE* fd) { intval_t amount = highest_idx - lowest_idx; if(Process_verbosity) printf("Saving %ld ($%lx) bytes ($%lx - $%lx exclusive).\n", amount, amount, lowest_idx, highest_idx); // Output file header according to file format switch(output_format) { case OUTPUT_FORMAT_UNSPECIFIED: case OUTPUT_FORMAT_PLAIN: PLATFORM_SETFILETYPE_PLAIN(output_filename); break; case OUTPUT_FORMAT_CBM: PLATFORM_SETFILETYPE_CBM(output_filename); // output 16-bit load address in little-endian byte order putc(lowest_idx & 255, fd); putc(lowest_idx >> 8, fd); break; } // Dump output buffer to file fwrite(output_buffer + lowest_idx, sizeof(char), amount, fd); } char* Output_get_final_data(int *length) { intval_t amount = highest_idx - lowest_idx; int bufsize = amount * sizeof(char); if(Process_verbosity) printf("Saving %ld ($%lx) bytes ($%lx - $%lx exclusive).\n", amount, amount, lowest_idx, highest_idx); // Output file header according to file format switch(output_format) { case OUTPUT_FORMAT_UNSPECIFIED: case OUTPUT_FORMAT_PLAIN: PLATFORM_SETFILETYPE_PLAIN(output_filename); break; case OUTPUT_FORMAT_CBM: PLATFORM_SETFILETYPE_CBM(output_filename); // TODO: insert load address here // output 16-bit load address in little-endian byte order //cbm_load_address = lowest_idx; //putc(lowest_idx & 255, fd); //putc(lowest_idx >> 8, fd); bufsize += 2; break; } // Dump output buffer to file //fwrite(output_buffer + lowest_idx, sizeof(char), amount, fd); char* buffer = malloc(bufsize); if(output_format == OUTPUT_FORMAT_CBM) { buffer[0] = lowest_idx & 255; buffer[1] = lowest_idx >> 8; memcpy(buffer + 2, output_buffer + lowest_idx, amount); } else { memcpy(buffer, output_buffer + lowest_idx, amount); } *length = bufsize; return buffer; } // Link segment data into segment chain static void link_segment(intval_t start, intval_t length) { struct segment_t* new_segment; new_segment = safe_malloc(sizeof(struct segment_t)); new_segment->start = start; new_segment->length = length; new_segment->next = segment_list; segment_list = new_segment; } // Show start and end of current segment // Called whenever a new segment begins, and at end of pass. void Output_end_segment(void) { intval_t amount; if(CPU_uses_pseudo_pc()) Throw_first_pass_warning("Offset assembly still active at end of segment."); // FIXME - should be error! if(pass_count == 0) { amount = write_idx - segment_start; link_segment(segment_start, amount); if(Process_verbosity > 1) printf( "Segment size is %ld ($%lx) bytes ($%lx - $%lx exclusive).\n", amount, amount, segment_start, write_idx); } // FIXME - this was in real_output(): // check for new max address (FIXME - move to close_segment?) if(write_idx > highest_idx) highest_idx = write_idx; } // Check whether given PC is inside segment. static void check_segment(intval_t new_pc) { struct segment_t* test_segment; test_segment = segment_list; while(test_segment) { if((new_pc >= test_segment->start) && (new_pc < (test_segment->start) + (test_segment->length))) Throw_warning("Segment starts inside another one, overwriting it."); test_segment = test_segment->next; } } // init lowest and highest address static void init_borders(intval_t address) { lowest_idx = address; highest_idx = address; } // clear segment list void Output_passinit(signed long start_addr) { struct segment_t* temp; // delete segment list (and free blocks) while((temp = segment_list)) { segment_list = segment_list->next; free(temp); } set_mem_ptr(start_addr); // negative values deactivate output // if start address given, set program counter if(start_addr >= 0) { CPU_set_pc(start_addr); // FIXME - integrate next two? init_borders(start_addr); segment_start = start_addr; } else { init_borders(0); // set to _something_ (for !initmem) segment_start = 0; } // other stuff segment_max = OUTBUFFERSIZE-1; } // Called when "*=EXPRESSION" is parsed void Output_start_segment(void) { intval_t new_addr = ALU_defined_int(); if(CPU_pc.flags & MVALUE_DEFINED) { // It's a redefinition. Check some things: // check whether new low if(new_addr < lowest_idx) lowest_idx = new_addr; // show status of previous segment Output_end_segment(); // in first pass, maybe issue warning if(pass_count == 0) { check_segment(new_addr); find_segment_max(new_addr); } } else init_borders(new_addr);// it's the first pc definition CPU_set_pc(new_addr); segment_start = new_addr; set_mem_ptr(new_addr); } CheeseCutter-2.10/src/asm/output.h000066400000000000000000000027621516216315000171060ustar00rootroot00000000000000// // ACME - a crossassembler for producing 6502/65c02/65816 code. // Copyright (C) 1998-2006 Marco Baye // Have a look at "acme.c" for further info // // Output stuff #ifndef output_H #define output_H #include #include "config.h" // Constants #define MEMINIT_USE_DEFAULT 256 // Prototypes // Init file format tree (is done early) extern void Outputfile_init(void); // alloc and init mem buffer, register pseudo opcodes (done later) extern void Output_init(signed long fill_value); // clear segment list extern void Output_passinit(signed long start_addr); // call this if really calling Output_byte would be a waste of time extern void Output_fake(int size); // Send low byte of arg to output buffer and advance pointer extern void (*Output_byte)(intval_t); // Output 8-bit value with range check extern void Output_8b(intval_t); // Output 16-bit value with range check extern void Output_16b(intval_t); // Output 24-bit value with range check extern void Output_24b(intval_t); // Output 32-bit value (without range check) extern void Output_32b(intval_t); // Try to set output format held in DynaBuf. Returns whether succeeded. extern bool Output_set_output_format(void); // write smallest-possible part of memory buffer to file extern void Output_save_file(FILE* fd); // send final output as binary extern char* Output_get_final_data(); // Call when "*=EXPRESSION" is parsed extern void Output_start_segment(void); // Show start and end of current segment extern void Output_end_segment(void); #endif CheeseCutter-2.10/src/asm/platform.c000066400000000000000000000012641516216315000173610ustar00rootroot00000000000000// // ACME - a crossassembler for producing 6502/65c02/65816 code. // Copyright (C) 1998-2006 Marco Baye // Have a look at "acme.c" for further info // // Platform specific stuff #include "config.h" #include "platform.h" // Amiga #ifdef _AMIGA #ifndef platform_C #define platform_C // Nothing here - Amigas don't need no stinkin' platform-specific stuff! #endif #endif // DOS and OS/2 #ifdef __DJGPP__ #include "_dos.c" #endif #ifdef __OS2__ #include "_dos.c" #endif //#ifdef __Windows__ //#include "_dos.c" //#endif // RISC OS #ifdef __riscos__ #include "_riscos.c" #endif // add further platform files here // Unix/Linux/others (surprisingly also works on Windows) #include "_std.c" CheeseCutter-2.10/src/asm/platform.h000066400000000000000000000006231516216315000173640ustar00rootroot00000000000000// // ACME - a crossassembler for producing 6502/65c02/65816 code. // Copyright (C) 1998-2006 Marco Baye // Have a look at "acme.c" for further info // // Platform specific stuff // Unix/Linux/others (surprisingly also works on Windows) #ifndef PLATFORM_VERSION #define PLATFORM_VERSION "Platform independent version.\nCurrent maintainer Krzysztof Dabrowski aka BruSH/ElysiuM" #endif #include "_std.h" CheeseCutter-2.10/src/asm/section.c000066400000000000000000000070751516216315000172070ustar00rootroot00000000000000// // ACME - a crossassembler for producing 6502/65c02/65816 code. // Copyright (C) 1998-2006 Marco Baye // Have a look at "acme.c" for further info // // Section stuff #include "config.h" #include "dynabuf.h" #include "global.h" #include "input.h" #include "tree.h" #include "section.h" // Constants static const char type_zone[] = "Zone"; static const char s_subzone[] = "subzone"; #define s_zone (s_subzone+3) // Yes, I know I'm sick static char untitled[] = ""; // ...is actually constant, but flagging it "const" results in heap of warnings // fake section structure (for error msgs before any real section is in use) static section_t initial_section = { 0, // zone value "during", // "type" => normally "zone Title" or "init", // "title" => "macro test", now "during init" FALSE, // no, title was not malloc'd }; // Variables section_t* Section_now = &initial_section;// current section static section_t outer_section; // outermost section struct static zone_t zone_max; // Highest zone number yet // Write given info into given zone structure and activate it void Section_new_zone(section_t* section, const char* type, char* title, bool allocated) { section->zone = ++zone_max; section->type = type; section->title = title; section->allocated = allocated; // activate new section Section_now = section; } // Tidy up: If necessary, release section title. // Warning - the state of the component "Allocd" may have // changed in the meantime, so don't rely on a local variable. void Section_finalize(section_t* section) { if(section->allocated) free(section->title); } // Switch to new zone ("!zone" or "!zn"). Has to be re-entrant. static enum eos_t PO_zone(void) { section_t entry_values;// buffer for outer zone char* new_title; bool allocated; // remember everything about current structure entry_values = *Section_now; // set default values in case there is no valid title new_title = untitled; allocated = FALSE; // Check whether a zone title is given. If yes and it can be read, // get copy, remember pointer and remember to free it later on. if(BYTEFLAGS(GotByte) & CONTS_KEYWORD) { // Because we know of one character for sure, // there's no need to check the return value. Input_read_keyword(); new_title = DynaBuf_get_copy(GlobalDynaBuf); allocated = TRUE; } // setup new section // section type is "subzone", just in case a block follows Section_new_zone(Section_now, "Subzone", new_title, allocated); if(Parse_optional_block()) { // Block has been parsed, so it was a SUBzone. Section_finalize(Section_now);// end inner zone *Section_now = entry_values;// restore entry values } else { // no block found, so it's a normal zone change Section_finalize(&entry_values);// end outer zone Section_now->type = type_zone;// change type to "zone" } return(ENSURE_EOS); } // Start subzone ("!subzone" or "!sz"). Has to be re-entrant. static enum eos_t PO_subzone(void) { // output deprecation warning Throw_first_pass_warning("\"!subzone {}\" is deprecated; use \"!zone {}\" instead."); // call "!zone" instead return(PO_zone()); } // predefined stuff static node_t pseudo_opcodes[] = { PREDEFNODE(s_zone, PO_zone), PREDEFNODE("zn", PO_zone), PREDEFNODE(s_subzone, PO_subzone), PREDEFLAST("sz", PO_subzone), // ^^^^ this marks the last element }; // register pseudo opcodes void Section_init(void) { Tree_add_table(&pseudo_opcode_tree, pseudo_opcodes); } // Setup outermost section void Section_passinit(void) { zone_max = ZONE_GLOBAL;// will be incremented by next line Section_new_zone(&outer_section, type_zone, untitled, FALSE); } CheeseCutter-2.10/src/asm/section.h000066400000000000000000000020071516216315000172020ustar00rootroot00000000000000// // ACME - a crossassembler for producing 6502/65c02/65816 code. // Copyright (C) 1998-2006 Marco Baye // Have a look at "acme.c" for further info // // Section stuff #ifndef section_H #define section_H #include "config.h" // "section" structure type definition typedef struct { zone_t zone; // current zone value const char* type; // "Zone", "Subzone" or "Macro" char* title; // zone title, subzone title or macro title int allocated; // whether title was malloc()'d } section_t; // Constants #define ZONE_GLOBAL 0 // Number of "global zone" // Variables // current section structure extern section_t *Section_now; // Prototypes // Write given info into given zone structure and activate it extern void Section_new_zone(section_t*, const char* type, char* title, bool allocated); // register pseudo opcodes extern void Section_init(void); // Setup outermost section extern void Section_passinit(void); // Tidy up: If necessary, release section title. extern void Section_finalize(section_t* section); #endif CheeseCutter-2.10/src/asm/tree.c000066400000000000000000000136711516216315000165010ustar00rootroot00000000000000// // ACME - a crossassembler for producing 6502/65c02/65816 code. // Copyright (C) 1998-2006 Marco Baye // Have a look at "acme.c" for further info // // Tree stuff #include "config.h" #include "dynabuf.h" #include "global.h" #include "tree.h" #include "platform.h" // Functions // Compute hash value by exclusive ORing the node's ID string and write // output to struct. // This function is not allowed to change GlobalDynaBuf! hash_t make_hash(node_t* node) { register char byte; register const char* read; register hash_t tmp = 0; read = node->id_string; while((byte = *read++)) tmp = ((tmp << 7) | (tmp >> (8 * sizeof(hash_t) - 7))) ^ byte; node->hash_value = tmp; return(tmp); } // Link a predefined data set to a tree void add_node_to_tree(node_t** tree, node_t* node_to_add) { hash_t hash; // compute hash value hash = make_hash(node_to_add); while(*tree) { // compare HashValue if(hash > (*tree)->hash_value) tree = &((*tree)->greater_than); else tree = &((*tree)->less_than_or_equal); } *tree = node_to_add;// add new leaf to tree // New nodes are always added as leaves, so there's no need to copy a second // pointer. And because the PREDEF* macros contain NULL as init values, it is // not necessary to clear the new node's greater_than and less_than_or_equal // fields. } // Add predefined tree items to given tree. The PREDEF* macros set HashValue // to 1 in all entries but the last. The last entry contains 0. void Tree_add_table(node_t** tree, node_t* table_to_add) { // Caution when trying to optimise this. :) while(table_to_add->hash_value) add_node_to_tree(tree, table_to_add++); add_node_to_tree(tree, table_to_add); } // Search for a given ID string in a given tree. // Compute the hash of the given string and then use that to try to find a // tree item that matches the given data (HashValue and DynaBuf-String). // Store "Body" component in NodeBody and return TRUE. // Return FALSE if no matching item found. bool Tree_easy_scan(node_t* tree, void** node_body, struct dynabuf_t* dyna_buf) { node_t wanted;// temporary storage const char *p1, *p2; char b1, b2; hash_t hash; wanted.id_string = dyna_buf->buffer; hash = make_hash(&wanted); while(tree) { // compare HashValue if(hash > tree->hash_value) { // wanted hash is bigger than current, so go // to tree branch with bigger hashes tree = tree->greater_than; continue; } if(hash == tree->hash_value) { p1 = wanted.id_string; p2 = tree->id_string; do { b1 = *p1++; b2 = *p2++; } while((b1 == b2) && b1); if(b1 == b2) { // store body data *node_body = tree->body; return(TRUE); } } // either the wanted hash is smaller or // it was exact but didn't match tree = tree->less_than_or_equal; } return(FALSE); // indicate failure } // Search for a "RAM tree" item. Compute the hash of string in GlobalDynaBuf // and then use that to try to find a tree item that matches the given data // (HashValue, ID_Number, GlobalDynaBuf-String). Save pointer to found tree // item in given location. // If no matching item is found, check the "Create" flag. If it is set, create // a new tree item, link to tree, fill with data and store its pointer. If the // "Create" flag is clear, store NULL as result. // Returns whether item was created. bool Tree_hard_scan(node_ra_t** result, node_ra_t** forest, int id_number, bool create) { node_t wanted; // temporary storage node_ra_t **current_node; node_ra_t *new_leaf_node; const char *p1, *p2; char b1, b2; hash_t byte_hash; wanted.id_string = GLOBALDYNABUF_CURRENT; // incorporate ID number into hash value byte_hash = make_hash(&wanted) ^ id_number; wanted.hash_value = byte_hash;// correct struct's hash PLATFORM_UINT2CHAR(byte_hash);// transform into byte current_node = &(forest[byte_hash]);// point into table while(*current_node) { // compare HashValue if(wanted.hash_value > (*current_node)->hash_value) { // wanted hash is bigger than current, so go // to tree branch with bigger hashes current_node = &((*current_node)->greater_than); continue; } if(wanted.hash_value == (*current_node)->hash_value) { if(id_number == (*current_node)->id_number) { p1 = wanted.id_string; p2 = (*current_node)->id_string; do { b1 = *p1++; b2 = *p2++; } while((b1 == b2) && b1); if(b1 == b2) { // store node pointer *result = *current_node; // return FALSE because node // was not created return(FALSE); } } } // either the wanted hash is smaller or // it was exact but didn't match current_node = &((*current_node)->less_than_or_equal); } // node wasn't found. Check whether to create it if(create == FALSE) { *result = NULL;// indicate failure return(FALSE);// return FALSE because node was not created } // create new node new_leaf_node = safe_malloc(sizeof(node_ra_t)); new_leaf_node->greater_than = NULL; new_leaf_node->less_than_or_equal = NULL; new_leaf_node->hash_value = wanted.hash_value; new_leaf_node->id_number = id_number; new_leaf_node->id_string = DynaBuf_get_copy(GlobalDynaBuf);// make permanent copy // add new leaf to tree *current_node = new_leaf_node; // store pointer to new node in result location *result = new_leaf_node; return(TRUE);// return TRUE because node was created } // Call given function for each object of matching type in the given tree. // Calls itself recursively. void dump_tree(node_ra_t* node, int id_number, void (*fn)(node_ra_t*, FILE*), FILE* env) { if(node->id_number == id_number) fn(node, env); if(node->greater_than) dump_tree(node->greater_than, id_number, fn, env); if(node->less_than_or_equal) dump_tree(node->less_than_or_equal, id_number, fn, env); } // Calls Tree_dump_tree for each non-zero entry of the given tree table. void Tree_dump_forest(node_ra_t** forest, int id_number, void (*fn)(node_ra_t*, FILE*), FILE* env) { int i; for(i = 255; i >= 0; i--) { if(*forest) dump_tree(*forest, id_number, fn, env); forest++; } } CheeseCutter-2.10/src/asm/tree.h000066400000000000000000000037531516216315000165060ustar00rootroot00000000000000// // ACME - a crossassembler for producing 6502/65c02/65816 code. // Copyright (C) 1998-2006 Marco Baye // Have a look at "acme.c" for further info // // Tree stuff #ifndef tree_H #define tree_H #include #include "config.h" // Macros for pre-defining tree node tables #define PREDEFNODE(s, v) {NULL, NULL, 1, s, (void*) (v)} #define PREDEFLAST(s, v) {NULL, NULL, 0, s, (void*) (v)} // type definitions typedef unsigned int hash_t; // Must be unsigned, otherwise the hash algorithm won't be very useful! // tree node structure type definition (for easy lookups) struct node_t { node_t* greater_than; // pointer to sub-tree node_t* less_than_or_equal;// pointer to sub-tree hash_t hash_value; const char* id_string; // name, zero-terminated void* body; // bytes, handles or handler function }; // tree node structure type definition (for macros/labels) struct node_ra_t { node_ra_t* greater_than; // pointer to sub-tree node_ra_t* less_than_or_equal;// pointer to sub-tree hash_t hash_value; char* id_string; // name, zero-terminated void* body; // macro/label body unsigned int id_number; // zone number }; // Prototypes // Add predefined tree items to given tree. extern void Tree_add_table(node_t** tree, node_t* table_to_add); // Search for a given ID string in a given tree. Store "Body" component in // NodeBody and return TRUE. Return FALSE if no matching item found. extern bool Tree_easy_scan(node_t* tree, void** node_body, struct dynabuf_t* dyna_buf); // Search for a "RAM tree" item. Save pointer to found tree item in given // location. If no matching item is found, check the "Create" flag: If set, // create new tree item, link to tree, fill with data and store its pointer. // If "Create" is clear, store NULL. Returns whether item was created. extern bool Tree_hard_scan(node_ra_t**, node_ra_t**, int, bool); // Calls given function for each node of each tree of given forest. extern void Tree_dump_forest(node_ra_t**, int, void (*)(node_ra_t*, FILE*), FILE*); #endif CheeseCutter-2.10/src/audio/000077500000000000000000000000001516216315000157075ustar00rootroot00000000000000CheeseCutter-2.10/src/audio/audio.d000066400000000000000000000076721516216315000171710ustar00rootroot00000000000000/* CheeseCutter v2 (C) Abaddon. Licensed under GNU GPL. */ module audio.audio; import derelict.sdl2.sdl; import audio.resid.filter; import audio.player; import audio.callback; import std.stdio; import core.stdc.stdlib; import core.stdc.string; import std.conv; enum MIXBUF_MUL = 2; __gshared SDL_AudioSpec audiospec; __gshared bool audioInited = false; __gshared int framerate = 50; __gshared int multiplier; __gshared int freq = 48000, bufferSize = 2048; __gshared private int callbackCounter = 0; __gshared private int bufferUsed; // in samples __gshared private int callbackInterval; __gshared short* mixbuf = null; extern(C) { extern __gshared char[0x19] sidreg; extern __gshared int residdelay; extern __gshared int sid_init(int, Filterparams*, int, int, int, int, int) nothrow ; extern __gshared int sid_fillbuffer(short *, int, int) nothrow ; extern __gshared int sid_close(); __gshared void function() nothrow callback; int audio_init(int fr, void function() nothrow cb) { SDL_AudioSpec requested; if(audioInited) return 0; audioInited = true; framerate = fr; if(bufferSize < freq / framerate) { // fprintf(stderr,"Minimum buffer size is %d bytes.\n", freq / framerate); return -1; } requested.freq = freq; requested.format = AUDIO_S16LSB; requested.channels = 1; requested.samples = cast(ushort) bufferSize; requested.callback = &audio_callback_2; requested.userdata = null; callback = cb; if(SDL_OpenAudio(&requested, &audiospec) < 0) { writeln("Could not open audio: ", to!string(SDL_GetError())); return -1; } if(audiospec.format != AUDIO_S16LSB) { writeln("Incorrect audio format obtained."); return -1; } bufferSize = audiospec.samples; mixbuf = cast(short *)malloc(bufferSize * short.sizeof * MIXBUF_MUL); memset(mixbuf, 0, bufferSize * short.sizeof * MIXBUF_MUL); setCallMultiplier(1); return 0; } int getbufsize() { return cast(int)(bufferSize * MIXBUF_MUL); } void audio_close() { SDL_CloseAudio(); if(mixbuf) free(mixbuf); sid_close(); } void reset() { bufferUsed = callbackCounter = 0; } void setCallMultiplier(int m) { if(m < 1 || m > 16) return; if(m == multiplier) return; SDL_LockAudio(); multiplier = m; framerate = 50 * m; callbackInterval = audiospec.freq / framerate; reset(); SDL_UnlockAudio(); } void audio_callback(void *data, ubyte* stream, int len) nothrow { int samplesRequested = cast(int) (len / short.sizeof); int total = 0,todo = 0,t = 0; int steps; if(!audio.player.isPlaying()) return; while(total < samplesRequested) { todo = samplesRequested - total; assert(todo >= 0); if(callbackCounter + todo >= callbackInterval) { int c = callbackInterval - callbackCounter; assert(c > 0); t = sid_fillbuffer(cast(short*)stream + total, c, 0); (*callback)(); callbackCounter -= callbackInterval; assert(callbackCounter + todo >= 0); } else { assert(total + todo <= samplesRequested); t = sid_fillbuffer(cast(short*)stream + total, todo, 0); } total += t; callbackCounter += t; steps++; } assert(total == samplesRequested); } __gshared void audio_callback_2(void *data, ubyte* stream, int len) nothrow { int samplesRequested = cast(int) (len / short.sizeof); int i,t; if(!audio.player.isPlaying()) { //memcpy(stream, cast(ubyte*)mixbuf, len); memset(stream, 0, len); return; } while((bufferUsed + callbackInterval) <= bufferSize * MIXBUF_MUL) { t = sid_fillbuffer(mixbuf+bufferUsed, callbackInterval, cyclesPerFrame); bufferUsed += t; (*callback)(); } memcpy(stream, cast(ubyte*)mixbuf, len); bufferUsed -= samplesRequested; if(bufferUsed < 0) { // writeln("Audio buffer underrun ", bufferUsed); bufferUsed = 0; } short* pi, po; for(i = 0, pi = mixbuf, po = mixbuf + samplesRequested; i < bufferSize * MIXBUF_MUL - samplesRequested; i++) { *(pi++) = *(po++); } } } CheeseCutter-2.10/src/audio/callback.d000066400000000000000000000103271516216315000176130ustar00rootroot00000000000000/* CheeseCutter v2 (C) Abaddon. Licensed under GNU GPL. */ module audio.callback; import derelict.sdl2.sdl; import audio.player; import com.session; import com.cpu; import ct.base; static import audio.timer, audio.audio; /+ holds the state of cpu and memory for frame debug dumps. not implemented for now. +/ class SongState { int totalFramecallCounter, subframeCounter; private CPU cpu; private ubyte[65536] data; CPUException exception; /+ this(Song song, int tfc, int sfc) { data = song.data; cpu = new CPU(data); totalFramecallCounter = tfc; subframeCounter = sfc; exception = null; } void dump() { writefln("Frame %d(%d)", totalFrameCallCounter, subframeCounter); cpu.execute(pc, true); }+/ } __gshared private int frameCallCounter, totalFrameCallCounter; // for multispeed __gshared private Exception playbackStatus = null; __gshared private bool dumpFrameRequested = false; __gshared private bool dumpRequested = false; __gshared int cyclesPerFrame; __gshared int linesPerFrame, maxCycles, maxLines, maxCycleFrame; __gshared char[0x19][5*50] dump; __gshared int dumpctr; __gshared auto avgsPerFrame = new int[](20); Exception getException() { Exception ex = playbackStatus; playbackStatus = null; return ex; } void reset() { maxCycles = 0; cyclesPerFrame = 0; frameCallCounter = 0; totalFrameCallCounter = 0; } void requestDump() { dumpRequested = true; } // called each frame from soundbuffer callback extern(C) __gshared void audio_frame() nothrow { static char[0x19][5*50] dumpbak; switch(audio.player.getPlaystatus()) { case Status.Play: audio.timer.tick(); cpuCall(frameCallCounter > 0 ? 0x1006 : 0x1003, false); break; case Status.Keyjam: address call = 0x100c; song.cpu.regs.x = 0; if(song.ver > 7) { call = song.offsets[Offsets.Submplayplay]; } cpuCall(call,false); break; default: return; } frameCallCounter++; totalFrameCallCounter++; if(frameCallCounter >= audio.audio.multiplier) { frameCallCounter = 0; frameDone(); } for(int i=0; i<0x19; i++) { sidreg[i] = song.sidbuf[i]; // if(com.session.debugMode) // dump[dumpctr][i] = song.sidbuf[i]; } // if(com.session.debugMode) { // dumpctr++; // if(dumpctr >= dump.length) { // dumpbak = dump[]; // dumpctr--; // dump[0 .. $-1] = dumpbak[1 .. $]; // } // } } private void frameDone() nothrow { static int[5] avgs; int totalCycles; auto playerFrameCounter = song.data[song.offsets[2]]; static int[][] _avgsPerFrame = new int[][](20,5); if(cyclesPerFrame > maxCycles) { maxCycles = cyclesPerFrame; maxCycleFrame = song.data[song.offsets[2]]; } foreach(idx, ref avg; avgs) { if(idx == avgs.length - 1) { avg = cyclesPerFrame; } else avg = avgs[idx+1]; totalCycles += avg; } int[] _avgPerFrame = _avgsPerFrame[playerFrameCounter]; import std.stdio; _avgPerFrame[0 .. $-1] = _avgPerFrame[1 .. $].dup; _avgPerFrame[$-1] = cyclesPerFrame; int avg; foreach(i; 0 .. 5) { avg += _avgPerFrame[i]; } avg /= 5; avgsPerFrame[playerFrameCounter] = avg / 10; import std.math : ceil; maxLines = cast(int)ceil(maxCycles / 63.0); cyclesPerFrame = 0; linesPerFrame = cast(int)(totalCycles / avgs.length / 63); if(dumpRequested) { dumpFrameRequested = true; dumpRequested = false; } else dumpFrameRequested = false; audio.timer.tickFullFrame(); } void cpuCall(ushort pc, bool lockAudio) nothrow{ cpuCall(pc, lockAudio, false); } void cpuCall(ushort pc, bool lockAudio, bool forcedump) nothrow { if(lockAudio) SDL_LockAudio(); try { if(dumpFrameRequested) { // state = new SongState(song, totalFrameCallCounter, frameCallCounter); } int i = song.cpu.execute(pc, false); if(muted[0]) song.sidbuf[0..7] = 0; if(muted[1]) song.sidbuf[7..14] = 0; if(muted[2]) song.sidbuf[14..21] = 0; cyclesPerFrame += i; } catch(Exception e) { playbackStatus = e; stop(); // < TODO: player.d should check if playback is in error state and stop by itself //UI.statusline.display(e.toString()); //stop(); } finally { if(lockAudio) SDL_UnlockAudio(); } } extern(C) { __gshared extern char[0x19] sidreg; } CheeseCutter-2.10/src/audio/player.d000066400000000000000000000144171516216315000173570ustar00rootroot00000000000000/* CheeseCutter v2 (C) Abaddon. Licensed under GNU GPL. */ module audio.player; import com.cpu; import com.session; private import ct.base; import audio.timer; import audio.callback; import audio.audio; import audio.resid.filter; import seq.sequencer; import ui.ui; import derelict.sdl2.sdl; import std.stdio; enum Status { Stop, Play, Keyjam }; shared private int playstatus; shared int[3] muted; int usefp = 1, sidtype, interpolate = 1, badline, ntsc; __gshared Filterparams curfp; int curfp6581 = 0, curfp8580 = 0; int getPlaystatus() nothrow { return playstatus; } bool isPlaying() nothrow { return playstatus == Status.Play || playstatus == Status.Keyjam; } bool keyjamEnabled() nothrow { return playstatus == Status.Keyjam; } void init() { if(audio_init(ntsc ? 60 : 50, &audio_frame) < 0) { throw new Error("Could not init audio."); } SDL_LockAudio(); curfp = sidtype ? FP8580[curfp8580] : FP6581[curfp6581]; sid_init(usefp, &curfp, freq, sidtype, ntsc, interpolate, 0); /+ if(!audioinited) { writefln("audio init: engine=%s, freq=%d, buf=%d, sid=%d, clock=%s, interpolation=%s%s", usefp ? "resid-fp" : "resid", audio.audio.audiospec.freq, audio.audio.bufferSize, sidtype ? 8580 : 6581, ntsc ? "ntsc" : "pal", interpolate ? "on" : "off" , badline ? ", badlines=on" : ""); } if(badline) { audio.audio.residdelay = 48; // 4 } else audio.audio.residdelay = 0; +/ SDL_UnlockAudio(); } void setSidModel(int v) { assert(v == 0 || v == 1); if(sidtype == v) return; sidtype = v; init(); } void toggleSIDModel() { setSidModel(sidtype ^ 1); } void playNote(Element emt) { if(playstatus == Status.Play) return; int v = seq.sequencer.activeVoiceNum; // no audio reset if already inited if(playstatus != Status.Keyjam) { audio.callback.reset(); audio.audio.reset(); } playstatus = Status.Stop; song.setVoicon([v == 0 ? 0 : 1, v == 1 ? 0 : 1, v == 2 ? 0 : 1]); muteSID(1,1,1); song.cpu.reset(); song.cpu.regs.a = emt.note.value; song.cpu.regs.x = cast(ubyte)v; song.cpu.regs.y = emt.instr.value; if(song.ver > 8) song.memspace[song.offsets[Offsets.SHTRANS] + v] = 0; ushort call = 0x1009; if(song.ver > 7) { call = song.offsets[Offsets.Subnoteplay]; } cpuCall(call,true); playstatus = Status.Keyjam; } void playRow(Voice[] voices) { if(playstatus == Status.Play) return; int[] trk, seq; foreach(v; voices) { auto r = v.activeRow; trk ~= r.trkOffset; seq ~= r.seqOffset; } SDL_PauseAudio(1); if(SDL_GetAudioStatus() == SDL_AUDIO_PLAYING) std.stdio.writefln("Audio thread not finished!"); SDL_Delay(20); stop(); initPlayOffset(trk, seq); song.cpu.reset(); cpuCall(0x1003,true); cpuCall(0x1003,true); cpuCall(0x1003,true); playstatus = Status.Keyjam; SDL_PauseAudio(0); } void start(int[] trk, int[] seq) { SDL_PauseAudio(1); if(SDL_GetAudioStatus() == SDL_AUDIO_PLAYING) std.stdio.writefln("Audio thread not finished!"); SDL_Delay(20); stop(); initPlayOffset(trk,seq); audio.timer.start(); audio.callback.reset(); audio.audio.reset(); playstatus = Status.Play; SDL_PauseAudio(0); } void start() { start([0, 0, 0], [0, 0, 0]); } void stop() nothrow { playstatus = Status.Stop; muteSID(1,1,1); } void toggleVoice(int v) { if(v > 2 || v < 0) return; muted[v] = muted[v] ^ 1; setVoicon(muted); } void setVoicon(int v1, int v2, int v3) { setVoicon([v1, v2, v3]); } void setVoicon(int[] m) { muted[0] = m[0]; muted[1] = m[1]; muted[2] = m[2]; muteSID(m[0], m[1], m[2]); song.setVoicon(muted); } void setVoicon(shared int[] m) { muted[0] = m[0]; muted[1] = m[1]; muted[2] = m[2]; muteSID(m[0], m[1], m[2]); song.setVoicon(muted); } void initFP() { init(); song.fppres = sidtype ? curfp8580 : curfp6581; } void nextFP() { if (usefp) { if (sidtype) { ++curfp8580; curfp8580 %= FP8580.length; } else { ++curfp6581; curfp6581 %= FP6581.length; } initFP(); } } void setFP(int fp) { if (usefp) { if (sidtype) { curfp8580 = cast(int)(fp % FP8580.length); } else { curfp6581 = cast(int)(fp % FP6581.length); } initFP(); } } void prevFP() { if (usefp) { if (sidtype) { --curfp8580; if (curfp8580 < 0) curfp8580 = cast(int)(FP8580.length-1); } else { --curfp6581; if (curfp6581 < 0) curfp6581 = cast(int)(FP6581.length-1); } initFP(); } } void fastForward(int val) { int step = val * 16; SDL_LockAudio(); for(int i = 0 ; i < step; i++) { audio_frame(); } SDL_UnlockAudio(); } void dumpFrame() { if(playstatus == Status.Play || playstatus == Status.Keyjam) audio.callback.requestDump(); } void setMultiplier(int m) { if(m < 1 || m > 16) return; song.multiplier = m; audio.audio.setCallMultiplier(m); } void decMultiplier() { setMultiplier(song.multiplier - 1); } void incMultiplier() { setMultiplier(song.multiplier + 1); } private void initPlayOffset(int[] t, int[] s) { void out16b(int offs, int value) { song.buffer[offs] = value & 255; song.buffer[offs + 1] = (value >> 8) & 255; } address off1 = cast(ushort)(song.offsets[Offsets.Track1] + t[0] * 2); address off2 = cast(ushort)(song.offsets[Offsets.Track2] + t[1] * 2); address off3 = cast(ushort)(song.offsets[Offsets.Track3] + t[2] * 2); int tpoin2 = song.offsets[Offsets.Songsets]; int tpoin = song.offsets[Offsets.TRACKLO]; song.cpu.reset(); if(song.ver >= 6) { song.buffer[tpoin] = off1 & 255; song.buffer[tpoin+1] = off2 & 255; song.buffer[tpoin+2] = off3 & 255; song.buffer[tpoin+3] = off1 >> 8; song.buffer[tpoin+4] = off2 >> 8; song.buffer[tpoin+5] = off3 >> 8; out16b(tpoin2, song.offsets[Offsets.Track1]); out16b(tpoin2+2, song.offsets[Offsets.Track2]); out16b(tpoin2+4, song.offsets[Offsets.Track3]); } else { out16b(tpoin2, off1); out16b(tpoin2+2, off2); out16b(tpoin2+4, off3); } cpuCall(0x1000,false); int seqcnt = song.offsets[Offsets.NEWSEQ]; song.buffer[seqcnt] = cast(ubyte)(s[0] * 4 + 1); song.buffer[seqcnt+1] = cast(ubyte)(s[1] * 4 + 1); song.buffer[seqcnt+2] = cast(ubyte)(s[2] * 4 + 1); song.setVoicon(muted); SDL_PauseAudio(0); } private void muteSID(int v1, int v2, int v3 ) nothrow { if(v1) song.sidbuf[4] = 0x08; if(v2) song.sidbuf[7 + 4] = 0x08; if(v3) song.sidbuf[14 + 4]= 0x08; } CheeseCutter-2.10/src/audio/resid/000077500000000000000000000000001516216315000170155ustar00rootroot00000000000000CheeseCutter-2.10/src/audio/resid/filter.d000066400000000000000000000054431516216315000204550ustar00rootroot00000000000000module audio.resid.filter; struct Filterparams { float dr; float dp; float cft; float t3b; float t3o; float t3s; float t3m; float t4k; float t4b; float v; string id; } static const Filterparams[] FP6581 = [ {0.5f, 3.3e6f, 3.0e-4f, 1646009.8408527481f, 30099093.879106432f, 1.0054673476018452f, 14227.912103009101f, 5.5f, 20.0f, 0.9613160610660189f, "6581R3 2083"}, {0.5f, 3.3e6f, 3.0e-4f, 1.9e6f, 8.5e7f, 1.0058f, 2e4f, 5.5f, 20.0f, 0.9613160610660189f, "6581R3 0384"}, {0.5f, 3.3e6f, 3.0e-4f, 1.3e6f, 3.7e8f, 1.0066f, 1.8e4f, 5.5f, 20.0f, 0.9613160610660189f, "6581R3 0784"}, {0.5f, 3.3e6f, 3.0e-4f, 1.83e6f, 2.6e9f, 1.0064f, 2.5e4f, 5.5f, 20.0f, 0.9613160610660189f, "6581R3 1984"}, {0.5f, 3.3e6f, 3.0e-4f, 1.16e6f, 9.9e6f, 1.0058f, 1.48e4f, 5.5f, 20.0f, 0.9613160610660189f, "6581R3 3384"}, {0.5f, 3.3e6f, 3.0e-4f, 1.65e6f, 1.2e10f, 1.006f, 1e4f, 5.5f, 20.0f, 0.9613160610660189f, "6581R3 3684"}, {0.5f, 3.3e6f, 3.0e-4f, 1522171.922983084f, 21729926.667291082f, 1.004994802537475f, 14299.149638099827f, 5.5f, 20.0f, 0.9613160610660189f, "6581R3 3984"}, {0.5f, 3.3e6f, 3.0e-4f, 1.5e6f, 1.8e8f, 1.0065f, 1.8e4f, 5.5f, 20.0f, 0.9613160610660189f, "6581R3 3985"}, {0.5f, 3.3e6f, 3.0e-4f, 1.55e6f, 2.5e8f, 1.006f, 1.9e4f, 5.5f, 20.0f, 0.9613160610660189f, "6581R3 4285"}, {0.5f, 3.3e6f, 3.0e-4f, 1399768.3253307983f, 553018906.8926692f, 1.0051493199361266f, 11961.908870403166f, 5.5f, 20.0f, 0.9613160610660189f, "6581R3 4485"}, {0.5f, 3.3e6f, 3.0e-4f, 840577.4520801408f, 1909158.8633669745f, 1.0068865662510837f, 14858.140079688419f, 5.5f, 20.0f, 0.9613160610660189f, "6581R3 4885"}, {0.5f, 3.3e6f, 3.0e-4f, 1164920.4999651583f, 12915042.165290257f, 1.0058853753357735f, 12914.5661141159f, 5.5f, 20.0f, 0.9613160610660189f, "6581R3 0486S"}, {0.5f, 3.3e6f, 3.0e-4f, 1250736.2235895505f, 1521187976.8735676f, 1.005543646897986f, 8581.78418415723f, 5.5f, 20.0f, 0.9613160610660189f, "6581R4 1986S"}, {0.5f, 3.3e6f, 3.0e-4f, 1.3e6f, 1.9e8f, 1.0066f, 1.8e4f, 5.5f, 20.0f, 0.9613160610660189f, "6581R4AR 2286"}, {0.5f, 3.3e6f, 3.0e-4f, 1.1e6f, 8e6f, 1.0052f, 1.7e4f, 5.5f, 20.0f, 0.9613160610660189f, "6581R4AR 4486"}, {0.5f, 3.3e6f, 3.0e-4f, 1.45e6f, 1.75e8f, 1.0055f, 1e4f, 5.5f, 20.0f, 0.9613160610660189f, "6581R4AR 3488"}, {0.5f, 3.3e6f, 3.0e-4f, 1141069.9277645703f, 276016753.85303545f, 1.0066634233403395f, 16402.86712485317f, 5.5f, 20.0f, 0.9613160610660189f, "6581R4AR 3789"} ]; static const Filterparams[] FP8580 = [ {0.5f, 0f, 0f, 840577.4520801408f, 1909158.8633669745f, 1.0068865662510837f, 14858.140079688419f, 5.7f, 20.0f, 0.9613160610660189f, "8580R5 1489"}, {0.5f, 0f, 0f, 840577.4520801408f, 1909158.8633669745f, 1.0068865662510837f, 14858.140079688419f, 6.55f, 20.0f, 0.9613160610660189f, "8580R5 3691"} ]; CheeseCutter-2.10/src/audio/resid/residctrl.cpp000066400000000000000000000107011516216315000215130ustar00rootroot00000000000000/* reSID interface * * much of the code here is from GOATTRACKER, (c) Cadaver */ #define PALCLOCKRATE 985248 #define NTSCCLOCKRATE 1022727 #define NUMSIDREGS 0x19 #define SIDWRITEDELAY 9 // lda $xxxx,x 4 cycles, sta $d400,x 5 cycles #define SIDWAVEDELAY 4 // and $xxxx,x 4 cycles extra #include #include #include //#include #include extern "C" { typedef struct { float distortionrate; float distortionpoint; float distortioncfthreshold; float type3baseresistance; float type3offset; float type3steepness; float type3minimumfetresistance; float type4k; float type4b; float voicenonlinearity; } FILTERPARAMS; int clockrate; int samplerate; unsigned char sidreg[NUMSIDREGS]; const unsigned char sidorder[] = { 0x0e,0x0f,0x14,0x13,0x10,0x11,0x12, 0x07,0x08,0x0d,0x0c,0x09,0x0a,0x0b, 0x00,0x01,0x06,0x05,0x02,0x03,0x04, 0x16,0x17,0x18,0x15 }; SID *sid= 0; SIDFP *sidfp = 0; int residdelay = 0; int usefp = 0; void sid_close() { if(sid) delete sid; if(sidfp) delete sidfp; } void sid_init(int fp, FILTERPARAMS *fparams, int speed, unsigned m, unsigned ntsc, unsigned interpolate, unsigned customclockrate) { int c; usefp = fp; if (ntsc) clockrate = NTSCCLOCKRATE; else clockrate = PALCLOCKRATE; if (customclockrate) clockrate = customclockrate; samplerate = speed; if (!sidfp) sidfp = new SIDFP(); if (!sid) sid = new SID(); if(usefp) { switch(interpolate) { case 0: sidfp->set_sampling_parameters(clockrate, SAMPLE_INTERPOLATE, speed); break; default: sidfp->set_sampling_parameters(clockrate, SAMPLE_RESAMPLE_INTERPOLATE, speed); break; } sidfp->reset(); for (c = 0; c < NUMSIDREGS; c++) { sidreg[c] = 0x00; } if (m == 1) sidfp->set_chip_model(MOS8580); else sidfp->set_chip_model(MOS6581); sidfp->get_filter().set_distortion_properties( fparams->distortionrate, fparams->distortionpoint, fparams->distortioncfthreshold); sidfp->get_filter().set_type3_properties( fparams->type3baseresistance, fparams->type3offset, fparams->type3steepness, fparams->type3minimumfetresistance); sidfp->get_filter().set_type4_properties( fparams->type4k, fparams->type4b); sidfp->set_voice_nonlinearity( fparams->voicenonlinearity); sidfp->enable_filter(true); } else { switch(interpolate) { case 0: sid->set_sampling_parameters(clockrate, SAMPLE_FAST, speed, 20000); break; default: sid->set_sampling_parameters(clockrate, SAMPLE_INTERPOLATE, speed, 20000); break; } sid->reset(); for (c = 0; c < NUMSIDREGS; c++) { sidreg[c] = 0x00; } if (m == 1) { sid->set_chip_model(MOS8580); } else { sid->set_chip_model(MOS6581); } } } unsigned char sid_getorder(unsigned char index) { return sidorder[index]; } int sid_fillbuffer(short *ptr, int samples, const int cyc) { int os = samples; int rc = cyc / 3; // NUMVOICE int badline = rand() % NUMSIDREGS; int tdelta; int tdelta2; int result; int total = 0; int c; tdelta = clockrate * samples / samplerate; for (c = 0; c < NUMSIDREGS; c++) { unsigned char o = sid_getorder(c); // Extra delay per music routine iteration if (cyc > 0 && ((c == 0) || (c == 7) || (c == 14))) { tdelta2 = rc; if(usefp) result = sidfp->clock(tdelta2, ptr, samples); else result = sid->clock(tdelta2, ptr, samples); total += result; ptr += result; samples -= result; tdelta -= rc; } // Possible random badline delay once per writing /* if ((badline == c) && (residdelay)) { tdelta2 = residdelay; result = sid->clock(tdelta2, ptr, samples); total += result; ptr += result; samples -= result; tdelta -= residdelay; } */ if(usefp) sidfp->write(o, sidreg[o]); else sid->write(o, sidreg[o]); tdelta2 = SIDWRITEDELAY; if(usefp) result = sidfp->clock(tdelta2, ptr, samples); else result = sid->clock(tdelta2, ptr, samples); total += result; ptr += result; samples -= result; tdelta -= SIDWRITEDELAY; } if(usefp) result = sidfp->clock(tdelta, ptr, samples); else result = sid->clock(tdelta, ptr, samples); total += result; // assert(total <= os); return total; } } CheeseCutter-2.10/src/audio/timer.d000066400000000000000000000021211516216315000171700ustar00rootroot00000000000000/* CheeseCutter v2 (C) Abaddon. Licensed under GNU GPL. */ module audio.timer; import audio.audio; import com.session; import ct.base; __gshared int sec, min; __gshared private int clockCounter; __gshared private int fplayTickCounter, fplayRowCounter; // how many rows done since last fplay update? __gshared private int tickCounter; int readRowTick() { int t = fplayRowCounter; fplayRowCounter = 0; return t; } int readTick() { int t = tickCounter; tickCounter = 0; return t; } void stop() { } /+ from player.start +/ void start() { sec = min = clockCounter = 0; fplayTickCounter = fplayRowCounter = 0; } /+ should be called each on update from callback +/ void tick() nothrow { if(++clockCounter >= audio.audio.framerate) { clockCounter = 0; static import audio.callback; audio.callback.maxCycles = 0; if(++sec > 59) { sec = 0; min++; min %= 100; } } } /+ should be called once per frame cycle, updated fplay counters +/ void tickFullFrame() nothrow { tickCounter++; if(++fplayTickCounter > song.playSpeed) { fplayRowCounter++; fplayTickCounter = 0; } } CheeseCutter-2.10/src/c64/000077500000000000000000000000001516216315000152025ustar00rootroot00000000000000CheeseCutter-2.10/src/c64/player_v4.acme000066400000000000000000000733141516216315000177460ustar00rootroot00000000000000;;; ---------------------------------------- ;;; CCUTTER 2.x musicplayer by abad ;;; Based on JCH NP 21.G4 by Laxity/VIB ;;; ---------------------------------------- !ifdef ZREG { } else { ZREG = $fb } FALSE = 0 TRUE = 1 EXPORT = FALSE ; if TRUE, editor specific code will be left out MULTISPEED = TRUE ; support for multispeed playback INSNO = 48 ; number of instruments used CIA_VALUE = $4cc7 ; for multispeed MULTIPLIER = 1 ; for multispeed BASEADDRESS = $1000 ;;; ---------------------------------------- ;;; instr table enums ;;; ---------------------------------------- INS_AD = 0 ; INS_SR = 1 * INSNO INS_HR = 2 * INSNO ; $x0 = HR type, $0x arp delay count INS_4 = 3 * INSNO ; HR waveform INS_FLTP = 4 * INSNO ; INS_PULSP = 5 * INSNO ; INS_7 = 6 * INSNO ; INS_ARP = 7 * INSNO ;;; ---------------------------------------- ;;; assembly conditionals ;;; ---------------------------------------- INCLUDE_CMD_SLUP = TRUE INCLUDE_CMD_SLDOWN = TRUE INCLUDE_CMD_VIBR = TRUE INCLUDE_CMD_PORTA = TRUE INCLUDE_CMD_SET_ADSR = TRUE INCLUDE_CMD_SET_OFFSET = TRUE INCLUDE_CMD_SET_LOVIB = TRUE INCLUDE_CMD_SET_WAVE = FALSE INCLUDE_SEQ_SET_PULSE = TRUE INCLUDE_SEQ_SET_CHORD = TRUE INCLUDE_SEQ_SET_ATT = TRUE INCLUDE_SEQ_SET_DEC = TRUE INCLUDE_SEQ_SET_SUS = TRUE INCLUDE_SEQ_SET_REL = TRUE INCLUDE_SEQ_SET_SPEED = TRUE INCLUDE_SEQ_SET_VOL = TRUE INCLUDE_DIRECT_PULSE = TRUE INCLUDE_VIBRAFEEL = TRUE INCLUDE_BREAKSPEED = TRUE INCLUDE_CHORD = TRUE INCLUDE_FILTER = TRUE INCLUDE_SYNC = TRUE USE_MDRIVER = FALSE ;;; ---------------------------------------- ;;; new effect commands ;;; ---------------------------------------- CMD_SLIDE_UP = $00 CMD_SLIDE_DOWN = $01 CMD_VIBRATO = $02 CMD_SET_OFFSET = $03 CMD_SET_ADSR = $04 CMD_SET_LOVIB = $05 CMD_SET_WAVE = $06 CMD_PORTAMENTO = $07 CMD_STOP = $08 ;stop portamento/slide ;;; ---------------------------------------- SUPERHIGH = CMD_SET_OFFSET ;;; ---------------------------------------- ;;; the following data describes the player features ;;; for the editor ;;; ---------------------------------------- !if EXPORT = FALSE { *=$e00 features = * requestedTables !8 %00001111 ;;; 1 = points to wave table ;;; 2 = points to cmd table (NOT IMPLEMENTED) ;;; 3 = points to pulse table ;;; 4 = points to filter table ;;; ... instrumentFlags !8 0,0,0,0,4,3,0,1 ;;; 1 = points to wave table ;;; 3 = points to pulse table ;;; 4 = points to filter table cmdFlags !8 0,0,0,0,0,0,0,0 !8 0,0,0,0,0,0,0,0 instrumentDescriptionsHeader !16 idescr0,idescr1,idescr2,idescr3,idescr4,idescr5,idescr6,idescr7 pulseDescriptionsHeader !16 pdescr0,pdescr1,pdescr2,pdescr3 filterDescriptionsHeader !16 fdescr0,fdescr1,fdescr2,fdescr3 waveDescriptionsHeader !16 wdescr0,wdescr1 cmdDescriptionsHeader !16 mdescr0,mdescr1 } ;;; ---------------------------------------- ;;; some pointers for the editor ;;; ---------------------------------------- !if EXPORT = FALSE { *= $0fa0 ofa0 !16 features ofa2 !16 volume ofa4 !16 editorflag ofa6 !16 songsets ofa8 !16 playspeed ofaa !16 subnoteplay ofac !16 submplayplay ofae !16 instrumentDescriptionsHeader ofb0 !16 pulseDescriptionsHeader ofb2 !16 filterDescriptionsHeader ofb4 !16 waveDescriptionsHeader ofb6 !16 cmdDescriptionsHeader ofb8 !16 dummy ofba !16 dummy ofbc !16 arp1 ofbe !16 arp2 ofc0 !16 filttab ofc2 !16 pulstab ofc4 !16 inst ofc6 !16 track1 ofc8 !16 track2 ofca !16 track3 ofcc !16 seqlo ofce !16 seqhi ofd0 !16 cmd1 ofd2 !16 s0 ofd4 !16 speed ofd6 !16 tracklo ofd8 !16 voice ;voice 1c X, for voice on/of flagging ofda !16 gate ofdc !16 chord ofde !16 trans ofe0 !16 chordindex ofe2 !16 shtrans ofe6 !16 dummy ofe8 !16 dummy ofea !16 dummy ofec !16 dummy ofee !16 newseq version !pet "cc4.07" } ;;; ---------------------------------------- ;;; editor specific player routines, will be ;;; left out from a finalized tune ;;; ---------------------------------------- !if EXPORT = FALSE { *=$f000 idescr0 !raw "Attack / Decay.",0 idescr1 !raw "Sustain / Release.",0 idescr2 !raw "Restart type / arpeggio speed.&$00 = 3 Frame Restart.&$40 = Soft restart.&$80 = Hard Restart. &$00-$0F = Arpeggio delay value.",0 idescr3 !raw "Hard Restart waveform.",0 idescr4 !raw "Filter Table pointer.",0 idescr5 !raw "Pulse Table pointer $00-$3f.",0 idescr6 !raw "Hard restart SR envelope value.",0 idescr7 !raw "Wave Table pointer.",0 pdescr0 !raw "Duration and direction.&$00-$7F = Add n frames.&$80-$FF = Subtract n frames.",0 pdescr1 !raw "Add value.",0 pdescr2 !raw "Initial pulse value.&Note: Nibbles are reversed! $48 = $8400",0 pdescr3 !raw "Pointer to next set ($00-$3F) or $7F = stop pulse program.",0 fdescr0 !raw "Duration or filter type.&$00-$7f = Duration or $90-$F0 select filter type.",0 fdescr1 !raw "Add value or filter resonance and channel mask.",0 fdescr2 !raw "Initial filter value or $FF = skip.",0 fdescr3 !raw "Pointer to next set ($00-$3F) or $7F = stop filter program.",0 ;;; wave table help wdescr0 !raw "Transpose value / Loop.&$00-$5F = Relative transpose up,&" !raw "$80-$DF = Absolute tuning (unaffected by note/transpose value).&" !raw "$7E = loop to previous row, $7F = loop to row",0 wdescr1 !raw "Waveform / Wave delay / Loop pointer&" !raw "$00 = Do nothing.&" !raw "$01 - $0F = Override instrument's Wave Delay value for this row.&" !raw "$10 - $DF = Waveform; SID Control Register value.&" !raw "$E0 - $EF = SID Control Register value $00 - $0F.&" !raw "$00 - $FF = Loop pointer, if Byte 1 = $7F.",0 ;;; Command table help mdescr0 !raw "Command number.&" !raw "$0 = Slide up.&" !raw "$1 = Slide down.&" !raw "$2 = Hi-fi Vibrato.&" !raw "$3 = Detune current note.&" !raw "$4 = Set ADSR for the current note.&" !raw "$5 = Lo-fi vibrato.&" !raw "$6 = Set wave.&" !raw "$7 = Portamento a tie note.&" !raw "$8 = Stop portamento",0 mdescr1 !raw "Parameter values.&" !raw "Slide up/down: Slide speed (signed 16-bit).&" !raw "Vibrato: 1st byte, lonibble: vibrato 'feel'&" !raw " 2nd byte, hinibble: Speed.&" !raw " lonibble: Depth divider (bigger value = narrower vibrato).&" !raw "Detune: (signed 16-bit).&" !raw "ADSR: (self-explanatory).&" !raw "Lo-fi vibrato: Speed / Depth." !raw "&Set waveform (in the last parameter byte).&" ;;; !raw "Portamento: (Portamento must be applied to tie notes only and reset with e.g. No command 8-00 00).",0 !raw "Portamento: Portamento speed. Runs until a command 8-00 00 is given).",0 *=$f800 submplayplay lda #$80 sta state ldx #2 jmp updsound ;;; ---------------------------------------- ;;; used for triggering a note from th editor ;;; ---------------------------------------- subnoteplay sta shnote,x cmp #3 lda #0 rol eor #1 sta tienote,x tya sta shinst,x lda #3 sta tsync,x lda #0 sta synccnt,x lda #1 sta newinsflag,x lda #0 sta effstate,x sta chordvalue,x lda #$80 sta state sta chordtpos,x jmp updsound } *= BASEADDRESS init !if USE_MDRIVER = TRUE { jmp cinit } else { jmp subinit } play !if USE_MDRIVER = TRUE { jmp cplay } else { jmp subplay } !if MULTISPEED = TRUE { mplay jmp submplay } sync !8 0 ;--------------------------------------- subinit asl asl asl tay ldx #0 !if INCLUDE_BREAKSPEED = TRUE { stx speedsub } !if INCLUDE_SYNC = TRUE { stx sync } subinit0 lda songsets,y sta twraplo,x iny lda songsets,y sta twraphi,x iny inx cpx #3 bne subinit0 lda songsets,y ;set song speed sta speed !if EXPORT = FALSE { cmp #2 bcs subinit00 lda chord subinit00 sta playspeed lda editorflag beq subinit3 } ldx #2 subinit1 lda songsets+1,y and bits,x sta voicon,x lda twraplo,x ; trackpointers not set from the editor sta tracklo,x lda twraphi,x sta trackhi,x lda #1 ; newseq not set from the editor sta newseq,x dex bpl subinit1 subinit3 lda #1 sta state rts ;;; ---------------------------------------- ;;; do only sound work, used for multispeed ;;; playback frames ;;; ---------------------------------------- !if MULTISPEED = TRUE { submplay lda #$40 sta state ldx #2 jmp syncskip } ;;; ---------------------------------------- ;;; regular play call ;;; ---------------------------------------- subplay lda state beq run lda #2 sta speedcnt ldx #(clrlast-clrfirst) lda #0 subinit4 dex sta clrfirst,x bne subinit4 ;; reset synchonization ldx #2 subinit5 lda #2 sta synccnt,x ; HR allowed lda #$fe sta tsync,x ; sync done dex bpl subinit5 lda #$0f sta volume !if INCLUDE_FILTER = TRUE { lda #0 sta filter sta bandpass } lda #$f0 sta $d417 lda #0 sta state rts run dec speedcnt bpl speeddone lda speed !if INCLUDE_BREAKSPEED = TRUE { cmp #2 bpl speedok speedalt ldy speedsub lda chord,y bpl nowrap ldy #0 sty speedsub lda chord,y nowrap inc speedsub sta playspeed cmp #2 bpl speedok lda #2 } speedok sta speedcnt speeddone ;--------------------------------------- ldx #2 main0 lda voicon,x bne trackon jmp next trackon inc synccnt,x lda speedcnt beq jupdseq cmp #1 beq updtrack jmp updsound jupdseq jmp updseq ;--------------------------------------- updtrack lda newseq,x beq skiptrack sec sbc #1 sta seqcnt,x lda #0 sta newseq,x tay lda tracklo,x sta ZREG lda trackhi,x sta ZREG+1 lda (ZREG),y bpl trk02 cmp #$80 ; get transpose value beq skiptrans sbc #$a0 sta shtrans2,x skiptrans inc tracklo,x bne trk01 inc trackhi,x trk01 iny lda (ZREG),y trk02 sta curseq,x iny lda (ZREG),y cmp #$f0 bcc trk03 pha iny lda (ZREG),y clc adc twraplo,x sta tracklo,x pla and #$07 adc twraphi,x ; song wrap sta trackhi,x jmp updsound trk03 inc tracklo,x bne skiptrack inc trackhi,x skiptrack jmp updsound ;--------------------------------------- updseq dec durcnt,x bmi nextnote jmp updsound nextnote ldy curseq,x lda seqlo,y sta ZREG lda seqhi,y sta ZREG+1 lda #2 sta tsync,x getseq ldy seqcnt,x seqnext lda (ZREG),y cmp #$c0 bcs command cmp #$60-1 ; command coming up? bcc nocmdbyt sbc #$60 bpl nottie inc tienote,x ; $5f = flag tienote iny jmp seqnext nottie pha ; store note value iny lda (ZREG),y ; fetch sequence command beq skipcmd sta shsuper,x inc newcmdflag,x skipcmd pla nocmdbyt sta shnote,x ; check for rest & gate flags cmp #3 bcs sequpdtrans settie inc tienote,x jmp seqdone command cmp #$f0 bmi notdur setdur and #$0f sta duration,x iny jmp seqnext notdur sbc #$c0-1 sta shinst,x inc newinsflag,x iny jmp seqnext sequpdtrans lda shtrans2,x sta shtrans,x seqdone iny beq seqsetflag ; new seq automatically if seqcnt wrapped tya sta seqcnt,x lda (ZREG),y cmp #$bf ;seq end mark bne noteos seqsetflag inc newseq,x noteos lda duration,x sta durcnt,x !if INCLUDE_CMD_PORTA = TRUE { lda newcmdflag,x beq snotporta ; ! ;; Check for super commands that ;; ;should be parsed immidiately ldy shsuper,x ;cmd byte? cpy #$40 bpl updsound lda cmd1,y cmp #CMD_PORTAMENTO bne snotporta lda cmd2,y and #$0f sta portahi,x lda cmd3,y sta portalo,x lda #$81 sta effstate,x ;; formerly clrsuper lda #0 sta newcmdflag,x jmp updsound snotporta } ;;; ---------------------------------------- ;;; sound work ;;; ---------------------------------------- updsound lda #0 sta hardon,x lda tsync,x bpl dosync jmp syncskip dosync dec tsync,x lda tienote,x beq syncnottied jmp syncskip syncnottied lda tsync,x cmp #1 bne syncgate lda synccnt,x ; hard restart possible? cmp #2 bmi syncnohr ldy shinst,x ; use hard restart? lda inst+INS_HR,y bpl syncnohr and #$20 bne laxhr ;; Hard restart lda cmd2 ;Set adsr for HR sta ad,x laxhr lda inst+INS_7,y sta sr,x syncnohr lda #$fe sta gate,x jmp dowave ;only update wavetable syncgate cmp #$ff beq syncgateon jmp syncskip syncgateon lda newinsflag,x beq checknote ldy shinst,x lda inst,y ;Store ADSR of insturmen in shadow sta shad,x ;ADSR regs lda inst+INS_SR,y sta shsr,x lda effstate,x ;don't reset porta bmi checknote lda #0 sta effstate,x checknote lda shtrans,x ;set transpose to current sta trans,x lda shnote,x clc ;get real (transposed) value of the note adc trans,x sta notereal,x ldy effstate,x ;skip if portamento bmi skipsetfrq !if INCLUDE_CMD_PORTA = TRUE { tay lda freqtable_lo,y sta plo,x lda freqtable_hi,y sta phi,x } txa sta shfreqlo,x lda #0 sta shfreqhi,x skipsetfrq ldy shinst,x lda inst+INS_ARP,y ;set wave pos sta wavepos,x lda shad,x ;set ADSR sta ad,x lda shsr,x sta sr,x lda inst+INS_PULSP,y ;set the pulse beq setflt !if INCLUDE_DIRECT_PULSE = TRUE { bpl skippdirect and #$0f sta pulsehi,x lda #0 sta pulselo,x jmp pulsdirset } skippdirect asl asl pulsdirset sta pulsenxt,x ;pointer lda #0 sta pulsecnt,x setflt !if INCLUDE_FILTER = TRUE { lda inst+INS_FLTP,y beq filterdone ;no filter reset skipcutdirect asl asl sta filtnxt lda #0 sta filtcnt filterdone } scmddone lda #0 sta newinsflag,x !if INCLUDE_CHORD = TRUE { sta chordvalue,x lda #$80 sta chordtpos,x } lda inst+INS_HR,y ;set wave timer and #$0f sta wavetime,x lda #0 sta wavecnt,x lda inst+INS_HR,y and #$c0 ;Check for soft cmp #$40 ;restart beq wavenotoff lda inst+INS_4,y ora #1 sta waveform,x inc hardon,x wavenotoff lda #$ff ;Gate on sta gate,x lda #$00 ;Reset sync sta synccnt,x ldy effstate,x bmi noeffreset sta effstate,x noeffreset jmp checksuper syncskip ;;; ---------------------------------------- ;;; pulsework ;;; ---------------------------------------- updatepulse ldy pulsecur,x dec pulsecnt,x bpl pulsenotnew lda pulsenxt,x sta pulsecur,x tay lda pulstab+2,y cmp #$ff beq pulseskipset sta ZREG and #$f0 sta pulselo,x lda ZREG and #$0f sta pulsehi,x pulseskipset lda pulstab+0,y and #$7f sta pulsecnt,x lda pulstab+3,y bne pulsenotnxt lda pulsenxt,x clc adc #4 jmp pulsesetnxt pulsenotnxt cmp #$7f bne pulsenotstop lda #0 jmp pulsesetnxt pulsenotstop asl asl pulsesetnxt sta pulsenxt,x pulsenotnew lda pulstab,y bmi pulsesub lda pulselo,x clc adc pulstab+1,y sta pulselo,x bcc pulsedone inc pulsehi,x jmp pulsedone pulsesub lda pulselo,x sec sbc pulstab+1,y sta pulselo,x bcs pulsedone dec pulsehi,x pulsedone ;;; ---------------------------------------- ;;; sfx ;;; ---------------------------------------- lda effstate,x bne effdo1 jmp effdone effdo1 !if INCLUDE_CMD_SLUP { cmp #$01 bne effdo2 effslideup lda shfreqlo,x clc adc slidelo,x sta shfreqlo,x lda shfreqhi,x adc slidehi,x sta shfreqhi,x jmp effdone } effdo2 !if INCLUDE_CMD_SLDOWN { cmp #$02 bne effdo3 effslidedown lda shfreqlo,x sec sbc slidelo,x sta shfreqlo,x lda shfreqhi,x sbc slidehi,x sta shfreqhi,x jmp effdone } effdo3 !if INCLUDE_CMD_SET_LOVIB = TRUE { cmp #$04 bne effdo3a lda vibraamp,x sta ZREG lda #0 asl ZREG rol asl ZREG rol sta ZREG+1 jmp vibrealadd } effdo3a !if INCLUDE_CMD_VIBR = FALSE { jmp effdo4 } else { ;;; !if INCLUDE_CMD_VIBR = TRUE | INCLUDE_CMD_SET_LOVIB = TRUE { cmp #$03 beq effvibrato jmp effdo4 effvibrato ldy notereal,x sec lda freqtable_lo+1,y sbc freqtable_lo,y sta ZREG lda freqtable_hi+1,y sbc freqtable_hi+0,y sta ZREG+1 lda vibracor,x clc adc vibraamp,x tay lda #0 sta vibracor,x viblessamp dey bmi vibadd lsr ZREG+1 ror ZREG jmp viblessamp vibadd lda ZREG clc adc vibrafl,x sta ZREG lda ZREG+1 adc vibrafh,x sta ZREG+1 lda vibrafl,x clc adc vibraflv,x sta vibrafl,x lda vibrafh,x adc #0 sta vibrafh,x } !if INCLUDE_CMD_VIBR = TRUE | INCLUDE_CMD_SET_LOVIB = TRUE { vibrealadd lda vibradir,x and #1 bne vibradown lda shfreqlo,x clc adc ZREG sta shfreqlo,x lda shfreqhi,x adc ZREG+1 sta shfreqhi,x jmp vibrapost vibradown lda shfreqlo,x sec sbc ZREG sta shfreqlo,x lda shfreqhi,x sbc ZREG+1 sta shfreqhi,x vibrapost clc lda vibracnt,x adc #1 cmp vibrafrq,x bcc vibradirok inc vibradir,x lda #0 vibradirok sta vibracnt,x vibradone } effdo4 !if INCLUDE_CMD_PORTA = TRUE { cmp #$81 ; Portamento beq effporta jmp effdone effporta ldy notereal,x lda freqtable_lo,y sta ZREG lda freqtable_hi,y sta ZREG+1 lda plo,x sec sbc ZREG sta plo,x lda phi,x sbc ZREG+1 sta phi,x bmi portaup lda plo,x sec sbc portalo,x sta plo,x lda phi,x sbc portahi,x sta phi,x bpl portaclc jmp portaset portaup lda plo,x clc adc portalo,x sta plo,x lda phi,x adc portahi,x sta phi,x bmi portaclc portaset lda ZREG sta plo,x lda ZREG+1 sta phi,x jmp portadone portaclc lda plo,x clc adc ZREG sta plo,x lda phi,x adc ZREG+1 sta phi,x portadone ldy notereal,x lda plo,x sec sbc freqtable_lo,y sta shfreqlo,x lda phi,x sbc freqtable_hi,y sta shfreqhi,x } effdone ;;; ---------------------------------------- ;;; update wavetable ;;; ---------------------------------------- dowave lda hardon,x beq waveok jmp wavedone waveok dec wavecnt,x bpl waveprocess lda wavetime,x sta wavecnt,x ldy wavepos,x lda arp1,y sta wavetrans,x lda arp2,y cmp #$10 bcc waveskip cmp #$e0 bcc wavereg and #$0f wavereg sta waveform,x waveskip lda arp1+1,y cmp #$7e beq wavestore iny wavenotend cmp #$7f bne wavenotend2 lda arp2,y tay wavenotend2 lda arp2,y beq wavestore cmp #$10 bcs wavestore sta wavecnt,x wavestore tya sta wavepos,x !if INCLUDE_CHORD = TRUE { ldy chordtpos,x bmi chorddone chordinit lda chord,y cmp #$40 bcc chordnotneg ora #$80 chordnotneg sta chordvalue,x inc chordtpos,x lda chord+1,y bpl chorddone and #$7f sta chordtpos,x chorddone } waveprocess lda wavetrans,x bpl wavenotabs waveabs and #$7f tay lda freqtable_lo,y sta freqlo,x lda freqtable_hi,y sta freqhi,x jmp wavedone wavenotabs clc adc notereal,x !if INCLUDE_CHORD = TRUE { adc chordvalue,x } tay lda freqtable_lo,y clc adc shfreqlo,x sta freqlo,x lda freqtable_hi,y adc shfreqhi,x sta freqhi,x wavedone ;;; ------------------------------------------------------------ checksuper lda tsync,x cmp #$ff beq supersync jmp superdone supersync lda newcmdflag,x bne superparse jmp superdone superparse lda #0 sta newcmdflag,x superparse2 ldy shsuper,x cpy #$40 bcs *+5 jmp iscmd tya cmp #$60 bcs notpulse and #$1f asl asl sta pulsenxt,x lda #0 sta pulsecnt,x jmp superdone notpulse !if INCLUDE_FILTER = TRUE { cmp #$80 bcs notfilt and #$1f asl asl sta filtnxt lda #0 sta filtcnt jmp superdone notfilt } !if INCLUDE_CHORD = TRUE { cmp #$a0 bcs notchord and #$1f tay lda chordindex,y sta chordtpos,x jmp superdone } notchord !if INCLUDE_SEQ_SET_ATT = TRUE { cmp #$b0 bcs notatt asl asl asl asl sta ZREG lda ad,x and #$0f ora ZREG sta ad,x jmp superdone } notatt !if INCLUDE_SEQ_SET_DEC = TRUE { cmp #$c0 bcs notdec and #$0f sta ZREG lda ad,x and #$f0 ora ZREG sta ad,x jmp superdone } notdec !if INCLUDE_SEQ_SET_SUS = TRUE { cmp #$d0 bcs notsus asl asl asl asl sta ZREG lda sr,x and #$0f ora ZREG sta sr,x jmp superdone } notsus !if INCLUDE_SEQ_SET_REL = TRUE { cmp #$e0 bcs notrel and #$0f sta ZREG lda sr,x and #$f0 ora ZREG sta sr,x jmp superdone } notrel !if INCLUDE_SEQ_SET_VOL = TRUE { cmp #$f0 bcs notvol and #$0f sta volume jmp superdone } notvol !if INCLUDE_SEQ_SET_SPEED = TRUE { and #$0f !if INCLUDE_SYNC = TRUE { bne notsync inc sync jmp superdone notsync } sta speed !if INCLUDE_BREAKSPEED = TRUE { cmp #2 bcs notvol2 lda #1 sta speedsub lda chord } notvol2 sta playspeed sta speedcnt dec speedcnt } jmp superdone ;;; ---------------------------------------- ;;; process a command table entry ;;; ---------------------------------------- iscmd lda cmd2,y sta ZREG lda cmd1,y ; and #$0f sta ZREG+1 cmp #SUPERHIGH bcc superlow jmp superhigh ;SLIDE UP superlow !if INCLUDE_CMD_SLUP = TRUE { cmp #0 bne snotslide1 lda ZREG sta slidehi,x lda cmd3,y sta slidelo,x lda #1 sta effstate,x jmp superdone } ;SLIDE DOWN snotslide1 !if INCLUDE_CMD_SLDOWN = TRUE { cmp #CMD_SLIDE_DOWN bne snotslide2 lda ZREG sta slidehi,x lda cmd3,y sta slidelo,x lda #2 sta effstate,x jmp superdone } ;VIBRATO snotslide2 !if INCLUDE_CMD_VIBR = TRUE { cmp #CMD_VIBRATO bne snotvibrato lda #3 sta effstate,x lda ZREG and #$0f sta vibraflv,x lda cmd3,y and #$0f sta vibraamp,x lda cmd3,y lsr lsr lsr lsr clc adc #1 sta vibrafrq,x lsr bcc novibcor inc vibracor,x ;Correction novibcor sta vibracnt,x lda #0 sta vibradir,x sta vibrafl,x sta vibrafh,x } snotvibrato jmp superdone superhigh !if INCLUDE_CMD_SET_OFFSET = TRUE { cmp #CMD_SET_OFFSET bne snotoffset lda cmd2,y sta shfreqhi,x lda cmd3,y sta shfreqlo,x jmp superdone snotoffset } !if INCLUDE_CMD_SET_ADSR = TRUE { cmp #CMD_SET_ADSR bne snotattdec lda cmd2,y sta ad,x lda cmd3,y sta sr,x jmp superdone snotattdec } !if INCLUDE_CMD_SET_LOVIB { cmp #CMD_SET_LOVIB bne snotlovib lda #4 sta effstate,x lda cmd2,y sta vibrafrq,x lsr ;; adc #0 sta vibracnt,x lda cmd3,y sta vibraamp,x lda #0 sta vibradir,x snotlovib } !if INCLUDE_CMD_SET_WAVE { cmp #CMD_SET_WAVE bne snotwave lda cmd3,y sta waveform,x snotwave } !if INCLUDE_CMD_PORTA { cmp #CMD_STOP bne snotstop lda #0 sta effstate,x snotstop } superdone ;;; ---------------------------------------- setsid ldy voice,x lda freqlo,x sta $d400,y lda freqhi,x sta $d401,y lda sr,x sta $d406,y lda ad,x sta $d405,y lda pulselo,x sta $d402,y lda pulsehi,x sta $d403,y lda waveform,x and gate,x sta $d404,y ;;; ---------------------------------------- !if MULTISPEED = TRUE { bit state bvc *+5 jmp next } ;; check tie & super lda tsync,x cmp #$ff beq postsync jmp skippostsync postsync dec tsync,x lda tienote,x bne tiednote jmp next tiednote lda shtrans,x ;check the note sta trans,x lda shnote,x beq tiestore cmp #3 bcc setgatestat clc adc trans,x sta notereal,x ldy effstate,x bmi tieclear lda #0 sta shfreqlo,x sta shfreqhi,x sta effstate,x skiptiefrq jmp tiestore setgatestat tay lda gatestat-1,y sta gate,x tieclear lda #0 tiestore sta tienote,x skippostsync ;--------------------------------------- next dex bmi maindone !if EXPORT = FALSE { bit state ; 7th bit, keyjam call bpl *+5 jmp updsound bvs *+5 ; 6th bit, multiplay call jmp main0 jmp syncskip } else { !if MULTISPEED = TRUE { bit state bvs *+5 jmp main0 jmp syncskip } else { jmp main0 } } maindone !if MULTISPEED = TRUE | EXPORT = TRUE { lda #0 sta state } ;;; ---------------------------------------- ;;; filter routine ;;; ---------------------------------------- ;;; feb '12: sweeps now in 10 bits res to allow faster sweeps ;;; ($80 in 10 bits corresponds to $20 in 8 bits) !if INCLUDE_FILTER = TRUE { dec filtcnt bpl filtnotnew lda filtnxt filtstart sta filtcur tay lda filttab,y ;byte A = duration or bandpass bpl filtsetcnt and #$70 sta bandpass lda filttab+1,y sta $d417 lda #0 filtsetcnt sta filtcnt lda filttab+1,y and #3 asl sta filtadd+1 lda filttab+1,y cmp #$80 ror cmp #$80 ror ; cmp #$80 ; ror sta filtadd filtjump lda filttab+3,y ; check jump value bne filtnotnxt lda filtnxt clc adc #4 jmp filtsetnxt filtnotnxt cmp #$7f bne filtnotstop lda #0 jmp filtsetnxt filtnotstop asl asl filtsetnxt sta filtnxt lda filttab+2,y cmp #$ff beq filtnotset sta filter lda #0 sta filtlo filtnotset jmp filterskip filtnotnew lda filtadd+1 clc adc filtlo cmp #8 and #7 sta filtlo lda filter adc filtadd sta filter filterskip lda filtlo sta $d415 lda filter sta $d416 } lda volume !if INCLUDE_FILTER = TRUE { ora bandpass } sta $d418 rts !if USE_MDRIVER = TRUE { cplay dec cntr bmi *+5 jmp submplay lda #MULTIPLIER sta cntr jmp subplay cinit ldx #0 stx cntr timerlo = *+1 ldx #CIA_VALUE sty $dc05 stx $dc04 jmp subinit cntr !8 0 } !if EXPORT = FALSE { dummy !8 0 } ;--------------------------------------- freqtable_lo !8 $16,$27,$38,$4b,$5f,$73 !8 $8a,$a1,$ba,$d4,$f0,$0e !8 $2d,$4e,$71,$96,$bd,$e7 !8 $13,$42,$74,$a9,$e0,$1b !8 $5a,$9b,$e2,$2c,$7b,$ce !8 $27,$85,$e8,$51,$c1,$37 !8 $b4,$37,$c4,$57,$f5,$9c !8 $4e,$09,$d0,$a3,$82,$6e !8 $68,$6e,$88,$af,$eb,$39 !8 $9c,$13,$a1,$46,$04,$dc !8 $d0,$dc,$10,$5e,$d6,$72 !8 $38,$26,$42,$8c,$08,$b8 !8 $a0,$b8,$20,$bc,$ac,$e4 !8 $70,$4c,$84,$18,$10,$70 !8 $40,$70,$40,$78,$58,$c8 !8 $e0,$98,$08,$30,$20,$2e freqtable_hi !8 $01,$01,$01,$01,$01,$01 !8 $01,$01,$01,$01,$01,$02 !8 $02,$02,$02,$02,$02,$02 !8 $03,$03,$03,$03,$03,$04 !8 $04,$04,$04,$05,$05,$05 !8 $06,$06,$06,$07,$07,$08 !8 $08,$09,$09,$0a,$0a,$0b !8 $0c,$0d,$0d,$0e,$0f,$10 !8 $11,$12,$13,$14,$15,$17 !8 $18,$1a,$1b,$1d,$1f,$20 !8 $22,$24,$27,$29,$2b,$2e !8 $31,$34,$37,$3a,$3e,$41 !8 $45,$49,$4e,$52,$57,$5c !8 $62,$68,$6e,$75,$7c,$83 !8 $8b,$93,$9c,$a5,$af,$b9 !8 $c4,$d0,$dd,$ea,$f8,$fd ;--------------------------------------- ;Registers voicon !8 1,1,1 ;flags channels on and off !if EXPORT = FALSE { editorflag !8 0 ; set to >0 from packer } state !8 0 bits !8 %00000001 !8 %00000010 !8 %00000100 gatestat !8 $fe,$ff voice !8 0,7,14 tracklo !8 0,0,0 ;track pointers low trackhi !8 0,0,0 ;track pointers hig twraplo !8 0,0,0 ;track wrap low twraphi !8 0,0,0 ;track wrap high speed !8 0 speedcnt !8 0 playspeed !8 0 !if INCLUDE_BREAKSPEED = TRUE { speedsub !8 0 } newseq !8 0,0,0 volume !8 $0f shtrans2 !8 0,0,0 clrfirst ;Clear variables from here ;;; ---------------------------------------- ;;; State variables ;;; ---------------------------------------- newinsflag !8 0,0,0 newcmdflag !8 0,0,0 hardon !fi 3,0 duration !8 0,0,0 durcnt !8 0,0,0 tsync !8 0,0,0 synccnt !8 0,0,0 tienote !8 0,0,0 notereal !8 0,0,0 effstate !8 0,0,0 ;; 0 = no effect ;; 1 = slide up ;; 2 = slide down ;; 3 = vibrato ;; 0x80 = portamento ;;; ---------------------------------------- ;;; Shadow variables ;;; ---------------------------------------- ;; bit 0 = instrument was set ;; bit 1 = cmd was set shtrans !8 0,0,0 shnote !8 0,0,0 shinst !8 0,0,0 shsuper !8 0,0,0 shad !8 0,0,0 shsr !8 0,0,0 shfreqlo !8 0,0,0 shfreqhi !8 0,0,0 freqlo !8 0,0,0 freqhi !8 0,0,0 trans !8 0,0,0 gate !8 0,0,0 ;Sequence curseq !8 0,0,0 seqcnt !8 0,0,0 ;Filter !if INCLUDE_FILTER = TRUE { bandpass !8 0 filter !8 0 filtcnt !8 0 filtcur !8 0 filtnxt !8 0 filtadd !8 0,0 filtlo !8 0 } ;Vibration variables !if INCLUDE_CMD_VIBR = TRUE | INCLUDE_CMD_SET_LOVIB = TRUE { vibracnt !8 0,0,0 ;Count vibradir !8 0,0,0 ;Direction vibraamp !8 0,0,0 ;Amplitude vibrafrq !8 0,0,0 ;Frequency } !if INCLUDE_CMD_VIBR = TRUE { vibracor !8 0,0,0 ;Tune correction vibrafl !8 0,0,0 ;Vibrato feel low vibrafh !8 0,0,0 ;Vibrato feel high vibraflv !8 0,0,0 ;Vibrato feel add } ;Slide variables !if INCLUDE_CMD_SLUP = TRUE | INCLUDE_CMD_SLDOWN = TRUE { slidelo !8 0,0,0 ;Low fraction slidehi !8 0,0,0 ;High fraction } ;Pulse pulsecur !8 0,0,0 pulsenxt !8 0,0,0 pulsecnt !8 0,0,0 pulselo !8 0,0,0 ;-->d402 pulsehi !8 0,0,0 ;-->d403 ;ADSR ad !8 0,0,0 ;-->d405 sr !8 0,0,0 ;-->d406 ;Waveform waveform !8 0,0,0 ;-->d404 ;Wavetable wavetrans !8 0,0,0 wavecnt !8 0,0,0 wavepos !8 0,0,0 wavetime !8 0,0,0 !if INCLUDE_CHORD = TRUE { chordtpos !8 0,0,0 chordvalue !8 0,0,0 } ;Portamento !if INCLUDE_CMD_PORTA = TRUE { portahi !8 0,0,0 portalo !8 0,0,0 plo !8 0,0,0 phi !8 0,0,0 } clrlast ;Clear variables to here !if EXPORT = FALSE { *=$2000 ;--------------------------------------- songsets !16 track1,track2,track3 !8 5,7 ;--------------------------------------- *= songsets + $200 track1 !8 $a0,$00,$f0,0 !for .v, $1fe { !8 $f0,00 } *= track1+$0400 track2 !8 $a0,$00,$f0,0 !for .v, $1fe { !8 $f0,00 } *= track2+$0400 track3 !8 $a0,$00,$f0,0 !for .v, $1fe { !8 $f0,00 } ;--------------------------------------- *= track3 + $400 seqlo !fi 128, s0+((.v-1)*256) } ;--------------------------------------- *= seqlo+$0100 !macro emptyseq { !8 $f0,$f0,$60,$00 !8 $bf } s0 +emptyseq !set curPC = s0 !for .v, 128-1 { *= curPC + $100 !set curPC = * +emptyseq } ;--------------------------------------- *= curPC + $100 arp1 !8 0 ;--------------------------------------- *= arp1+$0100 arp2 !8 0 ;--------------------------------------- *= arp2+$0100 inst !fi 48*8,0 ;;; (more or less) dynamic tables follow...... *= inst+$0200 supertab cmd1 !8 $00 *= cmd1+$40 cmd2 !8 $0f *= cmd2+$40 cmd3 !8 $00 *= cmd3+$40 ;--------------------------------------- ;--------------------------------------- *= supertab+$0100 filttab !8 $7f,$00,$ff,$7f ;--------------------------------------- *= filttab+$0100 pulstab !8 $7f,$00,$ff,$7f *= pulstab+$0100 chord !fi 128,0 chordindex !fi 32,0 } CheeseCutter-2.10/src/com/000077500000000000000000000000001516216315000153645ustar00rootroot00000000000000CheeseCutter-2.10/src/com/cpu.d000066400000000000000000000511601516216315000163230ustar00rootroot00000000000000/* CheeseCutter v2 (C) Abaddon. Licensed under GNU GPL. */ module com.cpu; import std.stdio; import std.string; alias ushort address; ubyte highbyte(ushort value) { return value >> 8; } ubyte lowbyte(ushort value) { return value & 255; } address toAddress(ubyte[] arr) { return arr[0] | (arr[1] << 8); } ubyte[] toArr(address addr) { return [lowbyte(addr), highbyte(addr)]; } alias toArr addr2arr; class CPU { protected: enum St { C = 1, Z = 2, I = 4, D = 8, B = 16, V = 64, N = 128 }; enum Am { IMPLIED, IMMEDIATE, INDIRECT_X, INDIRECT_Y, IND, Z, RELATIVE, ACC, ABSOLUTE, ABSOLUTE_X, ABSOLUTE_Y, ZEROPAGE_X, ZY }; static immutable int[] OPSIZE = [ 0, 1, 1, 1, 2, 1, 1, 0, 2, 2, 2, 1, 1 ]; static string[] AMSTR = [ " \t", " \t#$", "(,x)\t$", "(),y\t$", "() \t$", " \t$", " \t+-", " \ta", " \t$", ",x \t$", ",y \t$", ",xZ \t$", ",yZ \t$" ]; enum Op { BRK = 0, ADC, AND, ASL, EOR, ORA, LSR, JSR, JMP, BIT, ROL, PHP, PLP, PHA, RTI, BVC, CLI, RTS, ROR, PLA, BVS, SEI, STA, STY, STX, DEY, TXA, BCC, TYA, TXS, LDY, LDA, LDX, TAY, TAX, BCS, CLV, TSX, CPY, CMP, DEC, INY, DEX, BNE, CLD, CPX, SBC, INC, INX, NOP, BEQ, SED, BPL, BMI, SEC, CLC }; static string[] OPSTR = [ "BRK", "ADC", "AND", "ASL", "EOR", "ORA", "LSR", "JSR", "JMP", "BIT", "ROL", "PHP", "PLP", "PHA", "RTI", "BVC", "CLI", "RTS", "ROR", "PLA", "BVS", "SEI", "STA", "STY", "STX", "DEY", "TXA", "BCC", "TYA", "TXS", "LDY", "LDA", "LDX", "TAY", "TAX", "BCS", "CLV", "TSX", "CPY", "CMP", "DEC", "INY", "DEX", "BNE", "CLD", "CPX", "SBC", "INC", "INX", "NOP", "BEQ", "SED", "BPL", "BMI", "SEC", "CLC" ]; struct Opcode { Op op; Am am; int cyc; } static immutable Opcode[256] OPTAB = [ { Op.BRK, Am.IMPLIED, 8 }, { Op.ORA, Am.INDIRECT_X, 6 }, { Op.BRK, Am.IMPLIED, 0 }, { Op.BRK, Am.IMPLIED, 0 }, { Op.BRK, Am.IMPLIED, 0 }, { Op.ORA, Am.Z , 3 }, { Op.ASL, Am.Z , 5 }, { Op.BRK, Am.IMPLIED, 0 }, { Op.PHP, Am.IMPLIED, 3 }, { Op.ORA, Am.IMMEDIATE, 2 }, { Op.ASL, Am.ACC, 2 }, { Op.BRK, Am.IMPLIED, 0 }, { Op.BRK, Am.IMPLIED, 0 }, { Op.ORA, Am.ABSOLUTE , 4 }, { Op.ASL, Am.ABSOLUTE , 6 }, { Op.BRK, Am.IMPLIED, 0 }, { Op.BPL, Am.RELATIVE, 2 }, { Op.ORA, Am.INDIRECT_Y, 5 }, { Op.BRK, Am.IMPLIED, 0 }, { Op.BRK, Am.IMPLIED, 0 }, { Op.BRK, Am.IMPLIED, 0 }, { Op.ORA, Am.ZEROPAGE_X , 4 }, { Op.ASL, Am.ZEROPAGE_X , 6 }, { Op.BRK, Am.IMPLIED, 0 }, { Op.CLC, Am.IMPLIED, 2 }, { Op.ORA, Am.ABSOLUTE_Y , 4 }, { Op.BRK, Am.IMPLIED, 0 }, { Op.BRK, Am.IMPLIED, 0 }, { Op.BRK, Am.IMPLIED, 0 }, { Op.ORA, Am.ABSOLUTE_X , 4 }, { Op.ASL, Am.ABSOLUTE_X , 7 }, { Op.BRK, Am.IMPLIED, 0 }, { Op.JSR, Am.ABSOLUTE , 6 }, { Op.AND, Am.INDIRECT_X, 6 }, { Op.BRK, Am.IMPLIED, 0 }, { Op.BRK, Am.IMPLIED, 0 }, { Op.BIT, Am.Z , 3 }, { Op.AND, Am.Z , 3 }, { Op.ROL, Am.Z , 3 }, { Op.BRK, Am.IMPLIED, 0 }, { Op.PLP, Am.IMPLIED, 4 }, { Op.AND, Am.IMMEDIATE, 2 }, { Op.ROL, Am.ACC, 2 }, { Op.BRK, Am.IMPLIED, 0 }, { Op.BIT, Am.ABSOLUTE , 4 }, { Op.AND, Am.ABSOLUTE , 4 }, { Op.ROL, Am.ABSOLUTE , 4 }, { Op.BRK, Am.IMPLIED, 0 }, { Op.BMI, Am.RELATIVE, 2 }, { Op.AND, Am.INDIRECT_Y, 5 }, { Op.BRK, Am.IMPLIED, 0 }, { Op.BRK, Am.IMPLIED, 0 }, { Op.BRK, Am.IMPLIED, 0 }, { Op.AND, Am.ZEROPAGE_X , 4 }, { Op.ROL, Am.ZEROPAGE_X , 6 }, { Op.BRK, Am.IMPLIED, 0 }, { Op.SEC, Am.IMPLIED, 2 }, { Op.AND, Am.ABSOLUTE_Y , 4 }, { Op.BRK, Am.IMPLIED, 0 }, { Op.BRK, Am.IMPLIED, 0 }, { Op.BRK, Am.IMPLIED, 0 }, { Op.AND, Am.ABSOLUTE_X , 4 }, { Op.ROL, Am.ABSOLUTE_X , 7 }, { Op.BRK, Am.IMPLIED, 0 }, { Op.RTI, Am.IMPLIED, 7 }, { Op.EOR, Am.INDIRECT_X, 6 }, { Op.BRK, Am.IMPLIED, 0 }, { Op.BRK, Am.IMPLIED, 0 }, { Op.BRK, Am.IMPLIED, 0 }, { Op.EOR, Am.Z , 3 }, { Op.LSR, Am.Z , 5 }, { Op.BRK, Am.IMPLIED, 0 }, { Op.PHA, Am.IMPLIED, 3 }, { Op.EOR, Am.IMMEDIATE, 2 }, { Op.LSR, Am.ACC, 2 }, { Op.BRK, Am.IMPLIED, 0 }, { Op.JMP, Am.ABSOLUTE , 3 }, { Op.EOR, Am.ABSOLUTE , 4 }, { Op.LSR, Am.ABSOLUTE , 6 }, { Op.BRK, Am.IMPLIED, 0 }, { Op.BVC, Am.RELATIVE, 2 }, { Op.EOR, Am.INDIRECT_Y, 5 }, { Op.BRK, Am.IMPLIED, 0 }, { Op.BRK, Am.IMPLIED, 0 }, { Op.BRK, Am.IMPLIED, 0 }, { Op.EOR, Am.ZEROPAGE_X , 4 }, { Op.LSR, Am.ZEROPAGE_X , 6 }, { Op.BRK, Am.IMPLIED, 4 }, { Op.CLI, Am.IMPLIED, 2 }, { Op.EOR, Am.ABSOLUTE_Y , 4 }, { Op.BRK, Am.IMPLIED, 4 }, { Op.BRK, Am.IMPLIED, 4 }, { Op.BRK, Am.IMPLIED, 4 }, { Op.EOR, Am.ABSOLUTE_X , 4 }, { Op.LSR, Am.ABSOLUTE_X , 7 }, { Op.BRK, Am.IMPLIED, 4 }, { Op.RTS, Am.IMPLIED, 6 }, { Op.ADC, Am.ZEROPAGE_X , 6 }, { Op.BRK, Am.IMPLIED, 4 }, { Op.BRK, Am.IMPLIED, 4 }, { Op.BRK, Am.IMPLIED, 4 }, { Op.ADC, Am.Z , 3 }, { Op.ROR, Am.Z , 5 }, { Op.BRK, Am.IMPLIED, 4 }, { Op.PLA, Am.IMPLIED, 4 }, { Op.ADC, Am.IMMEDIATE, 2 }, { Op.ROR, Am.ACC, 2 }, { Op.BRK, Am.IMPLIED, 4 }, { Op.JMP, Am.IND, 5 }, { Op.ADC, Am.ABSOLUTE , 4 }, { Op.ROR, Am.ABSOLUTE , 6 }, { Op.BRK, Am.IMPLIED, 4 }, { Op.BVS, Am.RELATIVE, 2 }, { Op.ADC, Am.ZY , 5 }, { Op.BRK, Am.IMPLIED, 4 }, { Op.BRK, Am.IMPLIED, 4 }, { Op.BRK, Am.IMPLIED, 4 }, { Op.ADC, Am.ZEROPAGE_X , 4 }, { Op.ROR, Am.ZEROPAGE_X , 6 }, { Op.BRK, Am.IMPLIED, 4 }, { Op.SEI, Am.IMPLIED, 2 }, { Op.ADC, Am.ABSOLUTE_Y , 4 }, { Op.BRK, Am.IMPLIED, 4 }, { Op.BRK, Am.IMPLIED, 4 }, { Op.BRK, Am.IMPLIED, 4 }, { Op.ADC, Am.ABSOLUTE_X , 4 }, { Op.ROR, Am.ABSOLUTE_X , 7 }, { Op.BRK, Am.IMPLIED, 4 }, { Op.BRK, Am.IMPLIED, 0 }, { Op.STA, Am.INDIRECT_X, 6 }, { Op.BRK, Am.IMPLIED, 0 }, { Op.BRK, Am.IMPLIED, 0 }, { Op.STY, Am.Z , 3 }, { Op.STA, Am.Z , 3 }, { Op.STX, Am.Z , 3 }, { Op.BRK, Am.IMPLIED, 4 }, { Op.DEY, Am.IMPLIED, 2 }, { Op.BRK, Am.IMPLIED, 4 }, { Op.TXA, Am.IMPLIED, 2 }, { Op.BRK, Am.IMPLIED, 4 }, { Op.STY, Am.ABSOLUTE , 4 }, { Op.STA, Am.ABSOLUTE , 4 }, { Op.STX, Am.ABSOLUTE , 4 }, { Op.BRK, Am.IMPLIED, 4 }, { Op.BCC, Am.RELATIVE, 4 }, { Op.STA, Am.INDIRECT_Y, 4 }, { Op.BRK, Am.IMPLIED, 4 }, { Op.BRK, Am.IMPLIED, 4 }, { Op.STY, Am.ZEROPAGE_X , 4 }, { Op.STA, Am.ZEROPAGE_X , 4 }, { Op.STX, Am.ZY , 4 }, { Op.BRK, Am.IMPLIED, 4 }, { Op.TYA, Am.IMPLIED, 2 }, { Op.STA, Am.ABSOLUTE_Y , 5 }, { Op.TXS, Am.IMPLIED, 2 }, { Op.BRK, Am.IMPLIED, 4 }, { Op.BRK, Am.IMPLIED, 4 }, { Op.STA, Am.ABSOLUTE_X , 5 }, { Op.BRK, Am.IMPLIED, 4 }, { Op.BRK, Am.IMPLIED, 4 }, { Op.LDY, Am.IMMEDIATE, 2 }, { Op.LDA, Am.INDIRECT_X, 6 }, { Op.LDX, Am.IMMEDIATE, 2 }, { Op.BRK, Am.IMPLIED, 0 }, { Op.LDY, Am.Z , 3 }, { Op.LDA, Am.Z , 3 }, { Op.LDX, Am.Z , 3 }, { Op.BRK, Am.IMPLIED, 0 }, { Op.TAY, Am.IMPLIED, 2 }, { Op.LDA, Am.IMMEDIATE, 2 }, { Op.TAX, Am.IMPLIED, 2 }, { Op.BRK, Am.IMPLIED, 0 }, { Op.LDY, Am.ABSOLUTE , 4 }, { Op.LDA, Am.ABSOLUTE , 4 }, { Op.LDX, Am.ABSOLUTE , 4 }, { Op.BRK, Am.IMPLIED, 0 }, { Op.BCS, Am.RELATIVE, 2 }, { Op.LDA, Am.INDIRECT_Y, 5 }, { Op.BRK, Am.IMPLIED, 0 }, { Op.BRK, Am.IMPLIED, 0 }, { Op.LDY, Am.ZEROPAGE_X , 4 }, { Op.LDA, Am.ZEROPAGE_X , 4 }, { Op.LDX, Am.ZEROPAGE_X , 4 }, { Op.BRK, Am.IMPLIED, 0 }, { Op.CLV, Am.IMPLIED, 2 }, { Op.LDA, Am.ABSOLUTE_Y , 4 }, { Op.TSX, Am.IMPLIED, 2 }, { Op.BRK, Am.IMPLIED, 0 }, { Op.LDY, Am.ABSOLUTE_X , 4 }, { Op.LDA, Am.ABSOLUTE_X , 4 }, { Op.LDX, Am.ABSOLUTE_Y , 4 }, { Op.BRK, Am.IMPLIED, 0 }, { Op.CPY, Am.IMMEDIATE, 2 }, { Op.CMP, Am.INDIRECT_X, 6 }, { Op.BRK, Am.IMPLIED, 0 }, { Op.BRK, Am.IMPLIED, 0 }, { Op.CPY, Am.Z , 3 }, { Op.CMP, Am.Z , 3 }, { Op.DEC, Am.Z , 5 }, { Op.BRK, Am.IMPLIED, 0 }, { Op.INY, Am.IMPLIED, 2 }, { Op.CMP, Am.IMMEDIATE, 2 }, { Op.DEX, Am.IMPLIED, 2 }, { Op.BRK, Am.IMPLIED, 0 }, { Op.CPY, Am.ABSOLUTE , 4 }, { Op.CMP, Am.ABSOLUTE , 4 }, { Op.DEC, Am.ABSOLUTE , 4 }, { Op.BRK, Am.IMPLIED, 0 }, { Op.BNE, Am.RELATIVE, 2 }, { Op.CMP, Am.INDIRECT_Y, 5 }, { Op.BRK, Am.IMPLIED, 4 }, { Op.BRK, Am.IMPLIED, 4 }, { Op.BRK, Am.IMPLIED, 4 }, { Op.CMP, Am.ZEROPAGE_X , 4 }, { Op.DEC, Am.ZEROPAGE_X , 6 }, { Op.BRK, Am.IMPLIED, 0 }, { Op.CLD, Am.IMPLIED, 2 }, { Op.CMP, Am.ABSOLUTE_Y , 4 }, { Op.BRK, Am.IMPLIED, 0 }, { Op.BRK, Am.IMPLIED, 0 }, { Op.BRK, Am.IMPLIED, 0 }, { Op.CMP, Am.ABSOLUTE_X , 4 }, { Op.DEC, Am.ABSOLUTE_X , 7 }, { Op.BRK, Am.IMPLIED, 0 }, { Op.CPX, Am.IMMEDIATE, 2 }, { Op.SBC, Am.INDIRECT_X, 6 }, { Op.BRK, Am.IMPLIED, 0 }, { Op.BRK, Am.IMPLIED, 0 }, { Op.CPX, Am.Z , 3 }, { Op.SBC, Am.Z , 3 }, { Op.INC, Am.Z , 5 }, { Op.BRK, Am.IMPLIED, 0 }, { Op.INX, Am.IMPLIED, 2 }, { Op.SBC, Am.IMMEDIATE, 2 }, { Op.NOP, Am.IMPLIED, 2 }, { Op.SBC, Am.IMMEDIATE, 2 }, { Op.CPX, Am.ABSOLUTE , 4 }, { Op.SBC, Am.ABSOLUTE , 4 }, { Op.INC, Am.ABSOLUTE , 6 }, { Op.BRK, Am.IMPLIED, 0 }, { Op.BEQ, Am.RELATIVE, 2 }, { Op.SBC, Am.INDIRECT_Y, 5 }, { Op.BRK, Am.IMPLIED, 0 }, { Op.BRK, Am.IMPLIED, 0 }, { Op.BRK, Am.IMPLIED, 0 }, { Op.SBC, Am.ZEROPAGE_X , 4 }, { Op.INC, Am.ZEROPAGE_X , 6 }, { Op.BRK, Am.IMPLIED, 0 }, { Op.SED, Am.IMPLIED, 2 }, { Op.SBC, Am.ABSOLUTE_Y , 4 }, { Op.BRK, Am.IMPLIED, 4 }, { Op.BRK, Am.IMPLIED, 4 }, { Op.BRK, Am.IMPLIED, 4 }, { Op.SBC, Am.ABSOLUTE_X , 4 }, { Op.INC, Am.ABSOLUTE_X , 7 }, { Op.BRK, Am.IMPLIED, 2 } ]; struct State { int opcode, realop, addrmode, arg, value, cyc; ubyte[] chunk; } struct Regs { ubyte a, x, y, st, sp; address pc; } int counter; ubyte[] memory; public: Regs regs; this(ubyte[] m) { reset(); memory = m; } void reset() { regs.a = regs.x = regs.y = 0; regs.sp = 255; regs.st = 32; } // execute a 6502 subroutine, return number of cycles used int execute(ushort addr) { return execute(addr, false); } int execute(ushort addr, bool d) { stPush(0); stPush(0); regs.pc = addr; counter = 0; while(regs.pc > 0 && !(regs.st & St.B)) { run(d); } return counter; } protected: /* execute a 6502 instruction * d indicates that ML monitor output is required * returns the number of cycles */ int run(bool d) { string s; address pc; State state; state = decode(); if(regs.pc >= 0xfffd) throw new CPUException(this, "program counter overflow!"); int oldpc = regs.pc; executeOp(state); counter += state.cyc; if(d) { int addrmode, arg, value, opcode; opcode = state.opcode; addrmode = state.addrmode; arg = state.arg; value = state.value; s = dumpRegs(); if(OPSIZE[addrmode] == 0) { writefln(format("$%04x\t$%02X\t%s\t\t\t\t%s c=%x C=$%04X", oldpc, state.realop, OPSTR[opcode], s, state.cyc, counter)); } else { writefln(format("$%04x\t$%02X\t%s%s%02x\t\t\t%s c=%x C=$%04X", oldpc, state.realop, OPSTR[opcode], AMSTR[addrmode], arg, s, state.cyc, counter)); } } if(regs.st & St.B) return state.cyc; return state.cyc; } void dumpOpcode(ref State state) { int addrmode, arg, value, opcode; opcode = state.opcode; addrmode = state.addrmode; arg = state.arg; value = state.value; string s = dumpRegs(); if(OPSIZE[addrmode] == 0) { writefln(format("$%04x\t$%02X\t%s\t\t\t\t%s c=%x C=$%04X", regs.pc, state.realop, OPSTR[opcode], s, state.cyc, counter)); } else { writefln(format("$%04x\t$%02X\t%s%s%02x\t\t\t%s c=%x C=$%04X", regs.pc, state.realop, OPSTR[opcode], AMSTR[addrmode], arg, s, state.cyc, counter)); } } void dumpline(ref State state) { } string dumpRegs() { return format("PC=$%04x A=$%02x X=$%02x Y=$%02x SP=$%02x ST=$%02x" , regs.pc, regs.a, regs.x,regs.y,regs.sp,regs.st); } void setST(ubyte value) { regs.st &= (255 - St.N - St.Z); regs.st |= value & St.N; if (!value) regs.st |= St.Z; } void regWrite(ref ubyte reg, ushort value) { reg = cast(ubyte)value; setST(cast(ubyte)value); } void regWrite(ref ubyte reg, ubyte value) { reg = value; setST(value); } alias regWrite set; void stPush(ubyte val) { memory[0x100 + regs.sp] = val; regs.sp--; } ubyte stPull() { regs.sp++; return memory[0x100 + regs.sp]; } /* prints cpu status and a message from player * message format: * [info byte] [data....] * info byte: $00-$7f number of bytes to dump/string length * 8th bit ON = output string, else output bytes */ void handleBreak() { /+ fprintf(stdout, toStringz(dumpRegs() ~ " ( ")); int info = memory[0xdf00]; if(info) { for(int i=0; i < (info & 0x7f); i++) { if(!(info & 0x80)) { fprintf(stdout,"$%02x ", memory[0xdf01 + i]); } } } fprintf(stdout, ") "); if(!(info & 0x80)) fprintf(stdout,"\n"); +/ throw new CPUException(this, "BRK"); } void executeOp(ref State stat) { int arg = stat.arg; ushort value = cast(ushort)stat.value; int acc; int am = stat.addrmode; int p = regs.pc; regs.pc += 1 + OPSIZE[stat.addrmode]; switch(stat.opcode) { case Op.BRK: handleBreak(); regs.st |= St.B; break; case Op.SEI: regs.st |= St.I; break; case Op.CLI: regs.st &= 255 - St.I; break; case Op.CLC: regs.st &= 255 - St.C; break; case Op.SEC: regs.st |= St.C; break; case Op.CLV: regs.st &= 255 - St.V; break; case Op.SED: regs.st |= St.D; throw new CPUException(this,"Decimal mode not supported"); case Op.CLD: regs.st &= 255 - St.D; break; case Op.LDA: set(regs.a, value); break; case Op.LDX: set(regs.x, value); break; case Op.LDY: set(regs.y, value); break; case Op.INX: set(regs.x, (regs.x + 1) & 255); break; case Op.INY: set(regs.y, (regs.y + 1) & 255); break; case Op.DEX: set(regs.x, (regs.x - 1) & 255); break; case Op.DEY: set(regs.y, (regs.y - 1) & 255); break; case Op.TAX: set(regs.x, regs.a); break; case Op.TXA: set(regs.a, regs.x); break; case Op.TAY: set(regs.y, regs.a); break; case Op.TYA: set(regs.a, regs.y); break; case Op.PHA: stPush(regs.a); break; case Op.PLA: set(regs.a, stPull()); break; case Op.PHP: stPush(regs.st); break; case Op.PLP: regs.st = stPull(); break; case Op.TSX: set(regs.x,regs.sp); break; case Op.TXS: regs.sp = regs.x; break; case Op.STA: write(stat, am, arg, regs.a); break; case Op.STX: write(stat, am, arg, regs.x); break; case Op.STY: write(stat, am, arg, regs.y); break; case Op.BIT: ubyte st; st = regs.st; st &= 0xff - St.N - St.V - St.Z; st |= value & 0xc0; if (!regs.a & value) st |= St.Z; regs.st = st; break; case Op.BEQ: if (regs.st & St.Z) { regs.pc = value; stat.cyc++; } break; case Op.BNE: if (!(regs.st & St.Z)) { regs.pc = value; stat.cyc++; } break; case Op.BPL: if (!(regs.st & St.N)) { regs.pc = value; stat.cyc++; } break; case Op.BMI: if (regs.st & St.N) { regs.pc = value; stat.cyc++; } break; case Op.BCC: if (!(regs.st & St.C)) { regs.pc = value; stat.cyc++; } break; case Op.BCS: if (regs.st & St.C) { regs.pc = value; stat.cyc++; } break; case Op.BVC: if (!(regs.st & St.V)) { regs.pc = value; stat.cyc++; } break; case Op.BVS: if (regs.st & St.V) { regs.pc = value; stat.cyc++; } break; case Op.JMP: if (am == Am.IND) regs.pc = value; else regs.pc = cast(ushort)arg; break; case Op.JSR: int pc = regs.pc; stPush(cast(ubyte)(pc >> 8)); // wrong byte order? stPush(cast(ubyte)(pc & 255)); regs.pc = cast(ushort)arg; break; case Op.RTS: regs.pc = (stPull())| (stPull() << 8); break; case Op.RTI: // need to change "I" flag? regs.st = stPull(); regs.pc = (stPull() << 8) | stPull(); break; case Op.ASL: acc = value << 1; regs.st &= 255 - St.C; regs.st |= (acc >> 8) & St.C; setST(acc & 255); write(stat, am,arg,acc &255); break; case Op.LSR: acc = value; regs.st &= 255 - St.C; regs.st |= acc & St.C; acc = acc >> 1; setST(acc & 255); write(stat,am,arg,acc & 255); break; case Op.ROL: acc = value << 1; acc |= regs.st & St.C; regs.st &= 255 - St.C; regs.st |= (acc >> 8) & St.C; setST(acc & 255); write(stat,am,arg,acc & 255); break; case Op.ROR: ubyte st; acc = value; st = regs.st; regs.st &= 255 - St.C; regs.st |= acc & St.C; acc = acc >> 1; acc |= (st & St.C) << 7; setST(acc & 255); write(stat,am,arg,acc & 255); break; case Op.ADC: int t; t = regs.a + (regs.st & St.C) + value; regs.st &= 255 - St.C; regs.st |= ((t >> 8) & St.C); set(regs.a,t & 255); break; case Op.SBC: int t; t = regs.a - value - !(regs.st & St.C); regs.st &= 255 - St.C; //regs.st |= value > regs.a ? 0 : St.C; regs.st |= t < 0 ? 0 : St.C; set(regs.a,t & 255); break; case Op.CMP: int t; t = regs.a - value; regs.st &= 255 - St.C; //regs.st |= value > regs.a ? 0 : St.C; regs.st |= t < 0 ? 0 : St.C; setST(t & 255); break; case Op.CPX: int t; t = regs.x - value; regs.st &= 255 - St.C; //regs.st |= value > regs.x ? 0 : St.C; regs.st |= t < 0 ? 0 : St.C; setST(t & 255); break; case Op.CPY: int t; t = regs.y - value; regs.st &= 255 - St.C; regs.st |= value > regs.y ? 0 : St.C; //regs.st |= value > regs.y ? 0 : St.C; regs.st |= t < 0 ? 0 : St.C; setST(t & 255); break; case Op.INC: write(stat,am,arg,(value + 1) & 255); setST(cast(ubyte)(value+1)); break; case Op.DEC: write(stat,am,arg,(value - 1) & 255); setST(cast(ubyte)(value-1)); break; case Op.AND: ubyte t; t = regs.a & value; set(regs.a,t); break; case Op.EOR: acc = regs.a ^ value; set(regs.a,acc & 255); break; case Op.ORA: acc = regs.a | value; set(regs.a,acc & 255); break; case Op.NOP: break; default: throw new CPUException(this,"Illegal instruction"); } } address fetchAddress(ref State st) { int am = st.addrmode; ushort arg = cast(ushort)st.arg; switch(am) { case Am.ABSOLUTE_X: return (arg + regs.x) & 65535; case Am.ZY, Am.ABSOLUTE_Y: return (arg + regs.y) & 65535; case Am.ZEROPAGE_X: return (arg + regs.x) & 255; case Am.Z: return arg & 255; case Am.ABSOLUTE: return arg; case Am.INDIRECT_Y: return cast(address)(toAddress(memory[(arg & 0xff) .. (arg & 0xff) + 2]) + regs.y); default: throw new CPUException(this,format("Illegal addressing mode %d", am)); } assert(0); } ushort fetch(ref State st) { int am = st.addrmode; ubyte arg = cast(ubyte)st.arg; switch(am) { case Am.IMPLIED: return 0; case Am.IMMEDIATE: return arg; case Am.ABSOLUTE_X, Am.ZY, Am.ABSOLUTE_Y, Am.ZEROPAGE_X, Am.Z, Am.ABSOLUTE, Am.INDIRECT_Y: return memory[fetchAddress(st)]; case Am.ACC: return regs.a; case Am.RELATIVE: return cast(ushort)(regs.pc + (arg >= 128 ? -256 + arg : arg) + 2); case Am.INDIRECT_X: throw new CPUException(this,"(indexed,x) not implemented"); default: throw new CPUException(this,format("Illegal addressing mode %d", am)); } assert(0); } State decode() { static State st; Opcode ops; st.chunk = memory[regs.pc .. regs.pc + 3]; ops = OPTAB[st.chunk[0]]; st.realop = st.chunk[0]; st.opcode = cast(int)ops.op; st.addrmode = cast(int)ops.am; st.cyc = cast(int)ops.cyc; st.arg = 0; if(OPSIZE[st.addrmode] == 1) { st.arg = st.chunk[1]; } else if(OPSIZE[st.addrmode] == 2) { st.arg = st.chunk[1] | (st.chunk[2] << 8); } st.value = fetch(st); return st; } void write(ref State stat, int am, int arg, ubyte val) { switch(am) { case Am.Z: case Am.ZEROPAGE_X: case Am.ABSOLUTE: case Am.ABSOLUTE_X: case Am.ABSOLUTE_Y: case Am.INDIRECT_Y: memory[fetchAddress(stat)] = val; return; case Am.ACC: regs.a = val; break; case Am.INDIRECT_X: throw new CPUException(this,"(indexed,x) not implemented"); default: throw new CPUException(this,format("Unsupported addrmode %d",am)); } } } class CPUException : Exception { CPU cpu; this(CPU cpu, string msg) { super("CPU error: " ~ msg ~ " (" ~ cpu.dumpRegs() ~ ")"); this.cpu = cpu; } override string toString() { return msg; } } CheeseCutter-2.10/src/com/fb.d000066400000000000000000000237161516216315000161310ustar00rootroot00000000000000/* CheeseCutter v2 (C) Abaddon. Licensed under GNU GPL. */ module com.fb; import derelict.sdl2.sdl; import std.string : indexOf; import com.util; immutable SDL_Color[] PALETTE = [ { 0,0,0 }, { 63 << 2,63 << 2,63 << 2 }, { 26 << 2,13 << 2,10 << 2 }, { 28 << 2,41 << 2,44 << 2 }, { 27 << 2,15 << 2,33 << 2 }, { 22 << 2,35 << 2,16 << 2 }, { 13 << 2,10 << 2,30 << 2 }, { 46 << 2,49 << 2,27 << 2 }, { 27 << 2,19 << 2,9 << 2 }, { 16 << 2,14 << 2,0 << 2 }, { 38 << 2,25 << 2,22 << 2 }, { 17 << 2,17 << 2,17 << 2 }, { 27 << 2,27 << 2,27 << 2 }, { 38 << 2,52 << 2,33 << 2 }, { 27 << 2,23 << 2,45 << 2 }, { 37 << 2,37 << 2,37 << 2 } ]; immutable FONT_X = 8, FONT_Y = 14; __gshared ubyte[] font; immutable int mode, border = 1; private bool isDirty = false; immutable CHECKX = "assert(x >= 0 && x < width);"; immutable CHECKY = "assert(y >= 0 && y < height);"; immutable CHECKS = "assert(x + y >= 0 && x + y < width*height);"; static this() { void[] arr; font.length = 256*16; // realign font data immutable rawfont = import("font.psf"); for(int i=0;i<256;i++) { font[i*16..i*16+14] = cast(ubyte[])rawfont[i*FONT_Y+4..i*FONT_Y+4+FONT_Y]; } } class Video { protected { SDL_Window* window; SDL_Renderer* renderer; SDL_Texture* texture; uint[] framebuffer; bool useFullscreen; Screen screen; const int requestedWidth, requestedHeight; int correctedHeight, correctedWidth; int height, width; // resolution of window //int displayHeight, displayWidth; // resolution of the monitor SDL_Rect destRect; } this(int wx, int wy, Screen scr, int fs) { this.screen = scr; this.requestedHeight = wy; this.requestedWidth = wx; this.framebuffer = new uint[wx*wy]; } ~this() { if(renderer !is null) SDL_DestroyRenderer(renderer); // if(texture !is null) // SDL_DestroyTexture if(window !is null) SDL_DestroyWindow(window); } bool init() { width = requestedWidth; height = requestedHeight; useFullscreen = false; import std.string, std.stdio; window = SDL_CreateWindow("CheeseCutter 2.10", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 800, 600, cast(SDL_WindowFlags) SDL_WINDOW_SHOWN | SDL_WINDOW_RESIZABLE ); if (window is null) { return false; } renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED); if (renderer is null) { return false; } texture = SDL_CreateTexture(renderer, SDL_GetWindowPixelFormat(window), SDL_TEXTUREACCESS_TARGET, 800, 600); if (texture is null) { return false; } SDL_SetRenderTarget(renderer, null); calcAspect(); screen.refresh(); return true; } void drawVisualizer(int) {} void clearVisualizer() {} protected void enableFullscreen(bool fs) {} void toggleFullscreen() { useFullscreen ^= 1; enableFullscreen(useFullscreen); } // TBD void scalePosition(ref int x, ref int y) { x -= destRect.x; y -= destRect.y; /+ x *= cast(float)requestedWidth / width; y *= cast(float)requestedHeight / height; +/ } void updateFrame() { auto surface = SDL_GetWindowSurface(window); int x, y; int a,b,c; ushort* bptr = &screen.data[0]; ushort* cptr = &screen.olddata[0]; uint* sptr = framebuffer.ptr; uint* sp; ubyte* bp; ubyte ubg, ufg; if (!isDirty) return; isDirty = false; for(y = 0;y < screen.height; y++) { for(x = 0; x < screen.width; x++) { if(*bptr != *cptr) { *cptr = *bptr; sp = sptr; a = *bptr & 255; bp = &font[a * 16]; ufg = (*bptr >> 8) & 15; ubg = (*bptr >> 12); auto fgcolor = getColor(surface, ufg), bgcolor = getColor(surface, ubg); for(c = 4; c < 18; c++, bp++) { b = *bp; if(b & 0x80) *(sp++) = fgcolor; else *(sp++) = bgcolor; if(b & 0x40) *(sp++) = fgcolor; else *(sp++) = bgcolor; if(b & 0x20) *(sp++) = fgcolor; else *(sp++) = bgcolor; if(b & 0x10) *(sp++) = fgcolor; else *(sp++) = bgcolor; if(b & 0x08) *(sp++) = fgcolor; else *(sp++) = bgcolor; if(b & 0x04) *(sp++) = fgcolor; else *(sp++) = bgcolor; if(b & 0x02) *(sp++) = fgcolor; else *(sp++) = bgcolor; if(b & 0x01) *(sp++) = fgcolor; else *(sp++) = bgcolor; sp += width - 8; } } sptr += 8; bptr++; cptr++; } sptr += width*13; } // Apparently this is fairly slow: https://wiki.libsdl.org/SDL3/SDL_UpdateTexture SDL_UpdateTexture(texture, null, framebuffer.ptr, 800 * uint.sizeof); SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255); SDL_RenderClear(renderer); SDL_RenderCopy(renderer, texture, null, &destRect); SDL_RenderPresent(renderer); } void resizeEvent(int nw, int nh) { calcAspect(); screen.refresh(); } private void calcAspect() { int windowWidth, windowHeight; SDL_GetWindowSize(window, &windowWidth, &windowHeight); int correctedHeight = windowHeight; int correctedWidth = windowWidth; if(cast(float)windowHeight / windowWidth < 0.75) { correctedWidth = cast(int)(correctedHeight / 0.75); correctedHeight = windowHeight; } else { correctedWidth = windowWidth; correctedHeight = cast(int)(correctedWidth * 0.75); } destRect.w = correctedWidth; destRect.h = correctedHeight; if (windowWidth > correctedWidth) destRect.x = (windowWidth - correctedWidth) / 2; else destRect.x = 0; if (windowHeight > correctedHeight) destRect.y = (windowHeight - correctedHeight) / 2; else destRect.y = 0; } } class Screen { Uint16[] data; private Uint16[] olddata; immutable int width, height; alias width w; alias height h; this(int xchars, int ychars) { width = xchars; height = ychars; data.length = xchars * ychars; olddata.length = xchars * ychars; refresh(); } Uint16 getChar(int x, int y) { mixin(CHECKS); return data[x + y * width]; } void setChar(int x, int y, Uint16 c) { mixin(CHECKS); data[x + y * width] = c; isDirty = true; } void setColor(int x, int y, int fg, int bg) { mixin(CHECKS); Uint16* s = &data[x + y * width]; *s &= 0xff; *s |= (fg << 8) | (bg << 12); isDirty = true; } int getbg(int x, int y) { return getChar(x, y) >> 12; } void setbg(int x, int y, int bg) { Uint16* s = &data[x + y * width]; *s &= 0xfff; *s |= (bg << 12); isDirty = true; } void clrtoeol(int y, int bg) { clrtoeol(0, y, bg); } void clrtoeol(int x, int y, int bg) { mixin(CHECKY); Uint16* s = &data[x + y * width]; Uint16 v = cast(Uint16)(0x20 | (bg << 12)); while(x++ < width) *s++ = v; isDirty = true; } void clrscr() { data[] = 0x20; isDirty = true; } void refresh() { olddata[] = 255; isDirty = true; } void cprint(int x, int y, int fg, int bg, string txt) { mixin(CHECKS); bool skipbg, skipfg; if(bg < 0) { skipbg = true; bg = 0; } if(fg < 0) { skipfg = true; fg = 0; } Uint16[] s = data[x + y * width .. x + y * width + txt.length]; Uint16 col = cast(Uint16)((fg << 8) | (bg << 12)); foreach(i, char c; txt) { if(skipbg) col = cast(Uint16)((fg << 8) | (s[i] & 0xf000)); if(skipfg) col = cast(Uint16)((bg << 12) | (s[i] & 0x0f00)); s[i] = cast(Uint16)(c | col); } isDirty = true; } void fprint(int x, int y, string str) { mixin(CHECKS); assert(str.length < 256); Uint16[] outb = data[x + y * width .. $]; int bg = 0, fg = 0; int idx; while(idx < str.length) { int getcol(char c) { return cast(int)(c == '+' ? -1 : "0123456789abcdef".indexOf(c)); } if(str[idx] == '`') { bg = getcol(str[idx + 1]); fg = getcol(str[idx + 2]); idx += 3; continue; } if(bg >= 0) { outb[0] &= 0x0fff; outb[0] |= bg << 12; } if(fg >= 0) { outb[0] &= 0xf0ff; outb[0] |= fg << 8; } outb[0] &= 0xff00; outb[0] |= str[idx] & 255; outb = outb[1 .. $]; idx++; } } } interface Visualizer { void clear(); void draw(int); } private class Oscilloscope : Visualizer { private SDL_Surface* surface; private short* samples; private const short xconst, yconst; enum width = 960/4, height = 3*14; this(SDL_Surface* surface, short xpos, short ypos) { this.surface = surface; this.xconst = xpos; this.yconst = ypos; import audio.audio; samples = audio.audio.mixbuf; assert(samples !is null); } void clear() { SDL_FillRect(surface, new SDL_Rect(xconst, yconst, width, height), 0); } void draw(int frames) { float smpofs; float n = frames * 50.0f; int count = cast(int)(48000 / n); auto colh = getColor(surface, 13), coll = getColor(surface, 5); clear(); smpofs = 0.0f; import audio.audio; int oldposition = height / 2 + samples[cast(int)smpofs] / 768; for(int i = 0; i < width; i++) { int sample = samples[cast(int)smpofs] / 768; int position = height / 2 + sample; position = com.util.umod(position, 0, height-1); int a = oldposition, b = position; if(a > b) { int temp = b; b = a; a = temp; } assert(a <= b); Uint32* pos = cast(Uint32 *)surface.pixels + xconst + i + (a + yconst) * surface.w; *pos = (i > 12 && i < width - 12) ? colh : coll; for(int k = a; k < b; k++) { *pos = (i > 12 && i < width - 12) ? colh : coll; pos += surface.w; } smpofs++; if(smpofs >= audio.audio.getbufsize()) smpofs -= cast(int)audio.audio.getbufsize(); oldposition = position; } } } class DisplayError : Error { this(string msg) { super("SDL Error: " ~ msg); } } void enableKeyRepeat() { // SDL_EnableKeyRepeat(200, 10); } void disableKeyRepeat() { //SDL_EnableKeyRepeat(0, 0); } Uint16 readkey() { SDL_Event evt; bool loop = true; while(loop) { while(SDL_PollEvent(&evt)) { if(evt.type == SDL_QUIT) { SDL_Quit(); return 0; } if(evt.type == SDL_KEYDOWN) { loop = false; break; } } SDL_Delay(50); } return cast(Uint16)evt.key.keysym.unicode; } auto getColor(SDL_Surface* s, int c) { return SDL_MapRGBA(s.format, PALETTE[c].r, PALETTE[c].g, PALETTE[c].b, 255); } CheeseCutter-2.10/src/com/kbd.d000066400000000000000000000024571516216315000163010ustar00rootroot00000000000000/* CheeseCutter v2 (C) Abaddon. Licensed under GNU GPL. */ module com.kbd; import derelict.sdl2.sdl; import ui.input : Keyinfo; void translate(ref Keyinfo key) { switch(key.key) { case SDLK_KP_ENTER: // for shitty laptops and apple computers... key.key = SDLK_INSERT; break; default: break; } // do this last since platform specific translations need to be done 1st translate_super(key); } void translate_super(ref Keyinfo key) { if(key.mods & KMOD_GUI) { switch(key.key) { case SDLK_1: key.key = SDLK_KP_1; break; case SDLK_2: key.key = SDLK_KP_2; break; case SDLK_3: key.key = SDLK_KP_3; break; case SDLK_4: key.key = SDLK_KP_4; break; case SDLK_5: key.key = SDLK_KP_5; break; case SDLK_6: key.key = SDLK_KP_6; break; case SDLK_7: key.key = SDLK_KP_7; break; case SDLK_8: key.key = SDLK_KP_8; break; case SDLK_9: key.key = SDLK_KP_9; break; case SDLK_UP: key.mods = KMOD_SHIFT; key.key = SDLK_HOME; break; case SDLK_DOWN: key.mods = KMOD_SHIFT; key.key = SDLK_END; break; default: // otherwise just translate to ctrl+shift... key.mods |= KMOD_CTRL | KMOD_SHIFT; break; } key.mods ^= KMOD_GUI; // meta off } } CheeseCutter-2.10/src/com/session.d000066400000000000000000000042641516216315000172220ustar00rootroot00000000000000/* CheeseCutter v2 (C) Abaddon. Licensed under GNU GPL. */ module com.session; import ct.base; import com.fb; import com.util; import ui.ui; import seq.sequencer; import std.typecons; import com.util; interface Undoable { void undo(UndoValue); UndoValue createRedoState(UndoValue); } struct TracklistStore { Tracklist store, source; } struct UndoValue { import ct.base; alias Array = Tuple!(ubyte[], "target", ubyte[], "source"); // undo data needed by sequencer Array array; Sequence seq; // undo data needed by track editor TracklistStore[] trackLists; ushort trackValue; Track track; ubyte[][] tableData; int subtuneNum; PosDataTable posTable; bool allVoices; } struct UndoState { Undoable func; UndoValue value; } struct EditorState { __gshared Song song; PosDataTable fplayPos, seqPos; int octave = 3; int activeInstrument; bool autoinsertInstrument = true; bool shortTitles = true; bool displayHelp = true; bool keyjamStatus = false; bool allowInstabNavigation = true; string filename; auto undoQueue = Queue!UndoState(); auto redoQueue = Queue!UndoState(); } UI mainui; Video video; Screen screen; EditorState state; void insertUndo(Undoable undoable, UndoValue value) { state.undoQueue.insert(UndoState(undoable, value)); } void executeUndo() { if(state.undoQueue.empty) return; auto u = state.undoQueue.pop(); // make entry for redo (copy current state) auto redo = makeRedoOrUndo(u); state.redoQueue.insert(redo); u.func.undo(u.value); } void executeRedo() { if(state.redoQueue.empty) return; auto r = state.redoQueue.pop(); // make entry for undo (copy current state) auto undo = makeRedoOrUndo(r); state.undoQueue.insert(undo); r.func.undo(r.value); } private UndoState makeRedoOrUndo(UndoState state) { state.value = state.func.createRedoState(state.value); return state; } @property song() { return state.song; } @property seqPos() { return state.seqPos; } @property fplayPos() { return state.fplayPos; } void initSession() { state.song = new Song(); state.seqPos = new PosDataTable(); state.fplayPos = new PosDataTable(); for(int i = 0; i < 3; i++) { state.seqPos[i].tracks = song.tracks[i]; state.fplayPos[i].tracks = song.tracks[i]; } } CheeseCutter-2.10/src/com/util.d000066400000000000000000000120551516216315000165110ustar00rootroot00000000000000/* CheeseCutter v2 (C) Abaddon. Licensed under GNU GPL. */ module com.util; import std.stdio; import std.string; import std.conv; import std.array; alias char* PetString; //private auto regexFn = regex("[^a-zA-Z0-9_\\-\\.]"); string versionInfo() { version(DEV) return " (" ~__DATE__ ~ " git)"; return " (" ~__DATE__ ~ ")"; } struct Clip { int trans, no; } struct Queue(T) { enum NUM_UNDO_STAGES = 200; import std.container.dlist; auto stages = DList!T(); void insert(T t) { import std.range; auto r = stages[]; if(r.walkLength >= NUM_UNDO_STAGES) stages.removeBack(); stages.insertFront(t); } bool empty() { return stages.empty; } T pop() { if(stages.empty) assert(0); auto t = stages.front; stages.removeFront(); return t; } void clear() { stages.clear; } } class UserException : Exception { this(string msg) { super(msg); } override string toString() { return msg; } } int paddedStringLength(string s, char padchar) { int i; for(i = cast(int)(s.length - 1); i >= 0; i--) { if(s[i] != padchar) return cast(int)(i+1); } return 0; } void hexdump(ubyte[] buf, int rowlen) { hexdump(buf, rowlen, false); } void hexdump(ubyte[] buf, int rowlen, bool prrow) { int c, r; if(prrow) writef("%02x: ", 0); foreach(b; buf) { writef("%02X ", b); c++; if(c >= rowlen) { c = 0; writef("\n"); if(prrow) writef("%02x: ",++r); } } writef("\n"); } string petscii2D(PetString petstring) { char[] s; int idx; s.length = 512; while(*petstring != '\0') { char c = *(petstring++); if(c == '&') { s[idx] = '\n'; s[idx + 1 .. idx + 6] = ' '; idx += 6; } else s[idx++] = c; } s.length = idx; return format(s); } deprecated string getArgumentValue(string argname, string[] text) { foreach(line; text) { string[] tokens = std.array.split(line); //string[] tokens = line.split(); if(tokens.length == 0) continue; if(tokens[0] == argname && tokens.length > 2 && tokens[1] == "=") return tokens[2]; } return null; } string setArgumentValue(string argname, string value, string text) { string s; bool found; //foreach(line; text.splitLines()) { foreach(line; text.splitLines()) { //string[] tokens = line.split(); string[] tokens = std.array.split(line); if(tokens.length == 0) continue; if(tokens[0] == argname && tokens.length > 2 && tokens[1] == "=") { line = tokens[0] ~ tokens[1] ~ " " ~ value; found = true; } s ~= line ~ "\n"; } if(!found) throw new Exception("argname " ~ argname ~ " not found"); return s; } ubyte[] table2Array(string table) { static ubyte[4096] arr; int idx; foreach(strvalue; std.array.split(table)) { string s = strvalue.replace("\r\n\t", ""); arr[idx] = cast(ubyte)str2Value(s); idx++; } return arr[0..idx]; } int str2Value(string s) { if(s[0] == 'x' || s[0] == '$') { return convertHex(s[1 .. $]); } return to!int(s); } int convertHex(string s) { int val, i; foreach_reverse(c; toUpper(s)) { if(c == 'x' || c == '$') break; if("0123456789ABCDEF".indexOf(c) < 0) throw new Exception("Illegal hexadecimal value in string."); val += ( (c >= '0' && c <= '9') ? c - '0' : c - ('A' - 10)) << (4 * i++); } return val; } void parseList(ref int[] array, string arg) { int index; string[] list = std.string.split(arg, ","); foreach(valueset; list) { string[] values = std.string.split(valueset, ":"); if(values.length == 0) { // length == 0, just skip index++; } else if(values.length == 1) { // the sole value is the speed array[index] = to!int(values[0]); } else { index = to!int(values[0]); if(index > 31) throw new UserException("Value list index out of bounds."); array[index] = to!int(values[1]); } index++; if(index > 31) throw new UserException("Value list too long."); } } int str2Value2(string s) { int idx; bool hexUsed; if(s[0] == 'x' || s[0] == '$') { hexUsed = true; idx = 1; } else if(s.length > 2 && s[0..2] == "0x") { hexUsed = true; idx = 2; } if(hexUsed) { int val, i; foreach_reverse(char c; toUpper(s[idx..$])) { if("0123456789ABCDEF".indexOf(c) < 0) throw new UserException("Illegal hexadecimal value in argument."); val += ( (c >= '0' && c <= '9') ? c - '0' : c - ('A' - 10)) << (4 * i++); } return val; } foreach(char c; s) { if("0123456789".indexOf(c) < 0) throw new UserException("Illegal value in argument."); } return to!int(s); } string arr2str(ubyte[] arr) { //char[] c = new string(arr.length * 2); char[] c = (new string(arr.length * 2)).dup; foreach(idx, ubyte byt; arr) { c[idx * 2 .. idx * 2 + 2] = std.string.format("%02x", byt); } return to!string(c); } /* string fnClean(string fn) { return replaceAll(fn,regexFn,"_"); } bool fnIsSane(string fn) { return matchAll(fn,regexFn).empty; }*/ string fnClean(string fn) { return tr(fn,"a-zA-Z0-9._-","_","c"); } bool fnIsSane(string fn) { return (fn == fnClean(fn)); } int clamp(int n, int l, int h) { return n > h ? h : n < l ? l : n; } int umod(int n, int l, int h) { return n > h ? l : n < l ? h : n; } // 0-terminated string to d string string ztos(char[] str) { return to!string(&str[0]); } CheeseCutter-2.10/src/ct/000077500000000000000000000000001516216315000152145ustar00rootroot00000000000000CheeseCutter-2.10/src/ct/base.d000066400000000000000000001257371516216315000163120ustar00rootroot00000000000000/* CheeseCutter v2 (C) Abaddon. Licensed under GNU GPL. */ module ct.base; import com.cpu; import com.util; import ct.purge; import std.string; import std.file; import std.zlib; enum Offsets { Features, Volume, Editorflag, Songsets, PlaySpeed, Subnoteplay, Submplayplay, InstrumentDescriptionsHeader, PulseDescriptionsHeader, FilterDescriptionsHeader, WaveDescriptionsHeader, CmdDescriptionsHeader, FREQTABLE, FINETUNE, Arp1, Arp2, FILTTAB, PULSTAB, Inst, Track1, Track2, Track3, SeqLO, SeqHI, CMD1, S00, SPEED, TRACKLO, VOICE, GATE, ChordTable, TRANS, ChordIndexTable, SHTRANS, FOO3, NEXT, CURINST, GEED, NEWSEQ } immutable string[] NOTES = [ "C-0", "C#0", "D-0", "D#0", "E-0", "F-0", "F#0", "G-0", "G#0", "A-0", "A#0", "B-0", "C-1", "C#1", "D-1", "D#1", "E-1", "F-1", "F#1", "G-1", "G#1", "A-1", "A#1", "B-1", "C-2", "C#2", "D-2", "D#2", "E-2", "F-2", "F#2", "G-2", "G#2", "A-2", "A#2", "B-2", "C-3", "C#3", "D-3", "D#3", "E-3", "F-3", "F#3", "G-3", "G#3", "A-3", "A#3", "B-3", "C-4", "C#4", "D-4", "D#4", "E-4", "F-4", "F#4", "G-4", "G#4", "A-4", "A#4", "B-4", "C-5", "C#5", "D-5", "D#5", "E-5", "F-5", "F#5", "G-5", "G#5", "A-5", "A#5", "B-5", "C-6", "C#6", "D-6", "D#6", "E-6", "F-6", "F#6", "G-6", "G#6", "A-6", "A#6", "B-6", "C-7", "C#7", "D-7", "D#7", "E-7", "F-7", "F#7", "G-7", "G#7", "A-7", "A#7", "B-7" ]; enum { MAX_SEQ_ROWS = 0x40, MAX_SEQ_NUM = 0x80, TRACK_LIST_LENGTH = 0x200, OFFSETTAB_LENGTH = 16 * 6, SEQ_END_MARK = 0xbf, SONG_REVISION = 12, NOTE_KEYOFF = 1, NOTE_KEYON = 2, SUBTUNE_MAX = 32 } immutable ubyte[] CLEAR = [0xf0, 0xf0, 0x60, 0x00]; immutable ubyte[] INITIAL_SEQ = [0xf0, 0xf0, 0x60, 0x00, 0xbf]; alias char*[] ByteDescription; struct Cmd { private ubyte[] data; static Cmd opCall() { static Cmd cmd; return cmd; } static Cmd opCall(ubyte[] d) { static Cmd cmd; cmd.data = d; return cmd; } void opAssign(ubyte cmd) { data[3] = cmd; if(cmd >= 0 && data[2] < 0x60) data[2] += 0x60; } void opAssign(Cmd cmd) { data = cmd.data; } @property ubyte value() { return data[3]; } alias value rawValue; string toString() { return toString(true); } string toString(bool colors) { ubyte v = data[3]; if(v > 0) return format("`+f%02X", v); else return "`+b--"; } string toPlainString() { ubyte v = data[3]; if(v > 0) return format("%02X", v); else return "--"; } } struct Ins { private ubyte[] data; static Ins opCall() { static Ins ins; return ins; } static Ins opCall(ubyte[] d) { static Ins ins; ins.data = d; return ins; } void opAssign(ubyte newins) { if(newins < 0x30) data[0] = cast(ubyte) (newins + 0xc0); else data[0] = cast(ubyte)0xf0; } void opAssign(Ins ins) { data = ins.data; } @property ubyte rawValue() { return data[0]; } @property ubyte value() { return cast(ubyte)(data[0] - 0xc0); } private alias value v; @property bool hasValue() { return value() < 0x30; } string toString() { if(v >= 0 && v < 0x30) return format("`+f%02X", v); else return "`+b--"; } string toPlainString() { alias value v; if(v >= 0 && v < 0x30) return format("%02X", v); else return "--"; } } struct Note { private ubyte[] data; static Note opCall(ubyte[] d) { static Note no; no.data = d; return no; } void opAssign(ubyte newnote) { if(newnote > 0x5e) newnote = 0x5e; data[2] = cast(ubyte)(newnote + 0x60); } void opAssign(Note note) { data = note.data; } @property ubyte rawValue() { return data[2]; } @property ubyte value() { return data[2] % 0x60; } private alias value v; @property bool isTied() { return data[1] == 0x5f; } void setTied(bool t) { data[1] = t ? 0x5f : 0xf0; } string toString(int trns) { string col, colh; if(isTied()) { col = "`4f"; colh = "`4b"; } else { col = "`0f"; colh = "`0b"; } switch(v) { case 0: return format("%s---", colh ); case 1: return format("%s===", col ); case 2: return format("%s+++", col ); default: if((v + trns) > 0x5e || (v + trns) < 0) return format("%s???", col); else return format("%s%s", col, NOTES[v + trns]); } } string toPlainString(int trns) { switch(v) { case 0: return "---"; case 1: return "==="; case 2: return "+++"; default: if((v + trns) > 0x5e || (v + trns) < 0) return "???"; else return NOTES[v + trns]; } } } struct Element { Ins instr; alias instr instrument; Cmd cmd; Note note; int transpose; ubyte[] data; static Element opCall(ubyte[] chunk) { static Element e; e.cmd = Cmd.opCall(chunk); e.instr = Ins(chunk); e.note = Note(chunk); e.data = chunk; return e; } string toString() { return toString(transpose); } string toString(int trans) { return format("%s`+0 %s %s", note.toString(trans), instr.toString(), cmd.toString()); } string toPlainString() { return format("%s %s %s", note.toPlainString(transpose), instr.toPlainString(), cmd.toPlainString()); } } struct Tracklist { private Track[] list; Track opIndex(int i) { if(i >= 0x400) i = 0; assert(i >= 0 && i < length); return list[i]; } static Tracklist opCall(Tracklist tl) { Tracklist t; t = tl; return t; } static Tracklist opCall(Track[] t) { Tracklist tl; tl.list = t; return tl; } Tracklist deepcopy() { auto copy = new Track[](list.length); foreach(idx, t; list) { auto tr = cast(ubyte)t.trans; auto number = cast(ubyte)t.number; copy[idx] = Track([tr, number]); } return Tracklist(copy); } void overwriteFrom(Tracklist tl) { for(int idx = 0; idx < tl.length; idx++) { auto tr = cast(ubyte)tl[idx].trans; auto number = cast(ubyte)tl[idx].number; list[idx].trans = tr; list[idx].number = number; } } void opIndexAssign(Track t, size_t il) { list[il] = t; } Track[] opSlice() { return list; } Tracklist opSlice(size_t x, size_t y) { return Tracklist(list[x .. y]); } int opApply(int delegate(ref Track) dg) { int result; for(int i = 0; i < trackLength; i++) { result = dg(list[i]); if(result) break; } return result; } int opApplyReverse(int delegate(ref Track) dg) { int result; for(int i = cast(int)(length - 1); i >= 0; i--) { result = dg(list[i]); if(result) break; } return result; } @property int length() { return cast(int) list.length; } @property void length(size_t il) { list.length = il; } @property Track lastTrack() { return list[trackLength]; } @property int trackLength() { int i; for(i = 0; i < length; i++) { Track t = list[i]; if(t.trans >= 0xf0) return i; } assert(0); } @property address wrapOffset() { return (lastTrack.smashedValue() / 2) & 0x7ff; } @property void wrapOffset(address offset) { if((offset & 0xff00) >= 0xf000) return; assert(offset >= 0 && offset < 0x400); if(offset >= trackLength) offset = cast(ushort)(trackLength - 1); offset *= 2; offset |= 0xf000; lastTrack() = [(offset & 0xff00) >> 8, offset & 0x00ff]; } void expand() { insertAt(trackLength); } void shrink() { deleteAt(trackLength-1); } // returns transpose value other than 0x80 above idx OR below(if idx == 0) ubyte getTransAt(int idx) { if(idx > 0) { do { if(list[idx].trans > 0x80 && list[idx].trans < 0xc0) return list[idx].trans; } while(idx-- > 0); } else if(idx == 0) { do { if(list[idx].trans > 0x80 && list[idx].trans < 0xc0) return list[idx].trans; } while(idx++ < trackLength); } return 0xa0; } void insertAt(int offset) { if(offset > list.length - 2) return; assert(offset >= 0 && offset < list.length); for(int i = cast(int)(list.length - 2); i >= offset; i--) { list[i+1] = list[i].dup; } list[offset].trans = getTransAt(offset); list[offset].number = 0; if(wrapOffset() >= offset) { wrapOffset = cast(address)(wrapOffset + 1); } } void deleteAt(int offset) { if(list[1].trans >= 0xf0) return; for(int i = offset; i < list.length - 2; i++) { list[i] = list[i+1].dup; } if(wrapOffset() >= offset) { wrapOffset = cast(address)(wrapOffset - 1); } } void transposeAt(int s, int e, int t) { foreach(trk; list[s .. e]) trk.transpose(t); } auto compact() { ubyte[] arr = new ubyte[1024]; int p, trans = -1, wrapptr = wrapOffset * 2; foreach(idx, track; list) { if(track.trans >= 0xf0) { wrapptr |= 0xf000; arr[p .. p + 2] = [(wrapptr & 0xff00) >> 8, wrapptr & 0x00ff]; p += 2; break; } if((track.trans != trans && track.trans != 0x80) || idx == wrapOffset) { trans = track.trans; arr[p++] = cast(ubyte)trans; } else if(idx < wrapOffset) { wrapptr--; } arr[p++] = track.number; } return arr[0..p]; } } struct Track { private ubyte[] data; static Track opCall(ubyte[] tr) { Track t; t.data = tr; assert(t.data.length == 2); return t; } void opAssign(ushort s) { data[0] = s & 255; data[1] = s >> 8; } void opAssign(ubyte[] d) { data[] = d[]; } void opAssign(Track tr) { data = tr.data; } @property void trans(ubyte t) { data[0] = t; } @property deprecated ushort dup() { return trans | (number << 8); } @property ushort smashedValue() { // "real" int value, trans = highbyte return number | (trans << 8); } @property ubyte trans() { return data[0]; } @property ubyte number() { return data[1]; } @property void number(ubyte no) { data[1] = no; } alias number trackNumber; void setValue(int tr, int no) { tr = clamp(tr, 0x80, 0xf3); if(no < 0) no = 0; if(no >= MAX_SEQ_NUM) no = MAX_SEQ_NUM-1; data[0] = tr & 255; data[1] = no & 255; } string toString() { string s = format("%02X%02X", trans, number); return s; } void transpose(int val) { if(trans == 0x80 || trans >= 0xf0) return; int t = trans + val; trans = (cast(ubyte)clamp(t, 0x80, 0xbf)); } } class Sequence { ElementArray data; int rows; static struct ElementArray { ubyte[] raw; Element opIndex(int i) { assert(i < MAX_SEQ_ROWS * 4); assert(i < (raw.length * 4)); ubyte[] chunk = raw[i * 4 .. i * 4 + 4]; return Element(chunk); } void opIndexAssign(int value, size_t il) { raw[il] = cast(ubyte)value; } int opApply(int delegate(Element) dg) { int result; for(int i = 0; i < length()/4; i++) { result = dg(opIndex(i)); if(result) break; } return result; } @property int length() { return cast(int)raw.length; } } this(ubyte[] d) { data = ElementArray(d); refresh(); if(rows*4+4 < 254) data.raw[rows*4 + 4 .. 254] = 0; } this(ubyte[] rd, int r) { data = ElementArray(rd); rows = r; } void refresh() { int p, r; // find seq length while(p < data.length) { ubyte b; b = data.raw[p+0]; if(b == SEQ_END_MARK) break; p += 4; r++; } rows = r; } override bool opEquals(Object o) const { auto rhs = cast(const Sequence)o; return (rhs && (data.raw[] == rhs.data.raw[])); } void clear() { data.raw[] = 0; data.raw[0..5] = [0xf0,0xf0,0x60,0x00,0xbf]; refresh(); } void expand(int pos, int r) { expand(pos, r, true); } void expand(int pos, int r, bool doInsert) { int i, len; int j; if(rows >= MAX_SEQ_ROWS) return; for(j=0;j= MAX_SEQ_ROWS) break; rows++; if(doInsert) insert(pos); else data.raw[(rows-1) * 4..(rows-1) * 4 + 4] = cast(ubyte[])CLEAR; } if(rows < 64) data.raw[rows*4] = SEQ_END_MARK; } void shrink(int pos, int r, bool doRemove) { if(rows <= 1 || pos >= rows - 1) return; for(int j = 0; j < r; j++) { if(doRemove) remove(pos); // clear endmark data.raw[rows * 4 .. $] = 0; rows--; data.raw[rows * 4 .. rows * 4 + 4] = cast(ubyte[])[ SEQ_END_MARK, 0, 0, 0 ]; } } void transpose(int r, int n) { for(int i = r; i < rows;i++) { Note note = data[i].note; int v = note.value; if(v < 3) continue; if(n >= 0 && (v+n) < 0x60) v += n; if(n < 0 && (v+n) >= 3) v += n; note = cast(ubyte) v; } } void insert(int pos) { int p1 = pos * 4; int p2 = rows * 4; if(p2 > 256) return; ubyte[] c = data.raw[p1 .. p2]; ubyte[] n = c.dup; c[4..$] = n[0..$-4].dup; // clear cursor pos c[0..4] = cast(ubyte[])CLEAR; } void remove(int pos) { ubyte[] tmp; int start = pos * 4; int end = rows * 4; tmp = data.raw[start + 4 .. end].dup; data.raw[start .. end - 4] = tmp; data.raw[end - 4 .. end] = cast(ubyte[])CLEAR; } void copyFrom(Sequence f) { rows = f.rows; data.raw[] = f.data.raw[].dup; } // insert seq f to offset ofs void insertFrom(Sequence f, int ofs) { // make temporary copy so that seq can be appended over itself Sequence copy = new Sequence(f.data.raw.dup); expand(ofs, f.rows); int max = MAX_SEQ_ROWS*4; int st = ofs * 4; int len = copy.rows * 4; int end = st + len; if(end >= max) { end = max; len = end - st; } data.raw[st .. end] = copy.data.raw[0..len]; } ubyte[] compact() { ubyte[] outarr = new ubyte[257]; int i, outp, olddel, oldins = -1, olddelay = -1, delay; for(i = 0; i < rows;) { Element e = data[i]; bool cmd = false; int note = e.note.rawValue; if(note >= 0x60 && e.cmd.rawValue > 0) cmd = true; else { if(note >= 0x60) note -= 0x60; } if(e.instr.value < 0x30 && oldins != e.instr.value) { oldins = e.instr.value; outarr[outp++] = cast(ubyte)(e.instr.value + 0xc0); } // calc delay delay = 0; for(int j = i + 1; j < rows; j++) { Element ee = data[j]; if((ee.note.rawValue % 0x60) == 0 && ee.cmd.rawValue == 0 && !ee.instr.hasValue()) { delay++; i++; } else break; } if(olddelay != delay) { olddelay = delay & 15; outarr[outp++] = cast(ubyte)(delay | 0xf0); olddelay = delay & 15; delay -= delay & 15; } if(e.note.isTied()) outarr[outp++] = 0x5f; outarr[outp++] = cast(ubyte)note; if(cmd) outarr[outp++] = cast(ubyte)(e.cmd.rawValue); while(delay > 15) { int d = delay; if(d > 15) d = 15; if(olddelay != d) { outarr[outp++] = cast(ubyte)(d | 0xf0); olddelay = d; } outarr[outp++] = cast(ubyte)0; delay -= 16; } i++; } outarr[outp++] = cast(ubyte)SEQ_END_MARK; return outarr[0..outp]; } } class Song { enum DatafileOffset { Binary, Header = 65536, Title = Header + 256 + 5, Author = Title + 32, Release = Author + 32, Insnames = Title + 40 * 4, Subtunes = Insnames + 1024 * 2 } private struct Features { ubyte requestedTables; ubyte[8] instrumentFlags; ubyte[16] cmdFlags; } private struct Patch { string name; ubyte[] def, wave1, wave2, filt, pulse; } static struct Chunk { int offset; ubyte[] wave1, wave2; bool used; int tokill; string toString() { return format("%x", offset); } // TODO implement .dup which copies arrasys as well Chunk dup() { assert(0); } } static class Table { ubyte[] data; this(ubyte[] data) { this.data = data; } int size() { foreach_reverse(idx, val; data) { if(val != 0) return cast(int)(idx + 1); } return 0; } int length() { return cast(int)data.length; } ubyte[] opSlice() { return data; } ubyte[] opSlice(size_t x, size_t y) { return data[x..y]; } } class WaveTable : Table { struct WaveProgram { ubyte[] wave1, wave2; int offset; } // info for each waveprogram ubyte[] wave1, wave2; this(ubyte[] data) { super(data); wave1 = data[0 .. 256]; wave2 = data[256 .. 512]; } int seekTableEnd() { for(int i = 255; i >= 1; i--) { if(wave1[i-1] != 0) { return i; } } return 0; } Chunk[] getChunks() { return getChunks(data); } Chunk[] getChunks(ubyte[] wavetab) { /+ static +/ Chunk[] chunks = new Chunk[256]; int counter; for(int i = 0, b; i < 256; i++) { if(wavetab[i] == 0x7f || wavetab[i] == 0x7e) { chunks[counter] = Chunk(b, wavetab[b .. i + 1], wavetab[b + 256 .. i + 256 + 1]); b = i + 1; counter++; } } return chunks[0 .. counter]; } bool isValid(int waveOffset) { auto chunks = getChunks(data); return whichCell(chunks, waveOffset) >= 0; } // get program starting at waveOffset // mostly copied from purgeWave WaveProgram getProgram(int waveOffset) { auto chunks = getChunks(data.dup); int topRow = 255; int cell = whichCell(chunks, waveOffset); if(cell < 0) throw new Error("Illegal waveprogram offset"); markCells(chunks, cell); WaveProgram wp; /+ get top row in used chunks, needed to recalc arpofs NB might be necessary to calc last +/ foreach(ref chunk; chunks) { if(chunk.used && chunk.offset < topRow) topRow = chunk.offset; } /+ generate arrays +/ foreach(ref chunk; chunks) { if(!chunk.used) { if(waveOffset >= chunk.offset) waveOffset -= cast(int)chunk.wave1.length; foreach(ref chunk2; chunks) { if(chunk2.wave1[$ - 1] == 0x7f && chunk2.wave2[$ - 1] >= chunk.offset) { // check that 7f-xx is not pointing WITHIN this chunk //assert(chunk2.wave2[$ - 1] > chunk.offset + chunk.wave1.length); // calc wrap int t = chunk2.wave2[$ - 1] - cast(int)chunk.wave1.length; t = com.util.clamp(t, 0, 256); chunk2.wave2[$ - 1] = cast(ubyte)t; } if(chunk2.offset >=chunk.offset) chunk2.offset -= chunk.wave1.length; } } } foreach(ref chunk; chunks) { if(!chunk.used) continue; wp.wave1 ~= chunk.wave1; wp.wave2 ~= chunk.wave2; assert(wp.wave1[$-1] == 0x7f || wp.wave1[$-1] == 0x7e); } wp.offset = waveOffset; return wp; } static int whichCell(Chunk[] chunks, int ptr) { foreach(idx, chunk; chunks) { int b = chunk.offset, e = cast(int)(chunk.offset + chunk.wave1.length); if(ptr >= b && ptr < e) { return cast(int)idx; } } return -1; } static void markCells(Chunk[] chunks, int cell) { assert(cell >= 0 && cell < chunks.length); for(;;) { if(chunks[cell].used) break; chunks[cell].used = true; Chunk c = chunks[cell]; assert(c.wave1[$-1] == 0x7e || c.wave1[$-1] == 0x7f); if(c.wave1[$-1] == 0x7e) break; cell = whichCell(chunks, c.wave2[$-1]); if(cell < 0) break; } } void deleteRow(Song song, int pos) { deleteRow(song, pos, 1); } void deleteRow(Song song, int pos, int num) { for(int n = 0; n < num; n++) { int i; assert(pos < 255 && pos >= 0); for(i = pos; i < 255; i++) { wave1[i] = wave1[i + 1]; wave2[i] = wave2[i + 1]; } for(i=0;i < 256;i++) { if((wave1[i] == 0x7f || wave1[i] == 0x7e) && wave2[i] >= pos) { if(wave2[i] > 0) --wave2[i]; } } arpPointerUpdate(song, pos, -1); } } void insertRow(Song song, int pos) { int i; for(i = 254; i >= pos; i--) { wave1[i + 1] = wave1[i]; wave2[i + 1] = wave2[i]; } for(i=0;i<256;i++) { if(wave1[i] == 0x7f && wave2[i] >= pos) wave2[i]++; } wave1[pos] = 0; wave2[pos] = 0; arpPointerUpdate(song, pos, 1); } private void arpPointerUpdate(Song song, int pos, int val) { for(int j = 0; j < 48; j++) { ubyte b7 = instrumentTable[j + 7 * 48]; if(b7 > pos) { int v = b7 + val; if(v < 0) v = 0; // TODO rewrite not to access global.. instrumentTable[j + 7 * 48] = cast(ubyte)v; } } } } class InstrumentTable : Table { this(ubyte[] data) { super(data); } ubyte[] getInstrument(int no) { ubyte[] arr = new ubyte[8]; for(int i = 0; i < 8 ; i++) { arr[i] = data[no + i * 48]; } return arr; } } class SweepTable : Table { this(ubyte[] data) { super(data); } struct SweepProgram { int offset; ubyte[] data; } bool isValid(int currentRow) { if(currentRow >= 0x80 && currentRow < 0x90) return true; bool[0x40] visited; for(int row = currentRow; row < 0x40;) { if(visited[row]) return true; visited[row] = true; int jumpValue = data[row * 4 + 3]; if(jumpValue > 0x3f && jumpValue != 0x7f) // if illegal, break return false; if(jumpValue == 0x7f) return true; else if(jumpValue == 0) row++; else row = jumpValue; } return false; } SweepProgram getProgram(int currentRow) { bool[0x40] visited; int topRow = currentRow; for(int row = currentRow; row < 0x40;) { if(row < topRow) topRow = row; if(visited[row]) break; visited[row] = true; int jumpValue = data[row * 4 + 3]; if(jumpValue > 0x3f && jumpValue != 0x7f) // if illegal, break break; if(jumpValue == 0x7f) break; // if loops or ends, break else if(jumpValue == 0) row++; else row = jumpValue; } int toremove; ubyte[] copy = data.dup; foreach(idx, vis; visited) { if(!vis && idx > 0) { for(int i = 1; i < 64; i++) { int jumpval = data[i * 4 + 3]; if(jumpval < 0x40 && jumpval >= idx) { copy[i * 4 + 3]--; } } if(currentRow >= idx) ++toremove; //--currentRow; } } ubyte[] arr; foreach(idx, vis; visited) { if(vis) { arr ~= copy[idx * 4 .. idx * 4 + 4]; } } assert(arr[$-1] > 0); return SweepProgram(currentRow - toremove, arr); } int seekTableEnd() { for(int i = 0x3c; i >= 0; i -= 4) { if(data[i + 3] > 0) { return i / 4 + 1; } } return 0; } } private class Subtunes { ubyte[1024][3][32] subtunes; private int active; this() { initArray(); } this(ubyte[] arr) { ubyte[] subts; this(); subts = cast(ubyte[])(&subtunes)[0..1]; subts[] = arr; } @property int numOf() { foreach_reverse(idx, ref tune; subtunes) { foreach(ref voice; tune) { if(voice[1 .. 4] != cast(ubyte[])[0x00, 0xf0, 0x00]) { return cast(int)(idx + 1); } } } return 0; } private void initArray() { foreach(ref tune; subtunes) { foreach(ref voice; tune) { voice[0 .. 2] = cast(ubyte[])[0xa0, 0x00]; for(int i = 2; i < voice.length; i += 2) { voice[i .. i+2] = cast(ubyte[])[0xf0, 0x00]; } } } } void clearAll() { initArray(); syncFromBuffer(); } void clear(int no) { foreach(ref voice; subtunes[no]) { voice[0 .. 2] = cast(ubyte[])[0xa0, 0x00]; for(int i = 2; i < voice.length; i += 2) { voice[i .. i+2] = cast(ubyte[])[0xf0, 0x00]; } } if(no == active) syncFromBuffer(); } void swap(int targetNo, int sourceNo) { if(targetNo == sourceNo) return; if(targetNo == active || sourceNo == active) sync(); ubyte[1024][3] sourcebuf, targetbuf; for(int i = 0; i < 3; i++) { targetbuf[i][] = subtunes[targetNo][i][]; subtunes[targetNo][i][] = subtunes[sourceNo][i][]; subtunes[sourceNo][i][] = targetbuf[i][]; } ubyte spdtemp = songspeeds[targetNo]; songspeeds[targetNo] = songspeeds[sourceNo]; songspeeds[sourceNo] = spdtemp; if(active == targetNo || active == sourceNo) syncFromBuffer(); } private void syncFromBuffer() { for(int i = 0; i < 3; i++) { data[offsets[Offsets.Track1 + i] .. offsets[Offsets.Track1 + i] + 0x400] = subtunes[active][i][0..0x400]; } } Tracklist[] opIndex(int n) { static Tracklist[3] tr; for(int i=0;i<3;i++) { tr[i].length = TRACK_LIST_LENGTH; } for(int i = 0; i < 3 ; i++) { ubyte[] b; // use array from c64 memory if getting current subtune if(n == active) b = buffer[offsets[Offsets.Track1 + i] .. offsets[Offsets.Track1 + i] + 0x400]; else b = subtunes[n][i][0..0x400]; for(int j = 0; j < b.length / 2; j++) { tr[i][j] = Track(b[j * 2 .. j * 2 + 2]); } } return tr; } void activate(int n) { activate(n, true); } void activate(int n, bool dosync) { if(n > 0x1f || n < 0) return; if(dosync) sync(); active = n; for(int i = 0; i < 3; i++) { buffer[offsets[Offsets.Track1 + i] .. offsets[Offsets.Track1 + i] + 0x400] = subtunes[active][i][0..0x400]; } if(ver >= 6) speed = songspeeds[active]; } /* sync "external" subtune array to active one (stored in c64s mem) * the correct way would be to let trackinput also update the external array */ private void sync() { for(int i = 0; i < 3; i++) { subtunes[active][i][0..0x400] = buffer[offsets[Offsets.Track1 + i] .. offsets[Offsets.Track1 + i] + 0x400]; } } // highly dubious coding here (actually, like in most of this class..) ubyte[][][] compact() { ubyte[][][] arr; arr.length = numOf(); foreach(ref subarr; arr) { subarr.length = 3; } for(int i = 0; i < numOf(); i++) { ubyte[][] subarr = arr[i]; for(int j = 0; j < 3; j++) { buffer[offsets[Offsets.Track1 + j] .. offsets[Offsets.Track1 + j] + 0x400] = subtunes[i][j][0..0x400]; } foreach(idx, ref voice; subarr) { voice = tracks[idx].compact().dup; } } return arr; } } int ver = SONG_REVISION, clock, multiplier = 1, sidModel, fppres; char[32] title = ' ', author = ' ', release = ' ', message = ' '; char[32][48] insLabels; private Features features; CPU cpu; ubyte[] sidbuf; ubyte[65536] data; alias data buffer; alias data memspace; Tracklist[] tracks; Sequence[] seqs; alias seqs sequences; address[] offsets; ubyte[32] songspeeds; ubyte[] songsets, wave1Table, wave2Table, waveTable, instrumentTable, pulseTable, filterTable, superTable, chordTable, chordIndexTable, seqlo, seqhi; ByteDescription instrumentByteDescriptions, pulseDescriptions, filterDescriptions, waveDescriptions, cmdDescriptions; // dupes of raw tables above, will eventually update all code to use these Table tSongsets, tSuper, tChord, tChordIndex, tSeqlo, tSeqhi; InstrumentTable tInstr; WaveTable tWave; SweepTable tPulse, tFilter; Table tTrack1, tTrack2, tTrack3; Table[string] tables; char[] playerID; int subtune; Subtunes subtunes; // these used to be sequencer vars but they're here now since they get saved with the tune int highlight = 4, highlightOffset = 0; private auto playerBinary = cast(ubyte[])import("player.bin"); this() { this(playerBinary); } this(ubyte[] player) { cpu = new CPU(buffer); subtunes = new Subtunes(); foreach(ref desc; insLabels) { desc[] = 0x20; } ver = SONG_REVISION; ubyte[] bin; bin.length = 65536; bin[0xdfe .. 0xdfe + player.length] = player; if(bin[0xdfe .. 0xe00] != cast(ubyte[])[ 0x00, 0x0e ]) throw new UserException("Illegal loading address."); songspeeds[] = 5; initialize(bin); sidbuf = memspace[0xd400 .. 0xd419]; } @property int numOfSeqs() { int upto; foreach(i, s; seqs) { if(s.data.raw[0 .. 5] != INITIAL_SEQ) upto = cast(int)i; } return upto + 1; } @property int speed() { return memspace[offsets[Offsets.SPEED]]; } @property void speed(int spd) { memspace[offsets[Offsets.Songsets] + 6] = cast(ubyte)spd; memspace[offsets[Offsets.SPEED]] = cast(ubyte)spd; songspeeds[subtune] = cast(ubyte)spd; if(ver >= 5 && spd >= 2) memspace[offsets[Offsets.PlaySpeed]] = cast(ubyte)spd; } @property int playSpeed() nothrow { return memspace[offsets[Offsets.PlaySpeed]]; } @property int numInstr() { int maxInsno; seqIterator((Sequence s, Element e) { int insval = e.instr.value; if(insval > 0x2f) return; if(insval > maxInsno) maxInsno = insval; }); return maxInsno; } void open(string fn) { ubyte[] inbuf = cast(ubyte[])read(fn); if(inbuf[0..3] != cast(ubyte[])"CC2"[0..3]) { throw new UserException(format("%s: Incorrect filetype.", fn)); } ubyte[] debuf = cast(ubyte[])std.zlib.uncompress(inbuf[3..$],167832); int offset = 65536; ver = debuf[offset++]; if(ver < 6) throw new UserException("The song is incompatible (too old) for this version of the editor."); if(ver >= 128) throw new UserException("The song appears to be a stereo SID file and doesn't work with this editor."); clock = debuf[offset++]; multiplier = debuf[offset++]; sidModel = debuf[offset++]; fppres = debuf[offset++]; if(ver >= 6) { songspeeds[0..32] = debuf[offset .. offset+32]; offset += 32; } if(ver > 10) { highlight = debuf[offset++]; highlightOffset = debuf[offset++]; } offset = DatafileOffset.Title; title[0..32] = cast(char[])debuf[offset .. offset + 32]; author[0..32] = cast(char[])debuf[offset + 32 .. offset + 64]; release[0..32] = cast(char[])debuf[offset + 64 .. offset + 96]; offset += 40 * 4; assert(DatafileOffset.Insnames == offset); offset = DatafileOffset.Insnames; ubyte[] insnames = cast(ubyte[])(&insLabels)[0..1]; insnames[] = debuf[offset .. offset + 48*32]; assert(DatafileOffset.Subtunes == offset + 1024 * 2); offset += 1024 * 2; int len = 1024*3*32; subtunes = new Subtunes(debuf[offset .. offset + len]); offset += len; initialize(debuf[0..65536]); } void setMultiplier(int m) { assert(m > 0 && m < 16); multiplier = m; memspace[Offsets.Volume + 1] = cast(ubyte)m; } protected void initialize(ubyte[] buf) { int voi, ofs; data[] = buf; offsets.length = 0x60; seqs.length = MAX_SEQ_NUM; tracks.length = 3; for(int i = 0; i < 3; i++) { tracks[i].length = TRACK_LIST_LENGTH; } for(int i = 0; i < OFFSETTAB_LENGTH; i++) { offsets[i] = data[0xfa0+i*2] | (data[0xfa1+i*2] << 8); } for(int no = 0; no < MAX_SEQ_NUM; no++) { int p, lo, hi; int lobyt = offsets[Offsets.SeqLO] + no, hibyt = offsets[Offsets.SeqHI] + no; p = data[lobyt] + (data[hibyt] << 8); ubyte[] raw_seq_data = data[p .. p+256]; seqs[no] = new Sequence(raw_seq_data); } for(voi = 0; voi < 3; voi++) { ubyte[] b; int t; int offset = offsets[Offsets.Track1 + voi]; b = data[offset .. offset + 0x400]; for(int i = 0; i < b.length/2; i++) { tracks[voi][i] = Track(memspace[offset + i * 2 .. offset + i * 2 + 2]); } } ofs = offsets[Offsets.Songsets]; songsets = data[ofs .. ofs + 256]; tSongsets = new Table(songsets); ofs = offsets[Offsets.Arp1]; wave1Table = data[ofs .. ofs + 256]; wave2Table = data[ofs + 256 .. ofs + 512]; waveTable = data[ofs .. ofs + 512]; // tWave1 = new Table(wave1Table); // tWave2 = new Table(wave2Table, ofs + 256); tWave = new WaveTable(waveTable); ofs = offsets[Offsets.Inst]; instrumentTable = data[ofs .. ofs + 512]; tInstr = new InstrumentTable(instrumentTable); ofs = offsets[Offsets.CMD1]; superTable = data[ofs .. ofs + 256]; tSuper = new Table(superTable); ofs = offsets[Offsets.PULSTAB]; pulseTable = data[ofs .. ofs + 256]; tPulse = new SweepTable(pulseTable); ofs = offsets[Offsets.FILTTAB]; filterTable = data[ofs .. ofs + 256]; tFilter = new SweepTable(filterTable); ofs = offsets[Offsets.SeqLO]; seqlo = data[ofs .. ofs + 256]; tSeqlo = new Table(seqlo); ofs = offsets[Offsets.SeqHI]; seqhi = data[ofs ..ofs + 256]; tSeqhi = new Table(seqhi); ofs = offsets[Offsets.ChordTable]; chordTable = data[ofs .. ofs + 128]; tChord = new Table(chordTable); ofs = offsets[Offsets.ChordIndexTable]; chordIndexTable = data[ofs .. ofs + 32]; tChordIndex = new Table(chordIndexTable); generateChordIndex(); ofs = offsets[Offsets.Track1]; tTrack1 = new Table(data[ofs .. ofs + 0x400]); ofs = offsets[Offsets.Track2]; tTrack2 = new Table(data[ofs .. ofs + 0x400]); ofs = offsets[Offsets.Track3]; tTrack3 = new Table(data[ofs .. ofs + 0x400]); playerID = cast(char[])data[0xfee .. 0xff5]; subtune = 0; ofs = offsets[Offsets.Features]; ubyte[] b = memspace[ofs .. ofs + 64]; features.requestedTables = b[0]; features.instrumentFlags[] = b[1..9]; /* ubyte* b = cast(ubyte*)&features; b[0..features.sizeof] = memspace[ofs .. ofs + features.sizeof]; */ if(ver > 7) { instrumentByteDescriptions.length = 8; ofs = offsets[Offsets.InstrumentDescriptionsHeader]; for(int j = 0; j < 8; j++) { int iofs = memspace[ofs] | (memspace[ofs+1] << 8); instrumentByteDescriptions[j] = cast(char*)&memspace[iofs]; ofs += 2; } } if(ver > 8) { int offset; filterDescriptions.length = 4; offset = offsets[Offsets.FilterDescriptionsHeader]; foreach(idx, ref descr; filterDescriptions) { int soffset = memspace[offset + idx * 2] | (memspace[offset + idx * 2 + 1] << 8); descr = cast(char*)&memspace[soffset]; } pulseDescriptions.length = 4; offset = offsets[Offsets.PulseDescriptionsHeader]; foreach(idx, ref descr; pulseDescriptions) { int soffset = memspace[offset + idx * 2] | (memspace[offset + idx * 2 + 1] << 8); descr = cast(char*)&memspace[soffset]; } waveDescriptions.length = 2; offset = offsets[Offsets.WaveDescriptionsHeader]; foreach(idx, ref descr; waveDescriptions) { int soffset = memspace[offset + idx * 2] | (memspace[offset + idx * 2 + 1] << 8); descr = cast(char*)&memspace[soffset]; } cmdDescriptions.length = 2; offset = offsets[Offsets.CmdDescriptionsHeader]; foreach(idx, ref descr; cmdDescriptions) { int soffset = memspace[offset + idx * 2] | (memspace[offset + idx * 2 + 1] << 8); descr = cast(char*)&memspace[soffset]; } } subtunes.syncFromBuffer(); speed = songspeeds[0]; cpu.reset(); cpu.execute(0x1000); tables = [ cast(string)"songsets":tSongsets, "wave":tWave, "instr":tInstr, "pulse":tPulse, "filter":tFilter, "cmd":tSuper, "chord":tChord, "chordidx":tChordIndex, "seqlo":tSeqlo, "seqhi":tSeqhi ]; } void save(string fn) { // get tracks from the c64 memory to subtunes-array subtunes.sync(); ubyte[] b; int offset; b.length = 300000; b[0..65536] = memspace; offset += 65536; foreach(val; [ver, clock, multiplier, sidModel, fppres]) { b[offset++] = val & 255; } b[offset .. offset+32] = songspeeds[]; offset += 32; b[offset++] = cast(ubyte)highlight; b[offset++] = cast(ubyte)highlightOffset; offset = DatafileOffset.Title; foreach(str; [title, author, release, message]) { b[offset .. offset + 32] = cast(ubyte[])str[]; offset += 32; } offset = DatafileOffset.Insnames; ubyte[] arr; arr = cast(ubyte[])(&insLabels)[0..1]; b[offset .. offset + arr.length] = arr[]; offset += arr.length; offset += 32 * 32 - 0x200; arr = cast(ubyte[])(&subtunes.subtunes)[0..1]; b[offset .. offset + arr.length] = arr[]; offset += arr.length; std.file.write(fn, "CC2"); append(fn, std.zlib.compress(b)); } void splitSequence(int seqnumber, int seqofs) { if(seqnumber == 0 || seqofs == 0) return; int suborig = subtune; int newseqnumber = getFreeSequence(0); Sequence s = seqs[seqnumber]; if(seqofs == s.rows - 1) return; Sequence copy = new Sequence(s.data.raw.dup); Sequence ns = seqs[newseqnumber]; ns.copyFrom(s); ns.shrink(0, seqofs, true); s.shrink(seqofs, s.rows - seqofs, true); subtunes.sync(); foreach(sIdx, st; subtunes.subtunes) { subtunes.activate(cast(int)sIdx); foreach(vIdx, voice; tracks) { for(int tIdx = voice.length - 1; tIdx >= 0; tIdx--) { Track t = voice[tIdx]; if(t.number == seqnumber) { tracks[vIdx].insertAt(tIdx+1); Track t2 = tracks[vIdx][tIdx+1]; t2.trans = 0x80; t2.number = (cast(ubyte)newseqnumber); } } } } subtunes.activate(suborig); } private int getTablepointer(ubyte[] table, ubyte[] flags, int requestedFlag, int insno) { foreach(i, flag; flags) { if(flag != requestedFlag) continue; return table[insno + i * 48]; } throw new UserException(std.string.format("Missing tablepointer %d", requestedFlag)); } int wavetablePointer(int insno) { return getTablepointer(instrumentTable, features.instrumentFlags, 1, insno); } int pulsetablePointer(int insno) { int ptr = getTablepointer(instrumentTable, features.instrumentFlags, 3, insno); if(ptr >= 0x80) return 0; return ptr; } int filtertablePointer(int insno) { return getTablepointer(instrumentTable, features.instrumentFlags, 4, insno); } void seqIterator(void delegate(Sequence s, Element e) dg) { foreach(i, s; seqs) { for(int j = 0; j < s.rows; j++) { Element e = s.data[j]; dg(s, e); } } } void seqIterator(void delegate(int seqno, Sequence s, Element e) dg) { foreach(i, s; seqs) { for(int j = 0; j < s.rows; j++) { Element e = s.data[j]; dg(cast(int)i, s, e); } } } void trackIterator(void delegate(Track t) dg) { for(int sidx = 0; sidx < 32; sidx++) { Tracklist[] subtune = subtunes[sidx]; foreach(voice; subtune) { foreach(track; voice) { dg(track); } } } } void tableIterator(void delegate(Table t) dg) { foreach(idx, table; [ "wave", "cmd", "instr", "chord", "pulse", "filter"]) { dg(tables[table]); } } void setVoicon(shared int[] m) { //setVoicon(m[0], m[1], m[2]); buffer[offsets[Offsets.VOICE]+0] = m[0] ? 0x19 : 0x00; buffer[offsets[Offsets.VOICE]+1] = m[1] ? 0x19 : 0x07; buffer[offsets[Offsets.VOICE]+2] = m[2] ? 0x19 : 0x0e; } int getFreeSequence(int start) { bool seqUsed; subtunes.sync(); for(int seqnum = start; seqnum < MAX_SEQ_NUM; seqnum++) { seqUsed = false; foreach(ist, st; subtunes.subtunes) { foreach(voice; st) { foreach(t; voice) { if(t == seqnum) seqUsed = true; } } } if(!seqUsed) return seqnum; } return -1; } void clearSeqs() { for(int i = 1; i < MAX_SEQ_NUM; i++) { seqs[i].clear(); } subtunes.clearAll(); } void incSubtune() { if(subtune < 31) subtunes.activate(++subtune); } void decSubtune() { if(subtune > 0) subtunes.activate(--subtune); } void generateChordIndex() { int crd, p; for(int i = 0; i < 128; i++) { if(chordTable[i] >= 0x80) { chordIndexTable[crd] = cast(ubyte)p; if(++crd >= 31) throw new Error("Chord index overflow"); p = i + 1; } } chordIndexTable[crd++] = cast(ubyte)(p); } void importData(Song insong) { buffer[0xdfe .. 0xdfe + playerBinary.length] = playerBinary[]; ver = SONG_REVISION; initialize(buffer.dup); // copy tables foreach(idx, table; [ "wave", "cmd", "instr", "chord", "pulse", "filter"]) { tables[table].data[] = insong.tables[table].data; } // sequences foreach(idx, ref seq; insong.seqs) { seqs[idx].data.raw[] = seq.data.raw; seqs[idx].refresh(); } // subtunes subtunes.subtunes[][][] = insong.subtunes.subtunes[][][]; subtunes.syncFromBuffer(); // labels insLabels[] = insong.insLabels[]; title[] = insong.title[]; author[] = insong.author[]; release[] = insong.release[]; // vars clock = insong.clock; multiplier = insong.multiplier; sidModel = insong.sidModel; fppres = insong.fppres; songspeeds = insong.songspeeds[]; speed = songspeeds[0]; // TODO highlight, highlightoffset generateChordIndex(); subtunes.activate(0); } // hack to help sequencer rowcounting Sequence sequence(Track t) { return seqs[t.number]; } void savePatch(string filename, int no) { import std.conv; string insname = std.string.stripRight (to!string(insLabels[no])); int waveptr = wavetablePointer(no); int pulseptr = pulsetablePointer(no); int filtptr = filtertablePointer(no); if(!tWave.isValid(waveptr)) { throw new UserException("Cannot save; instrument is not valid (wavetable does not wrap)."); } if(!tPulse.isValid(pulseptr)) { throw new UserException("Cannot save; pulse is not valid."); } if(!tFilter.isValid(filtptr)) { throw new UserException("Cannot save; filter is not valid."); } auto wp = tWave.getProgram(waveptr); auto pp = tPulse.getProgram(pulseptr); auto fp = tFilter.getProgram(filtptr); // rewrite pointers. TODO: move elsewhere auto instr = tInstr.getInstrument(no); instr[7] = cast(ubyte)wp.offset; // skipping 0-rows since it implies inactive sweep if(pp.offset > 0) instr[5] = cast(ubyte)pp.offset; if(fp.offset > 0) instr[4] = cast(ubyte)fp.offset; string csv = to!string(playerID[0..6]) ~ "`" ~ insname ~ "`" ~ com.util.arr2str(instr) ~ "`" ~ com.util.arr2str(wp.wave1) ~ "`" ~ com.util.arr2str(wp.wave2) ~ "`" ~ (pulseptr > 0 ? com.util.arr2str(pp.data) : "") ~ "`" ~ (filtptr > 0 ? com.util.arr2str(fp.data) : ""); if(filename is null) { filename = com.util.fnClean(insname ~ ".cti"); } std.file.write(filename, csv); } void insertPatch(string filename, int insno) { import std.csv : csvReader; auto conv(string s) { ubyte[] arr = new ubyte[s.length / 2]; for(int i = 0, j = 0; i < s.length; i += 2, j++) { arr[j] = cast(ubyte)com.util.convertHex(s[i .. i + 2]); } return arr; } struct Rec { string playerid, name, def, wave1, wave2, pulse, filt; } string patch = cast(string)std.file.read(filename); auto recs = csvReader!Rec(patch,'`'); foreach(rec; recs) { auto p = new Purge(this); p.deleteInstrument(insno); insertInstrument(Patch(rec.name, conv(rec.def), conv(rec.wave1), conv(rec.wave2), conv(rec.filt), conv(rec.pulse)), insno); if(rec.name.length > 31) rec.name.length = 31; insLabels[insno][] = ' '; insLabels[insno][0..rec.name.length] = rec.name; // break because only 1st row needed (though there should never be more) break; } } private void insertInstrument(Patch patch, int insno) { assert(patch.wave1.length == patch.wave2.length); // check for free space in tables int waveptr = tWave.seekTableEnd(); int pulseptr = tPulse.seekTableEnd() * 4; int filterptr = tFilter.seekTableEnd() * 4; if(patch.wave1.length + waveptr > tWave.wave1.length - 1) throw new UserException("Not enough free rows in wavetable"); if(patch.pulse.length + pulseptr > tPulse.data.length - 4) throw new UserException("Not enough free rows in pulse table"); if(patch.filt.length + filterptr > tFilter.data.length - 4) throw new UserException("Not enough free rows in filter table"); // cram loaded data into tables ubyte[] wave1 = tWave.wave1[waveptr .. waveptr + patch.wave1.length]; ubyte[] wave2 = tWave.wave2[waveptr .. waveptr + patch.wave2.length]; for(int i = 0; i < wave1.length; i++) { if(wave1[i] == 0x7f) wave2[i] += waveptr; } wave1[0..$] = patch.wave1[]; wave2[0..$] = patch.wave2[]; // ---------------------------------------- void fixSweepOffsets(ubyte[] table, int offset) { for(int i = 0; i < table.length; i += 4) { if(table[i + 3] > 0 && table[i + 3] < 0x40) { table[i + 3] += offset; assert(table[i + 3] < 0x40); } } } // insert pulse program if defined if(patch.def[5] > 0) { ubyte[] pulse = tPulse.data[pulseptr .. $]; fixSweepOffsets(pulse, pulseptr + patch.def[5]); tPulse.data[pulseptr .. pulseptr + patch.pulse.length] = patch.pulse[]; for(int i = 0; i < pulse.length - 4; i += 4) { if(pulse[i + 3] > 0 && pulse[i + 3] < 0x40) { pulse[i + 3] += pulseptr / 4 - 1; } } patch.def[5] += pulseptr / 4 - 1; } // insert filter if defined if(patch.def[4] > 0) { ubyte[] filt = tFilter.data[filterptr .. $]; fixSweepOffsets(filt, filterptr + patch.def[4]); tFilter.data[filterptr .. filterptr + patch.filt.length] = patch.filt[]; for(int i = 0; i < filt.length; i += 4) { if(filt[i + 3] > 0 && filt[i + 3] < 0x40) { filt[i + 3] += filterptr / 4 - 1; } } patch.def[4] += filterptr / 4 - 1; } // recalc wrap points for inserted data for(int i = 0; i < wave1.length; i++) { if(wave1[i] == 0x7f) wave2[i] += waveptr; } patch.def[7] += waveptr; for(int i = 0; i < 8; i++) { instrumentTable[i * 48 + insno] = patch.def[i]; } } } CheeseCutter-2.10/src/ct/build.d000066400000000000000000000215521516216315000164650ustar00rootroot00000000000000/* CheeseCutter v2 (C) Abaddon. Licensed under GNU GPL. */ module ct.build; import ct.base; import ct.dump; import com.cpu; import com.util; import std.stdio; import std.string; import std.conv; import core.stdc.string; import core.stdc.stdlib; import std.array; extern(C) { extern char* acme_assemble(const char*,int*,char*); } static const string playerSource = import("player_v4.acme"); const ubyte[] SIDHEADER = [ 0x50, 0x53, 0x49, 0x44, 0x00, 0x02, 0x00, 0x7c, 0x00, 0x00, 0x10, 0x00, 0x10, 0x03, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x53, 0x77, 0x61, 0x6d, 0x70, 0x20, 0x50, 0x6f, 0x6f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x54, 0x68, 0x6f, 0x6d, 0x61, 0x73, 0x20, 0x4d, 0x6f, 0x67, 0x65, 0x6e, 0x73, 0x65, 0x6e, 0x20, 0x28, 0x44, 0x52, 0x41, 0x58, 0x29, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x32, 0x30, 0x30, 0x34, 0x20, 0x4d, 0x61, 0x6e, 0x69, 0x61, 0x63, 0x73, 0x20, 0x6f, 0x66, 0x20, 0x4e, 0x6f, 0x69, 0x73, 0x65, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x00 ]; enum { PSID_LOAD_ADDR_OFFSET = 0x08, PSID_INIT_OFFSET = 0x0a, PSID_PLAY_OFFSET = 0x0c, PSID_TITLE_OFFSET = 0x16, PSID_FLAGS_OFFSET = 0x76, PSID_NUM_SONGS = 0x0e, PSID_START_SONG = 0x10, PSID_SPEED_OFFSET = 0x12, // CIA_OFFSET = 0x09, // DIV_COUNTER = 0x1b, PAL_CLOCK = 0x4cc7, PSID_DATA_START = 0x7c } // quick and ugly hack to circumvent D2 phobos weirdness private int paddedStringLength(char[] s, char padchar) { int i; for(i = cast(int)(s.length - 1); i >= 0; i--) { if(s[i] != padchar) return cast(int)(i+1); } return 0; } private char[] assemble(string source) { int length; char[1024] error_message; memset(&error_message, '\0', 1024); char* input = acme_assemble(toStringz(source), &length, &error_message[0]); if(input is null) { string msg = to!string(&error_message[0]); throw new UserException(format("Could not assemble player. Message:\n%s", msg)); } char[] assembled = new char[length]; memcpy(assembled.ptr, input, length); free(input); return assembled; } private ubyte[] generatePSIDHeader(Song insong, ubyte[] data, int initAddress, int playAddress, int defaultSubtune) { /+ SID default tune indicatior starts from value 1... +/ if(defaultSubtune > insong.subtunes.numOf) throw new UserException(format("This song has only %d subtunes", insong.subtunes.numOf)); data = SIDHEADER ~ data; void outstr(char[] s, int offset) { data[offset .. offset + s.length] = cast(ubyte[])s; } data[PSID_TITLE_OFFSET .. PSID_TITLE_OFFSET + 0x20] = '\0'; data[PSID_TITLE_OFFSET + 0x20 .. PSID_TITLE_OFFSET + 0x40] = '\0'; data[PSID_TITLE_OFFSET + 0x40 .. PSID_TITLE_OFFSET + 0x60] = '\0'; // circumventing D2 phobos weirdness char[32] title = insong.title; title[paddedStringLength(title,' ') .. $] = '\0'; char[32] author = insong.author; author[paddedStringLength(author,' ') .. $] = '\0'; char[32] release = insong.release; release[paddedStringLength(release,' ') .. $] = '\0'; outstr(title,PSID_TITLE_OFFSET); outstr(author,PSID_TITLE_OFFSET + 0x20); outstr(release,PSID_TITLE_OFFSET + 0x40); data[PSID_NUM_SONGS + 1] = cast(ubyte)insong.subtunes.numOf; data[PSID_START_SONG + 1] = cast(ubyte)defaultSubtune; if(insong.multiplier > 1) { data[PSID_SPEED_OFFSET .. PSID_SPEED_OFFSET + 4] = 255; } data[PSID_INIT_OFFSET .. PSID_INIT_OFFSET + 2] = cast(ubyte[])[ initAddress >> 8, initAddress & 255 ]; data[PSID_PLAY_OFFSET .. PSID_PLAY_OFFSET + 2] = cast(ubyte[])[ playAddress >> 8, playAddress & 255 ]; int endAddr = cast(int)(initAddress + data.length); if(endAddr > 0xfff9) throw new UserException(format("The relocated tune goes past $fff9 (by $%x bytes).",endAddr-0xfff9)); data[PSID_FLAGS_OFFSET + 1] = cast(ubyte)(0x04 /+ PAL +/ | (insong.sidModel ? 0x20 : 0x10)); return data; } ubyte[] doBuild(Song song, int address, int zpAddress, bool genPSID, int defaultSubtune, bool verbose) { // Valid range for subtunes is 1 - 32. if(!(defaultSubtune >= 1 && defaultSubtune <= ct.base.SUBTUNE_MAX)) throw new UserException(format("Valid range for subtunes is 1 - %d.", ct.base.SUBTUNE_MAX)); if(song.subtunes.numOf == 0) { throw new UserException("No subtunes found"); } // Dump data to asm source string input = dumpOptimized(song, address, zpAddress, genPSID, verbose); if(verbose) writeln("Assembling..."); ubyte[] assembled = cast(ubyte[])assemble(input); if(verbose) writeln(format("Size %d bytes ($%04x-$%04x).", assembled.length - 2, address, address + assembled.length - 2)); return genPSID ? generatePSIDHeader(song, assembled, address, address + 3, defaultSubtune) : assembled; } string dumpOptimized(Song song, int address, int zpAddress, bool genPSID, bool verbose) { string input = playerSource; input ~= dumpData(song); input = setArgumentValue("INSNO", format("%d", song.numInstr+1), input); char[] linkedPlayerID = (new Song()).playerID; if(song.playerID[0..6] != linkedPlayerID[0..6] && verbose) { writeln("Warning: your song uses an old version of the player!\n", "The assembled song may sound different.\nSong player: ", to!string(song.playerID[0..6]), ", linked player: ", to!string(linkedPlayerID[0..6])); } bool chordUsed, swingUsed, filterUsed, vibratoUsed; bool setAttUsed, setDecUsed, setSusUsed, setRelUsed, setVolUsed, setSpeedUsed; bool offsetUsed, slideUpUsed, slideDnUsed, lovibUsed, portaUsed, setADSRUsed; song.seqIterator((Sequence s, Element e) { int val = e.cmd.value; int cmdval = -1; if(val == 0) return; if(val < 0x40) { cmdval = song.superTable[val]; if(cmdval < 1) slideUpUsed = true; else if(cmdval == 1) slideDnUsed = true; else if(cmdval == 2) vibratoUsed = true; else if(cmdval == 3) offsetUsed = true; else if(cmdval == 4) setADSRUsed = true; else if(cmdval == 5) lovibUsed = true; else if(cmdval == 7) portaUsed = true; return; } else if(val < 0x60) return; else if(val < 0x80) filterUsed = true; else if(val < 0xa0) chordUsed = true; else if(val < 0xb0) setAttUsed = true; else if(val < 0xc0) setDecUsed = true; else if(val < 0xd0) setSusUsed = true; else if(val < 0xe0) setRelUsed = true; else if(val < 0xf0) setVolUsed = true; else { if(val == 0xf0 || val == 0xf1) swingUsed = true; setSpeedUsed = true; } }); for(int i = 0; i < song.subtunes.numOf; i++) { if(song.songspeeds[i] < 2) swingUsed = true; } for(int i = 0; i < 48; i++) { if(song.filtertablePointer(i) > 0) filterUsed = true; } if(verbose) { string[] fxdescr = [ "slup", "sldn", "vib", "porta", "adsr", "8x", "offset", "lovib", "Ax", "Bx", "Cx", "Dx", "Ex", "Fx", "swing", "filter" ]; auto fxused = std.array.appender!string(); foreach(idx, used; [slideUpUsed, slideDnUsed, vibratoUsed, portaUsed, setADSRUsed, chordUsed, offsetUsed, lovibUsed, setAttUsed, setDecUsed, setSusUsed, setRelUsed, setVolUsed, setSpeedUsed, swingUsed, filterUsed]) { if(used) fxused.put(fxdescr[idx] ~ " "); } if(fxused.data.length > 0) { writeln("Effects used: " ~ fxused.data); } } void setArgVal(string arg, string val) { input = setArgumentValue(arg, val, input); } input = setArgumentValue("EXPORT", "TRUE", input); if(zpAddress > 0) setArgVal("ZREG", format("$%02X", zpAddress)); setArgVal("INCLUDE_CMD_SLUP", slideUpUsed ? "TRUE" : "FALSE"); setArgVal("INCLUDE_CMD_SLDOWN", slideDnUsed ? "TRUE" : "FALSE"); setArgVal("INCLUDE_CMD_VIBR", vibratoUsed ? "TRUE" : "FALSE"); setArgVal("INCLUDE_CMD_PORTA", portaUsed ? "TRUE" : "FALSE"); setArgVal("INCLUDE_CMD_SET_ADSR", setADSRUsed ? "TRUE" : "FALSE"); setArgVal("INCLUDE_SEQ_SET_CHORD", chordUsed ? "TRUE" : "FALSE"); setArgVal("INCLUDE_CHORD", chordUsed ? "TRUE" : "FALSE"); setArgVal("INCLUDE_CMD_SET_OFFSET", offsetUsed ? "TRUE" : "FALSE"); setArgVal("INCLUDE_CMD_SET_LOVIB", lovibUsed ? "TRUE" : "FALSE"); setArgVal("INCLUDE_SEQ_SET_ATT", setAttUsed ? "TRUE" : "FALSE"); setArgVal("INCLUDE_SEQ_SET_DEC", setDecUsed ? "TRUE" : "FALSE"); setArgVal("INCLUDE_SEQ_SET_SUS", setSusUsed ? "TRUE" : "FALSE"); setArgVal("INCLUDE_SEQ_SET_REL", setRelUsed ? "TRUE" : "FALSE"); setArgVal("INCLUDE_SEQ_SET_VOL", setVolUsed ? "TRUE" : "FALSE"); setArgVal("INCLUDE_SEQ_SET_SPEED", setSpeedUsed ? "TRUE" : "FALSE"); setArgVal("INCLUDE_BREAKSPEED", swingUsed ? "TRUE" : "FALSE"); setArgVal("INCLUDE_FILTER", filterUsed ? "TRUE" : "FALSE"); setArgVal("MULTISPEED", song.multiplier > 1 ? "TRUE" : "FALSE"); if(song.multiplier > 1) { setArgVal("USE_MDRIVER", genPSID ? "TRUE" : "FALSE"); setArgVal("CIA_VALUE", format("$%04x", PAL_CLOCK / song.multiplier)); setArgVal("MULTIPLIER", format("%d", song.multiplier - 1)); } setArgVal("BASEADDRESS", format("$%04x", address), ); return input; } CheeseCutter-2.10/src/ct/dump.d000066400000000000000000000071421516216315000163320ustar00rootroot00000000000000/* CheeseCutter v2 (C) Abaddon. Licensed under GNU GPL. */ /** date to source dumper. very ugly quick and dirty hack */ module ct.dump; import ct.base; import com.util; import std.string; import std.array; private const string byteOp = "!byte", wordOp = "!word"; string dumpData(Song sng) { auto app = appender!string(); int getHighestUsed(ubyte[] array) { for(int i = cast(int)array.length - 1; i >= 0; i--) { if(array[i] > 0) return cast(int)i; } return 0; } void append(string s) { app.put(s); } void hexdump(ubyte[] buf, int rowlen) { int c; append("\t\t" ~ byteOp ~ " "); foreach(i, b; buf) { append(format("$%02x", b)); c++; if(c >= rowlen) { c = 0; if(i < buf.length - 1) append("\n\t\t" ~ byteOp ~ " "); } else if(i < buf.length - 1) append(","); } append("\n"); } int tablen; ushort[][] trackpointers = new ushort[][sng.subtunes.numOf]; sng.subtunes.activate(0); auto packedTracks = sng.subtunes.compact(); append( "arp1 = *\n"); tablen = getHighestUsed(sng.wave1Table) + 1; hexdump(sng.wave1Table[0 .. tablen], 16); append( "arp2 = *\n"); hexdump(sng.wave2Table[0 .. tablen], 16); append( "filttab = *\n"); hexdump(sng.filterTable[0 .. getHighestUsed(sng.filterTable) + 4], 4); append( "pulstab = *\n"); hexdump(sng.pulseTable[0 .. getHighestUsed(sng.pulseTable) + 4], 4); append( "inst = *\n"); ubyte[512] instab = 0; int maxInsno; sng.seqIterator((Sequence s, Element e) { int insval = e.instr.value; if(insval > 0x2f) return; if(insval > maxInsno) maxInsno = insval; }); for(int i = 0; i < 8; i++) { append( format("\ninst%d = *\n",i)); hexdump(sng.instrumentTable[i * 48 .. i * 48 + (maxInsno+1)], 16); } // cmd ---------------------------------------- tablen = 1; append( "\nseqlo = *\n\t\t!8 "); for(int i = 0; i < sng.numOfSeqs(); i++) { append(format("s%02x", i)); if(i < sng.numOfSeqs() - 1) append(","); } sng.seqIterator((Sequence s, Element e) { int val = e.cmd.value; if(val == 0) return; if(val < 0x40 && val > tablen) { tablen = val; } }); ++tablen; append( "\ncmd1 = *\n"); hexdump(sng.superTable[0..tablen], 16); append( "cmd2 = *\n"); hexdump(sng.superTable[64..64+tablen], 16); append( "cmd3 = *\n"); hexdump(sng.superTable[128..128+tablen], 16); // songsets ------------------------------------ append( "songsets = *\n"); for(int i = 0; i < sng.subtunes.numOf; i++) { append(wordOp ~ "\t"); for(int voice = 0; voice < 3; voice++) { if(voice > 0) append(","); append(" " ~ format("track%d_%d", i, voice)); } append( format("\n\t\t" ~ byteOp ~ " %d, 7\n", sng.songspeeds[i])); } // tracks ------------------------------------- foreach(i, ref subtune; packedTracks) { foreach(j, voice; subtune) { append(format("track%d_%d = *\n", i, j)); hexdump(voice, 16); } } for(int i = 0; i < sng.numOfSeqs(); i++) { append( format("s%02x = *\n", i)); Sequence s = sng.seqs[i]; hexdump(s.compact(), 16); } // chords ------------------------------------- tablen = getHighestUsed(sng.chordTable) + 1; append("\nchord"); if(tablen < 1) tablen = 1; hexdump(sng.chordTable[0..tablen], 16); append("\nchordindex"); int highestChord = 0; sng.seqIterator((Sequence s, Element e) { if(e.cmd.value >= 0x80 && e.cmd.value <= 0x9f && (e.cmd.value & 0x1f) > highestChord) highestChord = e.cmd.value & 0x1f; }); hexdump(sng.chordIndexTable[0..highestChord+1], 16); return app.data; } CheeseCutter-2.10/src/ct/purge.d000066400000000000000000000305651516216315000165140ustar00rootroot00000000000000/* CheeseCutter v2 (C) Abaddon. Licensed under GNU GPL. */ /* TODO: make all purge funcs public so user can optimize selected tables. requires writing proper initialization for each func so they can be run independently. */ module ct.purge; import ct.base; import com.util; import std.string; import std.stdio; final class Purge { Song song; private { // song.seqIterator does not care if seq is in use or not // therefore purgeSeqs must be done always 1st on purgeAll - unused seqs get cleared bool[0x80] seqUsed; bool[0x30] instrUsed; bool[0x40] super_used, pulse_used, filter_used; bool verbose, initialized; } this(Song song) { this.song = song; } this(Song song, bool v) { verbose = v; this(song); } void purgeAll() { initialize(true); purgeSeqs(); purgeInstruments(); purgeWavetable(); purgeChordtable(); purgeCmdtable(); purgePulseFilter(); initialized = false; } void deleteInstrument(int insno) { initialize(false); int waveptr = song.wavetablePointer(insno); int pulseptr = song.pulsetablePointer(insno); int filtptr = song.filtertablePointer(insno); // ugly hack to not clear defined but unused instruments for(int i = 47; i >= 0; i--) { if(instrUsed[i] == false) instrUsed[i] = !instrIsEmpty(i); } instrUsed[insno] = false; purgeWavetable(); purgePulseFilter(); for(int i = 0; i < 8; i++) { song.instrumentTable[i * 48 + insno] = 0; } song.insLabels[insno][] = ' '; initialized = false; } private: bool instrIsEmpty(int insno) { for(int i = 0; i < 8; i++) { if(song.instrumentTable[i * 48 + insno] != 0) return false; } return true; } // marking unused seqs optional in case you only want to optimize some tables void initialize(bool markUnusedSeqs) { if(initialized) return; if(markUnusedSeqs) { seqUsed[] = false; song.trackIterator((Track t) { seqUsed[t.number] = true; }); } else seqUsed[] = true; instrUsed[] = false; // find out which instruments are in use foreach(i, n; seqUsed) { if(!n) continue; Sequence s = song.seqs[i]; for(int j = 0; j < s.rows; j++) { Element e = s.data[j]; if(!e.instr.hasValue()) continue; instrUsed[e.instr.value] = true; } } initialized = true; } private void purgeSeqs() { int counter; for(int i = 0x7f; i >= 1; i--) { if(!seqUsed[i]) continue; for(int j = 1; j < i; j++) { Sequence s1 = song.seqs[i]; Sequence s2 = song.seqs[j]; if (s1 == s2) { seqUsed[j] = false; replaceTrackvalue(j, i); counter++; } } } explain(format("%d identical seqs found.",counter)); counter = 0; for(int i = 0x7f; i >= 1; i--) { if(!seqUsed[i]) { song.seqs[i].clear(); continue; } for(int j = 1; j < i; j++) { if(!seqUsed[j]) { song.seqs[j].copyFrom(song.seqs[i]); song.seqs[i].clear(); seqUsed[j] = true; seqUsed[i] = false; replaceTrackvalue(i, j); counter++; break; } } } explain(format("%d unused sequences removed.",counter)); } private void purgeInstruments() { int counter; // clear unused for(int i = 0; i < 48; i++) { if(instrUsed[i]) { counter++; continue; } //instrtab[i*8 .. i*8 + 8] = 0; for(int j = 0; j < 8; j++) { song.instrumentTable[i + j * 48] = 0; } song.insLabels[i][] = ' '; } // compact for(int i = 0; i < 48; i++) { if(instrUsed[i]) continue; for(int j = i + 1; j < 48; j++) { if(instrUsed[j]) { for(int cidx = 0; cidx < 8; cidx++) { int o = cidx * 48; song.instrumentTable[i + o] = song.instrumentTable[j + o]; } song.insLabels[i][] = song.insLabels[j][]; replaceInsvalue(j, i); instrUsed[i] = true; instrUsed[j] = false; for(int k = 0; k < 8; k++) { song.instrumentTable[j + k * 48] = 0; } song.insLabels[j][] = ' '; break; } } } explain(format("%d instruments used.", counter)); } private void purgeWavetable() { Song.Chunk[] chunks = song.tWave.getChunks(); for(int i = 0; i < 48; i++) { if(!instrUsed[i]) continue; int ptr = song.wavetablePointer(i); int cell = song.tWave.whichCell(chunks, ptr); if(cell < 0) continue; song.tWave.markCells(chunks, cell); } int numcleared; // compact for(int i = cast(int)(chunks.length - 1); i >= 0; i--) { Song.Chunk chunk = chunks[i]; if(chunk.used) continue; song.tWave.deleteRow(song, chunk.offset, cast(int)chunk.wave1.length); numcleared++; } explain(format("%d wave programs removed.", numcleared)); } private void purgePulseFilter() { int i; pulse_used[] = false; filter_used[] = false; filter_used[0] = true; pulse_used[0] = true; void seekNMark(ref ubyte[] table, bool* usedflags, int pointer) { int pp = pointer; for(;;) { if(usedflags[pp]) break; usedflags[pp] = true; int newptr = table[pp*4 + 3]; if(newptr == 0x7f) break; if(newptr == 0) pp++; else pp = newptr; } } for(i = 0; i < 48; i++) { if(!instrUsed[i]) continue; try { seekNMark(song.pulseTable, &pulse_used[0], song.pulsetablePointer(i)); seekNMark(song.filterTable, &filter_used[0], song.filtertablePointer(i)); } catch(Exception e) { explain(format("Could not purge pulse / filter table: %s", e.toString())); return; } } song.seqIterator((Sequence s, Element e) { if(e.cmd.value >= 0x40 && e.cmd.value < 0x60) seekNMark(song.pulseTable, &pulse_used[0], e.cmd.value - 0x40); if(e.cmd.value >= 0x60 && e.cmd.value < 0x80) seekNMark(song.filterTable, &filter_used[0], e.cmd.value - 0x60); }); for(i = 0; i < 64; i++) { if(!pulse_used[i]) song.pulseTable[i * 4 .. i * 4 + 4] = 0; if(!filter_used[i]) song.filterTable[i * 4 .. i * 4 + 4] = 0; } // compact filter & pulse table. this is EXTREMELY slow. for(i = 0; i < 0x3e; i++) { int seek = i + 1; while(!filter_used[i] && seek < 64) { { filterDeleteRow(song, i); filter_used[i .. $-1] = filter_used[i+1 .. $].dup; } seek++; } } for(i = 0; i < 0x3e; i++) { int seek = i + 1; while(!pulse_used[i] && seek < 64) { { pulseDeleteRow(song, i); pulse_used[i .. $-1] = pulse_used[i+1 .. $].dup; } seek++; } } } private void purgeChordtable() { bool[0x20] chordsUsed; song.seqIterator((Sequence s, Element e) { if(e.cmd.value >= 0x80 && e.cmd.value <= 0x9f) { chordsUsed[e.cmd.value & 0x1f] = true; } }); struct Chunk { ubyte[] data; int oldOffset; } int getidx2(int cmdidx, int idx) { for(int i = idx; i < 128; i++) { if(song.chordTable[i] >= 0x80) return i; } throw new PurgeException(format("Could not find valid chord for value %x", cmdidx)); } song.generateChordIndex(); Chunk[] chunks; chunks ~= Chunk(song.chordTable[0 .. song.chordIndexTable[1]].dup, 0); int tablestart = 1; // TODO: find out if swingtepo is used and purge first chunk too if needed for(int i = tablestart; i < 0x20; i++) { if(chordsUsed[i]) { int idx = song.chordIndexTable[i]; int idx2 = getidx2(i,idx)+1; // FIX: check... might cause problems //int idx2 = song.chordIndexTable[i+1]; assert(idx != 0); if(idx2 == 0) break; ubyte[] chord = song.chordTable[idx .. idx2].dup; chunks ~= Chunk(chord, idx); } else { for(int j = i + 1; j < 0x20; j++) { if(chordsUsed[j]) { int idx = song.chordIndexTable[j]; int idx2 = getidx2(j, idx)+1; replaceCmdColumnvalue(song, 0x80 + j, 0x80 + i); ubyte[] chord = song.chordTable[idx .. idx2].dup; chunks ~= Chunk(chord, idx); chordsUsed[i] = true; chordsUsed[j] = false; break; } } } } int counter; int idx; int np; foreach(chunk; chunks) { if(chunk.data.length == 0) continue; int oldwrap = (chunk.data[$-1] - 0x80) - chunk.oldOffset; assert(chunk.data[$-1] >= 0x80); chunk.data[$-1] = cast(ubyte)(idx + oldwrap + 0x80); idx += chunk.data.length; counter++; } song.chordTable[] = 0; foreach(chunk; chunks) { song.chordTable[np .. np + chunk.data.length] = chunk.data; np += chunk.data.length; } song.generateChordIndex(); explain(format("%d chords used.",counter)); } private void purgeCmdtable() { song.seqIterator((Sequence s, Element e) { if(e.cmd.value == 0) return; if(e.cmd.value < 0x40) super_used[e.cmd.value] = true; }); int counter; for(int i = 1; i < 64; i++) { if(super_used[i]) { counter++; continue; } song.superTable[i] = 0; song.superTable[i+64] = 0; song.superTable[i+128] = 0; for(int j = i + 1; j < 64; j++) { if(super_used[j]) { song.superTable[i] = song.superTable[j]; song.superTable[i+64] = song.superTable[j+64]; song.superTable[i+128] = song.superTable[j+128]; replaceCmdColumnvalue(song, j, i); super_used[i] = true; super_used[j] = false; song.superTable[j] = 0; song.superTable[j+64] = 0; song.superTable[j+128] = 0; break; } } } } void replaceInsvalue(int seek, int repl) { int skipped; song.seqIterator((Sequence s, Element e) { if(!e.instr.hasValue()) return; if(e.instr.value() == seek) e.instr = cast(ubyte)repl; }); } void replaceTrackvalue(int find, int rep) { song.trackIterator((Track t) { if(t.number == find) t.number = cast(ubyte)rep; }); } void explain(string s) { if(verbose) writefln(s); } } // TODO: move to tFilter void filterDeleteRow(Song song, int row) { genericDeleteRow(song, song.filterTable, row); song.seqIterator((Sequence s, Element e) { if(row > 0x1f) return; if(e.cmd.value == 0) return; if(e.cmd.value() >= (0x60 + (row & 0x1f) + 1) && e.cmd.value() < 0x80) e.cmd = cast(ubyte)(e.cmd.value - 1); }); for(int j = 0; j < 48; j++) { int fptr = song.instrumentTable[4 * 48 + j]; if(fptr >= row && fptr < 0x40 && fptr > 0) song.instrumentTable[4 * 48 + j]--; } } // TODO: move to tPulse void pulseDeleteRow(Song song, int row) { genericDeleteRow(song, song.pulseTable, row); song.seqIterator((Sequence s, Element e) { if(row > 0x1f) return; if(e.cmd.value == 0) return; if(e.cmd.value() >= (0x40 + (row & 0x1f) + 1) && e.cmd.value() < 0x60) e.cmd = cast(ubyte)(e.cmd.value - 1); }); for(int j = 0; j < 48; j++) { int pptr = song.instrumentTable[5 * 48 + j]; if(pptr >= row && pptr < 0x40 && pptr > 0) song.instrumentTable[5 * 48 + j]--; } } // TODO: move to tFilter void filterInsertRow(Song song, int row) { genericInsertRow(song, song.filterTable, row); song.seqIterator((Sequence s, Element e) { if(row > 0x1f) return; if(e.cmd.value == 0) return; if(e.cmd.value() >= (0x60 + (row & 0x1f)) && e.cmd.value() < 0x80) e.cmd = cast(ubyte)(e.cmd.value + 1); }); for(int j = 0; j < 48; j++) { int fptr = song.instrumentTable[4 * 48 + j]; if(fptr >= row && fptr < 0x40) song.instrumentTable[4 * 48 + j]++; } } // TODO: move to tPulse void pulseInsertRow(Song song, int row) { genericInsertRow(song, song.pulseTable, row); song.seqIterator((Sequence s, Element e) { if(row > 0x1f) return; if(e.cmd.value == 0) return; if(e.cmd.value() >= (0x40 + (row & 0x1f)) && e.cmd.value() < 0x60) e.cmd = cast(ubyte)(e.cmd.value + 1); }); for(int j = 0; j < 48; j++) { int pptr = song.instrumentTable[5 * 48 + j]; if(pptr >= row && pptr < 0x40 && pptr > 0) song.instrumentTable[5 * 48 + j]++; } } private void replaceCmdColumnvalue(Song song, int seek, int repl) { int skipped; song.seqIterator((Sequence s, Element e) { if(e.cmd.value == 0) return; if(e.cmd.value() == seek) e.cmd = cast(ubyte)repl; }); } // TODO: move to Table private void genericDeleteRow(Song song, ubyte[] table, int row) { assert(row < 64 && row >= 0); int row4 = row * 4; table[row4 .. $ - 4] = table[row4 + 4 .. $].dup; for(int j = 0; j < 64; j++) { int fptr = table[j * 4 + 3]; if(fptr > 0 && fptr < 0x40) { if(fptr >= row) table[j * 4 + 3]--; } } } // TODO: move to Table private void genericInsertRow(Song song, ubyte[] table, int row) { assert(row < 64 && row >= 0); int row4 = row * 4; table[row4 + 4 .. $] = table[row4 .. $ - 4].dup; table[row4 .. row4+4] = 0; for(int j = 0; j < 64; j++) { int fptr = table[j * 4 + 3]; if(fptr > 0 && fptr < 0x40) { if(fptr >= row) table[j * 4 + 3]++; } } } class PurgeException : Exception { this(string msg) { super(msg); } override string toString() { return "Purge error: " ~ msg; } } CheeseCutter-2.10/src/ct2util.d000066400000000000000000000233451516216315000163500ustar00rootroot00000000000000/* CheeseCutter v2 (C) Abaddon. Licensed under GNU GPL. */ import com.cpu; import com.util; import ct.base; import ct.purge; import ct.dump; import ct.build; import std.stdio; import std.string; import std.conv; import std.file; enum Command { None, ExportPRG, ExportSID, Dump, Import, Init } const string[] exts = [ "", "prg", "sid", "s", "ct", "ct" ]; bool verbose = true; bool noPurge; void explain(string str) { if(verbose) writefln(str); } string defineOutfn(int cmd, string infn) { string name; int r = cast(int)(infn.lastIndexOf('.')); if(r <= 0) name = infn; else name = infn[0 .. infn.lastIndexOf('.')]; return name ~ "." ~ exts[cmd]; } bool doPurge(ref Song song) { if(noPurge) return true; explain("Purging data..."); Purge p = new Purge(song, verbose); try { p.purgeAll(); } catch(PurgeException e) { writeln(e); return false; } return true; } void validate(ref Song song) { explain("Checking validity..."); for(int i = 0; i < song.numInstr; i++) { //ubyte[] instr = song.getInstrument(i); int waveptr = song.wavetablePointer(i); int pulseptr = song.pulsetablePointer(i); int filtptr = song.filtertablePointer(i); if(!song.tWave.isValid(waveptr)) { throw new ValidateException(format("Error: instrument %d is not valid (wavetable does not wrap).", i)); } if(!song.tPulse.isValid(pulseptr)) { throw new ValidateException(format("Cannot save; pulse %d is not valid.", pulseptr)); } if(!song.tFilter.isValid(filtptr)) { throw new ValidateException(format("Cannot save; filter %d is not valid.", filtptr)); } song.seqIterator((int seqno, Sequence s, Element e) { if(e.cmd.value >= 0x80 && e.cmd.value <= 0x9f) { int idx = song.chordIndexTable[e.cmd.value & 0x1f]; for(int i = idx; i < 128; i++) { if(song.chordTable[i] >= 0x80) return; } throw new ValidateException(format("sequence $%02x, could not find end for chord %x. The song has a 8x command pointing to nonexistant chord program.", seqno, e.cmd.value & 0x1f)); } }); } } class ValidateException : Exception { this(string msg) { super(msg); } override string toString() { return "Validation error: " ~ msg; } } int main(string[] args) { int relocAddress = 0x1000, zpAddress = 0; int[] speeds, masks; // these two use PSID ranges (1..32) int defaultTune = 1, singleSubtune = -1; bool outfnDefined = false, infnDefined = false; int command; Song insong; string infn, outfn; string[3] infns; speeds.length = 32; masks.length = 32; void printheader() { enum hdr = "CheeseCutter 2 utilities" ~ com.util.versionInfo; writefln(hdr); writefln("\nUsage: \t%s <-o outfile>",args[0]); writefln("\t%s import <-o outfile>",args[0]); writefln("\t%s init <-o outfile>",args[0]); writefln("\nCommands:"); writefln(" prg Export song (.ct) to PRG file"); writefln(" sid Export song (.ct) to SID file"); writefln(" dump Dump song data to assembler source (BETA)"); writefln(" import Copy data from another song without overwriting the player"); writefln(" init Create a fresh .ct from player binary"); writefln("\nGeneral options:"); writefln(" -o Set output filename (by default gathered from input filename)"); writefln("\nExport options:"); // writefln(" -n Do not purge before exporting/dumping (leaves unused data)"); writefln(" -r Relocate output to address (default = $1000)"); writefln(" -d Set the default subtune (1-" ~ to!string(ct.base.SUBTUNE_MAX) ~ ")"); // writefln(" -s [subtune]:[speed],... Set speeds for subtunes"); // writefln(" -c [subtune]:[voicemask],...Set voice bitmasks for subtunes"); writefln(" -s Export single subtune (1-" ~ to!string(ct.base.SUBTUNE_MAX) ~ ") (disables -d)"); writefln(" -zp Relocate zero page (valid range 2-$fe)"); writefln(" -q Don't output information"); writefln("\nPrefix value options with '0x' or '$' to indicate a hexadecimal value."); } if(args.length < 2) { printheader(); return 0; } try { switch(args[1]) { case "prg", "buildprg": command = Command.ExportPRG; break; case "sid", "build": command = Command.ExportSID; break; case "dump": command = Command.Dump; break; case "import": command = Command.Import; break; case "init": command = Command.Init; break; default: throw new UserException(format("command '%s' not recognized.",args[1])); } int infncounter = 0; if(args.length >= 2) { for(int argp = 2; argp < args.length; argp++) { string nextArg() { if(argp+1 >= args.length || args[argp+1][0] == '-') throw new UserException("Missing value for option '" ~ args[argp] ~"'"); argp++; return args[argp]; } switch(args[argp]) { case "-n": noPurge = true; break; case "-r": if(command != Command.ExportSID && command != Command.ExportPRG) throw new UserException("Option available only with exporting commands."); int r = str2Value2(nextArg()); if(r < 0x200 || r > 0xf900) throw new UserException("-r: reloc address out of range"); relocAddress = cast(ushort)r; break; case "-s": if(command != Command.ExportSID && command != Command.ExportPRG) throw new UserException("Option available only with exporting commands."); //parseList(speeds, nextArg()); int value = str2Value2(nextArg()); if(value < 1 || value > ct.base.SUBTUNE_MAX) throw new UserException(format("Valid range for subtunes is 1 - %d.", ct.base.SUBTUNE_MAX)); singleSubtune = value; break; case "-c": if(command != Command.ExportSID && command != Command.ExportPRG) throw new UserException("Option available only with exporting commands."); parseList(masks, nextArg()); break; case "-d": if(command != Command.ExportSID) throw new UserException("Option available only when exporting to SID."); defaultTune = str2Value2(nextArg()); if(defaultTune < 1 || defaultTune > ct.base.SUBTUNE_MAX) throw new UserException(format("Valid range for subtunes is 1 - %d.", ct.base.SUBTUNE_MAX)); break; case "-z", "-zp": if(command != Command.ExportSID && command != Command.ExportPRG) throw new UserException("Option available only with exporting commands."); zpAddress = str2Value2(nextArg()); if(zpAddress < 2 || zpAddress > 0xfe) { throw new UserException("Valid range for zero page is 2 - $fe"); } break; case "-o": if(outfnDefined) throw new UserException("Output file already defined."); outfn = args[argp+1]; outfnDefined = true; argp++; break; case "-q": verbose = false; break; default: if(args[argp][0] == '-') throw new UserException("Unrecognized option '" ~ args[argp] ~ "'"); if(infnDefined && command != Command.Import) throw new UserException("Input filename already defined. Use -o to define output file."); if(command == Command.Import) { if(infncounter > 1) throw new UserException("Infile & import filename already defined."); infns[infncounter++] = args[argp]; infn = infns[0]; } else infn = args[argp]; infnDefined = true; break; } } } assert(command != Command.None); if(!infnDefined) throw new UserException("Input filename not defined."); if(command == Command.Init && !outfnDefined) { throw new UserException("Command 'init' requires output filename to be defined (option -o)."); } else if(command == Command.Import && !outfnDefined) { throw new UserException("Command 'import' requires output filename to be defined (option -o)."); } if(!outfnDefined) { outfn = defineOutfn(command, infn); } if(!std.file.exists(infn)) throw new UserException(format("File %s does not exist", infn)); explain("Input file: " ~ infn); explain("Output file: " ~ outfn); if(command == Command.ExportSID || command == Command.ExportPRG) { explain(format("Relocating data to $%x", relocAddress)); } switch(command) { case Command.ExportPRG, Command.ExportSID: insong = new Song; insong.open(infn); if(singleSubtune >= 1) { for(int i = 0; i < ct.base.SUBTUNE_MAX; i++) { if(i == singleSubtune - 1) continue; insong.subtunes.clear(i); } insong.subtunes.swap(0, singleSubtune - 1); defaultTune = 1; } if(!doPurge(insong)) { writeln("Aborting"); return -1; } try { validate(insong); } catch(ValidateException e) { writeln(e); writeln("Aborting"); return -1; } ubyte[] data = doBuild(insong, relocAddress, zpAddress, command == Command.ExportSID, defaultTune, verbose); std.file.write(outfn, data); break; case Command.Import: if(infncounter < 2) throw new UserException("Import song not defined."); explain("Importing data from " ~ infns[1]); insong = new Song; insong.open(infns[0]); Song importsong = new Song(); importsong.open(infns[1]); insong.importData(importsong); insong.save(outfn); break; case Command.Dump: insong = new Song; insong.open(infn); doPurge(insong); string dumped = dumpOptimized(insong, 0x1000, 0, true, verbose); string header = format(";;; ACME dump for %s\n\n", infn); std.file.write(outfn, header ~ dumped); break; case Command.Init: insong = new Song(cast(ubyte[])std.file.read(infn)); insong.save(outfn); break; default: assert(0); } } catch(UserException e) { writeln("error: ", e); return -1; } catch(Exception e) { writeln(e); return -1; } scope(failure) { writeln("Aborted."); } scope(success) { explain("Done."); } return 0; } CheeseCutter-2.10/src/derelict/000077500000000000000000000000001516216315000164015ustar00rootroot00000000000000CheeseCutter-2.10/src/derelict/sdl2/000077500000000000000000000000001516216315000172455ustar00rootroot00000000000000CheeseCutter-2.10/src/derelict/sdl2/config.d000066400000000000000000000043631516216315000206650ustar00rootroot00000000000000/* Boost Software License - Version 1.0 - August 17th,2003 Permission is hereby granted,free of charge,to any person or organization obtaining a copy of the software and accompanying documentation covered by this license (the "Software") to use,reproduce,display,distribute, execute,and transmit the Software,and to prepare derivative works of the Software,and to permit third-parties to whom the Software is furnished to do so,all subject to the following: The copyright notices in the Software and this entire statement,including the above license grant,this restriction and the following disclaimer, must be included in all copies of the Software,in whole or in part,and all derivative works of the Software,unless such copies or derivative works are solely in the form of machine-executable object code generated by a source language processor. THE SOFTWARE IS PROVIDED "AS IS",WITHOUT WARRANTY OF ANY KIND,EXPRESS OR IMPLIED,INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE,TITLE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE FOR ANY DAMAGES OR OTHER LIABILITY,WHETHER IN CONTRACT,TORT OR OTHERWISE, ARISING FROM,OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ module derelict.sdl2.config; version(Derelict_Static) version = DerelictSDL2_Static; version(DerelictSDL2_Static) { version = DerelictSDL2Core_Static; version = DerelictSDL2GPU_Static; version = DerelictSDL2Image_Static; version = DerelictSDL2Mixer_Static; version = DerelictSDL2Net_Static; version = DerelictSDL2TTF_Static; } version(DerelictSDL2Core_Static) enum staticSDL = true; else enum staticSDL = false; version(DerelictSDL2GPU_Static) enum staticGPU = true; else enum staticGPU = false; version(DerelictSDL2Image_Static) enum staticImage = true; else enum staticImage = false; version(DerelictSDL2Mixer_Static) enum staticMixer = true; else enum staticMixer = false; version(DerelictSDL2Net_Static) enum staticNet = true; else enum staticNet = false; version(DerelictSDL2TTF_Static) enum staticTTF = true; else enum staticTTF = false;CheeseCutter-2.10/src/derelict/sdl2/gpu.d000066400000000000000000000030571516216315000202120ustar00rootroot00000000000000/* Boost Software License - Version 1.0 - August 17th,2003 Permission is hereby granted,free of charge,to any person or organization obtaining a copy of the software and accompanying documentation covered by this license(the "Software") to use,reproduce,display,distribute, execute,and transmit the Software,and to prepare derivative works of the Software,and to permit third-parties to whom the Software is furnished to do so,all subject to the following: The copyright notices in the Software and this entire statement,including the above license grant,this restriction and the following disclaimer, must be included in all copies of the Software,in whole or in part,and all derivative works of the Software,unless such copies or derivative works are solely in the form of machine-executable object code generated by a source language processor. THE SOFTWARE IS PROVIDED "AS IS",WITHOUT WARRANTY OF ANY KIND,EXPRESS OR IMPLIED,INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE,TITLE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE FOR ANY DAMAGES OR OTHER LIABILITY,WHETHER IN CONTRACT,TORT OR OTHERWISE, ARISING FROM,OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ module derelict.sdl2.gpu; import derelict.sdl2.config; public: import derelict.sdl2.internal.gpu_types; static if(staticGPU) import derelict.sdl2.internal.gpu_static; else import derelict.sdl2.internal.gpu_dynload;CheeseCutter-2.10/src/derelict/sdl2/image.d000066400000000000000000000303031516216315000204730ustar00rootroot00000000000000/* Boost Software License - Version 1.0 - August 17th,2003 Permission is hereby granted,free of charge,to any person or organization obtaining a copy of the software and accompanying documentation covered by this license (the "Software") to use,reproduce,display,distribute, execute,and transmit the Software,and to prepare derivative works of the Software,and to permit third-parties to whom the Software is furnished to do so,all subject to the following: The copyright notices in the Software and this entire statement,including the above license grant,this restriction and the following disclaimer, must be included in all copies of the Software,in whole or in part,and all derivative works of the Software,unless such copies or derivative works are solely in the form of machine-executable object code generated by a source language processor. THE SOFTWARE IS PROVIDED "AS IS",WITHOUT WARRANTY OF ANY KIND,EXPRESS OR IMPLIED,INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE,TITLE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE FOR ANY DAMAGES OR OTHER LIABILITY,WHETHER IN CONTRACT,TORT OR OTHERWISE, ARISING FROM,OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ module derelict.sdl2.image; import derelict.sdl2.config, derelict.sdl2.internal.sdl_types; static if(staticSDL) import derelict.sdl2.internal.sdl_static : SDL_GetError, SDL_SetError; else import derelict.sdl2.internal.sdl_dynamic : SDL_GetError, SDL_SetError; alias IMG_SetError = SDL_SetError; alias IMG_GetError = SDL_GetError; enum : Uint8 { SDL_IMAGE_MAJOR_VERSION = 2, SDL_IMAGE_MINOR_VERSION = 0, SDL_IMAGE_PATCHLEVEL = 0, } @nogc nothrow void SDL_IMAGE_VERSION(SDL_version* X) { X.major = SDL_IMAGE_MAJOR_VERSION; X.minor = SDL_IMAGE_MINOR_VERSION; X.patch = SDL_IMAGE_PATCHLEVEL; } enum { IMG_INIT_JPG = 0x00000001, IMG_INIT_PNG = 0x00000002, IMG_INIT_TIF = 0x00000004, IMG_INIT_WEBP = 0x00000008, } static if(staticImage) { extern(C) @nogc nothrow { int IMG_Init(int); int IMG_Quit(); const(SDL_version)* IMG_Linked_Version(); SDL_Surface* IMG_LoadTyped_RW(SDL_RWops*,int,const(char)*); SDL_Surface* IMG_Load(const(char)*); SDL_Surface* IMG_Load_RW(SDL_RWops*,int); SDL_Texture* IMG_LoadTexture(SDL_Renderer*,const(char)*); SDL_Texture* IMG_LoadTexture_RW(SDL_Renderer*,SDL_RWops*,int); SDL_Texture* IMG_LoadTextureTyped_RW(SDL_Renderer*,SDL_RWops*,int,const(char)*); int IMG_isICO(SDL_RWops*); int IMG_isCUR(SDL_RWops*); int IMG_isBMP(SDL_RWops*); int IMG_isGIF(SDL_RWops*); int IMG_isJPG(SDL_RWops*); int IMG_isLBM(SDL_RWops*); int IMG_isPCX(SDL_RWops*); int IMG_isPNG(SDL_RWops*); int IMG_isPNM(SDL_RWops*); int IMG_isTIF(SDL_RWops*); int IMG_isXCF(SDL_RWops*); int IMG_isXPM(SDL_RWops*); int IMG_isXV(SDL_RWops*); int IMG_isWEBP(SDL_RWops*); SDL_Surface* IMG_LoadICO_RW(SDL_RWops*); SDL_Surface* IMG_LoadCUR_RW(SDL_RWops*); SDL_Surface* IMG_LoadBMP_RW(SDL_RWops*); SDL_Surface* IMG_LoadGIF_RW(SDL_RWops*); SDL_Surface* IMG_LoadJPG_RW(SDL_RWops*); SDL_Surface* IMG_LoadLBM_RW(SDL_RWops*); SDL_Surface* IMG_LoadPCX_RW(SDL_RWops*); SDL_Surface* IMG_LoadPNG_RW(SDL_RWops*); SDL_Surface* IMG_LoadPNM_RW(SDL_RWops*); SDL_Surface* IMG_LoadTGA_RW(SDL_RWops*); SDL_Surface* IMG_LoadTIF_RW(SDL_RWops*); SDL_Surface* IMG_LoadXCF_RW(SDL_RWops*); SDL_Surface* IMG_LoadXPM_RW(SDL_RWops*); SDL_Surface* IMG_LoadXV_RW(SDL_RWops*); SDL_Surface* IMG_LoadWEBP_RW(SDL_RWops*); SDL_Surface* IMG_ReadXPMFromArray(char**); int IMG_SavePNG(SDL_Surface*,const(char)*); int IMG_SavePNG_RW(SDL_Surface*,SDL_RWops*,int); } } else { import derelict.util.loader, derelict.util.exception, derelict.util.system; extern(C) @nogc nothrow { alias da_IMG_Init = int function(int); alias da_IMG_Quit = int function(); alias da_IMG_Linked_Version = const(SDL_version)* function(); alias da_IMG_LoadTyped_RW = SDL_Surface* function(SDL_RWops*,int,const(char)*); alias da_IMG_Load = SDL_Surface* function(const(char)*); alias da_IMG_Load_RW = SDL_Surface* function(SDL_RWops*,int); alias da_IMG_LoadTexture = SDL_Texture* function(SDL_Renderer*,const(char)*); alias da_IMG_LoadTexture_RW = SDL_Texture* function(SDL_Renderer*,SDL_RWops*,int); alias da_IMG_LoadTextureTyped_RW = SDL_Texture* function(SDL_Renderer*,SDL_RWops*,int,const(char)*); alias da_IMG_isICO = int function(SDL_RWops*); alias da_IMG_isCUR = int function(SDL_RWops*); alias da_IMG_isBMP = int function(SDL_RWops*); alias da_IMG_isGIF = int function(SDL_RWops*); alias da_IMG_isJPG = int function(SDL_RWops*); alias da_IMG_isLBM = int function(SDL_RWops*); alias da_IMG_isPCX = int function(SDL_RWops*); alias da_IMG_isPNG = int function(SDL_RWops*); alias da_IMG_isPNM = int function(SDL_RWops*); alias da_IMG_isTIF = int function(SDL_RWops*); alias da_IMG_isXCF = int function(SDL_RWops*); alias da_IMG_isXPM = int function(SDL_RWops*); alias da_IMG_isXV = int function(SDL_RWops*); alias da_IMG_isWEBP = int function(SDL_RWops*); alias da_IMG_LoadICO_RW = SDL_Surface* function(SDL_RWops*); alias da_IMG_LoadCUR_RW = SDL_Surface* function(SDL_RWops*); alias da_IMG_LoadBMP_RW = SDL_Surface* function(SDL_RWops*); alias da_IMG_LoadGIF_RW = SDL_Surface* function(SDL_RWops*); alias da_IMG_LoadJPG_RW = SDL_Surface* function(SDL_RWops*); alias da_IMG_LoadLBM_RW = SDL_Surface* function(SDL_RWops*); alias da_IMG_LoadPCX_RW = SDL_Surface* function(SDL_RWops*); alias da_IMG_LoadPNG_RW = SDL_Surface* function(SDL_RWops*); alias da_IMG_LoadPNM_RW = SDL_Surface* function(SDL_RWops*); alias da_IMG_LoadTGA_RW = SDL_Surface* function(SDL_RWops*); alias da_IMG_LoadTIF_RW = SDL_Surface* function(SDL_RWops*); alias da_IMG_LoadXCF_RW = SDL_Surface* function(SDL_RWops*); alias da_IMG_LoadXPM_RW = SDL_Surface* function(SDL_RWops*); alias da_IMG_LoadXV_RW = SDL_Surface* function(SDL_RWops*); alias da_IMG_LoadWEBP_RW = SDL_Surface* function(SDL_RWops*); alias da_IMG_ReadXPMFromArray = SDL_Surface* function(char**); alias da_IMG_SavePNG = int function(SDL_Surface*,const(char)*); alias da_IMG_SavePNG_RW = int function(SDL_Surface*,SDL_RWops*,int); } __gshared { da_IMG_Init IMG_Init; da_IMG_Quit IMG_Quit; da_IMG_Linked_Version IMG_Linked_Version; da_IMG_LoadTyped_RW IMG_LoadTyped_RW; da_IMG_Load IMG_Load; da_IMG_Load_RW IMG_Load_RW; da_IMG_LoadTexture IMG_LoadTexture; da_IMG_LoadTexture_RW IMG_LoadTexture_RW; da_IMG_LoadTextureTyped_RW IMG_LoadTextureTyped_RW; da_IMG_isICO IMG_isICO; da_IMG_isCUR IMG_isCUR; da_IMG_isBMP IMG_isBMP; da_IMG_isGIF IMG_isGIF; da_IMG_isJPG IMG_isJPG; da_IMG_isLBM IMG_isLBM; da_IMG_isPCX IMG_isPCX; da_IMG_isPNG IMG_isPNG; da_IMG_isPNM IMG_isPNM; da_IMG_isTIF IMG_isTIF; da_IMG_isXCF IMG_isXCF; da_IMG_isXPM IMG_isXPM; da_IMG_isXV IMG_isXV; da_IMG_isWEBP IMG_isWEBP; da_IMG_LoadICO_RW IMG_LoadICO_RW; da_IMG_LoadCUR_RW IMG_LoadCUR_RW; da_IMG_LoadBMP_RW IMG_LoadBMP_RW; da_IMG_LoadGIF_RW IMG_LoadGIF_RW; da_IMG_LoadJPG_RW IMG_LoadJPG_RW; da_IMG_LoadLBM_RW IMG_LoadLBM_RW; da_IMG_LoadPCX_RW IMG_LoadPCX_RW; da_IMG_LoadPNG_RW IMG_LoadPNG_RW; da_IMG_LoadPNM_RW IMG_LoadPNM_RW; da_IMG_LoadTGA_RW IMG_LoadTGA_RW; da_IMG_LoadTIF_RW IMG_LoadTIF_RW; da_IMG_LoadXCF_RW IMG_LoadXCF_RW; da_IMG_LoadXPM_RW IMG_LoadXPM_RW; da_IMG_LoadXV_RW IMG_LoadXV_RW; da_IMG_LoadWEBP_RW IMG_LoadWEBP_RW; da_IMG_ReadXPMFromArray IMG_ReadXPMFromArray; da_IMG_SavePNG IMG_SavePNG; da_IMG_SavePNG_RW IMG_SavePNG_RW; } class DerelictSDL2ImageLoader : SharedLibLoader { this() { super(libNames); } protected override void loadSymbols() { bindFunc(cast(void**)&IMG_Init,"IMG_Init"); bindFunc(cast(void**)&IMG_Quit,"IMG_Quit"); bindFunc(cast(void**)&IMG_Linked_Version,"IMG_Linked_Version"); bindFunc(cast(void**)&IMG_LoadTyped_RW,"IMG_LoadTyped_RW"); bindFunc(cast(void**)&IMG_Load,"IMG_Load"); bindFunc(cast(void**)&IMG_Load_RW,"IMG_Load_RW"); bindFunc(cast(void**)&IMG_LoadTexture,"IMG_LoadTexture"); bindFunc(cast(void**)&IMG_LoadTexture_RW,"IMG_LoadTexture_RW"); bindFunc(cast(void**)&IMG_LoadTextureTyped_RW,"IMG_LoadTextureTyped_RW"); bindFunc(cast(void**)&IMG_isICO,"IMG_isICO"); bindFunc(cast(void**)&IMG_isCUR,"IMG_isCUR"); bindFunc(cast(void**)&IMG_isBMP,"IMG_isBMP"); bindFunc(cast(void**)&IMG_isGIF,"IMG_isGIF"); bindFunc(cast(void**)&IMG_isJPG,"IMG_isJPG"); bindFunc(cast(void**)&IMG_isLBM,"IMG_isLBM"); bindFunc(cast(void**)&IMG_isPCX,"IMG_isPCX"); bindFunc(cast(void**)&IMG_isPNG,"IMG_isPNG"); bindFunc(cast(void**)&IMG_isPNM,"IMG_isPNM"); bindFunc(cast(void**)&IMG_isTIF,"IMG_isTIF"); bindFunc(cast(void**)&IMG_isXCF,"IMG_isXCF"); bindFunc(cast(void**)&IMG_isXPM,"IMG_isXPM"); bindFunc(cast(void**)&IMG_isXV,"IMG_isXV"); bindFunc(cast(void**)&IMG_isWEBP,"IMG_isWEBP"); bindFunc(cast(void**)&IMG_LoadICO_RW,"IMG_LoadICO_RW"); bindFunc(cast(void**)&IMG_LoadCUR_RW,"IMG_LoadCUR_RW"); bindFunc(cast(void**)&IMG_LoadBMP_RW,"IMG_LoadBMP_RW"); bindFunc(cast(void**)&IMG_LoadGIF_RW,"IMG_LoadGIF_RW"); bindFunc(cast(void**)&IMG_LoadJPG_RW,"IMG_LoadJPG_RW"); bindFunc(cast(void**)&IMG_LoadLBM_RW,"IMG_LoadLBM_RW"); bindFunc(cast(void**)&IMG_LoadPCX_RW,"IMG_LoadPCX_RW"); bindFunc(cast(void**)&IMG_LoadPNG_RW,"IMG_LoadPNG_RW"); bindFunc(cast(void**)&IMG_LoadPNM_RW,"IMG_LoadPNM_RW"); bindFunc(cast(void**)&IMG_LoadTGA_RW,"IMG_LoadTGA_RW"); bindFunc(cast(void**)&IMG_LoadTIF_RW,"IMG_LoadTIF_RW"); bindFunc(cast(void**)&IMG_LoadXCF_RW,"IMG_LoadXCF_RW"); bindFunc(cast(void**)&IMG_LoadXPM_RW,"IMG_LoadXPM_RW"); bindFunc(cast(void**)&IMG_LoadXV_RW,"IMG_LoadXV_RW"); bindFunc(cast(void**)&IMG_isXV,"IMG_isXV"); bindFunc(cast(void**)&IMG_LoadWEBP_RW,"IMG_LoadWEBP_RW"); bindFunc(cast(void**)&IMG_SavePNG,"IMG_SavePNG"); bindFunc(cast(void**)&IMG_SavePNG_RW,"IMG_SavePNG_RW"); } } __gshared DerelictSDL2ImageLoader DerelictSDL2Image; shared static this() { DerelictSDL2Image = new DerelictSDL2ImageLoader(); } private: static if(Derelict_OS_Windows) enum libNames = "SDL2_image.dll"; else static if(Derelict_OS_Mac) enum libNames = "/usr/local/lib/libSDL2_image.dylib,../Frameworks/SDL2_image.framework/SDL2_image,/Library/Frameworks/SDL2_image.framework/SDL2_image,/System/Library/Frameworks/SDL2_image.framework/SDL2_image"; else static if(Derelict_OS_Posix) enum libNames = "libSDL2_image.so,libSDL2_image-2.0.so,libSDL2_image-2.0.so.0,/usr/local/lib/libSDL2_image.so,/usr/local/lib/libSDL2_image-2.0.so,/usr/local/lib/libSDL2_image-2.0.so.0"; else static assert(0,"Need to implement SDL2_image libNames for this operating system."); }CheeseCutter-2.10/src/derelict/sdl2/internal/000077500000000000000000000000001516216315000210615ustar00rootroot00000000000000CheeseCutter-2.10/src/derelict/sdl2/internal/gpu_dynamic.d000066400000000000000000000753311516216315000235360ustar00rootroot00000000000000/* Boost Software License - Version 1.0 - August 17th,2003 Permission is hereby granted,free of charge,to any person or organization obtaining a copy of the software and accompanying documentation covered by this license(the "Software") to use,reproduce,display,distribute, execute,and transmit the Software,and to prepare derivative works of the Software,and to permit third-parties to whom the Software is furnished to do so,all subject to the following: The copyright notices in the Software and this entire statement,including the above license grant,this restriction and the following disclaimer, must be included in all copies of the Software,in whole or in part,and all derivative works of the Software,unless such copies or derivative works are solely in the form of machine-executable object code generated by a source language processor. THE SOFTWARE IS PROVIDED "AS IS",WITHOUT WARRANTY OF ANY KIND,EXPRESS OR IMPLIED,INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE,TITLE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE FOR ANY DAMAGES OR OTHER LIABILITY,WHETHER IN CONTRACT,TORT OR OTHERWISE, ARISING FROM,OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ module derelict.sdl2.internal.gpu_dynamic; import derelict.sdl2.config; static if(!staticGPU) { import core.stdc.config, core.stdc.stdarg; import derelict.sdl2.internal.gpu_types, derelict.sdl2.internal.sdl_types; extern(C) @nogc nothrow { alias da_GPU_GetLinkedVersion = SDL_version function(); alias da_GPU_GetInitWindow = uint function(); alias da_GPU_SetPreInitFlags = void function(GPU_InitFlagEnum); alias da_GPU_GetPreInitFlags = GPU_InitFlagEnum function(); alias da_GPU_SetRequiredFeatures = void function(GPU_FeatureEnum); alias da_GPU_GetRequiredFeatures = GPU_FeatureEnum function(); alias da_GPU_GetDefaultRendererOrder = void function(int*,GPU_RendererID*); alias da_GPU_GetRendererOrder = void function(int*,GPU_RendererID); alias da_GPU_SetRendererOrder = void function(int*,GPU_RendererID); alias da_GPU_Init = GPU_Target* function(ushort,ushort,GPU_WindowFlagEnum); alias da_GPU_InitRenderer = GPU_Target* function(GPU_RendererEnum,ushort,ushort,GPU_WindowFlagEnum); alias da_GPU_InitRendererByID = GPU_Target* function(GPU_RendererID,ushort,ushort,GPU_WindowFlagEnum); alias da_GPU_IsFeatureEnabled = GPU_bool function(GPU_FeatureEnum); alias da_GPU_CloseCurrentRenderer = void function(); alias da_GPU_Quit = void function(); alias da_GPU_SetDebugLevel = void function(GPU_DebugLevelEnum); alias da_GPU_GetDebugLevel = GPU_DebugLevelEnum function(); alias da_GPU_LogInfo = void function(const(char)*,...); alias da_GPU_LogWarning = void function(const(char)*,...); alias da_GPU_LogError = void function(const(char)*,...); alias da_GPU_SetLogCallback = void function(LogCallback); alias da_GPU_PushErrorCode = void function(const(char)*,GPU_ErrorEnum,const(char)*,...); alias da_GPU_PopErrorCode = GPU_ErrorObject function(); alias da_GPU_GetErrorString = const(char)* function(GPU_ErrorEnum); alias da_GPU_SetErrorQueueMax = void function(uint); alias da_GPU_MakeRendererID = GPU_RendererID function(const(char)*,GPU_RendererEnum,int,int); alias da_GPU_GetRendererID = GPU_RendererID function(GPU_RendererEnum); alias da_GPU_GetNumRegisteredRenderers = int function(); alias da_GPU_GetRegisteredRendererList = void function(GPU_RendererID*); alias da_GPU_RegisterRenderer = void function(GPU_RendererID,RendererConstructor,RendererDestructor); alias da_GPU_ReserveNextRendererEnum = GPU_RendererEnum function(); alias da_GPU_GetNumActiveRenderers = int function(); alias da_GPU_GetActiveRendererList = void function(GPU_RendererID*); alias da_GPU_GetCurrentRenderer = GPU_Renderer* function(); alias da_GPU_SetCurrentRenderer = void function(GPU_RendererID); alias da_GPU_GetRenderer = GPU_Renderer* function(GPU_RendererID); alias da_GPU_FreeRenderer = void function(GPU_Renderer*); alias da_GPU_ResetRendererState = void function(); alias da_GPU_SetCoordinateMode = void function(GPU_bool); alias da_GPU_GetCoordinateMode = GPU_bool function(); alias da_GPU_SetDefaultAnchor = void function(float,float); alias da_GPU_GetDefaultAnchor = void function(float*,float*); alias da_GPU_GetContextTarget = GPU_Target* function(); alias da_GPU_GetWindowTarget = GPU_Target* function(uint); alias da_GPU_CreateTargetFromWindow = GPU_Target* function(uint); alias da_GPU_MakeCurrent = void function(GPU_Target*,uint); alias da_GPU_SetWindowResolution = GPU_bool function(ushort,ushort); alias da_GPU_SetFullscreen = GPU_bool function(GPU_bool,GPU_bool); alias da_GPU_GetFullscreen = GPU_bool function(); alias da_GPU_SetShapeBlending = void function(GPU_bool); alias da_GPU_GetBlendModeFromPreset = GPU_BlendMode function(GPU_BlendPresetEnum); alias da_GPU_SetShapeBlendFunction = void function(GPU_BlendFuncEnum,GPU_BlendFuncEnum,GPU_BlendFuncEnum,GPU_BlendFuncEnum); alias da_GPU_SetShapeBlendEquation = void function(GPU_BlendEqEnum,GPU_BlendEqEnum); alias da_GPU_SetShapeBlendMode = void function(GPU_BlendPresetEnum); alias da_GPU_SetLineThickness = float function(float); alias da_GPU_GetLineThickness = float function(); alias da_GPU_CreateAliasTarget = GPU_Target* function(GPU_Target*); alias da_GPU_LoadTarget = GPU_Target* function(GPU_Image*); alias da_GPU_FreeTarget = void function(GPU_Target*); alias da_GPU_SetVirtualResolution = void function(GPU_Target*,ushort,ushort); alias da_GPU_GetVirtualResolution = void function(GPU_Target*,ushort*,ushort*); alias da_GPU_GetVirtualCoords = void function(GPU_Target*,float*,float*,float,float); alias da_GPU_UnsetVirtualResolution = void function(GPU_Target*); alias da_GPU_MakeRect = GPU_Rect function(float,float,float,float); alias da_GPU_MakeColor = SDL_Color function(ubyte,ubyte,ubyte,ubyte); alias da_GPU_SetViewport = void function(GPU_Target*,GPU_Rect); alias da_GPU_UnsetViewport = void function(GPU_Target*); alias da_GPU_GetDefaultCamera = GPU_Camera function(); alias da_GPU_GetCamera = GPU_Camera function(GPU_Target*); alias da_GPU_SetCamera = GPU_Camera function(GPU_Target*,GPU_Camera); alias da_GPU_EnableCamera = void function(GPU_Target*,GPU_bool); alias da_GPU_IsCameraEnabled = GPU_bool function(GPU_Target*); alias da_GPU_GetPixel = SDL_Color function(GPU_Target*,short,short); alias da_GPU_SetClipRect = GPU_Rect function(GPU_Target*,GPU_Rect); alias da_GPU_SetClip = GPU_Rect function(short,short,ushort,ushort); alias da_GPU_UnsetClip = void function(GPU_Target*); alias da_GPU_IntersectRect = GPU_bool function(GPU_Rect,GPU_Rect,GPU_Rect*); alias da_GPU_IntersectClipRect = GPU_bool function(GPU_Target*,GPU_Rect); alias da_GPU_SetTargetColor = void function(GPU_Target*,SDL_Color); alias da_GPU_SetTargetRGB = void function(GPU_Target*,ubyte,ubyte,ubyte); alias da_GPU_SetTargetRGBA = void function(GPU_Target*,ubyte,ubyte,ubyte,ubyte); alias da_GPU_UnsetTargetColor = void function(GPU_Target*); alias da_GPU_LoadSurface = SDL_Surface* function(const(char*)); alias da_GPU_LoadSurface_RW = SDL_Surface* function(SDL_RWops*,GPU_bool); alias da_GPU_SaveSurface = GPU_bool function(SDL_Surface*,const(char)*,GPU_FileFormatEnum); alias da_GPU_SaveSurface_RW = GPU_bool function(SDL_Surface*,SDL_RWops*,GPU_bool,GPU_FileFormatEnum); alias da_GPU_CreateImage = GPU_Image* function(ushort,ushort,GPU_FormatEnum); alias da_GPU_CreateImageUsingTexture = GPU_Image* function(uint,GPU_bool); alias da_GPU_LoadImage = GPU_Image* function(const(char)*); alias da_GPU_LoadImage_RW = GPU_Image* function(SDL_RWops*,GPU_bool); alias da_GPU_CreateAliasImage = GPU_Image* function(GPU_Image*); alias da_GPU_CopyImage = GPU_Image* function(GPU_Image*); alias da_GPU_FreeImage = void function(GPU_Image*); alias da_GPU_SetImageVirtualResolution = void function(GPU_Image*,ushort,ushort); alias da_GPU_UnsetImageVirtualResolution = void function(GPU_Image*); alias da_GPU_UpdateImage = void function(GPU_Image*,const(GPU_Rect)*,SDL_Surface*,const(GPU_Rect)*); alias da_GPU_UpdateImageBytes = void function(GPU_Image*,const(GPU_Rect)*,const(ubyte)*,int); alias da_GPU_ReplaceImage = GPU_bool function(GPU_Image*,SDL_Surface*,const(GPU_Rect)*); alias da_GPU_SaveImage = GPU_bool function(GPU_Image*,const(char)*,GPU_FileFormatEnum); alias da_GPU_SaveImage_RW = GPU_bool function(GPU_Image*,SDL_RWops*,GPU_bool,GPU_FileFormatEnum); alias da_GPU_GenerateMipmaps = void function(GPU_Image*); alias da_GPU_SetColor = void function(GPU_Image*,SDL_Color); alias da_GPU_SetRGB = void function(GPU_Image*,ubyte,ubyte,ubyte); alias da_GPU_SetRGBA = void function(GPU_Image*,ubyte,ubyte,ubyte,ubyte); alias da_GPU_UnsetColor = void function(GPU_Image*); alias da_GPU_GetBlending = GPU_bool function(GPU_Image*); alias da_GPU_SetBlending = void function(GPU_Image*,GPU_bool); alias da_GPU_SetBlendFunction = void function(GPU_Image*,GPU_BlendFuncEnum,GPU_BlendFuncEnum,GPU_BlendFuncEnum,GPU_BlendFuncEnum); alias da_GPU_SetBlendEquation = void function(GPU_Image*,GPU_BlendEqEnum,GPU_BlendEqEnum); alias da_GPU_SetBlendMode = void function(GPU_Image*,GPU_BlendPresetEnum); alias da_GPU_SetImageFilter = void function(GPU_Image*,GPU_FilterEnum); alias da_GPU_SetAnchor = void function(GPU_Image*,float,float); alias da_GPU_GetAnchor = void function(GPU_Image*,float*,float*); alias da_GPU_GetSnapMode = GPU_SnapEnum function(GPU_Image*); alias da_GPU_SetSnapMode = void function(GPU_Image*,GPU_SnapEnum); alias da_GPU_SetWrapMode = void function(GPU_Image*,GPU_WrapEnum,GPU_WrapEnum); alias da_GPU_CopyImageFromSurface = GPU_Image* function(SDL_Surface*); alias da_GPU_CopyImageFromTarget = GPU_Image* function(GPU_Target*); alias da_GPU_CopySurfaceFromTarget = SDL_Surface* function(GPU_Target*); alias da_GPU_CopySurfaceFromImage = SDL_Surface* function(GPU_Image*); alias da_GPU_VectorLength = float function(float*); alias da_GPU_VectorNormalize = void function(float*); alias da_GPU_VectorDot = float function(float*,float*); alias da_GPU_VectorCross = void function(float*,float*,float*); alias da_GPU_VectorCopy = void function(float*,float*); alias da_GPU_VectorApplyMatrix = void function(float*,float*); alias da_GPU_MatrixCopy = void function(float*,float*); alias da_GPU_MatrixIdentity = void function(float*); alias da_GPU_MatrixOrtho = void function(float*,float,float,float,float,float,float); alias da_GPU_MatrixFrustum = void function(float*,float,float,float,float,float,float); alias da_GPU_MatrixPerspective = void function(float*,float,float,float,float); alias da_GPU_MatrixLookAt = void function(float*,float,float,float,float,float,float,float,float,float); alias da_GPU_MatrixTranslate = void function(float*,float,float,float); alias da_GPU_MatrixScale = void function(float*,float,float,float); alias da_GPU_MatrixRotate = void function(float*,float,float,float,float); alias da_GPU_MatrixMultiply = void function(float*,const(float)*,const(float)*); alias da_GPU_MultiplyAndAssign = void function(float*,float*); alias da_GPU_GetMatrixString = const(char)* function(float*); alias da_GPU_GetCurrentMatrix = float* function(); alias da_GPU_GetModelView = float* function(); alias da_GPU_GetProjection = float* function(); alias da_GPU_GetModelViewProjection = void function(float*); alias da_GPU_MatrixMode = void function(int); alias da_GPU_PushMatrix = void function(); alias da_GPU_PopMatrix = void function(); alias da_GPU_LoadIdentity = void function(); alias da_GPU_Ortho = void function(float,float,float,float,float,float); alias da_GPU_Frustum = void function(float,float,float,float,float,float); alias da_GPU_Translate = void function(float,float,float); alias da_GPU_Scale = void function(float,float,float); alias da_GPU_Rotate = void function(float,float,float,float); alias da_GPU_MultMatrix = void function(float*); alias da_GPU_Clear = void function(GPU_Target*); alias da_GPU_ClearColor = void function(GPU_Target*,SDL_Color); alias da_GPU_ClearRGB = void function(GPU_Target*,ubyte,ubyte,ubyte); alias da_GPU_ClearRGBA = void function(GPU_Target*,ubyte,ubyte,ubyte,ubyte); alias da_GPU_Blit = void function(GPU_Image*,GPU_Rect*,GPU_Target*,float,float); alias da_GPU_BlitRotate = void function(GPU_Image*,GPU_Rect*,GPU_Target*,float,float,float); alias da_GPU_BlitScale = void function(GPU_Image*,GPU_Rect*,GPU_Target*,float,float,float,float); alias da_GPU_BlitTransform = void function(GPU_Image*,GPU_Rect*,GPU_Target*,float,float,float,float,float); alias da_GPU_BlitTransformX = void function(GPU_Image*,GPU_Rect*,GPU_Target*,float,float,float,float,float,float,float); alias da_GPU_BlitRect = void function(GPU_Image*,GPU_Rect*,GPU_Target*,GPU_Rect*); alias da_GPU_BlitRectX = void function(GPU_Image*,GPU_Rect*,GPU_Target*,GPU_Rect*,float,float,float,GPU_FlipEnum); alias da_GPU_TriangleBatch = void function(GPU_Image*,GPU_Target*,ushort,float*,uint,ushort*,GPU_BatchFlagEnum); alias da_GPU_TriangleBatchX = void function(GPU_Image*,GPU_Target*,ushort,void*,uint,ushort*,GPU_BatchFlagEnum); alias da_GPU_FlushBlitBuffer = void function(); alias da_GPU_Flip = void function(GPU_Target*); alias da_GPU_Pixel = void function(GPU_Target*,float,float,SDL_Color); alias da_GPU_Line = void function(GPU_Target*,float,float,float,float,SDL_Color); alias da_GPU_Arc = void function(GPU_Target*,float,float,float,float,float,SDL_Color); alias da_GPU_ArcFilled = void function(GPU_Target*,float,float,float,float,float,SDL_Color); alias da_GPU_Circle = void function(GPU_Target*,float,float,float,SDL_Color); alias da_GPU_CircleFilled = void function(GPU_Target*,float,float,float,SDL_Color); alias da_GPU_Ellipse = void function(GPU_Target*,float,float,float,float,float,SDL_Color); alias da_GPU_EllipseFilled = void function(GPU_Target*,float,float,float,float,float,SDL_Color); alias da_GPU_Sector = void function(GPU_Target*,float,float,float,float,float,float,SDL_Color); alias da_GPU_SectorFilled = void function(GPU_Target*,float,float,float,float,float,float,SDL_Color); alias da_GPU_Tri = void function(GPU_Target*,float,float,float,float,float,float,SDL_Color); alias da_GPU_TriFilled = void function(GPU_Target*,float,float,float,float,float,float,SDL_Color); alias da_GPU_Rectangle = void function(GPU_Target*,float,float,float,float,SDL_Color); alias da_GPU_Rectangle2 = void function(GPU_Target*,GPU_Rect,SDL_Color); alias da_GPU_RectangleFilled = void function(GPU_Target*,float,float,float,float,SDL_Color); alias da_GPU_RectangleFilled2 = void function(GPU_Target*,GPU_Rect,SDL_Color); alias da_GPU_RectangleRound = void function(GPU_Target*,float,float,float,float,float,SDL_Color); alias da_GPU_RectangleRound2 = void function(GPU_Target*,GPU_Rect,float,SDL_Color); alias da_GPU_RectangleRoundFilled = void function(GPU_Target*,float,float,float,float,float,SDL_Color); alias da_GPU_RectangleRoundFilled2 = void function(GPU_Target*,GPU_Rect,float,SDL_Color); alias da_GPU_Polygon = void function(GPU_Target*,uint,float*,SDL_Color); alias da_GPU_PolygonFilled = void function(GPU_Target*,uint,float*,SDL_Color); alias da_GPU_CreateShaderProgram = uint function(); alias da_GPU_FreeShaderProgram = void function(uint); alias da_GPU_CompileShader_RW = uint function(GPU_ShaderEnum,SDL_RWops*,GPU_bool); alias da_GPU_CompileShader = uint function(GPU_ShaderEnum,const(char)*); alias da_GPU_LoadShader = uint function(GPU_ShaderEnum,const(char)*); alias da_GPU_LinkShaders = uint function(uint,uint); alias da_GPU_LinkManyShaders = uint function(uint*,int); alias da_GPU_FreeShader = void function(uint); alias da_GPU_AttachShader = void function(uint,uint); alias da_GPU_DetachShader = void function(uint,uint); alias da_GPU_LinkShaderProgram = GPU_bool function(uint); alias da_GPU_GetCurrentShaderProgram = uint function(); alias da_GPU_IsDefaultShaderProgram = GPU_bool function(uint); alias da_GPU_ActivateShaderProgram = void function(uint,GPU_ShaderBlock*); alias da_GPU_DeactivateShaderProgram = void function(); alias da_GPU_GetShaderMessage = const(char)* function(); alias da_GPU_GetAttributeLocation = int function(uint,const(char)*); alias da_GPU_MakeAttributeFormat = GPU_AttributeFormat function(int,GPU_TypeEnum,GPU_bool,int,int); alias da_GPU_MakeAttribute = GPU_Attribute function(int,void*,GPU_AttributeFormat); alias da_GPU_GetUniformLocation = int function(uint,const(char)*); alias da_GPU_LoadShaderBlock = GPU_ShaderBlock function(uint,const(char)*,const(char)*,const(char)*,const(char)*); alias da_GPU_SetShaderBlock = void function(GPU_ShaderBlock); alias da_GPU_GetShaderBlock = GPU_ShaderBlock function(); alias da_GPU_SetShaderImage = void function(GPU_Image*,int,int); alias da_GPU_GetUniformiv = void function(uint,int,int*); alias da_GPU_SetUniformi = void function(int,int); alias da_GPU_SetUniformiv = void function(int,int,int,int*); alias da_GPU_GetUniformuiv = void function(uint,int,uint*); alias da_GPU_SetUniformui = void function(int,uint); alias da_GPU_SetUniformuiv = void function(int,int,int,uint*); alias da_GPU_GetUniformfv = void function(uint,int,float*); alias da_GPU_SetUniformf = void function(int,float); alias da_GPU_SetUniformfv = void function(int,int,int,float*); alias da_GPU_GetUniformMatrixfv = void function(uint,int,float*); alias da_GPU_SetUniformMatrixfv = void function(int,int,int,int,GPU_bool,float*); alias da_GPU_SetAttributef = void function(int,float); alias da_GPU_SetAttributei = void function(int,int); alias da_GPU_SetAttributeui = void function(int,uint); alias da_GPU_SetAttributefv = void function(int,int,float*); alias da_GPU_SetAttributeiv = void function(int,int,int*); alias da_GPU_SetAttributeuiv = void function(int,int,uint*); alias da_GPU_SetAttributeSource = void function(int,GPU_Attribute); } __gshared { da_GPU_GetLinkedVersion GPU_GetLinkedVersion; da_GPU_GetInitWindow GPU_GetInitWindow; da_GPU_SetPreInitFlags GPU_SetPreInitFlags; da_GPU_GetPreInitFlags GPU_GetPreInitFlags; da_GPU_SetRequiredFeatures GPU_SetRequiredFeatures; da_GPU_GetRequiredFeatures GPU_GetRequiredFeatures; da_GPU_GetDefaultRendererOrder GPU_GetDefaultRendererOrder; da_GPU_GetRendererOrder GPU_GetRendererOrder; da_GPU_SetRendererOrder GPU_SetRendererOrder; da_GPU_Init GPU_Init; da_GPU_InitRenderer GPU_InitRenderer; da_GPU_InitRendererByID GPU_InitRendererByID; da_GPU_IsFeatureEnabled GPU_IsFeatureEnabled; da_GPU_CloseCurrentRenderer GPU_CloseCurrentRenderer; da_GPU_Quit GPU_Quit; da_GPU_SetDebugLevel GPU_SetDebugLevel; da_GPU_GetDebugLevel GPU_GetDebugLevel; da_GPU_LogInfo GPU_LogInfo; da_GPU_LogWarning GPU_LogWarning; da_GPU_LogError GPU_LogError; da_GPU_SetLogCallback GPU_SetLogCallback; da_GPU_PushErrorCode GPU_PushErrorCode; da_GPU_PopErrorCode GPU_PopErrorCode; da_GPU_GetErrorString GPU_GetErrorString; da_GPU_SetErrorQueueMax GPU_SetErrorQueueMax; da_GPU_MakeRendererID GPU_MakeRendererID; da_GPU_GetRendererID GPU_GetRendererID; da_GPU_GetNumRegisteredRenderers GPU_GetNumRegisteredRenderers; da_GPU_GetRegisteredRendererList GPU_GetRegisteredRendererList; da_GPU_RegisterRenderer GPU_RegisterRenderer; da_GPU_ReserveNextRendererEnum GPU_ReserveNextRendererEnum; da_GPU_GetNumActiveRenderers GPU_GetNumActiveRenderers; da_GPU_GetActiveRendererList GPU_GetActiveRendererList; da_GPU_GetCurrentRenderer GPU_GetCurrentRenderer; da_GPU_SetCurrentRenderer GPU_SetCurrentRenderer; da_GPU_GetRenderer GPU_GetRenderer; da_GPU_FreeRenderer GPU_FreeRenderer; da_GPU_ResetRendererState GPU_ResetRendererState; da_GPU_SetCoordinateMode GPU_SetCoordinateMode; da_GPU_GetCoordinateMode GPU_GetCoordinateMode; da_GPU_SetDefaultAnchor GPU_SetDefaultAnchor; da_GPU_GetDefaultAnchor GPU_GetDefaultAnchor; da_GPU_GetContextTarget GPU_GetContextTarget; da_GPU_GetWindowTarget GPU_GetWindowTarget; da_GPU_CreateTargetFromWindow GPU_CreateTargetFromWindow; da_GPU_MakeCurrent GPU_MakeCurrent; da_GPU_SetWindowResolution GPU_SetWindowResolution; da_GPU_SetFullscreen GPU_SetFullscreen; da_GPU_GetFullscreen GPU_GetFullscreen; da_GPU_SetShapeBlending GPU_SetShapeBlending; da_GPU_GetBlendModeFromPreset GPU_GetBlendModeFromPreset; da_GPU_SetShapeBlendFunction GPU_SetShapeBlendFunction; da_GPU_SetShapeBlendEquation GPU_SetShapeBlendEquation; da_GPU_SetShapeBlendMode GPU_SetShapeBlendMode; da_GPU_SetLineThickness GPU_SetLineThickness; da_GPU_GetLineThickness GPU_GetLineThickness; da_GPU_CreateAliasTarget GPU_CreateAliasTarget; da_GPU_LoadTarget GPU_LoadTarget; da_GPU_FreeTarget GPU_FreeTarget; da_GPU_SetVirtualResolution GPU_SetVirtualResolution; da_GPU_GetVirtualResolution GPU_GetVirtualResolution; da_GPU_GetVirtualCoords GPU_GetVirtualCoords; da_GPU_UnsetVirtualResolution GPU_UnsetVirtualResolution; da_GPU_MakeRect GPU_MakeRect; da_GPU_MakeColor GPU_MakeColor; da_GPU_SetViewport GPU_SetViewport; da_GPU_UnsetViewport GPU_UnsetViewport; da_GPU_GetDefaultCamera GPU_GetDefaultCamera; da_GPU_GetCamera GPU_GetCamera; da_GPU_SetCamera GPU_SetCamera; da_GPU_EnableCamera GPU_EnableCamera; da_GPU_IsCameraEnabled GPU_IsCameraEnabled; da_GPU_GetPixel GPU_GetPixel; da_GPU_SetClipRect GPU_SetClipRect; da_GPU_SetClip GPU_SetClip; da_GPU_UnsetClip GPU_UnsetClip; da_GPU_IntersectRect GPU_IntersectRect; da_GPU_IntersectClipRect GPU_IntersectClipRect; da_GPU_SetTargetColor GPU_SetTargetColor; da_GPU_SetTargetRGB GPU_SetTargetRGB; da_GPU_SetTargetRGBA GPU_SetTargetRGBA; da_GPU_UnsetTargetColor GPU_UnsetTargetColor; da_GPU_LoadSurface GPU_LoadSurface; da_GPU_LoadSurface_RW GPU_LoadSurface_RW; da_GPU_SaveSurface GPU_SaveSurface; da_GPU_SaveSurface_RW GPU_SaveSurface_RW; da_GPU_CreateImage GPU_CreateImage; da_GPU_CreateImageUsingTexture GPU_CreateImageUsingTexture; da_GPU_LoadImage GPU_LoadImage; da_GPU_LoadImage_RW GPU_LoadImage_RW; da_GPU_CreateAliasImage GPU_CreateAliasImage; da_GPU_CopyImage GPU_CopyImage; da_GPU_FreeImage GPU_FreeImage; da_GPU_SetImageVirtualResolution GPU_SetImageVirtualResolution; da_GPU_UnsetImageVirtualResolution GPU_UnsetImageVirtualResolution; da_GPU_UpdateImage GPU_UpdateImage; da_GPU_UpdateImageBytes GPU_UpdateImageBytes; da_GPU_ReplaceImage GPU_ReplaceImage; da_GPU_SaveImage GPU_SaveImage; da_GPU_SaveImage_RW GPU_SaveImage_RW; da_GPU_GenerateMipmaps GPU_GenerateMipmaps; da_GPU_SetColor GPU_SetColor; da_GPU_SetRGB GPU_SetRGB; da_GPU_SetRGBA GPU_SetRGBA; da_GPU_UnsetColor GPU_UnsetColor; da_GPU_GetBlending GPU_GetBlending; da_GPU_SetBlending GPU_SetBlending; da_GPU_SetBlendFunction GPU_SetBlendFunction; da_GPU_SetBlendEquation GPU_SetBlendEquation; da_GPU_SetBlendMode GPU_SetBlendMode; da_GPU_SetImageFilter GPU_SetImageFilter; da_GPU_SetAnchor GPU_SetAnchor; da_GPU_GetAnchor GPU_GetAnchor; da_GPU_GetSnapMode GPU_GetSnapMode; da_GPU_SetSnapMode GPU_SetSnapMode; da_GPU_SetWrapMode GPU_SetWrapMode; da_GPU_CopyImageFromSurface GPU_CopyImageFromSurface; da_GPU_CopyImageFromTarget GPU_CopyImageFromTarget; da_GPU_CopySurfaceFromTarget GPU_CopySurfaceFromTarget; da_GPU_CopySurfaceFromImage GPU_CopySurfaceFromImage; da_GPU_VectorLength GPU_VectorLength; da_GPU_VectorNormalize GPU_VectorNormalize; da_GPU_VectorDot GPU_VectorDot; da_GPU_VectorCross GPU_VectorCross; da_GPU_VectorCopy GPU_VectorCopy; da_GPU_VectorApplyMatrix GPU_VectorApplyMatrix; da_GPU_MatrixCopy GPU_MatrixCopy; da_GPU_MatrixIdentity GPU_MatrixIdentity; da_GPU_MatrixOrtho GPU_MatrixOrtho; da_GPU_MatrixFrustum GPU_MatrixFrustum; da_GPU_MatrixPerspective GPU_MatrixPerspective; da_GPU_MatrixLookAt GPU_MatrixLookAt; da_GPU_MatrixTranslate GPU_MatrixTranslate; da_GPU_MatrixScale GPU_MatrixScale; da_GPU_MatrixRotate GPU_MatrixRotate; da_GPU_MatrixMultiply GPU_MatrixMultiply; da_GPU_MultiplyAndAssign GPU_MultiplyAndAssign; da_GPU_GetMatrixString GPU_GetMatrixString; da_GPU_GetCurrentMatrix GPU_GetCurrentMatrix; da_GPU_GetModelView GPU_GetModelView; da_GPU_GetProjection GPU_GetProjection; da_GPU_GetModelViewProjection GPU_GetModelViewProjection; da_GPU_MatrixMode GPU_MatrixMode; da_GPU_PushMatrix GPU_PushMatrix; da_GPU_PopMatrix GPU_PopMatrix; da_GPU_LoadIdentity GPU_LoadIdentity; da_GPU_Ortho GPU_Ortho; da_GPU_Frustum GPU_Frustum; da_GPU_Translate GPU_Translate; da_GPU_Scale GPU_Scale; da_GPU_Rotate GPU_Rotate; da_GPU_MultMatrix GPU_MultMatrix; da_GPU_Clear GPU_Clear; da_GPU_ClearColor GPU_ClearColor; da_GPU_ClearRGB GPU_ClearRGB; da_GPU_ClearRGBA GPU_ClearRGBA; da_GPU_Blit GPU_Blit; da_GPU_BlitRotate GPU_BlitRotate; da_GPU_BlitScale GPU_BlitScale; da_GPU_BlitTransform GPU_BlitTransform; da_GPU_BlitTransformX GPU_BlitTransformX; da_GPU_BlitRect GPU_BlitRect; da_GPU_BlitRectX GPU_BlitRectX; da_GPU_TriangleBatch GPU_TriangleBatch; da_GPU_TriangleBatchX GPU_TriangleBatchX; da_GPU_FlushBlitBuffer GPU_FlushBlitBuffer; da_GPU_Flip GPU_Flip; da_GPU_Pixel GPU_Pixel; da_GPU_Line GPU_Line; da_GPU_Arc GPU_Arc; da_GPU_ArcFilled GPU_ArcFilled; da_GPU_Circle GPU_Circle; da_GPU_CircleFilled GPU_CircleFilled; da_GPU_Ellipse GPU_Ellipse; da_GPU_EllipseFilled GPU_EllipseFilled; da_GPU_Sector GPU_Sector; da_GPU_SectorFilled GPU_SectorFilled; da_GPU_Tri GPU_Tri; da_GPU_TriFilled GPU_TriFilled; da_GPU_Rectangle GPU_Rectangle; da_GPU_Rectangle2 GPU_Rectangle2; da_GPU_RectangleFilled GPU_RectangleFilled; da_GPU_RectangleFilled2 GPU_RectangleFilled2; da_GPU_RectangleRound GPU_RectangleRound; da_GPU_RectangleRound2 GPU_RectangleRound2; da_GPU_RectangleRoundFilled GPU_RectangleRoundFilled; da_GPU_RectangleRoundFilled2 GPU_RectangleRoundFilled2; da_GPU_Polygon GPU_Polygon; da_GPU_PolygonFilled GPU_PolygonFilled; da_GPU_CreateShaderProgram GPU_CreateShaderProgram; da_GPU_FreeShaderProgram GPU_FreeShaderProgram; da_GPU_CompileShader_RW GPU_CompileShader_RW; da_GPU_CompileShader GPU_CompileShader; da_GPU_LoadShader GPU_LoadShader; da_GPU_LinkShaders GPU_LinkShaders; da_GPU_LinkManyShaders GPU_LinkManyShaders; da_GPU_FreeShader GPU_FreeShader; da_GPU_AttachShader GPU_AttachShader; da_GPU_DetachShader GPU_DetachShader; da_GPU_LinkShaderProgram GPU_LinkShaderProgram; da_GPU_GetCurrentShaderProgram GPU_GetCurrentShaderProgram; da_GPU_IsDefaultShaderProgram GPU_IsDefaultShaderProgram; da_GPU_ActivateShaderProgram GPU_ActivateShaderProgram; da_GPU_DeactivateShaderProgram GPU_DeactivateShaderProgram; da_GPU_GetShaderMessage GPU_GetShaderMessage; da_GPU_GetAttributeLocation GPU_GetAttributeLocation; da_GPU_MakeAttributeFormat GPU_MakeAttributeFormat; da_GPU_MakeAttribute GPU_MakeAttribute; da_GPU_GetUniformLocation GPU_GetUniformLocation; da_GPU_LoadShaderBlock GPU_LoadShaderBlock; da_GPU_SetShaderBlock GPU_SetShaderBlock; da_GPU_GetShaderBlock GPU_GetShaderBlock; da_GPU_SetShaderImage GPU_SetShaderImage; da_GPU_GetUniformiv GPU_GetUniformiv; da_GPU_SetUniformi GPU_SetUniformi; da_GPU_SetUniformiv GPU_SetUniformiv; da_GPU_GetUniformuiv GPU_GetUniformuiv; da_GPU_SetUniformui GPU_SetUniformui; da_GPU_SetUniformuiv GPU_SetUniformuiv; da_GPU_GetUniformfv GPU_GetUniformfv; da_GPU_SetUniformf GPU_SetUniformf; da_GPU_SetUniformfv GPU_SetUniformfv; da_GPU_GetUniformMatrixfv GPU_GetUniformMatrixfv; da_GPU_SetUniformMatrixfv GPU_SetUniformMatrixfv; da_GPU_SetAttributef GPU_SetAttributef; da_GPU_SetAttributei GPU_SetAttributei; da_GPU_SetAttributeui GPU_SetAttributeui; da_GPU_SetAttributefv GPU_SetAttributefv; da_GPU_SetAttributeiv GPU_SetAttributeiv; da_GPU_SetAttributeuiv GPU_SetAttributeuiv; da_GPU_SetAttributeSource GPU_SetAttributeSource; } }CheeseCutter-2.10/src/derelict/sdl2/internal/gpu_dynload.d000066400000000000000000000473321516216315000235440ustar00rootroot00000000000000/* Boost Software License - Version 1.0 - August 17th,2003 Permission is hereby granted,free of charge,to any person or organization obtaining a copy of the software and accompanying documentation covered by this license(the "Software") to use,reproduce,display,distribute, execute,and transmit the Software,and to prepare derivative works of the Software,and to permit third-parties to whom the Software is furnished to do so,all subject to the following: The copyright notices in the Software and this entire statement,including the above license grant,this restriction and the following disclaimer, must be included in all copies of the Software,in whole or in part,and all derivative works of the Software,unless such copies or derivative works are solely in the form of machine-executable object code generated by a source language processor. THE SOFTWARE IS PROVIDED "AS IS",WITHOUT WARRANTY OF ANY KIND,EXPRESS OR IMPLIED,INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE,TITLE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE FOR ANY DAMAGES OR OTHER LIABILITY,WHETHER IN CONTRACT,TORT OR OTHERWISE, ARISING FROM,OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ module derelict.sdl2.internal.gpu_dynload; import derelict.sdl2.config; static if(!staticGPU) { import derelict.util.loader, derelict.util.system; public import derelict.sdl2.internal.gpu_dynamic; class DerelictSDL2GPULoader : SharedLibLoader { this() { super(libNames); } protected override void loadSymbols() { bindFunc(cast(void**)&GPU_GetLinkedVersion, "GPU_GetLinkedVersion"); bindFunc(cast(void**)&GPU_GetInitWindow, "GPU_GetInitWindow"); bindFunc(cast(void**)&GPU_SetPreInitFlags, "GPU_SetPreInitFlags"); bindFunc(cast(void**)&GPU_GetPreInitFlags, "GPU_GetPreInitFlags"); bindFunc(cast(void**)&GPU_SetRequiredFeatures, "GPU_SetRequiredFeatures"); bindFunc(cast(void**)&GPU_GetRequiredFeatures, "GPU_GetRequiredFeatures"); bindFunc(cast(void**)&GPU_GetDefaultRendererOrder, "GPU_GetDefaultRendererOrder"); bindFunc(cast(void**)&GPU_GetRendererOrder, "GPU_GetRendererOrder"); bindFunc(cast(void**)&GPU_SetRendererOrder, "GPU_SetRendererOrder"); bindFunc(cast(void**)&GPU_Init, "GPU_Init"); bindFunc(cast(void**)&GPU_InitRenderer, "GPU_InitRenderer"); bindFunc(cast(void**)&GPU_InitRendererByID, "GPU_InitRendererByID"); bindFunc(cast(void**)&GPU_IsFeatureEnabled, "GPU_IsFeatureEnabled"); bindFunc(cast(void**)&GPU_CloseCurrentRenderer, "GPU_CloseCurrentRenderer"); bindFunc(cast(void**)&GPU_Quit, "GPU_Quit"); bindFunc(cast(void**)&GPU_SetDebugLevel, "GPU_SetDebugLevel"); bindFunc(cast(void**)&GPU_GetDebugLevel, "GPU_GetDebugLevel"); bindFunc(cast(void**)&GPU_LogInfo, "GPU_LogInfo"); bindFunc(cast(void**)&GPU_LogWarning, "GPU_LogWarning"); bindFunc(cast(void**)&GPU_LogError, "GPU_LogError"); bindFunc(cast(void**)&GPU_SetLogCallback, "GPU_SetLogCallback"); bindFunc(cast(void**)&GPU_PushErrorCode, "GPU_PushErrorCode"); bindFunc(cast(void**)&GPU_PopErrorCode, "GPU_PopErrorCode"); bindFunc(cast(void**)&GPU_GetErrorString, "GPU_GetErrorString"); bindFunc(cast(void**)&GPU_SetErrorQueueMax, "GPU_SetErrorQueueMax"); bindFunc(cast(void**)&GPU_MakeRendererID, "GPU_MakeRendererID"); bindFunc(cast(void**)&GPU_GetRendererID, "GPU_GetRendererID"); bindFunc(cast(void**)&GPU_GetNumRegisteredRenderers, "GPU_GetNumRegisteredRenderers"); bindFunc(cast(void**)&GPU_GetRegisteredRendererList, "GPU_GetRegisteredRendererList"); bindFunc(cast(void**)&GPU_RegisterRenderer, "GPU_RegisterRenderer"); bindFunc(cast(void**)&GPU_ReserveNextRendererEnum, "GPU_ReserveNextRendererEnum"); bindFunc(cast(void**)&GPU_GetNumActiveRenderers, "GPU_GetNumActiveRenderers"); bindFunc(cast(void**)&GPU_GetActiveRendererList, "GPU_GetActiveRendererList"); bindFunc(cast(void**)&GPU_GetCurrentRenderer, "GPU_GetCurrentRenderer"); bindFunc(cast(void**)&GPU_SetCurrentRenderer, "GPU_SetCurrentRenderer"); bindFunc(cast(void**)&GPU_GetRenderer, "GPU_GetRenderer"); bindFunc(cast(void**)&GPU_FreeRenderer, "GPU_FreeRenderer"); bindFunc(cast(void**)&GPU_ResetRendererState, "GPU_ResetRendererState"); bindFunc(cast(void**)&GPU_SetCoordinateMode, "GPU_SetCoordinateMode"); bindFunc(cast(void**)&GPU_GetCoordinateMode, "GPU_GetCoordinateMode"); bindFunc(cast(void**)&GPU_SetDefaultAnchor, "GPU_SetDefaultAnchor"); bindFunc(cast(void**)&GPU_GetDefaultAnchor, "GPU_GetDefaultAnchor"); bindFunc(cast(void**)&GPU_GetContextTarget, "GPU_GetContextTarget"); bindFunc(cast(void**)&GPU_GetWindowTarget, "GPU_GetWindowTarget"); bindFunc(cast(void**)&GPU_CreateTargetFromWindow, "GPU_CreateTargetFromWindow"); bindFunc(cast(void**)&GPU_MakeCurrent, "GPU_MakeCurrent"); bindFunc(cast(void**)&GPU_SetWindowResolution, "GPU_SetWindowResolution"); bindFunc(cast(void**)&GPU_SetFullscreen, "GPU_SetFullscreen"); bindFunc(cast(void**)&GPU_GetFullscreen, "GPU_GetFullscreen"); bindFunc(cast(void**)&GPU_SetShapeBlending, "GPU_SetShapeBlending"); bindFunc(cast(void**)&GPU_GetBlendModeFromPreset, "GPU_GetBlendModeFromPreset"); bindFunc(cast(void**)&GPU_SetShapeBlendFunction, "GPU_SetShapeBlendFunction"); bindFunc(cast(void**)&GPU_SetShapeBlendEquation, "GPU_SetShapeBlendEquation"); bindFunc(cast(void**)&GPU_SetShapeBlendMode, "GPU_SetShapeBlendMode"); bindFunc(cast(void**)&GPU_SetLineThickness, "GPU_SetLineThickness"); bindFunc(cast(void**)&GPU_GetLineThickness, "GPU_GetLineThickness"); bindFunc(cast(void**)&GPU_CreateAliasTarget, "GPU_CreateAliasTarget"); bindFunc(cast(void**)&GPU_LoadTarget, "GPU_LoadTarget"); bindFunc(cast(void**)&GPU_FreeTarget, "GPU_FreeTarget"); bindFunc(cast(void**)&GPU_SetVirtualResolution, "GPU_SetVirtualResolution"); bindFunc(cast(void**)&GPU_GetVirtualResolution, "GPU_GetVirtualResolution"); bindFunc(cast(void**)&GPU_GetVirtualCoords, "GPU_GetVirtualCoords"); bindFunc(cast(void**)&GPU_UnsetVirtualResolution, "GPU_UnsetVirtualResolution"); bindFunc(cast(void**)&GPU_MakeRect, "GPU_MakeRect"); bindFunc(cast(void**)&GPU_MakeColor, "GPU_MakeColor"); bindFunc(cast(void**)&GPU_SetViewport, "GPU_SetViewport"); bindFunc(cast(void**)&GPU_UnsetViewport, "GPU_UnsetViewport"); bindFunc(cast(void**)&GPU_GetDefaultCamera, "GPU_GetDefaultCamera"); bindFunc(cast(void**)&GPU_GetCamera, "GPU_GetCamera"); bindFunc(cast(void**)&GPU_SetCamera, "GPU_SetCamera"); bindFunc(cast(void**)&GPU_EnableCamera, "GPU_EnableCamera"); bindFunc(cast(void**)&GPU_IsCameraEnabled, "GPU_IsCameraEnabled"); bindFunc(cast(void**)&GPU_GetPixel, "GPU_GetPixel"); bindFunc(cast(void**)&GPU_SetClipRect, "GPU_SetClipRect"); bindFunc(cast(void**)&GPU_SetClip, "GPU_SetClip"); bindFunc(cast(void**)&GPU_UnsetClip, "GPU_UnsetClip"); bindFunc(cast(void**)&GPU_IntersectRect, "GPU_IntersectRect"); bindFunc(cast(void**)&GPU_IntersectClipRect, "GPU_IntersectClipRect"); bindFunc(cast(void**)&GPU_SetTargetColor, "GPU_SetTargetColor"); bindFunc(cast(void**)&GPU_SetTargetRGB, "GPU_SetTargetRGB"); bindFunc(cast(void**)&GPU_SetTargetRGBA, "GPU_SetTargetRGBA"); bindFunc(cast(void**)&GPU_UnsetTargetColor, "GPU_UnsetTargetColor"); bindFunc(cast(void**)&GPU_LoadSurface, "GPU_LoadSurface"); bindFunc(cast(void**)&GPU_LoadSurface_RW, "GPU_LoadSurface_RW"); bindFunc(cast(void**)&GPU_SaveSurface, "GPU_SaveSurface"); bindFunc(cast(void**)&GPU_SaveSurface_RW, "GPU_SaveSurface_RW"); bindFunc(cast(void**)&GPU_CreateImage, "GPU_CreateImage"); bindFunc(cast(void**)&GPU_CreateImageUsingTexture, "GPU_CreateImageUsingTexture"); bindFunc(cast(void**)&GPU_LoadImage, "GPU_LoadImage"); bindFunc(cast(void**)&GPU_LoadImage_RW, "GPU_LoadImage_RW"); bindFunc(cast(void**)&GPU_CreateAliasImage, "GPU_CreateAliasImage"); bindFunc(cast(void**)&GPU_CopyImage, "GPU_CopyImage"); bindFunc(cast(void**)&GPU_FreeImage, "GPU_FreeImage"); bindFunc(cast(void**)&GPU_SetImageVirtualResolution, "GPU_SetImageVirtualResolution"); bindFunc(cast(void**)&GPU_UnsetImageVirtualResolution, "GPU_UnsetImageVirtualResolution"); bindFunc(cast(void**)&GPU_UpdateImage, "GPU_UpdateImage"); bindFunc(cast(void**)&GPU_UpdateImageBytes, "GPU_UpdateImageBytes"); bindFunc(cast(void**)&GPU_ReplaceImage, "GPU_ReplaceImage"); bindFunc(cast(void**)&GPU_SaveImage, "GPU_SaveImage"); bindFunc(cast(void**)&GPU_SaveImage_RW, "GPU_SaveImage_RW"); bindFunc(cast(void**)&GPU_GenerateMipmaps, "GPU_GenerateMipmaps"); bindFunc(cast(void**)&GPU_SetColor, "GPU_SetColor"); bindFunc(cast(void**)&GPU_SetRGB, "GPU_SetRGB"); bindFunc(cast(void**)&GPU_SetRGBA, "GPU_SetRGBA"); bindFunc(cast(void**)&GPU_GetBlending, "GPU_GetBlending"); bindFunc(cast(void**)&GPU_SetBlending, "GPU_SetBlending"); bindFunc(cast(void**)&GPU_SetBlendFunction, "GPU_SetBlendFunction"); bindFunc(cast(void**)&GPU_SetBlendEquation, "GPU_SetBlendEquation"); bindFunc(cast(void**)&GPU_SetBlendMode, "GPU_SetBlendMode"); bindFunc(cast(void**)&GPU_SetImageFilter, "GPU_SetImageFilter"); bindFunc(cast(void**)&GPU_SetAnchor, "GPU_SetAnchor"); bindFunc(cast(void**)&GPU_GetAnchor, "GPU_GetAnchor"); bindFunc(cast(void**)&GPU_GetSnapMode, "GPU_GetSnapMode"); bindFunc(cast(void**)&GPU_SetSnapMode, "GPU_SetSnapMode"); bindFunc(cast(void**)&GPU_SetWrapMode, "GPU_SetWrapMode"); bindFunc(cast(void**)&GPU_CopyImageFromSurface, "GPU_CopyImageFromSurface"); bindFunc(cast(void**)&GPU_CopyImageFromTarget, "GPU_CopyImageFromTarget"); bindFunc(cast(void**)&GPU_CopySurfaceFromTarget, "GPU_CopySurfaceFromTarget"); bindFunc(cast(void**)&GPU_CopySurfaceFromImage, "GPU_CopySurfaceFromImage"); bindFunc(cast(void**)&GPU_VectorLength, "GPU_VectorLength"); bindFunc(cast(void**)&GPU_VectorNormalize, "GPU_VectorNormalize"); bindFunc(cast(void**)&GPU_VectorDot, "GPU_VectorDot"); bindFunc(cast(void**)&GPU_VectorCross, "GPU_VectorCross"); bindFunc(cast(void**)&GPU_VectorCopy, "GPU_VectorCopy"); bindFunc(cast(void**)&GPU_VectorApplyMatrix, "GPU_VectorApplyMatrix"); bindFunc(cast(void**)&GPU_MatrixCopy, "GPU_MatrixCopy"); bindFunc(cast(void**)&GPU_MatrixIdentity, "GPU_MatrixIdentity"); bindFunc(cast(void**)&GPU_MatrixOrtho, "GPU_MatrixOrtho"); bindFunc(cast(void**)&GPU_MatrixFrustum, "GPU_MatrixFrustum"); bindFunc(cast(void**)&GPU_MatrixPerspective, "GPU_MatrixPerspective"); bindFunc(cast(void**)&GPU_MatrixLookAt, "GPU_MatrixLookAt"); bindFunc(cast(void**)&GPU_MatrixTranslate, "GPU_MatrixTranslate"); bindFunc(cast(void**)&GPU_MatrixScale, "GPU_MatrixScale"); bindFunc(cast(void**)&GPU_MatrixRotate, "GPU_MatrixRotate"); bindFunc(cast(void**)&GPU_MatrixMultiply, "GPU_MatrixMultiply"); bindFunc(cast(void**)&GPU_MultiplyAndAssign, "GPU_MultiplyAndAssign"); bindFunc(cast(void**)&GPU_GetMatrixString, "GPU_GetMatrixString"); bindFunc(cast(void**)&GPU_GetCurrentMatrix, "GPU_GetCurrentMatrix"); bindFunc(cast(void**)&GPU_GetModelView, "GPU_GetModelView"); bindFunc(cast(void**)&GPU_GetProjection, "GPU_GetProjection"); bindFunc(cast(void**)&GPU_GetModelViewProjection, "GPU_GetModelViewProjection"); bindFunc(cast(void**)&GPU_MatrixMode, "GPU_MatrixMode"); bindFunc(cast(void**)&GPU_PushMatrix, "GPU_PushMatrix"); bindFunc(cast(void**)&GPU_PopMatrix, "GPU_PopMatrix"); bindFunc(cast(void**)&GPU_LoadIdentity, "GPU_LoadIdentity"); bindFunc(cast(void**)&GPU_Ortho, "GPU_Ortho"); bindFunc(cast(void**)&GPU_Frustum, "GPU_Frustum"); bindFunc(cast(void**)&GPU_Translate, "GPU_Translate"); bindFunc(cast(void**)&GPU_Scale, "GPU_Scale"); bindFunc(cast(void**)&GPU_Rotate, "GPU_Rotate"); bindFunc(cast(void**)&GPU_MultMatrix, "GPU_MultMatrix"); bindFunc(cast(void**)&GPU_Clear, "GPU_Clear"); bindFunc(cast(void**)&GPU_ClearColor, "GPU_ClearColor"); bindFunc(cast(void**)&GPU_ClearRGB, "GPU_ClearRGB"); bindFunc(cast(void**)&GPU_ClearRGBA, "GPU_ClearRGBA"); bindFunc(cast(void**)&GPU_Blit, "GPU_Blit"); bindFunc(cast(void**)&GPU_BlitRotate, "GPU_BlitRotate"); bindFunc(cast(void**)&GPU_BlitScale, "GPU_BlitScale"); bindFunc(cast(void**)&GPU_BlitTransform, "GPU_BlitTransform"); bindFunc(cast(void**)&GPU_BlitTransformX, "GPU_BlitTransformX"); bindFunc(cast(void**)&GPU_BlitRect, "GPU_BlitRect"); bindFunc(cast(void**)&GPU_BlitRectX, "GPU_BlitRectX"); bindFunc(cast(void**)&GPU_TriangleBatch, "GPU_TriangleBatch"); bindFunc(cast(void**)&GPU_TriangleBatchX, "GPU_TriangleBatchX"); bindFunc(cast(void**)&GPU_FlushBlitBuffer, "GPU_FlushBlitBuffer"); bindFunc(cast(void**)&GPU_Flip, "GPU_Flip"); bindFunc(cast(void**)&GPU_Pixel, "GPU_Pixel"); bindFunc(cast(void**)&GPU_Line, "GPU_Line"); bindFunc(cast(void**)&GPU_Arc, "GPU_Arc"); bindFunc(cast(void**)&GPU_ArcFilled, "GPU_ArcFilled"); bindFunc(cast(void**)&GPU_Circle, "GPU_Circle"); bindFunc(cast(void**)&GPU_CircleFilled, "GPU_CircleFilled"); bindFunc(cast(void**)&GPU_Ellipse, "GPU_Ellipse"); bindFunc(cast(void**)&GPU_EllipseFilled, "GPU_EllipseFilled"); bindFunc(cast(void**)&GPU_Sector, "GPU_Sector"); bindFunc(cast(void**)&GPU_SectorFilled, "GPU_SectorFilled"); bindFunc(cast(void**)&GPU_Tri, "GPU_Tri"); bindFunc(cast(void**)&GPU_TriFilled, "GPU_TriFilled"); bindFunc(cast(void**)&GPU_Rectangle, "GPU_Rectangle"); bindFunc(cast(void**)&GPU_Rectangle2, "GPU_Rectangle2"); bindFunc(cast(void**)&GPU_RectangleFilled, "GPU_RectangleFilled"); bindFunc(cast(void**)&GPU_RectangleFilled2, "GPU_RectangleFilled2"); bindFunc(cast(void**)&GPU_RectangleRound, "GPU_RectangleRound"); bindFunc(cast(void**)&GPU_RectangleRound2, "GPU_RectangleRound2"); bindFunc(cast(void**)&GPU_RectangleRoundFilled, "GPU_RectangleRoundFilled"); bindFunc(cast(void**)&GPU_RectangleRoundFilled2, "GPU_RectangleRoundFilled2"); bindFunc(cast(void**)&GPU_Polygon, "GPU_Polygon"); bindFunc(cast(void**)&GPU_PolygonFilled, "GPU_PolygonFilled"); bindFunc(cast(void**)&GPU_CreateShaderProgram, "GPU_CreateShaderProgram"); bindFunc(cast(void**)&GPU_FreeShaderProgram, "GPU_FreeShaderProgram"); bindFunc(cast(void**)&GPU_CompileShader_RW, "GPU_CompileShader_RW"); bindFunc(cast(void**)&GPU_CompileShader, "GPU_CompileShader"); bindFunc(cast(void**)&GPU_LoadShader, "GPU_LoadShader"); bindFunc(cast(void**)&GPU_LinkShaders, "GPU_LinkShaders"); bindFunc(cast(void**)&GPU_LinkManyShaders, "GPU_LinkManyShaders"); bindFunc(cast(void**)&GPU_FreeShader, "GPU_FreeShader"); bindFunc(cast(void**)&GPU_AttachShader, "GPU_AttachShader"); bindFunc(cast(void**)&GPU_DetachShader, "GPU_DetachShader"); bindFunc(cast(void**)&GPU_LinkShaderProgram, "GPU_LinkShaderProgram"); bindFunc(cast(void**)&GPU_GetCurrentShaderProgram, "GPU_GetCurrentShaderProgram"); bindFunc(cast(void**)&GPU_IsDefaultShaderProgram, "GPU_IsDefaultShaderProgram"); bindFunc(cast(void**)&GPU_ActivateShaderProgram, "GPU_ActivateShaderProgram"); bindFunc(cast(void**)&GPU_DeactivateShaderProgram, "GPU_DeactivateShaderProgram"); bindFunc(cast(void**)&GPU_GetShaderMessage, "GPU_GetShaderMessage"); bindFunc(cast(void**)&GPU_GetAttributeLocation, "GPU_GetAttributeLocation"); bindFunc(cast(void**)&GPU_MakeAttributeFormat, "GPU_MakeAttributeFormat"); bindFunc(cast(void**)&GPU_MakeAttribute, "GPU_MakeAttribute"); bindFunc(cast(void**)&GPU_GetUniformLocation, "GPU_GetUniformLocation"); bindFunc(cast(void**)&GPU_LoadShaderBlock, "GPU_LoadShaderBlock"); bindFunc(cast(void**)&GPU_SetShaderBlock, "GPU_SetShaderBlock"); bindFunc(cast(void**)&GPU_GetShaderBlock, "GPU_GetShaderBlock"); bindFunc(cast(void**)&GPU_SetShaderImage, "GPU_SetShaderImage"); bindFunc(cast(void**)&GPU_GetUniformiv, "GPU_GetUniformiv"); bindFunc(cast(void**)&GPU_SetUniformi, "GPU_SetUniformi"); bindFunc(cast(void**)&GPU_SetUniformiv, "GPU_SetUniformiv"); bindFunc(cast(void**)&GPU_GetUniformuiv, "GPU_GetUniformuiv"); bindFunc(cast(void**)&GPU_SetUniformui, "GPU_SetUniformui"); bindFunc(cast(void**)&GPU_SetUniformuiv, "GPU_SetUniformuiv"); bindFunc(cast(void**)&GPU_GetUniformfv, "GPU_GetUniformfv"); bindFunc(cast(void**)&GPU_SetUniformf, "GPU_SetUniformf"); bindFunc(cast(void**)&GPU_SetUniformfv, "GPU_SetUniformfv"); bindFunc(cast(void**)&GPU_GetUniformMatrixfv, "GPU_GetUniformMatrixfv"); bindFunc(cast(void**)&GPU_SetUniformMatrixfv, "GPU_SetUniformMatrixfv"); bindFunc(cast(void**)&GPU_SetAttributef, "GPU_SetAttributef"); bindFunc(cast(void**)&GPU_SetAttributei, "GPU_SetAttributei"); bindFunc(cast(void**)&GPU_SetAttributeui, "GPU_SetAttributeui"); bindFunc(cast(void**)&GPU_SetAttributefv, "GPU_SetAttributefv"); bindFunc(cast(void**)&GPU_SetAttributeiv, "GPU_SetAttributeiv"); bindFunc(cast(void**)&GPU_SetAttributeuiv, "GPU_SetAttributeuiv"); bindFunc(cast(void**)&GPU_SetAttributeSource, "GPU_SetAttributeSource"); } } __gshared DerelictSDL2GPULoader DerelictSDL2GPU; shared static this() { DerelictSDL2GPU = new DerelictSDL2GPULoader(); } private: static if(Derelict_OS_Windows) enum libNames = "SDL2_gpu.dll"; else static if(Derelict_OS_Mac) enum libNames = "/usr/local/lib/libSDL2_gpu.dylib,../Frameworks/SDL2_gpu.framework/SDL2_gpu,/Library/Frameworks/SDL2_gpu.framework/SDL2_gpu,/System/Library/Frameworks/SDL2_gpu.framework/SDL2_gpu"; else static if(Derelict_OS_Posix) enum libNames = "libSDL2_gpu.so"; else static assert(0,"Need to implement SDL2_gpu libNames for this operating system."); }CheeseCutter-2.10/src/derelict/sdl2/internal/gpu_static.d000066400000000000000000000355651516216315000234060ustar00rootroot00000000000000/* Boost Software License - Version 1.0 - August 17th,2003 Permission is hereby granted,free of charge,to any person or organization obtaining a copy of the software and accompanying documentation covered by this license(the "Software") to use,reproduce,display,distribute, execute,and transmit the Software,and to prepare derivative works of the Software,and to permit third-parties to whom the Software is furnished to do so,all subject to the following: The copyright notices in the Software and this entire statement,including the above license grant,this restriction and the following disclaimer, must be included in all copies of the Software,in whole or in part,and all derivative works of the Software,unless such copies or derivative works are solely in the form of machine-executable object code generated by a source language processor. THE SOFTWARE IS PROVIDED "AS IS",WITHOUT WARRANTY OF ANY KIND,EXPRESS OR IMPLIED,INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE,TITLE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE FOR ANY DAMAGES OR OTHER LIABILITY,WHETHER IN CONTRACT,TORT OR OTHERWISE, ARISING FROM,OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ module derelict.sdl2.internal.gpu_static; import derelict.sdl2.config; static if(staticGPU) { import core.stdc.config, core.stdc.stdarg; import derelict.sdl2.internal.gpu_types, derelict.sdl2.internal.sdl_types; extern(C) @nogc nothrow { SDL_version GPU_GetLinkedVersion(); uint GPU_GetInitWindow(); void GPU_SetPreInitFlags(GPU_InitFlagEnum); GPU_InitFlagEnum GPU_GetPreInitFlags(); void GPU_SetRequiredFeatures(GPU_FeatureEnum); GPU_FeatureEnum GPU_GetRequiredFeatures(); void GPU_GetDefaultRendererOrder(int*,GPU_RendererID*); void GPU_GetRendererOrder(int*,GPU_RendererID); void GPU_SetRendererOrder(int*,GPU_RendererID); GPU_Target* GPU_Init(ushort,ushort,GPU_WindowFlagEnum); GPU_Target* GPU_InitRenderer(GPU_RendererEnum,ushort,ushort,GPU_WindowFlagEnum); GPU_Target* GPU_InitRendererByID(GPU_RendererID,ushort,ushort,GPU_WindowFlagEnum); GPU_bool GPU_IsFeatureEnabled(GPU_FeatureEnum); void GPU_CloseCurrentRenderer(); void GPU_Quit(); void GPU_SetDebugLevel(GPU_DebugLevelEnum); GPU_DebugLevelEnum GPU_GetDebugLevel(); void GPU_LogInfo(const(char)*,...); void GPU_LogWarning(const(char)*,...); void GPU_LogError(const(char)*,...); void GPU_SetLogCallback(LogCallback); void GPU_PushErrorCode(const(char)*,GPU_ErrorEnum,const(char)*,...); GPU_ErrorObject GPU_PopErrorCode(); const(char)* GPU_GetErrorString(GPU_ErrorEnum); void GPU_SetErrorQueueMax(uint); GPU_RendererID GPU_MakeRendererID(const(char)*,GPU_RendererEnum,int,int); GPU_RendererID GPU_GetRendererID(GPU_RendererEnum); int GPU_GetNumRegisteredRenderers(); void GPU_GetRegisteredRendererList(GPU_RendererID*); void GPU_RegisterRenderer(GPU_RendererID,RendererConstructor,RendererDestructor); GPU_RendererEnum GPU_ReserveNextRendererEnum(); int GPU_GetNumActiveRenderers(); void GPU_GetActiveRendererList(GPU_RendererID*); GPU_Renderer* GPU_GetCurrentRenderer(); void GPU_SetCurrentRenderer(GPU_RendererID); GPU_Renderer* GPU_GetRenderer(GPU_RendererID); void GPU_FreeRenderer(GPU_Renderer*); void GPU_ResetRendererState(); void GPU_SetCoordinateMode(GPU_bool); GPU_bool GPU_GetCoordinateMode(); void GPU_SetDefaultAnchor(float,float); void GPU_GetDefaultAnchor(float*,float*); GPU_Target* GPU_GetContextTarget(); GPU_Target* GPU_GetWindowTarget(uint); GPU_Target* GPU_CreateTargetFromWindow(uint); void GPU_MakeCurrent(GPU_Target*,uint); GPU_bool GPU_SetWindowResolution(ushort,ushort); GPU_bool GPU_SetFullscreen(GPU_bool,GPU_bool); GPU_bool GPU_GetFullscreen(); void GPU_SetShapeBlending(GPU_bool); GPU_BlendMode GPU_GetBlendModeFromPreset(GPU_BlendPresetEnum); void GPU_SetShapeBlendFunction(GPU_BlendFuncEnum,GPU_BlendFuncEnum,GPU_BlendFuncEnum,GPU_BlendFuncEnum); void GPU_SetShapeBlendEquation(GPU_BlendEqEnum,GPU_BlendEqEnum); void GPU_SetShapeBlendMode(GPU_BlendPresetEnum); float GPU_SetLineThickness(float); float GPU_GetLineThickness(); GPU_Target* GPU_CreateAliasTarget(GPU_Target*); GPU_Target* GPU_LoadTarget(GPU_Image*); void GPU_FreeTarget(GPU_Target*); void GPU_SetVirtualResolution(GPU_Target*,ushort,ushort); void GPU_GetVirtualResolution(GPU_Target*,ushort*,ushort*); void GPU_GetVirtualCoords(GPU_Target*,float*,float*,float,float); void GPU_UnsetVirtualResolution(GPU_Target*); GPU_Rect GPU_MakeRect(float,float,float,float); SDL_Color GPU_MakeColor(ubyte,ubyte,ubyte,ubyte); void GPU_SetViewport(GPU_Target*,GPU_Rect); void GPU_UnsetViewport(GPU_Target*); GPU_Camera GPU_GetDefaultCamera(); GPU_Camera GPU_GetCamera(GPU_Target*); GPU_Camera GPU_SetCamera(GPU_Target*,GPU_Camera); void GPU_EnableCamera(GPU_Target*,GPU_bool); GPU_bool GPU_IsCameraEnabled(GPU_Target*); SDL_Color GPU_GetPixel(GPU_Target*,short,short); GPU_Rect GPU_SetClipRect(GPU_Target*,GPU_Rect); GPU_Rect GPU_SetClip(short,short,ushort,ushort); void GPU_UnsetClip(GPU_Target*); GPU_bool GPU_IntersectRect(GPU_Rect,GPU_Rect,GPU_Rect*); GPU_bool GPU_IntersectClipRect(GPU_Target*,GPU_Rect); void GPU_SetTargetColor(GPU_Target*,SDL_Color); void GPU_SetTargetRGB(GPU_Target*,ubyte,ubyte,ubyte); void GPU_SetTargetRGBA(GPU_Target*,ubyte,ubyte,ubyte,ubyte); void GPU_UnsetTargetColor(GPU_Target*); SDL_Surface* GPU_LoadSurface(const(char*)); SDL_Surface* GPU_LoadSurface_RW(SDL_RWops*,GPU_bool); GPU_bool GPU_SaveSurface(SDL_Surface*,const(char)*,GPU_FileFormatEnum); GPU_bool GPU_SaveSurface_RW(SDL_Surface*,SDL_RWops*,GPU_bool,GPU_FileFormatEnum); GPU_Image* GPU_CreateImage(ushort,ushort,GPU_FormatEnum); GPU_Image* GPU_CreateImageUsingTexture(uint,GPU_bool); GPU_Image* GPU_LoadImage(const(char)*); GPU_Image* GPU_LoadImage_RW(SDL_RWops*,GPU_bool); GPU_Image* GPU_CreateAliasImage(GPU_Image*); GPU_Image* GPU_CopyImage(GPU_Image*); void GPU_FreeImage(GPU_Image*); void GPU_SetImageVirtualResolution(GPU_Image*,ushort,ushort); void GPU_UnsetImageVirtualResolution(GPU_Image*); void GPU_UpdateImage(GPU_Image*,const(GPU_Rect)*,SDL_Surface*,const(GPU_Rect)*); void GPU_UpdateImageBytes(GPU_Image*,const(GPU_Rect)*,const(ubyte)*,int); GPU_bool GPU_ReplaceImage(GPU_Image*,SDL_Surface*,const(GPU_Rect)*); GPU_bool GPU_SaveImage(GPU_Image*,const(char)*,GPU_FileFormatEnum); GPU_bool GPU_SaveImage_RW(GPU_Image*,SDL_RWops*,GPU_bool,GPU_FileFormatEnum); void GPU_GenerateMipmaps(GPU_Image*); void GPU_SetColor(GPU_Image*,SDL_Color); void GPU_SetRGB(GPU_Image*,ubyte,ubyte,ubyte); void GPU_SetRGBA(GPU_Image*,ubyte,ubyte,ubyte,ubyte); GPU_bool GPU_GetBlending(GPU_Image*); void GPU_SetBlending(GPU_Image*,GPU_bool); void GPU_SetBlendFunction(GPU_Image*,GPU_BlendFuncEnum,GPU_BlendFuncEnum,GPU_BlendFuncEnum,GPU_BlendFuncEnum); void GPU_SetBlendEquation(GPU_Image*,GPU_BlendEqEnum,GPU_BlendEqEnum); void GPU_SetBlendMode(GPU_Image*,GPU_BlendPresetEnum); void GPU_SetImageFilter(GPU_Image*,GPU_FilterEnum); void GPU_SetAnchor(GPU_Image*,float,float); void GPU_GetAnchor(GPU_Image*,float*,float*); GPU_SnapEnum GPU_GetSnapMode(GPU_Image*); void GPU_SetSnapMode(GPU_Image*,GPU_SnapEnum); void GPU_SetWrapMode(GPU_Image*,GPU_WrapEnum,GPU_WrapEnum); GPU_Image* GPU_CopyImageFromSurface(SDL_Surface*); GPU_Image* GPU_CopyImageFromTarget(GPU_Target*); SDL_Surface* GPU_CopySurfaceFromTarget(GPU_Target*); SDL_Surface* GPU_CopySurfaceFromImage(GPU_Image*); float GPU_VectorLength(float*); void GPU_VectorNormalize(float*); float GPU_VectorDot(float*,float*); void GPU_VectorCross(float*,float*,float*); void GPU_VectorCopy(float*,float*); void GPU_VectorApplyMatrix(float*,float*); void GPU_MatrixCopy(float*,float*); void GPU_MatrixIdentity(float*); void GPU_MatrixOrtho(float*,float,float,float,float,float,float); void GPU_MatrixFrustum(float*,float,float,float,float,float,float); void GPU_MatrixPerspective(float*,float,float,float,float); void GPU_MatrixLookAt(float*,float,float,float,float,float,float,float,float,float); void GPU_MatrixTranslate(float*,float,float,float); void GPU_MatrixScale(float*,float,float,float); void GPU_MatrixRotate(float*,float,float,float,float); void GPU_MatrixMultiply(float*,const(float)*,const(float)*); void GPU_MultiplyAndAssign(float*,float*); const(char)* GPU_GetMatrixString(float*); float* GPU_GetCurrentMatrix(); float* GPU_GetModelView(); float* GPU_GetProjection(); void GPU_GetModelViewProjection(float*); void GPU_MatrixMode(int); void GPU_PushMatrix(); void GPU_PopMatrix(); void GPU_LoadIdentity(); void GPU_Ortho(float,float,float,float,float,float); void GPU_Frustum(float,float,float,float,float,float); void GPU_Translate(float,float,float); void GPU_Scale(float,float,float); void GPU_Rotate(float,float,float,float); void GPU_MultMatrix(float*); void GPU_Clear(GPU_Target*); void GPU_ClearColor(GPU_Target*,SDL_Color); void GPU_ClearRGB(GPU_Target*,ubyte,ubyte,ubyte); void GPU_ClearRGBA(GPU_Target*,ubyte,ubyte,ubyte,ubyte); void GPU_Blit(GPU_Image*,GPU_Rect*,GPU_Target*,float,float); void GPU_BlitRotate(GPU_Image*,GPU_Rect*,GPU_Target*,float,float,float); void GPU_BlitScale(GPU_Image*,GPU_Rect*,GPU_Target*,float,float,float,float); void GPU_BlitTransform(GPU_Image*,GPU_Rect*,GPU_Target*,float,float,float,float,float); void GPU_BlitTransformX(GPU_Image*,GPU_Rect*,GPU_Target*,float,float,float,float,float,float,float); void GPU_BlitRect(GPU_Image*,GPU_Rect*,GPU_Target*,GPU_Rect*); void GPU_BlitRectX(GPU_Image*,GPU_Rect*,GPU_Target*,GPU_Rect*,float,float,float,GPU_FlipEnum); void GPU_TriangleBatch(GPU_Image*,GPU_Target*,ushort,float*,uint,ushort*,GPU_BatchFlagEnum); void GPU_TriangleBatchX(GPU_Image*,GPU_Target*,ushort,void*,uint,ushort*,GPU_BatchFlagEnum); void GPU_FlushBlitBuffer(); void GPU_Flip(GPU_Target*); void GPU_Pixel(GPU_Target*,float,float,SDL_Color); void GPU_Line(GPU_Target*,float,float,float,float,SDL_Color); void GPU_Arc(GPU_Target*,float,float,float,float,float,SDL_Color); void GPU_ArcFilled(GPU_Target*,float,float,float,float,float,SDL_Color); void GPU_Circle(GPU_Target*,float,float,float,SDL_Color); void GPU_CircleFilled(GPU_Target*,float,float,float,SDL_Color); void GPU_Ellipse(GPU_Target*,float,float,float,float,float,SDL_Color); void GPU_EllipseFilled(GPU_Target*,float,float,float,float,float,SDL_Color); void GPU_Sector(GPU_Target*,float,float,float,float,float,float,SDL_Color); void GPU_SectorFilled(GPU_Target*,float,float,float,float,float,float,SDL_Color); void GPU_Tri(GPU_Target*,float,float,float,float,float,float,SDL_Color); void GPU_TriFilled(GPU_Target*,float,float,float,float,float,float,SDL_Color); void GPU_Rectangle(GPU_Target*,float,float,float,float,SDL_Color); void GPU_Rectangle2(GPU_Target*,GPU_Rect,SDL_Color); void GPU_RectangleFilled(GPU_Target*,float,float,float,float,SDL_Color); void GPU_RectangleFilled2(GPU_Target*,GPU_Rect,SDL_Color); void GPU_RectangleRound(GPU_Target*,float,float,float,float,float,SDL_Color); void GPU_RectangleRound2(GPU_Target*,GPU_Rect,float,SDL_Color); void GPU_RectangleRoundFilled(GPU_Target*,float,float,float,float,float,SDL_Color); void GPU_RectangleRoundFilled2(GPU_Target*,GPU_Rect,float,SDL_Color); void GPU_Polygon(GPU_Target*,uint,float*,SDL_Color); void GPU_PolygonFilled(GPU_Target*,uint,float*,SDL_Color); uint GPU_CreateShaderProgram(); void GPU_FreeShaderProgram(uint); uint GPU_CompileShader_RW(GPU_ShaderEnum,SDL_RWops*,GPU_bool); uint GPU_CompileShader(GPU_ShaderEnum,const(char)*); uint GPU_LoadShader(GPU_ShaderEnum,const(char)*); uint GPU_LinkShaders(uint,uint); uint GPU_LinkManyShaders(uint*,int); void GPU_FreeShader(uint); void GPU_AttachShader(uint,uint); void GPU_DetachShader(uint,uint); GPU_bool GPU_LinkShaderProgram(uint); uint GPU_GetCurrentShaderProgram(); GPU_bool GPU_IsDefaultShaderProgram(uint); void GPU_ActivateShaderProgram(uint,GPU_ShaderBlock*); void GPU_DeactivateShaderProgram(); const(char)* GPU_GetShaderMessage(); int GPU_GetAttributeLocation(uint,const(char)*); GPU_AttributeFormat GPU_MakeAttributeFormat(int,GPU_TypeEnum,GPU_bool,int,int); GPU_Attribute GPU_MakeAttribute(int,void*,GPU_AttributeFormat); int GPU_GetUniformLocation(uint,const(char)*); GPU_ShaderBlock GPU_LoadShaderBlock(uint,const(char)*,const(char)*,const(char)*,const(char)*); void GPU_SetShaderBlock(GPU_ShaderBlock); GPU_ShaderBlock GPU_GetShaderBlock(); void GPU_SetShaderImage(GPU_Image*,int,int); void GPU_GetUniformiv(uint,int,int*); void GPU_SetUniformi(int,int); void GPU_SetUniformiv(int,int,int,int*); void GPU_GetUniformuiv(uint,int,uint*); void GPU_SetUniformui(int,uint); void GPU_SetUniformuiv(int,int,int,uint*); void GPU_GetUniformfv(uint,int,float*); void GPU_SetUniformf(int,float); void GPU_SetUniformfv(int,int,int,float*); void GPU_GetUniformMatrixfv(uint,int,float*); void GPU_SetUniformMatrixfv(int,int,int,int,GPU_bool,float*); void GPU_SetAttributef(int,float); void GPU_SetAttributei(int,int); void GPU_SetAttributeui(int,uint); void GPU_SetAttributefv(int,int,float*); void GPU_SetAttributeiv(int,int,int*); void GPU_SetAttributeuiv(int,int,uint*); void GPU_SetAttributeSource(int,GPU_Attribute); } }CheeseCutter-2.10/src/derelict/sdl2/internal/gpu_types.d000066400000000000000000000272541516216315000232570ustar00rootroot00000000000000/* Boost Software License - Version 1.0 - August 17th,2003 Permission is hereby granted,free of charge,to any person or organization obtaining a copy of the software and accompanying documentation covered by this license(the "Software") to use,reproduce,display,distribute, execute,and transmit the Software,and to prepare derivative works of the Software,and to permit third-parties to whom the Software is furnished to do so,all subject to the following: The copyright notices in the Software and this entire statement,including the above license grant,this restriction and the following disclaimer, must be included in all copies of the Software,in whole or in part,and all derivative works of the Software,unless such copies or derivative works are solely in the form of machine-executable object code generated by a source language processor. THE SOFTWARE IS PROVIDED "AS IS",WITHOUT WARRANTY OF ANY KIND,EXPRESS OR IMPLIED,INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE,TITLE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE FOR ANY DAMAGES OR OTHER LIABILITY,WHETHER IN CONTRACT,TORT OR OTHERWISE, ARISING FROM,OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ module derelict.sdl2.internal.gpu_types; import core.stdc.stdarg : va_list; import derelict.sdl2.internal.sdl_types; version(DerelictSDL2GPU_UseIntBool) alias GPU_bool = int; else alias GPU_bool = bool; enum GPU_FALSE = 0; enum GPU_TRUE = 1; struct GPU_Rect { float x, y; float w, h; } alias GPU_RendererEnum = uint; enum : uint { GPU_RENDERER_UNKNOWN = 0, GPU_RENDERER_OPENGL_1_BASE = 1, GPU_RENDERER_OPENGL_1 = 2, GPU_RENDERER_OPENGL_2 = 3, GPU_RENDERER_OPENGL_3 = 4, GPU_RENDERER_OPENGL_4 = 5, GPU_RENDERER_GLES_1 = 11, GPU_RENDERER_GLES_2 = 12, GPU_RENDERER_GLES_3 = 13, GPU_RENDERER_D3D9 = 21, GPU_RENDERER_D3D10 = 22, GPU_RENDERER_D3D11 = 23, GPU_RENDERER_CUSTOM_0 = 1000, } struct GPU_RendererID { const(char)* name; GPU_RendererEnum renderer; int major_version; int minor_version; } alias GPU_BlendFuncEnum = int; enum { GPU_FUNC_ZERO = 0, GPU_FUNC_ONE = 1, GPU_FUNC_SRC_COLOR = 0x0300, GPU_FUNC_DST_COLOR = 0x0306, GPU_FUNC_ONE_MINUS_SRC = 0x0301, GPU_FUNC_ONE_MINUS_DST = 0x0307, GPU_FUNC_SRC_ALPHA = 0x0302, GPU_FUNC_DST_ALPHA = 0x0304, GPU_FUNC_ONE_MINUS_SRC_ALPHA = 0x0303, GPU_FUNC_ONE_MINUS_DST_ALPHA = 0x0305, } alias GPU_BlendEqEnum = int; enum { GPU_EQ_ADD = 0x8006, GPU_EQ_SUBTRACT = 0x800A, GPU_EQ_REVERSE_SUBRRACT = 0x800B, } struct GPU_BlendMode { GPU_BlendFuncEnum source_color; GPU_BlendFuncEnum dest_color; GPU_BlendFuncEnum source_alpha; GPU_BlendFuncEnum dest_alpha; GPU_BlendEqEnum color_equation; GPU_BlendEqEnum alpha_equation; } alias GPU_BlendPresetEnum = int; enum { GPU_BLEND_NORMAL = 0, GPU_BLEND_PREMULTIPLIED_ALPHA = 1, GPU_BLEND_MULTIPLY = 2, GPU_BLEND_ADD = 3, GPU_BLEND_SUBTRACT = 4, GPU_BLEND_MOD_ALPHA = 5, GPU_BLEND_SET_ALPHA = 6, GPU_BLEND_SET = 7, GPU_BLEND_NORMAL_KEEP_ALPHA = 8, GPU_BLEND_NORMAL_ADD_ALPHA = 9, GPU_BLEND_NORMAL_FACTOR_ALPHA = 10, } alias GPU_FilterEnum = int; enum { GPU_FILTER_NEAREST = 0, GPU_FILTER_LINEAR = 1, GPU_FILTER_LINEAR_MIPMAP = 2, } alias GPU_SnapEnum = int; enum { GPU_SNAP_NONE = 0, GPU_SNAP_POSITION = 1, GPU_SNAP_DIMENSIONS = 2, GPU_SNAP_POSITION_AND_DIMENSIONS = 3 } alias GPU_WrapEnum = int; enum { GPU_WRAP_NONE = 0, GPU_WRAP_REPEAT = 1, GPU_WRAP_MIRRORED = 2 } alias GPU_FormatEnum = int; enum { GPU_FORMAT_LUMINANCE = 1, GPU_FORMAT_LUMINANCE_ALPHA = 2, GPU_FORMAT_RGB = 3, GPU_FORMAT_RGBA = 4, GPU_FORMAT_ALPHA = 5, GPU_FORMAT_RG = 6, GPU_FORMAT_YCbCr422 = 7, GPU_FORMAT_YCbCr420P = 8, } alias GPU_FileFormatEnum = int; enum { GPU_FILE_AUTO = 0, GPU_FILE_PNG, GPU_FILE_BMP, GPU_FILE_TGA } struct GPU_Image { GPU_Renderer* renderer; GPU_Target* context_target; GPU_Target* target; ushort w, h; GPU_bool using_virtual_resolution; GPU_FormatEnum format; int num_layers; int bytes_per_pixel; ushort base_w, base_h; ushort texture_w, texture_h; GPU_bool has_mipmaps; float anchor_x; float anchor_y; SDL_Color color; GPU_bool use_blending; GPU_BlendMode blend_mode; GPU_FilterEnum filter_mode; GPU_SnapEnum snap_mode; GPU_WrapEnum wrap_mode_x; GPU_WrapEnum wrap_mode_y; void* data; int refcount; GPU_bool is_alias; } struct GPU_Camera { float x, y, z; float angle; float zoom; } struct GPU_ShaderBlock { int position_loc; int texcoord_loc; int color_loc; int modelViewProjection_loc; } enum GPU_MODELVIEW = 0; enum GPU_PROJECTION = 1; enum GPU_MATRIX_STACK_MAX = 5; struct GPU_MatrixStack { uint size; float[16][GPU_MATRIX_STACK_MAX] matrix; } struct GPU_Context { void* context; GPU_bool failed; uint windowID; int window_w; int window_h; int drawable_w; int drawable_h; int stored_window_w; int stored_window_h; uint current_shader_program; uint default_textured_shader_program; uint default_untextured_shader_program; GPU_ShaderBlock current_shader_block; GPU_ShaderBlock default_textured_shader_block; GPU_ShaderBlock default_untextured_shader_block; GPU_bool shapes_use_blending; GPU_BlendMode shapes_blend_mode; float line_thickness; GPU_bool use_texturing; int matrix_mode; GPU_MatrixStack projection_matrix; GPU_MatrixStack modelview_matrix; void* data; } struct GPU_Target { GPU_Renderer* renderer; GPU_Target* context_target; GPU_Image* image; void* data; ushort w, h; GPU_bool using_virtual_resolution; ushort base_w, base_h; GPU_bool use_clip_rect; GPU_Rect clip_rect; GPU_bool use_color; SDL_Color color; GPU_Rect viewport; GPU_Camera camera; GPU_bool use_camera; GPU_Context* context; int refcount; GPU_bool is_alias; } alias GPU_FeatureEnum = int; enum { GPU_FEATURE_NON_POWER_OF_TWO = 0x1, GPU_FEATURE_RENDER_TARGETS = 0x2, GPU_FEATURE_BLEND_EQUATIONS = 0x4, GPU_FEATURE_BLEND_FUNC_SEPARATE = 0x8, GPU_FEATURE_BLEND_EQUATIONS_SEPARATE = 0x10, GPU_FEATURE_GL_BGR = 0x20, GPU_FEATURE_GL_BGRA = 0x40, GPU_FEATURE_GL_ABGR = 0x80, GPU_FEATURE_VERTEX_SHADER = 0x100, GPU_FEATURE_FRAGMENT_SHADER = 0x200, GPU_FEATURE_PIXEL_SHADER = 0x200, GPU_FEATURE_GEOMETRY_SHADER = 0x400, GPU_FEATURE_WRAP_REPEAT_MIRRORED = 0x800, } alias GPU_WindowFlagEnum = uint; alias GPU_InitFlagEnum = uint; enum : uint { GPU_INIT_ENABLE_VSYNC = 0x1, GPU_INIT_DISABLE_VSYNC = 0x2, GPU_INIT_DISABLE_DOUBLE_BUFFER = 0x4, GPU_INIT_DISABLE_AUTO_VIRTUAL_RESOLUTION = 0x8, GPU_INIT_REQUEST_COMPATIBILITY_PROFILE = 0x10, } enum GPU_DEFAULT_INIT_FLAGS = 0; enum uint GPU_NONE = 0; alias GPU_BatchFlagEnum = uint; enum : uint { GPU_BATCH_XY = 0x1, GPU_BATCH_XYZ = 0x2, GPU_BATCH_ST = 0x4, GPU_BATCH_RGB = 0x8, GPU_BATCH_RGBA = 0x10, GPU_BATCH_RGB8 = 0x20, GPU_BATCH_RGBA8 = 0x40, GPU_BATCH_XY_ST = GPU_BATCH_XY | GPU_BATCH_ST, GPU_BATCH_XYZ_ST = GPU_BATCH_XYZ | GPU_BATCH_ST, GPU_BATCH_XY_RGB = GPU_BATCH_XY | GPU_BATCH_RGB, GPU_BATCH_XYZ_RGB = GPU_BATCH_XYZ | GPU_BATCH_RGB, GPU_BATCH_XY_RGBA = GPU_BATCH_XY | GPU_BATCH_RGBA, GPU_BATCH_XYZ_RGBA = GPU_BATCH_XYZ | GPU_BATCH_RGBA, GPU_BATCH_XY_ST_RGBA = GPU_BATCH_XY | GPU_BATCH_ST | GPU_BATCH_RGBA, GPU_BATCH_XYZ_ST_RGBA = GPU_BATCH_XYZ | GPU_BATCH_ST | GPU_BATCH_RGBA, GPU_BATCH_XY_RGB8 = GPU_BATCH_XY | GPU_BATCH_RGB8, GPU_BATCH_XYZ_RGB8 = GPU_BATCH_XYZ | GPU_BATCH_RGB8, GPU_BATCH_XY_RGBA8 = GPU_BATCH_XY | GPU_BATCH_RGBA8, GPU_BATCH_XYZ_RGBA8 = GPU_BATCH_XYZ | GPU_BATCH_RGBA8, GPU_BATCH_XY_ST_RGBA8 = GPU_BATCH_XY | GPU_BATCH_ST | GPU_BATCH_RGBA8, GPU_BATCH_XYZ_ST_RGBA8 = GPU_BATCH_XYZ | GPU_BATCH_ST | GPU_BATCH_RGBA8, } alias GPU_FlipEnum = uint; enum : uint { GPU_FLIP_NONE = 0x0, GPU_FLIP_HORIZONTAL = 0x1, GPU_FLIP_VERTICAL = 0x2, } alias GPU_TypeEnum = uint; enum : uint { GPU_TYPE_BYTE = 0x1400, GPU_TYPE_UNSIGNED_BYTE = 0x1401, GPU_TYPE_SHORT = 0x1402, GPU_TYPE_UNSIGNED_SHORT = 0x1403, GPU_TYPE_INT = 0x1404, GPU_TYPE_UNSIGNED_INT = 0x1405, GPU_TYPE_FLOAT = 0x1406, GPU_TYPE_DOUBLE = 0x140A, } alias GPU_ShaderEnum = int; enum { GPU_VERTEX_SHADER = 0, GPU_FRAGMENT_SHADER = 1, GPU_PIXEL_SHADER = 1, GPU_GEOMETRY_SHADER = 2, } alias GPU_ShaderLanguageEnum = int; enum { GPU_LANGUAGE_NONE = 0, GPU_LANGUAGE_ARB_ASSEMBLY = 1, GPU_LANGUAGE_GLSL = 2, GPU_LANGUAGE_GLSLES = 3, GPU_LANGUAGE_HLSL = 4, GPU_LANGUAGE_CG = 5, } struct GPU_AttributeFormat { GPU_bool is_per_sprite; int num_elems_per_value; GPU_TypeEnum type; GPU_bool normalize; int stride_bytes; int offset_bytes; } struct GPU_Attribute { int location; void* values; GPU_AttributeFormat format; } struct GPU_AttributeSource { GPU_bool enabled; int num_values; void* next_value; int per_vertex_storage_stride_bytes; int per_vertex_storage_offset_bytes; int per_vertex_storage_size; void* per_vertex_storage; GPU_Attribute attribute; } alias GPU_ErrorEnum = int; enum { GPU_ERROR_NONE = 0, GPU_ERROR_BACKEND_ERROR = 1, GPU_ERROR_DATA_ERROR = 2, GPU_ERROR_USER_ERROR = 3, GPU_ERROR_UNSUPPORTED_FUNCTION = 4, GPU_ERROR_NULL_ARGUMENT = 5, GPU_ERROR_FILE_NOT_FOUND = 6, } struct GPU_ErrorObject { char* function_; GPU_ErrorEnum error; char* details; } alias GPU_DebugLevelEnum = int; enum { GPU_DEBUG_LEVEL_0 = 0, GPU_DEBUG_LEVEL_1 = 1, GPU_DEBUG_LEVEL_2 = 2, GPU_DEBUG_LEVEL_3 = 3, GPU_DEBUG_LEVEL_MAX = 3, } alias GPU_LogLevelEnum = int; enum { GPU_LOG_INFO = 0, GPU_LOG_WARNING, GPU_LOG_ERROR, } struct GPU_RendererImpl; struct GPU_Renderer { GPU_RendererID id; GPU_RendererID requested_id; GPU_WindowFlagEnum SDL_init_flags; GPU_InitFlagEnum GPU_init_flags; GPU_ShaderLanguageEnum shader_language; int min_shader_version; int max_shader_version; GPU_FeatureEnum enabled_features; GPU_Target* current_context_target; GPU_bool coordinate_mode; float default_image_anchor_x; float default_image_anchor_y; GPU_RendererImpl* impl; } extern(C) nothrow { alias LogCallback = int function(GPU_LogLevelEnum,const(char)*,va_list); alias RendererConstructor = GPU_Renderer* function(GPU_RendererID); alias RendererDestructor = void function(GPU_Renderer*); }CheeseCutter-2.10/src/derelict/sdl2/internal/sdl_dynamic.d000066400000000000000000001631201516216315000235170ustar00rootroot00000000000000/* Boost Software License - Version 1.0 - August 17th,2003 Permission is hereby granted,free of charge,to any person or organization obtaining a copy of the software and accompanying documentation covered by this license (the "Software") to use,reproduce,display,distribute, execute,and transmit the Software,and to prepare derivative works of the Software,and to permit third-parties to whom the Software is furnished to do so,all subject to the following: The copyright notices in the Software and this entire statement,including the above license grant,this restriction and the following disclaimer, must be included in all copies of the Software,in whole or in part,and all derivative works of the Software,unless such copies or derivative works are solely in the form of machine-executable object code generated by a source language processor. THE SOFTWARE IS PROVIDED "AS IS",WITHOUT WARRANTY OF ANY KIND,EXPRESS OR IMPLIED,INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE,TITLE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE FOR ANY DAMAGES OR OTHER LIABILITY,WHETHER IN CONTRACT,TORT OR OTHERWISE, ARISING FROM,OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ module derelict.sdl2.internal.sdl_dynamic; import core.stdc.stdarg, core.stdc.stdio; import derelict.util.system; import derelict.sdl2.internal.sdl_types; extern(C) @nogc nothrow { // SDL.h alias da_SDL_Init = int function(Uint32); alias da_SDL_InitSubSystem = int function(Uint32); alias da_SDL_QuitSubSystem = void function(Uint32); alias da_SDL_WasInit = Uint32 function(Uint32); alias da_SDL_Quit = void function(); alias da_SDL_free = void function(void* mem); // SDL_assert.h alias da_SDL_SetAssertionHandler = void function(SDL_AssertionHandler,void*); alias da_SDL_GetDefaultAssertionHandler = SDL_AssertionHandler function(); alias da_SDL_GetAssertionHandler = SDL_AssertionHandler function(void**); alias da_SDL_GetAssertionReport = const(SDL_assert_data)* function(); alias da_SDL_ResetAssertionReport = void function(); // SDL_audio.h alias da_SDL_GetNumAudioDrivers = int function(); alias da_SDL_GetAudioDriver = const(char)* function(int); alias da_SDL_AudioInit = int function(const(char)*); alias da_SDL_AudioQuit = void function(); alias da_SDL_GetCurrentAudioDriver = const(char)* function(); alias da_SDL_OpenAudio = int function(SDL_AudioSpec*,SDL_AudioSpec*); alias da_SDL_GetNumAudioDevices = int function(int); alias da_SDL_GetAudioDeviceName = const(char)* function(int,int); alias da_SDL_OpenAudioDevice = SDL_AudioDeviceID function(const(char)*,int,const(SDL_AudioSpec)*,SDL_AudioSpec*,int); alias da_SDL_GetAudioStatus = SDL_AudioStatus function(); alias da_SDL_GetAudioDeviceStatus = SDL_AudioStatus function(SDL_AudioDeviceID); alias da_SDL_PauseAudio = void function(int); alias da_SDL_PauseAudioDevice = void function(SDL_AudioDeviceID,int); alias da_SDL_LoadWAV_RW = SDL_AudioSpec* function(SDL_RWops*,int,SDL_AudioSpec*,Uint8**,Uint32*); alias da_SDL_FreeWAV = void function(Uint8*); alias da_SDL_BuildAudioCVT = int function(SDL_AudioCVT*,SDL_AudioFormat,Uint8,int,SDL_AudioFormat,Uint8,int); alias da_SDL_ConvertAudio = int function(SDL_AudioCVT*); alias da_SDL_MixAudio = void function(Uint8*,const(Uint8)*,Uint32,int); alias da_SDL_MixAudioFormat = void function(Uint8*,const(Uint8)*,SDL_AudioFormat,Uint32,int); alias da_SDL_QueueAudio = int function(SDL_AudioDeviceID,const (void)*,Uint32); alias da_SDL_DequeueAudio = Uint32 function(SDL_AudioDeviceID,void*,Uint32); alias da_SDL_GetQueuedAudioSize = int function(SDL_AudioDeviceID); alias da_SDL_ClearQueuedAudio = int function(SDL_AudioDeviceID); alias da_SDL_LockAudio = void function(); alias da_SDL_LockAudioDevice = void function(SDL_AudioDeviceID); alias da_SDL_UnlockAudio = void function(); alias da_SDL_UnlockAudioDevice = void function(SDL_AudioDeviceID); alias da_SDL_CloseAudio = void function(); alias da_SDL_CloseAudioDevice = void function(SDL_AudioDeviceID); alias da_SDL_AudioDeviceConnected = int function(SDL_AudioDeviceID); // SDL_clipboard.h alias da_SDL_SetClipboardText = int function(const(char)*); alias da_SDL_GetClipboardText = char* function(); alias da_SDL_HasClipboardText = SDL_bool function(); // SDL_cpuinfo.h alias da_SDL_GetCPUCount = int function(); alias da_SDL_GetCPUCacheLineSize = int function(); alias da_SDL_HasRDTSC = SDL_bool function(); alias da_SDL_HasAltiVec = SDL_bool function(); alias da_SDL_HasMMX = SDL_bool function(); alias da_SDL_Has3DNow = SDL_bool function(); alias da_SDL_HasSSE = SDL_bool function(); alias da_SDL_HasSSE2 = SDL_bool function(); alias da_SDL_HasSSE3 = SDL_bool function(); alias da_SDL_HasSSE41 = SDL_bool function(); alias da_SDL_HasSSE42 = SDL_bool function(); alias da_SDL_HasAVX = SDL_bool function(); alias da_SDL_HasAVX2 = SDL_bool function(); alias da_SDL_GetSystemRAM = int function(); // SDL_error.h alias da_SDL_SetError = void function(const(char)*,...); alias da_SDL_GetError = const(char)* function(); alias da_SDL_ClearError = void function(); // SDL_events.h alias da_SDL_PumpEvents = void function(); alias da_SDL_PeepEvents = int function(SDL_Event*,int,SDL_eventaction,Uint32,Uint32); alias da_SDL_HasEvent = SDL_bool function(Uint32); alias da_SDL_HasEvents = SDL_bool function(Uint32,Uint32); alias da_SDL_FlushEvent = void function(Uint32); alias da_SDL_FlushEvents = void function(Uint32,Uint32); alias da_SDL_PollEvent = int function(SDL_Event*); alias da_SDL_WaitEvent = int function(SDL_Event*); alias da_SDL_WaitEventTimeout = int function(SDL_Event*,int); alias da_SDL_PushEvent = int function(SDL_Event*); alias da_SDL_SetEventFilter = void function(SDL_EventFilter,void*); alias da_SDL_GetEventFilter = SDL_bool function(SDL_EventFilter*,void**); alias da_SDL_AddEventWatch = void function(SDL_EventFilter,void*); alias da_SDL_DelEventWatch = void function(SDL_EventFilter,void*); alias da_SDL_FilterEvents = void function(SDL_EventFilter,void*); alias da_SDL_EventState = Uint8 function(Uint32,int); alias da_SDL_RegisterEvents = Uint32 function(int); // SDL_filesystem.h alias da_SDL_GetBasePath = char* function(); alias da_SDL_GetPrefPath = char* function(const(char)* org,const(char)* app); // SDL_gamecontroller.h alias da_SDL_GameControllerAddMappingsFromRW = int function(SDL_RWops*,int); alias da_SDL_GameControllerAddMapping = int function(const(char)*); alias da_SDL_GameControllerMappingForGUID = char* function(SDL_JoystickGUID); alias da_SDL_GameControllerMapping = char* function(SDL_GameController*); alias da_SDL_IsGameController = SDL_bool function(int); alias da_SDL_GameControllerNameForIndex = const(char)* function(int); alias da_SDL_GameControllerOpen = SDL_GameController* function(int); alias da_SDL_GameControllerFromInstanceID = SDL_GameController* function(SDL_JoystickID); alias da_SDL_GameControllerName = const(char)* function(SDL_GameController*); alias da_SDL_GameControllerGetAttached = SDL_bool function(SDL_GameController*); alias da_SDL_GameControllerGetJoystick = SDL_Joystick* function(SDL_GameController*); alias da_SDL_GameControllerEventState = int function(int); alias da_SDL_GameControllerUpdate = void function(); alias da_SDL_GameControllerGetAxisFromString = SDL_GameControllerAxis function(const(char)*); alias da_SDL_GameControllerGetStringForAxis = const(char)* function(SDL_GameControllerAxis); alias da_SDL_GameControllerGetBindForAxis = SDL_GameControllerButtonBind function(SDL_GameController*,SDL_GameControllerAxis); alias da_SDL_GameControllerGetAxis = Sint16 function(SDL_GameController*,SDL_GameControllerAxis); alias da_SDL_GameControllerGetButtonFromString = SDL_GameControllerButton function(const(char*)); alias da_SDL_GameControllerGetStringForButton = const(char)* function(SDL_GameControllerButton); alias da_SDL_GameControllerGetBindForButton = SDL_GameControllerButtonBind function(SDL_GameController*,SDL_GameControllerButton); alias da_SDL_GameControllerGetButton = Uint8 function(SDL_GameController*,SDL_GameControllerButton); alias da_SDL_GameControllerClose = void function(SDL_GameController*); // SDL_gesture.h alias da_SDL_RecordGesture = int function(SDL_TouchID); alias da_SDL_SaveAllDollarTemplates = int function(SDL_RWops*); alias da_SDL_SaveDollarTemplate = int function(SDL_GestureID,SDL_RWops*); alias da_SDL_LoadDollarTemplates = int function(SDL_TouchID,SDL_RWops*); // SDL_haptic.h alias da_SDL_NumHaptics = int function(); alias da_SDL_HapticName = const(char)* function(int); alias da_SDL_HapticOpen = SDL_Haptic* function(int); alias da_SDL_HapticOpened = int function(int); alias da_SDL_HapticIndex = int function(SDL_Haptic*); alias da_SDL_MouseIsHaptic = int function(); alias da_SDL_HapticOpenFromMouse = SDL_Haptic* function(); alias da_SDL_JoystickIsHaptic = int function(SDL_Joystick*); alias da_SDL_HapticOpenFromJoystick = SDL_Haptic* function(SDL_Joystick*); alias da_SDL_HapticClose = int function(SDL_Haptic*); alias da_SDL_HapticNumEffects = int function(SDL_Haptic*); alias da_SDL_HapticNumEffectsPlaying = int function(SDL_Haptic*); alias da_SDL_HapticQuery = uint function(SDL_Haptic*); alias da_SDL_HapticNumAxes = int function(SDL_Haptic*); alias da_SDL_HapticEffectSupported = int function(SDL_Haptic*,SDL_HapticEffect*); alias da_SDL_HapticNewEffect = int function(SDL_Haptic*,SDL_HapticEffect*); alias da_SDL_HapticUpdateEffect = int function(SDL_Haptic*,int,SDL_HapticEffect*); alias da_SDL_HapticRunEffect = int function(SDL_Haptic*,int,Uint32); alias da_SDL_HapticStopEffect = int function(SDL_Haptic*,int); alias da_SDL_HapticDestroyEffect = int function(SDL_Haptic*,int); alias da_SDL_HapticGetEffectStatus = int function(SDL_Haptic*,int); alias da_SDL_HapticSetGain = int function(SDL_Haptic*,int); alias da_SDL_HapticSetAutocenter = int function(SDL_Haptic*,int); alias da_SDL_HapticPause = int function(SDL_Haptic*); alias da_SDL_HapticUnpause = int function(SDL_Haptic*); alias da_SDL_HapticStopAll = int function(SDL_Haptic*); alias da_SDL_HapticRumbleSupported = int function(SDL_Haptic*); alias da_SDL_HapticRumbleInit = int function(SDL_Haptic*); alias da_SDL_HapticRumblePlay = int function(SDL_Haptic*,float,Uint32); alias da_SDL_HapticRumbleStop = int function(SDL_Haptic*); // SDL_hints.h alias da_SDL_SetHintWithPriority = SDL_bool function(const(char)*,const(char)*,SDL_HintPriority); alias da_SDL_SetHint = SDL_bool function(const(char)*,const(char)*); alias da_SDL_GetHint = const(char)* function(const(char)*); alias da_SDL_GetHintBoolean = SDL_bool function(const(char)*,SDL_bool); alias da_SDL_AddHintCallback = void function(const(char)*,SDL_HintCallback,void*); alias da_SDL_DelHintCallback = void function(const(char)*,SDL_HintCallback,void*); alias da_SDL_ClearHints = void function(); // SDL_joystick.h alias da_SDL_NumJoysticks = int function(); alias da_SDL_JoystickNameForIndex = const(char)* function(int); alias da_SDL_JoystickOpen = SDL_Joystick* function(int); alias da_SDL_JoystickFromInstanceID = SDL_Joystick* function(SDL_JoystickID); alias da_SDL_JoystickName = const(char)* function(SDL_Joystick*); alias da_SDL_JoystickGetDeviceGUID = SDL_JoystickGUID function(int); alias da_SDL_JoystickGetGUID = SDL_JoystickGUID function(SDL_Joystick*); alias da_SDL_JoystickGetGUIDString = char* function(SDL_JoystickGUID); alias da_SDL_JoystickGetGUIDFromString = SDL_JoystickGUID function(const(char)*); alias da_SDL_JoystickGetAttached = SDL_bool function(SDL_Joystick*); alias da_SDL_JoystickInstanceID = SDL_JoystickID function(SDL_Joystick*); alias da_SDL_JoystickNumAxes = int function(SDL_Joystick*); alias da_SDL_JoystickNumBalls = int function(SDL_Joystick*); alias da_SDL_JoystickNumHats = int function(SDL_Joystick*); alias da_SDL_JoystickNumButtons = int function(SDL_Joystick*); alias da_SDL_JoystickUpdate = void function(); alias da_SDL_JoystickEventState = int function(int); alias da_SDL_JoystickGetAxis = Sint16 function(SDL_Joystick*,int); alias da_SDL_JoystickGetHat = Uint8 function(SDL_Joystick*,int); alias da_SDL_JoystickGetBall = int function(SDL_Joystick*,int,int*,int*); alias da_SDL_JoystickGetButton = Uint8 function(SDL_Joystick*,int); alias da_SDL_JoystickClose = void function(SDL_Joystick*); alias da_SDL_JoystickCurrentPowerLevel = SDL_JoystickPowerLevel function(SDL_Joystick*); // SDL_keyboard.h alias da_SDL_GetKeyboardFocus = SDL_Window* function(); alias da_SDL_GetKeyboardState = Uint8* function(int*); alias da_SDL_GetModState = SDL_Keymod function(); alias da_SDL_SetModState = void function(SDL_Keymod); alias da_SDL_GetKeyFromScancode = SDL_Keycode function(SDL_Scancode); alias da_SDL_GetScancodeFromKey = SDL_Scancode function(SDL_Keycode); alias da_SDL_GetScancodeName = const(char)* function(SDL_Scancode); alias da_SDL_GetScancodeFromName = SDL_Scancode function(const(char)*); alias da_SDL_GetKeyName = const(char)* function(SDL_Keycode); alias da_SDL_GetKeyFromName = SDL_Keycode function(const(char)*); alias da_SDL_StartTextInput = void function(); alias da_SDL_IsTextInputActive = SDL_bool function(); alias da_SDL_StopTextInput = void function(); alias da_SDL_SetTextInputRect = void function(SDL_Rect*); alias da_SDL_HasScreenKeyboardSupport = SDL_bool function(); alias da_SDL_IsScreenKeyboardShown = SDL_bool function(SDL_Window*); // SDL_loadso.h alias da_SDL_LoadObject = void* function(const(char)*); alias da_SDL_LoadFunction = void* function(void*,const(char*)); alias da_SDL_UnloadObject = void function(void*); // SDL_log.h alias da_SDL_LogSetAllPriority = void function(SDL_LogPriority); alias da_SDL_LogSetPriority = void function(int,SDL_LogPriority); alias da_SDL_LogGetPriority = SDL_LogPriority function(int); alias da_SDL_LogResetPriorities = void function(); alias da_SDL_Log = void function(const(char)*,...); alias da_SDL_LogVerbose = void function(int,const(char)*,...); alias da_SDL_LogDebug = void function(int,const(char)*,...); alias da_SDL_LogInfo = void function(int,const(char)*,...); alias da_SDL_LogWarn = void function(int,const(char)*,...); alias da_SDL_LogError = void function(int,const(char)*,...); alias da_SDL_LogCritical = void function(int,const(char)*,...); alias da_SDL_LogMessage = void function(int,SDL_LogPriority,const(char)*,...); alias da_SDL_LogMessageV = void function(int,SDL_LogPriority,const(char)*,va_list); alias da_SDL_LogGetOutputFunction = void function(SDL_LogOutputFunction,void**); alias da_SDL_LogSetOutputFunction = void function(SDL_LogOutputFunction,void*); // SDL_messagebox.h alias da_SDL_ShowMessageBox = int function(const(SDL_MessageBoxData)*,int*); alias da_SDL_ShowSimpleMessageBox = int function(Uint32,const(char)*,const(char)*,SDL_Window*); // SDL_mouse.h alias da_SDL_GetMouseFocus = SDL_Window* function(); alias da_SDL_GetMouseState = Uint32 function(int*,int*); alias da_SDL_GetGlobalMouseState = Uint32 function(int*,int*); alias da_SDL_GetRelativeMouseState = Uint32 function(int*,int*); alias da_SDL_WarpMouseInWindow = void function(SDL_Window*,int,int); alias da_SDL_WarpMouseGlobal = void function(int,int); alias da_SDL_SetRelativeMouseMode = int function(SDL_bool); alias da_SDL_CaptureMouse = int function(SDL_bool); alias da_SDL_GetRelativeMouseMode = SDL_bool function(); alias da_SDL_CreateCursor = SDL_Cursor* function(const(Uint8)*,const(Uint8)*,int,int,int,int); alias da_SDL_CreateColorCursor = SDL_Cursor* function(SDL_Surface*,int,int); alias da_SDL_CreateSystemCursor = SDL_Cursor* function(SDL_SystemCursor); alias da_SDL_SetCursor = void function(SDL_Cursor*); alias da_SDL_GetCursor = SDL_Cursor* function(); alias da_SDL_GetDefaultCursor = SDL_Cursor* function(); alias da_SDL_FreeCursor = void function(SDL_Cursor*); alias da_SDL_ShowCursor = int function(int); // SDL_pixels.h alias da_SDL_GetPixelFormatName = const(char)* function(Uint32); alias da_SDL_PixelFormatEnumToMasks = SDL_bool function(Uint32,int*,Uint32*,Uint32*,Uint32*,Uint32*); alias da_SDL_MasksToPixelFormatEnum = Uint32 function(int,Uint32,Uint32,Uint32,Uint32); alias da_SDL_AllocFormat = SDL_PixelFormat* function(Uint32); alias da_SDL_FreeFormat = void function(SDL_PixelFormat*); alias da_SDL_AllocPalette = SDL_Palette* function(int); alias da_SDL_SetPixelFormatPalette = int function(SDL_PixelFormat*,SDL_Palette*); alias da_SDL_SetPaletteColors = int function(SDL_Palette*,const(SDL_Color)*,int,int); alias da_SDL_FreePalette = void function(SDL_Palette*); alias da_SDL_MapRGB = Uint32 function(const(SDL_PixelFormat)*,Uint8,Uint8,Uint8); alias da_SDL_MapRGBA = Uint32 function(const(SDL_PixelFormat)*,Uint8,Uint8,Uint8,Uint8); alias da_SDL_GetRGB = void function(Uint32,const(SDL_PixelFormat)*,Uint8*,Uint8*,Uint8*); alias da_SDL_GetRGBA = void function(Uint32,const(SDL_PixelFormat)*,Uint8*,Uint8*,Uint8*,Uint8*); alias da_SDL_CalculateGammaRamp = void function(float,Uint16*); // SDL_platform.h alias da_SDL_GetPlatform = const(char)* function(); // SDL_power.h alias da_SDL_GetPowerInfo = SDL_PowerState function(int*,int*); // SDL_Rect.h alias da_SDL_HasIntersection = SDL_bool function(const(SDL_Rect)*,const(SDL_Rect)*); alias da_SDL_IntersectRect = SDL_bool function(const(SDL_Rect)*,const(SDL_Rect)*,SDL_Rect*); alias da_SDL_UnionRect = void function(const(SDL_Rect)*,const(SDL_Rect)*,SDL_Rect*); alias da_SDL_EnclosePoints = SDL_bool function(const(SDL_Point)*,int,const(SDL_Rect)*,SDL_Rect*); alias da_SDL_IntersectRectAndLine = SDL_bool function(const(SDL_Rect)*,int*,int*,int*,int*); // SDL_Render.h alias da_SDL_GetNumRenderDrivers = int function(); alias da_SDL_GetRenderDriverInfo = int function(int,SDL_RendererInfo*); alias da_SDL_CreateWindowAndRenderer = int function(int,int,Uint32,SDL_Window**,SDL_Renderer**); alias da_SDL_CreateRenderer = SDL_Renderer* function(SDL_Window*,int,SDL_RendererFlags); alias da_SDL_CreateSoftwareRenderer = SDL_Renderer* function(SDL_Surface*); alias da_SDL_GetRenderer = SDL_Renderer* function(SDL_Window*); alias da_SDL_GetRendererInfo = int function(SDL_Renderer*,SDL_RendererInfo*); alias da_SDL_GetRendererOutputSize = int function(SDL_Renderer*,int*,int*); alias da_SDL_CreateTexture = SDL_Texture* function(SDL_Renderer*,Uint32,SDL_TextureAccess,int,int); alias da_SDL_CreateTextureFromSurface = SDL_Texture* function(SDL_Renderer*,SDL_Surface*); alias da_SDL_QueryTexture = int function(SDL_Texture*,Uint32*,int*,int*,int*); alias da_SDL_SetTextureColorMod = int function(SDL_Texture*,Uint8,Uint8,Uint8); alias da_SDL_GetTextureColorMod = int function(SDL_Texture*,Uint8*,Uint8*,Uint8*); alias da_SDL_SetTextureAlphaMod = int function(SDL_Texture*,Uint8); alias da_SDL_GetTextureAlphaMod = int function(SDL_Texture*,Uint8*); alias da_SDL_SetTextureBlendMode = int function(SDL_Texture*,SDL_BlendMode); alias da_SDL_GetTextureBlendMode = int function(SDL_Texture*,SDL_BlendMode*); alias da_SDL_UpdateTexture = int function(SDL_Texture*,const(SDL_Rect)*,const(void)*,int); alias da_SDL_UpdateYUVTexture = int function(SDL_Texture*,const(SDL_Rect)*,const(Uint8)*,int,const(Uint8)*,int,const(Uint8)*,int); alias da_SDL_LockTexture = int function(SDL_Texture*,const(SDL_Rect)*,void**,int*); alias da_SDL_UnlockTexture = void function(SDL_Texture*); alias da_SDL_RenderTargetSupported = SDL_bool function(SDL_Renderer*); alias da_SDL_SetRenderTarget = int function(SDL_Renderer*,SDL_Texture*); alias da_SDL_GetRenderTarget = SDL_Texture* function(SDL_Renderer*); alias da_SDL_RenderSetClipRect = int function(SDL_Renderer*,const(SDL_Rect)*); alias da_SDL_RenderGetClipRect = void function(SDL_Renderer* renderer,SDL_Rect*); alias da_SDL_RenderSetLogicalSize = int function(SDL_Renderer*,int,int); alias da_SDL_RenderGetLogicalSize = void function(SDL_Renderer*,int*,int*); alias da_SDL_RenderSetIntegerScale = int function(SDL_Renderer*,SDL_bool); alias da_SDL_RenderGetIntegerScale = SDL_bool function(SDL_Renderer*); alias da_SDL_RenderSetViewport = int function(SDL_Renderer*,const(SDL_Rect)*); alias da_SDL_RenderGetViewport = void function(SDL_Renderer*,SDL_Rect*); alias da_SDL_RenderIsClipEnabled = SDL_bool function(SDL_Renderer*); alias da_SDL_RenderSetScale = int function(SDL_Renderer*,float,float); alias da_SDL_RenderGetScale = int function(SDL_Renderer*,float*,float*); alias da_SDL_SetRenderDrawColor = int function(SDL_Renderer*,Uint8,Uint8,Uint8,Uint8); alias da_SDL_GetRenderDrawColor = int function(SDL_Renderer*,Uint8*,Uint8*,Uint8*,Uint8*); alias da_SDL_SetRenderDrawBlendMode = int function(SDL_Renderer*,SDL_BlendMode); alias da_SDL_GetRenderDrawBlendMode = int function(SDL_Renderer*,SDL_BlendMode*); alias da_SDL_RenderClear = int function(SDL_Renderer*); alias da_SDL_RenderDrawPoint = int function(SDL_Renderer*,int,int); alias da_SDL_RenderDrawPoints = int function(SDL_Renderer*,const(SDL_Point)*,int); alias da_SDL_RenderDrawLine = int function(SDL_Renderer*,int,int,int,int); alias da_SDL_RenderDrawLines = int function(SDL_Renderer*,const(SDL_Point)*,int); alias da_SDL_RenderDrawRect = int function(SDL_Renderer*,const(SDL_Rect)*); alias da_SDL_RenderDrawRects = int function(SDL_Renderer*,const(SDL_Rect)*,int); alias da_SDL_RenderFillRect = int function(SDL_Renderer*,const(SDL_Rect)*); alias da_SDL_RenderFillRects = int function(SDL_Renderer*,const(SDL_Rect)*,int); alias da_SDL_RenderCopy = int function(SDL_Renderer*,SDL_Texture*,const(SDL_Rect)*,const(SDL_Rect*)); alias da_SDL_RenderCopyEx = int function(SDL_Renderer*,SDL_Texture*,const(SDL_Rect)*,const(SDL_Rect)*,const(double),const(SDL_Point)*,const(SDL_RendererFlip)); alias da_SDL_RenderReadPixels = int function(SDL_Renderer*,const(SDL_Rect)*,Uint32,void*,int); alias da_SDL_RenderPresent = void function(SDL_Renderer*); alias da_SDL_DestroyTexture = void function(SDL_Texture*); alias da_SDL_DestroyRenderer = void function(SDL_Renderer*); alias da_SDL_GL_BindTexture = int function(SDL_Texture*,float*,float*); alias da_SDL_GL_UnbindTexture = int function(SDL_Texture*); // SDL_rwops.h alias da_SDL_RWFromFile = SDL_RWops* function(const(char)*,const(char)*); alias da_SDL_RWFromFP = SDL_RWops* function(FILE*,SDL_bool); alias da_SDL_RWFromMem = SDL_RWops* function(void*,int); alias da_SDL_RWFromConstMem = SDL_RWops* function(const(void)*,int); alias da_SDL_AllocRW = SDL_RWops* function(); alias da_SDL_FreeRW = void function(SDL_RWops*); alias da_SDL_ReadU8 = Uint8 function(SDL_RWops*); alias da_SDL_ReadLE16 = Uint16 function(SDL_RWops*); alias da_SDL_ReadBE16 = Uint16 function(SDL_RWops*); alias da_SDL_ReadLE32 = Uint32 function(SDL_RWops*); alias da_SDL_ReadBE32 = Uint32 function(SDL_RWops*); alias da_SDL_ReadLE64 = Uint64 function(SDL_RWops*); alias da_SDL_ReadBE64 = Uint64 function(SDL_RWops*); alias da_SDL_WriteU8 = size_t function(SDL_RWops*,Uint8); alias da_SDL_WriteLE16 = size_t function(SDL_RWops*,Uint16); alias da_SDL_WriteBE16 = size_t function(SDL_RWops*,Uint16); alias da_SDL_WriteLE32 = size_t function(SDL_RWops*,Uint32); alias da_SDL_WriteBE32 = size_t function(SDL_RWops*,Uint32); alias da_SDL_WriteLE64 = size_t function(SDL_RWops*,Uint64); alias da_SDL_WriteBE64 = size_t function(SDL_RWops*,Uint64); // SDL_shape.h alias da_SDL_CreateShapedWindow = SDL_Window* function(const(char)*,uint,uint,uint,uint,Uint32); alias da_SDL_IsShapedWindow = SDL_bool function(const(SDL_Window)*); alias da_SDL_SetWindowShape = int function(SDL_Window*,SDL_Surface*,SDL_WindowShapeMode*); alias da_SDL_GetShapedWindowMode = int function(SDL_Window*,SDL_WindowShapeMode*); // SDL_surface.h alias da_SDL_CreateRGBSurface = SDL_Surface* function(Uint32,int,int,int,Uint32,Uint32,Uint32,Uint32); alias da_SDL_CreateRGBSurfaceWithFormat = SDL_Surface* function(Uint32,int,int,int,Uint32); alias da_SDL_CreateRGBSurfaceFrom = SDL_Surface* function(void*,int,int,int,int,Uint32,Uint32,Uint32,Uint32); alias da_SDL_CreateRGBSurfaceWithFormatFrom = SDL_Surface* function(void*,int,int,int,int,Uint32); alias da_SDL_FreeSurface = void function(SDL_Surface*); alias da_SDL_SetSurfacePalette = int function(SDL_Surface*,SDL_Palette*); alias da_SDL_LockSurface = int function(SDL_Surface*); alias da_SDL_UnlockSurface = int function(SDL_Surface*); alias da_SDL_LoadBMP_RW = SDL_Surface* function(SDL_RWops*,int); alias da_SDL_SaveBMP_RW = int function(SDL_Surface*,SDL_RWops*,int); alias da_SDL_SetSurfaceRLE = int function(SDL_Surface*,int); alias da_SDL_SetColorKey = int function(SDL_Surface*,int,Uint32); alias da_SDL_GetColorKey = int function(SDL_Surface*,Uint32*); alias da_SDL_SetSurfaceColorMod = int function(SDL_Surface*,Uint8,Uint8,Uint8); alias da_SDL_GetSurfaceColorMod = int function(SDL_Surface*,Uint8*,Uint8*,Uint8*); alias da_SDL_SetSurfaceAlphaMod = int function(SDL_Surface*,Uint8); alias da_SDL_GetSurfaceAlphaMod = int function(SDL_Surface*,Uint8*); alias da_SDL_SetSurfaceBlendMode = int function(SDL_Surface*,SDL_BlendMode); alias da_SDL_GetSurfaceBlendMode = int function(SDL_Surface*,SDL_BlendMode*); alias da_SDL_SetClipRect = SDL_bool function(SDL_Surface*,const(SDL_Rect)*); alias da_SDL_GetClipRect = void function(SDL_Surface*,SDL_Rect*); alias da_SDL_ConvertSurface = SDL_Surface* function(SDL_Surface*,const(SDL_PixelFormat)*,Uint32); alias da_SDL_ConvertSurfaceFormat = SDL_Surface* function(SDL_Surface*,Uint32,Uint32); alias da_SDL_ConvertPixels = int function(int,int,Uint32,const(void)*,int,Uint32,void*,int); alias da_SDL_FillRect = int function(SDL_Surface*,const(SDL_Rect)*,Uint32); alias da_SDL_FillRects = int function(SDL_Surface*,const(SDL_Rect)*,int,Uint32); alias da_SDL_UpperBlit = int function(SDL_Surface*,const(SDL_Rect)*,SDL_Surface*,SDL_Rect*); alias da_SDL_LowerBlit = int function(SDL_Surface*,SDL_Rect*,SDL_Surface*,SDL_Rect*); alias da_SDL_SoftStretch = int function(SDL_Surface*,const(SDL_Rect)*,SDL_Surface*,const(SDL_Rect)*); alias da_SDL_UpperBlitScaled = int function(SDL_Surface*,const(SDL_Rect)*,SDL_Surface*,SDL_Rect*); alias da_SDL_LowerBlitScaled = int function(SDL_Surface*,SDL_Rect*,SDL_Surface*,SDL_Rect*); // SDL_system.h static if(Derelict_OS_Windows) { alias da_SDL_Direct3D9GetAdapterIndex = int function(int); alias da_SDL_RenderGetD3D9Device = IDirect3DDevice9* function(SDL_Renderer*); alias da_SDL_DXGIGetOutputInfo = SDL_bool function (int,int*,int*); } static if(Derelict_OS_iOS) { alias da_SDL_iPhoneSetAnimationCallback = int function(SDL_Window*,int,SDL_iPhoneAnimationCallback,void*); alias da_SDL_iPhoneSetEventPump = void function(SDL_bool); } static if(Derelict_OS_Android) { alias da_SDL_AndroidGetJNIEnv = void* function(); alias da_SDL_AndroidGetActivity = void* function(); alias da_SDL_AndroidGetInternalStoragePath = const(char)* function(); alias da_SDL_AndroidGetInternalStorageState = int function(); alias da_SDL_AndroidGetExternalStoragePath = const(char)* function(); } static if(Derelict_OS_WinRT) { alias da_SDL_WinRTGetFSPathUNICODE = const(wchar_t)* function(SDL_WinRT_Path); alias da_SDL_WinRTGetFSPathUTF8 = const(char)* function(SDL_WinRT_Path); alias da_SDL_WinRTRunApp = int function(int function(int,char**),void*); } // SDL_syswm.h alias da_SDL_GetWindowWMInfo = SDL_bool function(SDL_Window* window,SDL_SysWMinfo * info); // SDL_timer.h alias da_SDL_GetTicks = Uint32 function(); alias da_SDL_GetPerformanceCounter = Uint64 function(); alias da_SDL_GetPerformanceFrequency = Uint64 function(); alias da_SDL_Delay = void function(Uint32); alias da_SDL_AddTimer = SDL_TimerID function(Uint32,SDL_TimerCallback,void*); alias da_SDL_RemoveTimer = SDL_bool function(SDL_TimerID); // SDL_touch.h alias da_SDL_GetNumTouchDevices = int function(); alias da_SDL_GetTouchDevice = SDL_TouchID function(int); alias da_SDL_GetNumTouchFingers = int function(SDL_TouchID); alias da_SDL_GetTouchFinger = SDL_Finger* function(SDL_TouchID,int); // SDL_version.h alias da_SDL_GetVersion = void function(SDL_version*); alias da_SDL_GetRevision = const(char)* function(); alias da_SDL_GetRevisionNumber = int function(); // SDL_video.h alias da_SDL_GetNumVideoDrivers = int function(); alias da_SDL_GetVideoDriver = const(char)* function(int); alias da_SDL_VideoInit = int function(const(char)*); alias da_SDL_VideoQuit = void function(); alias da_SDL_GetCurrentVideoDriver = const(char)* function(); alias da_SDL_GetNumVideoDisplays = int function(); alias da_SDL_GetDisplayName = const(char)* function(int); alias da_SDL_GetDisplayBounds = int function(int,SDL_Rect*); alias da_SDL_GetDisplayDPI = int function(int,float*,float*,float*); alias da_SDL_GetDisplayUsableBounds = int function(int,SDL_Rect*); alias da_SDL_GetNumDisplayModes = int function(int); alias da_SDL_GetDisplayMode = int function(int,int,SDL_DisplayMode*); alias da_SDL_GetDesktopDisplayMode = int function(int,SDL_DisplayMode*); alias da_SDL_GetCurrentDisplayMode = int function(int,SDL_DisplayMode*); alias da_SDL_GetClosestDisplayMode = SDL_DisplayMode* function(int,const(SDL_DisplayMode)*,SDL_DisplayMode*); alias da_SDL_GetWindowDisplayIndex = int function(SDL_Window*); alias da_SDL_SetWindowDisplayMode = int function(SDL_Window*,const(SDL_DisplayMode)*); alias da_SDL_GetWindowDisplayMode = int function(SDL_Window*,SDL_DisplayMode*); alias da_SDL_GetWindowPixelFormat = Uint32 function(SDL_Window*); alias da_SDL_CreateWindow = SDL_Window* function(const(char)*,int,int,int,int,SDL_WindowFlags); alias da_SDL_CreateWindowFrom = SDL_Window* function(const(void)*); alias da_SDL_GetWindowID = Uint32 function(SDL_Window*); alias da_SDL_GetWindowFromID = SDL_Window* function(Uint32); alias da_SDL_GetWindowFlags = SDL_WindowFlags function(SDL_Window*); alias da_SDL_SetWindowTitle = void function(SDL_Window*,const(char)*); alias da_SDL_GetWindowTitle = const(char)* function(SDL_Window*); alias da_SDL_SetWindowIcon = void function(SDL_Window*,SDL_Surface*); alias da_SDL_SetWindowData = void* function(SDL_Window*,const(char)*,void*); alias da_SDL_GetWindowData = void* function(SDL_Window*,const(char)*); alias da_SDL_SetWindowPosition = void function(SDL_Window*,int,int); alias da_SDL_GetWindowPosition = void function(SDL_Window*,int*,int*); alias da_SDL_SetWindowSize = void function(SDL_Window*,int,int); alias da_SDL_GetWindowSize = void function(SDL_Window*,int*,int*); alias da_SDL_GetWindowBordersSize = int function(SDL_Window*,int*,int*,int*,int*); alias da_SDL_SetWindowMinimumSize = void function(SDL_Window*,int,int); alias da_SDL_GetWindowMinimumSize = void function(SDL_Window*,int*,int*); alias da_SDL_SetWindowMaximumSize = void function(SDL_Window*,int,int); alias da_SDL_GetWindowMaximumSize = void function(SDL_Window*,int*,int*); alias da_SDL_SetWindowBordered = void function(SDL_Window*,SDL_bool); alias da_SDL_SetWindowResizable = void function(SDL_Window*,SDL_bool); alias da_SDL_ShowWindow = void function(SDL_Window*); alias da_SDL_HideWindow = void function(SDL_Window*); alias da_SDL_RaiseWindow = void function(SDL_Window*); alias da_SDL_MaximizeWindow = void function(SDL_Window*); alias da_SDL_MinimizeWindow = void function(SDL_Window*); alias da_SDL_RestoreWindow = void function(SDL_Window*); alias da_SDL_SetWindowFullscreen = int function(SDL_Window*,Uint32); alias da_SDL_GetWindowSurface = SDL_Surface* function(SDL_Window*); alias da_SDL_UpdateWindowSurface = int function(SDL_Window*); alias da_SDL_UpdateWindowSurfaceRects = int function(SDL_Window*,SDL_Rect*,int); alias da_SDL_SetWindowGrab = void function(SDL_Window*,SDL_bool); alias da_SDL_GetWindowGrab = SDL_bool function(SDL_Window*); alias da_SDL_GetGrabbedWindow = SDL_Window* function(); alias da_SDL_SetWindowBrightness = int function(SDL_Window*,float); alias da_SDL_GetWindowBrightness = float function(SDL_Window*); alias da_SDL_SetWindowOpacity = int function(SDL_Window*,float); alias da_SDL_GetWindowOpacity = int function(SDL_Window*,float*); alias da_SDL_SetWindowModalFor = int function(SDL_Window*,SDL_Window*); alias da_SDL_SetWindowInputFocus = int function(SDL_Window*); alias da_SDL_SetWindowGammaRamp = int function(SDL_Window*,const(Uint16)*,const(Uint16)*,const(Uint16)*); alias da_SDL_GetWindowGammaRamp = int function(SDL_Window*,Uint16*,Uint16*,Uint16*); alias da_SDL_SetWindowHitTest = int function(SDL_Window*,SDL_HitTest,void*); alias da_SDL_DestroyWindow = void function(SDL_Window*); alias da_SDL_IsScreenSaverEnabled = SDL_bool function(); alias da_SDL_EnableScreenSaver = void function(); alias da_SDL_DisableScreenSaver = void function(); alias da_SDL_GL_LoadLibrary = int function(const(char)*); alias da_SDL_GL_GetProcAddress = void* function(const(char)*); alias da_SDL_GL_UnloadLibrary = void function(); alias da_SDL_GL_ExtensionSupported = SDL_bool function(const(char)*); alias da_SDL_GL_ResetAttributes = void function(); alias da_SDL_GL_SetAttribute = int function(SDL_GLattr,int); alias da_SDL_GL_GetAttribute = int function(SDL_GLattr,int*); alias da_SDL_GL_CreateContext = SDL_GLContext function(SDL_Window*); alias da_SDL_GL_MakeCurrent = int function(SDL_Window*,SDL_GLContext); alias da_SDL_GL_GetCurrentWindow = SDL_Window* function(); alias da_SDL_GL_GetCurrentContext = SDL_GLContext function(); alias da_SDL_GL_GetDrawableSize = void function(SDL_Window*,int*,int*); alias da_SDL_GL_SetSwapInterval = int function(int); alias da_SDL_GL_GetSwapInterval = int function(); alias da_SDL_GL_SwapWindow = void function(SDL_Window*); alias da_SDL_GL_DeleteContext = void function(SDL_GLContext); } __gshared { da_SDL_Init SDL_Init; da_SDL_InitSubSystem SDL_InitSubSystem; da_SDL_QuitSubSystem SDL_QuitSubSystem; da_SDL_WasInit SDL_WasInit; da_SDL_Quit SDL_Quit; da_SDL_free SDL_free; da_SDL_SetAssertionHandler SDL_SetAssertionHandler; da_SDL_GetDefaultAssertionHandler SDL_GetDefaultAssertionHandler; da_SDL_GetAssertionHandler SDL_GetAssertionHandler; da_SDL_GetAssertionReport SDL_GetAssertionReport; da_SDL_ResetAssertionReport SDL_ResetAssertionReport; da_SDL_GetNumAudioDrivers SDL_GetNumAudioDrivers; da_SDL_GetAudioDriver SDL_GetAudioDriver; da_SDL_AudioInit SDL_AudioInit; da_SDL_AudioQuit SDL_AudioQuit; da_SDL_GetCurrentAudioDriver SDL_GetCurrentAudioDriver; da_SDL_OpenAudio SDL_OpenAudio; da_SDL_GetNumAudioDevices SDL_GetNumAudioDevices; da_SDL_GetAudioDeviceName SDL_GetAudioDeviceName; da_SDL_OpenAudioDevice SDL_OpenAudioDevice; da_SDL_GetAudioStatus SDL_GetAudioStatus; da_SDL_GetAudioDeviceStatus SDL_GetAudioDeviceStatus; da_SDL_PauseAudio SDL_PauseAudio; da_SDL_PauseAudioDevice SDL_PauseAudioDevice; da_SDL_LoadWAV_RW SDL_LoadWAV_RW; da_SDL_FreeWAV SDL_FreeWAV; da_SDL_BuildAudioCVT SDL_BuildAudioCVT; da_SDL_ConvertAudio SDL_ConvertAudio; da_SDL_MixAudio SDL_MixAudio; da_SDL_MixAudioFormat SDL_MixAudioFormat; da_SDL_QueueAudio SDL_QueueAudio; da_SDL_DequeueAudio SDL_DequeueAudio; da_SDL_GetQueuedAudioSize SDL_GetQueuedAudioSize; da_SDL_ClearQueuedAudio SDL_ClearQueuedAudio; da_SDL_LockAudio SDL_LockAudio; da_SDL_LockAudioDevice SDL_LockAudioDevice; da_SDL_UnlockAudio SDL_UnlockAudio; da_SDL_UnlockAudioDevice SDL_UnlockAudioDevice; da_SDL_CloseAudio SDL_CloseAudio; da_SDL_CloseAudioDevice SDL_CloseAudioDevice; // da_SDL_AudioDeviceConnected SDL_AudioDeviceConnected; da_SDL_SetClipboardText SDL_SetClipboardText; da_SDL_GetClipboardText SDL_GetClipboardText; da_SDL_HasClipboardText SDL_HasClipboardText; da_SDL_GetCPUCount SDL_GetCPUCount; da_SDL_GetCPUCacheLineSize SDL_GetCPUCacheLineSize; da_SDL_HasRDTSC SDL_HasRDTSC; da_SDL_HasAltiVec SDL_HasAltiVec; da_SDL_HasMMX SDL_HasMMX; da_SDL_Has3DNow SDL_Has3DNow; da_SDL_HasSSE SDL_HasSSE; da_SDL_HasSSE2 SDL_HasSSE2; da_SDL_HasSSE3 SDL_HasSSE3; da_SDL_HasSSE41 SDL_HasSSE41; da_SDL_HasSSE42 SDL_HasSSE42; da_SDL_HasAVX SDL_HasAVX; da_SDL_HasAVX2 SDL_HasAVX2; da_SDL_GetSystemRAM SDL_GetSystemRAM; da_SDL_SetError SDL_SetError; da_SDL_GetError SDL_GetError; da_SDL_ClearError SDL_ClearError; da_SDL_PumpEvents SDL_PumpEvents; da_SDL_PeepEvents SDL_PeepEvents; da_SDL_HasEvent SDL_HasEvent; da_SDL_HasEvents SDL_HasEvents; da_SDL_FlushEvent SDL_FlushEvent; da_SDL_FlushEvents SDL_FlushEvents; da_SDL_PollEvent SDL_PollEvent; da_SDL_WaitEvent SDL_WaitEvent; da_SDL_WaitEventTimeout SDL_WaitEventTimeout; da_SDL_PushEvent SDL_PushEvent; da_SDL_SetEventFilter SDL_SetEventFilter; da_SDL_GetEventFilter SDL_GetEventFilter; da_SDL_AddEventWatch SDL_AddEventWatch; da_SDL_DelEventWatch SDL_DelEventWatch; da_SDL_FilterEvents SDL_FilterEvents; da_SDL_EventState SDL_EventState; da_SDL_RegisterEvents SDL_RegisterEvents; da_SDL_GetBasePath SDL_GetBasePath; da_SDL_GetPrefPath SDL_GetPrefPath; da_SDL_GameControllerAddMappingsFromRW SDL_GameControllerAddMappingsFromRW; da_SDL_GameControllerAddMapping SDL_GameControllerAddMapping; da_SDL_GameControllerMappingForGUID SDL_GameControllerMappingForGUID; da_SDL_GameControllerMapping SDL_GameControllerMapping; da_SDL_IsGameController SDL_IsGameController; da_SDL_GameControllerNameForIndex SDL_GameControllerNameForIndex; da_SDL_GameControllerOpen SDL_GameControllerOpen; da_SDL_GameControllerFromInstanceID SDL_GameControllerFromInstanceID; da_SDL_GameControllerName SDL_GameControllerName; da_SDL_GameControllerGetAttached SDL_GameControllerGetAttached; da_SDL_GameControllerGetJoystick SDL_GameControllerGetJoystick; da_SDL_GameControllerEventState SDL_GameControllerEventState; da_SDL_GameControllerUpdate SDL_GameControllerUpdate; da_SDL_GameControllerGetAxisFromString SDL_GameControllerGetAxisFromString; da_SDL_GameControllerGetStringForAxis SDL_GameControllerGetStringForAxis; da_SDL_GameControllerGetBindForAxis SDL_GameControllerGetBindForAxis; da_SDL_GameControllerGetAxis SDL_GameControllerGetAxis; da_SDL_GameControllerGetButtonFromString SDL_GameControllerGetButtonFromString; da_SDL_GameControllerGetStringForButton SDL_GameControllerGetStringForButton; da_SDL_GameControllerGetBindForButton SDL_GameControllerGetBindForButton; da_SDL_GameControllerGetButton SDL_GameControllerGetButton; da_SDL_GameControllerClose SDL_GameControllerClose; da_SDL_RecordGesture SDL_RecordGesture; da_SDL_SaveAllDollarTemplates SDL_SaveAllDollarTemplates; da_SDL_SaveDollarTemplate SDL_SaveDollarTemplate; da_SDL_LoadDollarTemplates SDL_LoadDollarTemplates; da_SDL_NumHaptics SDL_NumHaptics; da_SDL_HapticName SDL_HapticName; da_SDL_HapticOpen SDL_HapticOpen; da_SDL_HapticOpened SDL_HapticOpened; da_SDL_HapticIndex SDL_HapticIndex; da_SDL_MouseIsHaptic SDL_MouseIsHaptic; da_SDL_HapticOpenFromMouse SDL_HapticOpenFromMouse; da_SDL_JoystickIsHaptic SDL_JoystickIsHaptic; da_SDL_HapticOpenFromJoystick SDL_HapticOpenFromJoystick; da_SDL_HapticClose SDL_HapticClose; da_SDL_HapticNumEffects SDL_HapticNumEffects; da_SDL_HapticNumEffectsPlaying SDL_HapticNumEffectsPlaying; da_SDL_HapticQuery SDL_HapticQuery; da_SDL_HapticNumAxes SDL_HapticNumAxes; da_SDL_HapticEffectSupported SDL_HapticEffectSupported; da_SDL_HapticNewEffect SDL_HapticNewEffect; da_SDL_HapticUpdateEffect SDL_HapticUpdateEffect; da_SDL_HapticRunEffect SDL_HapticRunEffect; da_SDL_HapticStopEffect SDL_HapticStopEffect; da_SDL_HapticDestroyEffect SDL_HapticDestroyEffect; da_SDL_HapticGetEffectStatus SDL_HapticGetEffectStatus; da_SDL_HapticSetGain SDL_HapticSetGain; da_SDL_HapticSetAutocenter SDL_HapticSetAutocenter; da_SDL_HapticPause SDL_HapticPause; da_SDL_HapticUnpause SDL_HapticUnpause; da_SDL_HapticStopAll SDL_HapticStopAll; da_SDL_HapticRumbleSupported SDL_HapticRumbleSupported; da_SDL_HapticRumbleInit SDL_HapticRumbleInit; da_SDL_HapticRumblePlay SDL_HapticRumblePlay; da_SDL_HapticRumbleStop SDL_HapticRumbleStop; da_SDL_SetHintWithPriority SDL_SetHintWithPriority; da_SDL_SetHint SDL_SetHint; da_SDL_GetHint SDL_GetHint; da_SDL_GetHintBoolean SDL_GetHintBoolean; da_SDL_AddHintCallback SDL_AddHintCallback; da_SDL_DelHintCallback SDL_DelHintCallback; da_SDL_ClearHints SDL_ClearHints; da_SDL_NumJoysticks SDL_NumJoysticks; da_SDL_JoystickNameForIndex SDL_JoystickNameForIndex; da_SDL_JoystickOpen SDL_JoystickOpen; da_SDL_JoystickName SDL_JoystickName; da_SDL_JoystickFromInstanceID SDL_JoystickFromInstanceID; da_SDL_JoystickGetDeviceGUID SDL_JoystickGetDeviceGUID; da_SDL_JoystickGetGUID SDL_JoystickGetGUID; da_SDL_JoystickGetGUIDString SDL_JoystickGetGUIDString; da_SDL_JoystickGetGUIDFromString SDL_JoystickGetGUIDFromString; da_SDL_JoystickGetAttached SDL_JoystickGetAttached; da_SDL_JoystickInstanceID SDL_JoystickInstanceID; da_SDL_JoystickNumAxes SDL_JoystickNumAxes; da_SDL_JoystickNumBalls SDL_JoystickNumBalls; da_SDL_JoystickNumHats SDL_JoystickNumHats; da_SDL_JoystickNumButtons SDL_JoystickNumButtons; da_SDL_JoystickUpdate SDL_JoystickUpdate; da_SDL_JoystickEventState SDL_JoystickEventState; da_SDL_JoystickGetAxis SDL_JoystickGetAxis; da_SDL_JoystickGetHat SDL_JoystickGetHat; da_SDL_JoystickGetBall SDL_JoystickGetBall; da_SDL_JoystickGetButton SDL_JoystickGetButton; da_SDL_JoystickClose SDL_JoystickClose; da_SDL_JoystickCurrentPowerLevel SDL_JoystickCurrentPowerLevel; da_SDL_GetKeyboardFocus SDL_GetKeyboardFocus; da_SDL_GetKeyboardState SDL_GetKeyboardState; da_SDL_GetModState SDL_GetModState; da_SDL_SetModState SDL_SetModState; da_SDL_GetKeyFromScancode SDL_GetKeyFromScancode; da_SDL_GetScancodeFromKey SDL_GetScancodeFromKey; da_SDL_GetScancodeName SDL_GetScancodeName; da_SDL_GetScancodeFromName SDL_GetScancodeFromName; da_SDL_GetKeyName SDL_GetKeyName; da_SDL_GetKeyFromName SDL_GetKeyFromName; da_SDL_StartTextInput SDL_StartTextInput; da_SDL_IsTextInputActive SDL_IsTextInputActive; da_SDL_StopTextInput SDL_StopTextInput; da_SDL_SetTextInputRect SDL_SetTextInputRect; da_SDL_HasScreenKeyboardSupport SDL_HasScreenKeyboardSupport; da_SDL_IsScreenKeyboardShown SDL_IsScreenKeyboardShown; da_SDL_LoadObject SDL_LoadObject; da_SDL_LoadFunction SDL_LoadFunction; da_SDL_UnloadObject SDL_UnloadObject; da_SDL_LogSetAllPriority SDL_LogSetAllPriority; da_SDL_LogSetPriority SDL_LogSetPriority; da_SDL_LogGetPriority SDL_LogGetPriority; da_SDL_LogResetPriorities SDL_LogResetPriorities; da_SDL_Log SDL_Log; da_SDL_LogVerbose SDL_LogVerbose; da_SDL_LogDebug SDL_LogDebug; da_SDL_LogInfo SDL_LogInfo; da_SDL_LogWarn SDL_LogWarn; da_SDL_LogError SDL_LogError; da_SDL_LogCritical SDL_LogCritical; da_SDL_LogMessage SDL_LogMessage; da_SDL_LogMessageV SDL_LogMessageV; da_SDL_LogGetOutputFunction SDL_LogGetOutputFunction; da_SDL_LogSetOutputFunction SDL_LogSetOutputFunction; da_SDL_ShowMessageBox SDL_ShowMessageBox; da_SDL_ShowSimpleMessageBox SDL_ShowSimpleMessageBox; da_SDL_GetMouseFocus SDL_GetMouseFocus; da_SDL_GetMouseState SDL_GetMouseState; da_SDL_GetGlobalMouseState SDL_GetGlobalMouseState; da_SDL_GetRelativeMouseState SDL_GetRelativeMouseState; da_SDL_WarpMouseInWindow SDL_WarpMouseInWindow; da_SDL_WarpMouseGlobal SDL_WarpMouseGlobal; da_SDL_SetRelativeMouseMode SDL_SetRelativeMouseMode; da_SDL_CaptureMouse SDL_CaptureMouse; da_SDL_GetRelativeMouseMode SDL_GetRelativeMouseMode; da_SDL_CreateCursor SDL_CreateCursor; da_SDL_CreateColorCursor SDL_CreateColorCursor; da_SDL_CreateSystemCursor SDL_CreateSystemCursor; da_SDL_SetCursor SDL_SetCursor; da_SDL_GetCursor SDL_GetCursor; da_SDL_GetDefaultCursor SDL_GetDefaultCursor; da_SDL_FreeCursor SDL_FreeCursor; da_SDL_ShowCursor SDL_ShowCursor; da_SDL_GetPixelFormatName SDL_GetPixelFormatName; da_SDL_PixelFormatEnumToMasks SDL_PixelFormatEnumToMasks; da_SDL_MasksToPixelFormatEnum SDL_MasksToPixelFormatEnum; da_SDL_AllocFormat SDL_AllocFormat; da_SDL_FreeFormat SDL_FreeFormat; da_SDL_AllocPalette SDL_AllocPalette; da_SDL_SetPixelFormatPalette SDL_SetPixelFormatPalette; da_SDL_SetPaletteColors SDL_SetPaletteColors; da_SDL_FreePalette SDL_FreePalette; da_SDL_MapRGB SDL_MapRGB; da_SDL_MapRGBA SDL_MapRGBA; da_SDL_GetRGB SDL_GetRGB; da_SDL_GetRGBA SDL_GetRGBA; da_SDL_CalculateGammaRamp SDL_CalculateGammaRamp; da_SDL_GetPlatform SDL_GetPlatform; da_SDL_GetPowerInfo SDL_GetPowerInfo; da_SDL_HasIntersection SDL_HasIntersection; da_SDL_IntersectRect SDL_IntersectRect; da_SDL_UnionRect SDL_UnionRect; da_SDL_EnclosePoints SDL_EnclosePoints; da_SDL_IntersectRectAndLine SDL_IntersectRectAndLine; da_SDL_GetNumRenderDrivers SDL_GetNumRenderDrivers; da_SDL_GetRenderDriverInfo SDL_GetRenderDriverInfo; da_SDL_CreateWindowAndRenderer SDL_CreateWindowAndRenderer; da_SDL_CreateRenderer SDL_CreateRenderer; da_SDL_CreateSoftwareRenderer SDL_CreateSoftwareRenderer; da_SDL_GetRenderer SDL_GetRenderer; da_SDL_GetRendererInfo SDL_GetRendererInfo; da_SDL_GetRendererOutputSize SDL_GetRendererOutputSize; da_SDL_CreateTexture SDL_CreateTexture; da_SDL_CreateTextureFromSurface SDL_CreateTextureFromSurface; da_SDL_QueryTexture SDL_QueryTexture; da_SDL_SetTextureColorMod SDL_SetTextureColorMod; da_SDL_GetTextureColorMod SDL_GetTextureColorMod; da_SDL_SetTextureAlphaMod SDL_SetTextureAlphaMod; da_SDL_GetTextureAlphaMod SDL_GetTextureAlphaMod; da_SDL_SetTextureBlendMode SDL_SetTextureBlendMode; da_SDL_GetTextureBlendMode SDL_GetTextureBlendMode; da_SDL_UpdateTexture SDL_UpdateTexture; da_SDL_UpdateYUVTexture SDL_UpdateYUVTexture; da_SDL_LockTexture SDL_LockTexture; da_SDL_UnlockTexture SDL_UnlockTexture; da_SDL_RenderTargetSupported SDL_RenderTargetSupported; da_SDL_SetRenderTarget SDL_SetRenderTarget; da_SDL_GetRenderTarget SDL_GetRenderTarget; da_SDL_RenderSetClipRect SDL_RenderSetClipRect; da_SDL_RenderGetClipRect SDL_RenderGetClipRect; da_SDL_RenderSetLogicalSize SDL_RenderSetLogicalSize; da_SDL_RenderGetLogicalSize SDL_RenderGetLogicalSize; da_SDL_RenderSetIntegerScale SDL_RenderSetIntegerScale; da_SDL_RenderGetIntegerScale SDL_RenderGetIntegerScale; da_SDL_RenderSetViewport SDL_RenderSetViewport; da_SDL_RenderGetViewport SDL_RenderGetViewport; da_SDL_RenderIsClipEnabled SDL_RenderIsClipEnabled; da_SDL_RenderSetScale SDL_RenderSetScale; da_SDL_RenderGetScale SDL_RenderGetScale; da_SDL_SetRenderDrawColor SDL_SetRenderDrawColor; da_SDL_GetRenderDrawColor SDL_GetRenderDrawColor; da_SDL_SetRenderDrawBlendMode SDL_SetRenderDrawBlendMode; da_SDL_GetRenderDrawBlendMode SDL_GetRenderDrawBlendMode; da_SDL_RenderClear SDL_RenderClear; da_SDL_RenderDrawPoint SDL_RenderDrawPoint; da_SDL_RenderDrawPoints SDL_RenderDrawPoints; da_SDL_RenderDrawLine SDL_RenderDrawLine; da_SDL_RenderDrawLines SDL_RenderDrawLines; da_SDL_RenderDrawRect SDL_RenderDrawRect; da_SDL_RenderDrawRects SDL_RenderDrawRects; da_SDL_RenderFillRect SDL_RenderFillRect; da_SDL_RenderFillRects SDL_RenderFillRects; da_SDL_RenderCopy SDL_RenderCopy; da_SDL_RenderCopyEx SDL_RenderCopyEx; da_SDL_RenderReadPixels SDL_RenderReadPixels; da_SDL_RenderPresent SDL_RenderPresent; da_SDL_DestroyTexture SDL_DestroyTexture; da_SDL_DestroyRenderer SDL_DestroyRenderer; da_SDL_GL_BindTexture SDL_GL_BindTexture; da_SDL_GL_UnbindTexture SDL_GL_UnbindTexture; da_SDL_RWFromFile SDL_RWFromFile; da_SDL_RWFromFP SDL_RWFromFP; da_SDL_RWFromMem SDL_RWFromMem; da_SDL_RWFromConstMem SDL_RWFromConstMem; da_SDL_AllocRW SDL_AllocRW; da_SDL_FreeRW SDL_FreeRW; da_SDL_ReadU8 SDL_ReadU8; da_SDL_ReadLE16 SDL_ReadLE16; da_SDL_ReadBE16 SDL_ReadBE16; da_SDL_ReadLE32 SDL_ReadLE32; da_SDL_ReadBE32 SDL_ReadBE32; da_SDL_ReadLE64 SDL_ReadLE64; da_SDL_ReadBE64 SDL_ReadBE64; da_SDL_WriteU8 SDL_WriteU8; da_SDL_WriteLE16 SDL_WriteLE16; da_SDL_WriteBE16 SDL_WriteBE16; da_SDL_WriteLE32 SDL_WriteLE32; da_SDL_WriteBE32 SDL_WriteBE32; da_SDL_WriteLE64 SDL_WriteLE64; da_SDL_WriteBE64 SDL_WriteBE64; da_SDL_CreateShapedWindow SDL_CreateShapedWindow; da_SDL_IsShapedWindow SDL_IsShapedWindow; da_SDL_SetWindowShape SDL_SetWindowShape; da_SDL_GetShapedWindowMode SDL_GetShapedWindowMode; da_SDL_CreateRGBSurface SDL_CreateRGBSurface; da_SDL_CreateRGBSurfaceWithFormat SDL_CreateRGBSurfaceWithFormat; da_SDL_CreateRGBSurfaceFrom SDL_CreateRGBSurfaceFrom; da_SDL_CreateRGBSurfaceWithFormatFrom SDL_CreateRGBSurfaceWithFormatFrom; da_SDL_FreeSurface SDL_FreeSurface; da_SDL_SetSurfacePalette SDL_SetSurfacePalette; da_SDL_LockSurface SDL_LockSurface; da_SDL_UnlockSurface SDL_UnlockSurface; da_SDL_LoadBMP_RW SDL_LoadBMP_RW; da_SDL_SaveBMP_RW SDL_SaveBMP_RW; da_SDL_SetSurfaceRLE SDL_SetSurfaceRLE; da_SDL_SetColorKey SDL_SetColorKey; da_SDL_GetColorKey SDL_GetColorKey; da_SDL_SetSurfaceColorMod SDL_SetSurfaceColorMod; da_SDL_GetSurfaceColorMod SDL_GetSurfaceColorMod; da_SDL_SetSurfaceAlphaMod SDL_SetSurfaceAlphaMod; da_SDL_GetSurfaceAlphaMod SDL_GetSurfaceAlphaMod; da_SDL_SetSurfaceBlendMode SDL_SetSurfaceBlendMode; da_SDL_GetSurfaceBlendMode SDL_GetSurfaceBlendMode; da_SDL_SetClipRect SDL_SetClipRect; da_SDL_GetClipRect SDL_GetClipRect; da_SDL_ConvertSurface SDL_ConvertSurface; da_SDL_ConvertSurfaceFormat SDL_ConvertSurfaceFormat; da_SDL_ConvertPixels SDL_ConvertPixels; da_SDL_FillRect SDL_FillRect; da_SDL_FillRects SDL_FillRects; da_SDL_UpperBlit SDL_UpperBlit; da_SDL_LowerBlit SDL_LowerBlit; da_SDL_SoftStretch SDL_SoftStretch; da_SDL_UpperBlitScaled SDL_UpperBlitScaled; da_SDL_LowerBlitScaled SDL_LowerBlitScaled; static if(Derelict_OS_Windows) { da_SDL_Direct3D9GetAdapterIndex SDL_Direct3D9GetAdapterIndex ; da_SDL_RenderGetD3D9Device SDL_RenderGetD3D9Device; da_SDL_DXGIGetOutputInfo SDL_DXGIGetOutputInfo; } static if(Derelict_OS_iOS) { da_SDL_iPhoneSetAnimationCallback SDL_iPhoneSetAnimationCallback; da_SDL_iPhoneSetEventPump SDL_iPhoneSetEventPump; } static if(Derelict_OS_Android) { da_SDL_AndroidGetJNIEnv SDL_AndroidGetJNIEnv; da_SDL_AndroidGetActivity SDL_AndroidGetActivity; da_SDL_AndroidGetInternalStoragePath SDL_AndroidGetInternalStoragePath; da_SDL_AndroidGetInternalStorageState SDL_AndroidGetInternalStorageState; da_SDL_AndroidGetExternalStoragePath SDL_AndroidGetExternalStoragePath; } static if(Derelict_OS_WinRT) { da_SDL_WinRTGetFSPathUNICODE SDL_WinRTGetFSPathUNICODE; da_SDL_WinRTGetFSPathUTF8 SDL_WinRTGetFSPathUTF8; da_SDL_WinRTRunApp SDL_WinRTRunApp; } da_SDL_GetWindowWMInfo SDL_GetWindowWMInfo; da_SDL_GetTicks SDL_GetTicks; da_SDL_GetPerformanceCounter SDL_GetPerformanceCounter; da_SDL_GetPerformanceFrequency SDL_GetPerformanceFrequency; da_SDL_Delay SDL_Delay; da_SDL_AddTimer SDL_AddTimer; da_SDL_RemoveTimer SDL_RemoveTimer; da_SDL_GetNumTouchDevices SDL_GetNumTouchDevices; da_SDL_GetTouchDevice SDL_GetTouchDevice; da_SDL_GetNumTouchFingers SDL_GetNumTouchFingers; da_SDL_GetTouchFinger SDL_GetTouchFinger; da_SDL_GetVersion SDL_GetVersion; da_SDL_GetRevision SDL_GetRevision; da_SDL_GetRevisionNumber SDL_GetRevisionNumber; da_SDL_GetNumVideoDrivers SDL_GetNumVideoDrivers; da_SDL_GetVideoDriver SDL_GetVideoDriver; da_SDL_VideoInit SDL_VideoInit; da_SDL_VideoQuit SDL_VideoQuit; da_SDL_GetCurrentVideoDriver SDL_GetCurrentVideoDriver; da_SDL_GetNumVideoDisplays SDL_GetNumVideoDisplays; da_SDL_GetDisplayName SDL_GetDisplayName; da_SDL_GetDisplayBounds SDL_GetDisplayBounds; da_SDL_GetDisplayDPI SDL_GetDisplayDPI; da_SDL_GetDisplayUsableBounds SDL_GetDisplayUsableBounds; da_SDL_GetNumDisplayModes SDL_GetNumDisplayModes; da_SDL_GetDisplayMode SDL_GetDisplayMode; da_SDL_GetDesktopDisplayMode SDL_GetDesktopDisplayMode; da_SDL_GetCurrentDisplayMode SDL_GetCurrentDisplayMode; da_SDL_GetClosestDisplayMode SDL_GetClosestDisplayMode; da_SDL_GetWindowDisplayIndex SDL_GetWindowDisplayIndex; da_SDL_SetWindowDisplayMode SDL_SetWindowDisplayMode; da_SDL_GetWindowDisplayMode SDL_GetWindowDisplayMode; da_SDL_GetWindowPixelFormat SDL_GetWindowPixelFormat; da_SDL_CreateWindow SDL_CreateWindow; da_SDL_CreateWindowFrom SDL_CreateWindowFrom; da_SDL_GetWindowID SDL_GetWindowID; da_SDL_GetWindowFromID SDL_GetWindowFromID; da_SDL_GetWindowFlags SDL_GetWindowFlags; da_SDL_SetWindowTitle SDL_SetWindowTitle; da_SDL_GetWindowTitle SDL_GetWindowTitle; da_SDL_SetWindowIcon SDL_SetWindowIcon; da_SDL_SetWindowData SDL_SetWindowData; da_SDL_GetWindowData SDL_GetWindowData; da_SDL_SetWindowPosition SDL_SetWindowPosition; da_SDL_GetWindowPosition SDL_GetWindowPosition; da_SDL_SetWindowSize SDL_SetWindowSize; da_SDL_GetWindowSize SDL_GetWindowSize; da_SDL_GetWindowBordersSize SDL_GetWindowBordersSize; da_SDL_SetWindowMinimumSize SDL_SetWindowMinimumSize; da_SDL_GetWindowMinimumSize SDL_GetWindowMinimumSize; da_SDL_SetWindowMaximumSize SDL_SetWindowMaximumSize; da_SDL_GetWindowMaximumSize SDL_GetWindowMaximumSize; da_SDL_SetWindowBordered SDL_SetWindowBordered; da_SDL_SetWindowResizable SDL_SetWindowResizable; da_SDL_ShowWindow SDL_ShowWindow; da_SDL_HideWindow SDL_HideWindow; da_SDL_RaiseWindow SDL_RaiseWindow; da_SDL_MaximizeWindow SDL_MaximizeWindow; da_SDL_MinimizeWindow SDL_MinimizeWindow; da_SDL_RestoreWindow SDL_RestoreWindow; da_SDL_SetWindowFullscreen SDL_SetWindowFullscreen; da_SDL_GetWindowSurface SDL_GetWindowSurface; da_SDL_UpdateWindowSurface SDL_UpdateWindowSurface; da_SDL_UpdateWindowSurfaceRects SDL_UpdateWindowSurfaceRects; da_SDL_SetWindowGrab SDL_SetWindowGrab; da_SDL_GetWindowGrab SDL_GetWindowGrab; da_SDL_GetGrabbedWindow SDL_GetGrabbedWindow; da_SDL_SetWindowBrightness SDL_SetWindowBrightness; da_SDL_GetWindowBrightness SDL_GetWindowBrightness; da_SDL_SetWindowOpacity SDL_SetWindowOpacity; da_SDL_GetWindowOpacity SDL_GetWindowOpacity; da_SDL_SetWindowModalFor SDL_SetWindowModalFor; da_SDL_SetWindowInputFocus SDL_SetWindowInputFocus; da_SDL_SetWindowGammaRamp SDL_SetWindowGammaRamp; da_SDL_GetWindowGammaRamp SDL_GetWindowGammaRamp; da_SDL_SetWindowHitTest SDL_SetWindowHitTest; da_SDL_DestroyWindow SDL_DestroyWindow; da_SDL_IsScreenSaverEnabled SDL_IsScreenSaverEnabled; da_SDL_EnableScreenSaver SDL_EnableScreenSaver; da_SDL_DisableScreenSaver SDL_DisableScreenSaver; da_SDL_GL_LoadLibrary SDL_GL_LoadLibrary; da_SDL_GL_GetProcAddress SDL_GL_GetProcAddress; da_SDL_GL_UnloadLibrary SDL_GL_UnloadLibrary; da_SDL_GL_ExtensionSupported SDL_GL_ExtensionSupported; da_SDL_GL_ResetAttributes SDL_GL_ResetAttributes; da_SDL_GL_SetAttribute SDL_GL_SetAttribute; da_SDL_GL_GetAttribute SDL_GL_GetAttribute; da_SDL_GL_CreateContext SDL_GL_CreateContext; da_SDL_GL_MakeCurrent SDL_GL_MakeCurrent; da_SDL_GL_GetCurrentWindow SDL_GL_GetCurrentWindow; da_SDL_GL_GetCurrentContext SDL_GL_GetCurrentContext; da_SDL_GL_GetDrawableSize SDL_GL_GetDrawableSize; da_SDL_GL_SetSwapInterval SDL_GL_SetSwapInterval; da_SDL_GL_GetSwapInterval SDL_GL_GetSwapInterval; da_SDL_GL_SwapWindow SDL_GL_SwapWindow; da_SDL_GL_DeleteContext SDL_GL_DeleteContext; } CheeseCutter-2.10/src/derelict/sdl2/internal/sdl_dynload.d000066400000000000000000001334351516216315000235330ustar00rootroot00000000000000/* Boost Software License - Version 1.0 - August 17th, 2003 Permission is hereby granted, free of charge, to any person or organization obtaining a copy of the software and accompanying documentation covered by this license (the "Software") to use, reproduce, display, distribute, execute, and transmit the Software, and to prepare derivative works of the Software, and to permit third-parties to whom the Software is furnished to do so, all subject to the following: The copyright notices in the Software and this entire statement, including the above license grant, this restriction and the following disclaimer, must be included in all copies of the Software, in whole or in part, and all derivative works of the Software, unless such copies or derivative works are solely in the form of machine-executable object code generated by a source language processor. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ module derelict.sdl2.internal.sdl_dynload; public { import derelict.sdl2.internal.sdl_dynamic, derelict.sdl2.internal.sdl_types; import derelict.util.loader; } import derelict.util.exception, derelict.util.system; /* This function is not part of the public interface, but SDL expects it to be called before any subsystems have been intiailized. Normally, this happens via linking with libSDLmain, but since that doesn't happen when using Derelict, then the loader must load this function and call it before the load method returns. Otherwise, bad things can happen. */ private extern(C) nothrow alias da_SDL_SetMainReady = void function(); class DerelictSDL2Loader : SharedLibLoader { this() { super(libNames); } protected: override void configureMinimumVersion(SharedLibVersion minVersion) { if(minVersion.major == 2 && minVersion.minor == 0) { if(minVersion.patch == 4) { missingSymbolCallback = &allowSDL_2_0_4; } else if(minVersion.patch == 3) { missingSymbolCallback = &allowSDL_2_0_3; } else if(minVersion.patch == 2) { missingSymbolCallback = &allowSDL_2_0_2; } else if(minVersion.patch == 1) { missingSymbolCallback = &allowSDL_2_0_1; } else if(minVersion.patch == 0) { missingSymbolCallback = &allowSDL_2_0_0; } } } override void loadSymbols() { bindFunc(cast(void**)&SDL_Init, "SDL_Init"); bindFunc(cast(void**)&SDL_InitSubSystem, "SDL_InitSubSystem"); bindFunc(cast(void**)&SDL_QuitSubSystem, "SDL_QuitSubSystem"); bindFunc(cast(void**)&SDL_WasInit, "SDL_WasInit"); bindFunc(cast(void**)&SDL_Quit, "SDL_Quit"); bindFunc(cast(void**)&SDL_free, "SDL_free"); bindFunc(cast(void**)&SDL_SetAssertionHandler, "SDL_SetAssertionHandler"); bindFunc(cast(void**)&SDL_GetDefaultAssertionHandler, "SDL_GetDefaultAssertionHandler"); bindFunc(cast(void**)&SDL_GetAssertionHandler, "SDL_GetAssertionHandler"); bindFunc(cast(void**)&SDL_GetAssertionReport, "SDL_GetAssertionReport"); bindFunc(cast(void**)&SDL_ResetAssertionReport, "SDL_ResetAssertionReport"); bindFunc(cast(void**)&SDL_GetNumAudioDrivers, "SDL_GetNumAudioDrivers"); bindFunc(cast(void**)&SDL_GetAudioDriver, "SDL_GetAudioDriver"); bindFunc(cast(void**)&SDL_AudioInit, "SDL_AudioInit"); bindFunc(cast(void**)&SDL_AudioQuit, "SDL_AudioQuit"); bindFunc(cast(void**)&SDL_GetCurrentAudioDriver, "SDL_GetCurrentAudioDriver"); bindFunc(cast(void**)&SDL_OpenAudio, "SDL_OpenAudio"); bindFunc(cast(void**)&SDL_GetNumAudioDevices, "SDL_GetNumAudioDevices"); bindFunc(cast(void**)&SDL_GetAudioDeviceName, "SDL_GetAudioDeviceName"); bindFunc(cast(void**)&SDL_OpenAudioDevice, "SDL_OpenAudioDevice"); bindFunc(cast(void**)&SDL_GetAudioStatus, "SDL_GetAudioStatus"); bindFunc(cast(void**)&SDL_GetAudioDeviceStatus, "SDL_GetAudioDeviceStatus"); bindFunc(cast(void**)&SDL_PauseAudio, "SDL_PauseAudio"); bindFunc(cast(void**)&SDL_PauseAudioDevice, "SDL_PauseAudioDevice"); bindFunc(cast(void**)&SDL_LoadWAV_RW, "SDL_LoadWAV_RW"); bindFunc(cast(void**)&SDL_FreeWAV, "SDL_FreeWAV"); bindFunc(cast(void**)&SDL_BuildAudioCVT, "SDL_BuildAudioCVT"); bindFunc(cast(void**)&SDL_ConvertAudio, "SDL_ConvertAudio"); bindFunc(cast(void**)&SDL_MixAudio, "SDL_MixAudio"); bindFunc(cast(void**)&SDL_MixAudioFormat, "SDL_MixAudioFormat"); bindFunc(cast(void**)&SDL_QueueAudio, "SDL_QueueAudio"); bindFunc(cast(void**)&SDL_DequeueAudio, "SDL_DequeueAudio"); bindFunc(cast(void**)&SDL_GetQueuedAudioSize, "SDL_GetQueuedAudioSize"); bindFunc(cast(void**)&SDL_ClearQueuedAudio, "SDL_ClearQueuedAudio"); bindFunc(cast(void**)&SDL_LockAudio, "SDL_LockAudio"); bindFunc(cast(void**)&SDL_LockAudioDevice, "SDL_LockAudioDevice"); bindFunc(cast(void**)&SDL_UnlockAudio, "SDL_UnlockAudio"); bindFunc(cast(void**)&SDL_UnlockAudioDevice, "SDL_UnlockAudioDevice"); bindFunc(cast(void**)&SDL_CloseAudio, "SDL_CloseAudio"); bindFunc(cast(void**)&SDL_CloseAudioDevice, "SDL_CloseAudioDevice"); //bindFunc(cast(void**)&SDL_AudioDeviceConnected, "SDL_AudioDeviceConnected"); bindFunc(cast(void**)&SDL_SetClipboardText, "SDL_SetClipboardText"); bindFunc(cast(void**)&SDL_GetClipboardText, "SDL_GetClipboardText"); bindFunc(cast(void**)&SDL_HasClipboardText, "SDL_HasClipboardText"); bindFunc(cast(void**)&SDL_GetCPUCount, "SDL_GetCPUCount"); bindFunc(cast(void**)&SDL_GetCPUCacheLineSize, "SDL_GetCPUCacheLineSize"); bindFunc(cast(void**)&SDL_HasRDTSC, "SDL_HasRDTSC"); bindFunc(cast(void**)&SDL_HasAltiVec, "SDL_HasAltiVec"); bindFunc(cast(void**)&SDL_HasMMX, "SDL_HasMMX"); bindFunc(cast(void**)&SDL_Has3DNow, "SDL_Has3DNow"); bindFunc(cast(void**)&SDL_HasSSE, "SDL_HasSSE"); bindFunc(cast(void**)&SDL_HasSSE2, "SDL_HasSSE2"); bindFunc(cast(void**)&SDL_HasSSE3, "SDL_HasSSE3"); bindFunc(cast(void**)&SDL_HasSSE41, "SDL_HasSSE41"); bindFunc(cast(void**)&SDL_HasSSE42, "SDL_HasSSE42"); bindFunc(cast(void**)&SDL_HasAVX, "SDL_HasAVX"); bindFunc(cast(void**)&SDL_HasAVX2, "SDL_HasAVX2"); bindFunc(cast(void**)&SDL_GetSystemRAM, "SDL_GetSystemRAM"); bindFunc(cast(void**)&SDL_SetError, "SDL_SetError"); bindFunc(cast(void**)&SDL_GetError, "SDL_GetError"); bindFunc(cast(void**)&SDL_ClearError, "SDL_ClearError"); bindFunc(cast(void**)&SDL_PumpEvents, "SDL_PumpEvents"); bindFunc(cast(void**)&SDL_PeepEvents, "SDL_PeepEvents"); bindFunc(cast(void**)&SDL_HasEvent, "SDL_HasEvent"); bindFunc(cast(void**)&SDL_HasEvents, "SDL_HasEvents"); bindFunc(cast(void**)&SDL_FlushEvent, "SDL_FlushEvent"); bindFunc(cast(void**)&SDL_FlushEvents, "SDL_FlushEvents"); bindFunc(cast(void**)&SDL_PollEvent, "SDL_PollEvent"); bindFunc(cast(void**)&SDL_WaitEvent, "SDL_WaitEvent"); bindFunc(cast(void**)&SDL_WaitEventTimeout, "SDL_WaitEventTimeout"); bindFunc(cast(void**)&SDL_PushEvent, "SDL_PushEvent"); bindFunc(cast(void**)&SDL_SetEventFilter, "SDL_SetEventFilter"); bindFunc(cast(void**)&SDL_GetEventFilter, "SDL_GetEventFilter"); bindFunc(cast(void**)&SDL_AddEventWatch, "SDL_AddEventWatch"); bindFunc(cast(void**)&SDL_DelEventWatch, "SDL_DelEventWatch"); bindFunc(cast(void**)&SDL_FilterEvents, "SDL_FilterEvents"); bindFunc(cast(void**)&SDL_EventState, "SDL_EventState"); bindFunc(cast(void**)&SDL_RegisterEvents, "SDL_RegisterEvents"); bindFunc(cast(void**)&SDL_GetBasePath, "SDL_GetBasePath"); bindFunc(cast(void**)&SDL_GetPrefPath, "SDL_GetPrefPath"); bindFunc(cast(void**)&SDL_GameControllerAddMappingsFromRW, "SDL_GameControllerAddMappingsFromRW"); bindFunc(cast(void**)&SDL_GameControllerAddMapping, "SDL_GameControllerAddMapping"); bindFunc(cast(void**)&SDL_GameControllerMappingForGUID, "SDL_GameControllerMappingForGUID"); bindFunc(cast(void**)&SDL_GameControllerMapping, "SDL_GameControllerMapping"); bindFunc(cast(void**)&SDL_IsGameController, "SDL_IsGameController"); bindFunc(cast(void**)&SDL_GameControllerNameForIndex, "SDL_GameControllerNameForIndex"); bindFunc(cast(void**)&SDL_GameControllerOpen, "SDL_GameControllerOpen"); bindFunc(cast(void**)&SDL_GameControllerFromInstanceID, "SDL_GameControllerFromInstanceID"); bindFunc(cast(void**)&SDL_GameControllerName, "SDL_GameControllerName"); bindFunc(cast(void**)&SDL_GameControllerGetAttached, "SDL_GameControllerGetAttached"); bindFunc(cast(void**)&SDL_GameControllerGetJoystick, "SDL_GameControllerGetJoystick"); bindFunc(cast(void**)&SDL_GameControllerEventState, "SDL_GameControllerEventState"); bindFunc(cast(void**)&SDL_GameControllerUpdate, "SDL_GameControllerUpdate"); bindFunc(cast(void**)&SDL_GameControllerGetAxisFromString, "SDL_GameControllerGetAxisFromString"); bindFunc(cast(void**)&SDL_GameControllerGetStringForAxis, "SDL_GameControllerGetStringForAxis"); bindFunc(cast(void**)&SDL_GameControllerGetBindForAxis, "SDL_GameControllerGetBindForAxis"); bindFunc(cast(void**)&SDL_GameControllerGetAxis, "SDL_GameControllerGetAxis"); bindFunc(cast(void**)&SDL_GameControllerGetButtonFromString, "SDL_GameControllerGetButtonFromString"); bindFunc(cast(void**)&SDL_GameControllerGetStringForButton, "SDL_GameControllerGetStringForButton"); bindFunc(cast(void**)&SDL_GameControllerGetBindForButton, "SDL_GameControllerGetBindForButton"); bindFunc(cast(void**)&SDL_GameControllerGetButton, "SDL_GameControllerGetButton"); bindFunc(cast(void**)&SDL_GameControllerClose, "SDL_GameControllerClose"); bindFunc(cast(void**)&SDL_RecordGesture, "SDL_RecordGesture"); bindFunc(cast(void**)&SDL_SaveAllDollarTemplates, "SDL_SaveAllDollarTemplates"); bindFunc(cast(void**)&SDL_SaveDollarTemplate, "SDL_SaveDollarTemplate"); bindFunc(cast(void**)&SDL_LoadDollarTemplates, "SDL_LoadDollarTemplates"); bindFunc(cast(void**)&SDL_NumHaptics, "SDL_NumHaptics"); bindFunc(cast(void**)&SDL_HapticName, "SDL_HapticName"); bindFunc(cast(void**)&SDL_HapticOpen, "SDL_HapticOpen"); bindFunc(cast(void**)&SDL_HapticOpened, "SDL_HapticOpened"); bindFunc(cast(void**)&SDL_HapticIndex, "SDL_HapticIndex"); bindFunc(cast(void**)&SDL_MouseIsHaptic, "SDL_MouseIsHaptic"); bindFunc(cast(void**)&SDL_HapticOpenFromMouse, "SDL_HapticOpenFromMouse"); bindFunc(cast(void**)&SDL_JoystickIsHaptic, "SDL_JoystickIsHaptic"); bindFunc(cast(void**)&SDL_HapticOpenFromJoystick, "SDL_HapticOpenFromJoystick"); bindFunc(cast(void**)&SDL_HapticClose, "SDL_HapticClose"); bindFunc(cast(void**)&SDL_HapticNumEffects, "SDL_HapticNumEffects"); bindFunc(cast(void**)&SDL_HapticNumEffectsPlaying, "SDL_HapticNumEffectsPlaying"); bindFunc(cast(void**)&SDL_HapticQuery, "SDL_HapticQuery"); bindFunc(cast(void**)&SDL_HapticNumAxes, "SDL_HapticNumAxes"); bindFunc(cast(void**)&SDL_HapticEffectSupported, "SDL_HapticEffectSupported"); bindFunc(cast(void**)&SDL_HapticNewEffect, "SDL_HapticNewEffect"); bindFunc(cast(void**)&SDL_HapticUpdateEffect, "SDL_HapticUpdateEffect"); bindFunc(cast(void**)&SDL_HapticRunEffect, "SDL_HapticRunEffect"); bindFunc(cast(void**)&SDL_HapticStopEffect, "SDL_HapticStopEffect"); bindFunc(cast(void**)&SDL_HapticDestroyEffect, "SDL_HapticDestroyEffect"); bindFunc(cast(void**)&SDL_HapticGetEffectStatus, "SDL_HapticGetEffectStatus"); bindFunc(cast(void**)&SDL_HapticSetGain, "SDL_HapticSetGain"); bindFunc(cast(void**)&SDL_HapticSetAutocenter, "SDL_HapticSetAutocenter"); bindFunc(cast(void**)&SDL_HapticPause, "SDL_HapticPause"); bindFunc(cast(void**)&SDL_HapticUnpause, "SDL_HapticUnpause"); bindFunc(cast(void**)&SDL_HapticStopAll, "SDL_HapticStopAll"); bindFunc(cast(void**)&SDL_HapticRumbleSupported, "SDL_HapticRumbleSupported"); bindFunc(cast(void**)&SDL_HapticRumbleInit, "SDL_HapticRumbleInit"); bindFunc(cast(void**)&SDL_HapticRumblePlay, "SDL_HapticRumblePlay"); bindFunc(cast(void**)&SDL_HapticRumbleStop, "SDL_HapticRumbleStop"); bindFunc(cast(void**)&SDL_SetHintWithPriority, "SDL_SetHintWithPriority"); bindFunc(cast(void**)&SDL_SetHint, "SDL_SetHint"); bindFunc(cast(void**)&SDL_GetHint, "SDL_GetHint"); bindFunc(cast(void**)&SDL_GetHintBoolean, "SDL_GetHintBoolean"); bindFunc(cast(void**)&SDL_AddHintCallback, "SDL_AddHintCallback"); bindFunc(cast(void**)&SDL_DelHintCallback, "SDL_DelHintCallback"); bindFunc(cast(void**)&SDL_ClearHints, "SDL_ClearHints"); bindFunc(cast(void**)&SDL_NumJoysticks, "SDL_NumJoysticks"); bindFunc(cast(void**)&SDL_JoystickNameForIndex, "SDL_JoystickNameForIndex"); bindFunc(cast(void**)&SDL_JoystickOpen, "SDL_JoystickOpen"); bindFunc(cast(void**)&SDL_JoystickName, "SDL_JoystickName"); bindFunc(cast(void**)&SDL_JoystickFromInstanceID, "SDL_JoystickFromInstanceID"); bindFunc(cast(void**)&SDL_JoystickGetDeviceGUID, "SDL_JoystickGetDeviceGUID"); bindFunc(cast(void**)&SDL_JoystickGetGUID, "SDL_JoystickGetGUID"); bindFunc(cast(void**)&SDL_JoystickGetGUIDString, "SDL_JoystickGetGUIDString"); bindFunc(cast(void**)&SDL_JoystickGetGUIDFromString, "SDL_JoystickGetGUIDFromString"); bindFunc(cast(void**)&SDL_JoystickGetAttached, "SDL_JoystickGetAttached"); bindFunc(cast(void**)&SDL_JoystickInstanceID, "SDL_JoystickInstanceID"); bindFunc(cast(void**)&SDL_JoystickNumAxes, "SDL_JoystickNumAxes"); bindFunc(cast(void**)&SDL_JoystickNumBalls, "SDL_JoystickNumBalls"); bindFunc(cast(void**)&SDL_JoystickNumHats, "SDL_JoystickNumHats"); bindFunc(cast(void**)&SDL_JoystickNumButtons, "SDL_JoystickNumButtons"); bindFunc(cast(void**)&SDL_JoystickUpdate, "SDL_JoystickUpdate"); bindFunc(cast(void**)&SDL_JoystickEventState, "SDL_JoystickEventState"); bindFunc(cast(void**)&SDL_JoystickGetAxis, "SDL_JoystickGetAxis"); bindFunc(cast(void**)&SDL_JoystickGetHat, "SDL_JoystickGetHat"); bindFunc(cast(void**)&SDL_JoystickGetBall, "SDL_JoystickGetBall"); bindFunc(cast(void**)&SDL_JoystickGetButton, "SDL_JoystickGetButton"); bindFunc(cast(void**)&SDL_JoystickClose, "SDL_JoystickClose"); bindFunc(cast(void**)&SDL_JoystickCurrentPowerLevel, "SDL_JoystickCurrentPowerLevel"); bindFunc(cast(void**)&SDL_GetKeyboardFocus, "SDL_GetKeyboardFocus"); bindFunc(cast(void**)&SDL_GetKeyboardState, "SDL_GetKeyboardState"); bindFunc(cast(void**)&SDL_GetModState, "SDL_GetModState"); bindFunc(cast(void**)&SDL_SetModState, "SDL_SetModState"); bindFunc(cast(void**)&SDL_GetKeyFromScancode, "SDL_GetKeyFromScancode"); bindFunc(cast(void**)&SDL_GetScancodeFromKey, "SDL_GetScancodeFromKey"); bindFunc(cast(void**)&SDL_GetScancodeName, "SDL_GetScancodeName"); bindFunc(cast(void**)&SDL_GetScancodeFromName, "SDL_GetScancodeFromName"); bindFunc(cast(void**)&SDL_GetKeyName, "SDL_GetKeyName"); bindFunc(cast(void**)&SDL_GetKeyFromName, "SDL_GetKeyFromName"); bindFunc(cast(void**)&SDL_StartTextInput, "SDL_StartTextInput"); bindFunc(cast(void**)&SDL_IsTextInputActive, "SDL_IsTextInputActive"); bindFunc(cast(void**)&SDL_StopTextInput, "SDL_StopTextInput"); bindFunc(cast(void**)&SDL_SetTextInputRect, "SDL_SetTextInputRect"); bindFunc(cast(void**)&SDL_HasScreenKeyboardSupport, "SDL_HasScreenKeyboardSupport"); bindFunc(cast(void**)&SDL_IsScreenKeyboardShown, "SDL_IsScreenKeyboardShown"); bindFunc(cast(void**)&SDL_LoadObject, "SDL_LoadObject"); bindFunc(cast(void**)&SDL_LoadFunction, "SDL_LoadFunction"); bindFunc(cast(void**)&SDL_UnloadObject, "SDL_UnloadObject"); bindFunc(cast(void**)&SDL_LogSetAllPriority, "SDL_LogSetAllPriority"); bindFunc(cast(void**)&SDL_LogSetPriority, "SDL_LogSetPriority"); bindFunc(cast(void**)&SDL_LogGetPriority, "SDL_LogGetPriority"); bindFunc(cast(void**)&SDL_LogResetPriorities, "SDL_LogResetPriorities"); bindFunc(cast(void**)&SDL_Log, "SDL_Log"); bindFunc(cast(void**)&SDL_LogVerbose, "SDL_LogVerbose"); bindFunc(cast(void**)&SDL_LogDebug, "SDL_LogDebug"); bindFunc(cast(void**)&SDL_LogInfo, "SDL_LogInfo"); bindFunc(cast(void**)&SDL_LogWarn, "SDL_LogWarn"); bindFunc(cast(void**)&SDL_LogError, "SDL_LogError"); bindFunc(cast(void**)&SDL_LogCritical, "SDL_LogCritical"); bindFunc(cast(void**)&SDL_LogMessage, "SDL_LogMessage"); bindFunc(cast(void**)&SDL_LogMessageV, "SDL_LogMessageV"); bindFunc(cast(void**)&SDL_LogGetOutputFunction, "SDL_LogGetOutputFunction"); bindFunc(cast(void**)&SDL_LogSetOutputFunction, "SDL_LogSetOutputFunction"); bindFunc(cast(void**)&SDL_ShowMessageBox, "SDL_ShowMessageBox"); bindFunc(cast(void**)&SDL_ShowSimpleMessageBox, "SDL_ShowSimpleMessageBox"); bindFunc(cast(void**)&SDL_GetMouseFocus, "SDL_GetMouseFocus"); bindFunc(cast(void**)&SDL_GetMouseState, "SDL_GetMouseState"); bindFunc(cast(void**)&SDL_GetGlobalMouseState, "SDL_GetGlobalMouseState"); bindFunc(cast(void**)&SDL_GetRelativeMouseState, "SDL_GetRelativeMouseState"); bindFunc(cast(void**)&SDL_WarpMouseInWindow, "SDL_WarpMouseInWindow"); bindFunc(cast(void**)&SDL_WarpMouseGlobal, "SDL_WarpMouseGlobal"); bindFunc(cast(void**)&SDL_SetRelativeMouseMode, "SDL_SetRelativeMouseMode"); bindFunc(cast(void**)&SDL_CaptureMouse, "SDL_CaptureMouse"); bindFunc(cast(void**)&SDL_GetRelativeMouseMode, "SDL_GetRelativeMouseMode"); bindFunc(cast(void**)&SDL_CreateCursor, "SDL_CreateCursor"); bindFunc(cast(void**)&SDL_CreateColorCursor, "SDL_CreateColorCursor"); bindFunc(cast(void**)&SDL_CreateSystemCursor, "SDL_CreateSystemCursor"); bindFunc(cast(void**)&SDL_SetCursor, "SDL_SetCursor"); bindFunc(cast(void**)&SDL_GetCursor, "SDL_GetCursor"); bindFunc(cast(void**)&SDL_GetDefaultCursor, "SDL_GetDefaultCursor"); bindFunc(cast(void**)&SDL_FreeCursor, "SDL_FreeCursor"); bindFunc(cast(void**)&SDL_ShowCursor, "SDL_ShowCursor"); bindFunc(cast(void**)&SDL_GetPixelFormatName, "SDL_GetPixelFormatName"); bindFunc(cast(void**)&SDL_PixelFormatEnumToMasks, "SDL_PixelFormatEnumToMasks"); bindFunc(cast(void**)&SDL_MasksToPixelFormatEnum, "SDL_MasksToPixelFormatEnum"); bindFunc(cast(void**)&SDL_AllocFormat, "SDL_AllocFormat"); bindFunc(cast(void**)&SDL_FreeFormat, "SDL_FreeFormat"); bindFunc(cast(void**)&SDL_AllocPalette, "SDL_AllocPalette"); bindFunc(cast(void**)&SDL_SetPixelFormatPalette, "SDL_SetPixelFormatPalette"); bindFunc(cast(void**)&SDL_SetPaletteColors, "SDL_SetPaletteColors"); bindFunc(cast(void**)&SDL_FreePalette, "SDL_FreePalette"); bindFunc(cast(void**)&SDL_MapRGB, "SDL_MapRGB"); bindFunc(cast(void**)&SDL_MapRGBA, "SDL_MapRGBA"); bindFunc(cast(void**)&SDL_GetRGB, "SDL_GetRGB"); bindFunc(cast(void**)&SDL_GetRGBA, "SDL_GetRGBA"); bindFunc(cast(void**)&SDL_CalculateGammaRamp, "SDL_CalculateGammaRamp"); bindFunc(cast(void**)&SDL_GetPlatform, "SDL_GetPlatform"); bindFunc(cast(void**)&SDL_GetPowerInfo, "SDL_GetPowerInfo"); bindFunc(cast(void**)&SDL_HasIntersection, "SDL_HasIntersection"); bindFunc(cast(void**)&SDL_IntersectRect, "SDL_IntersectRect"); bindFunc(cast(void**)&SDL_UnionRect, "SDL_UnionRect"); bindFunc(cast(void**)&SDL_EnclosePoints, "SDL_EnclosePoints"); bindFunc(cast(void**)&SDL_IntersectRectAndLine, "SDL_IntersectRectAndLine"); bindFunc(cast(void**)&SDL_GetNumRenderDrivers, "SDL_GetNumRenderDrivers"); bindFunc(cast(void**)&SDL_GetRenderDriverInfo, "SDL_GetRenderDriverInfo"); bindFunc(cast(void**)&SDL_CreateWindowAndRenderer, "SDL_CreateWindowAndRenderer"); bindFunc(cast(void**)&SDL_CreateRenderer, "SDL_CreateRenderer"); bindFunc(cast(void**)&SDL_CreateSoftwareRenderer, "SDL_CreateSoftwareRenderer"); bindFunc(cast(void**)&SDL_GetRenderer, "SDL_GetRenderer"); bindFunc(cast(void**)&SDL_GetRendererInfo, "SDL_GetRendererInfo"); bindFunc(cast(void**)&SDL_GetRendererOutputSize, "SDL_GetRendererOutputSize"); bindFunc(cast(void**)&SDL_CreateTexture, "SDL_CreateTexture"); bindFunc(cast(void**)&SDL_CreateTextureFromSurface, "SDL_CreateTextureFromSurface"); bindFunc(cast(void**)&SDL_QueryTexture, "SDL_QueryTexture"); bindFunc(cast(void**)&SDL_SetTextureColorMod, "SDL_SetTextureColorMod"); bindFunc(cast(void**)&SDL_GetTextureColorMod, "SDL_GetTextureColorMod"); bindFunc(cast(void**)&SDL_SetTextureAlphaMod, "SDL_SetTextureAlphaMod"); bindFunc(cast(void**)&SDL_GetTextureAlphaMod, "SDL_GetTextureAlphaMod"); bindFunc(cast(void**)&SDL_SetTextureBlendMode, "SDL_SetTextureBlendMode"); bindFunc(cast(void**)&SDL_GetTextureBlendMode, "SDL_GetTextureBlendMode"); bindFunc(cast(void**)&SDL_UpdateTexture, "SDL_UpdateTexture"); bindFunc(cast(void**)&SDL_UpdateYUVTexture, "SDL_UpdateYUVTexture"); bindFunc(cast(void**)&SDL_LockTexture, "SDL_LockTexture"); bindFunc(cast(void**)&SDL_UnlockTexture, "SDL_UnlockTexture"); bindFunc(cast(void**)&SDL_RenderTargetSupported, "SDL_RenderTargetSupported"); bindFunc(cast(void**)&SDL_SetRenderTarget, "SDL_SetRenderTarget"); bindFunc(cast(void**)&SDL_GetRenderTarget, "SDL_GetRenderTarget"); bindFunc(cast(void**)&SDL_RenderSetClipRect, "SDL_RenderSetClipRect"); bindFunc(cast(void**)&SDL_RenderGetClipRect, "SDL_RenderGetClipRect"); bindFunc(cast(void**)&SDL_RenderSetLogicalSize, "SDL_RenderSetLogicalSize"); bindFunc(cast(void**)&SDL_RenderGetLogicalSize, "SDL_RenderGetLogicalSize"); bindFunc(cast(void**)&SDL_RenderSetIntegerScale, "SDL_RenderSetIntegerScale"); bindFunc(cast(void**)&SDL_RenderGetIntegerScale, "SDL_RenderGetIntegerScale"); bindFunc(cast(void**)&SDL_RenderSetViewport, "SDL_RenderSetViewport"); bindFunc(cast(void**)&SDL_RenderGetViewport, "SDL_RenderGetViewport"); bindFunc(cast(void**)&SDL_RenderIsClipEnabled, "SDL_RenderIsClipEnabled"); bindFunc(cast(void**)&SDL_RenderSetScale, "SDL_RenderSetScale"); bindFunc(cast(void**)&SDL_RenderGetScale, "SDL_RenderGetScale"); bindFunc(cast(void**)&SDL_SetRenderDrawColor, "SDL_SetRenderDrawColor"); bindFunc(cast(void**)&SDL_GetRenderDrawColor, "SDL_GetRenderDrawColor"); bindFunc(cast(void**)&SDL_SetRenderDrawBlendMode, "SDL_SetRenderDrawBlendMode"); bindFunc(cast(void**)&SDL_GetRenderDrawBlendMode, "SDL_GetRenderDrawBlendMode"); bindFunc(cast(void**)&SDL_RenderClear, "SDL_RenderClear"); bindFunc(cast(void**)&SDL_RenderDrawPoint, "SDL_RenderDrawPoint"); bindFunc(cast(void**)&SDL_RenderDrawPoints, "SDL_RenderDrawPoints"); bindFunc(cast(void**)&SDL_RenderDrawLine, "SDL_RenderDrawLine"); bindFunc(cast(void**)&SDL_RenderDrawLines, "SDL_RenderDrawLines"); bindFunc(cast(void**)&SDL_RenderDrawRect, "SDL_RenderDrawRect"); bindFunc(cast(void**)&SDL_RenderDrawRects, "SDL_RenderDrawRects"); bindFunc(cast(void**)&SDL_RenderFillRect, "SDL_RenderFillRect"); bindFunc(cast(void**)&SDL_RenderFillRects, "SDL_RenderFillRects"); bindFunc(cast(void**)&SDL_RenderCopy, "SDL_RenderCopy"); bindFunc(cast(void**)&SDL_RenderCopyEx, "SDL_RenderCopyEx"); bindFunc(cast(void**)&SDL_RenderReadPixels, "SDL_RenderReadPixels"); bindFunc(cast(void**)&SDL_RenderPresent, "SDL_RenderPresent"); bindFunc(cast(void**)&SDL_DestroyTexture, "SDL_DestroyTexture"); bindFunc(cast(void**)&SDL_DestroyRenderer, "SDL_DestroyRenderer"); bindFunc(cast(void**)&SDL_GL_BindTexture, "SDL_GL_BindTexture"); bindFunc(cast(void**)&SDL_GL_UnbindTexture, "SDL_GL_UnbindTexture"); bindFunc(cast(void**)&SDL_RWFromFile, "SDL_RWFromFile"); bindFunc(cast(void**)&SDL_RWFromFP, "SDL_RWFromFP"); bindFunc(cast(void**)&SDL_RWFromMem, "SDL_RWFromMem"); bindFunc(cast(void**)&SDL_RWFromConstMem, "SDL_RWFromConstMem"); bindFunc(cast(void**)&SDL_AllocRW, "SDL_AllocRW"); bindFunc(cast(void**)&SDL_FreeRW, "SDL_FreeRW"); bindFunc(cast(void**)&SDL_ReadU8, "SDL_ReadU8"); bindFunc(cast(void**)&SDL_ReadLE16, "SDL_ReadLE16"); bindFunc(cast(void**)&SDL_ReadBE16, "SDL_ReadBE16"); bindFunc(cast(void**)&SDL_ReadLE32, "SDL_ReadLE32"); bindFunc(cast(void**)&SDL_ReadBE32, "SDL_ReadBE32"); bindFunc(cast(void**)&SDL_ReadLE64, "SDL_ReadLE64"); bindFunc(cast(void**)&SDL_ReadBE64, "SDL_ReadBE64"); bindFunc(cast(void**)&SDL_WriteU8, "SDL_WriteU8"); bindFunc(cast(void**)&SDL_WriteLE16, "SDL_WriteLE16"); bindFunc(cast(void**)&SDL_WriteBE16, "SDL_WriteBE16"); bindFunc(cast(void**)&SDL_WriteLE32, "SDL_WriteLE32"); bindFunc(cast(void**)&SDL_WriteBE32, "SDL_WriteBE32"); bindFunc(cast(void**)&SDL_WriteLE64, "SDL_WriteLE64"); bindFunc(cast(void**)&SDL_WriteBE64, "SDL_WriteBE64"); bindFunc(cast(void**)&SDL_CreateShapedWindow, "SDL_CreateShapedWindow"); bindFunc(cast(void**)&SDL_IsShapedWindow, "SDL_IsShapedWindow"); bindFunc(cast(void**)&SDL_SetWindowShape, "SDL_SetWindowShape"); bindFunc(cast(void**)&SDL_GetShapedWindowMode, "SDL_GetShapedWindowMode"); bindFunc(cast(void**)&SDL_CreateRGBSurface, "SDL_CreateRGBSurface"); bindFunc(cast(void**)&SDL_CreateRGBSurfaceWithFormat, "SDL_CreateRGBSurfaceWithFormat"); bindFunc(cast(void**)&SDL_CreateRGBSurfaceFrom, "SDL_CreateRGBSurfaceFrom"); bindFunc(cast(void**)&SDL_CreateRGBSurfaceWithFormatFrom, "SDL_CreateRGBSurfaceWithFormatFrom"); bindFunc(cast(void**)&SDL_FreeSurface, "SDL_FreeSurface"); bindFunc(cast(void**)&SDL_SetSurfacePalette, "SDL_SetSurfacePalette"); bindFunc(cast(void**)&SDL_LockSurface, "SDL_LockSurface"); bindFunc(cast(void**)&SDL_UnlockSurface, "SDL_UnlockSurface"); bindFunc(cast(void**)&SDL_LoadBMP_RW, "SDL_LoadBMP_RW"); bindFunc(cast(void**)&SDL_SaveBMP_RW, "SDL_SaveBMP_RW"); bindFunc(cast(void**)&SDL_SetSurfaceRLE, "SDL_SetSurfaceRLE"); bindFunc(cast(void**)&SDL_SetColorKey, "SDL_SetColorKey"); bindFunc(cast(void**)&SDL_GetColorKey, "SDL_GetColorKey"); bindFunc(cast(void**)&SDL_SetSurfaceColorMod, "SDL_SetSurfaceColorMod"); bindFunc(cast(void**)&SDL_GetSurfaceColorMod, "SDL_GetSurfaceColorMod"); bindFunc(cast(void**)&SDL_SetSurfaceAlphaMod, "SDL_SetSurfaceAlphaMod"); bindFunc(cast(void**)&SDL_GetSurfaceAlphaMod, "SDL_GetSurfaceAlphaMod"); bindFunc(cast(void**)&SDL_SetSurfaceBlendMode, "SDL_SetSurfaceBlendMode"); bindFunc(cast(void**)&SDL_GetSurfaceBlendMode, "SDL_GetSurfaceBlendMode"); bindFunc(cast(void**)&SDL_SetClipRect, "SDL_SetClipRect"); bindFunc(cast(void**)&SDL_GetClipRect, "SDL_GetClipRect"); bindFunc(cast(void**)&SDL_ConvertSurface, "SDL_ConvertSurface"); bindFunc(cast(void**)&SDL_ConvertSurfaceFormat, "SDL_ConvertSurfaceFormat"); bindFunc(cast(void**)&SDL_ConvertPixels, "SDL_ConvertPixels"); bindFunc(cast(void**)&SDL_FillRect, "SDL_FillRect"); bindFunc(cast(void**)&SDL_FillRects, "SDL_FillRects"); bindFunc(cast(void**)&SDL_UpperBlit, "SDL_UpperBlit"); bindFunc(cast(void**)&SDL_LowerBlit, "SDL_LowerBlit"); bindFunc(cast(void**)&SDL_SoftStretch, "SDL_SoftStretch"); bindFunc(cast(void**)&SDL_UpperBlitScaled, "SDL_UpperBlitScaled"); bindFunc(cast(void**)&SDL_LowerBlitScaled, "SDL_LowerBlitScaled"); static if(Derelict_OS_Windows) { bindFunc(cast(void**)&SDL_Direct3D9GetAdapterIndex, "SDL_Direct3D9GetAdapterIndex") ; bindFunc(cast(void**)&SDL_RenderGetD3D9Device, "SDL_RenderGetD3D9Device"); bindFunc(cast(void**)&SDL_DXGIGetOutputInfo, "SDL_DXGIGetOutputInfo"); } static if(Derelict_OS_iOS) { bindFunc(cast(void**)&SDL_iPhoneSetAnimationCallback, "SDL_iPhoneSetAnimationCallback"); bindFunc(cast(void**)&SDL_iPhoneSetEventPump, "SDL_iPhoneSetEventPump"); } static if(Derelict_OS_Android) { bindFunc(cast(void**)&SDL_AndroidGetJNIEnv, "SDL_AndroidGetJNIEnv"); bindFunc(cast(void**)&SDL_AndroidGetActivity, "SDL_AndroidGetActivity"); bindFunc(cast(void**)&SDL_AndroidGetInternalStoragePath, "SDL_AndroidGetInternalStoragePath"); bindFunc(cast(void**)&SDL_AndroidGetInternalStorageState, "SDL_AndroidGetInternalStorageState"); bindFunc(cast(void**)&SDL_AndroidGetExternalStoragePath, "SDL_AndroidGetExternalStoragePath"); } static if(Derelict_OS_WinRT) { bindFunc(cast(void**)&SDL_WinRTGetFSPathUNICODE, "SDL_WinRTGetFSPathUNICODE"); bindFunc(cast(void**)&SDL_WinRTGetFSPathUTF8, "SDL_WinRTGetFSPathUTF8"); bindFunc(cast(void**)&SDL_WinRTRunApp, "SDL_WinRTRunApp"); } bindFunc(cast(void**)&SDL_GetWindowWMInfo, "SDL_GetWindowWMInfo"); bindFunc(cast(void**)&SDL_GetTicks, "SDL_GetTicks"); bindFunc(cast(void**)&SDL_GetPerformanceCounter, "SDL_GetPerformanceCounter"); bindFunc(cast(void**)&SDL_GetPerformanceFrequency, "SDL_GetPerformanceFrequency"); bindFunc(cast(void**)&SDL_Delay, "SDL_Delay"); bindFunc(cast(void**)&SDL_AddTimer, "SDL_AddTimer"); bindFunc(cast(void**)&SDL_RemoveTimer, "SDL_RemoveTimer"); bindFunc(cast(void**)&SDL_GetNumTouchDevices, "SDL_GetNumTouchDevices"); bindFunc(cast(void**)&SDL_GetTouchDevice, "SDL_GetTouchDevice"); bindFunc(cast(void**)&SDL_GetNumTouchFingers, "SDL_GetNumTouchFingers"); bindFunc(cast(void**)&SDL_GetTouchFinger, "SDL_GetTouchFinger"); bindFunc(cast(void**)&SDL_GetVersion, "SDL_GetVersion"); bindFunc(cast(void**)&SDL_GetRevision, "SDL_GetRevision"); bindFunc(cast(void**)&SDL_GetRevisionNumber, "SDL_GetRevisionNumber"); bindFunc(cast(void**)&SDL_GetNumVideoDrivers, "SDL_GetNumVideoDrivers"); bindFunc(cast(void**)&SDL_GetVideoDriver, "SDL_GetVideoDriver"); bindFunc(cast(void**)&SDL_VideoInit, "SDL_VideoInit"); bindFunc(cast(void**)&SDL_VideoQuit, "SDL_VideoQuit"); bindFunc(cast(void**)&SDL_GetCurrentVideoDriver, "SDL_GetCurrentVideoDriver"); bindFunc(cast(void**)&SDL_GetNumVideoDisplays, "SDL_GetNumVideoDisplays"); bindFunc(cast(void**)&SDL_GetDisplayName, "SDL_GetDisplayName"); bindFunc(cast(void**)&SDL_GetDisplayBounds, "SDL_GetDisplayBounds"); bindFunc(cast(void**)&SDL_GetDisplayDPI, "SDL_GetDisplayDPI"); bindFunc(cast(void**)&SDL_GetDisplayUsableBounds, "SDL_GetDisplayUsableBounds"); bindFunc(cast(void**)&SDL_GetNumDisplayModes, "SDL_GetNumDisplayModes"); bindFunc(cast(void**)&SDL_GetDisplayMode, "SDL_GetDisplayMode"); bindFunc(cast(void**)&SDL_GetDesktopDisplayMode, "SDL_GetDesktopDisplayMode"); bindFunc(cast(void**)&SDL_GetCurrentDisplayMode, "SDL_GetCurrentDisplayMode"); bindFunc(cast(void**)&SDL_GetClosestDisplayMode, "SDL_GetClosestDisplayMode"); bindFunc(cast(void**)&SDL_GetWindowDisplayIndex, "SDL_GetWindowDisplayIndex"); bindFunc(cast(void**)&SDL_SetWindowDisplayMode, "SDL_SetWindowDisplayMode"); bindFunc(cast(void**)&SDL_GetWindowDisplayMode, "SDL_GetWindowDisplayMode"); bindFunc(cast(void**)&SDL_GetWindowPixelFormat, "SDL_GetWindowPixelFormat"); bindFunc(cast(void**)&SDL_CreateWindow, "SDL_CreateWindow"); bindFunc(cast(void**)&SDL_CreateWindowFrom, "SDL_CreateWindowFrom"); bindFunc(cast(void**)&SDL_GetWindowID, "SDL_GetWindowID"); bindFunc(cast(void**)&SDL_GetWindowFromID, "SDL_GetWindowFromID"); bindFunc(cast(void**)&SDL_GetWindowFlags, "SDL_GetWindowFlags"); bindFunc(cast(void**)&SDL_SetWindowTitle, "SDL_SetWindowTitle"); bindFunc(cast(void**)&SDL_GetWindowTitle, "SDL_GetWindowTitle"); bindFunc(cast(void**)&SDL_SetWindowIcon, "SDL_SetWindowIcon"); bindFunc(cast(void**)&SDL_SetWindowData, "SDL_SetWindowData"); bindFunc(cast(void**)&SDL_GetWindowData, "SDL_GetWindowData"); bindFunc(cast(void**)&SDL_SetWindowPosition, "SDL_SetWindowPosition"); bindFunc(cast(void**)&SDL_GetWindowPosition, "SDL_GetWindowPosition"); bindFunc(cast(void**)&SDL_SetWindowSize, "SDL_SetWindowSize"); bindFunc(cast(void**)&SDL_GetWindowSize, "SDL_GetWindowSize"); bindFunc(cast(void**)&SDL_GetWindowBordersSize, "SDL_GetWindowBordersSize"); bindFunc(cast(void**)&SDL_SetWindowMinimumSize, "SDL_SetWindowMinimumSize"); bindFunc(cast(void**)&SDL_GetWindowMinimumSize, "SDL_GetWindowMinimumSize"); bindFunc(cast(void**)&SDL_SetWindowMaximumSize, "SDL_SetWindowMaximumSize"); bindFunc(cast(void**)&SDL_GetWindowMaximumSize, "SDL_GetWindowMaximumSize"); bindFunc(cast(void**)&SDL_SetWindowBordered, "SDL_SetWindowBordered"); bindFunc(cast(void**)&SDL_SetWindowResizable, "SDL_SetWindowResizable"); bindFunc(cast(void**)&SDL_ShowWindow, "SDL_ShowWindow"); bindFunc(cast(void**)&SDL_HideWindow, "SDL_HideWindow"); bindFunc(cast(void**)&SDL_RaiseWindow, "SDL_RaiseWindow"); bindFunc(cast(void**)&SDL_MaximizeWindow, "SDL_MaximizeWindow"); bindFunc(cast(void**)&SDL_MinimizeWindow, "SDL_MinimizeWindow"); bindFunc(cast(void**)&SDL_RestoreWindow, "SDL_RestoreWindow"); bindFunc(cast(void**)&SDL_SetWindowFullscreen, "SDL_SetWindowFullscreen"); bindFunc(cast(void**)&SDL_GetWindowSurface, "SDL_GetWindowSurface"); bindFunc(cast(void**)&SDL_UpdateWindowSurface, "SDL_UpdateWindowSurface"); bindFunc(cast(void**)&SDL_UpdateWindowSurfaceRects, "SDL_UpdateWindowSurfaceRects"); bindFunc(cast(void**)&SDL_SetWindowGrab, "SDL_SetWindowGrab"); bindFunc(cast(void**)&SDL_GetWindowGrab, "SDL_GetWindowGrab"); bindFunc(cast(void**)&SDL_GetGrabbedWindow, "SDL_GetGrabbedWindow"); bindFunc(cast(void**)&SDL_SetWindowBrightness, "SDL_SetWindowBrightness"); bindFunc(cast(void**)&SDL_GetWindowBrightness, "SDL_GetWindowBrightness"); bindFunc(cast(void**)&SDL_SetWindowOpacity, "SDL_SetWindowOpacity"); bindFunc(cast(void**)&SDL_GetWindowOpacity, "SDL_GetWindowOpacity"); bindFunc(cast(void**)&SDL_SetWindowModalFor, "SDL_SetWindowModalFor"); bindFunc(cast(void**)&SDL_SetWindowInputFocus, "SDL_SetWindowInputFocus"); bindFunc(cast(void**)&SDL_SetWindowGammaRamp, "SDL_SetWindowGammaRamp"); bindFunc(cast(void**)&SDL_GetWindowGammaRamp, "SDL_GetWindowGammaRamp"); bindFunc(cast(void**)&SDL_SetWindowHitTest, "SDL_SetWindowHitTest"); bindFunc(cast(void**)&SDL_DestroyWindow, "SDL_DestroyWindow"); bindFunc(cast(void**)&SDL_IsScreenSaverEnabled, "SDL_IsScreenSaverEnabled"); bindFunc(cast(void**)&SDL_EnableScreenSaver, "SDL_EnableScreenSaver"); bindFunc(cast(void**)&SDL_DisableScreenSaver, "SDL_DisableScreenSaver"); bindFunc(cast(void**)&SDL_GL_LoadLibrary, "SDL_GL_LoadLibrary"); bindFunc(cast(void**)&SDL_GL_GetProcAddress, "SDL_GL_GetProcAddress"); bindFunc(cast(void**)&SDL_GL_UnloadLibrary, "SDL_GL_UnloadLibrary"); bindFunc(cast(void**)&SDL_GL_ExtensionSupported, "SDL_GL_ExtensionSupported"); bindFunc(cast(void**)&SDL_GL_ResetAttributes, "SDL_GL_ResetAttributes"); bindFunc(cast(void**)&SDL_GL_SetAttribute, "SDL_GL_SetAttribute"); bindFunc(cast(void**)&SDL_GL_GetAttribute, "SDL_GL_GetAttribute"); bindFunc(cast(void**)&SDL_GL_CreateContext, "SDL_GL_CreateContext"); bindFunc(cast(void**)&SDL_GL_MakeCurrent, "SDL_GL_MakeCurrent"); bindFunc(cast(void**)&SDL_GL_GetCurrentWindow, "SDL_GL_GetCurrentWindow"); bindFunc(cast(void**)&SDL_GL_GetCurrentContext, "SDL_GL_GetCurrentContext"); bindFunc(cast(void**)&SDL_GL_SetSwapInterval, "SDL_GL_SetSwapInterval"); bindFunc(cast(void**)&SDL_GL_GetSwapInterval, "SDL_GL_GetSwapInterval"); bindFunc(cast(void**)&SDL_GL_SwapWindow, "SDL_GL_SwapWindow"); bindFunc(cast(void**)&SDL_GL_DeleteContext, "SDL_GL_DeleteContext"); bindFunc(cast(void**)&SDL_GL_GetDrawableSize, "SDL_GL_GetDrawableSize"); // SDL_init will fail if SDL_SetMainReady has not been called. // Since there's no SDL_main on the D side, it needs to be handled // manually. My understanding that this is fine on the platforms // that D is currently available on. If we ever get on to Android // or iPhone, though, this will need to be versioned. // I've wrapped it in a try/catch because it seem the function is // not always exported on Linux. See issue #153 // https://github.com/aldacron/Derelict3/issues/153 try { da_SDL_SetMainReady setReady; bindFunc(cast(void**)&setReady, "SDL_SetMainReady"); setReady(); } catch( DerelictException de ) {} } private: ShouldThrow allowSDL_2_0_0(string symbolName) { switch(symbolName) { // Functions added in 2.0.1 case "SDL_free": break; case "SDL_SetAssertionHandler": break; case "SDL_GetAssertionReport": break; case "SDL_ResetAssertionReport": break; case "SDL_GetSystemRAM": break; case "SDL_UpdateYUVTexture": break; case "SDL_GL_GetDrawableSize": break; case "SDL_GetBasePath": break; case "SDL_GetPrefPath": break; default: return allowSDL_2_0_1(symbolName); } return ShouldThrow.No; } ShouldThrow allowSDL_2_0_1(string symbolName) { switch(symbolName) { // Functions added in 2.0.2 case "SDL_HasAVX": break; case "SDL_GameControllerAddMappingsFromRW": break; case "SDL_GetDefaultAssertionHandler": break; case "SDL_GetAssertionHandler": break; case "SDL_GL_ResetAttributes": break; static if(Derelict_OS_Windows) { case "SDL_Direct3D9GetAdapterIndex": break; case "SDL_RenderGetD3D9Device": break; case "SDL_DXGIGetOutputInfo": break; } else static if(Derelict_OS_iOS) { case "SDL_iPhoneSetAnimationCallback": break; case "SDL_iPhoneSetEventPump": break; } else static if(Derelict_OS_Android) { case "SDL_AndroidGetJNIEnv": break; case "SDL_AndroidGetActivity": break; case "SDL_AndroidGetInternalStoragePath": break; case "SDL_AndroidGetInternalStorageState": break; case "SDL_AndroidGetExternalStoragePath": break; } default: return allowSDL_2_0_2(symbolName); } return ShouldThrow.No; } ShouldThrow allowSDL_2_0_2(string symbolName) { static if(Derelict_OS_WinRT) { switch(symbolName) { // Functions added in 2.0.3 static if(Derelict_OS_WinRT) { case "SDL_WinRTGetFSPathUNICODE": break; case "SDL_WinRTGetFSPathUTF8": break; case "SDL_WinRTRunApp": break; } default: return allowSDL_2_0_3(symbolName); } } return ShouldThrow.No; } ShouldThrow allowSDL_2_0_3(string symbolName) { switch(symbolName) { // Functions added in 2.0.4 case "SDL_CaptureMouse": break; case "SDL_ClearQueuedAudio": break; case "SDL_GameControllerFromInstanceID": break; case "SDL_GetDisplayDPI": break; case "SDL_GetGlobalMouseState": break; case "SDL_GetGrabbedWindow": break; case "SDL_GetQueuedAudioSize": break; case "SDL_HasAVX2": break; case "SDL_JoystickCurrentPowerLevel": break; case "SDL_JoystickFromInstanceID": break; case "SDL_QueueAudio": break; case "SDL_RenderIsClipEnabled": break; case "SDL_SetWindowHitTest": break; case "SDL_WarpMouseGlobal": break; default: return allowSDL_2_0_4(symbolName); } return ShouldThrow.No; } ShouldThrow allowSDL_2_0_4(string symbolName) { switch(symbolName) { // Functions added in 2.0.5 case "SDL_DequeueAudio": break; case "SDL_GetHintBoolean": break; case "SDL_RenderSetIntegerScale": break; case "SDL_RenderGetIntegerScale": break; case "SDL_CreateRGBSurfaceWithFormat": break; case "SDL_CreateRGBSurfaceWithFormatFrom": break; case "SDL_GetDisplayUsableBounds": break; case "SDL_GetWindowBordersSize": break; case "SDL_SetWindowResizable": break; case "SDL_SetWindowOpacity": break; case "SDL_GetWindowOpacity": break; case "SDL_SetWindowModalFor": break; case "SDL_SetWindowInputFocus": break; default: return ShouldThrow.Yes; } return ShouldThrow.No; } } __gshared DerelictSDL2Loader DerelictSDL2; shared static this() { DerelictSDL2 = new DerelictSDL2Loader(); } private: static if(Derelict_OS_Windows) enum libNames = "SDL2.dll"; else static if(Derelict_OS_Mac) enum libNames = "libSDL2.dylib, /usr/local/lib/libSDL2.dylib, /usr/local/lib/libSDL2/libSDL2.dylib, ../Frameworks/SDL2.framework/SDL2, /Library/Frameworks/SDL2.framework/SDL2, /System/Library/Frameworks/SDL2.framework/SDL2, /opt/local/lib/libSDL2.dylib"; else static if(Derelict_OS_Posix) enum libNames = "libSDL2.so, libSDL2-2.0.so, libSDL2-2.0.so.0, /usr/local/lib/libSDL2.so, /usr/local/lib/libSDL2-2.0.so, /usr/local/lib/libSDL2-2.0.so.0"; else static assert(0, "Need to implement SDL2 libNames for this operating system."); CheeseCutter-2.10/src/derelict/sdl2/internal/sdl_static.d000066400000000000000000000626041516216315000233670ustar00rootroot00000000000000/* Boost Software License - Version 1.0 - August 17th,2003 Permission is hereby granted,free of charge,to any person or organization obtaining a copy of the software and accompanying documentation covered by this license (the "Software") to use,reproduce,display,distribute, execute,and transmit the Software,and to prepare derivative works of the Software,and to permit third-parties to whom the Software is furnished to do so,all subject to the following: The copyright notices in the Software and this entire statement,including the above license grant,this restriction and the following disclaimer, must be included in all copies of the Software,in whole or in part,and all derivative works of the Software,unless such copies or derivative works are solely in the form of machine-executable object code generated by a source language processor. THE SOFTWARE IS PROVIDED "AS IS",WITHOUT WARRANTY OF ANY KIND,EXPRESS OR IMPLIED,INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE,TITLE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE FOR ANY DAMAGES OR OTHER LIABILITY,WHETHER IN CONTRACT,TORT OR OTHERWISE, ARISING FROM,OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ module derelict.sdl2.internal.sdl_static; import core.stdc.stdarg, core.stdc.stdio; import derelict.util.system; import derelict.sdl2.internal.sdl_types; extern(C) @nogc nothrow { int SDL_Init(Uint32); int SDL_InitSubSystem(Uint32); void SDL_QuitSubSystem(Uint32); Uint32 SDL_WasInit(Uint32); void SDL_Quit(); void SDL_free(void* mem); void SDL_SetAssertionHandler(SDL_AssertionHandler,void*); SDL_AssertionHandler SDL_GetDefaultAssertionHandler(); SDL_AssertionHandler SDL_GetAssertionHandler(void**); const(SDL_assert_data)* SDL_GetAssertionReport(); void SDL_ResetAssertionReport(); int SDL_GetNumAudioDrivers(); const(char)* SDL_GetAudioDriver(int); int SDL_AudioInit(const(char)*); void SDL_AudioQuit(); const(char)* SDL_GetCurrentAudioDriver(); int SDL_OpenAudio(SDL_AudioSpec*,SDL_AudioSpec*); int SDL_GetNumAudioDevices(int); const(char)* SDL_GetAudioDeviceName(int,int); SDL_AudioDeviceID SDL_OpenAudioDevice(const(char)*,int,const(SDL_AudioSpec)*,SDL_AudioSpec*,int); SDL_AudioStatus SDL_GetAudioStatus(); SDL_AudioStatus SDL_GetAudioDeviceStatus(SDL_AudioDeviceID); void SDL_PauseAudio(int); void SDL_PauseAudioDevice(SDL_AudioDeviceID,int); SDL_AudioSpec* SDL_LoadWAV_RW(SDL_RWops*,int,SDL_AudioSpec*,Uint8**,Uint32*); void SDL_FreeWAV(Uint8*); int SDL_BuildAudioCVT(SDL_AudioCVT*,SDL_AudioFormat,Uint8,int,SDL_AudioFormat,Uint8,int); int SDL_ConvertAudio(SDL_AudioCVT*); void SDL_MixAudio(Uint8*,const(Uint8)*,Uint32,int); void SDL_MixAudioFormat(Uint8*,const(Uint8)*,SDL_AudioFormat,Uint32,int); int SDL_QueueAudio(SDL_AudioDeviceID,const(void)*,Uint32); Uint32 SDL_DequeueAudio(SDL_AudioDeviceID,void*,Uint32); int SDL_GetQueuedAudioSize(SDL_AudioDeviceID); int SDL_ClearQueuedAudio(SDL_AudioDeviceID); void SDL_LockAudio(); void SDL_LockAudioDevice(SDL_AudioDeviceID); void SDL_UnlockAudio(); void SDL_UnlockAudioDevice(SDL_AudioDeviceID); void SDL_CloseAudio(); void SDL_CloseAudioDevice(SDL_AudioDeviceID); int SDL_AudioDeviceConnected(SDL_AudioDeviceID); int SDL_SetClipboardText(const(char)*); char* SDL_GetClipboardText(); SDL_bool SDL_HasClipboardText(); int SDL_GetCPUCount(); int SDL_GetCPUCacheLineSize(); SDL_bool SDL_HasRDTSC(); SDL_bool SDL_HasAltiVec(); SDL_bool SDL_HasMMX(); SDL_bool SDL_Has3DNow(); SDL_bool SDL_HasSSE(); SDL_bool SDL_HasSSE2(); SDL_bool SDL_HasSSE3(); SDL_bool SDL_HasSSE41(); SDL_bool SDL_HasSSE42(); SDL_bool SDL_HasAVX(); SDL_bool SDL_HasAVX2(); int SDL_GetSystemRAM(); void SDL_SetError(const(char)*,...); const(char)* SDL_GetError(); void SDL_ClearError(); void SDL_PumpEvents(); int SDL_PeepEvents(SDL_Event*,int,SDL_eventaction,Uint32,Uint32); SDL_bool SDL_HasEvent(Uint32); SDL_bool SDL_HasEvents(Uint32,Uint32); void SDL_FlushEvent(Uint32); void SDL_FlushEvents(Uint32,Uint32); int SDL_PollEvent(SDL_Event*); int SDL_WaitEvent(SDL_Event*); int SDL_WaitEventTimeout(SDL_Event*,int); int SDL_PushEvent(SDL_Event*); void SDL_SetEventFilter(SDL_EventFilter,void*); SDL_bool SDL_GetEventFilter(SDL_EventFilter*,void**); void SDL_AddEventWatch(SDL_EventFilter,void*); void SDL_DelEventWatch(SDL_EventFilter,void*); void SDL_FilterEvents(SDL_EventFilter,void*); Uint8 SDL_EventState(Uint32,int); Uint32 SDL_RegisterEvents(int); char* SDL_GetBasePath(); char* SDL_GetPrefPath(const(char)* org,const(char)* app); int SDL_GameControllerAddMappingsFromRW(SDL_RWops*,int); int SDL_GameControllerAddMapping(const(char)*); char* SDL_GameControllerMappingForGUID(SDL_JoystickGUID); char* SDL_GameControllerMapping(SDL_GameController*); SDL_bool SDL_IsGameController(int); const(char)* SDL_GameControllerNameForIndex(int); SDL_GameController* SDL_GameControllerOpen(int); SDL_GameController* SDL_GameControllerFromInstanceID(SDL_JoystickID); const(char)* SDL_GameControllerName(SDL_GameController*); SDL_bool SDL_GameControllerGetAttached(SDL_GameController*); SDL_Joystick* SDL_GameControllerGetJoystick(SDL_GameController*); int SDL_GameControllerEventState(int); void SDL_GameControllerUpdate(); SDL_GameControllerAxis SDL_GameControllerGetAxisFromString(const(char)*); const(char)* SDL_GameControllerGetStringForAxis(SDL_GameControllerAxis); SDL_GameControllerButtonBind SDL_GameControllerGetBindForAxis(SDL_GameController*,SDL_GameControllerAxis); Sint16 SDL_GameControllerGetAxis(SDL_GameController*,SDL_GameControllerAxis); SDL_GameControllerButton SDL_GameControllerGetButtonFromString(const(char*)); const(char)* SDL_GameControllerGetStringForButton(SDL_GameControllerButton); SDL_GameControllerButtonBind SDL_GameControllerGetBindForButton(SDL_GameController*,SDL_GameControllerButton); Uint8 SDL_GameControllerGetButton(SDL_GameController*,SDL_GameControllerButton); void SDL_GameControllerClose(SDL_GameController*); int SDL_RecordGesture(SDL_TouchID); int SDL_SaveAllDollarTemplates(SDL_RWops*); int SDL_SaveDollarTemplate(SDL_GestureID,SDL_RWops*); int SDL_LoadDollarTemplates(SDL_TouchID,SDL_RWops*); int SDL_NumHaptics(); const(char)* SDL_HapticName(int); SDL_Haptic* SDL_HapticOpen(int); int SDL_HapticOpened(int); int SDL_HapticIndex(SDL_Haptic*); int SDL_MouseIsHaptic(); SDL_Haptic* SDL_HapticOpenFromMouse(); int SDL_JoystickIsHaptic(SDL_Joystick*); SDL_Haptic* SDL_HapticOpenFromJoystick(SDL_Joystick*); int SDL_HapticClose(SDL_Haptic*); int SDL_HapticNumEffects(SDL_Haptic*); int SDL_HapticNumEffectsPlaying(SDL_Haptic*); uint SDL_HapticQuery(SDL_Haptic*); int SDL_HapticNumAxes(SDL_Haptic*); int SDL_HapticEffectSupported(SDL_Haptic*,SDL_HapticEffect*); int SDL_HapticNewEffect(SDL_Haptic*,SDL_HapticEffect*); int SDL_HapticUpdateEffect(SDL_Haptic*,int,SDL_HapticEffect*); int SDL_HapticRunEffect(SDL_Haptic*,int,Uint32); int SDL_HapticStopEffect(SDL_Haptic*,int); int SDL_HapticDestroyEffect(SDL_Haptic*,int); int SDL_HapticGetEffectStatus(SDL_Haptic*,int); int SDL_HapticSetGain(SDL_Haptic*,int); int SDL_HapticSetAutocenter(SDL_Haptic*,int); int SDL_HapticPause(SDL_Haptic*); int SDL_HapticUnpause(SDL_Haptic*); int SDL_HapticStopAll(SDL_Haptic*); int SDL_HapticRumbleSupported(SDL_Haptic*); int SDL_HapticRumbleInit(SDL_Haptic*); int SDL_HapticRumblePlay(SDL_Haptic*,float,Uint32); int SDL_HapticRumbleStop(SDL_Haptic*); SDL_bool SDL_SetHintWithPriority(const(char)*,const(char)*,SDL_HintPriority); SDL_bool SDL_SetHint(const(char)*,const(char)*); const(char)* SDL_GetHint(const(char)*); SDL_bool SDL_GetHintBoolean(const(char)*,SDL_bool); void SDL_AddHintCallback(const(char)*,SDL_HintCallback,void*); void SDL_DelHintCallback(const(char)*,SDL_HintCallback,void*); void SDL_ClearHints(); int SDL_NumJoysticks(); const(char)* SDL_JoystickNameForIndex(int); SDL_Joystick* SDL_JoystickOpen(int); SDL_Joystick* SDL_JoystickFromInstanceID(SDL_JoystickID); const(char)* SDL_JoystickName(SDL_Joystick*); SDL_JoystickGUID SDL_JoystickGetDeviceGUID(int); SDL_JoystickGUID SDL_JoystickGetGUID(SDL_Joystick*); char* SDL_JoystickGetGUIDString(SDL_JoystickGUID); SDL_JoystickGUID SDL_JoystickGetGUIDFromString(const(char)*); SDL_bool SDL_JoystickGetAttached(SDL_Joystick*); SDL_JoystickID SDL_JoystickInstanceID(SDL_Joystick*); int SDL_JoystickNumAxes(SDL_Joystick*); int SDL_JoystickNumBalls(SDL_Joystick*); int SDL_JoystickNumHats(SDL_Joystick*); int SDL_JoystickNumButtons(SDL_Joystick*); void SDL_JoystickUpdate(); int SDL_JoystickEventState(int); Sint16 SDL_JoystickGetAxis(SDL_Joystick*,int); Uint8 SDL_JoystickGetHat(SDL_Joystick*,int); int SDL_JoystickGetBall(SDL_Joystick*,int,int*,int*); Uint8 SDL_JoystickGetButton(SDL_Joystick*,int); void SDL_JoystickClose(SDL_Joystick*); SDL_JoystickPowerLevel SDL_JoystickCurrentPowerLevel(SDL_Joystick*); SDL_Window* SDL_GetKeyboardFocus(); Uint8* SDL_GetKeyboardState(int*); SDL_Keymod SDL_GetModState(); void SDL_SetModState(SDL_Keymod); SDL_Keycode SDL_GetKeyFromScancode(SDL_Scancode); SDL_Scancode SDL_GetScancodeFromKey(SDL_Keycode); const(char)* SDL_GetScancodeName(SDL_Scancode); SDL_Scancode SDL_GetScancodeFromName(const(char)*); const(char)* SDL_GetKeyName(SDL_Keycode); SDL_Keycode SDL_GetKeyFromName(const(char)*); void SDL_StartTextInput(); SDL_bool SDL_IsTextInputActive(); void SDL_StopTextInput(); void SDL_SetTextInputRect(SDL_Rect*); SDL_bool SDL_HasScreenKeyboardSupport(); SDL_bool SDL_IsScreenKeyboardShown(SDL_Window*); void* SDL_LoadObject(const(char)*); void* SDL_LoadFunction(void*,const(char*)); void SDL_UnloadObject(void*); void SDL_LogSetAllPriority(SDL_LogPriority); void SDL_LogSetPriority(int,SDL_LogPriority); SDL_LogPriority SDL_LogGetPriority(int); void SDL_LogResetPriorities(); void SDL_Log(const(char)*,...); void SDL_LogVerbose(int,const(char)*,...); void SDL_LogDebug(int,const(char)*,...); void SDL_LogInfo(int,const(char)*,...); void SDL_LogWarn(int,const(char)*,...); void SDL_LogError(int,const(char)*,...); void SDL_LogCritical(int,const(char)*,...); void SDL_LogMessage(int,SDL_LogPriority,const(char)*,...); void SDL_LogMessageV(int,SDL_LogPriority,const(char)*,va_list); void SDL_LogGetOutputFunction(SDL_LogOutputFunction,void**); void SDL_LogSetOutputFunction(SDL_LogOutputFunction,void*); int SDL_ShowMessageBox(const(SDL_MessageBoxData)*,int*); int SDL_ShowSimpleMessageBox(Uint32,const(char)*,const(char)*,SDL_Window*); SDL_Window* SDL_GetMouseFocus(); Uint32 SDL_GetMouseState(int*,int*); Uint32 SDL_GetGlobalMouseState(int*,int*); Uint32 SDL_GetRelativeMouseState(int*,int*); void SDL_WarpMouseInWindow(SDL_Window*,int,int); void SDL_WarpMouseGlobal(int,int); int SDL_SetRelativeMouseMode(SDL_bool); int SDL_CaptureMouse(SDL_bool); SDL_bool SDL_GetRelativeMouseMode(); SDL_Cursor* SDL_CreateCursor(const(Uint8)*,const(Uint8)*,int,int,int,int); SDL_Cursor* SDL_CreateColorCursor(SDL_Surface*,int,int); SDL_Cursor* SDL_CreateSystemCursor(SDL_SystemCursor); void SDL_SetCursor(SDL_Cursor*); SDL_Cursor* SDL_GetCursor(); SDL_Cursor* SDL_GetDefaultCursor(); void SDL_FreeCursor(SDL_Cursor*); int SDL_ShowCursor(int); const(char)* SDL_GetPixelFormatName(Uint32); SDL_bool SDL_PixelFormatEnumToMasks(Uint32,int*,Uint32*,Uint32*,Uint32*,Uint32*); Uint32 SDL_MasksToPixelFormatEnum(int,Uint32,Uint32,Uint32,Uint32); SDL_PixelFormat* SDL_AllocFormat(Uint32); void SDL_FreeFormat(SDL_PixelFormat*); SDL_Palette* SDL_AllocPalette(int); int SDL_SetPixelFormatPalette(SDL_PixelFormat*,SDL_Palette*); int SDL_SetPaletteColors(SDL_Palette*,const(SDL_Color)*,int,int); void SDL_FreePalette(SDL_Palette*); Uint32 SDL_MapRGB(const(SDL_PixelFormat)*,Uint8,Uint8,Uint8); Uint32 SDL_MapRGBA(const(SDL_PixelFormat)*,Uint8,Uint8,Uint8,Uint8); void SDL_GetRGB(Uint32,const(SDL_PixelFormat)*,Uint8*,Uint8*,Uint8*); void SDL_GetRGBA(Uint32,const(SDL_PixelFormat)*,Uint8*,Uint8*,Uint8*,Uint8*); void SDL_CalculateGammaRamp(float,Uint16*); const(char)* SDL_GetPlatform(); SDL_PowerState SDL_GetPowerInfo(int*,int*); SDL_bool SDL_HasIntersection(const(SDL_Rect)*,const(SDL_Rect)*); SDL_bool SDL_IntersectRect(const(SDL_Rect)*,const(SDL_Rect)*,SDL_Rect*); void SDL_UnionRect(const(SDL_Rect)*,const(SDL_Rect)*,SDL_Rect*); SDL_bool SDL_EnclosePoints(const(SDL_Point)*,int,const(SDL_Rect)*,SDL_Rect*); SDL_bool SDL_IntersectRectAndLine(const(SDL_Rect)*,int*,int*,int*,int*); int SDL_GetNumRenderDrivers(); int SDL_GetRenderDriverInfo(int,SDL_RendererInfo*); int SDL_CreateWindowAndRenderer(int,int,Uint32,SDL_Window**,SDL_Renderer**); SDL_Renderer* SDL_CreateRenderer(SDL_Window*,int,SDL_RendererFlags); SDL_Renderer* SDL_CreateSoftwareRenderer(SDL_Surface*); SDL_Renderer* SDL_GetRenderer(SDL_Window*); int SDL_GetRendererInfo(SDL_Renderer*,SDL_RendererInfo*); int SDL_GetRendererOutputSize(SDL_Renderer*,int*,int*); SDL_Texture* SDL_CreateTexture(SDL_Renderer*,Uint32,SDL_TextureAccess,int,int); SDL_Texture* SDL_CreateTextureFromSurface(SDL_Renderer*,SDL_Surface*); int SDL_QueryTexture(SDL_Texture*,Uint32*,int*,int*,int*); int SDL_SetTextureColorMod(SDL_Texture*,Uint8,Uint8,Uint8); int SDL_GetTextureColorMod(SDL_Texture*,Uint8*,Uint8*,Uint8*); int SDL_SetTextureAlphaMod(SDL_Texture*,Uint8); int SDL_GetTextureAlphaMod(SDL_Texture*,Uint8*); int SDL_SetTextureBlendMode(SDL_Texture*,SDL_BlendMode); int SDL_GetTextureBlendMode(SDL_Texture*,SDL_BlendMode*); int SDL_UpdateTexture(SDL_Texture*,const(SDL_Rect)*,const(void)*,int); int SDL_UpdateYUVTexture(SDL_Texture*,const(SDL_Rect)*,const(Uint8)*,int,const(Uint8)*,int,const(Uint8)*,int); int SDL_LockTexture(SDL_Texture*,const(SDL_Rect)*,void**,int*); void SDL_UnlockTexture(SDL_Texture*); SDL_bool SDL_RenderTargetSupported(SDL_Renderer*); int SDL_SetRenderTarget(SDL_Renderer*,SDL_Texture*); SDL_Texture* SDL_GetRenderTarget(SDL_Renderer*); int SDL_RenderSetClipRect(SDL_Renderer*,const(SDL_Rect)*); void SDL_RenderGetClipRect(SDL_Renderer* renderer,SDL_Rect*); int SDL_RenderSetLogicalSize(SDL_Renderer*,int,int); void SDL_RenderGetLogicalSize(SDL_Renderer*,int*,int*); int SDL_RenderSetIntegerScale(SDL_Renderer*,SDL_bool); SDL_bool SDL_RenderGetIntegerScale(SDL_Renderer*); int SDL_RenderSetViewport(SDL_Renderer*,const(SDL_Rect)*); void SDL_RenderGetViewport(SDL_Renderer*,SDL_Rect*); SDL_bool SDL_RenderIsClipEnabled(SDL_Renderer*); int SDL_RenderSetScale(SDL_Renderer*,float,float); int SDL_RenderGetScale(SDL_Renderer*,float*,float*); int SDL_SetRenderDrawColor(SDL_Renderer*,Uint8,Uint8,Uint8,Uint8); int SDL_GetRenderDrawColor(SDL_Renderer*,Uint8*,Uint8*,Uint8*,Uint8*); int SDL_SetRenderDrawBlendMode(SDL_Renderer*,SDL_BlendMode); int SDL_GetRenderDrawBlendMode(SDL_Renderer*,SDL_BlendMode*); int SDL_RenderClear(SDL_Renderer*); int SDL_RenderDrawPoint(SDL_Renderer*,int,int); int SDL_RenderDrawPoints(SDL_Renderer*,const(SDL_Point)*,int); int SDL_RenderDrawLine(SDL_Renderer*,int,int,int,int); int SDL_RenderDrawLines(SDL_Renderer*,const(SDL_Point)*,int); int SDL_RenderDrawRect(SDL_Renderer*,const(SDL_Rect)*); int SDL_RenderDrawRects(SDL_Renderer*,const(SDL_Rect)*,int); int SDL_RenderFillRect(SDL_Renderer*,const(SDL_Rect)*); int SDL_RenderFillRects(SDL_Renderer*,const(SDL_Rect)*,int); int SDL_RenderCopy(SDL_Renderer*,SDL_Texture*,const(SDL_Rect)*,const(SDL_Rect*)); int SDL_RenderCopyEx(SDL_Renderer*,SDL_Texture*,const(SDL_Rect)*,const(SDL_Rect)*,const(double),const(SDL_Point)*,const(SDL_RendererFlip)); int SDL_RenderReadPixels(SDL_Renderer*,const(SDL_Rect)*,Uint32,void*,int); void SDL_RenderPresent(SDL_Renderer*); void SDL_DestroyTexture(SDL_Texture*); void SDL_DestroyRenderer(SDL_Renderer*); int SDL_GL_BindTexture(SDL_Texture*,float*,float*); int SDL_GL_UnbindTexture(SDL_Texture*); SDL_RWops* SDL_RWFromFile(const(char)*,const(char)*); SDL_RWops* SDL_RWFromFP(FILE*,SDL_bool); SDL_RWops* SDL_RWFromMem(void*,int); SDL_RWops* SDL_RWFromConstMem(const(void)*,int); SDL_RWops* SDL_AllocRW(); void SDL_FreeRW(SDL_RWops*); Uint8 SDL_ReadU8(SDL_RWops*); Uint16 SDL_ReadLE16(SDL_RWops*); Uint16 SDL_ReadBE16(SDL_RWops*); Uint32 SDL_ReadLE32(SDL_RWops*); Uint32 SDL_ReadBE32(SDL_RWops*); Uint64 SDL_ReadLE64(SDL_RWops*); Uint64 SDL_ReadBE64(SDL_RWops*); size_t SDL_WriteU8(SDL_RWops*,Uint8); size_t SDL_WriteLE16(SDL_RWops*,Uint16); size_t SDL_WriteBE16(SDL_RWops*,Uint16); size_t SDL_WriteLE32(SDL_RWops*,Uint32); size_t SDL_WriteBE32(SDL_RWops*,Uint32); size_t SDL_WriteLE64(SDL_RWops*,Uint64); size_t SDL_WriteBE64(SDL_RWops*,Uint64); SDL_Window* SDL_CreateShapedWindow(const(char)*,uint,uint,uint,uint,Uint32); SDL_bool SDL_IsShapedWindow(const(SDL_Window)*); int SDL_SetWindowShape(SDL_Window*,SDL_Surface*,SDL_WindowShapeMode*); int SDL_GetShapedWindowMode(SDL_Window*,SDL_WindowShapeMode*); SDL_Surface* SDL_CreateRGBSurface(Uint32,int,int,int,Uint32,Uint32,Uint32,Uint32); SDL_Surface* SDL_CreateRGBSurfaceWithFormat(Uint32,int,int,int,Uint32); SDL_Surface* SDL_CreateRGBSurfaceFrom(void*,int,int,int,int,Uint32,Uint32,Uint32,Uint32); SDL_Surface* SDL_CreateRGBSurfaceWithFormatFrom(void*,int,int,int,int,Uint32); void SDL_FreeSurface(SDL_Surface*); int SDL_SetSurfacePalette(SDL_Surface*,SDL_Palette*); int SDL_LockSurface(SDL_Surface*); int SDL_UnlockSurface(SDL_Surface*); SDL_Surface* SDL_LoadBMP_RW(SDL_RWops*,int); int SDL_SaveBMP_RW(SDL_Surface*,SDL_RWops*,int); int SDL_SetSurfaceRLE(SDL_Surface*,int); int SDL_SetColorKey(SDL_Surface*,int,Uint32); int SDL_GetColorKey(SDL_Surface*,Uint32*); int SDL_SetSurfaceColorMod(SDL_Surface*,Uint8,Uint8,Uint8); int SDL_GetSurfaceColorMod(SDL_Surface*,Uint8*,Uint8*,Uint8*); int SDL_SetSurfaceAlphaMod(SDL_Surface*,Uint8); int SDL_GetSurfaceAlphaMod(SDL_Surface*,Uint8*); int SDL_SetSurfaceBlendMode(SDL_Surface*,SDL_BlendMode); int SDL_GetSurfaceBlendMode(SDL_Surface*,SDL_BlendMode*); SDL_bool SDL_SetClipRect(SDL_Surface*,const(SDL_Rect)*); void SDL_GetClipRect(SDL_Surface*,SDL_Rect*); SDL_Surface* SDL_ConvertSurface(SDL_Surface*,const(SDL_PixelFormat)*,Uint32); SDL_Surface* SDL_ConvertSurfaceFormat(SDL_Surface*,Uint32,Uint32); int SDL_ConvertPixels(int,int,Uint32,const(void)*,int,Uint32,void*,int); int SDL_FillRect(SDL_Surface*,const(SDL_Rect)*,Uint32); int SDL_FillRects(SDL_Surface*,const(SDL_Rect)*,int,Uint32); int SDL_UpperBlit(SDL_Surface*,const(SDL_Rect)*,SDL_Surface*,SDL_Rect*); int SDL_LowerBlit(SDL_Surface*,SDL_Rect*,SDL_Surface*,SDL_Rect*); int SDL_SoftStretch(SDL_Surface*,const(SDL_Rect)*,SDL_Surface*,const(SDL_Rect)*); int SDL_UpperBlitScaled(SDL_Surface*,const(SDL_Rect)*,SDL_Surface*,SDL_Rect*); int SDL_LowerBlitScaled(SDL_Surface*,SDL_Rect*,SDL_Surface*,SDL_Rect*); static if(Derelict_OS_Windows) { int SDL_Direct3D9GetAdapterIndex(int); IDirect3DDevice9* SDL_RenderGetD3D9Device(SDL_Renderer*); SDL_bool SDL_DXGIGetOutputInfo(int,int*,int*); } static if(Derelict_OS_iOS) { int SDL_iPhoneSetAnimationCallback(SDL_Window*,int,SDL_iPhoneAnimationCallback,void*); void SDL_iPhoneSetEventPump(SDL_bool); } static if(Derelict_OS_Android) { void* SDL_AndroidGetJNIEnv(); void* SDL_AndroidGetActivity(); const(char)* SDL_AndroidGetInternalStoragePath(); int SDL_AndroidGetInternalStorageState(); const(char)* SDL_AndroidGetExternalStoragePath(); } static if(Derelict_OS_WinRT) { const(wchar_t)* SDL_WinRTGetFSPathUNICODE(SDL_WinRT_Path); const(char)* SDL_WinRTGetFSPathUTF8(SDL_WinRT_Path); int SDL_WinRTRunApp(int function(int,char**),void*); } SDL_bool SDL_GetWindowWMInfo(SDL_Window* window,SDL_SysWMinfo * info); Uint32 SDL_GetTicks(); Uint64 SDL_GetPerformanceCounter(); Uint64 SDL_GetPerformanceFrequency(); void SDL_Delay(Uint32); SDL_TimerID SDL_AddTimer(Uint32,SDL_TimerCallback,void*); SDL_bool SDL_RemoveTimer(SDL_TimerID); int SDL_GetNumTouchDevices(); SDL_TouchID SDL_GetTouchDevice(int); int SDL_GetNumTouchFingers(SDL_TouchID); SDL_Finger* SDL_GetTouchFinger(SDL_TouchID,int); void SDL_GetVersion(SDL_version*); const(char)* SDL_GetRevision(); int SDL_GetRevisionNumber(); int SDL_GetNumVideoDrivers(); const(char)* SDL_GetVideoDriver(int); int SDL_VideoInit(const(char)*); void SDL_VideoQuit(); const(char)* SDL_GetCurrentVideoDriver(); int SDL_GetNumVideoDisplays(); const(char)* SDL_GetDisplayName(int); int SDL_GetDisplayBounds(int,SDL_Rect*); int SDL_GetDisplayDPI(int,float*,float*,float*); int SDL_GetDisplayUsableBounds(int,SDL_Rect*); int SDL_GetNumDisplayModes(int); int SDL_GetDisplayMode(int,int,SDL_DisplayMode*); int SDL_GetDesktopDisplayMode(int,SDL_DisplayMode*); int SDL_GetCurrentDisplayMode(int,SDL_DisplayMode*); SDL_DisplayMode* SDL_GetClosestDisplayMode(int,const(SDL_DisplayMode)*,SDL_DisplayMode*); int SDL_GetWindowDisplayIndex(SDL_Window*); int SDL_SetWindowDisplayMode(SDL_Window*,const(SDL_DisplayMode)*); int SDL_GetWindowDisplayMode(SDL_Window*,SDL_DisplayMode*); Uint32 SDL_GetWindowPixelFormat(SDL_Window*); SDL_Window* SDL_CreateWindow(const(char)*,int,int,int,int,SDL_WindowFlags); SDL_Window* SDL_CreateWindowFrom(const(void)*); Uint32 SDL_GetWindowID(SDL_Window*); SDL_Window* SDL_GetWindowFromID(Uint32); SDL_WindowFlags SDL_GetWindowFlags(SDL_Window*); void SDL_SetWindowTitle(SDL_Window*,const(char)*); const(char)* SDL_GetWindowTitle(SDL_Window*); void SDL_SetWindowIcon(SDL_Window*,SDL_Surface*); void* SDL_SetWindowData(SDL_Window*,const(char)*,void*); void* SDL_GetWindowData(SDL_Window*,const(char)*); void SDL_SetWindowPosition(SDL_Window*,int,int); void SDL_GetWindowPosition(SDL_Window*,int*,int*); void SDL_SetWindowSize(SDL_Window*,int,int); void SDL_GetWindowSize(SDL_Window*,int*,int*); int SDL_GetWindowBordersSize(SDL_Window*,int*,int*,int*,int*); void SDL_SetWindowMinimumSize(SDL_Window*,int,int); void SDL_GetWindowMinimumSize(SDL_Window*,int*,int*); void SDL_SetWindowMaximumSize(SDL_Window*,int,int); void SDL_GetWindowMaximumSize(SDL_Window*,int*,int*); void SDL_SetWindowBordered(SDL_Window*,SDL_bool); void SDL_SetWindowResizable(SDL_Window*,SDL_bool); void SDL_ShowWindow(SDL_Window*); void SDL_HideWindow(SDL_Window*); void SDL_RaiseWindow(SDL_Window*); void SDL_MaximizeWindow(SDL_Window*); void SDL_MinimizeWindow(SDL_Window*); void SDL_RestoreWindow(SDL_Window*); int SDL_SetWindowFullscreen(SDL_Window*,Uint32); SDL_Surface* SDL_GetWindowSurface(SDL_Window*); int SDL_UpdateWindowSurface(SDL_Window*); int SDL_UpdateWindowSurfaceRects(SDL_Window*,SDL_Rect*,int); void SDL_SetWindowGrab(SDL_Window*,SDL_bool); SDL_bool SDL_GetWindowGrab(SDL_Window*); SDL_Window* SDL_GetGrabbedWindow(); int SDL_SetWindowBrightness(SDL_Window*,float); float SDL_GetWindowBrightness(SDL_Window*); int SDL_SetWindowOpacity(SDL_Window*,float); int SDL_GetWindowOpacity(SDL_Window*,float*); int SDL_SetWindowModalFor(SDL_Window*,SDL_Window*); int SDL_SetWindowInputFocus(SDL_Window*); int SDL_SetWindowGammaRamp(SDL_Window*,const(Uint16)*,const(Uint16)*,const(Uint16)*); int SDL_GetWindowGammaRamp(SDL_Window*,Uint16*,Uint16*,Uint16*); int SDL_SetWindowHitTest(SDL_Window*,SDL_HitTest,void*); void SDL_DestroyWindow(SDL_Window*); SDL_bool SDL_IsScreenSaverEnabled(); void SDL_EnableScreenSaver(); void SDL_DisableScreenSaver(); int SDL_GL_LoadLibrary(const(char)*); void* SDL_GL_GetProcAddress(const(char)*); void SDL_GL_UnloadLibrary(); SDL_bool SDL_GL_ExtensionSupported(const(char)*); void SDL_GL_ResetAttributes(); int SDL_GL_SetAttribute(SDL_GLattr,int); int SDL_GL_GetAttribute(SDL_GLattr,int*); SDL_GLContext SDL_GL_CreateContext(SDL_Window*); int SDL_GL_MakeCurrent(SDL_Window*,SDL_GLContext); SDL_Window* SDL_GL_GetCurrentWindow(); SDL_GLContext SDL_GL_GetCurrentContext(); void SDL_GL_GetDrawableSize(SDL_Window*,int*,int*); int SDL_GL_SetSwapInterval(int); int SDL_GL_GetSwapInterval(); void SDL_GL_SwapWindow(SDL_Window*); void SDL_GL_DeleteContext(SDL_GLContext); } CheeseCutter-2.10/src/derelict/sdl2/internal/sdl_types.d000066400000000000000000002230651516216315000232440ustar00rootroot00000000000000/* Boost Software License - Version 1.0 - August 17th, 2003 Permission is hereby granted, free of charge, to any person or organization obtaining a copy of the software and accompanying documentation covered by this license (the "Software") to use, reproduce, display, distribute, execute, and transmit the Software, and to prepare derivative works of the Software, and to permit third-parties to whom the Software is furnished to do so, all subject to the following: The copyright notices in the Software and this entire statement, including the above license grant, this restriction and the following disclaimer, must be included in all copies of the Software, in whole or in part, and all derivative works of the Software, unless such copies or derivative works are solely in the form of machine-executable object code generated by a source language processor. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ module derelict.sdl2.internal.sdl_types; import core.stdc.config, core.stdc.stdio; import derelict.util.system; // SDL_version.h struct SDL_version { Uint8 major; Uint8 minor; Uint8 patch; } enum : Uint8 { SDL_MAJOR_VERSION = 2, SDL_MINOR_VERSION = 0, SDL_PATCHLEVEL = 5, } @nogc nothrow pure { void SDL_VERSION(SDL_version* x) { x.major = SDL_MAJOR_VERSION; x.minor = SDL_MINOR_VERSION; x.patch = SDL_PATCHLEVEL; } Uint32 SDL_VERSIONNUM(Uint8 X, Uint8 Y, Uint8 Z) { return X*1000 + Y*100 + Z; } Uint32 SDL_COMPILEDVERSION() { return SDL_VERSIONNUM(SDL_MAJOR_VERSION, SDL_MINOR_VERSION, SDL_PATCHLEVEL); } bool SDL_VERSION_ATLEAST(Uint8 X, Uint8 Y, Uint8 Z) { return (SDL_COMPILEDVERSION() >= SDL_VERSIONNUM(X, Y, Z)); } } // From SDL_stdinc.h enum SDL_bool { SDL_FALSE = 0, SDL_TRUE = 1 } mixin(MakeEnum!SDL_bool); alias Sint8 = byte; alias Uint8 = ubyte; alias Sint16 = short; alias Uint16 = ushort; alias Sint32 = int; alias Uint32 = uint; alias Sint64 = long; alias Uint64 = ulong; @nogc nothrow pure Uint32 SDL_FOURCC(char A, char B, char C, char D) { return ((A << 0) | (B << 8) | (C << 16) | (D << 24)); } // SDL.h enum : Uint32 { SDL_INIT_TIMER = 0x00000001, SDL_INIT_AUDIO = 0x00000010, SDL_INIT_VIDEO = 0x00000020, SDL_INIT_JOYSTICK = 0x00000200, SDL_INIT_HAPTIC = 0x00001000, SDL_INIT_GAMECONTROLLER = 0x00002000, SDL_INIT_EVENTS = 0x00004000, SDL_INIT_NOPARACHUTE = 0x00100000, SDL_INIT_EVERYTHING = SDL_INIT_TIMER | SDL_INIT_AUDIO | SDL_INIT_VIDEO | SDL_INIT_EVENTS | SDL_INIT_JOYSTICK | SDL_INIT_HAPTIC | SDL_INIT_GAMECONTROLLER } // SDL_assert.h enum SDL_AssertState : Uint32 { SDL_ASSERTION_RETRY = 0, SDL_ASSERTION_BREAK = 1, SDL_ASSERTION_ABORT = 2, SDL_ASSERTION_IGNORE = 3, SDL_ASSERTION_ALWAYS_IGNORE = 4 } mixin(MakeEnum!SDL_AssertState); alias SDL_assert_state = SDL_AssertState; struct SDL_AssertData { int always_ignore; Uint32 trigger_count; const(char) *condition; const(char) *filename; int linenum; const(char) *function_; const(SDL_AssertData) *next; } alias SDL_assert_data = SDL_AssertData; extern(C) nothrow alias SDL_AssertionHandler = SDL_AssertState function(const(SDL_AssertData)* data, void* userdata); // SDL_audio.h enum SDL_AudioMask : Uint16 { SDL_AUDIO_MASK_BITSIZE = 0xFF, SDL_AUDIO_MASK_DATATYPE = 1<<8, SDL_AUDIO_MASK_ENDIAN = 1<<12, SDL_AUDIO_MASK_SIGNED = 1<<15, } mixin(MakeEnum!SDL_AudioMask); @nogc nothrow pure { int SDL_AUDIO_BITSIZE(SDL_AudioFormat x) { return x & SDL_AUDIO_MASK_BITSIZE; } int SDL_AUDIO_ISFLOAT(SDL_AudioFormat x) { return x & SDL_AUDIO_MASK_DATATYPE; } int SDL_AUDIO_ISBIGENDIAN(SDL_AudioFormat x) { return x & SDL_AUDIO_MASK_ENDIAN; } int SDL_AUDIO_ISSIGNED(SDL_AudioFormat x) { return x & SDL_AUDIO_MASK_SIGNED; } int SDL_AUDIO_ISINT(SDL_AudioFormat x) { return !SDL_AUDIO_ISFLOAT(x); } int SDL_AUDIO_ISLITTLEENDIAN(SDL_AudioFormat x) { return !SDL_AUDIO_ISBIGENDIAN(x); } int SDL_AUDIO_ISUNSIGNED(SDL_AudioFormat x) { return !SDL_AUDIO_ISSIGNED(x); } } enum SDL_AudioFormat : Uint16 { AUDIO_U8 = 0x0008, AUDIO_S8 = 0x8008, AUDIO_U16LSB = 0x0010, AUDIO_S16LSB = 0x8010, AUDIO_U16MSB = 0x1010, AUDIO_S16MSB = 0x9010, AUDIO_U16 = AUDIO_U16LSB, AUDIO_S16 = AUDIO_S16LSB, AUDIO_S32LSB = 0x8020, AUDIO_S32MSB = 0x9020, AUDIO_S32 = AUDIO_S32LSB, AUDIO_F32LSB = 0x8120, AUDIO_F32MSB = 0x9120, AUDIO_F32 = AUDIO_F32LSB, } mixin(MakeEnum!SDL_AudioFormat); version(LittleEndian) { alias AUDIO_U16SYS = AUDIO_U16LSB; alias AUDIO_S16SYS = AUDIO_S16LSB; alias AUDIO_S32SYS = AUDIO_S32LSB; alias AUDIO_F32SYS = AUDIO_F32LSB; } else { alias AUDIO_U16SYS = AUDIO_U16MSB; alias AUDIO_S16SYS = AUDIO_S16MSB; alias AUDIO_S32SYS = AUDIO_S32MSB; alias AUDIO_F32SYS = AUDIO_F32MSB; } enum { SDL_AUDIO_ALLOW_FREQUENCY_CHANGE = 0x00000001, SDL_AUDIO_ALLOW_FORMAT_CHANGE = 0x00000002, SDL_AUDIO_ALLOW_CHANNELS_CHANGE = 0x00000004, SDL_AUDIO_ALLOW_ANY_CHANGE = (SDL_AUDIO_ALLOW_FREQUENCY_CHANGE|SDL_AUDIO_ALLOW_FORMAT_CHANGE|SDL_AUDIO_ALLOW_CHANNELS_CHANGE), } extern(C) nothrow alias SDL_AudioCallback = void function(void* userdata, Uint8* stream, int len); struct SDL_AudioSpec { int freq; SDL_AudioFormat format; Uint8 channels; Uint8 silence; Uint16 samples; Uint16 padding; Uint32 size; SDL_AudioCallback callback; void* userdata; } extern(C) nothrow alias SDL_AudioFilter = void function(SDL_AudioCVT* cvt, SDL_AudioFormat format); struct SDL_AudioCVT { int needed; SDL_AudioFormat src_format; SDL_AudioFormat dst_format; double rate_incr; Uint8* buf; int len; int len_cvt; int len_mult; double len_ratio; SDL_AudioFilter[10] filters; int filter_index; } alias Uint32 SDL_AudioDeviceID; enum SDL_AudioStatus { SDL_AUDIO_STOPPED = 0, SDL_AUDIO_PLAYING, SDL_AUDIO_PAUSED, } mixin(MakeEnum!SDL_AudioStatus); enum SDL_MIX_MAXVOLUME = 128; // SDL_blendmode.h enum SDL_BlendMode { SDL_BLENDMODE_NONE = 0x00000000, SDL_BLENDMODE_BLEND = 0x00000001, SDL_BLENDMODE_ADD = 0x00000002, SDL_BLENDMODE_MOD = 0x00000004 } mixin(MakeEnum!SDL_BlendMode); // SDL_cpuinfo.h enum SDL_CACHELINE_SIZE = 128; // SDL_events.h enum { SDL_RELEASED = 0, SDL_PRESSED = 1, } enum SDL_EventType { SDL_FIRSTEVENT = 0, SDL_QUIT = 0x100, SDL_APP_TERMINATING, SDL_APP_LOWMEMORY, SDL_APP_WILLENTERBACKGROUND, SDL_APP_DIDENTERBACKGROUND, SDL_APP_WILLENTERFOREGROUND, SDL_APP_DIDENTERFOREGROUND, SDL_WINDOWEVENT = 0x200, SDL_SYSWMEVENT, SDL_KEYDOWN = 0x300, SDL_KEYUP, SDL_TEXTEDITING, SDL_TEXTINPUT, SDL_KEYMAPCHANGED, SDL_MOUSEMOTION = 0x400, SDL_MOUSEBUTTONDOWN, SDL_MOUSEBUTTONUP, SDL_MOUSEWHEEL, SDL_JOYAXISMOTION = 0x600, SDL_JOYBALLMOTION, SDL_JOYHATMOTION, SDL_JOYBUTTONDOWN, SDL_JOYBUTTONUP, SDL_JOYDEVICEADDED, SDL_JOYDEVICEREMOVED, SDL_CONTROLLERAXISMOTION = 0x650, SDL_CONTROLLERBUTTONDOWN, SDL_CONTROLLERBUTTONUP, SDL_CONTROLLERDEVICEADDED, SDL_CONTROLLERDEVICEREMOVED, SDL_CONTROLLERDEVICEREMAPPED, SDL_FINGERDOWN = 0x700, SDL_FINGERUP, SDL_FINGERMOTION, SDL_DOLLARGESTURE = 0x800, SDL_DOLLARRECORD, SDL_MULTIGESTURE, SDL_CLIPBOARDUPDATE = 0x900, SDL_DROPFILE = 0x1000, SDL_DROPTEXT, SDL_DROPBEGIN, SDL_DROPCOMPLETE, SDL_AUDIODEVICEADDED = 0x1100, SDL_AUDIODEVICEREMOVED, SDL_RENDER_TARGETS_RESET = 0x2000, SDL_RENDER_DEVICE_RESET = 0x2001, SDL_USEREVENT = 0x8000, SDL_LASTEVENT = 0xFFFF } mixin(MakeEnum!SDL_EventType); struct SDL_CommonEvent { SDL_EventType type; Uint32 timestamp; } struct SDL_WindowEvent { SDL_EventType type; Uint32 timestamp; Uint32 windowID; SDL_WindowEventID event; Uint8 padding1; Uint8 padding2; Uint8 padding3; Sint32 data1; Sint32 data2; } struct SDL_KeyboardEvent { SDL_EventType type; Uint32 timestamp; Uint32 windowID; Uint8 state; Uint8 repeat; Uint8 padding2; Uint8 padding3; SDL_Keysym keysym; } enum SDL_TEXTEDITINGEVENT_TEXT_SIZE = 32; struct SDL_TextEditingEvent { SDL_EventType type; Uint32 timestamp; Uint32 windowID; char[SDL_TEXTEDITINGEVENT_TEXT_SIZE] text; Sint32 start; Sint32 length; } enum SDL_TEXTINPUTEVENT_TEXT_SIZE = 32; struct SDL_TextInputEvent { SDL_EventType type; Uint32 timestamp; Uint32 windowID; char[SDL_TEXTINPUTEVENT_TEXT_SIZE] text; } struct SDL_MouseMotionEvent { SDL_EventType type; Uint32 timestamp; Uint32 windowID; Uint32 which; Uint32 state; Sint32 x; Sint32 y; Sint32 xrel; Sint32 yrel; } struct SDL_MouseButtonEvent { SDL_EventType type; Uint32 timestamp; Uint32 windowID; Uint32 which; Uint8 button; Uint8 state; Uint8 clicks; Uint8 padding1; Sint32 x; Sint32 y; } struct SDL_MouseWheelEvent { SDL_EventType type; Uint32 timestamp; Uint32 windowID; Uint32 which; Sint32 x; Sint32 y; Uint32 direction; } struct SDL_JoyAxisEvent { SDL_EventType type; Uint32 timestamp; SDL_JoystickID which; Uint8 axis; Uint8 padding1; Uint8 padding2; Uint8 padding3; Sint16 value; Uint16 padding4; } struct SDL_JoyBallEvent { SDL_EventType type; Uint32 timestamp; SDL_JoystickID which; Uint8 ball; Uint8 padding1; Uint8 padding2; Uint8 padding3; Sint16 xrel; Sint16 yrel; } struct SDL_JoyHatEvent { SDL_EventType type; Uint32 timestamp; SDL_JoystickID which; Uint8 hat; Uint8 value; Uint8 padding1; Uint8 padding2; } struct SDL_JoyButtonEvent { SDL_EventType type; Uint32 timestamp; SDL_JoystickID which; Uint8 button; Uint8 state; Uint8 padding1; Uint8 padding2; } struct SDL_JoyDeviceEvent { SDL_EventType type; Uint32 timestamp; Sint32 which; } struct SDL_ControllerAxisEvent { SDL_EventType type; Uint32 timestamp; SDL_JoystickID which; Uint8 axis; Uint8 padding1; Uint8 padding2; Uint8 padding3; Sint16 value; Uint16 padding4; } struct SDL_ControllerButtonEvent { SDL_EventType type; Uint32 timestamp; SDL_JoystickID which; Uint8 button; Uint8 state; Uint8 padding1; Uint8 padding2; } struct SDL_ControllerDeviceEvent { SDL_EventType type; Uint32 timestamp; Sint32 which; } struct SDL_AudioDeviceEvent { SDL_EventType type; Uint32 timestamp; Uint32 which; Uint8 iscapture; Uint8 padding1; Uint8 padding2; Uint8 padding3; } struct SDL_TouchFingerEvent { SDL_EventType type; Uint32 timestamp; SDL_TouchID touchId; SDL_FingerID fingerId; float x; float y; float dx; float dy; float pressure; } struct SDL_MultiGestureEvent { SDL_EventType type; Uint32 timestamp; SDL_TouchID touchId; float dTheta; float dDist; float x; float y; Uint16 numFingers; Uint16 padding; } struct SDL_DollarGestureEvent { SDL_EventType type; Uint32 timestamp; SDL_TouchID touchId; SDL_GestureID gestureId; Uint32 numFingers; float error; float x; float y; } struct SDL_DropEvent { SDL_EventType type; Uint32 timestamp; char* file; Uint32 windowID; // Added in SDL 2.0.5! } struct SDL_QuitEvent { SDL_EventType type; Uint32 timestamp; } struct SDL_OSEvent { SDL_EventType type; Uint32 timestamp; } struct SDL_UserEvent { SDL_EventType type; Uint32 timestamp; Uint32 windowID; Sint32 code; void* data1; void* data2; } struct SDL_SysWMEvent { SDL_EventType type; Uint32 timestamp; SDL_SysWMmsg* msg; } union SDL_Event { SDL_EventType type; SDL_CommonEvent common; SDL_WindowEvent window; SDL_KeyboardEvent key; SDL_TextEditingEvent edit; SDL_TextInputEvent text; SDL_MouseMotionEvent motion; SDL_MouseButtonEvent button; SDL_MouseWheelEvent wheel; SDL_JoyAxisEvent jaxis; SDL_JoyBallEvent jball; SDL_JoyHatEvent jhat; SDL_JoyButtonEvent jbutton; SDL_JoyDeviceEvent jdevice; SDL_ControllerAxisEvent caxis; SDL_ControllerButtonEvent cbutton; SDL_ControllerDeviceEvent cdevice; SDL_AudioDeviceEvent adevice; SDL_QuitEvent quit; SDL_UserEvent user; SDL_SysWMEvent syswm; SDL_TouchFingerEvent tfinger; SDL_MultiGestureEvent mgesture; SDL_DollarGestureEvent dgesture; SDL_DropEvent drop; Uint8[56] padding; } enum SDL_eventaction { SDL_ADDEVENT, SDL_PEEKEVENT, SDL_GETEVENT } mixin(MakeEnum!SDL_eventaction); extern(C) nothrow alias SDL_EventFilter = int function(void* userdata, SDL_Event* event); enum { SDL_QUERY = -1, SDL_IGNORE = 0, SDL_DISABLE = 0, SDL_ENABLE = 1, } // SDL_gamecontroller.h struct SDL_GameController; enum SDL_GameControllerBindType { SDL_CONTROLLER_BINDTYPE_NONE = 0, SDL_CONTROLLER_BINDTYPE_BUTTON, SDL_CONTROLLER_BINDTYPE_AXIS, SDL_CONTROLLER_BINDTYPE_HAT, } mixin(MakeEnum!SDL_GameControllerBindType); struct SDL_GameControllerButtonBind { SDL_GameControllerBindType bindType; union value { int button; int axis; struct hat { int hat; int hat_mask; } } alias button = value.button; alias axis = value.axis; alias hat = value.hat; } enum SDL_GameControllerAxis { SDL_CONTROLLER_AXIS_INVALID = -1, SDL_CONTROLLER_AXIS_LEFTX, SDL_CONTROLLER_AXIS_LEFTY, SDL_CONTROLLER_AXIS_RIGHTX, SDL_CONTROLLER_AXIS_RIGHTY, SDL_CONTROLLER_AXIS_TRIGGERLEFT, SDL_CONTROLLER_AXIS_TRIGGERRIGHT, SDL_CONTROLLER_AXIS_MAX } mixin(MakeEnum!SDL_GameControllerAxis); enum SDL_GameControllerButton { SDL_CONTROLLER_BUTTON_INVALID = -1, SDL_CONTROLLER_BUTTON_A, SDL_CONTROLLER_BUTTON_B, SDL_CONTROLLER_BUTTON_X, SDL_CONTROLLER_BUTTON_Y, SDL_CONTROLLER_BUTTON_BACK, SDL_CONTROLLER_BUTTON_GUIDE, SDL_CONTROLLER_BUTTON_START, SDL_CONTROLLER_BUTTON_LEFTSTICK, SDL_CONTROLLER_BUTTON_RIGHTSTICK, SDL_CONTROLLER_BUTTON_LEFTSHOULDER, SDL_CONTROLLER_BUTTON_RIGHTSHOULDER, SDL_CONTROLLER_BUTTON_DPAD_UP, SDL_CONTROLLER_BUTTON_DPAD_DOWN, SDL_CONTROLLER_BUTTON_DPAD_LEFT, SDL_CONTROLLER_BUTTON_DPAD_RIGHT, SDL_CONTROLLER_BUTTON_MAX } mixin(MakeEnum!SDL_GameControllerButton); // SDL_gesture.h alias SDL_GestureID = Sint64; // SDL_haptic.h struct SDL_Haptic; enum SDL_D_HapticFlags : Uint16 { SDL_HAPTIC_CONSTANT = 1u<<0, SDL_HAPTIC_SINE = 1u<<1, SDL_HAPTIC_LEFTRIGHT = 1u<<2, SDL_HAPTIC_TRIANGLE = 1u<<3, SDL_HAPTIC_SAWTOOTHUP = 1u<<4, SDL_HAPTIC_SAWTOOTHDOWN = 1u<<5, SDL_HAPTIC_RAMP = 1u<<6, SDL_HAPTIC_SPRING = 1u<<7, SDL_HAPTIC_DAMPER = 1u<<8, SDL_HAPTIC_INERTIA = 1u<<9, SDL_HAPTIC_FRICTION = 1u<<10, SDL_HAPTIC_CUSTOM = 1u<<11, SDL_HAPTIC_GAIN = 1u<<12, SDL_HAPTIC_AUTOCENTER = 1u<<13, SDL_HAPTIC_STATUS = 1u<<14, SDL_HAPTIC_PAUSE = 1u<<15, SDL_HAPTIC_POLAR = 0, SDL_HAPTIC_CARTESIAN = 1, SDL_HAPTIC_SPHERICAL = 2, } mixin(MakeEnum!SDL_D_HapticFlags); enum SDL_HAPTIC_INFINITY = 4294967295U; struct SDL_HapticDirection { Uint8 type; Sint32[3] dir; } struct SDL_HapticConstant { SDL_D_HapticFlags type; SDL_HapticDirection direction; Uint32 length; Uint16 delay; Uint16 button; Uint16 interval; Sint16 level; Uint16 attack_length; Uint16 attack_level; Uint16 fade_length; Uint16 fade_level; } struct SDL_HapticPeriodic { SDL_D_HapticFlags type; SDL_HapticDirection direction; Uint32 length; Uint32 delay; Uint16 button; Uint16 interval; Uint16 period; Sint16 magnitude; Sint16 offset; Uint16 phase; Uint16 attack_length; Uint16 attack_level; Uint16 fade_length; Uint16 fade_level; } struct SDL_HapticCondition { SDL_D_HapticFlags type; SDL_HapticDirection direciton; Uint32 length; Uint16 delay; Uint16 button; Uint16 interval; Uint16[3] right_sat; Uint16[3] left_sat; Sint16[3] right_coeff; Sint16[3] left_coeff; Uint16[3] deadband; Uint16[3] center; } struct SDL_HapticRamp { SDL_D_HapticFlags type; SDL_HapticDirection direction; Uint32 length; Uint16 delay; Uint16 button; Uint16 interval; Sint16 start; Sint16 end; Uint16 attack_length; Uint16 attack_level; Uint16 fade_length; Uint16 fade_level; } struct SDL_HapticLeftRight { SDL_D_HapticFlags type; Uint32 length; Uint16 large_magnitude; Uint16 small_magnitude; } struct SDL_HapticCustom { SDL_D_HapticFlags type; SDL_HapticDirection direction; Uint32 length; Uint16 delay; Uint16 button; Uint16 interval; Uint8 channels; Uint16 period; Uint16 samples; Uint16* data; Uint16 attack_length; Uint16 attack_level; Uint16 fade_length; Uint16 fade_level; } union SDL_HapticEffect { SDL_D_HapticFlags type; SDL_HapticConstant constant; SDL_HapticPeriodic periodic; SDL_HapticCondition condition; SDL_HapticRamp ramp; SDL_HapticLeftRight leftright; SDL_HapticCustom custom; } // SDL_hints.h enum : string { SDL_HINT_FRAMEBUFFER_ACCELERATION = "SDL_FRAMEBUFFER_ACCELERATION", SDL_HINT_RENDER_DRIVER = "SDL_RENDER_DRIVER", SDL_HINT_RENDER_OPENGL_SHADERS = "SDL_RENDER_OPENGL_SHADERS", SDL_HINT_RENDER_DIRECT3D_THREADSAFE = "SDL_RENDER_DIRECT3D_THREADSAFE", SDL_HINT_RENDER_DIRECT3D11_DEBUG = "SDL_RENDER_DIRECT3D11_DEBUG", SDL_HINT_RENDER_SCALE_QUALITY = "SDL_RENDER_SCALE_QUALITY", SDL_HINT_RENDER_VSYNC = "SDL_RENDER_VSYNC", SDL_HINT_VIDEO_ALLOW_SCREENSAVER = "SDL_VIDEO_ALLOW_SCREENSAVER", SDL_HINT_VIDEO_X11_XVIDMODE = "SDL_VIDEO_X11_XVIDMODE", SDL_HINT_VIDEO_X11_XINERAMA = "SDL_VIDEO_X11_XINERAMA", SDL_HINT_VIDEO_X11_XRANDR = "SDL_VIDEO_X11_XRANDR", SDL_HINT_VIDEO_X11_NET_WM_PING = "SDL_VIDEO_X11_NET_WM_PING", SDL_HINT_WINDOW_FRAME_USABLE_WHILE_CURSOR_HIDDEN = "SDL_WINDOW_FRAME_USABLE_WHILE_CURSOR_HIDDEN", SDL_HINT_WINDOWS_ENABLE_MESSAGELOOP = "SDL_WINDOWS_ENABLE_MESSAGELOOP", SDL_HINT_GRAB_KEYBOARD = "SDL_GRAB_KEYBOARD", SDL_HINT_MOUSE_RELATIVE_MODE_WARP = "SDL_MOUSE_RELATIVE_MODE_WARP", SDL_HINT_MOUSE_FOCUS_CLICKTHROUGH = "SDL_MOUSE_FOCUS_CLICKTHROUGH", SDL_HINT_VIDEO_MINIMIZE_ON_FOCUS_LOSS = "SDL_VIDEO_MINIMIZE_ON_FOCUS_LOSS", SDL_HINT_IDLE_TIMER_DISABLED = "SDL_IOS_IDLE_TIMER_DISABLED", SDL_HINT_ORIENTATIONS = "SDL_IOS_ORIENTATIONS", SDL_HINT_APPLE_TV_CONTROLLER_UI_EVENTS = "SDL_APPLE_TV_CONTROLLER_UI_EVENTS", SDL_HINT_APPLE_TV_REMOTE_ALLOW_ROTATION = "SDL_APPLE_TV_REMOTE_ALLOW_ROTATION", SDL_HINT_ACCELEROMETER_AS_JOYSTICK = "SDL_ACCELEROMETER_AS_JOYSTICK", SDL_HINT_XINPUT_ENABLED = "SDL_XINPUT_ENABLED", SDL_HINT_XINPUT_USE_OLD_JOYSTICK_MAPPING = "SDL_XINPUT_USE_OLD_JOYSTICK_MAPPING", SDL_HINT_GAMECONTROLLERCONFIG = "SDL_GAMECONTROLLERCONFIG", SDL_HINT_JOYSTICK_ALLOW_BACKGROUND_EVENTS = "SDL_JOYSTICK_ALLOW_BACKGROUND_EVENTS", SDL_HINT_ALLOW_TOPMOST = "SDL_ALLOW_TOPMOST", SDL_HINT_TIMER_RESOLUTION = "SDL_TIMER_RESOLUTION", SDL_HINT_THREAD_STACK_SIZE = "SDL_THREAD_STACK_SIZE", SDL_HINT_VIDEO_HIGHDPI_DISABLED = "SDL_VIDEO_HIGHDPI_DISABLED", SDL_HINT_MAC_CTRL_CLICK_EMULATE_RIGHT_CLICK = "SDL_MAC_CTRL_CLICK_EMULATE_RIGHT_CLICK", SDL_HINT_VIDEO_WIN_D3DCOMPILER = "SDL_VIDEO_WIN_D3DCOMPILER", SDL_HINT_VIDEO_WINDOW_SHARE_PIXEL_FORMAT = "SDL_VIDEO_WINDOW_SHARE_PIXEL_FORMAT", SDL_HINT_WINRT_PRIVACY_POLICY_URL = "SDL_WINRT_PRIVACY_POLICY_URL", SDL_HINT_WINRT_PRIVACY_POLICY_LABEL = "SDL_WINRT_PRIVACY_POLICY_LABEL", SDL_HINT_WINRT_HANDLE_BACK_BUTTON = "SDL_WINRT_HANDLE_BACK_BUTTON", SDL_HINT_VIDEO_MAC_FULLSCREEN_SPACES = "SDL_HINT_VIDEO_MAC_FULLSCREEN_SPACES", SDL_HINT_MAC_BACKGROUND_APP = "SDL_MAC_BACKGROUND_APP", SDL_HINT_ANDROID_APK_EXPANSION_MAIN_FILE_VERSION = "SDL_ANDROID_APK_EXPANSION_MAIN_FILE_VERSION", SDL_HINT_ANDROID_APK_EXPANSION_PATCH_FILE_VERSION = "SDL_ANDROID_APK_EXPANSION_PATCH_FILE_VERSION", SDL_HINT_IME_INTERNAL_EDITING = "SDL_IME_INTERNAL_EDITING", SDL_HINT_ANDROID_SEPARATE_MOUSE_AND_TOUCH = "SDL_ANDROID_SEPARATE_MOUSE_AND_TOUCH", SDL_HINT_EMSCRIPTEN_KEYBOARD_ELEMENT = "SDL_EMSCRIPTEN_KEYBOARD_ELEMENT", SDL_HINT_NO_SIGNAL_HANDLERS = "SDL_NO_SIGNAL_HANDLERS", SDL_HINT_WINDOWS_NO_CLOSE_ON_ALT_F4 = "SDL_WINDOWS_NO_CLOSE_ON_ALT_F4", SDL_HINT_BMP_SAVE_LEGACY_FORMAT = "SDL_BMP_SAVE_LEGACY_FORMAT", SDL_HINT_WINDOWS_DISABLE_THREAD_NAMING = "SDL_WINDOWS_DISABLE_THREAD_NAMING", SDL_HINT_RPI_VIDEO_LAYER ="SDL_RPI_VIDEO_LAYER", } enum SDL_HintPriority { SDL_HINT_DEFAULT, SDL_HINT_NORMAL, SDL_HINT_OVERRIDE, } mixin(MakeEnum!SDL_HintPriority); extern(C) nothrow alias SDL_HintCallback = void function(void*, const(char)*, const(char)*); // SDL_joystick.h struct SDL_Joystick; struct SDL_JoystickGUID { Uint8[16] data; } alias SDL_JoystickID = Sint32; enum SDL_JoystickPowerLevel { SDL_JOYSTICK_POWER_UNKNOWN = -1, SDL_JOYSTICK_POWER_EMPTY, SDL_JOYSTICK_POWER_LOW, SDL_JOYSTICK_POWER_MEDIUM, SDL_JOYSTICK_POWER_FULL, SDL_JOYSTICK_POWER_WIRED, SDL_JOYSTICK_POWER_MAX } mixin(MakeEnum!SDL_JoystickPowerLevel); enum : Uint8 { SDL_HAT_CENTERED = 0x00, SDL_HAT_UP = 0x01, SDL_HAT_RIGHT = 0x02, SDL_HAT_DOWN = 0x04, SDL_HAT_LEFT = 0x08, SDL_HAT_RIGHTUP = (SDL_HAT_RIGHT|SDL_HAT_UP), SDL_HAT_RIGHTDOWN = (SDL_HAT_RIGHT|SDL_HAT_DOWN), SDL_HAT_LEFTUP = (SDL_HAT_LEFT|SDL_HAT_UP), SDL_HAT_LEFTDOWN = (SDL_HAT_LEFT|SDL_HAT_DOWN), } // SDL_keyboard.h struct SDL_Keysym { SDL_Scancode scancode; SDL_Keycode sym; Uint16 mod; Uint32 unicode; } // SDL_messagebox.h enum SDL_MessageBoxFlags { SDL_MESSAGEBOX_ERROR = 0x00000010, SDL_MESSAGEBOX_WARNING = 0x00000020, SDL_MESSAGEBOX_INFORMATION = 0x00000040, } mixin(MakeEnum!SDL_MessageBoxFlags); enum SDL_MessageBoxButtonFlags { SDL_MESSAGEBOX_BUTTON_RETURNKEY_DEFAULT = 0x00000001, SDL_MESSAGEBOX_BUTTON_ESCAPEKEY_DEFAULT = 0x00000002, } mixin(MakeEnum!SDL_MessageBoxButtonFlags); struct SDL_MessageBoxButtonData { Uint32 flags; int buttonid; const(char)* text; } struct SDL_MessageBoxColor { Uint8 r, g, b; } enum SDL_MessageBoxColorType { SDL_MESSAGEBOX_COLOR_BACKGROUND, SDL_MESSAGEBOX_COLOR_TEXT, SDL_MESSAGEBOX_COLOR_BUTTON_BORDER, SDL_MESSAGEBOX_COLOR_BUTTON_BACKGROUND, SDL_MESSAGEBOX_COLOR_BUTTON_SELECTED, SDL_MESSAGEBOX_COLOR_MAX, } mixin(MakeEnum!SDL_MessageBoxColorType); struct SDL_MessageBoxColorScheme { SDL_MessageBoxColor[SDL_MESSAGEBOX_COLOR_MAX] colors; } struct SDL_MessageBoxData { Uint32 flags; SDL_Window* window; const(char)* title; const(char)* message; int numbuttons; const(SDL_MessageBoxButtonData)* buttons; const(SDL_MessageBoxColorScheme)* colorScheme; } // SDL_scancode.h enum SDL_Scancode { SDL_SCANCODE_UNKNOWN = 0, SDL_SCANCODE_A = 4, SDL_SCANCODE_B = 5, SDL_SCANCODE_C = 6, SDL_SCANCODE_D = 7, SDL_SCANCODE_E = 8, SDL_SCANCODE_F = 9, SDL_SCANCODE_G = 10, SDL_SCANCODE_H = 11, SDL_SCANCODE_I = 12, SDL_SCANCODE_J = 13, SDL_SCANCODE_K = 14, SDL_SCANCODE_L = 15, SDL_SCANCODE_M = 16, SDL_SCANCODE_N = 17, SDL_SCANCODE_O = 18, SDL_SCANCODE_P = 19, SDL_SCANCODE_Q = 20, SDL_SCANCODE_R = 21, SDL_SCANCODE_S = 22, SDL_SCANCODE_T = 23, SDL_SCANCODE_U = 24, SDL_SCANCODE_V = 25, SDL_SCANCODE_W = 26, SDL_SCANCODE_X = 27, SDL_SCANCODE_Y = 28, SDL_SCANCODE_Z = 29, SDL_SCANCODE_1 = 30, SDL_SCANCODE_2 = 31, SDL_SCANCODE_3 = 32, SDL_SCANCODE_4 = 33, SDL_SCANCODE_5 = 34, SDL_SCANCODE_6 = 35, SDL_SCANCODE_7 = 36, SDL_SCANCODE_8 = 37, SDL_SCANCODE_9 = 38, SDL_SCANCODE_0 = 39, SDL_SCANCODE_RETURN = 40, SDL_SCANCODE_ESCAPE = 41, SDL_SCANCODE_BACKSPACE = 42, SDL_SCANCODE_TAB = 43, SDL_SCANCODE_SPACE = 44, SDL_SCANCODE_MINUS = 45, SDL_SCANCODE_EQUALS = 46, SDL_SCANCODE_LEFTBRACKET = 47, SDL_SCANCODE_RIGHTBRACKET = 48, SDL_SCANCODE_BACKSLASH = 49, SDL_SCANCODE_NONUSHASH = 50, SDL_SCANCODE_SEMICOLON = 51, SDL_SCANCODE_APOSTROPHE = 52, SDL_SCANCODE_GRAVE = 53, SDL_SCANCODE_COMMA = 54, SDL_SCANCODE_PERIOD = 55, SDL_SCANCODE_SLASH = 56, SDL_SCANCODE_CAPSLOCK = 57, SDL_SCANCODE_F1 = 58, SDL_SCANCODE_F2 = 59, SDL_SCANCODE_F3 = 60, SDL_SCANCODE_F4 = 61, SDL_SCANCODE_F5 = 62, SDL_SCANCODE_F6 = 63, SDL_SCANCODE_F7 = 64, SDL_SCANCODE_F8 = 65, SDL_SCANCODE_F9 = 66, SDL_SCANCODE_F10 = 67, SDL_SCANCODE_F11 = 68, SDL_SCANCODE_F12 = 69, SDL_SCANCODE_PRINTSCREEN = 70, SDL_SCANCODE_SCROLLLOCK = 71, SDL_SCANCODE_PAUSE = 72, SDL_SCANCODE_INSERT = 73, SDL_SCANCODE_HOME = 74, SDL_SCANCODE_PAGEUP = 75, SDL_SCANCODE_DELETE = 76, SDL_SCANCODE_END = 77, SDL_SCANCODE_PAGEDOWN = 78, SDL_SCANCODE_RIGHT = 79, SDL_SCANCODE_LEFT = 80, SDL_SCANCODE_DOWN = 81, SDL_SCANCODE_UP = 82, SDL_SCANCODE_NUMLOCKCLEAR = 83, SDL_SCANCODE_KP_DIVIDE = 84, SDL_SCANCODE_KP_MULTIPLY = 85, SDL_SCANCODE_KP_MINUS = 86, SDL_SCANCODE_KP_PLUS = 87, SDL_SCANCODE_KP_ENTER = 88, SDL_SCANCODE_KP_1 = 89, SDL_SCANCODE_KP_2 = 90, SDL_SCANCODE_KP_3 = 91, SDL_SCANCODE_KP_4 = 92, SDL_SCANCODE_KP_5 = 93, SDL_SCANCODE_KP_6 = 94, SDL_SCANCODE_KP_7 = 95, SDL_SCANCODE_KP_8 = 96, SDL_SCANCODE_KP_9 = 97, SDL_SCANCODE_KP_0 = 98, SDL_SCANCODE_KP_PERIOD = 99, SDL_SCANCODE_NONUSBACKSLASH = 100, SDL_SCANCODE_APPLICATION = 101, SDL_SCANCODE_POWER = 102, SDL_SCANCODE_KP_EQUALS = 103, SDL_SCANCODE_F13 = 104, SDL_SCANCODE_F14 = 105, SDL_SCANCODE_F15 = 106, SDL_SCANCODE_F16 = 107, SDL_SCANCODE_F17 = 108, SDL_SCANCODE_F18 = 109, SDL_SCANCODE_F19 = 110, SDL_SCANCODE_F20 = 111, SDL_SCANCODE_F21 = 112, SDL_SCANCODE_F22 = 113, SDL_SCANCODE_F23 = 114, SDL_SCANCODE_F24 = 115, SDL_SCANCODE_EXECUTE = 116, SDL_SCANCODE_HELP = 117, SDL_SCANCODE_MENU = 118, SDL_SCANCODE_SELECT = 119, SDL_SCANCODE_STOP = 120, SDL_SCANCODE_AGAIN = 121, SDL_SCANCODE_UNDO = 122, SDL_SCANCODE_CUT = 123, SDL_SCANCODE_COPY = 124, SDL_SCANCODE_PASTE = 125, SDL_SCANCODE_FIND = 126, SDL_SCANCODE_MUTE = 127, SDL_SCANCODE_VOLUMEUP = 128, SDL_SCANCODE_VOLUMEDOWN = 129, SDL_SCANCODE_KP_COMMA = 133, SDL_SCANCODE_KP_EQUALSAS400 = 134, SDL_SCANCODE_INTERNATIONAL1 = 135, SDL_SCANCODE_INTERNATIONAL2 = 136, SDL_SCANCODE_INTERNATIONAL3 = 137, SDL_SCANCODE_INTERNATIONAL4 = 138, SDL_SCANCODE_INTERNATIONAL5 = 139, SDL_SCANCODE_INTERNATIONAL6 = 140, SDL_SCANCODE_INTERNATIONAL7 = 141, SDL_SCANCODE_INTERNATIONAL8 = 142, SDL_SCANCODE_INTERNATIONAL9 = 143, SDL_SCANCODE_LANG1 = 144, SDL_SCANCODE_LANG2 = 145, SDL_SCANCODE_LANG3 = 146, SDL_SCANCODE_LANG4 = 147, SDL_SCANCODE_LANG5 = 148, SDL_SCANCODE_LANG6 = 149, SDL_SCANCODE_LANG7 = 150, SDL_SCANCODE_LANG8 = 151, SDL_SCANCODE_LANG9 = 152, SDL_SCANCODE_ALTERASE = 153, SDL_SCANCODE_SYSREQ = 154, SDL_SCANCODE_CANCEL = 155, SDL_SCANCODE_CLEAR = 156, SDL_SCANCODE_PRIOR = 157, SDL_SCANCODE_RETURN2 = 158, SDL_SCANCODE_SEPARATOR = 159, SDL_SCANCODE_OUT = 160, SDL_SCANCODE_OPER = 161, SDL_SCANCODE_CLEARAGAIN = 162, SDL_SCANCODE_CRSEL = 163, SDL_SCANCODE_EXSEL = 164, SDL_SCANCODE_KP_00 = 176, SDL_SCANCODE_KP_000 = 177, SDL_SCANCODE_THOUSANDSSEPARATOR = 178, SDL_SCANCODE_DECIMALSEPARATOR = 179, SDL_SCANCODE_CURRENCYUNIT = 180, SDL_SCANCODE_CURRENCYSUBUNIT = 181, SDL_SCANCODE_KP_LEFTPAREN = 182, SDL_SCANCODE_KP_RIGHTPAREN = 183, SDL_SCANCODE_KP_LEFTBRACE = 184, SDL_SCANCODE_KP_RIGHTBRACE = 185, SDL_SCANCODE_KP_TAB = 186, SDL_SCANCODE_KP_BACKSPACE = 187, SDL_SCANCODE_KP_A = 188, SDL_SCANCODE_KP_B = 189, SDL_SCANCODE_KP_C = 190, SDL_SCANCODE_KP_D = 191, SDL_SCANCODE_KP_E = 192, SDL_SCANCODE_KP_F = 193, SDL_SCANCODE_KP_XOR = 194, SDL_SCANCODE_KP_POWER = 195, SDL_SCANCODE_KP_PERCENT = 196, SDL_SCANCODE_KP_LESS = 197, SDL_SCANCODE_KP_GREATER = 198, SDL_SCANCODE_KP_AMPERSAND = 199, SDL_SCANCODE_KP_DBLAMPERSAND = 200, SDL_SCANCODE_KP_VERTICALBAR = 201, SDL_SCANCODE_KP_DBLVERTICALBAR = 202, SDL_SCANCODE_KP_COLON = 203, SDL_SCANCODE_KP_HASH = 204, SDL_SCANCODE_KP_SPACE = 205, SDL_SCANCODE_KP_AT = 206, SDL_SCANCODE_KP_EXCLAM = 207, SDL_SCANCODE_KP_MEMSTORE = 208, SDL_SCANCODE_KP_MEMRECALL = 209, SDL_SCANCODE_KP_MEMCLEAR = 210, SDL_SCANCODE_KP_MEMADD = 211, SDL_SCANCODE_KP_MEMSUBTRACT = 212, SDL_SCANCODE_KP_MEMMULTIPLY = 213, SDL_SCANCODE_KP_MEMDIVIDE = 214, SDL_SCANCODE_KP_PLUSMINUS = 215, SDL_SCANCODE_KP_CLEAR = 216, SDL_SCANCODE_KP_CLEARENTRY = 217, SDL_SCANCODE_KP_BINARY = 218, SDL_SCANCODE_KP_OCTAL = 219, SDL_SCANCODE_KP_DECIMAL = 220, SDL_SCANCODE_KP_HEXADECIMAL = 221, SDL_SCANCODE_LCTRL = 224, SDL_SCANCODE_LSHIFT = 225, SDL_SCANCODE_LALT = 226, SDL_SCANCODE_LGUI = 227, SDL_SCANCODE_RCTRL = 228, SDL_SCANCODE_RSHIFT = 229, SDL_SCANCODE_RALT = 230, SDL_SCANCODE_RGUI = 231, SDL_SCANCODE_MODE = 257, SDL_SCANCODE_AUDIONEXT = 258, SDL_SCANCODE_AUDIOPREV = 259, SDL_SCANCODE_AUDIOSTOP = 260, SDL_SCANCODE_AUDIOPLAY = 261, SDL_SCANCODE_AUDIOMUTE = 262, SDL_SCANCODE_MEDIASELECT = 263, SDL_SCANCODE_WWW = 264, SDL_SCANCODE_MAIL = 265, SDL_SCANCODE_CALCULATOR = 266, SDL_SCANCODE_COMPUTER = 267, SDL_SCANCODE_AC_SEARCH = 268, SDL_SCANCODE_AC_HOME = 269, SDL_SCANCODE_AC_BACK = 270, SDL_SCANCODE_AC_FORWARD = 271, SDL_SCANCODE_AC_STOP = 272, SDL_SCANCODE_AC_REFRESH = 273, SDL_SCANCODE_AC_BOOKMARKS = 274, SDL_SCANCODE_BRIGHTNESSDOWN = 275, SDL_SCANCODE_BRIGHTNESSUP = 276, SDL_SCANCODE_DISPLAYSWITCH = 277, SDL_SCANCODE_KBDILLUMTOGGLE = 278, SDL_SCANCODE_KBDILLUMDOWN = 279, SDL_SCANCODE_KBDILLUMUP = 280, SDL_SCANCODE_EJECT = 281, SDL_SCANCODE_SLEEP = 282, SDL_SCANCODE_APP1 = 283, SDL_SCANCODE_APP2 = 284, SDL_NUM_SCANCODES = 512 } mixin(MakeEnum!SDL_Scancode); // SDL_keycode.h enum SDLK_SCANCODE_MASK = 1<<30; @nogc nothrow pure int SDL_SCANCODE_TO_KEYCODE(SDL_Scancode X) { return (X | SDLK_SCANCODE_MASK); } enum SDL_Keycode { SDLK_UNKNOWN = 0, SDLK_RETURN = '\r', SDLK_ESCAPE = '\033', SDLK_BACKSPACE = '\b', SDLK_TAB = '\t', SDLK_SPACE = ' ', SDLK_EXCLAIM = '!', SDLK_QUOTEDBL = '"', SDLK_HASH = '#', SDLK_PERCENT = '%', SDLK_DOLLAR = '$', SDLK_AMPERSAND = '&', SDLK_QUOTE = '\'', SDLK_LEFTPAREN = '(', SDLK_RIGHTPAREN = ')', SDLK_ASTERISK = '*', SDLK_PLUS = '+', SDLK_COMMA = ',', SDLK_MINUS = '-', SDLK_PERIOD = '.', SDLK_SLASH = '/', SDLK_0 = '0', SDLK_1 = '1', SDLK_2 = '2', SDLK_3 = '3', SDLK_4 = '4', SDLK_5 = '5', SDLK_6 = '6', SDLK_7 = '7', SDLK_8 = '8', SDLK_9 = '9', SDLK_COLON = ':', SDLK_SEMICOLON = ';', SDLK_LESS = '<', SDLK_EQUALS = '=', SDLK_GREATER = '>', SDLK_QUESTION = '?', SDLK_AT = '@', SDLK_LEFTBRACKET = '[', SDLK_BACKSLASH = '\\', SDLK_RIGHTBRACKET = ']', SDLK_CARET = '^', SDLK_UNDERSCORE = '_', SDLK_BACKQUOTE = '`', SDLK_a = 'a', SDLK_b = 'b', SDLK_c = 'c', SDLK_d = 'd', SDLK_e = 'e', SDLK_f = 'f', SDLK_g = 'g', SDLK_h = 'h', SDLK_i = 'i', SDLK_j = 'j', SDLK_k = 'k', SDLK_l = 'l', SDLK_m = 'm', SDLK_n = 'n', SDLK_o = 'o', SDLK_p = 'p', SDLK_q = 'q', SDLK_r = 'r', SDLK_s = 's', SDLK_t = 't', SDLK_u = 'u', SDLK_v = 'v', SDLK_w = 'w', SDLK_x = 'x', SDLK_y = 'y', SDLK_z = 'z', SDLK_CAPSLOCK = SDL_SCANCODE_TO_KEYCODE(SDL_Scancode.SDL_SCANCODE_CAPSLOCK), SDLK_F1 = SDL_SCANCODE_TO_KEYCODE(SDL_Scancode.SDL_SCANCODE_F1), SDLK_F2 = SDL_SCANCODE_TO_KEYCODE(SDL_Scancode.SDL_SCANCODE_F2), SDLK_F3 = SDL_SCANCODE_TO_KEYCODE(SDL_Scancode.SDL_SCANCODE_F3), SDLK_F4 = SDL_SCANCODE_TO_KEYCODE(SDL_Scancode.SDL_SCANCODE_F4), SDLK_F5 = SDL_SCANCODE_TO_KEYCODE(SDL_Scancode.SDL_SCANCODE_F5), SDLK_F6 = SDL_SCANCODE_TO_KEYCODE(SDL_Scancode.SDL_SCANCODE_F6), SDLK_F7 = SDL_SCANCODE_TO_KEYCODE(SDL_Scancode.SDL_SCANCODE_F7), SDLK_F8 = SDL_SCANCODE_TO_KEYCODE(SDL_Scancode.SDL_SCANCODE_F8), SDLK_F9 = SDL_SCANCODE_TO_KEYCODE(SDL_Scancode.SDL_SCANCODE_F9), SDLK_F10 = SDL_SCANCODE_TO_KEYCODE(SDL_Scancode.SDL_SCANCODE_F10), SDLK_F11 = SDL_SCANCODE_TO_KEYCODE(SDL_Scancode.SDL_SCANCODE_F11), SDLK_F12 = SDL_SCANCODE_TO_KEYCODE(SDL_Scancode.SDL_SCANCODE_F12), SDLK_PRINTSCREEN = SDL_SCANCODE_TO_KEYCODE(SDL_Scancode.SDL_SCANCODE_PRINTSCREEN), SDLK_SCROLLLOCK = SDL_SCANCODE_TO_KEYCODE(SDL_Scancode.SDL_SCANCODE_SCROLLLOCK), SDLK_PAUSE = SDL_SCANCODE_TO_KEYCODE(SDL_Scancode.SDL_SCANCODE_PAUSE), SDLK_INSERT = SDL_SCANCODE_TO_KEYCODE(SDL_Scancode.SDL_SCANCODE_INSERT), SDLK_HOME = SDL_SCANCODE_TO_KEYCODE(SDL_Scancode.SDL_SCANCODE_HOME), SDLK_PAGEUP = SDL_SCANCODE_TO_KEYCODE(SDL_Scancode.SDL_SCANCODE_PAGEUP), SDLK_DELETE = '\177', SDLK_END = SDL_SCANCODE_TO_KEYCODE(SDL_Scancode.SDL_SCANCODE_END), SDLK_PAGEDOWN = SDL_SCANCODE_TO_KEYCODE(SDL_Scancode.SDL_SCANCODE_PAGEDOWN), SDLK_RIGHT = SDL_SCANCODE_TO_KEYCODE(SDL_Scancode.SDL_SCANCODE_RIGHT), SDLK_LEFT = SDL_SCANCODE_TO_KEYCODE(SDL_Scancode.SDL_SCANCODE_LEFT), SDLK_DOWN = SDL_SCANCODE_TO_KEYCODE(SDL_Scancode.SDL_SCANCODE_DOWN), SDLK_UP = SDL_SCANCODE_TO_KEYCODE(SDL_Scancode.SDL_SCANCODE_UP), SDLK_NUMLOCKCLEAR = SDL_SCANCODE_TO_KEYCODE(SDL_Scancode.SDL_SCANCODE_NUMLOCKCLEAR), SDLK_KP_DIVIDE = SDL_SCANCODE_TO_KEYCODE(SDL_Scancode.SDL_SCANCODE_KP_DIVIDE), SDLK_KP_MULTIPLY = SDL_SCANCODE_TO_KEYCODE(SDL_Scancode.SDL_SCANCODE_KP_MULTIPLY), SDLK_KP_MINUS = SDL_SCANCODE_TO_KEYCODE(SDL_Scancode.SDL_SCANCODE_KP_MINUS), SDLK_KP_PLUS = SDL_SCANCODE_TO_KEYCODE(SDL_Scancode.SDL_SCANCODE_KP_PLUS), SDLK_KP_ENTER = SDL_SCANCODE_TO_KEYCODE(SDL_Scancode.SDL_SCANCODE_KP_ENTER), SDLK_KP_1 = SDL_SCANCODE_TO_KEYCODE(SDL_Scancode.SDL_SCANCODE_KP_1), SDLK_KP_2 = SDL_SCANCODE_TO_KEYCODE(SDL_Scancode.SDL_SCANCODE_KP_2), SDLK_KP_3 = SDL_SCANCODE_TO_KEYCODE(SDL_Scancode.SDL_SCANCODE_KP_3), SDLK_KP_4 = SDL_SCANCODE_TO_KEYCODE(SDL_Scancode.SDL_SCANCODE_KP_4), SDLK_KP_5 = SDL_SCANCODE_TO_KEYCODE(SDL_Scancode.SDL_SCANCODE_KP_5), SDLK_KP_6 = SDL_SCANCODE_TO_KEYCODE(SDL_Scancode.SDL_SCANCODE_KP_6), SDLK_KP_7 = SDL_SCANCODE_TO_KEYCODE(SDL_Scancode.SDL_SCANCODE_KP_7), SDLK_KP_8 = SDL_SCANCODE_TO_KEYCODE(SDL_Scancode.SDL_SCANCODE_KP_8), SDLK_KP_9 = SDL_SCANCODE_TO_KEYCODE(SDL_Scancode.SDL_SCANCODE_KP_9), SDLK_KP_0 = SDL_SCANCODE_TO_KEYCODE(SDL_Scancode.SDL_SCANCODE_KP_0), SDLK_KP_PERIOD = SDL_SCANCODE_TO_KEYCODE(SDL_Scancode.SDL_SCANCODE_KP_PERIOD), SDLK_APPLICATION = SDL_SCANCODE_TO_KEYCODE(SDL_Scancode.SDL_SCANCODE_APPLICATION), SDLK_POWER = SDL_SCANCODE_TO_KEYCODE(SDL_Scancode.SDL_SCANCODE_POWER), SDLK_KP_EQUALS = SDL_SCANCODE_TO_KEYCODE(SDL_Scancode.SDL_SCANCODE_KP_EQUALS), SDLK_F13 = SDL_SCANCODE_TO_KEYCODE(SDL_Scancode.SDL_SCANCODE_F13), SDLK_F14 = SDL_SCANCODE_TO_KEYCODE(SDL_Scancode.SDL_SCANCODE_F14), SDLK_F15 = SDL_SCANCODE_TO_KEYCODE(SDL_Scancode.SDL_SCANCODE_F15), SDLK_F16 = SDL_SCANCODE_TO_KEYCODE(SDL_Scancode.SDL_SCANCODE_F16), SDLK_F17 = SDL_SCANCODE_TO_KEYCODE(SDL_Scancode.SDL_SCANCODE_F17), SDLK_F18 = SDL_SCANCODE_TO_KEYCODE(SDL_Scancode.SDL_SCANCODE_F18), SDLK_F19 = SDL_SCANCODE_TO_KEYCODE(SDL_Scancode.SDL_SCANCODE_F19), SDLK_F20 = SDL_SCANCODE_TO_KEYCODE(SDL_Scancode.SDL_SCANCODE_F20), SDLK_F21 = SDL_SCANCODE_TO_KEYCODE(SDL_Scancode.SDL_SCANCODE_F21), SDLK_F22 = SDL_SCANCODE_TO_KEYCODE(SDL_Scancode.SDL_SCANCODE_F22), SDLK_F23 = SDL_SCANCODE_TO_KEYCODE(SDL_Scancode.SDL_SCANCODE_F23), SDLK_F24 = SDL_SCANCODE_TO_KEYCODE(SDL_Scancode.SDL_SCANCODE_F24), SDLK_EXECUTE = SDL_SCANCODE_TO_KEYCODE(SDL_Scancode.SDL_SCANCODE_EXECUTE), SDLK_HELP = SDL_SCANCODE_TO_KEYCODE(SDL_Scancode.SDL_SCANCODE_HELP), SDLK_MENU = SDL_SCANCODE_TO_KEYCODE(SDL_Scancode.SDL_SCANCODE_MENU), SDLK_SELECT = SDL_SCANCODE_TO_KEYCODE(SDL_Scancode.SDL_SCANCODE_SELECT), SDLK_STOP = SDL_SCANCODE_TO_KEYCODE(SDL_Scancode.SDL_SCANCODE_STOP), SDLK_AGAIN = SDL_SCANCODE_TO_KEYCODE(SDL_Scancode.SDL_SCANCODE_AGAIN), SDLK_UNDO = SDL_SCANCODE_TO_KEYCODE(SDL_Scancode.SDL_SCANCODE_UNDO), SDLK_CUT = SDL_SCANCODE_TO_KEYCODE(SDL_Scancode.SDL_SCANCODE_CUT), SDLK_COPY = SDL_SCANCODE_TO_KEYCODE(SDL_Scancode.SDL_SCANCODE_COPY), SDLK_PASTE = SDL_SCANCODE_TO_KEYCODE(SDL_Scancode.SDL_SCANCODE_PASTE), SDLK_FIND = SDL_SCANCODE_TO_KEYCODE(SDL_Scancode.SDL_SCANCODE_FIND), SDLK_MUTE = SDL_SCANCODE_TO_KEYCODE(SDL_Scancode.SDL_SCANCODE_MUTE), SDLK_VOLUMEUP = SDL_SCANCODE_TO_KEYCODE(SDL_Scancode.SDL_SCANCODE_VOLUMEUP), SDLK_VOLUMEDOWN = SDL_SCANCODE_TO_KEYCODE(SDL_Scancode.SDL_SCANCODE_VOLUMEDOWN), SDLK_KP_COMMA = SDL_SCANCODE_TO_KEYCODE(SDL_Scancode.SDL_SCANCODE_KP_COMMA), SDLK_KP_EQUALSAS400 = SDL_SCANCODE_TO_KEYCODE(SDL_Scancode.SDL_SCANCODE_KP_EQUALSAS400), SDLK_ALTERASE = SDL_SCANCODE_TO_KEYCODE(SDL_Scancode.SDL_SCANCODE_ALTERASE), SDLK_SYSREQ = SDL_SCANCODE_TO_KEYCODE(SDL_Scancode.SDL_SCANCODE_SYSREQ), SDLK_CANCEL = SDL_SCANCODE_TO_KEYCODE(SDL_Scancode.SDL_SCANCODE_CANCEL), SDLK_CLEAR = SDL_SCANCODE_TO_KEYCODE(SDL_Scancode.SDL_SCANCODE_CLEAR), SDLK_PRIOR = SDL_SCANCODE_TO_KEYCODE(SDL_Scancode.SDL_SCANCODE_PRIOR), SDLK_RETURN2 = SDL_SCANCODE_TO_KEYCODE(SDL_Scancode.SDL_SCANCODE_RETURN2), SDLK_SEPARATOR = SDL_SCANCODE_TO_KEYCODE(SDL_Scancode.SDL_SCANCODE_SEPARATOR), SDLK_OUT = SDL_SCANCODE_TO_KEYCODE(SDL_Scancode.SDL_SCANCODE_OUT), SDLK_OPER = SDL_SCANCODE_TO_KEYCODE(SDL_Scancode.SDL_SCANCODE_OPER), SDLK_CLEARAGAIN = SDL_SCANCODE_TO_KEYCODE(SDL_Scancode.SDL_SCANCODE_CLEARAGAIN), SDLK_CRSEL = SDL_SCANCODE_TO_KEYCODE(SDL_Scancode.SDL_SCANCODE_CRSEL), SDLK_EXSEL = SDL_SCANCODE_TO_KEYCODE(SDL_Scancode.SDL_SCANCODE_EXSEL), SDLK_KP_00 = SDL_SCANCODE_TO_KEYCODE(SDL_Scancode.SDL_SCANCODE_KP_00), SDLK_KP_000 = SDL_SCANCODE_TO_KEYCODE(SDL_Scancode.SDL_SCANCODE_KP_000), SDLK_THOUSANDSSEPARATOR = SDL_SCANCODE_TO_KEYCODE(SDL_Scancode.SDL_SCANCODE_THOUSANDSSEPARATOR), SDLK_DECIMALSEPARATOR = SDL_SCANCODE_TO_KEYCODE(SDL_Scancode.SDL_SCANCODE_DECIMALSEPARATOR), SDLK_CURRENCYUNIT = SDL_SCANCODE_TO_KEYCODE(SDL_Scancode.SDL_SCANCODE_CURRENCYUNIT), SDLK_CURRENCYSUBUNIT = SDL_SCANCODE_TO_KEYCODE(SDL_Scancode.SDL_SCANCODE_CURRENCYSUBUNIT), SDLK_KP_LEFTPAREN = SDL_SCANCODE_TO_KEYCODE(SDL_Scancode.SDL_SCANCODE_KP_LEFTPAREN), SDLK_KP_RIGHTPAREN = SDL_SCANCODE_TO_KEYCODE(SDL_Scancode.SDL_SCANCODE_KP_RIGHTPAREN), SDLK_KP_LEFTBRACE = SDL_SCANCODE_TO_KEYCODE(SDL_Scancode.SDL_SCANCODE_KP_LEFTBRACE), SDLK_KP_RIGHTBRACE = SDL_SCANCODE_TO_KEYCODE(SDL_Scancode.SDL_SCANCODE_KP_RIGHTBRACE), SDLK_KP_TAB = SDL_SCANCODE_TO_KEYCODE(SDL_Scancode.SDL_SCANCODE_KP_TAB), SDLK_KP_BACKSPACE = SDL_SCANCODE_TO_KEYCODE(SDL_Scancode.SDL_SCANCODE_KP_BACKSPACE), SDLK_KP_A = SDL_SCANCODE_TO_KEYCODE(SDL_Scancode.SDL_SCANCODE_KP_A), SDLK_KP_B = SDL_SCANCODE_TO_KEYCODE(SDL_Scancode.SDL_SCANCODE_KP_B), SDLK_KP_C = SDL_SCANCODE_TO_KEYCODE(SDL_Scancode.SDL_SCANCODE_KP_C), SDLK_KP_D = SDL_SCANCODE_TO_KEYCODE(SDL_Scancode.SDL_SCANCODE_KP_D), SDLK_KP_E = SDL_SCANCODE_TO_KEYCODE(SDL_Scancode.SDL_SCANCODE_KP_E), SDLK_KP_F = SDL_SCANCODE_TO_KEYCODE(SDL_Scancode.SDL_SCANCODE_KP_F), SDLK_KP_XOR = SDL_SCANCODE_TO_KEYCODE(SDL_Scancode.SDL_SCANCODE_KP_XOR), SDLK_KP_POWER = SDL_SCANCODE_TO_KEYCODE(SDL_Scancode.SDL_SCANCODE_KP_POWER), SDLK_KP_PERCENT = SDL_SCANCODE_TO_KEYCODE(SDL_Scancode.SDL_SCANCODE_KP_PERCENT), SDLK_KP_LESS = SDL_SCANCODE_TO_KEYCODE(SDL_Scancode.SDL_SCANCODE_KP_LESS), SDLK_KP_GREATER = SDL_SCANCODE_TO_KEYCODE(SDL_Scancode.SDL_SCANCODE_KP_GREATER), SDLK_KP_AMPERSAND = SDL_SCANCODE_TO_KEYCODE(SDL_Scancode.SDL_SCANCODE_KP_AMPERSAND), SDLK_KP_DBLAMPERSAND = SDL_SCANCODE_TO_KEYCODE(SDL_Scancode.SDL_SCANCODE_KP_DBLAMPERSAND), SDLK_KP_VERTICALBAR = SDL_SCANCODE_TO_KEYCODE(SDL_Scancode.SDL_SCANCODE_KP_VERTICALBAR), SDLK_KP_DBLVERTICALBAR = SDL_SCANCODE_TO_KEYCODE(SDL_Scancode.SDL_SCANCODE_KP_DBLVERTICALBAR), SDLK_KP_COLON = SDL_SCANCODE_TO_KEYCODE(SDL_Scancode.SDL_SCANCODE_KP_COLON), SDLK_KP_HASH = SDL_SCANCODE_TO_KEYCODE(SDL_Scancode.SDL_SCANCODE_KP_HASH), SDLK_KP_SPACE = SDL_SCANCODE_TO_KEYCODE(SDL_Scancode.SDL_SCANCODE_KP_SPACE), SDLK_KP_AT = SDL_SCANCODE_TO_KEYCODE(SDL_Scancode.SDL_SCANCODE_KP_AT), SDLK_KP_EXCLAM = SDL_SCANCODE_TO_KEYCODE(SDL_Scancode.SDL_SCANCODE_KP_EXCLAM), SDLK_KP_MEMSTORE = SDL_SCANCODE_TO_KEYCODE(SDL_Scancode.SDL_SCANCODE_KP_MEMSTORE), SDLK_KP_MEMRECALL = SDL_SCANCODE_TO_KEYCODE(SDL_Scancode.SDL_SCANCODE_KP_MEMRECALL), SDLK_KP_MEMCLEAR = SDL_SCANCODE_TO_KEYCODE(SDL_Scancode.SDL_SCANCODE_KP_MEMCLEAR), SDLK_KP_MEMADD = SDL_SCANCODE_TO_KEYCODE(SDL_Scancode.SDL_SCANCODE_KP_MEMADD), SDLK_KP_MEMSUBTRACT = SDL_SCANCODE_TO_KEYCODE(SDL_Scancode.SDL_SCANCODE_KP_MEMSUBTRACT), SDLK_KP_MEMMULTIPLY = SDL_SCANCODE_TO_KEYCODE(SDL_Scancode.SDL_SCANCODE_KP_MEMMULTIPLY), SDLK_KP_MEMDIVIDE = SDL_SCANCODE_TO_KEYCODE(SDL_Scancode.SDL_SCANCODE_KP_MEMDIVIDE), SDLK_KP_PLUSMINUS = SDL_SCANCODE_TO_KEYCODE(SDL_Scancode.SDL_SCANCODE_KP_PLUSMINUS), SDLK_KP_CLEAR = SDL_SCANCODE_TO_KEYCODE(SDL_Scancode.SDL_SCANCODE_KP_CLEAR), SDLK_KP_CLEARENTRY = SDL_SCANCODE_TO_KEYCODE(SDL_Scancode.SDL_SCANCODE_KP_CLEARENTRY), SDLK_KP_BINARY = SDL_SCANCODE_TO_KEYCODE(SDL_Scancode.SDL_SCANCODE_KP_BINARY), SDLK_KP_OCTAL = SDL_SCANCODE_TO_KEYCODE(SDL_Scancode.SDL_SCANCODE_KP_OCTAL), SDLK_KP_DECIMAL = SDL_SCANCODE_TO_KEYCODE(SDL_Scancode.SDL_SCANCODE_KP_DECIMAL), SDLK_KP_HEXADECIMAL = SDL_SCANCODE_TO_KEYCODE(SDL_Scancode.SDL_SCANCODE_KP_HEXADECIMAL), SDLK_LCTRL = SDL_SCANCODE_TO_KEYCODE(SDL_Scancode.SDL_SCANCODE_LCTRL), SDLK_LSHIFT = SDL_SCANCODE_TO_KEYCODE(SDL_Scancode.SDL_SCANCODE_LSHIFT), SDLK_LALT = SDL_SCANCODE_TO_KEYCODE(SDL_Scancode.SDL_SCANCODE_LALT), SDLK_LGUI = SDL_SCANCODE_TO_KEYCODE(SDL_Scancode.SDL_SCANCODE_LGUI), SDLK_RCTRL = SDL_SCANCODE_TO_KEYCODE(SDL_Scancode.SDL_SCANCODE_RCTRL), SDLK_RSHIFT = SDL_SCANCODE_TO_KEYCODE(SDL_Scancode.SDL_SCANCODE_RSHIFT), SDLK_RALT = SDL_SCANCODE_TO_KEYCODE(SDL_Scancode.SDL_SCANCODE_RALT), SDLK_RGUI = SDL_SCANCODE_TO_KEYCODE(SDL_Scancode.SDL_SCANCODE_RGUI), SDLK_MODE = SDL_SCANCODE_TO_KEYCODE(SDL_Scancode.SDL_SCANCODE_MODE), SDLK_AUDIONEXT = SDL_SCANCODE_TO_KEYCODE(SDL_Scancode.SDL_SCANCODE_AUDIONEXT), SDLK_AUDIOPREV = SDL_SCANCODE_TO_KEYCODE(SDL_Scancode.SDL_SCANCODE_AUDIOPREV), SDLK_AUDIOSTOP = SDL_SCANCODE_TO_KEYCODE(SDL_Scancode.SDL_SCANCODE_AUDIOSTOP), SDLK_AUDIOPLAY = SDL_SCANCODE_TO_KEYCODE(SDL_Scancode.SDL_SCANCODE_AUDIOPLAY), SDLK_AUDIOMUTE = SDL_SCANCODE_TO_KEYCODE(SDL_Scancode.SDL_SCANCODE_AUDIOMUTE), SDLK_MEDIASELECT = SDL_SCANCODE_TO_KEYCODE(SDL_Scancode.SDL_SCANCODE_MEDIASELECT), SDLK_WWW = SDL_SCANCODE_TO_KEYCODE(SDL_Scancode.SDL_SCANCODE_WWW), SDLK_MAIL = SDL_SCANCODE_TO_KEYCODE(SDL_Scancode.SDL_SCANCODE_MAIL), SDLK_CALCULATOR = SDL_SCANCODE_TO_KEYCODE(SDL_Scancode.SDL_SCANCODE_CALCULATOR), SDLK_COMPUTER = SDL_SCANCODE_TO_KEYCODE(SDL_Scancode.SDL_SCANCODE_COMPUTER), SDLK_AC_SEARCH = SDL_SCANCODE_TO_KEYCODE(SDL_Scancode.SDL_SCANCODE_AC_SEARCH), SDLK_AC_HOME = SDL_SCANCODE_TO_KEYCODE(SDL_Scancode.SDL_SCANCODE_AC_HOME), SDLK_AC_BACK = SDL_SCANCODE_TO_KEYCODE(SDL_Scancode.SDL_SCANCODE_AC_BACK), SDLK_AC_FORWARD = SDL_SCANCODE_TO_KEYCODE(SDL_Scancode.SDL_SCANCODE_AC_FORWARD), SDLK_AC_STOP = SDL_SCANCODE_TO_KEYCODE(SDL_Scancode.SDL_SCANCODE_AC_STOP), SDLK_AC_REFRESH = SDL_SCANCODE_TO_KEYCODE(SDL_Scancode.SDL_SCANCODE_AC_REFRESH), SDLK_AC_BOOKMARKS = SDL_SCANCODE_TO_KEYCODE(SDL_Scancode.SDL_SCANCODE_AC_BOOKMARKS), SDLK_BRIGHTNESSDOWN = SDL_SCANCODE_TO_KEYCODE(SDL_Scancode.SDL_SCANCODE_BRIGHTNESSDOWN), SDLK_BRIGHTNESSUP = SDL_SCANCODE_TO_KEYCODE(SDL_Scancode.SDL_SCANCODE_BRIGHTNESSUP), SDLK_DISPLAYSWITCH = SDL_SCANCODE_TO_KEYCODE(SDL_Scancode.SDL_SCANCODE_DISPLAYSWITCH), SDLK_KBDILLUMTOGGLE = SDL_SCANCODE_TO_KEYCODE(SDL_Scancode.SDL_SCANCODE_KBDILLUMTOGGLE), SDLK_KBDILLUMDOWN = SDL_SCANCODE_TO_KEYCODE(SDL_Scancode.SDL_SCANCODE_KBDILLUMDOWN), SDLK_KBDILLUMUP = SDL_SCANCODE_TO_KEYCODE(SDL_Scancode.SDL_SCANCODE_KBDILLUMUP), SDLK_EJECT = SDL_SCANCODE_TO_KEYCODE(SDL_Scancode.SDL_SCANCODE_EJECT), SDLK_SLEEP = SDL_SCANCODE_TO_KEYCODE(SDL_Scancode.SDL_SCANCODE_SLEEP) } mixin(MakeEnum!SDL_Keycode); enum SDL_Keymod { KMOD_NONE = 0x0000, KMOD_LSHIFT = 0x0001, KMOD_RSHIFT = 0x0002, KMOD_LCTRL = 0x0040, KMOD_RCTRL = 0x0080, KMOD_LALT = 0x0100, KMOD_RALT = 0x0200, KMOD_LGUI = 0x0400, KMOD_RGUI = 0x0800, KMOD_NUM = 0x1000, KMOD_CAPS = 0x2000, KMOD_MODE = 0x4000, KMOD_RESERVED = 0x8000, KMOD_CTRL = (KMOD_LCTRL|KMOD_RCTRL), KMOD_SHIFT = (KMOD_LSHIFT|KMOD_RSHIFT), KMOD_ALT = (KMOD_LALT|KMOD_RALT), KMOD_GUI = (KMOD_LGUI|KMOD_RGUI), } mixin(MakeEnum!SDL_Keymod); // SDL_log.h enum SDL_MAX_LOG_MESSAGE = 4096; enum { SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_CATEGORY_ERROR, SDL_LOG_CATEGORY_ASSERT, SDL_LOG_CATEGORY_SYSTEM, SDL_LOG_CATEGORY_AUDIO, SDL_LOG_CATEGORY_VIDEO, SDL_LOG_CATEGORY_RENDER, SDL_LOG_CATEGORY_INPUT, SDL_LOG_CATEGORY_RESERVED1, SDL_LOG_CATEGORY_RESERVED2, SDL_LOG_CATEGORY_RESERVED3, SDL_LOG_CATEGORY_RESERVED4, SDL_LOG_CATEGORY_RESERVED5, SDL_LOG_CATEGORY_RESERVED6, SDL_LOG_CATEGORY_RESERVED7, SDL_LOG_CATEGORY_RESERVED8, SDL_LOG_CATEGORY_RESERVED9, SDL_LOG_CATEGORY_RESERVED10, SDL_LOG_CATEGORY_CUSTOM } enum SDL_LogPriority { SDL_LOG_PRIORITY_VERBOSE = 1, SDL_LOG_PRIORITY_DEBUG, SDL_LOG_PRIORITY_INFO, SDL_LOG_PRIORITY_WARN, SDL_LOG_PRIORITY_ERROR, SDL_LOG_PRIORITY_CRITICAL, SDL_NUM_LOG_PRIORITIES } mixin(MakeEnum!SDL_LogPriority); extern(C) nothrow alias SDL_LogOutputFunction = void function(void*, int, SDL_LogPriority, const(char)*); // SDL_mouse.h struct SDL_Cursor; @nogc nothrow pure Uint8 SDL_BUTTON(Uint8 X) { return cast(Uint8)(1 << (X - 1)); } enum SDL_SystemCursor { SDL_SYSTEM_CURSOR_ARROW, SDL_SYSTEM_CURSOR_IBEAM, SDL_SYSTEM_CURSOR_WAIT, SDL_SYSTEM_CURSOR_CROSSHAIR, SDL_SYSTEM_CURSOR_WAITARROW, SDL_SYSTEM_CURSOR_SIZENWSE, SDL_SYSTEM_CURSOR_SIZENESW, SDL_SYSTEM_CURSOR_SIZEWE, SDL_SYSTEM_CURSOR_SIZENS, SDL_SYSTEM_CURSOR_SIZEALL, SDL_SYSTEM_CURSOR_NO, SDL_SYSTEM_CURSOR_HAND, SDL_NUM_SYSTEM_CURSORS } mixin(MakeEnum!SDL_SystemCursor); enum SDL_MouseWheelDirection { SDL_MOUSEWHEEL_NORMAL, SDL_MOUSEWHEEL_FLIPPED } mixin(MakeEnum!SDL_MouseWheelDirection); enum SDL_D_MouseButton : Uint8 { SDL_BUTTON_LEFT = 1, SDL_BUTTON_MIDDLE = 2, SDL_BUTTON_RIGHT = 3, SDL_BUTTON_X1 = 4, SDL_BUTTON_X2 = 5, SDL_BUTTON_LMASK = SDL_BUTTON(SDL_BUTTON_LEFT), SDL_BUTTON_MMASK = SDL_BUTTON(SDL_BUTTON_MIDDLE), SDL_BUTTON_RMASK = SDL_BUTTON(SDL_BUTTON_RIGHT), SDL_BUTTON_X1MASK = SDL_BUTTON(SDL_BUTTON_X1), SDL_BUTTON_X2MASK = SDL_BUTTON(SDL_BUTTON_X2), } mixin(MakeEnum!SDL_D_MouseButton); // SDL_pixels.h enum SDL_ALPHA_OPAQUE = 255; enum SDL_ALPHA_TRANSPARENT = 0; enum { SDL_PIXELTYPE_UNKNOWN, SDL_PIXELTYPE_INDEX1, SDL_PIXELTYPE_INDEX4, SDL_PIXELTYPE_INDEX8, SDL_PIXELTYPE_PACKED8, SDL_PIXELTYPE_PACKED16, SDL_PIXELTYPE_PACKED32, SDL_PIXELTYPE_ARRAYU8, SDL_PIXELTYPE_ARRAYU16, SDL_PIXELTYPE_ARRAYU32, SDL_PIXELTYPE_ARRAYF16, SDL_PIXELTYPE_ARRAYF32 } enum { SDL_BITMAPORDER_NONE, SDL_BITMAPORDER_4321, SDL_BITMAPORDER_1234 } enum { SDL_PACKEDORDER_NONE, SDL_PACKEDORDER_XRGB, SDL_PACKEDORDER_RGBX, SDL_PACKEDORDER_ARGB, SDL_PACKEDORDER_RGBA, SDL_PACKEDORDER_XBGR, SDL_PACKEDORDER_BGRX, SDL_PACKEDORDER_ABGR, SDL_PACKEDORDER_BGRA } enum { SDL_ARRAYORDER_NONE, SDL_ARRAYORDER_RGB, SDL_ARRAYORDER_RGBA, SDL_ARRAYORDER_ARGB, SDL_ARRAYORDER_BGR, SDL_ARRAYORDER_BGRA, SDL_ARRAYORDER_ABGR } enum { SDL_PACKEDLAYOUT_NONE, SDL_PACKEDLAYOUT_332, SDL_PACKEDLAYOUT_4444, SDL_PACKEDLAYOUT_1555, SDL_PACKEDLAYOUT_5551, SDL_PACKEDLAYOUT_565, SDL_PACKEDLAYOUT_8888, SDL_PACKEDLAYOUT_2101010, SDL_PACKEDLAYOUT_1010102 } alias SDL_DEFINE_PIXELFOURCC = SDL_FOURCC ; @nogc nothrow { Uint32 SDL_DEFINE_PIXELFORMAT(int type, int order, int layout, int bits, int bytes) { return (1<<28) | (type << 24) | (order << 20) | (layout << 16) | (bits << 8) | (bytes << 0); } Uint32 SDL_PIXELFLAG(Uint32 X) { return (X >> 28) & 0x0F; } Uint32 SDL_PIXELTYPE(Uint32 X) { return (X >> 24) & 0x0F; } Uint32 SDL_PIXELORDER(Uint32 X) { return (X >> 20) & 0x0F; } Uint32 SDL_PIXELLAYOUT(Uint32 X) { return (X >> 16) & 0x0F; } Uint32 SDL_BITSPERPIXEL(Uint32 X) { return (X >> 8) & 0xFF; } Uint32 SDL_BYTESPERPIXEL(Uint32 X) { if(SDL_ISPIXELFORMAT_FOURCC(X)) { if(X == SDL_PIXELFORMAT_YUY2 || X == SDL_PIXELFORMAT_UYVY || X == SDL_PIXELFORMAT_YVYU) return 2; else return 1; } else { return (X >> 0) & 0xFF; } } bool SDL_ISPIXELFORMAT_INDEXED(Uint32 format) { if(!SDL_ISPIXELFORMAT_FOURCC(format)) { auto pixelType = SDL_PIXELTYPE(format); return pixelType == SDL_PIXELTYPE_INDEX1 || pixelType == SDL_PIXELTYPE_INDEX4 || pixelType == SDL_PIXELTYPE_INDEX8; } return false; } bool SDL_ISPIXELFORMAT_PACKED(Uint32 format) { if(!SDL_ISPIXELFORMAT_FOURCC(format)) { auto pixelType = SDL_PIXELTYPE(format); return pixelType == SDL_PIXELTYPE_PACKED8 || pixelType == SDL_PIXELTYPE_PACKED16 || pixelType == SDL_PIXELTYPE_PACKED32; } return false; } bool SDL_ISPIXELFORMAT_ARRAY(Uint32 format) { if(!SDL_ISPIXELFORMAT_FOURCC(format)) { auto pixelType = SDL_PIXELTYPE(format); return pixelType == SDL_PIXELTYPE_ARRAYU8 || pixelType == SDL_PIXELTYPE_ARRAYU16 || pixelType == SDL_PIXELTYPE_ARRAYU32 || pixelType == SDL_PIXELTYPE_ARRAYF16 || pixelType == SDL_PIXELTYPE_ARRAYF32; } return false; } bool SDL_ISPIXELFORMAT_ALPHA(Uint32 format) { if(!SDL_ISPIXELFORMAT_FOURCC(format)) { auto pixelOrder = SDL_PIXELORDER(format); return ((SDL_ISPIXELFORMAT_PACKED(format) && (pixelOrder == SDL_PACKEDORDER_ARGB || pixelOrder == SDL_PACKEDORDER_RGBA || pixelOrder == SDL_PACKEDORDER_ABGR || pixelOrder == SDL_PACKEDORDER_BGRA)) || (SDL_ISPIXELFORMAT_ARRAY(format) && (pixelOrder == SDL_ARRAYORDER_ARGB || pixelOrder == SDL_ARRAYORDER_RGBA || pixelOrder == SDL_ARRAYORDER_ABGR || pixelOrder == SDL_ARRAYORDER_BGRA))); } return false; } bool SDL_ISPIXELFORMAT_FOURCC(Uint32 format) { return format && !(format & 0x80000000); } } enum { SDL_PIXELFORMAT_UNKNOWN, SDL_PIXELFORMAT_INDEX1LSB = SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_INDEX1, SDL_BITMAPORDER_4321, 0, 1, 0), SDL_PIXELFORMAT_INDEX1MSB = SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_INDEX1, SDL_BITMAPORDER_1234, 0, 1, 0), SDL_PIXELFORMAT_INDEX4LSB = SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_INDEX4, SDL_BITMAPORDER_4321, 0, 4, 0), SDL_PIXELFORMAT_INDEX4MSB = SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_INDEX4, SDL_BITMAPORDER_1234, 0, 4, 0), SDL_PIXELFORMAT_INDEX8 = SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_INDEX8, 0, 0, 8, 1), SDL_PIXELFORMAT_RGB332 = SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_PACKED8, SDL_PACKEDORDER_XRGB, SDL_PACKEDLAYOUT_332, 8, 1), SDL_PIXELFORMAT_RGB444 = SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_PACKED16, SDL_PACKEDORDER_XRGB, SDL_PACKEDLAYOUT_4444, 12, 2), SDL_PIXELFORMAT_RGB555 = SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_PACKED16, SDL_PACKEDORDER_XRGB, SDL_PACKEDLAYOUT_1555, 15, 2), SDL_PIXELFORMAT_BGR555 = SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_PACKED16, SDL_PACKEDORDER_XBGR, SDL_PACKEDLAYOUT_1555, 15, 2), SDL_PIXELFORMAT_ARGB4444 = SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_PACKED16, SDL_PACKEDORDER_ARGB, SDL_PACKEDLAYOUT_4444, 16, 2), SDL_PIXELFORMAT_RGBA4444 = SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_PACKED16, SDL_PACKEDORDER_RGBA, SDL_PACKEDLAYOUT_4444, 16, 2), SDL_PIXELFORMAT_ABGR4444 = SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_PACKED16, SDL_PACKEDORDER_ABGR, SDL_PACKEDLAYOUT_4444, 16, 2), SDL_PIXELFORMAT_BGRA4444 = SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_PACKED16, SDL_PACKEDORDER_BGRA, SDL_PACKEDLAYOUT_4444, 16, 2), SDL_PIXELFORMAT_ARGB1555 = SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_PACKED16, SDL_PACKEDORDER_ARGB, SDL_PACKEDLAYOUT_1555, 16, 2), SDL_PIXELFORMAT_RGBA5551 = SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_PACKED16, SDL_PACKEDORDER_RGBA, SDL_PACKEDLAYOUT_5551, 16, 2), SDL_PIXELFORMAT_ABGR1555 = SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_PACKED16, SDL_PACKEDORDER_ABGR, SDL_PACKEDLAYOUT_1555, 16, 2), SDL_PIXELFORMAT_BGRA5551 = SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_PACKED16, SDL_PACKEDORDER_BGRA, SDL_PACKEDLAYOUT_5551, 16, 2), SDL_PIXELFORMAT_RGB565 = SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_PACKED16, SDL_PACKEDORDER_XRGB, SDL_PACKEDLAYOUT_565, 16, 2), SDL_PIXELFORMAT_BGR565 = SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_PACKED16, SDL_PACKEDORDER_XBGR, SDL_PACKEDLAYOUT_565, 16, 2), SDL_PIXELFORMAT_RGB24 = SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_ARRAYU8, SDL_ARRAYORDER_RGB, 0, 24, 3), SDL_PIXELFORMAT_BGR24 = SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_ARRAYU8, SDL_ARRAYORDER_BGR, 0, 24, 3), SDL_PIXELFORMAT_RGB888 = SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_PACKED32, SDL_PACKEDORDER_XRGB, SDL_PACKEDLAYOUT_8888, 24, 4), SDL_PIXELFORMAT_RGBX8888 = SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_PACKED32, SDL_PACKEDORDER_RGBX, SDL_PACKEDLAYOUT_8888, 24, 4), SDL_PIXELFORMAT_BGR888 = SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_PACKED32, SDL_PACKEDORDER_XBGR, SDL_PACKEDLAYOUT_8888, 24, 4), SDL_PIXELFORMAT_BGRX8888 = SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_PACKED32, SDL_PACKEDORDER_BGRX, SDL_PACKEDLAYOUT_8888, 24, 4), SDL_PIXELFORMAT_ARGB8888 = SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_PACKED32, SDL_PACKEDORDER_ARGB, SDL_PACKEDLAYOUT_8888, 32, 4), SDL_PIXELFORMAT_RGBA8888 = SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_PACKED32, SDL_PACKEDORDER_RGBA, SDL_PACKEDLAYOUT_8888, 32, 4), SDL_PIXELFORMAT_ABGR8888 = SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_PACKED32, SDL_PACKEDORDER_ABGR, SDL_PACKEDLAYOUT_8888, 32, 4), SDL_PIXELFORMAT_BGRA8888 = SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_PACKED32, SDL_PACKEDORDER_BGRA, SDL_PACKEDLAYOUT_8888, 32, 4), SDL_PIXELFORMAT_ARGB2101010 = SDL_DEFINE_PIXELFORMAT(SDL_PIXELTYPE_PACKED32, SDL_PACKEDORDER_ARGB, SDL_PACKEDLAYOUT_2101010, 32, 4), SDL_PIXELFORMAT_YV12 = SDL_DEFINE_PIXELFOURCC('Y', 'V', '1', '2'), SDL_PIXELFORMAT_IYUV = SDL_DEFINE_PIXELFOURCC('I', 'Y', 'U', 'V'), SDL_PIXELFORMAT_YUY2 = SDL_DEFINE_PIXELFOURCC('Y', 'U', 'Y', '2'), SDL_PIXELFORMAT_UYVY = SDL_DEFINE_PIXELFOURCC('U', 'Y', 'V', 'Y'), SDL_PIXELFORMAT_YVYU = SDL_DEFINE_PIXELFOURCC('Y', 'V', 'Y', 'U'), SDL_PIXELFORMAT_NV12 = SDL_DEFINE_PIXELFOURCC('N', 'V', '1', '2'), SDL_PIXELFORMAT_NV21 = SDL_DEFINE_PIXELFOURCC('N', 'V', '2', '1') } static assert(SDL_PIXELFORMAT_BGRX8888 == 0x16661804); version(BigEndian) { alias SDL_PIXELFORMAT_RGBA32 = SDL_PIXELFORMAT_RGBA8888; alias SDL_PIXELFORMAT_ARGB32 = SDL_PIXELFORMAT_ARGB8888; alias SDL_PIXELFORMAT_BGRA32 = SDL_PIXELFORMAT_BGRA8888; alias SDL_PIXELFORMAT_ABGR32 = SDL_PIXELFORMAT_ABGR8888; } else { alias SDL_PIXELFORMAT_RGBA32 = SDL_PIXELFORMAT_ABGR8888; alias SDL_PIXELFORMAT_ARGB32 = SDL_PIXELFORMAT_BGRA8888; alias SDL_PIXELFORMAT_BGRA32 = SDL_PIXELFORMAT_ARGB8888; alias SDL_PIXELFORMAT_ABGR32 = SDL_PIXELFORMAT_RGBA8888; } struct SDL_Color { Uint8 r; Uint8 g; Uint8 b; Uint8 a; } struct SDL_Palette { int ncolors; SDL_Color* colors; // NOTE: original was named 'version' Uint32 _version; int refcount; } struct SDL_PixelFormat { Uint32 format; SDL_Palette *palette; Uint8 BitsPerPixel; Uint8 BytesPerPixel; Uint8[2] padding; Uint32 Rmask; Uint32 Gmask; Uint32 Bmask; Uint32 Amask; Uint8 Rloss; Uint8 Gloss; Uint8 Bloss; Uint8 Aloss; Uint8 Rshift; Uint8 Gshift; Uint8 Bshift; Uint8 Ashift; int refcount; SDL_PixelFormat* next; } // SDL_power.h enum SDL_PowerState { SDL_POWERSTATE_UNKNOWN, SDL_POWERSTATE_ON_BATTERY, SDL_POWERSTATE_NO_BATTERY, SDL_POWERSTATE_CHARGING, SDL_POWERSTATE_CHARGED } mixin(MakeEnum!SDL_PowerState); // SDL_rect.h struct SDL_Point { int x; int y; } struct SDL_Rect { int x, y; int w, h; } @nogc nothrow pure { bool SDL_PointInRect(const SDL_Point *p, const SDL_Rect *r) { return ((p.x >= r.x) && (p.x < (r.x + r.w)) && (p.y >= r.y) && (p.y < (r.y + r.h))); } bool SDL_RectEmpty(const(SDL_Rect)* X) { return !X || (X.w <= 0) || (X.h <= 0); } bool SDL_RectEquals(const(SDL_Rect)* A, const(SDL_Rect)* B) { return A && B && (A.x == B.x) && (A.y == B.y) && (A.w == B.w) && (A.h == B.h); } } // SDL_render.h enum SDL_RendererFlags : Uint32 { SDL_RENDERER_SOFTWARE = 0x00000001, SDL_RENDERER_ACCELERATED = 0x00000002, SDL_RENDERER_PRESENTVSYNC = 0x00000004, SDL_RENDERER_TARGETTEXTURE = 0x00000008, } mixin(MakeEnum!SDL_RendererFlags); struct SDL_RendererInfo { const(char)* name; SDL_RendererFlags flags; Uint32 num_texture_formats; Uint32[16] texture_formats; int max_texture_width; int max_texture_height; } enum SDL_TextureAccess { SDL_TEXTUREACCESS_STATIC, SDL_TEXTUREACCESS_STREAMING, SDL_TEXTUREACCESS_TARGET, } mixin(MakeEnum!SDL_TextureAccess); enum SDL_TextureModulate { SDL_TEXTUREMODULATE_NONE = 0x00000000, SDL_TEXTUREMODULATE_COLOR = 0x00000001, SDL_TEXTUREMODULATE_ALPHA = 0x00000002 } mixin(MakeEnum!SDL_TextureModulate); enum SDL_RendererFlip { SDL_FLIP_NONE = 0x00000000, SDL_FLIP_HORIZONTAL = 0x00000001, SDL_FLIP_VERTICAL = 0x00000002, } mixin(MakeEnum!SDL_RendererFlip); struct SDL_Renderer; struct SDL_Texture; // SDL_rwops.h enum : uint { SDL_RWOPS_UNKNOWN = 0, SDL_RWOPS_WINFILE = 1, SDL_RWOPS_STDFILE = 2, SDL_RWOPS_JNIFILE = 3, SDL_RWOPS_MEMORY = 4, SDL_RWOPS_MEMORY_RO = 5, } struct SDL_RWops { extern(C) @nogc nothrow { Sint64 function(SDL_RWops*) size; Sint64 function(SDL_RWops*, Sint64, int) seek; size_t function(SDL_RWops*, void*, size_t, size_t) read; size_t function(SDL_RWops*, const(void)*, size_t, size_t) write; int function(SDL_RWops*) close; } Uint32 type; union Hidden { // version(Android) version(Windows) { struct Windowsio { SDL_bool append; void* h; struct Buffer { void* data; size_t size; size_t left; } Buffer buffer; } Windowsio windowsio; } struct Stdio { SDL_bool autoclose; FILE* fp; } Stdio stdio; struct Mem { Uint8* base; Uint8* here; Uint8* stop; } Mem mem; struct Unknown { void* data1; } Unknown unknown; } Hidden hidden; } enum { RW_SEEK_SET = 0, RW_SEEK_CUR = 1, RW_SEEK_END = 2, } @nogc nothrow { Sint64 SDL_RWsize(SDL_RWops* ctx) { return ctx.size(ctx); } Sint64 SDL_RWseek(SDL_RWops* ctx, Sint64 offset, int whence) { return ctx.seek(ctx, offset, whence); } Sint64 SDL_RWtell(SDL_RWops* ctx) { return ctx.seek(ctx, 0, RW_SEEK_CUR); } size_t SDL_RWread(SDL_RWops* ctx, void* ptr, size_t size, size_t n) { return ctx.read(ctx, ptr, size, n); } size_t SDL_RWwrite(SDL_RWops* ctx, const(void)* ptr, size_t size, size_t n) { return ctx.write(ctx, ptr, size, n); } int SDL_RWclose(SDL_RWops* ctx) { return ctx.close(ctx); } } // SDL_shape.h enum { SDL_NONSHAPEABLE_WINDOW = -1, SDL_INVALID_SHAPE_ARGUMENT = -2, SDL_WINDOW_LACKS_SHAPE = -3, } enum WindowShapeMode { ShapeModeDefault, ShapeModeBinarizeAlpha, ShapeModeReverseBinarizeAlpha, ShapeModeColorKey } mixin(MakeEnum!WindowShapeMode); @nogc nothrow pure bool SDL_SHAPEMODEALPHA(WindowShapeMode mode) { return mode == ShapeModeDefault || mode == ShapeModeBinarizeAlpha || mode == ShapeModeReverseBinarizeAlpha; } union SDL_WindowShapeParams { Uint8 binarizationCutoff; SDL_Color colorKey; } struct SDL_WindowShapeMode { WindowShapeMode mode; SDL_WindowShapeParams parameters; } // SDL_surface.h enum SDL_D_SurfaceFlags { SDL_SWSURFACE = 0, SDL_PREALLOC = 0x00000001, SDL_RLEACCEL = 0x00000002, SDL_DONTFREE = 0x00000004, } mixin(MakeEnum!SDL_D_SurfaceFlags); @nogc nothrow pure bool SDL_MUSTLOCK(const(SDL_Surface)* S) { return (S.flags & SDL_RLEACCEL) != 0; } struct SDL_BlitMap; struct SDL_Surface { SDL_D_SurfaceFlags flags; SDL_PixelFormat* format; int w, h; int pitch; void* pixels; void* userdata; int locked; void* lock_data; SDL_Rect clip_rect; SDL_BlitMap* map; int refcount; } extern(C) nothrow alias SDL_blit = int function(SDL_Surface* src, SDL_Rect* srcrect, SDL_Surface* dst, SDL_Rect* dstrect); // SDL_system.h static if(Derelict_OS_Windows) { struct IDirect3DDevice9; } static if(Derelict_OS_iOS) { extern(C) nothrow alias SDL_iPhoneAnimationCallback = void function(void*); } static if(Derelict_OS_Android) { enum int SDL_ANDROID_EXTERNAL_STORAGE_READ = 0x01; enum int SDL_ANDROID_EXTERNAL_STORAGE_WRITE = 0x02; } static if(Derelict_OS_WinRT) { enum SDL_WinRT_Path { SDL_WINRT_PATH_INSTALLED_LOCATION, SDL_WINRT_PATH_LOCAL_FOLDER, SDL_WINRT_PATH_ROAMING_FOLDER, SDL_WINRT_PATH_TEMP_FOLDER } } // SDL_syswm.h enum SDL_SYSWM_TYPE { SDL_SYSWM_UNKNOWN, SDL_SYSWM_WINDOWS, SDL_SYSWM_X11, SDL_SYSWM_DIRECTFB, SDL_SYSWM_COCOA, SDL_SYSWM_UIKIT, SDL_SYSWM_WAYLAND, SDL_SYSWM_MIR, SDL_SYSWM_WINRT, SDL_SYSWM_ANDROID, SDL_SYSWM_VIVANTE, } mixin(MakeEnum!SDL_SYSWM_TYPE); static if(Derelict_OS_Windows) { // I don't want to import core.sys.windows.windows just for these version(Win64) { alias wparam = ulong; alias lparam = long; }else { alias wparam = uint; alias lparam = int; } } struct SDL_SysWMmsg { SDL_version version_; SDL_SYSWM_TYPE subsystem; union msg_ { static if(Derelict_OS_Windows) { struct win_ { void* hwnd; uint msg; wparam wParam; lparam lParam; } win_ win; } static if(Derelict_OS_WinRT) { struct winrt_ { void* window; } winrt_ winrt; } static if(Derelict_OS_Mac) { struct cocoa_ { int dummy; } cocoa_ cocoa; } static if(Derelict_OS_Posix) { // X11 unsupported for now struct x11_ { c_long[24] pad; // sufficient size for any X11 event } x11_ x11; } static if(Derelict_OS_Linux) { // DirectFB unsupported for now // Consequently SDL_SysWMmsg might have a different size that in SDL struct dfb_ { void* event; } dfb_ dfb; } int dummy; } msg_ msg; } struct SDL_SysWMinfo { SDL_version version_; // version is reserved in D SDL_SYSWM_TYPE subsystem; union info_ { static if(Derelict_OS_Windows) { struct win_ { void* window; void* hdc; } win_ win; } static if(Derelict_OS_WinRT) { struct winrt_ { void* window; } winrt_ winrt; } static if(Derelict_OS_Posix) { struct x11_ { void* display; uint window; } x11_ x11; } // TODO not too sure about all the Derelict_OS tests below. static if(Derelict_OS_Linux) { struct dfb_ { void *dfb; void *window; void *surface; } dfb_ dfb; struct wl_ { void *display; void *surface; void *shell_surface; } wl_ wl; struct mir_ { void *connection; void *surface; } mir_ mir; } static if(Derelict_OS_Mac || Derelict_OS_iOS) { struct cocoa_ { void* window; } cocoa_ cocoa; struct uikit_ { void *window; } uikit_ uikit; } } info_ info; } // SDL_timer.h extern(C) nothrow alias SDL_TimerCallback = Uint32 function(Uint32 interval, void* param); alias SDL_TimerID = int; @nogc nothrow pure bool SDL_TICKS_PASSED(Uint32 A, Uint32 B) { return cast(Sint32)(B - A) <= 0; } // SDL_touch.h alias SDL_TouchID = Sint64; alias SDL_FingerID = Sint64; struct SDL_Finger { SDL_FingerID id; float x; float y; float pressure; } enum SDL_TOUCH_MOUSEID = cast(Uint32)-1; // SDL_video.h struct SDL_DisplayMode { Uint32 format; int w; int h; int refresh_rate; void* driverdata; } struct SDL_Window; enum SDL_WindowFlags { SDL_WINDOW_FULLSCREEN = 0x00000001, SDL_WINDOW_OPENGL = 0x00000002, SDL_WINDOW_SHOWN = 0x00000004, SDL_WINDOW_HIDDEN = 0x00000008, SDL_WINDOW_BORDERLESS = 0x00000010, SDL_WINDOW_RESIZABLE = 0x00000020, SDL_WINDOW_MINIMIZED = 0x00000040, SDL_WINDOW_MAXIMIZED = 0x00000080, SDL_WINDOW_INPUT_GRABBED = 0x00000100, SDL_WINDOW_INPUT_FOCUS = 0x00000200, SDL_WINDOW_MOUSE_FOCUS = 0x00000400, SDL_WINDOW_FULLSCREEN_DESKTOP = SDL_WINDOW_FULLSCREEN | 0x00001000, SDL_WINDOW_FOREIGN = 0x00000800, SDL_WINDOW_ALLOW_HIGHDPI = 0x00002000, SDL_WINDOW_MOUSE_CAPTURE = 0x00004000, SDL_WINDOW_ALWAYS_ON_TOP = 0x00008000, SDL_WINDOW_SKIP_TASKBAR = 0x00010000, SDL_WINDOW_UTILITY = 0x00020000, SDL_WINDOW_TOOLTIP = 0x00040000, SDL_WINDOW_POPUP_MENU = 0x00080000, } mixin(MakeEnum!SDL_WindowFlags); enum { SDL_WINDOWPOS_UNDEFINED_MASK = 0x1FFF0000, SDL_WINDOWPOS_UNDEFINED = SDL_WINDOWPOS_UNDEFINED_DISPLAY(0), SDL_WINDOWPOS_CENTERED_MASK = 0x2FFF0000, SDL_WINDOWPOS_CENTERED = SDL_WINDOWPOS_CENTERED_DISPLAY(0), } @nogc nothrow pure { Uint32 SDL_WINDOWPOS_UNDEFINED_DISPLAY(Uint32 X) { return (SDL_WINDOWPOS_UNDEFINED_MASK | X); } bool SDL_WINDOWPOS_ISUNDEFINED(Uint32 X) { return (X & 0xFFFF0000) == SDL_WINDOWPOS_UNDEFINED_MASK; } Uint32 SDL_WINDOWPOS_CENTERED_DISPLAY(Uint32 X) { return (SDL_WINDOWPOS_CENTERED_MASK | X); } bool SDL_WINDOWPOS_ISCENTERED(Uint32 X) { return (X & 0xFFFF0000) == SDL_WINDOWPOS_CENTERED_MASK; } } enum SDL_WindowEventID : Uint8 { SDL_WINDOWEVENT_NONE, SDL_WINDOWEVENT_SHOWN, SDL_WINDOWEVENT_HIDDEN, SDL_WINDOWEVENT_EXPOSED, SDL_WINDOWEVENT_MOVED, SDL_WINDOWEVENT_RESIZED, SDL_WINDOWEVENT_SIZE_CHANGED, SDL_WINDOWEVENT_MINIMIZED, SDL_WINDOWEVENT_MAXIMIZED, SDL_WINDOWEVENT_RESTORED, SDL_WINDOWEVENT_ENTER, SDL_WINDOWEVENT_LEAVE, SDL_WINDOWEVENT_FOCUS_GAINED, SDL_WINDOWEVENT_FOCUS_LOST, SDL_WINDOWEVENT_CLOSE, SDL_WINDOWEVENT_TAKE_FOCUS, SDL_WINDOWEVENT_HIT_TEST, } mixin(MakeEnum!SDL_WindowEventID); alias SDL_GLContext = void*; enum SDL_GLattr { SDL_GL_RED_SIZE, SDL_GL_GREEN_SIZE, SDL_GL_BLUE_SIZE, SDL_GL_ALPHA_SIZE, SDL_GL_BUFFER_SIZE, SDL_GL_DOUBLEBUFFER, SDL_GL_DEPTH_SIZE, SDL_GL_STENCIL_SIZE, SDL_GL_ACCUM_RED_SIZE, SDL_GL_ACCUM_GREEN_SIZE, SDL_GL_ACCUM_BLUE_SIZE, SDL_GL_ACCUM_ALPHA_SIZE, SDL_GL_STEREO, SDL_GL_MULTISAMPLEBUFFERS, SDL_GL_MULTISAMPLESAMPLES, SDL_GL_ACCELERATED_VISUAL, SDL_GL_RETAINED_BACKING, SDL_GL_CONTEXT_MAJOR_VERSION, SDL_GL_CONTEXT_MINOR_VERSION, SDL_GL_CONTEXT_EGL, SDL_GL_CONTEXT_FLAGS, SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_SHARE_WITH_CURRENT_CONTEXT, SDL_GL_FRAMEBUFFER_SRGB_CAPABLE, SDL_GL_CONTEXT_RELEASE_BEHAVIOR, } mixin(MakeEnum!SDL_GLattr); enum SDL_GLprofile { SDL_GL_CONTEXT_PROFILE_CORE = 0x0001, SDL_GL_CONTEXT_PROFILE_COMPATIBILITY = 0x0002, SDL_GL_CONTEXT_PROFILE_ES = 0x0004, } mixin(MakeEnum!SDL_GLprofile); enum SDL_GLcontextFlag { SDL_GL_CONTEXT_DEBUG_FLAG = 0x0001, SDL_GL_CONTEXT_FORWARD_COMPATIBLE_FLAG = 0x0002, SDL_GL_CONTEXT_ROBUST_ACCESS_FLAG = 0x0004, SDL_GL_CONTEXT_RESET_ISOLATION_FLAG = 0x0008, } mixin(MakeEnum!SDL_GLcontextFlag); enum SDL_GLcontextReleaseFlag { SDL_GL_CONTEXT_RELEASE_BEHAVIOR_NONE = 0x0000, SDL_GL_CONTEXT_RELEASE_BEHAVIOR_FLUSH = 0x0001, } mixin(MakeEnum!SDL_GLcontextReleaseFlag); enum SDL_HitTestResult { SDL_HITTEST_NORMAL, SDL_HITTEST_DRAGGABLE, SDL_HITTEST_RESIZE_TOPLEFT, SDL_HITTEST_RESIZE_TOP, SDL_HITTEST_RESIZE_TOPRIGHT, SDL_HITTEST_RESIZE_RIGHT, SDL_HITTEST_RESIZE_BOTTOMRIGHT, SDL_HITTEST_RESIZE_BOTTOM, SDL_HITTEST_RESIZE_BOTTOMLEFT, SDL_HITTEST_RESIZE_LEFT, } mixin(MakeEnum!SDL_HitTestResult); extern(C) nothrow alias SDL_HitTest = SDL_HitTestResult function(SDL_Window*, const(SDL_Point)*, void*);CheeseCutter-2.10/src/derelict/sdl2/sdl.d000066400000000000000000000052001516216315000201710ustar00rootroot00000000000000/* Boost Software License - Version 1.0 - August 17th, 2003 Permission is hereby granted, free of charge, to any person or organization obtaining a copy of the software and accompanying documentation covered by this license (the "Software") to use, reproduce, display, distribute, execute, and transmit the Software, and to prepare derivative works of the Software, and to permit third-parties to whom the Software is furnished to do so, all subject to the following: The copyright notices in the Software and this entire statement, including the above license grant, this restriction and the following disclaimer, must be included in all copies of the Software, in whole or in part, and all derivative works of the Software, unless such copies or derivative works are solely in the form of machine-executable object code generated by a source language processor. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ module derelict.sdl2.sdl; import derelict.sdl2.config; public: import derelict.sdl2.internal.sdl_types; static if(staticSDL) import derelict.sdl2.internal.sdl_static; else import derelict.sdl2.internal.sdl_dynload; alias SDL_BlitSurface = SDL_UpperBlit; alias SDL_BlitScaled = SDL_UpperBlitScaled; @nogc nothrow { // SDL_audio.h SDL_AudioSpec* SDL_LoadWAV(const(char)* file,SDL_AudioSpec* spec,Uint8** audio_buf,Uint32* len) { return SDL_LoadWAV_RW(SDL_RWFromFile(file,"rb"),1,spec,audio_buf,len); } // SDL_events.h Uint8 SDL_GetEventState(Uint32 type) { return SDL_EventState(type,SDL_QUERY); } // SDL_GameController.h int SDL_GameControllerAddMappingsFromFile(const(char)* file) { return SDL_GameControllerAddMappingsFromRW(SDL_RWFromFile(file,"rb"),1); } // SDL_quit.h bool SDL_QuitRequested() { SDL_PumpEvents(); return SDL_PeepEvents(null,0,SDL_PEEKEVENT,SDL_QUIT,SDL_QUIT) > 0; } // SDL_surface.h SDL_Surface* SDL_LoadBMP(const(char)* file) { return SDL_LoadBMP_RW(SDL_RWFromFile(file,"rb"),1); } int SDL_SaveBMP(SDL_Surface* surface,const(char)* file) { return SDL_SaveBMP_RW(surface,SDL_RWFromFile(file,"wb"),1); } }CheeseCutter-2.10/src/derelict/sdl2/ttf.d000066400000000000000000000410661516216315000202160ustar00rootroot00000000000000/* Boost Software License - Version 1.0 - August 17th,2003 Permission is hereby granted,free of charge,to any person or organization obtaining a copy of the software and accompanying documentation covered by this license(the "Software") to use,reproduce,display,distribute, execute,and transmit the Software,and to prepare derivative works of the Software,and to permit third-parties to whom the Software is furnished to do so,all subject to the following: The copyright notices in the Software and this entire statement,including the above license grant,this restriction and the following disclaimer, must be included in all copies of the Software,in whole or in part,and all derivative works of the Software,unless such copies or derivative works are solely in the form of machine-executable object code generated by a source language processor. THE SOFTWARE IS PROVIDED "AS IS",WITHOUT WARRANTY OF ANY KIND,EXPRESS OR IMPLIED,INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE,TITLE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE FOR ANY DAMAGES OR OTHER LIABILITY,WHETHER IN CONTRACT,TORT OR OTHERWISE, ARISING FROM,OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ module derelict.sdl2.ttf; import core.stdc.config; import derelict.sdl2.config, derelict.sdl2.internal.sdl_types; static if(staticSDL) import derelict.sdl2.internal.sdl_static : SDL_GetError,SDL_SetError; else import derelict.sdl2.internal.sdl_dynamic : SDL_GetError,SDL_SetError; enum : Uint8 { SDL_TTF_MAJOR_VERSION = 2, SDL_TTF_MINOR_VERSION = 0, SDL_TTF_PATCHLEVEL = 12, } alias TTF_MAJOR_VERSION = SDL_TTF_MAJOR_VERSION; alias TTF_MINOR_VERSION = SDL_TTF_MINOR_VERSION; alias TTF_PATCHLEVEL = SDL_TTF_PATCHLEVEL; enum { UNICODE_BOM_NATIVE = 0xFEFF, UNICODE_BOM_SWAPPED = 0xFFFE, TTF_STYLE_NORMAL = 0x00, TTF_STYLE_BOLD = 0x01, TTF_STYLE_ITALIC = 0x02, TTF_STYLE_UNDERLINE = 0x04, TTF_STYLE_STRIKETHROUGH = 0x08, } enum { TTF_HINTING_NORMAL = 0, TTF_HINTING_LIGHT = 1, TTF_HINTING_MONO = 2, TTF_HINTING_NONE = 3, } alias TTF_SetError = SDL_SetError; alias TTF_GetError = SDL_GetError; struct TTF_Font; @nogc nothrow { void SDL_TTF_VERSION(SDL_version* X) { X.major = SDL_TTF_MAJOR_VERSION; X.minor = SDL_TTF_MINOR_VERSION; X.patch = SDL_TTF_PATCHLEVEL; } void TTF_VERSION(SDL_version* X) { SDL_TTF_VERSION(X); } } static if(staticTTF) { extern(C) @nogc nothrow { SDL_version* TTF_Linked_Version(); void TTF_ByteSwappedUNICODE(int); int TTF_Init(); TTF_Font * TTF_OpenFont(const(char)*,int); TTF_Font * TTF_OpenFontIndex(const(char)*,int,c_long ); TTF_Font * TTF_OpenFontRW(SDL_RWops*,int,int); TTF_Font * TTF_OpenFontIndexRW(SDL_RWops*,int,int,c_long); int TTF_GetFontStyle(const(TTF_Font)*); void TTF_SetFontStyle(const(TTF_Font)*,int style); int TTF_GetFontOutline(const(TTF_Font)*); void TTF_SetFontOutline(TTF_Font*,int); int TTF_GetFontHinting(const(TTF_Font)*); void TTF_SetFontHinting(TTF_Font*,int); int TTF_FontHeight(const(TTF_Font)*); int TTF_FontAscent(const(TTF_Font)*); int TTF_FontDescent(const(TTF_Font)*); int TTF_FontLineSkip(const(TTF_Font)*); int TTF_GetFontKerning(const(TTF_Font)*); void TTF_SetFontKerning(TTF_Font*,int); int TTF_FontFaces(const(TTF_Font)*); int TTF_FontFaceIsFixedWidth(const(TTF_Font)*); char* TTF_FontFaceFamilyName(const(TTF_Font)*); char* TTF_FontFaceStyleName(const(TTF_Font)*); int TTF_GlyphIsProvided(const(TTF_Font)*,Uint16); int TTF_GlyphMetrics(TTF_Font*,Uint16,int*,int*,int*,int*,int*); int TTF_SizeText(TTF_Font*,const(char)*,int*,int*); int TTF_SizeUTF8(TTF_Font*,const(char)*,int*,int*); int TTF_SizeUNICODE(TTF_Font*,Uint16*,int*,int*); SDL_Surface* TTF_RenderText_Solid(TTF_Font*,const(char)*,SDL_Color); SDL_Surface* TTF_RenderUTF8_Solid(TTF_Font*,const(char)*,SDL_Color); SDL_Surface* TTF_RenderUNICODE_Solid(TTF_Font*,const(Uint16)*,SDL_Color); SDL_Surface* TTF_RenderGlyph_Solid(TTF_Font*,Uint16,SDL_Color); SDL_Surface* TTF_RenderText_Shaded(TTF_Font*,const(char)*,SDL_Color,SDL_Color); SDL_Surface* TTF_RenderUTF8_Shaded(TTF_Font*,const(char)*,SDL_Color,SDL_Color); SDL_Surface* TTF_RenderUNICODE_Shaded(TTF_Font*,const(Uint16)*,SDL_Color,SDL_Color); SDL_Surface* TTF_RenderGlyph_Shaded(TTF_Font*,Uint16,SDL_Color,SDL_Color); SDL_Surface* TTF_RenderText_Blended(TTF_Font*,const(char)*,SDL_Color); SDL_Surface* TTF_RenderUTF8_Blended(TTF_Font*,const(char)*,SDL_Color); SDL_Surface* TTF_RenderUNICODE_Blended(TTF_Font*,const(Uint16)*,SDL_Color); SDL_Surface* TTF_RenderText_Blended_Wrapped(TTF_Font*,const(char)*,SDL_Color,Uint32); SDL_Surface* TTF_RenderUTF8_Blended_Wrapped(TTF_Font*,const(char)*,SDL_Color,Uint32); SDL_Surface* TTF_RenderUNICODE_Blended_Wrapped(TTF_Font*,const(Uint16)*,SDL_Color,Uint32); SDL_Surface* TTF_RenderGlyph_Blended(TTF_Font*,Uint16,SDL_Color); void TTF_CloseFont(TTF_Font*); void TTF_Quit(); int TTF_WasInit(); int TTF_GetFontKerningSize(TTF_Font*,int,int); } } else { import derelict.util.loader, derelict.util.system; extern(C) @nogc nothrow { alias da_TTF_Linked_Version = SDL_version* function(); alias da_TTF_ByteSwappedUNICODE = void function(int); alias da_TTF_Init = int function(); alias da_TTF_OpenFont = TTF_Font * function(const(char)*,int); alias da_TTF_OpenFontIndex = TTF_Font * function(const(char)*,int,c_long ); alias da_TTF_OpenFontRW = TTF_Font * function(SDL_RWops*,int,int); alias da_TTF_OpenFontIndexRW = TTF_Font * function(SDL_RWops*,int,int,c_long); alias da_TTF_GetFontStyle = int function(const(TTF_Font)*); alias da_TTF_SetFontStyle = void function(const(TTF_Font)*,int style); alias da_TTF_GetFontOutline = int function(const(TTF_Font)*); alias da_TTF_SetFontOutline = void function(TTF_Font*,int); alias da_TTF_GetFontHinting = int function(const(TTF_Font)*); alias da_TTF_SetFontHinting = void function(TTF_Font*,int); alias da_TTF_FontHeight = int function(const(TTF_Font)*); alias da_TTF_FontAscent = int function(const(TTF_Font)*); alias da_TTF_FontDescent = int function(const(TTF_Font)*); alias da_TTF_FontLineSkip = int function(const(TTF_Font)*); alias da_TTF_GetFontKerning = int function(const(TTF_Font)*); alias da_TTF_SetFontKerning = void function(TTF_Font*,int); alias da_TTF_FontFaces = int function(const(TTF_Font)*); alias da_TTF_FontFaceIsFixedWidth = int function(const(TTF_Font)*); alias da_TTF_FontFaceFamilyName = char* function(const(TTF_Font)*); alias da_TTF_FontFaceStyleName = char* function(const(TTF_Font)*); alias da_TTF_GlyphIsProvided = int function(const(TTF_Font)*,Uint16); alias da_TTF_GlyphMetrics = int function(TTF_Font*,Uint16,int*,int*,int*,int*,int*); alias da_TTF_SizeText = int function(TTF_Font*,const(char)*,int*,int*); alias da_TTF_SizeUTF8 = int function(TTF_Font*,const(char)*,int*,int*); alias da_TTF_SizeUNICODE = int function(TTF_Font*,Uint16*,int*,int*); alias da_TTF_RenderText_Solid = SDL_Surface* function(TTF_Font*,const(char)*,SDL_Color); alias da_TTF_RenderUTF8_Solid = SDL_Surface* function(TTF_Font*,const(char)*,SDL_Color); alias da_TTF_RenderUNICODE_Solid = SDL_Surface* function(TTF_Font*,const(Uint16)*,SDL_Color); alias da_TTF_RenderGlyph_Solid = SDL_Surface* function(TTF_Font*,Uint16,SDL_Color); alias da_TTF_RenderText_Shaded = SDL_Surface* function(TTF_Font*,const(char)*,SDL_Color,SDL_Color); alias da_TTF_RenderUTF8_Shaded = SDL_Surface* function(TTF_Font*,const(char)*,SDL_Color,SDL_Color); alias da_TTF_RenderUNICODE_Shaded = SDL_Surface* function(TTF_Font*,const(Uint16)*,SDL_Color,SDL_Color); alias da_TTF_RenderGlyph_Shaded = SDL_Surface* function(TTF_Font*,Uint16,SDL_Color,SDL_Color); alias da_TTF_RenderText_Blended = SDL_Surface* function(TTF_Font*,const(char)*,SDL_Color); alias da_TTF_RenderUTF8_Blended = SDL_Surface* function(TTF_Font*,const(char)*,SDL_Color); alias da_TTF_RenderUNICODE_Blended = SDL_Surface* function(TTF_Font*,const(Uint16)*,SDL_Color); alias da_TTF_RenderText_Blended_Wrapped = SDL_Surface* function(TTF_Font*,const(char)*,SDL_Color,Uint32); alias da_TTF_RenderUTF8_Blended_Wrapped = SDL_Surface* function(TTF_Font*,const(char)*,SDL_Color,Uint32); alias da_TTF_RenderUNICODE_Blended_Wrapped = SDL_Surface* function(TTF_Font*,const(Uint16)*,SDL_Color,Uint32); alias da_TTF_RenderGlyph_Blended = SDL_Surface* function(TTF_Font*,Uint16,SDL_Color); alias da_TTF_CloseFont = void function(TTF_Font*); alias da_TTF_Quit = void function(); alias da_TTF_WasInit = int function(); alias da_TTF_GetFontKerningSize = int function(TTF_Font*,int,int); } __gshared { da_TTF_Linked_Version TTF_Linked_Version; da_TTF_ByteSwappedUNICODE TTF_ByteSwappedUNICODE; da_TTF_Init TTF_Init; da_TTF_OpenFont TTF_OpenFont; da_TTF_OpenFontIndex TTF_OpenFontIndex; da_TTF_OpenFontRW TTF_OpenFontRW; da_TTF_OpenFontIndexRW TTF_OpenFontIndexRW; da_TTF_GetFontStyle TTF_GetFontStyle; da_TTF_SetFontStyle TTF_SetFontStyle; da_TTF_GetFontOutline TTF_GetFontOutline; da_TTF_SetFontOutline TTF_SetFontOutline; da_TTF_GetFontHinting TTF_GetFontHinting; da_TTF_SetFontHinting TTF_SetFontHinting; da_TTF_FontHeight TTF_FontHeight; da_TTF_FontAscent TTF_FontAscent; da_TTF_FontDescent TTF_FontDescent; da_TTF_FontLineSkip TTF_FontLineSkip; da_TTF_GetFontKerning TTF_GetFontKerning; da_TTF_SetFontKerning TTF_SetFontKerning; da_TTF_FontFaces TTF_FontFaces; da_TTF_FontFaceIsFixedWidth TTF_FontFaceIsFixedWidth; da_TTF_FontFaceFamilyName TTF_FontFaceFamilyName; da_TTF_FontFaceStyleName TTF_FontFaceStyleName; da_TTF_GlyphIsProvided TTF_GlyphIsProvided; da_TTF_GlyphMetrics TTF_GlyphMetrics; da_TTF_SizeText TTF_SizeText; da_TTF_SizeUTF8 TTF_SizeUTF8; da_TTF_SizeUNICODE TTF_SizeUNICODE; da_TTF_RenderText_Solid TTF_RenderText_Solid; da_TTF_RenderUTF8_Solid TTF_RenderUTF8_Solid; da_TTF_RenderUNICODE_Solid TTF_RenderUNICODE_Solid; da_TTF_RenderGlyph_Solid TTF_RenderGlyph_Solid; da_TTF_RenderText_Shaded TTF_RenderText_Shaded; da_TTF_RenderUTF8_Shaded TTF_RenderUTF8_Shaded; da_TTF_RenderUNICODE_Shaded TTF_RenderUNICODE_Shaded; da_TTF_RenderGlyph_Shaded TTF_RenderGlyph_Shaded; da_TTF_RenderText_Blended TTF_RenderText_Blended; da_TTF_RenderUTF8_Blended TTF_RenderUTF8_Blended; da_TTF_RenderUNICODE_Blended TTF_RenderUNICODE_Blended; da_TTF_RenderText_Blended_Wrapped TTF_RenderText_Blended_Wrapped; da_TTF_RenderUTF8_Blended_Wrapped TTF_RenderUTF8_Blended_Wrapped; da_TTF_RenderUNICODE_Blended_Wrapped TTF_RenderUNICODE_Blended_Wrapped; da_TTF_RenderGlyph_Blended TTF_RenderGlyph_Blended; da_TTF_CloseFont TTF_CloseFont; da_TTF_Quit TTF_Quit; da_TTF_WasInit TTF_WasInit; da_TTF_GetFontKerningSize TTF_GetFontKerningSize; } class DerelictSDL2ttfLoader : SharedLibLoader { this() { super(libNames); } protected override void loadSymbols() { bindFunc(cast(void**)&TTF_Linked_Version,"TTF_Linked_Version"); bindFunc(cast(void**)&TTF_ByteSwappedUNICODE,"TTF_ByteSwappedUNICODE"); bindFunc(cast(void**)&TTF_Init,"TTF_Init"); bindFunc(cast(void**)&TTF_OpenFont,"TTF_OpenFont"); bindFunc(cast(void**)&TTF_OpenFontIndex,"TTF_OpenFontIndex"); bindFunc(cast(void**)&TTF_OpenFontRW,"TTF_OpenFontRW"); bindFunc(cast(void**)&TTF_OpenFontIndexRW,"TTF_OpenFontIndexRW"); bindFunc(cast(void**)&TTF_GetFontStyle,"TTF_GetFontStyle"); bindFunc(cast(void**)&TTF_SetFontStyle,"TTF_SetFontStyle"); bindFunc(cast(void**)&TTF_GetFontOutline,"TTF_GetFontOutline"); bindFunc(cast(void**)&TTF_SetFontOutline,"TTF_SetFontOutline"); bindFunc(cast(void**)&TTF_GetFontHinting,"TTF_GetFontHinting"); bindFunc(cast(void**)&TTF_SetFontHinting,"TTF_SetFontHinting"); bindFunc(cast(void**)&TTF_FontHeight,"TTF_FontHeight"); bindFunc(cast(void**)&TTF_FontAscent,"TTF_FontAscent"); bindFunc(cast(void**)&TTF_FontDescent,"TTF_FontDescent"); bindFunc(cast(void**)&TTF_FontLineSkip,"TTF_FontLineSkip"); bindFunc(cast(void**)&TTF_GetFontKerning,"TTF_GetFontKerning"); bindFunc(cast(void**)&TTF_SetFontKerning,"TTF_SetFontKerning"); bindFunc(cast(void**)&TTF_FontFaces,"TTF_FontFaces"); bindFunc(cast(void**)&TTF_FontFaceIsFixedWidth,"TTF_FontFaceIsFixedWidth"); bindFunc(cast(void**)&TTF_FontFaceFamilyName,"TTF_FontFaceFamilyName"); bindFunc(cast(void**)&TTF_FontFaceStyleName,"TTF_FontFaceStyleName"); bindFunc(cast(void**)&TTF_GlyphIsProvided,"TTF_GlyphIsProvided"); bindFunc(cast(void**)&TTF_GlyphMetrics,"TTF_GlyphMetrics"); bindFunc(cast(void**)&TTF_SizeText,"TTF_SizeText"); bindFunc(cast(void**)&TTF_SizeUTF8,"TTF_SizeUTF8"); bindFunc(cast(void**)&TTF_SizeUNICODE,"TTF_SizeUNICODE"); bindFunc(cast(void**)&TTF_RenderText_Solid,"TTF_RenderText_Solid"); bindFunc(cast(void**)&TTF_RenderUTF8_Solid,"TTF_RenderUTF8_Solid"); bindFunc(cast(void**)&TTF_RenderUNICODE_Solid,"TTF_RenderUNICODE_Solid"); bindFunc(cast(void**)&TTF_RenderGlyph_Solid,"TTF_RenderGlyph_Solid"); bindFunc(cast(void**)&TTF_RenderText_Shaded,"TTF_RenderText_Shaded"); bindFunc(cast(void**)&TTF_RenderUTF8_Shaded,"TTF_RenderUTF8_Shaded"); bindFunc(cast(void**)&TTF_RenderUNICODE_Shaded,"TTF_RenderUNICODE_Shaded"); bindFunc(cast(void**)&TTF_RenderGlyph_Shaded,"TTF_RenderGlyph_Shaded"); bindFunc(cast(void**)&TTF_RenderText_Blended,"TTF_RenderText_Blended"); bindFunc(cast(void**)&TTF_RenderUTF8_Blended,"TTF_RenderUTF8_Blended"); bindFunc(cast(void**)&TTF_RenderUNICODE_Blended,"TTF_RenderUNICODE_Blended"); bindFunc(cast(void**)&TTF_RenderText_Blended_Wrapped,"TTF_RenderText_Blended_Wrapped"); bindFunc(cast(void**)&TTF_RenderUTF8_Blended_Wrapped,"TTF_RenderUTF8_Blended_Wrapped"); bindFunc(cast(void**)&TTF_RenderUNICODE_Blended_Wrapped,"TTF_RenderUNICODE_Blended_Wrapped"); bindFunc(cast(void**)&TTF_RenderGlyph_Blended,"TTF_RenderGlyph_Blended"); bindFunc(cast(void**)&TTF_CloseFont,"TTF_CloseFont"); bindFunc(cast(void**)&TTF_Quit,"TTF_Quit"); bindFunc(cast(void**)&TTF_WasInit,"TTF_WasInit"); bindFunc(cast(void**)&TTF_GetFontKerningSize,"TTF_GetFontKerningSize"); } } __gshared DerelictSDL2ttfLoader DerelictSDL2ttf; alias DerelictSDL2TTF = DerelictSDL2ttf; shared static this() { DerelictSDL2ttf = new DerelictSDL2ttfLoader(); } private: static if(Derelict_OS_Windows) enum libNames = "SDL2_ttf.dll"; else static if(Derelict_OS_Mac) enum libNames = "/usr/local/lib/libSDL2_ttf.dylib,../Frameworks/SDL2_ttf.framework/SDL2_ttf,/Library/Frameworks/SDL2_ttf.framework/SDL2_ttf,/System/Library/Frameworks/SDL2_ttf.framework/SDL2_ttf"; else static if(Derelict_OS_Posix) enum libNames = "libSDL2_ttf.so,libSDL2_ttf-2.0.so,libSDL2_ttf-2.0.so.0,/usr/local/lib/libSDL2_ttf-2.0.so,/usr/local/lib/libSDL2_ttf-2.0.so.0"; else static assert(0,"Need to implement SDL2_ttf libNames for this operating system."); } alias TTF_RenderText = TTF_RenderText_Shaded; alias TTF_RenderUTF8 = TTF_RenderUTF8_Shaded; alias TTF_RenderUNICODE = TTF_RenderUNICODE_Shaded;CheeseCutter-2.10/src/derelict/util/000077500000000000000000000000001516216315000173565ustar00rootroot00000000000000CheeseCutter-2.10/src/derelict/util/exception.d000066400000000000000000000114631516216315000215260ustar00rootroot00000000000000/* Boost Software License - Version 1.0 - August 17th, 2003 Permission is hereby granted, free of charge, to any person or organization obtaining a copy of the software and accompanying documentation covered by this license (the "Software") to use, reproduce, display, distribute, execute, and transmit the Software, and to prepare derivative works of the Software, and to permit third-parties to whom the Software is furnished to do so, all subject to the following: The copyright notices in the Software and this entire statement, including the above license grant, this restriction and the following disclaimer, must be included in all copies of the Software, in whole or in part, and all derivative works of the Software, unless such copies or derivative works are solely in the form of machine-executable object code generated by a source language processor. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ module derelict.util.exception; /++ Base class for all exceptions thrown by Derelict packages. +/ class DerelictException : Exception { public this(string msg, size_t line = __LINE__, string file = __FILE__) { super(msg, file, line, null); } } /++ Helper struct to facilitate throwing a single SharedLibException after failing to load a library using multiple names. +/ private struct FailedSharedLib { string name; string reason; } /++ This exception is thrown when a shared library cannot be loaded because it is either missing or not on the system path. +/ class SharedLibLoadException : DerelictException { private string _sharedLibName; public { static void throwNew(string[] libNames, string[] reasons, size_t line = __LINE__, string file = __FILE__) { string msg = "Failed to load one or more shared libraries:"; foreach(i, n; libNames) { msg ~= "\n\t" ~ n ~ " - "; if(i < reasons.length) msg ~= reasons[i]; else msg ~= "Unknown"; } throw new SharedLibLoadException(msg, line, file); } this(string msg, size_t line = __LINE__, string file = __FILE__) { super(msg, line, file); _sharedLibName = ""; } this(string msg, string sharedLibName, size_t line = __LINE__, string file = __FILE__) { super(msg, line, file); _sharedLibName = sharedLibName; } string sharedLibName() { return _sharedLibName; } } } /++ This exception is thrown when a symbol cannot be loaded from a shared library, either because it does not exist in the library or because the library is corrupt. +/ class SymbolLoadException : DerelictException { private string _symbolName; public { this(string msg, size_t line = __LINE__, string file = __FILE__) { super(msg, line, file); } this(string sharedLibName, string symbolName, size_t line = __LINE__, string file = __FILE__) { super("Failed to load symbol " ~ symbolName ~ " from shared library " ~ sharedLibName, line, file); _symbolName = symbolName; } string symbolName() { return _symbolName; } } } /++ The return type of the MissingSymbolCallbackFunc/Dg. +/ enum ShouldThrow { No, Yes } /++ The MissingSymbolCallback allows the user to prevent the throwing of SymbolLoadExceptions. By default, a SymbolLoadException is thrown when a symbol cannot be found in a shared library. Assigning a MissingSymbolCallback to a loader allows the application to override this behavior. If the missing symbol in question can be ignored, the callback should return ShouldThrow.No to prevent the exception from being thrown. Otherwise, the return value should be ShouldThrow.Yes. This is useful to allow a binding implemented for version N.N of a library to load older or newer versions that may be missing functions the loader expects to find, provided of course that the app does not need to use those functions. +/ alias MissingSymbolCallbackFunc = ShouldThrow function(string symbolName); /// Ditto alias MissingSymbolCallbackDg = ShouldThrow delegate(string symbolName); /// Convenient alias to use as a return value. alias MissingSymbolCallback = MissingSymbolCallbackDg; CheeseCutter-2.10/src/derelict/util/loader.d000066400000000000000000000360411516216315000207750ustar00rootroot00000000000000/* Boost Software License - Version 1.0 - August 17th, 2003 Permission is hereby granted, free of charge, to any person or organization obtaining a copy of the software and accompanying documentation covered by this license (the "Software") to use, reproduce, display, distribute, execute, and transmit the Software, and to prepare derivative works of the Software, and to permit third-parties to whom the Software is furnished to do so, all subject to the following: The copyright notices in the Software and this entire statement, including the above license grant, this restriction and the following disclaimer, must be included in all copies of the Software, in whole or in part, and all derivative works of the Software, unless such copies or derivative works are solely in the form of machine-executable object code generated by a source language processor. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ module derelict.util.loader; import std.array, std.string; import derelict.util.exception, derelict.util.sharedlib, derelict.util.system; struct SharedLibVersion { int major; int minor; int patch; } abstract class SharedLibLoader { /++ Constructs a new instance of shared lib loader with a string of one or more shared library names to use as default. Params: libNames = A string containing one or more comma-separated shared library names. +/ this(string libNames) { _libNames = libNames; } /++ Binds a function pointer to a symbol in this loader's shared library. Params: ptr = Pointer to a function pointer that will be used as the bind point. funcName = The name of the symbol to be bound. doThrow = If true, a SymbolLoadException will be thrown if the symbol is missing. If false, no exception will be thrown and the ptr parameter will be set to null. Throws: SymbolLoadException if doThrow is true and a the symbol specified by funcName is missing from the shared library. +/ final void bindFunc(void** ptr, string funcName, bool doThrow = true) { void* func = loadSymbol(funcName, doThrow); *ptr = func; } /++ Binds a function pointer to a stdcall symbol in this loader's shared library. On builds for anything other than 32-bit Windows, this simply delegates to bindFunc. Params: ptr = Pointer to a function pointer that will be used as the bind point. funcName = The name of the symbol to be bound. doThrow = If true, a SymbolLoadException will be thrown if the symbol is missing. If false, no exception will be thrown and the ptr parameter will be set to null. Throws: SymbolLoadException if doThrow is true and a the symbol specified by funcName is missing from the shared library. +/ final void bindFunc_stdcall(Func)(ref Func f, string unmangledName) { static if(Derelict_OS_Windows && !Derelict_Arch_64) { import std.format : format; import std.traits : ParameterTypeTuple; // get type-tuple of parameters ParameterTypeTuple!f params; size_t sizeOfParametersOnStack(A...)(A args) { size_t sum = 0; foreach (arg; args) { sum += arg.sizeof; // align on 32-bit stack if (sum % 4 != 0) sum += 4 - (sum % 4); } return sum; } unmangledName = format("_%s@%s", unmangledName, sizeOfParametersOnStack(params)); } bindFunc(cast(void**)&f, unmangledName); } /++ Finds and loads a shared library, using this loader's default shared library names and default supported shared library version. If multiple library names are specified as default, a SharedLibLoadException will only be thrown if all of the libraries fail to load. It will be the head of an exceptin chain containing one instance of the exception for each library that failed. Examples: If this loader supports versions 2.0 and 2.1 of a shared libary, this method will attempt to load 2.1 and will fail if only 2.0 is present on the system. Throws: SharedLibLoadException if the shared library or one of its dependencies cannot be found on the file system. SymbolLoadException if an expected symbol is missing from the library. +/ final void load() { load(_libNames); } /++ Finds and loads any version of a shared library greater than or equal to the required mimimum version, using this loader's default shared library names. If multiple library names are specified as default, a SharedLibLoadException will only be thrown if all of the libraries fail to load. It will be the head of an exceptin chain containing one instance of the exception for each library that failed. Examples: If this loader supports versions 2.0 and 2.1 of a shared library, passing a SharedLibVersion with the major field set to 2 and the minor field set to 0 will cause the loader to load version 2.0 if version 2.1 is not available on the system. Params: minRequiredVersion = the minimum version of the library that is acceptable. Subclasses are free to ignore this. Throws: SharedLibLoadException if the shared library or one of its dependencies cannot be found on the file system. SymbolLoadException if an expected symbol is missing from the library. +/ final void load(SharedLibVersion minRequiredVersion) { configureMinimumVersion(minRequiredVersion); load(); } /++ Finds and loads a shared library, using libNames to find the library on the file system. If multiple library names are specified in libNames, a SharedLibLoadException will only be thrown if all of the libraries fail to load. It will be the head of an exceptin chain containing one instance of the exception for each library that failed. Examples: If this loader supports versions 2.0 and 2.1 of a shared libary, this method will attempt to load 2.1 and will fail if only 2.0 is present on the system. Params: libNames = A string containing one or more comma-separated shared library names. Throws: SharedLibLoadException if the shared library or one of its dependencies cannot be found on the file system. SymbolLoadException if an expected symbol is missing from the library. +/ final void load(string libNames) { if(libNames == null) libNames = _libNames; auto lnames = libNames.split(","); foreach(ref string l; lnames) l = l.strip(); load(lnames); } /++ Finds and loads any version of a shared library greater than or equal to the required mimimum version, using libNames to find the library on the file system. If multiple library names are specified as default, a SharedLibLoadException will only be thrown if all of the libraries fail to load. It will be the head of an exceptin chain containing one instance of the exception for each library that failed. Examples: If this loader supports versions 2.0 and 2.1 of a shared library, passing a SharedLibVersion with the major field set to 2 and the minor field set to 0 will cause the loader to load version 2.0 if version 2.1 is not available on the system. Params: libNames = A string containing one or more comma-separated shared library names. minRequiredVersion = The minimum version of the library that is acceptable. Subclasses are free to ignore this. Throws: SharedLibLoadException if the shared library or one of its dependencies cannot be found on the file system. SymbolLoadException if an expected symbol is missing from the library. +/ final void load(string libNames, SharedLibVersion minRequiredVersion) { configureMinimumVersion(minRequiredVersion); load(libNames); } /++ Finds and loads a shared library, using libNames to find the library on the file system. If multiple library names are specified in libNames, a SharedLibLoadException will only be thrown if all of the libraries fail to load. It will be the head of an exception chain containing one instance of the exception for each library that failed. Params: libNames = An array containing one or more shared library names, with one name per index. Throws: SharedLibLoadException if the shared library or one of its dependencies cannot be found on the file system. SymbolLoadException if an expected symbol is missing from the library. +/ final void load(string[] libNames) { _lib.load(libNames); loadSymbols(); } /++ Finds and loads any version of a shared library greater than or equal to the required mimimum version, , using libNames to find the library on the file system. If multiple library names are specified in libNames, a SharedLibLoadException will only be thrown if all of the libraries fail to load. It will be the head of an exception chain containing one instance of the exception for each library that failed. Examples: If this loader supports versions 2.0 and 2.1 of a shared library, passing a SharedLibVersion with the major field set to 2 and the minor field set to 0 will cause the loader to load version 2.0 if version 2.1 is not available on the system. Params: libNames = An array containing one or more shared library names, with one name per index. minRequiredVersion = The minimum version of the library that is acceptable. Subclasses are free to ignore this. Throws: SharedLibLoadException if the shared library or one of its dependencies cannot be found on the file system. SymbolLoadException if an expected symbol is missing from the library. +/ final void load(string[] libNames, SharedLibVersion minRequiredVersion) { configureMinimumVersion(minRequiredVersion); load(libNames); } /++ Unloads the shared library from memory, invalidating all function pointers which were assigned a symbol by one of the load methods. +/ final void unload() { _lib.unload(); } /// Returns: true if the shared library is loaded, false otherwise. @property @nogc nothrow final bool isLoaded() { return _lib.isLoaded; } /++ Sets the callback that will be called when an expected symbol is missing from the shared library. Params: callback = A delegate that returns a value of type derelict.util.exception.ShouldThrow and accepts a string as the sole parameter. +/ @property @nogc nothrow final void missingSymbolCallback(MissingSymbolCallbackDg callback) { _lib.missingSymbolCallback = callback; } /++ Sets the callback that will be called when an expected symbol is missing from the shared library. Params: callback = A pointer to a function that returns a value of type derelict.util.exception.ShouldThrow and accepts a string as the sole parameter. +/ @property @nogc nothrow final void missingSymbolCallback(MissingSymbolCallbackFunc callback) { _lib.missingSymbolCallback = callback; } /++ Returns the currently active missing symbol callback. This exists primarily as a means to save the current callback before setting a new one. It's useful, for example, if the new callback needs to delegate to the old one. +/ @property @nogc nothrow final MissingSymbolCallback missingSymbolCallback() { return _lib.missingSymbolCallback; } protected: /++ Must be implemented by subclasses to load all of the symbols from a shared library. This method is called by the load methods. +/ abstract void loadSymbols(); /++ Allows a subclass to install an exception handler for specific versions of a library before loadSymbols is called. This method is optional. If the subclass does not implement it, calls to any of the overloads of the load method that take a SharedLibVersion will cause a compile time assert to fire. +/ void configureMinimumVersion(SharedLibVersion minVersion) { assert(0, "SharedLibVersion is not supported by this loader."); } /++ Subclasses can use this as an alternative to bindFunc, but must bind the returned symbol manually. bindFunc calls this internally, so it can be overloaded to get behavior different from the default. Params: name = The name of the symbol to load.doThrow = If true, a SymbolLoadException will be thrown if the symbol is missing. If false, no exception will be thrown and the ptr parameter will be set to null. Throws: SymbolLoadException if doThrow is true and a the symbol specified by funcName is missing from the shared library. Returns: The symbol matching the name parameter. +/ void* loadSymbol(string name, bool doThrow = true) { return _lib.loadSymbol(name, doThrow); } /// Returns a reference to the shared library wrapped by this loader. @property @nogc nothrow final ref SharedLib lib(){ return _lib; } private: string _libNames; SharedLib _lib; }CheeseCutter-2.10/src/derelict/util/sharedlib.d000066400000000000000000000176051516216315000214710ustar00rootroot00000000000000/* Boost Software License - Version 1.0 - August 17th, 2003 Permission is hereby granted, free of charge, to any person or organization obtaining a copy of the software and accompanying documentation covered by this license (the "Software") to use, reproduce, display, distribute, execute, and transmit the Software, and to prepare derivative works of the Software, and to permit third-parties to whom the Software is furnished to do so, all subject to the following: The copyright notices in the Software and this entire statement, including the above license grant, this restriction and the following disclaimer, must be included in all copies of the Software, in whole or in part, and all derivative works of the Software, unless such copies or derivative works are solely in the form of machine-executable object code generated by a source language processor. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ module derelict.util.sharedlib; import std.string; import derelict.util.exception, derelict.util.system; alias void* SharedLibHandle; static if(Derelict_OS_Posix) { import core.sys.posix.dlfcn; enum LDFlags { rtldLocal = RTLD_LOCAL, rtldLazy = RTLD_LAZY, rtldNow = RTLD_NOW, rtldGlobal = RTLD_GLOBAL, } void derelictLDFlags(LDFlags flags) { ldFlags = flags; } private { LDFlags ldFlags = LDFlags.rtldNow; SharedLibHandle LoadSharedLib(string libName) { return dlopen(libName.toStringz(), ldFlags); } void UnloadSharedLib(SharedLibHandle hlib) { dlclose(hlib); } void* GetSymbol(SharedLibHandle hlib, string symbolName) { return dlsym(hlib, symbolName.toStringz()); } string GetErrorStr() { import std.conv : to; auto err = dlerror(); if(err is null) return "Uknown Error"; return to!string(err); } } } else static if(Derelict_OS_Windows) { import core.sys.windows.windows; private { SharedLibHandle LoadSharedLib(string libName) { return LoadLibraryA(libName.toStringz()); } void UnloadSharedLib(SharedLibHandle hlib) { FreeLibrary(hlib); } void* GetSymbol(SharedLibHandle hlib, string symbolName) { return GetProcAddress(hlib, symbolName.toStringz()); } string GetErrorStr() { import std.windows.syserror; return sysErrorString(GetLastError()); } } } else { static assert(0, "Derelict does not support this platform."); } /++ Low-level wrapper of the even lower-level operating-specific shared library loading interface. While this interface can be used directly in applications, it is recommended to use the interface specified by derelict.util.loader.SharedLibLoader to implement bindings. SharedLib is designed to be the base of a higher-level loader, but can be used in a program if only a handful of functions need to be loaded from a given shared library. +/ struct SharedLib { /++ Finds and loads a shared library, using names to find the library on the file system. If multiple library names are specified in names, a SharedLibLoadException will only be thrown if all of the libraries fail to load. It will be the head of an exceptin chain containing one instance of the exception for each library that failed. Params: names = An array containing one or more shared library names, with one name per index. Throws: SharedLibLoadException if the shared library or one of its dependencies cannot be found on the file system. SymbolLoadException if an expected symbol is missing from the library. +/ void load(string[] names) { if(isLoaded) return; string[] failedLibs; string[] reasons; foreach(n; names) { _hlib = LoadSharedLib(n); if(_hlib !is null) { _name = n; break; } failedLibs ~= n; reasons ~= GetErrorStr(); } if(!isLoaded) { SharedLibLoadException.throwNew(failedLibs, reasons); } } /++ Loads the symbol specified by symbolName from a shared library. Params: symbolName = The name of the symbol to load. doThrow = If true, a SymbolLoadException will be thrown if the symbol is missing. If false, no exception will be thrown and the ptr parameter will be set to null. Throws: SymbolLoadException if doThrow is true and a the symbol specified by funcName is missing from the shared library. +/ void* loadSymbol(string symbolName, bool doThrow = true) { void* sym = GetSymbol(_hlib, symbolName); if(doThrow && !sym) { auto result = ShouldThrow.Yes; if(_onMissingSym !is null) result = _onMissingSym(symbolName); if(result == ShouldThrow.Yes) throw new SymbolLoadException(_name, symbolName); } return sym; } /++ Unloads the shared library from memory, invalidating all function pointers which were assigned a symbol by one of the load methods. +/ void unload() { if(isLoaded) { UnloadSharedLib(_hlib); _hlib = null; } } /// Returns the name of the shared library. @property @nogc nothrow string name() { return _name; } /// Returns true if the shared library is currently loaded, false otherwise. @property @nogc nothrow bool isLoaded() { return (_hlib !is null); } /++ Sets the callback that will be called when an expected symbol is missing from the shared library. Params: callback = A delegate that returns a value of type derelict.util.exception.ShouldThrow and accepts a string as the sole parameter. +/ @property @nogc nothrow void missingSymbolCallback(MissingSymbolCallbackDg callback) { _onMissingSym = callback; } /++ Sets the callback that will be called when an expected symbol is missing from the shared library. Params: callback = A pointer to a function that returns a value of type derelict.util.exception.ShouldThrow and accepts a string as the sole parameter. +/ @property @nogc nothrow void missingSymbolCallback(MissingSymbolCallbackFunc callback) { import std.functional : toDelegate; _onMissingSym = toDelegate(callback); } /++ Returns the currently active missing symbol callback. This exists primarily as a means to save the current callback before setting a new one. It's useful, for example, if the new callback needs to delegate to the old one. +/ @property @nogc nothrow MissingSymbolCallback missingSymbolCallback() { return _onMissingSym; } private: string _name; SharedLibHandle _hlib; private MissingSymbolCallbackDg _onMissingSym; } CheeseCutter-2.10/src/derelict/util/system.d000066400000000000000000000057721516216315000210620ustar00rootroot00000000000000/* Boost Software License - Version 1.0 - August 17th, 2003 Permission is hereby granted, free of charge, to any person or organization obtaining a copy of the software and accompanying documentation covered by this license (the "Software") to use, reproduce, display, distribute, execute, and transmit the Software, and to prepare derivative works of the Software, and to permit third-parties to whom the Software is furnished to do so, all subject to the following: The copyright notices in the Software and this entire statement, including the above license grant, this restriction and the following disclaimer, must be included in all copies of the Software, in whole or in part, and all derivative works of the Software, unless such copies or derivative works are solely in the form of machine-executable object code generated by a source language processor. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ module derelict.util.system; static if((void*).sizeof == 8) { enum Derelict_Arch_64 = true; enum Derelict_Arch_32 = false; } else { enum Derelict_Arch_64 = false; enum Derelict_Arch_32 = true; } version(Windows) enum Derelict_OS_Windows = true; else enum Derelict_OS_Windows = false; version(OSX) enum Derelict_OS_Mac = true; else enum Derelict_OS_Mac = false; version(linux) enum Derelict_OS_Linux = true; else enum Derelict_OS_Linux = false; version(Posix) enum Derelict_OS_Posix = true; else enum Derelict_OS_Posix = false; version(Android) enum Derelict_OS_Android = true; else enum Derelict_OS_Android = false; // TODO enum Derelict_OS_iOS = false; enum Derelict_OS_WinRT = false; version(FreeBSD) { enum Derelict_OS_AnyBSD = true; enum Derelict_OS_FreeBSD = true; enum Derelict_OS_OpenBSD = false; enum Derelict_OS_OtherBSD = false; } else version(OpenBSD) { enum Derelict_OS_AnyBSD = true; enum Derelict_OS_FreeBSD = false; enum Derelict_OS_OpenBSD = true; enum Derelict_OS_OtherBSD = false; } else version(BSD) { enum Derelict_OS_AnyBSD = true; enum Derelict_OS_FreeBSD = false; enum Derelict_OS_OpenBSD = false; enum Derelict_OS_OtherBSD = true; } else { enum Derelict_OS_AnyBSD = false; enum Derelict_OS_FreeBSD = false; enum Derelict_OS_OpenBSD = false; enum Derelict_OS_OtherBSD = false; } static if(__VERSION__ < 2066) enum nogc = 1; enum MakeEnum(EnumType, string fqnEnumType = EnumType.stringof) = (){ string MakeEnum = "enum {"; foreach(m;__traits(allMembers, EnumType)) { MakeEnum ~= m ~ " = " ~ fqnEnumType ~ "." ~ m ~ ","; } MakeEnum ~= "}"; return MakeEnum; }();CheeseCutter-2.10/src/font/000077500000000000000000000000001516216315000155545ustar00rootroot00000000000000CheeseCutter-2.10/src/font/font.psf000066400000000000000000000222521516216315000172370ustar00rootroot000000000000006UUUUUUU<~~<ffffff~~f<~~~~6ll6~~{l66l`bfl0`Λ |fcccccf|=gfn~vff ff<v{n=gn~v~~ffff<~p33f00`3```3UUQ| |~~ ~~ ````p```fffllllllll~~~fl 06kf8ll8vv 000000 0 0l88l~0 00``||8x~| 0`|<|6f|<`| 000||||~ x0 0`0 `0  0`| ~|||||<< x||||||||lll88Áll88llff< 0`<00000000<``00 < <3333338x۞00>333333>ffffffff~<~~~~~~<~~~``~ccccccx۞``~cccccc`````````````|8||8|flxxlfccflxlfcff<ll88lll8l~~llllxx~~`vn$ff$$~~$<f>~<<ZZ<f~<?3?00000|8l0|x 8 x000`80b60fΚ>0000`|0|0|8l|v|ll|8l8|||0`008lll0<< <<8l<<ff<<v0||0||8l||v||ll||l8l0|0|8l|ll|x0|~~0|~~8l|~~v|~~ll|~~8l8|~~||0`0||0||8l||ll||08< 8<8l8<ll8<h0X||v0||0||8l||v||ll||~0~0~8l~ll~0~|ll~|l8||l8~~|<<8<|||0`~|0`l8|||l8~|l8 0`l8 0`8lv0000fff~~~<< 0`0 `0 0`l8|l8|~~0||0||l8||l8||l8l8~~||l8l8||` 8<l8l88<88<00l8l86l||6l||00l8l80||| ~|00000000 l800000008l8|8l8~6l|6l~0 0`0 0` 0` 0`|||0`~|0`00000000 l8l86l8l||8l||||||8l||8l~~|||~~|8l66 x6ff<8l|||8l~|l8|l8~||||~~||||||||0` ~~|~<<|8<<<8<0`0`0`8<00`0`||||||0``|||~|00||00l8~|88|<|l86fffffff~|~``|fffff|```|fffff||>|~~6f|x|||~~||<|~l8~>fffff~`|fff|``|fff||>|~~6f0||0|||||00~l8~|88``|||𰖐 |<|00|<|00||00||00~~ll|ll|~~l8l8||||||||~ll||ll|||||||~||~|ll~|ll~|6l~|6l~|0vvxllllfffffffff>``>|888 l<pllllllllllffff|lll<~~<<~~<~&f` >~~>8|llllllllllll|88|ll|888llll88|8l2xx%f&j"k"RSx   & 0 "!A         !"#$%&'()*+,-  "  ./0123456789:;<=>?@ABC!DEFGHIJK*!LMNOP QRST"UVWX%YZ[\]^_`a0bcAde5fghiVjXklmno>p@qrsUtuvwxEyCz{|}~bd&'tus   $&()+.6<BDFHIKNRYZ[ "" #!!":&;&<&`&%%l%<%%j%%,%%4% %!%!%!%!%%%%e"d"%$%%%c&e&j&+!QW01^_`a}~     ! " %9 :   9:=>BCDGHPQTUXYZ[cenopqyz{|    !$%45\]lm"#*+./67;<EFLMVWjkr  #'*,-/1234789:;=?GJLMOPST\]^_!`"H" < a"")"""!##  2 3 &!!!!!!!!!"'"("*"#@&B&CheeseCutter-2.10/src/main.d000066400000000000000000000150551516216315000157050ustar00rootroot00000000000000/* CheeseCutter v2 (C) Abaddon. Licensed under GNU GPL. */ module main; import derelict.sdl2.sdl; import com.fb; import com.session; import com.kbd; import com.util; import ct.base; import ui.ui; import ui.input; import audio.player; import audio.resid.filter; import audio.audio, audio.callback, audio.timer; import std.stdio; import std.string; import std.conv; import std.file; version(linux) { const DIR_SEPARATOR = '/'; } version(FreeBSD) { const DIR_SEPARATOR = '/'; } version(OSX) { const DIR_SEPARATOR = '/'; } version(Win32) { const DIR_SEPARATOR = '\\'; } bool initVideo() { int mx = 800, my = 600; if( SDL_Init(SDL_INIT_VIDEO) < 0) return false; int width = mx / FONT_X; int height = my / FONT_Y; screen = new Screen(width, height); video = new Video(800, 600, screen, 0); // SDL_EnableKeyRepeat(200, 10); // SDL_EnableUNICODE(1); // SDL_WM_SetCaption("CheeseCutter".toStringz(),"CheeseCutter".toStringz()); return video.init(); } void mainloop() { int mods, key, unicode; bool quit = false; SDL_Event evt; while(!quit) { int ticks = audio.timer.readTick(); mainui.timerEvent(ticks); while(SDL_PollEvent(&evt)) { switch(evt.type) { case SDL_QUIT: quit = true; break; case SDL_KEYDOWN: if(mainui.activeInput !is null) { Cursor cursor = mainui.activeInput.cursor; if(cursor !is null) cursor.reset(); } mods = evt.key.keysym.mod; key = evt.key.keysym.sym; unicode = evt.key.keysym.unicode; mods &= 0xffffff - KMOD_NUM; auto keyinfo = Keyinfo(key, mods, unicode); com.kbd.translate(keyinfo); // FIXME version(OSX) { if (key == SDLK_q && evt.key.keysym.mod & KMOD_GUI) quit=true; } mainui.keypress(keyinfo); if(mainui.exitRequested) quit = true; mainui.update(); break; case SDL_KEYUP: mods = evt.key.keysym.mod; key = evt.key.keysym.sym; unicode = evt.key.keysym.unicode; mods &= 0xffff - KMOD_NUM; Keyinfo keyinfo = Keyinfo(key, mods, unicode); // com.kbd.translate(keyinfo); mainui.keyrelease(keyinfo); break; case SDL_MOUSEBUTTONDOWN: switch(evt.button.button) { case 1, 3: int x, y; SDL_GetMouseState(&x, &y); video.scalePosition(x, y); int cx = (x + 4) / 8, cy = y / 14; mainui.clickedAt(cx, cy, evt.button.button); break; case 5: //rootwin.windowByCoord(cx, cy).mousewheelDown(); mainui.keypress(Keyinfo(SDLK_DOWN, 0, 0)); break; case 4: mainui.keypress(Keyinfo(SDLK_UP, 0, 0)); break; default: break; } mainui.update(); break; case SDL_MOUSEMOTION: break; // case SDL_ACTIVEEVENT: //break; //case SDL_VIDEORESIZE: //video.resizeEvent(evt.resize.w, evt.resize.h); //break; //case SDL_VIDEOEXPOSE: //mainui.update(); //break; case SDL_WINDOWEVENT: if (evt.window.event == SDL_WINDOWEVENT_RESIZED) { video.resizeEvent(evt.window.data1, evt.window.data2); } break; default: //writeln("Unknown SDL event ",evt.type); break; } } if(mainui.activeInput !is null) { mainui.activeInput.update(); Cursor cursor = mainui.activeInput.cursor; if(cursor !is null) cursor.blink(); } SDL_Delay(40); video.updateFrame(); } } void printheader() { stderr.writefln("CheeseCutter (C) 2009-15 Abaddon"); stderr.writefln("Released under GNU GPL."); stderr.writef("\n"); stderr.writefln("Usage: ccutter [OPTION]... [FILE]"); stderr.writef("\n"); stderr.writefln("Options:"); stderr.writefln(" -b [value] Set playback buffer size (def=%d)", audio.audio.bufferSize); stderr.writefln(" -nofp Do not use resid-fp emulation"); stderr.writefln(" -fpr [x] Specify filter preset. x = 0..16 for 6581 and 0..1 for 8580"); stderr.writefln(" -i Disable resid interpolation (use fast mode instead)"); stderr.writefln(" -m [0|1] Specify SID model for reSID (6581/8580) (def=0)"); stderr.writefln(" -n Enable NTSC mode"); stderr.writefln(" -r [value] Set playback frequency (def=48000)"); stderr.writef("\n"); } int main(char[][] args) { int i; bool fs = false; string filename; bool fnDefined = false; // DerelictSDL2.load(); scope(exit) { SDL_Quit(); } scope(failure) { if(song !is null) { stderr.writefln("Crashed! Saving backup..."); song.save("_backup.ct"); } } try { i = 1; while(i < args.length) { switch(args[i]) { case "-h", "-help", "--help", "-?": printheader(); return 0; case "-m": sidtype = to!int(args[i+1]); if(sidtype != 0 && sidtype != 1 && sidtype != 6581 && sidtype != 8580) throw new UserException("Incorrect SID type; specify 0 for 6581 or 1 for 8580"); i++; break; case "-fpr": int fprarg = to!int(args[i+1]); sidtype ? (audio.player.curfp8580 = cast(int)(fprarg % FP8580.length)) : (audio.player.curfp6581 = cast(int)(fprarg % FP6581.length)); i++; break; case "-i": audio.player.interpolate = 0; break; case "-l": audio.player.badline = 1; break; case "-n": audio.player.ntsc = 1; break; case "-r": audio.audio.freq = to!int(args[i+1]); i++; break; case "-b": audio.audio.bufferSize = to!int(args[i+1]); i++; break; case "-nofp": audio.player.usefp = 0; break; default: version (OSX) { if (args[i].length > 3 && args[i][0..4] == "-psn"){ break; } } if(args[i][0] == '-') throw new UserException(format("Unrecognized option %s", args[i])); if(fnDefined) throw new UserException("Filename already defined."); filename = cast(string)args[i].dup; if(std.file.exists(filename) == 0 || std.file.isDir(filename)) { throw new UserException("File not found!"); } fnDefined = true; break; } i++; } } catch(UserException e) { std.stdio.stderr.writeln(e); return -1; } audio.player.init(); if (!initVideo()) { writeln("Video init failed: ", SDL_GetError().fromStringz); SDL_Quit(); return -1; } initSession(); mainui = new UI(); loadFile(filename); video.updateFrame(); SDL_PauseAudio(0); mainloop(); audio.audio.audio_close(); return 0; } void openFile(char* filename){ string str = to!(string)(filename); loadFile(str); } void loadFile(string filename){ if(filename && mainui) { string dir, fn; int sep = cast(int) filename.lastIndexOf(DIR_SEPARATOR); fn = filename[sep + 1..$]; if(sep >= 0) dir = filename[0 .. sep]; else dir = "."; chdir(dir); mainui.loadCallback(fn); mainui.update(); } } CheeseCutter-2.10/src/resid-fp/000077500000000000000000000000001516216315000163175ustar00rootroot00000000000000CheeseCutter-2.10/src/resid-fp/envelopefp.cpp000066400000000000000000000226711516216315000211760ustar00rootroot00000000000000// --------------------------------------------------------------------------- // This file is part of reSID, a MOS6581 SID emulator engine. // Copyright (C) 2004 Dag Lem // // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; either version 2 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public 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 "envelopefp.h" #include "sidfp.h" void EnvelopeGeneratorFP::set_nonlinearity(float nl) { for (int i = 0; i < 256; i ++) env_dac[i] = SIDFP::kinked_dac(i, nl, 8); } // ---------------------------------------------------------------------------- // Constructor. // ---------------------------------------------------------------------------- EnvelopeGeneratorFP::EnvelopeGeneratorFP() { reset(); } // ---------------------------------------------------------------------------- // SID reset. // ---------------------------------------------------------------------------- void EnvelopeGeneratorFP::reset() { muted = false; envelope_counter = 0; envelope_counter_dac = 0; attack = 0; decay = 0; sustain = 0; release = 0; gate = 0; rate_counter = 0; exponential_counter = 0; exponential_counter_period = 1; state = RELEASE; rate_period = rate_counter_period[release]; hold_zero = true; } void EnvelopeGeneratorFP::mute(bool enable) { muted = enable; } // Rate counter periods are calculated from the Envelope Rates table in // the Programmer's Reference Guide. The rate counter period is the number of // cycles between each increment of the envelope counter. // The rates have been verified by sampling ENV3. // // The rate counter is a 16 bit register which is incremented each cycle. // When the counter reaches a specific comparison value, the envelope counter // is incremented (attack) or decremented (decay/release) and the // counter is zeroed. // // NB! Sampling ENV3 shows that the calculated values are not exact. // It may seem like most calculated values have been rounded (.5 is rounded // down) and 1 has beed added to the result. A possible explanation for this // is that the SID designers have used the calculated values directly // as rate counter comparison values, not considering a one cycle delay to // zero the counter. This would yield an actual period of comparison value + 1. // // The time of the first envelope count can not be exactly controlled, except // possibly by resetting the chip. Because of this we cannot do cycle exact // sampling and must devise another method to calculate the rate counter // periods. // // The exact rate counter periods can be determined e.g. by counting the number // of cycles from envelope level 1 to envelope level 129, and dividing the // number of cycles by 128. CIA1 timer A and B in linked mode can perform // the cycle count. This is the method used to find the rates below. // // To avoid the ADSR delay bug, sampling of ENV3 should be done using // sustain = release = 0. This ensures that the attack state will not lower // the current rate counter period. // // The ENV3 sampling code below yields a maximum timing error of 14 cycles. // lda #$01 // l1: cmp $d41c // bne l1 // ... // lda #$ff // l2: cmp $d41c // bne l2 // // This yields a maximum error for the calculated rate period of 14/128 cycles. // The described method is thus sufficient for exact calculation of the rate // periods. // reg16 EnvelopeGeneratorFP::rate_counter_period[] = { 9, // 2ms*1.0MHz/256 = 7.81 32, // 8ms*1.0MHz/256 = 31.25 63, // 16ms*1.0MHz/256 = 62.50 95, // 24ms*1.0MHz/256 = 93.75 149, // 38ms*1.0MHz/256 = 148.44 220, // 56ms*1.0MHz/256 = 218.75 267, // 68ms*1.0MHz/256 = 265.63 313, // 80ms*1.0MHz/256 = 312.50 392, // 100ms*1.0MHz/256 = 390.63 977, // 250ms*1.0MHz/256 = 976.56 1954, // 500ms*1.0MHz/256 = 1953.13 3126, // 800ms*1.0MHz/256 = 3125.00 3907, // 1 s*1.0MHz/256 = 3906.25 11720, // 3 s*1.0MHz/256 = 11718.75 19532, // 5 s*1.0MHz/256 = 19531.25 31251 // 8 s*1.0MHz/256 = 31250.00 }; // For decay and release, the clock to the envelope counter is sequentially // divided by 1, 2, 4, 8, 16, 30, 1 to create a piece-wise linear approximation // of an exponential. The exponential counter period is loaded at the envelope // counter values 255, 93, 54, 26, 14, 6, 0. The period can be different for the // same envelope counter value, depending on whether the envelope has been // rising (attack -> release) or sinking (decay/release). // // Since it is not possible to reset the rate counter (the test bit has no // influence on the envelope generator whatsoever) a method must be devised to // do cycle exact sampling of ENV3 to do the investigation. This is possible // with knowledge of the rate period for A=0, found above. // // The CPU can be synchronized with ENV3 by first synchronizing with the rate // counter by setting A=0 and wait in a carefully timed loop for the envelope // counter _not_ to change for 9 cycles. We can then wait for a specific value // of ENV3 with another timed loop to fully synchronize with ENV3. // // At the first period when an exponential counter period larger than one // is used (decay or relase), one extra cycle is spent before the envelope is // decremented. The envelope output is then delayed one cycle until the state // is changed to attack. Now one cycle less will be spent before the envelope // is incremented, and the situation is normalized. // The delay is probably caused by the comparison with the exponential counter, // and does not seem to affect the rate counter. This has been verified by // timing 256 consecutive complete envelopes with A = D = R = 1, S = 0, using // CIA1 timer A and B in linked mode. If the rate counter is not affected the // period of each complete envelope is // (255 + 162*1 + 39*2 + 28*4 + 12*8 + 8*16 + 6*30)*32 = 756*32 = 32352 // which corresponds exactly to the timed value divided by the number of // complete envelopes. // NB! This one cycle delay is not modeled. // From the sustain levels it follows that both the low and high 4 bits of the // envelope counter are compared to the 4-bit sustain value. // This has been verified by sampling ENV3. // reg8 EnvelopeGeneratorFP::sustain_level[] = { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff, }; // ---------------------------------------------------------------------------- // Register functions. // ---------------------------------------------------------------------------- void EnvelopeGeneratorFP::writeCONTROL_REG(reg8 control) { reg8 gate_next = control & 0x01; // The rate counter is never reset, thus there will be a delay before the // envelope counter starts counting up (attack) or down (release). // Gate bit on: Start attack, decay, sustain. if (!gate && gate_next) { state = ATTACK; update_rate_period(rate_counter_period[attack]); // Switching to attack state unlocks the zero freeze. hold_zero = false; } // Gate bit off: Start release. else if (gate && !gate_next) { state = RELEASE; update_rate_period(rate_counter_period[release]); } gate = gate_next; } void EnvelopeGeneratorFP::writeATTACK_DECAY(reg8 attack_decay) { attack = (attack_decay >> 4) & 0x0f; decay = attack_decay & 0x0f; if (state == ATTACK) { update_rate_period(rate_counter_period[attack]); } else if (state == DECAY_SUSTAIN) { update_rate_period(rate_counter_period[decay]); } } void EnvelopeGeneratorFP::writeSUSTAIN_RELEASE(reg8 sustain_release) { sustain = (sustain_release >> 4) & 0x0f; release = sustain_release & 0x0f; if (state == RELEASE) { update_rate_period(rate_counter_period[release]); } } void EnvelopeGeneratorFP::update_rate_period(reg16 newperiod) { rate_period = newperiod; /* The ADSR counter is XOR shift register with 0x7fff unique values. * If the rate_period is adjusted to a value already seen in this cycle, * the register will wrap around. This is known as the ADSR delay bug. * * To simplify the hot path calculation, we simulate this through observing * that we add the 0x7fff cycle delay by changing the rate_counter variable * directly. This takes care of the 99 % common case. However, playroutine * could make multiple consequtive rate_period adjustments, in which case we * need to cancel the previous adjustment. */ /* if the new period exeecds 0x7fff, we need to wrap */ if (rate_period - rate_counter > 0x7fff) rate_counter += 0x7fff; /* simulate 0x7fff wraparound, if the period-to-be-written * is less than the current value. */ if (rate_period <= rate_counter) rate_counter -= 0x7fff; /* at this point it should be impossible for * rate_counter >= rate_period. If it is, there is a bug... */ } reg8 EnvelopeGeneratorFP::readENV() { return envelope_counter; } CheeseCutter-2.10/src/resid-fp/envelopefp.h000066400000000000000000000124301516216315000206330ustar00rootroot00000000000000// --------------------------------------------------------------------------- // This file is part of reSID, a MOS6581 SID emulator engine. // Copyright (C) 2004 Dag Lem // // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; either version 2 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public 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 __ENVELOPEFP_H__ #define __ENVELOPEFP_H__ #include "siddefsfp.h" extern float env_dac[256]; // ---------------------------------------------------------------------------- // A 15 bit counter is used to implement the envelope rates, in effect // dividing the clock to the envelope counter by the currently selected rate // period. // In addition, another counter is used to implement the exponential envelope // decay, in effect further dividing the clock to the envelope counter. // The period of this counter is set to 1, 2, 4, 8, 16, 30 at the envelope // counter values 255, 93, 54, 26, 14, 6, respectively. // ---------------------------------------------------------------------------- class EnvelopeGeneratorFP { public: EnvelopeGeneratorFP(); enum State { ATTACK, DECAY_SUSTAIN, RELEASE }; inline void clock(); void reset(); void mute(bool enable); void writeCONTROL_REG(reg8); void writeATTACK_DECAY(reg8); void writeSUSTAIN_RELEASE(reg8); reg8 readENV(); inline float output(); protected: void set_nonlinearity(float nl); void update_rate_period(reg16 period); int rate_counter; int rate_period; reg8 exponential_counter; reg8 exponential_counter_period; reg8 envelope_counter; float envelope_counter_dac; bool hold_zero; bool muted; reg4 attack; reg4 decay; reg4 sustain; reg4 release; reg8 gate; State state; // Lookup table to convert from attack, decay, or release value to rate // counter period. static reg16 rate_counter_period[]; // The 16 selectable sustain levels. static reg8 sustain_level[]; friend class SIDFP; }; // ---------------------------------------------------------------------------- // SID clocking - 1 cycle. // ---------------------------------------------------------------------------- inline void EnvelopeGeneratorFP::clock() { if (++ rate_counter != rate_period) return; rate_counter = 0; // The first envelope step in the attack state also resets the exponential // counter. This has been verified by sampling ENV3. // if (state == ATTACK || ++exponential_counter == exponential_counter_period) { exponential_counter = 0; // Check whether the envelope counter is frozen at zero. if (hold_zero) { return; } switch (state) { case ATTACK: // The envelope counter can flip from 0xff to 0x00 by changing state to // release, then to attack. The envelope counter is then frozen at // zero; to unlock this situation the state must be changed to release, // then to attack. This has been verified by sampling ENV3. // ++envelope_counter &= 0xff; if (envelope_counter == 0xff) { state = DECAY_SUSTAIN; update_rate_period(rate_counter_period[decay]); } break; case DECAY_SUSTAIN: if (envelope_counter != sustain_level[sustain]) { --envelope_counter; } break; case RELEASE: // The envelope counter can flip from 0x00 to 0xff by changing state to // attack, then to release. The envelope counter will then continue // counting down in the release state. // This has been verified by sampling ENV3. // NB! The operation below requires two's complement integer. // --envelope_counter &= 0xff; break; } // Check for change of exponential counter period. switch (envelope_counter) { case 0xff: exponential_counter_period = 1; break; case 0x5d: exponential_counter_period = 2; break; case 0x36: exponential_counter_period = 4; break; case 0x1a: exponential_counter_period = 8; break; case 0x0e: exponential_counter_period = 16; break; case 0x06: exponential_counter_period = 30; break; case 0x00: exponential_counter_period = 1; // When the envelope counter is changed to zero, it is frozen at zero. // This has been verified by sampling ENV3. hold_zero = true; break; } envelope_counter_dac = muted ? 0.f : env_dac[envelope_counter]; } } // ---------------------------------------------------------------------------- // Read the envelope generator output. // ---------------------------------------------------------------------------- inline float EnvelopeGeneratorFP::output() { return envelope_counter_dac; } #endif // not __ENVELOPE_H__ CheeseCutter-2.10/src/resid-fp/extfiltfp.cpp000066400000000000000000000041101516216315000210240ustar00rootroot00000000000000// --------------------------------------------------------------------------- // This file is part of reSID, a MOS6581 SID emulator engine. // Copyright (C) 2004 Dag Lem // // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; either version 2 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public 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 "extfiltfp.h" const float pass_frequency = 15915.6f; // ---------------------------------------------------------------------------- // Constructor. // ---------------------------------------------------------------------------- ExternalFilterFP::ExternalFilterFP() { reset(); set_clock_frequency(1e6f); } // ---------------------------------------------------------------------------- // Setup of the external filter sampling parameters. // ---------------------------------------------------------------------------- void ExternalFilterFP::set_clock_frequency(float clock_frequency) { // Low-pass: R = 10kOhm, C = 1000pF; w0l = 1/RC = 1/(1e4*1e-9) = 100000 // High-pass: R = 1kOhm, C = 10uF; w0h = 1/RC = 1/(1e3*1e-5) = 100 w0hp = 100.f / clock_frequency; w0lp = pass_frequency * 2.f * static_cast(M_PI) / clock_frequency; } // ---------------------------------------------------------------------------- // SID reset. // ---------------------------------------------------------------------------- void ExternalFilterFP::reset() { // State of filter. Vlp = 0; Vhp = 0; } CheeseCutter-2.10/src/resid-fp/extfiltfp.h000066400000000000000000000061171516216315000205020ustar00rootroot00000000000000// --------------------------------------------------------------------------- // This file is part of reSID, a MOS6581 SID emulator engine. // Copyright (C) 2004 Dag Lem // // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; either version 2 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public 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 __EXTFILTFP_H__ #define __EXTFILTFP_H__ #include #include "siddefsfp.h" // ---------------------------------------------------------------------------- // The audio output stage in a Commodore 64 consists of two STC networks, // a low-pass filter with 3-dB frequency 16kHz followed by a high-pass // filter with 3-dB frequency 16Hz (the latter provided an audio equipment // input impedance of 1kOhm). // The STC networks are connected with a BJT supposedly meant to act as // a unity gain buffer, which is not really how it works. A more elaborate // model would include the BJT, however DC circuit analysis yields BJT // base-emitter and emitter-base impedances sufficiently low to produce // additional low-pass and high-pass 3dB-frequencies in the order of hundreds // of kHz. This calls for a sampling frequency of several MHz, which is far // too high for practical use. // ---------------------------------------------------------------------------- class ExternalFilterFP { public: ExternalFilterFP(); void set_clock_frequency(float); inline void clock(float Vi); void reset(); // Audio output (20 bits). inline float output(); private: inline void nuke_denormals(); // State of filters. float Vlp; // lowpass float Vhp; // highpass // Cutoff frequencies. float w0lp; float w0hp; friend class SIDFP; }; // ---------------------------------------------------------------------------- // SID clocking - 1 cycle. // ---------------------------------------------------------------------------- inline void ExternalFilterFP::clock(float Vi) { float dVlp = w0lp * (Vi - Vlp); float dVhp = w0hp * (Vlp - Vhp); Vlp += dVlp; Vhp += dVhp; } // ---------------------------------------------------------------------------- // Audio output (19.5 bits). // ---------------------------------------------------------------------------- inline float ExternalFilterFP::output() { return Vlp - Vhp; } inline void ExternalFilterFP::nuke_denormals() { if (Vhp > -1e-12f && Vhp < 1e-12f) Vhp = 0; if (Vlp > -1e-12f && Vlp < 1e-12f) Vlp = 0; } #endif // not __EXTFILTFP_H__ CheeseCutter-2.10/src/resid-fp/filterfp.cpp000066400000000000000000000113531516216315000206410ustar00rootroot00000000000000// --------------------------------------------------------------------------- // This file is part of reSID, a MOS6581 SID emulator engine. // Copyright (C) 2004 Dag Lem // // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; either version 2 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // --------------------------------------------------------------------------- // Filter distortion code written by Antti S. Lankila 2007 - 2009. #include "filterfp.h" #include "sidfp.h" // ---------------------------------------------------------------------------- // Constructor. // ---------------------------------------------------------------------------- FilterFP::FilterFP() { model = (chip_model) 0; // neither 6581/8580; init time only enable_filter(true); /* approximate; sid.cc calls us when set_sampling_parameters() occurs. */ set_clock_frequency(1e6f); /* these parameters are a work-in-progress. */ set_distortion_properties(0.5f, 3.3e6f, 3.0e-4f); /* sound similar to alankila6581r4ar3789 */ set_type3_properties(1299501.5675945764f, 284015710.29875594f, 1.0065089724604026f, 18741.324073610594f); /* sound similar to trurl8580r5_3691 */ set_type4_properties(6.55f, 20.f); reset(); set_chip_model(MOS6581); } // ---------------------------------------------------------------------------- // Enable filter. // ---------------------------------------------------------------------------- void FilterFP::enable_filter(bool enable) { enabled = enable; if (! enabled) filt = 0; // XXX should also restore this... } // ---------------------------------------------------------------------------- // Set chip model. // ---------------------------------------------------------------------------- void FilterFP::set_chip_model(chip_model model) { this->model = model; set_Q(); set_w0(); } void FilterFP::set_nonlinearity(float nl) { nonlinearity = nl; set_w0(); } /* dist_CT eliminates 1/x at hot spot */ void FilterFP::set_clock_frequency(float clock) { clock_frequency = clock; distortion_CT = 1.f / (sidcaps_6581 * clock_frequency); set_w0(); } void FilterFP::set_distortion_properties(float a, float nl, float il) { attenuation = a; distortion_nonlinearity = nl; intermixing_leaks = il; set_w0(); } void FilterFP::set_type4_properties(float k, float b) { type4_k = k; type4_b = b; set_w0(); } void FilterFP::set_type3_properties(float br, float o, float s, float mfr) { type3_baseresistance = br; type3_offset = o; type3_steepness = -logf(s) / FC_TO_OSC; /* s^x to e^(x*ln(s)), 1/e^x == e^-x. */ type3_minimumfetresistance = mfr; set_w0(); } // ---------------------------------------------------------------------------- // SID reset. // ---------------------------------------------------------------------------- void FilterFP::reset() { fc = 0; res = filt = voice3off = hp_bp_lp = 0; vol = 0; volf = Vhp = Vbp = Vlp = 0; type3_fc_kink_exp = 0; type4_w0_cache = 0; set_w0(); set_Q(); } // ---------------------------------------------------------------------------- // Register functions. // ---------------------------------------------------------------------------- void FilterFP::writeFC_LO(reg8 fc_lo) { fc = (fc & 0x7f8) | (fc_lo & 0x007); set_w0(); } void FilterFP::writeFC_HI(reg8 fc_hi) { fc = ((fc_hi << 3) & 0x7f8) | (fc & 0x007); set_w0(); } void FilterFP::writeRES_FILT(reg8 res_filt) { res = (res_filt >> 4) & 0x0f; set_Q(); filt = enabled ? res_filt & 0x0f : 0; } void FilterFP::writeMODE_VOL(reg8 mode_vol) { voice3off = mode_vol & 0x80; hp_bp_lp = mode_vol >> 4; vol = mode_vol & 0x0f; volf = static_cast(vol) / 15.f; } // Set filter cutoff frequency. void FilterFP::set_w0() { if (model == MOS6581) { float type3_fc_kink = SIDFP::kinked_dac(fc, nonlinearity, 11); type3_fc_kink_exp = type3_offset * expf(type3_fc_kink * type3_steepness * FC_TO_OSC); } if (model == MOS8580) { type4_w0_cache = type4_w0(); } } // Set filter resonance. void FilterFP::set_Q() { if (model == MOS6581) { _1_div_Q = 1.f / (0.5f + res / 20.f); } else { _1_div_Q = 1.f / (0.707f + res / 15.f); } } CheeseCutter-2.10/src/resid-fp/filterfp.h000066400000000000000000000255201516216315000203070ustar00rootroot00000000000000// This file is part of reSID, a MOS6581 SID emulator engine. // Copyright (C) 2004 Dag Lem // // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; either version 2 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // --------------------------------------------------------------------------- // Filter distortion code written by Antti S. Lankila 2007 - 2009. #ifndef __FILTERFP_H__ #define __FILTERFP_H__ #define M_LN2 0.69314718055994530942 /* log_e 2 */ #define M_PI 3.14159265358979323846 /* pi */ #include #include "siddefsfp.h" // ---------------------------------------------------------------------------- // The SID filter is modeled with a two-integrator-loop biquadratic filter, // which has been confirmed by Bob Yannes to be the actual circuit used in // the SID chip. // // Measurements show that excellent emulation of the SID filter is achieved, // except when high resonance is combined with high sustain levels. // In this case the SID op-amps are performing less than ideally and are // causing some peculiar behavior of the SID filter. This however seems to // have more effect on the overall amplitude than on the color of the sound. // // The theory for the filter circuit can be found in "Microelectric Circuits" // by Adel S. Sedra and Kenneth C. Smith. // The circuit is modeled based on the explanation found there except that // an additional inverter is used in the feedback from the bandpass output, // allowing the summer op-amp to operate in single-ended mode. This yields // inverted filter outputs with levels independent of Q, which corresponds with // the results obtained from a real SID. // // We have been able to model the summer and the two integrators of the circuit // to form components of an IIR filter. // Vhp is the output of the summer, Vbp is the output of the first integrator, // and Vlp is the output of the second integrator in the filter circuit. // // According to Bob Yannes, the active stages of the SID filter are not really // op-amps. Rather, simple NMOS inverters are used. By biasing an inverter // into its region of quasi-linear operation using a feedback resistor from // input to output, a MOS inverter can be made to act like an op-amp for // small signals centered around the switching threshold. // // Qualified guesses at SID filter schematics are depicted below. // // SID filter // ---------- // // ----------------------------------------------- // | | // | ---Rq-- | // | | | | // | --------------|--R-----[A>--|--R-----[A>--| // | | | | // vi -----R1-- | | | // // vhp vbp vlp // // // vi - input voltage // vhp - highpass output // vbp - bandpass output // vlp - lowpass output // [A> - op-amp // R1 - summer resistor // Rq - resistor array controlling resonance (4 resistors) // R - NMOS FET voltage controlled resistor controlling cutoff frequency // Rs - shunt resitor // C - capacitor // // // // SID integrator // -------------- // // V+ // // | // | // -----| // | | // | ||-- // -|| // ---C--- ||-> // | | | // |---Rs-----------|---- vo // | | // | ||-- // vi ---- -----|------------|| // | ^ | ||-> // |___| | | // ----- | | // | | | // |---R2-- | // | // R1 V- // | // | // // Vw // // ---------------------------------------------------------------------------- class FilterFP { public: FilterFP(); void enable_filter(bool enable); void set_chip_model(chip_model model); void set_distortion_properties(float, float, float); void set_type3_properties(float, float, float, float); void set_type4_properties(float, float); void set_clock_frequency(float); void set_nonlinearity(float); inline float clock(float voice1, float voice2, float voice3, float ext_in); void reset(); // Write registers. void writeFC_LO(reg8); void writeFC_HI(reg8); void writeRES_FILT(reg8); void writeMODE_VOL(reg8); private: void set_Q(); void set_w0(); float type3_w0(const float dist); float type4_w0(); void calculate_helpers(); void nuke_denormals(); float waveshaper1(float value); float waveshaper2(float value); // Filter enabled. bool enabled; // 6581/8580 filter model (XXX: we should specialize in separate classes) chip_model model; // Filter cutoff frequency. reg12 fc; // Filter resonance. reg8 res; // Selects which inputs to route through filter. reg8 filt; // Switch voice 3 off. reg8 voice3off; // Highpass, bandpass, and lowpass filter modes. reg8 hp_bp_lp; // Output master volume. reg4 vol; float volf; /* avoid integer-to-float conversion at output */ // clock float clock_frequency; /* Distortion params for Type3 */ float attenuation, distortion_nonlinearity, intermixing_leaks; /* Type3 params. */ float type3_baseresistance, type3_offset, type3_steepness, type3_minimumfetresistance; /* Type4 params */ float type4_k, type4_b; // State of filter. float Vhp, Vbp, Vlp; /* Resonance/Distortion/Type3/Type4 helpers. */ float type4_w0_cache, _1_div_Q, type3_fc_kink_exp, distortion_CT; float nonlinearity; friend class SIDFP; }; // ---------------------------------------------------------------------------- // Inline functions. // The following functions are defined inline because they are called every // time a sample is calculated. // ---------------------------------------------------------------------------- const float sidcaps_6581 = 470e-12f; const float FC_TO_OSC = 512.f; inline static float fastexp(float val) { typedef union { int i; float f; } conv; conv tmp; /* single precision fp has 1 + 8 + 23 bits, exponent bias is 127. * It therefore follows that we need to shift left by 23 bits, and to * calculate exp(x) instead of pow(2, x) we divide the power by ln(2). */ const float a = static_cast((1 << 23) / M_LN2); /* The other factor corrects for the exponent bias so that 2^0 = 1. */ const float b = static_cast((1 << 23) * 127); /* According to "A Fast, Compact Approximation of the Exponential Function" * by Nicol N. Schraudolph, 60801.48 yields the minimum RMS error for the * piecewise-linear approximation when using doubles (20 bits residual). * We have 23 bits, so we scale this value by 8. */ const float c = 60801.48f * 8.f; /* Parenthesis are important: C standard disallows folding subtraction. * Unfortunately GCC appears to generate a write to memory rather than * handle this conversion entirely in registers. */ tmp.i = static_cast(a * val + (b - c + 0.5f)); return tmp.f; } inline float FilterFP::type3_w0(const float dist) { float fetresistance = type3_fc_kink_exp; if (dist > 0) { fetresistance *= fastexp(dist * type3_steepness); } const float dynamic_resistance = type3_minimumfetresistance + fetresistance; /* 2 parallel resistors */ const float _1_div_resistance = (type3_baseresistance + dynamic_resistance) / (type3_baseresistance * dynamic_resistance); /* 1.f / (clock * caps * resistance) */ return distortion_CT * _1_div_resistance; } inline float FilterFP::type4_w0() { const float freq = type4_k * fc + type4_b; return 2.f * static_cast(M_PI) * freq / clock_frequency; } inline float FilterFP::waveshaper1(float value) { if (value > distortion_nonlinearity) { value -= (value - distortion_nonlinearity) * 0.5f; } return value; } // ---------------------------------------------------------------------------- // SID clocking - 1 cycle. // ---------------------------------------------------------------------------- inline float FilterFP::clock(float voice1, float voice2, float voice3, float ext_in) { float Vi = 0.f, Vf = 0.f; // Route voices into or around filter. ((filt & 1) ? Vi : Vf) += voice1; ((filt & 2) ? Vi : Vf) += voice2; // NB! Voice 3 is not silenced by voice3off if it is routed through // the filter. if (filt & 4) { Vi += voice3; } else if (! voice3off) { Vf += voice3; } ((filt & 8) ? Vi : Vf) += ext_in; if (hp_bp_lp & 1) { Vf += Vlp; } if (hp_bp_lp & 2) { Vf += Vbp; } if (hp_bp_lp & 4) { Vf += Vhp; } if (model == MOS6581) { Vlp -= Vbp * type3_w0(Vbp); Vbp -= Vhp * type3_w0(Vhp); Vhp = (Vbp * _1_div_Q - Vlp - Vi * 0.85f) * attenuation; /* output strip mixing to filter state */ if (hp_bp_lp & 1) { Vlp += Vf * intermixing_leaks; } if (hp_bp_lp & 2) { Vbp += Vf * intermixing_leaks; } if (hp_bp_lp & 4) { Vhp += Vf * intermixing_leaks; } /* saturate. This is likely the output inverter saturation. */ Vf *= volf; Vf = waveshaper1(Vf); } else { /* On the 8580, BP appears mixed in phase with the rest. */ Vlp += Vbp * type4_w0_cache; Vbp += Vhp * type4_w0_cache; Vhp = -Vbp * _1_div_Q - Vlp - Vi; Vf *= volf; } return Vf; } inline void FilterFP::nuke_denormals() { /* We only need this for systems that don't do -msse and -mfpmath=sse */ if (Vbp > -1e-12f && Vbp < 1e-12f) Vbp = 0; if (Vlp > -1e-12f && Vlp < 1e-12f) Vlp = 0; } #endif // not __FILTER_H__ CheeseCutter-2.10/src/resid-fp/potfp.cpp000066400000000000000000000021061516216315000201520ustar00rootroot00000000000000// --------------------------------------------------------------------------- // This file is part of reSID, a MOS6581 SID emulator engine. // Copyright (C) 2004 Dag Lem // // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; either version 2 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public 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 "potfp.h" reg8 PotentiometerFP::readPOT() { // NB! Not modeled. return 0xff; } CheeseCutter-2.10/src/resid-fp/potfp.h000066400000000000000000000021471516216315000176240ustar00rootroot00000000000000// --------------------------------------------------------------------------- // This file is part of reSID, a MOS6581 SID emulator engine. // Copyright (C) 2004 Dag Lem // // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; either version 2 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public 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 __POTFP_H__ #define __POTFP_H__ #include "siddefsfp.h" class PotentiometerFP { public: reg8 readPOT(); }; #endif CheeseCutter-2.10/src/resid-fp/siddefsfp.h000066400000000000000000000021271516216315000204410ustar00rootroot00000000000000// --------------------------------------------------------------------------- // This file is part of reSID, a MOS6581 SID emulator engine. // Copyright (C) 1999 Dag Lem // // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; either version 2 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public 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 __SIDDEFSFP_H__ #define __SIDDEFSFP_H__ #include "../resid/siddefs.h" #endif // not __SIDDEFSFP_H__ CheeseCutter-2.10/src/resid-fp/sidfp.cpp000066400000000000000000000604721516216315000201410ustar00rootroot00000000000000// --------------------------------------------------------------------------- // This file is part of reSID, a MOS6581 SID emulator engine. // Copyright (C) 2004 Dag Lem // // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; either version 2 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public 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 "sidfp.h" #include #define RINGSIZE 2048 #ifdef __SSE__ #include #endif /* tables used by voice/wavegen/envgen */ float dac[12]; float env_dac[256]; float wftable[11][4096]; void SIDFP::set_voice_nonlinearity(float nl) { /* all voices, waves, etc. share the same tables */ voice[0].envelope.set_nonlinearity(nl); voice[0].wave.set_nonlinearity(nl); voice[0].wave.rebuild_wftable(); filter.set_nonlinearity(nl); } float SIDFP::kinked_dac(const int x, const float nonlinearity, const int max) { float value = 0.f; int bit = 1; float weight = 1.f; const float dir = 2.0f * nonlinearity; for (int i = 0; i < max; i ++) { if (x & bit) value += weight; bit <<= 1; weight *= dir; } return value / (weight / nonlinearity / nonlinearity) * (1 << max); } // ---------------------------------------------------------------------------- // Constructor. // ---------------------------------------------------------------------------- SIDFP::SIDFP() { // Initialize pointers. sample = 0; fir = 0; lastsample[0] = lastsample[1] = lastsample[2] = 0; filtercyclegate = 0; set_sampling_parameters(985248, SAMPLE_INTERPOLATE, 44100); bus_value = 0; bus_value_ttl = 0; input(0); } // ---------------------------------------------------------------------------- // Destructor. // ---------------------------------------------------------------------------- SIDFP::~SIDFP() { delete[] sample; delete[] fir; } // ---------------------------------------------------------------------------- // Set chip model. // ---------------------------------------------------------------------------- void SIDFP::set_chip_model(chip_model model) { for (int i = 0; i < 3; i++) { voice[i].set_chip_model(model); } voice[0].wave.rebuild_wftable(); filter.set_chip_model(model); } // ---------------------------------------------------------------------------- // SID reset. // ---------------------------------------------------------------------------- void SIDFP::reset() { for (int i = 0; i < 3; i++) { voice[i].reset(); } filter.reset(); extfilt.reset(); bus_value = 0; bus_value_ttl = 0; } // ---------------------------------------------------------------------------- // Write 16-bit sample to audio input. // NB! The caller is responsible for keeping the value within 16 bits. // Note that to mix in an external audio signal, the signal should be // resampled to 1MHz first to avoid sampling noise. // ---------------------------------------------------------------------------- void SIDFP::input(int sample) { // Voice outputs are 20 bits. Scale up to match three voices in order // to facilitate simulation of the MOS8580 "digi boost" hardware hack. ext_in = static_cast((sample << 4) * 3); } // ---------------------------------------------------------------------------- // Read sample from audio output, 16-bit result. // Do not use this directly, rather use the high-quality resampling outputs. // ---------------------------------------------------------------------------- float SIDFP::output() { /* Scale to roughly -1 .. 1 range. Voices go from -2048 to 2048 or so, * envelope from 0 to 255, there are 3 voices, and there's factor of 2 * for resonance. */ return extfilt.output() * (1.f / (2047.f * 255.f * 3.0f * 2.0f)); } // ---------------------------------------------------------------------------- // Read registers. // // Reading a write only register returns the last byte written to any SID // register. The individual bits in this value start to fade down towards // zero after a few cycles. All bits reach zero within approximately // $2000 - $4000 cycles. // It has been claimed that this fading happens in an orderly fashion, however // sampling of write only registers reveals that this is not the case. // NB! This is not correctly modeled. // The actual use of write only registers has largely been made in the belief // that all SID registers are readable. To support this belief the read // would have to be done immediately after a write to the same register // (remember that an intermediate write to another register would yield that // value instead). With this in mind we return the last value written to // any SID register for $2000 cycles without modeling the bit fading. // ---------------------------------------------------------------------------- reg8 SIDFP::read(reg8 offset) { switch (offset) { case 0x19: return potx.readPOT(); case 0x1a: return poty.readPOT(); case 0x1b: return voice[2].wave.readOSC(voice[0].wave); case 0x1c: return voice[2].envelope.readENV(); default: return bus_value; } } // ---------------------------------------------------------------------------- // Write registers. // ---------------------------------------------------------------------------- void SIDFP::write(reg8 offset, reg8 value) { bus_value = value; bus_value_ttl = 34000; switch (offset) { case 0x00: voice[0].wave.writeFREQ_LO(value); break; case 0x01: voice[0].wave.writeFREQ_HI(value); break; case 0x02: voice[0].wave.writePW_LO(value); break; case 0x03: voice[0].wave.writePW_HI(value); break; case 0x04: voice[0].writeCONTROL_REG(voice[1].wave, value); break; case 0x05: voice[0].envelope.writeATTACK_DECAY(value); break; case 0x06: voice[0].envelope.writeSUSTAIN_RELEASE(value); break; case 0x07: voice[1].wave.writeFREQ_LO(value); break; case 0x08: voice[1].wave.writeFREQ_HI(value); break; case 0x09: voice[1].wave.writePW_LO(value); break; case 0x0a: voice[1].wave.writePW_HI(value); break; case 0x0b: voice[1].writeCONTROL_REG(voice[2].wave, value); break; case 0x0c: voice[1].envelope.writeATTACK_DECAY(value); break; case 0x0d: voice[1].envelope.writeSUSTAIN_RELEASE(value); break; case 0x0e: voice[2].wave.writeFREQ_LO(value); break; case 0x0f: voice[2].wave.writeFREQ_HI(value); break; case 0x10: voice[2].wave.writePW_LO(value); break; case 0x11: voice[2].wave.writePW_HI(value); break; case 0x12: voice[2].writeCONTROL_REG(voice[0].wave, value); break; case 0x13: voice[2].envelope.writeATTACK_DECAY(value); break; case 0x14: voice[2].envelope.writeSUSTAIN_RELEASE(value); break; case 0x15: filter.writeFC_LO(value); break; case 0x16: filter.writeFC_HI(value); break; case 0x17: filter.writeRES_FILT(value); break; case 0x18: filter.writeMODE_VOL(value); break; default: break; } } // ---------------------------------------------------------------------------- // SID voice muting. // ---------------------------------------------------------------------------- void SIDFP::mute(reg8 channel, bool enable) { // Only have 3 voices! if (channel >= 3) return; voice[channel].mute (enable); } // ---------------------------------------------------------------------------- // Enable filter. // ---------------------------------------------------------------------------- void SIDFP::enable_filter(bool enable) { filter.enable_filter(enable); } // ---------------------------------------------------------------------------- // I0() computes the 0th order modified Bessel function of the first kind. // This function is originally from resample-1.5/filterkit.c by J. O. Smith. // ---------------------------------------------------------------------------- double SIDFP::I0(double x) { // Max error acceptable in I0 could be 1e-6, which gives that 96 dB already. // I'm overspecify these errors to get a beautiful FFT dump of the FIR. const double I0e = 1e-10; double sum, u, halfx, temp; int n; sum = u = n = 1; halfx = x/2.0; do { temp = halfx/n++; u *= temp*temp; sum += u; } while (u >= I0e*sum); return sum; } // ---------------------------------------------------------------------------- // Setting of SID sampling parameters. // // Use a clock freqency of 985248Hz for PAL C64, 1022730Hz for NTSC C64. // The default end of passband frequency is pass_freq = 0.9*sample_freq/2 // for sample frequencies up to ~ 44.1kHz, and 20kHz for higher sample // frequencies. // // For resampling, the ratio between the clock frequency and the sample // frequency is limited as follows: // 125*clock_freq/sample_freq < 16384 // E.g. provided a clock frequency of ~ 1MHz, the sample frequency can not // be set lower than ~ 8kHz. A lower sample frequency would make the // resampling code overfill its 16k sample ring buffer. // // The end of passband frequency is also limited: // pass_freq <= 0.9*sample_freq/2 // E.g. for a 44.1kHz sampling rate the end of passband frequency is limited // to slightly below 20kHz. This constraint ensures that the FIR table is // not overfilled. // ---------------------------------------------------------------------------- bool SIDFP::set_sampling_parameters(double clock_freq, sampling_method method, double sample_freq, double pass_freq) { filter.set_clock_frequency(static_cast(clock_freq * 0.5)); extfilt.set_clock_frequency(static_cast(clock_freq * 0.5)); cycles_per_sample = static_cast(clock_freq / sample_freq); // FIR initialization is only necessary for resampling. if (method != SAMPLE_RESAMPLE_INTERPOLATE) { sampling = method; delete[] sample; delete[] fir; sample = 0; fir = 0; sample_prev = 0; return true; } sample_offset = 0; // Allocate sample buffer. if (!sample) sample = new float[RINGSIZE*2]; // Clear sample buffer. for (int j = 0; j < RINGSIZE*2; j++) sample[j] = 0; sample_index = 0; /* Up to 20 kHz or at most 90 % of passband if it's lower than 20 kHz. */ if (pass_freq > 20000) pass_freq = 20000; if (2*pass_freq/sample_freq > 0.9) pass_freq = 0.9*sample_freq/2; // 16 bits -> -96dB stopband attenuation. const double A = -20*log10(1.0/(1 << 16)); // For calculation of beta and N see the reference for the kaiserord // function in the MATLAB Signal Processing Toolbox: // http://www.mathworks.com/access/helpdesk/help/toolbox/signal/kaiserord.html const double beta = 0.1102*(A - 8.7); const double I0beta = I0(beta); // Since we clock the filter at half the rate, we need to design the FIR // with the reduced rate in mind. double f_cycles_per_sample = (clock_freq * 0.5)/sample_freq; double f_samples_per_cycle = sample_freq/(clock_freq * 0.5); double aliasing_allowance = sample_freq / 2 - 20000; // no allowance to 20 kHz if (aliasing_allowance < 0) aliasing_allowance = 0; double transition_bandwidth = sample_freq/2 - pass_freq + aliasing_allowance; { // The filter order will maximally be 124 with the current constraints. // N >= (96.33 - 7.95)/(2 * pi * 2.285 * (maxfreq - passbandfreq) >= 123 // The filter order is equal to the number of zero crossings, i.e. // it should be an even number (sinc is symmetric about x = 0). // // XXX: analysis indicates that the filter is slighly overspecified by // there constraints. Need to check why. One possibility is the // level of audio being in truth closer to 15-bit than 16-bit. int N = static_cast((A - 7.95)/(2 * M_PI * 2.285 * transition_bandwidth/sample_freq) + 0.5); N += N & 1; // The filter length is equal to the filter order + 1. // The filter length must be an odd number (sinc is symmetric about x = 0). fir_N = static_cast(N*f_cycles_per_sample) + 1; fir_N |= 1; // Check whether the sample ring buffer would overfill. if (fir_N > RINGSIZE - 1) return false; /* Error is bound by 1.234 / L^2, so for 16-bit: sqrt(1.234 * (1 << 16)) */ fir_RES = static_cast(sqrt(1.234 * (1 << 16)) / f_cycles_per_sample + 0.5); } sampling = method; // Allocate memory for FIR tables. delete[] fir; fir = new float[fir_N*fir_RES]; // The cutoff frequency is midway through the transition band double wc = (pass_freq + transition_bandwidth/2) / sample_freq * M_PI * 2; // Calculate fir_RES FIR tables for linear interpolation. for (int i = 0; i < fir_RES; i++) { double j_offset = double(i)/fir_RES; // Calculate FIR table. This is the sinc function, weighted by the // Kaiser window. for (int j = 0; j < fir_N; j ++) { double jx = double(j) - fir_N/2.f - j_offset; double wt = wc*jx/f_cycles_per_sample; double temp = jx/(fir_N/2); double Kaiser = fabs(temp) <= 1 ? I0(beta*sqrt(1 - temp*temp))/I0beta : 0; // between 1e-7 and 1e-8 the FP result approximates to 1 due to FP limits double sincwt = fabs(wt) >= 1e-8 ? sin(wt)/wt : 1; fir[i * fir_N + j] = static_cast(f_samples_per_cycle*wc/M_PI*sincwt*Kaiser); } } return true; } inline void SIDFP::age_bus_value(cycle_count n) { // Age bus value. This is not supposed to be cycle exact, // so it should be safe to approximate. if (bus_value_ttl != 0) { bus_value_ttl -= n; if (bus_value_ttl <= 0) { bus_value = 0; bus_value_ttl = 0; } } } // ---------------------------------------------------------------------------- // SID clocking - 1 cycle. // ---------------------------------------------------------------------------- void SIDFP::clock() { // Clock amplitude modulators. for (int i = 0; i < 3; i++) { voice[i].envelope.clock(); voice[i].wave.clock(); } voice[0].wave.synchronize(voice[1].wave, voice[2].wave); voice[1].wave.synchronize(voice[2].wave, voice[0].wave); voice[2].wave.synchronize(voice[0].wave, voice[1].wave); /* because the analog parts are relatively expensive and do not really need * the precision of 1 MHz calculations, I average successive samples here to * reduce the cpu drain for filter calculations and output resampling. */ float voicestate[3]; voicestate[0] = voice[0].output(voice[2].wave); voicestate[1] = voice[1].output(voice[0].wave); voicestate[2] = voice[2].output(voice[1].wave); /* for every second sample in sequence, clock filter */ if (filtercyclegate ++ & 1) { extfilt.clock(filter.clock( (lastsample[0] + voicestate[0]) * 0.5f, (lastsample[1] + voicestate[1]) * 0.5f, (lastsample[2] + voicestate[2]) * 0.5f, ext_in )); } lastsample[0] = voicestate[0]; lastsample[1] = voicestate[1]; lastsample[2] = voicestate[2]; } // ---------------------------------------------------------------------------- // SID clocking with audio sampling. // // The example below shows how to clock the SID a specified amount of cycles // while producing audio output: // // while (delta_t) { // bufindex += sid.clock(delta_t, buf + bufindex, buflength - bufindex); // write(dsp, buf, bufindex*2); // bufindex = 0; // } // // ---------------------------------------------------------------------------- int SIDFP::clock(cycle_count& delta_t, short* buf, int n, int interleave) { /* XXX I assume n is generally large enough for delta_t here... */ age_bus_value(delta_t); /* We can only control that SSE is really used for GCC */ #if defined(__SSE__) && defined(__GNUC__) int old = _mm_getcsr(); _mm_setcsr(old | _MM_FLUSH_ZERO_ON); #endif int res; switch (sampling) { default: case SAMPLE_INTERPOLATE: res = clock_interpolate(delta_t, buf, n, interleave); break; case SAMPLE_RESAMPLE_INTERPOLATE: res = clock_resample_interpolate(delta_t, buf, n, interleave); break; } #if defined(__SSE__) && defined(__GNUC__) _mm_setcsr(old); #else filter.nuke_denormals(); extfilt.nuke_denormals(); #endif return res; } int SIDFP::clock_fast(cycle_count& delta_t, short* buf, int n, int interleave) { age_bus_value(delta_t); #if defined(__SSE__) && defined(__GNUC__) int old = _mm_getcsr(); _mm_setcsr(old | _MM_FLUSH_ZERO_ON); #endif int res = clock_interpolate(delta_t, buf, n, interleave); #if defined(__SSE__) && defined(__GNUC__) _mm_setcsr(old); #else filter.nuke_denormals(); extfilt.nuke_denormals(); #endif return res; } // ---------------------------------------------------------------------------- // SID clocking with audio sampling - cycle based with linear sample // interpolation. // // Here the chip is clocked every cycle. This yields higher quality // sound since the samples are linearly interpolated, and since the // external filter attenuates frequencies above 16kHz, thus reducing // sampling noise. // ---------------------------------------------------------------------------- inline int SIDFP::clock_interpolate(cycle_count& delta_t, short* buf, int n, int interleave) { int s = 0; int i; for (;;) { float next_sample_offset = sample_offset + cycles_per_sample; int delta_t_sample = static_cast(next_sample_offset); if (delta_t_sample > delta_t) { break; } if (s >= n) { return s; } for (i = 0; i < delta_t_sample - 1; i++) { clock(); } if (i < delta_t_sample) { sample_prev = output(); clock(); } delta_t -= delta_t_sample; sample_offset = next_sample_offset - delta_t_sample; float sample_now = output(); int sample_int = (int)((sample_prev + (sample_offset * (sample_now - sample_prev))) * 32768.0f); if (sample_int < -32768) sample_int = -32768; if (sample_int > 32767) sample_int = 32767; buf[s++ * interleave] = sample_int; sample_prev = sample_now; } for (i = 0; i < delta_t - 1; i++) { clock(); } if (i < delta_t) { sample_prev = output(); clock(); } sample_offset -= delta_t; delta_t = 0; return s; } static float convolve(const float *a, const float *b, int n) { float out = 0.f; #ifdef __SSE__ __m128 out4 = { 0, 0, 0, 0 }; /* examine if we can use aligned loads on both pointers -- some x86-32/64 * hackery here ... should use uintptr_t, but that needs --std=C99... */ int diff = static_cast(a - b) & 0xf; int a_align = static_cast(reinterpret_cast(a)) & 0xf; /* advance if necessary. We can't let n fall < 0, so no while (n --). */ while (n > 0 && a_align != 0 && a_align != 16) { out += (*(a ++)) * (*(b ++)); n --; a_align += 4; } if (diff == 0) { while (n >= 4) { out4 = _mm_add_ps(out4, _mm_mul_ps(_mm_load_ps(a), _mm_load_ps(b))); a += 4; b += 4; n -= 4; } } else { /* loadu is difficult to optimize: * * - using load and movhl tricks to sync the halves was not noticeably * faster, less than 1 % and that might have been measurement error. * - preparing copies of b for syncing with any alignment increased * memory pressure to the point that cache misses made it slower! */ while (n >= 4) { out4 = _mm_add_ps(out4, _mm_mul_ps(_mm_load_ps(a), _mm_loadu_ps(b))); a += 4; b += 4; n -= 4; } } /* sum the upper half of values with the lower half, pairwise */ out4 = _mm_add_ps(_mm_movehl_ps(out4, out4), out4); /* sum the value at slot 1 with the value at slot 0 */ out4 = _mm_add_ss(_mm_shuffle_ps(out4, out4, 1), out4); float out_tmp; /* save slot 0 to out_tmp, which is now 0+1+2+3 */ _mm_store_ss(&out_tmp, out4); out += out_tmp; #endif while (n --) out += (*(a ++)) * (*(b ++)); return out; } // ---------------------------------------------------------------------------- // SID clocking with audio sampling - cycle based with audio resampling. // // This is the theoretically correct (and computationally intensive) audio // sample generation. The samples are generated by resampling to the specified // sampling frequency. The work rate is inversely proportional to the // percentage of the bandwidth allocated to the filter transition band. // // This implementation is based on the paper "A Flexible Sampling-Rate // Conversion Method", by J. O. Smith and P. Gosset, or rather on the // expanded tutorial on the "Digital Audio Resampling Home Page": // http://www-ccrma.stanford.edu/~jos/resample/ // // By building shifted FIR tables with samples according to the // sampling frequency, this implementation dramatically reduces the // computational effort in the filter convolutions, without any loss // of accuracy. The filter convolutions are also vectorizable on // current hardware. // // Further possible optimizations are: // * An equiripple filter design could yield a lower filter order, see // http://www.mwrf.com/Articles/ArticleID/7229/7229.html // * The Convolution Theorem could be used to bring the complexity of // convolution down from O(n*n) to O(n*log(n)) using the Fast Fourier // Transform, see http://en.wikipedia.org/wiki/Convolution_theorem // * Simply resampling in two steps can also yield computational // savings, since the transition band will be wider in the first step // and the required filter order is thus lower in this step. // Laurent Ganier has found the optimal intermediate sampling frequency // to be (via derivation of sum of two steps): // 2 * pass_freq + sqrt [ 2 * pass_freq * orig_sample_freq // * (dest_sample_freq - 2 * pass_freq) / dest_sample_freq ] // // NB! the result of right shifting negative numbers is really // implementation dependent in the C++ standard. // ---------------------------------------------------------------------------- inline int SIDFP::clock_resample_interpolate(cycle_count& delta_t, short* buf, int n, int interleave) { int s = 0; for (;;) { float next_sample_offset = sample_offset + cycles_per_sample; /* full clocks left to next sample */ int delta_t_sample = static_cast(next_sample_offset); if (delta_t_sample > delta_t || s >= n) break; /* clock forward delta_t_sample samples */ for (int i = 0; i < delta_t_sample; i++) { clock(); if (filtercyclegate & 1) { sample[sample_index] = sample[sample_index + RINGSIZE] = output(); ++ sample_index; sample_index &= RINGSIZE - 1; } } delta_t -= delta_t_sample; /* Phase of the sample in terms of clock, [0 .. 1[. */ sample_offset = next_sample_offset - static_cast(delta_t_sample); /* find the first of the nearest fir tables close to the phase */ float fir_offset_rmd = sample_offset * fir_RES; int fir_offset = static_cast(fir_offset_rmd); /* [0 .. 1[ */ fir_offset_rmd -= static_cast(fir_offset); /* find fir_N most recent samples, plus one extra in case the FIR wraps. */ float* sample_start = sample + sample_index - fir_N + RINGSIZE - 1; float v1 = convolve(sample_start, fir + fir_offset * fir_N, fir_N); // Use next FIR table, wrap around to first FIR table using // the next sample. if (++ fir_offset == fir_RES) { fir_offset = 0; ++ sample_start; } float v2 = convolve(sample_start, fir + fir_offset * fir_N, fir_N); // Linear interpolation between the sinc tables yields good approximation // for the exact value. int sample_int = (int)((v1 + fir_offset_rmd * (v2 - v1)) * 32768.0f); if (sample_int < -32768) sample_int = -32768; if (sample_int > 32767) sample_int = 32767; buf[s++ * interleave] = sample_int; } /* clock forward delta_t samples */ for (int i = 0; i < delta_t; i++) { clock(); if (filtercyclegate & 1) { sample[sample_index] = sample[sample_index + RINGSIZE] = output(); ++ sample_index; sample_index &= RINGSIZE - 1; } } sample_offset -= static_cast(delta_t); delta_t = 0; return s; } CheeseCutter-2.10/src/resid-fp/sidfp.h000066400000000000000000000057011516216315000176000ustar00rootroot00000000000000// --------------------------------------------------------------------------- // This file is part of reSID, a MOS6581 SID emulator engine. // Copyright (C) 2004 Dag Lem // // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; either version 2 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public 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 __SIDFP_H__ #define __SIDFP_H__ #include "siddefsfp.h" #include "voicefp.h" #include "filterfp.h" #include "extfiltfp.h" #include "potfp.h" class SIDFP { public: SIDFP(); ~SIDFP(); static float kinked_dac(const int x, const float nonlinearity, const int bits); void set_chip_model(chip_model model); FilterFP& get_filter() { return filter; } void enable_filter(bool enable); bool set_sampling_parameters(double clock_freq, sampling_method method, double sample_freq, double pass_freq = 20000); void set_voice_nonlinearity(float nl); void clock(); int clock(cycle_count& delta_t, short* buf, int n, int interleave = 1); int clock_fast(cycle_count& delta_t, short* buf, int n, int interleave = 1); void reset(); // Read/write registers. reg8 read(reg8 offset); void write(reg8 offset, reg8 value); void mute(reg8 channel, bool enable); // 16-bit input (EXT IN). void input(int sample); // 16-bit output (AUDIO OUT). float output(); // Ring buffer with overflow for contiguous storage of RINGSIZE samples. float* sample; private: static double I0(double x); inline int clock_interpolate(cycle_count& delta_t, short* buf, int n, int interleave); inline int clock_resample_interpolate(cycle_count& delta_t, short* buf, int n, int interleave); inline void age_bus_value(cycle_count); VoiceFP voice[3]; FilterFP filter; ExternalFilterFP extfilt; PotentiometerFP potx; PotentiometerFP poty; reg8 bus_value; cycle_count bus_value_ttl; // External audio input. float ext_in; // Sampling variables. sampling_method sampling; float cycles_per_sample; float sample_offset; int sample_index; int fir_N; int fir_RES; /* for linear interpolation mode */ float sample_prev; // FIR_RES filter tables (FIR_N*FIR_RES). float* fir; /* analog parts are run at half the rate of digital ones. */ float lastsample[3]; unsigned char filtercyclegate; }; #endif // not __SIDFP_H__ CheeseCutter-2.10/src/resid-fp/versionfp.cpp000066400000000000000000000020311516216315000210320ustar00rootroot00000000000000// --------------------------------------------------------------------------- // This file is part of reSID, a MOS6581 SID emulator engine. // Copyright (C) 2004 Dag Lem // // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; either version 2 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // --------------------------------------------------------------------------- #define __VERSIONFP_CC__ #include "siddefsfp.h" CheeseCutter-2.10/src/resid-fp/voicefp.cpp000066400000000000000000000063661516216315000204710ustar00rootroot00000000000000// --------------------------------------------------------------------------- // This file is part of reSID, a MOS6581 SID emulator engine. // Copyright (C) 2004 Dag Lem // // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; either version 2 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public 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 "voicefp.h" // ---------------------------------------------------------------------------- // Constructor. // ---------------------------------------------------------------------------- VoiceFP::VoiceFP() { set_chip_model(MOS6581); } // ---------------------------------------------------------------------------- // Set chip model. // ---------------------------------------------------------------------------- void VoiceFP::set_chip_model(chip_model model) { wave.set_chip_model(model); if (model == MOS6581) { /* there is some level from each voice even if the env is down and osc * is stopped. You can hear this by routing a voice into filter (filter * should be kept disabled for this) as the master level changes. This * tunable affects the volume of digis. */ voice_DC = static_cast(0x800 * 0xff); /* In 8580 the waveforms seem well centered, but on the 6581 there is some * offset change as envelope grows, indicating that the waveforms are not * perfectly centered. The likely cause for this is the follows: * * The waveform DAC generates a voltage between 5 and 12 V corresponding * to oscillator state 0 .. 4095. * * The envelope DAC generates a voltage between waveform gen output and * the 5V level. * * The outputs are amplified against the 12V voltage and sent to the * mixer. * * The SID virtual ground is around 6.5 V. */ } else { voice_DC = 0.f; } } // ---------------------------------------------------------------------------- // Register functions. // ---------------------------------------------------------------------------- void VoiceFP::writeCONTROL_REG(WaveformGeneratorFP& source, reg8 control) { wave.writeCONTROL_REG(source, control); envelope.writeCONTROL_REG(control); } // ---------------------------------------------------------------------------- // SID reset. // ---------------------------------------------------------------------------- void VoiceFP::reset() { wave.reset(); envelope.reset(); } // ---------------------------------------------------------------------------- // VoiceFP mute. // ---------------------------------------------------------------------------- void VoiceFP::mute(bool enable) { envelope.mute(enable); } CheeseCutter-2.10/src/resid-fp/voicefp.h000066400000000000000000000036631516216315000201330ustar00rootroot00000000000000// --------------------------------------------------------------------------- // This file is part of reSID, a MOS6581 SID emulator engine. // Copyright (C) 2004 Dag Lem // // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; either version 2 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public 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 __VOICEFP_H__ #define __VOICEFP_H__ #include "siddefsfp.h" #include "wavefp.h" #include "envelopefp.h" class VoiceFP { public: VoiceFP(); void set_chip_model(chip_model model); void reset(); void mute(bool enable); void writeCONTROL_REG(WaveformGeneratorFP& source, reg8 value); // Amplitude modulated waveform output. // Range [-2048*255, 2047*255]. inline float output(WaveformGeneratorFP& source); protected: WaveformGeneratorFP wave; EnvelopeGeneratorFP envelope; // Multiplying D/A DC offset. float voice_DC; friend class SIDFP; }; // ---------------------------------------------------------------------------- // Amplitude modulated waveform output. // Ideal range [-2048*255, 2047*255]. // ---------------------------------------------------------------------------- inline float VoiceFP::output(WaveformGeneratorFP& source) { return wave.output(source) * envelope.output() + voice_DC; } #endif // not __VOICEFP_H__ CheeseCutter-2.10/src/resid-fp/wavefp.cpp000066400000000000000000000234411516216315000203170ustar00rootroot00000000000000// --------------------------------------------------------------------------- // This file is part of reSID, a MOS6581 SID emulator engine. // Copyright (C) 2004 Dag Lem // // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; either version 2 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public 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 "wavefp.h" #include "sidfp.h" typedef struct { float bias; float pulsestrength; float topbit; float distance; float stmix; } waveformconfig_t; const float sharpness = 512.f; const waveformconfig_t wfconfig[2][5] = { { /* kevtris chip G (6581) */ { 0.880815f, 0.f, 0.f, 0.3279614f, 0.5999545f }, // error 1795 { 0.8924618f, 2.014781f, 1.003332f, 0.02992322f, 0.0f }, // error 11610 { 0.8646501f, 1.712586f, 1.137704f, 0.02845423f, 0.f }, // error 21307 { 0.9527834f, 1.794777f, 0.f, 0.09806272f, 0.7752482f }, // error 196 { 0.5f, 0.0f, 1.0f, 0.0f, 0.0f, }, }, { /* kevtris chip V (8580) */ { 0.9781665f, 0.f, 0.9899469f, 8.087667f, 0.8226412f }, // error 5546 { 0.9097769f, 2.039997f, 0.9584096f, 0.1765447f, 0.f }, // error 18763 { 0.9231212f, 2.084788f, 0.9493895f, 0.1712518f, 0.f }, // error 17103 { 0.9845552f, 1.415612f, 0.9703883f, 3.68829f, 0.8265008f }, // error 3319 { 0.5f, 0.0f, 1.0f, 0.0f, 0.0f }, } }; /* render output from bitstate */ static float make_sample(float *o) { float out = 0; for (int i = 0; i < 12; i ++) { out += o[i] * dac[i]; } return out; } /* generate tables for waveforms 1 .. 7 */ void WaveformGeneratorFP::rebuild_wftable() { float o[12]; reg8 oldwf = waveform; reg32 oldacc = accumulator; reg12 oldpw = pw; for (waveform = 1; waveform < 8; waveform ++) { for (accumulator = 0; accumulator < (1<<24); accumulator += (1<<12)) { /* generate pulse-low variants. Also, * when waveform < 4, pw doesn't matter. */ pw = 0x1000; /* pulse always low */ calculate_waveform_sample(o); wftable[waveform - 1][accumulator >> 12] = make_sample(o) + wave_zero; /* Add pulse-high variants after pulse-low state variants */ if (waveform >= 4) { pw = 0x000; /* pulse always high */ calculate_waveform_sample(o); wftable[waveform + 3][accumulator >> 12] = make_sample(o) + wave_zero; } } } waveform = oldwf; accumulator = oldacc; pw = oldpw; } /* explode reg12 to a floating point bit array */ static void populate(reg12 v, float o[12]) { int j = 1; for (int i = 0; i < 12; i ++) { o[i] = v & j ? 1.f : 0.f; j <<= 1; } } /* waveform values valid are 1 .. 7 */ void WaveformGeneratorFP::calculate_waveform_sample(float o[12]) { int i; /* P */ if (waveform == 4) { populate((accumulator >> 12) >= pw ? 0xfff : 0x000, o); return; } const waveformconfig_t config = wfconfig[ model == MOS6581 ? 0 : 1 ][ waveform == 3 ? 0 : waveform == 5 ? 1 : waveform == 6 ? 2 : waveform == 7 ? 3 : 4 ]; /* S with strong top bit for 6581 */ populate(accumulator >> 12, o); /* convert to T */ if ((waveform & 3) == 1) { bool top = (accumulator & 0x800000) != 0; for (i = 11; i > 0; i --) { if (top) { o[i] = 1.0f - o[i-1]; } else { o[i] = o[i-1]; } } o[0] = 0; } /* convert to ST */ if ((waveform & 3) == 3) { /* bottom bit is grounded via T waveform selector */ o[0] *= config.stmix; for (i = 1; i < 12; i ++) { o[i] = o[i - 1] * (1.f - config.stmix) + o[i] * config.stmix; } } o[11] *= config.topbit; /* ST, P* waveform? */ if (waveform == 3 || waveform > 4) { float distancetable[12 * 2 + 1]; for (i = 0; i <= 12; i ++) { distancetable[12+i] = distancetable[12-i] = 1.f / (1.f + i * i * config.distance); } float pulse = (accumulator >> 12) >= pw ? 1.f : -1.f; pulse *= config.pulsestrength; float tmp[12]; for (i = 0; i < 12; i ++) { float avg = 0; float n = 0; for (int j = 0; j < 12; j ++) { float weight = distancetable[i - j + 12]; avg += o[j] * weight; n += weight; } /* pulse control bit */ if (waveform > 4) { float weight = distancetable[i - 12 + 12]; avg += pulse * weight; n += weight; } tmp[i] = (o[i] + avg / n) * 0.5f; } for (i = 0; i < 12; i ++) { o[i] = tmp[i]; } } /* use the environment around bias value to set/clear dac bit. The * relationship is nonlinear because that seems to sound a bit better. */ for (i = 0; i < 12; i ++) { o[i] = (o[i] - config.bias) * sharpness; o[i] += 0.5f; if (o[i] > 1.f) { o[i] = 1.f; } if (o[i] < 0.f) { o[i] = 0.; } } } void WaveformGeneratorFP::set_nonlinearity(float nl) { for (int i = 0; i < 12; i ++) { dac[i] = SIDFP::kinked_dac((1 << i), nl, 12); } } // ---------------------------------------------------------------------------- // Constructor. // ---------------------------------------------------------------------------- WaveformGeneratorFP::WaveformGeneratorFP() { set_chip_model(MOS6581); reset(); } // ---------------------------------------------------------------------------- // Set chip model. // ---------------------------------------------------------------------------- void WaveformGeneratorFP::set_chip_model(chip_model model) { this->model = model; wave_zero = static_cast(model == MOS6581 ? -0x380 : -0x800); } // ---------------------------------------------------------------------------- // Register functions. // ---------------------------------------------------------------------------- void WaveformGeneratorFP::writeFREQ_LO(reg8 freq_lo) { freq = (freq & 0xff00) | (freq_lo & 0xff); } void WaveformGeneratorFP::writeFREQ_HI(reg8 freq_hi) { freq = ((freq_hi << 8) & 0xff00) | (freq & 0xff); } void WaveformGeneratorFP::writePW_LO(reg8 pw_lo) { pw = (pw & 0xf00) | (pw_lo & 0x0ff); } void WaveformGeneratorFP::writePW_HI(reg8 pw_hi) { pw = ((pw_hi << 8) & 0xf00) | (pw & 0x0ff); } void WaveformGeneratorFP::writeCONTROL_REG(WaveformGeneratorFP& source, reg8 control) { /* when selecting the 0 waveform, the previous output is held for * a time in the DAC MOSFET gates. We keep on holding forever, though... */ reg4 waveform_next = (control >> 4) & 0x0f; if (waveform_next == 0 && waveform >= 1 && waveform <= 7) { previous = readOSC(source); previous_dac = output(source); } waveform = waveform_next; ring_mod = (control & 0x04) != 0; sync = (control & 0x02) != 0; bool test_next = (control & 0x08) != 0; // Test bit rising? Invert bit 19 and write it to bit 1. if (test_next && !test) { accumulator = 0; reg24 bit19 = (shift_register >> 18) & 2; shift_register = (shift_register & 0x7ffffd) | (bit19^2); noise_overwrite_delay = 200000; /* 200 ms, probably too generous? */ } else { if (! test_next) { // Test bit falling? clock noise once, // otherwise just emulate noise's combined waveforms. clock_noise(test); } } test = test_next; } reg8 WaveformGeneratorFP::readOSC(WaveformGeneratorFP& source) { float o[12]; if (waveform == 0 || waveform > 7) { return previous; } /* Include effects of the test bit & ring mod */ reg12 oldpw = pw; if (test) { pw = 0; } reg24 oldaccumulator = accumulator; accumulator ^= (waveform & 3) == 1 && ring_mod && (source.accumulator & 0x800000) ? 0x800000 : 0; calculate_waveform_sample(o); pw = oldpw; accumulator = oldaccumulator; reg8 out = 0; reg8 bit = 1; for (int i = 4; i < 12; i ++) { if (o[i] > 0.5f) { out |= bit; } bit <<= 1; } return out; } void WaveformGeneratorFP::clock_noise(const bool clock) { if (clock) { reg24 bit0 = ((shift_register >> 22) ^ (shift_register >> 17)) & 0x1; shift_register <<= 1; shift_register |= bit0; } // clear output bits of shift register if noise and other waveforms // are selected simultaneously if (waveform > 8) { shift_register &= 0x7fffff^(1<<22)^(1<<20)^(1<<16)^(1<<13)^(1<<11)^(1<<7)^(1<<4)^(1<<2); } if (waveform >= 8) { previous = outputN___() >> 4; previous_dac = wave_zero; for (int i = 0; i < 8; i ++) { if (previous & (1 << i)) { previous_dac += dac[i+4]; } } } } reg12 WaveformGeneratorFP::outputN___() { return ((shift_register & 0x400000) >> 11) | ((shift_register & 0x100000) >> 10) | ((shift_register & 0x010000) >> 7) | ((shift_register & 0x002000) >> 5) | ((shift_register & 0x000800) >> 4) | ((shift_register & 0x000080) >> 1) | ((shift_register & 0x000010) << 1) | ((shift_register & 0x000004) << 2); } // ---------------------------------------------------------------------------- // SID reset. // ---------------------------------------------------------------------------- void WaveformGeneratorFP::reset() { accumulator = 0; previous = 0; previous_dac = 0; shift_register = 0x7ffffc; freq = 0; pw = 0; test = 0; waveform = 0; writeCONTROL_REG(*this, 0); msb_rising = false; } CheeseCutter-2.10/src/resid-fp/wavefp.h000066400000000000000000000133051516216315000177620ustar00rootroot00000000000000// --------------------------------------------------------------------------- // This file is part of reSID, a MOS6581 SID emulator engine. // Copyright (C) 2004 Dag Lem // // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; either version 2 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public 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 __WAVEFP_H__ #define __WAVEFP_H__ #include "siddefsfp.h" extern float dac[12]; extern float wftable[11][4096]; // ---------------------------------------------------------------------------- // A 24 bit accumulator is the basis for waveform generation. FREQ is added to // the lower 16 bits of the accumulator each cycle. // The accumulator is set to zero when TEST is set, and starts counting // when TEST is cleared. // The noise waveform is taken from intermediate bits of a 23 bit shift // register. This register is clocked by bit 19 of the accumulator. // ---------------------------------------------------------------------------- class WaveformGeneratorFP { public: WaveformGeneratorFP(); void set_chip_model(chip_model model); inline void clock(); inline void synchronize(WaveformGeneratorFP& dest, WaveformGeneratorFP& source); void reset(); void writeFREQ_LO(reg8 value); void writeFREQ_HI(reg8 value); void writePW_LO(reg8 value); void writePW_HI(reg8 value); void writeCONTROL_REG(WaveformGeneratorFP& source, reg8 value); reg8 readOSC(WaveformGeneratorFP& source); inline float output(WaveformGeneratorFP& source); protected: void clock_noise(const bool clock); reg12 outputN___(); void set_nonlinearity(float nl); void rebuild_wftable(); void calculate_waveform_sample(float o[12]); chip_model model; // Tell whether the accumulator MSB was set high on this cycle. bool msb_rising; reg24 accumulator; reg24 shift_register; reg8 previous; int noise_overwrite_delay; // Fout = (Fn*Fclk/16777216)Hz reg16 freq; // PWout = (PWn/40.95)% reg12 pw; // The control register right-shifted 4 bits; used for output function // table lookup. reg8 waveform; // The remaining control register bits. bool test, ring_mod, sync; // The gate bit is handled by the EnvelopeGenerator. // zero level offset of waveform (< 0) float wave_zero; float previous_dac; friend class VoiceFP; friend class SIDFP; }; // ---------------------------------------------------------------------------- // SID clocking - 1 cycle. // ---------------------------------------------------------------------------- inline void WaveformGeneratorFP::clock() { /* no digital operation if test bit is set. Only emulate analog fade. */ if (test) { if (noise_overwrite_delay != 0) { if (-- noise_overwrite_delay == 0) { shift_register |= 0x7ffffc; clock_noise(false); } } return; } reg24 accumulator_prev = accumulator; // Calculate new accumulator value; accumulator += freq; accumulator &= 0xffffff; // Check whether the MSB became set high. This is used for synchronization. msb_rising = !(accumulator_prev & 0x800000) && (accumulator & 0x800000); // Shift noise register once for each time accumulator bit 19 is set high. if (!(accumulator_prev & 0x080000) && (accumulator & 0x080000)) { clock_noise(true); } } // ---------------------------------------------------------------------------- // Synchronize oscillators. // This must be done after all the oscillators have been clock()'ed since the // oscillators operate in parallel. // Note that the oscillators must be clocked exactly on the cycle when the // MSB is set high for hard sync to operate correctly. See SID::clock(). // ---------------------------------------------------------------------------- inline void WaveformGeneratorFP::synchronize(WaveformGeneratorFP& sync_dest, WaveformGeneratorFP &sync_source) { // A special case occurs when a sync source is synced itself on the same // cycle as when its MSB is set high. In this case the destination will // not be synced. This has been verified by sampling OSC3. if (msb_rising && sync_dest.sync && !(sync && sync_source.msb_rising)) { sync_dest.accumulator = 0; } } // ---------------------------------------------------------------------------- // Select one of 16 possible combinations of waveforms. // ---------------------------------------------------------------------------- inline float WaveformGeneratorFP::output(WaveformGeneratorFP& sync_source) { if (waveform == 0 || waveform > 7) { return previous_dac; } /* waveforms 1 .. 7 left */ /* Phase for all waveforms */ reg12 phase = accumulator >> 12; /* pulse on/off generates 4 more variants after the main pulse types */ int variant = waveform >= 4 && (test || phase >= pw) ? 3 : -1; /* triangle waveform XOR circuit. Since the table already makes a triangle * wave internally, we only need to account for the sync source here. * Flipping the top bit suffices to reproduce the original SID ringmod */ phase ^= ((waveform & 3) == 1 && ring_mod && (sync_source.accumulator & 0x800000)) ? 0x800 : 0x00; return wftable[waveform + variant][phase]; } #endif // not __WAVEFP_H__ CheeseCutter-2.10/src/resid/000077500000000000000000000000001516216315000157145ustar00rootroot00000000000000CheeseCutter-2.10/src/resid/envelope.cpp000066400000000000000000000204261516216315000202410ustar00rootroot00000000000000// --------------------------------------------------------------------------- // This file is part of reSID, a MOS6581 SID emulator engine. // Copyright (C) 2004 Dag Lem // // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; either version 2 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // --------------------------------------------------------------------------- #define __ENVELOPE_CC__ #include "envelope.h" // ---------------------------------------------------------------------------- // Constructor. // ---------------------------------------------------------------------------- EnvelopeGenerator::EnvelopeGenerator() { reset(); } // ---------------------------------------------------------------------------- // SID reset. // ---------------------------------------------------------------------------- void EnvelopeGenerator::reset() { envelope_counter = 0; attack = 0; decay = 0; sustain = 0; release = 0; gate = 0; rate_counter = 0; exponential_counter = 0; exponential_counter_period = 1; state = RELEASE; rate_period = rate_counter_period[release]; hold_zero = true; } // Rate counter periods are calculated from the Envelope Rates table in // the Programmer's Reference Guide. The rate counter period is the number of // cycles between each increment of the envelope counter. // The rates have been verified by sampling ENV3. // // The rate counter is a 16 bit register which is incremented each cycle. // When the counter reaches a specific comparison value, the envelope counter // is incremented (attack) or decremented (decay/release) and the // counter is zeroed. // // NB! Sampling ENV3 shows that the calculated values are not exact. // It may seem like most calculated values have been rounded (.5 is rounded // down) and 1 has beed added to the result. A possible explanation for this // is that the SID designers have used the calculated values directly // as rate counter comparison values, not considering a one cycle delay to // zero the counter. This would yield an actual period of comparison value + 1. // // The time of the first envelope count can not be exactly controlled, except // possibly by resetting the chip. Because of this we cannot do cycle exact // sampling and must devise another method to calculate the rate counter // periods. // // The exact rate counter periods can be determined e.g. by counting the number // of cycles from envelope level 1 to envelope level 129, and dividing the // number of cycles by 128. CIA1 timer A and B in linked mode can perform // the cycle count. This is the method used to find the rates below. // // To avoid the ADSR delay bug, sampling of ENV3 should be done using // sustain = release = 0. This ensures that the attack state will not lower // the current rate counter period. // // The ENV3 sampling code below yields a maximum timing error of 14 cycles. // lda #$01 // l1: cmp $d41c // bne l1 // ... // lda #$ff // l2: cmp $d41c // bne l2 // // This yields a maximum error for the calculated rate period of 14/128 cycles. // The described method is thus sufficient for exact calculation of the rate // periods. // reg16 EnvelopeGenerator::rate_counter_period[] = { 9, // 2ms*1.0MHz/256 = 7.81 32, // 8ms*1.0MHz/256 = 31.25 63, // 16ms*1.0MHz/256 = 62.50 95, // 24ms*1.0MHz/256 = 93.75 149, // 38ms*1.0MHz/256 = 148.44 220, // 56ms*1.0MHz/256 = 218.75 267, // 68ms*1.0MHz/256 = 265.63 313, // 80ms*1.0MHz/256 = 312.50 392, // 100ms*1.0MHz/256 = 390.63 977, // 250ms*1.0MHz/256 = 976.56 1954, // 500ms*1.0MHz/256 = 1953.13 3126, // 800ms*1.0MHz/256 = 3125.00 3907, // 1 s*1.0MHz/256 = 3906.25 11720, // 3 s*1.0MHz/256 = 11718.75 19532, // 5 s*1.0MHz/256 = 19531.25 31251 // 8 s*1.0MHz/256 = 31250.00 }; // For decay and release, the clock to the envelope counter is sequentially // divided by 1, 2, 4, 8, 16, 30, 1 to create a piece-wise linear approximation // of an exponential. The exponential counter period is loaded at the envelope // counter values 255, 93, 54, 26, 14, 6, 0. The period can be different for the // same envelope counter value, depending on whether the envelope has been // rising (attack -> release) or sinking (decay/release). // // Since it is not possible to reset the rate counter (the test bit has no // influence on the envelope generator whatsoever) a method must be devised to // do cycle exact sampling of ENV3 to do the investigation. This is possible // with knowledge of the rate period for A=0, found above. // // The CPU can be synchronized with ENV3 by first synchronizing with the rate // counter by setting A=0 and wait in a carefully timed loop for the envelope // counter _not_ to change for 9 cycles. We can then wait for a specific value // of ENV3 with another timed loop to fully synchronize with ENV3. // // At the first period when an exponential counter period larger than one // is used (decay or relase), one extra cycle is spent before the envelope is // decremented. The envelope output is then delayed one cycle until the state // is changed to attack. Now one cycle less will be spent before the envelope // is incremented, and the situation is normalized. // The delay is probably caused by the comparison with the exponential counter, // and does not seem to affect the rate counter. This has been verified by // timing 256 consecutive complete envelopes with A = D = R = 1, S = 0, using // CIA1 timer A and B in linked mode. If the rate counter is not affected the // period of each complete envelope is // (255 + 162*1 + 39*2 + 28*4 + 12*8 + 8*16 + 6*30)*32 = 756*32 = 32352 // which corresponds exactly to the timed value divided by the number of // complete envelopes. // NB! This one cycle delay is not modeled. // From the sustain levels it follows that both the low and high 4 bits of the // envelope counter are compared to the 4-bit sustain value. // This has been verified by sampling ENV3. // reg8 EnvelopeGenerator::sustain_level[] = { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff, }; // ---------------------------------------------------------------------------- // Register functions. // ---------------------------------------------------------------------------- void EnvelopeGenerator::writeCONTROL_REG(reg8 control) { reg8 gate_next = control & 0x01; // The rate counter is never reset, thus there will be a delay before the // envelope counter starts counting up (attack) or down (release). // Gate bit on: Start attack, decay, sustain. if (!gate && gate_next) { state = ATTACK; rate_period = rate_counter_period[attack]; // Switching to attack state unlocks the zero freeze. hold_zero = false; } // Gate bit off: Start release. else if (gate && !gate_next) { state = RELEASE; rate_period = rate_counter_period[release]; } gate = gate_next; } void EnvelopeGenerator::writeATTACK_DECAY(reg8 attack_decay) { attack = (attack_decay >> 4) & 0x0f; decay = attack_decay & 0x0f; if (state == ATTACK) { rate_period = rate_counter_period[attack]; } else if (state == DECAY_SUSTAIN) { rate_period = rate_counter_period[decay]; } } void EnvelopeGenerator::writeSUSTAIN_RELEASE(reg8 sustain_release) { sustain = (sustain_release >> 4) & 0x0f; release = sustain_release & 0x0f; if (state == RELEASE) { rate_period = rate_counter_period[release]; } } reg8 EnvelopeGenerator::readENV() { return output(); } CheeseCutter-2.10/src/resid/envelope.h000066400000000000000000000222711516216315000177060ustar00rootroot00000000000000// --------------------------------------------------------------------------- // This file is part of reSID, a MOS6581 SID emulator engine. // Copyright (C) 2004 Dag Lem // // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; either version 2 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public 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 __ENVELOPE_H__ #define __ENVELOPE_H__ #include "siddefs.h" // ---------------------------------------------------------------------------- // A 15 bit counter is used to implement the envelope rates, in effect // dividing the clock to the envelope counter by the currently selected rate // period. // In addition, another counter is used to implement the exponential envelope // decay, in effect further dividing the clock to the envelope counter. // The period of this counter is set to 1, 2, 4, 8, 16, 30 at the envelope // counter values 255, 93, 54, 26, 14, 6, respectively. // ---------------------------------------------------------------------------- class EnvelopeGenerator { public: EnvelopeGenerator(); enum State { ATTACK, DECAY_SUSTAIN, RELEASE }; RESID_INLINE void clock(); RESID_INLINE void clock(cycle_count delta_t); void reset(); void writeCONTROL_REG(reg8); void writeATTACK_DECAY(reg8); void writeSUSTAIN_RELEASE(reg8); reg8 readENV(); // 8-bit envelope output. RESID_INLINE reg8 output(); protected: reg16 rate_counter; reg16 rate_period; reg8 exponential_counter; reg8 exponential_counter_period; reg8 envelope_counter; bool hold_zero; reg4 attack; reg4 decay; reg4 sustain; reg4 release; reg8 gate; State state; // Lookup table to convert from attack, decay, or release value to rate // counter period. static reg16 rate_counter_period[]; // The 16 selectable sustain levels. static reg8 sustain_level[]; friend class SID; }; // ---------------------------------------------------------------------------- // Inline functions. // The following functions are defined inline because they are called every // time a sample is calculated. // ---------------------------------------------------------------------------- #if RESID_INLINING || defined(__ENVELOPE_CC__) // ---------------------------------------------------------------------------- // SID clocking - 1 cycle. // ---------------------------------------------------------------------------- RESID_INLINE void EnvelopeGenerator::clock() { // Check for ADSR delay bug. // If the rate counter comparison value is set below the current value of the // rate counter, the counter will continue counting up until it wraps around // to zero at 2^15 = 0x8000, and then count rate_period - 1 before the // envelope can finally be stepped. // This has been verified by sampling ENV3. // if (++rate_counter & 0x8000) { ++rate_counter &= 0x7fff; } if (rate_counter != rate_period) { return; } rate_counter = 0; // The first envelope step in the attack state also resets the exponential // counter. This has been verified by sampling ENV3. // if (state == ATTACK || ++exponential_counter == exponential_counter_period) { exponential_counter = 0; // Check whether the envelope counter is frozen at zero. if (hold_zero) { return; } switch (state) { case ATTACK: // The envelope counter can flip from 0xff to 0x00 by changing state to // release, then to attack. The envelope counter is then frozen at // zero; to unlock this situation the state must be changed to release, // then to attack. This has been verified by sampling ENV3. // ++envelope_counter &= 0xff; if (envelope_counter == 0xff) { state = DECAY_SUSTAIN; rate_period = rate_counter_period[decay]; } break; case DECAY_SUSTAIN: if (envelope_counter != sustain_level[sustain]) { --envelope_counter; } break; case RELEASE: // The envelope counter can flip from 0x00 to 0xff by changing state to // attack, then to release. The envelope counter will then continue // counting down in the release state. // This has been verified by sampling ENV3. // NB! The operation below requires two's complement integer. // --envelope_counter &= 0xff; break; } // Check for change of exponential counter period. switch (envelope_counter) { case 0xff: exponential_counter_period = 1; break; case 0x5d: exponential_counter_period = 2; break; case 0x36: exponential_counter_period = 4; break; case 0x1a: exponential_counter_period = 8; break; case 0x0e: exponential_counter_period = 16; break; case 0x06: exponential_counter_period = 30; break; case 0x00: exponential_counter_period = 1; // When the envelope counter is changed to zero, it is frozen at zero. // This has been verified by sampling ENV3. hold_zero = true; break; } } } // ---------------------------------------------------------------------------- // SID clocking - delta_t cycles. // ---------------------------------------------------------------------------- RESID_INLINE void EnvelopeGenerator::clock(cycle_count delta_t) { // Check for ADSR delay bug. // If the rate counter comparison value is set below the current value of the // rate counter, the counter will continue counting up until it wraps around // to zero at 2^15 = 0x8000, and then count rate_period - 1 before the // envelope can finally be stepped. // This has been verified by sampling ENV3. // // NB! This requires two's complement integer. int rate_step = rate_period - rate_counter; if (rate_step <= 0) { rate_step += 0x7fff; } while (delta_t) { if (delta_t < rate_step) { rate_counter += delta_t; if (rate_counter & 0x8000) { ++rate_counter &= 0x7fff; } return; } rate_counter = 0; delta_t -= rate_step; // The first envelope step in the attack state also resets the exponential // counter. This has been verified by sampling ENV3. // if (state == ATTACK || ++exponential_counter == exponential_counter_period) { exponential_counter = 0; // Check whether the envelope counter is frozen at zero. if (hold_zero) { rate_step = rate_period; continue; } switch (state) { case ATTACK: // The envelope counter can flip from 0xff to 0x00 by changing state to // release, then to attack. The envelope counter is then frozen at // zero; to unlock this situation the state must be changed to release, // then to attack. This has been verified by sampling ENV3. // ++envelope_counter &= 0xff; if (envelope_counter == 0xff) { state = DECAY_SUSTAIN; rate_period = rate_counter_period[decay]; } break; case DECAY_SUSTAIN: if (envelope_counter != sustain_level[sustain]) { --envelope_counter; } break; case RELEASE: // The envelope counter can flip from 0x00 to 0xff by changing state to // attack, then to release. The envelope counter will then continue // counting down in the release state. // This has been verified by sampling ENV3. // NB! The operation below requires two's complement integer. // --envelope_counter &= 0xff; break; } // Check for change of exponential counter period. switch (envelope_counter) { case 0xff: exponential_counter_period = 1; break; case 0x5d: exponential_counter_period = 2; break; case 0x36: exponential_counter_period = 4; break; case 0x1a: exponential_counter_period = 8; break; case 0x0e: exponential_counter_period = 16; break; case 0x06: exponential_counter_period = 30; break; case 0x00: exponential_counter_period = 1; // When the envelope counter is changed to zero, it is frozen at zero. // This has been verified by sampling ENV3. hold_zero = true; break; } } rate_step = rate_period; } } // ---------------------------------------------------------------------------- // Read the envelope generator output. // ---------------------------------------------------------------------------- RESID_INLINE reg8 EnvelopeGenerator::output() { return envelope_counter; } #endif // RESID_INLINING || defined(__ENVELOPE_CC__) #endif // not __ENVELOPE_H__ CheeseCutter-2.10/src/resid/extfilt.cpp000066400000000000000000000054341516216315000201050ustar00rootroot00000000000000// --------------------------------------------------------------------------- // This file is part of reSID, a MOS6581 SID emulator engine. // Copyright (C) 2004 Dag Lem // // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; either version 2 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // --------------------------------------------------------------------------- #define __EXTFILT_CC__ #include "extfilt.h" // ---------------------------------------------------------------------------- // Constructor. // ---------------------------------------------------------------------------- ExternalFilter::ExternalFilter() { reset(); enable_filter(true); set_chip_model(MOS6581); // Low-pass: R = 10kOhm, C = 1000pF; w0l = 1/RC = 1/(1e4*1e-9) = 100000 // High-pass: R = 1kOhm, C = 10uF; w0h = 1/RC = 1/(1e3*1e-5) = 100 // Multiply with 1.048576 to facilitate division by 1 000 000 by right- // shifting 20 times (2 ^ 20 = 1048576). w0lp = 104858; w0hp = 105; } // ---------------------------------------------------------------------------- // Enable filter. // ---------------------------------------------------------------------------- void ExternalFilter::enable_filter(bool enable) { enabled = enable; } // ---------------------------------------------------------------------------- // Set chip model. // ---------------------------------------------------------------------------- void ExternalFilter::set_chip_model(chip_model model) { if (model == MOS6581) { // Maximum mixer DC output level; to be removed if the external // filter is turned off: ((wave DC + voice DC)*voices + mixer DC)*volume // See voice.cc and filter.cc for an explanation of the values. mixer_DC = ((((0x800 - 0x380) + 0x800)*0xff*3 - 0xfff*0xff/18) >> 7)*0x0f; } else { // No DC offsets in the MOS8580. mixer_DC = 0; } } // ---------------------------------------------------------------------------- // SID reset. // ---------------------------------------------------------------------------- void ExternalFilter::reset() { // State of filter. Vlp = 0; Vhp = 0; Vo = 0; } CheeseCutter-2.10/src/resid/extfilt.h000066400000000000000000000123521516216315000175470ustar00rootroot00000000000000// --------------------------------------------------------------------------- // This file is part of reSID, a MOS6581 SID emulator engine. // Copyright (C) 2004 Dag Lem // // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; either version 2 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public 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 __EXTFILT_H__ #define __EXTFILT_H__ #include "siddefs.h" // ---------------------------------------------------------------------------- // The audio output stage in a Commodore 64 consists of two STC networks, // a low-pass filter with 3-dB frequency 16kHz followed by a high-pass // filter with 3-dB frequency 16Hz (the latter provided an audio equipment // input impedance of 1kOhm). // The STC networks are connected with a BJT supposedly meant to act as // a unity gain buffer, which is not really how it works. A more elaborate // model would include the BJT, however DC circuit analysis yields BJT // base-emitter and emitter-base impedances sufficiently low to produce // additional low-pass and high-pass 3dB-frequencies in the order of hundreds // of kHz. This calls for a sampling frequency of several MHz, which is far // too high for practical use. // ---------------------------------------------------------------------------- class ExternalFilter { public: ExternalFilter(); void enable_filter(bool enable); void set_chip_model(chip_model model); RESID_INLINE void clock(sound_sample Vi); RESID_INLINE void clock(cycle_count delta_t, sound_sample Vi); void reset(); // Audio output (20 bits). RESID_INLINE sound_sample output(); protected: // Filter enabled. bool enabled; // Maximum mixer DC offset. sound_sample mixer_DC; // State of filters. sound_sample Vlp; // lowpass sound_sample Vhp; // highpass sound_sample Vo; // Cutoff frequencies. sound_sample w0lp; sound_sample w0hp; friend class SID; }; // ---------------------------------------------------------------------------- // Inline functions. // The following functions are defined inline because they are called every // time a sample is calculated. // ---------------------------------------------------------------------------- #if RESID_INLINING || defined(__EXTFILT_CC__) // ---------------------------------------------------------------------------- // SID clocking - 1 cycle. // ---------------------------------------------------------------------------- RESID_INLINE void ExternalFilter::clock(sound_sample Vi) { // This is handy for testing. if (!enabled) { // Remove maximum DC level since there is no filter to do it. Vlp = Vhp = 0; Vo = Vi - mixer_DC; return; } // delta_t is converted to seconds given a 1MHz clock by dividing // with 1 000 000. // Calculate filter outputs. // Vo = Vlp - Vhp; // Vlp = Vlp + w0lp*(Vi - Vlp)*delta_t; // Vhp = Vhp + w0hp*(Vlp - Vhp)*delta_t; sound_sample dVlp = (w0lp >> 8)*(Vi - Vlp) >> 12; sound_sample dVhp = w0hp*(Vlp - Vhp) >> 20; Vo = Vlp - Vhp; Vlp += dVlp; Vhp += dVhp; } // ---------------------------------------------------------------------------- // SID clocking - delta_t cycles. // ---------------------------------------------------------------------------- RESID_INLINE void ExternalFilter::clock(cycle_count delta_t, sound_sample Vi) { // This is handy for testing. if (!enabled) { // Remove maximum DC level since there is no filter to do it. Vlp = Vhp = 0; Vo = Vi - mixer_DC; return; } // Maximum delta cycles for the external filter to work satisfactorily // is approximately 8. cycle_count delta_t_flt = 8; while (delta_t) { if (delta_t < delta_t_flt) { delta_t_flt = delta_t; } // delta_t is converted to seconds given a 1MHz clock by dividing // with 1 000 000. // Calculate filter outputs. // Vo = Vlp - Vhp; // Vlp = Vlp + w0lp*(Vi - Vlp)*delta_t; // Vhp = Vhp + w0hp*(Vlp - Vhp)*delta_t; sound_sample dVlp = (w0lp*delta_t_flt >> 8)*(Vi - Vlp) >> 12; sound_sample dVhp = w0hp*delta_t_flt*(Vlp - Vhp) >> 20; Vo = Vlp - Vhp; Vlp += dVlp; Vhp += dVhp; delta_t -= delta_t_flt; } } // ---------------------------------------------------------------------------- // Audio output (19.5 bits). // ---------------------------------------------------------------------------- RESID_INLINE sound_sample ExternalFilter::output() { return Vo; } #endif // RESID_INLINING || defined(__EXTFILT_CC__) #endif // not __EXTFILT_H__ CheeseCutter-2.10/src/resid/filter.cpp000066400000000000000000000223351516216315000177120ustar00rootroot00000000000000// --------------------------------------------------------------------------- // This file is part of reSID, a MOS6581 SID emulator engine. // Copyright (C) 2004 Dag Lem // // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; either version 2 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // --------------------------------------------------------------------------- #define __FILTER_CC__ #include "filter.h" // Maximum cutoff frequency is specified as // FCmax = 2.6e-5/C = 2.6e-5/2200e-12 = 11818. // // Measurements indicate a cutoff frequency range of approximately // 220Hz - 18kHz on a MOS6581 fitted with 470pF capacitors. The function // mapping FC to cutoff frequency has the shape of the tanh function, with // a discontinuity at FCHI = 0x80. // In contrast, the MOS8580 almost perfectly corresponds with the // specification of a linear mapping from 30Hz to 12kHz. // // The mappings have been measured by feeding the SID with an external // signal since the chip itself is incapable of generating waveforms of // higher fundamental frequency than 4kHz. It is best to use the bandpass // output at full resonance to pick out the cutoff frequency at any given // FC setting. // // The mapping function is specified with spline interpolation points and // the function values are retrieved via table lookup. // // NB! Cutoff frequency characteristics may vary, we have modeled two // particular Commodore 64s. fc_point Filter::f0_points_6581[] = { // FC f FCHI FCLO // ---------------------------- { 0, 220 }, // 0x00 - repeated end point { 0, 220 }, // 0x00 { 128, 230 }, // 0x10 { 256, 250 }, // 0x20 { 384, 300 }, // 0x30 { 512, 420 }, // 0x40 { 640, 780 }, // 0x50 { 768, 1600 }, // 0x60 { 832, 2300 }, // 0x68 { 896, 3200 }, // 0x70 { 960, 4300 }, // 0x78 { 992, 5000 }, // 0x7c { 1008, 5400 }, // 0x7e { 1016, 5700 }, // 0x7f { 1023, 6000 }, // 0x7f 0x07 { 1023, 6000 }, // 0x7f 0x07 - discontinuity { 1024, 4600 }, // 0x80 - { 1024, 4600 }, // 0x80 { 1032, 4800 }, // 0x81 { 1056, 5300 }, // 0x84 { 1088, 6000 }, // 0x88 { 1120, 6600 }, // 0x8c { 1152, 7200 }, // 0x90 { 1280, 9500 }, // 0xa0 { 1408, 12000 }, // 0xb0 { 1536, 14500 }, // 0xc0 { 1664, 16000 }, // 0xd0 { 1792, 17100 }, // 0xe0 { 1920, 17700 }, // 0xf0 { 2047, 18000 }, // 0xff 0x07 { 2047, 18000 } // 0xff 0x07 - repeated end point }; fc_point Filter::f0_points_8580[] = { // FC f FCHI FCLO // ---------------------------- { 0, 0 }, // 0x00 - repeated end point { 0, 0 }, // 0x00 { 128, 800 }, // 0x10 { 256, 1600 }, // 0x20 { 384, 2500 }, // 0x30 { 512, 3300 }, // 0x40 { 640, 4100 }, // 0x50 { 768, 4800 }, // 0x60 { 896, 5600 }, // 0x70 { 1024, 6500 }, // 0x80 { 1152, 7500 }, // 0x90 { 1280, 8400 }, // 0xa0 { 1408, 9200 }, // 0xb0 { 1536, 9800 }, // 0xc0 { 1664, 10500 }, // 0xd0 { 1792, 11000 }, // 0xe0 { 1920, 11700 }, // 0xf0 { 2047, 12500 }, // 0xff 0x07 { 2047, 12500 } // 0xff 0x07 - repeated end point }; // ---------------------------------------------------------------------------- // Constructor. // ---------------------------------------------------------------------------- Filter::Filter() { fc = 0; res = 0; filt = 0; voice3off = 0; hp_bp_lp = 0; vol = 0; // State of filter. Vhp = 0; Vbp = 0; Vlp = 0; Vnf = 0; enable_filter(true); // Create mappings from FC to cutoff frequency. interpolate(f0_points_6581, f0_points_6581 + sizeof(f0_points_6581)/sizeof(*f0_points_6581) - 1, PointPlotter(f0_6581), 1.0); interpolate(f0_points_8580, f0_points_8580 + sizeof(f0_points_8580)/sizeof(*f0_points_8580) - 1, PointPlotter(f0_8580), 1.0); set_chip_model(MOS6581); } // ---------------------------------------------------------------------------- // Enable filter. // ---------------------------------------------------------------------------- void Filter::enable_filter(bool enable) { enabled = enable; } // ---------------------------------------------------------------------------- // Set chip model. // ---------------------------------------------------------------------------- void Filter::set_chip_model(chip_model model) { if (model == MOS6581) { // The mixer has a small input DC offset. This is found as follows: // // The "zero" output level of the mixer measured on the SID audio // output pin is 5.50V at zero volume, and 5.44 at full // volume. This yields a DC offset of (5.44V - 5.50V) = -0.06V. // // The DC offset is thus -0.06V/1.05V ~ -1/18 of the dynamic range // of one voice. See voice.cc for measurement of the dynamic // range. mixer_DC = -0xfff*0xff/18 >> 7; f0 = f0_6581; f0_points = f0_points_6581; f0_count = sizeof(f0_points_6581)/sizeof(*f0_points_6581); } else { // No DC offsets in the MOS8580. mixer_DC = 0; f0 = f0_8580; f0_points = f0_points_8580; f0_count = sizeof(f0_points_8580)/sizeof(*f0_points_8580); } set_w0(); set_Q(); } // ---------------------------------------------------------------------------- // SID reset. // ---------------------------------------------------------------------------- void Filter::reset() { fc = 0; res = 0; filt = 0; voice3off = 0; hp_bp_lp = 0; vol = 0; // State of filter. Vhp = 0; Vbp = 0; Vlp = 0; Vnf = 0; set_w0(); set_Q(); } // ---------------------------------------------------------------------------- // Register functions. // ---------------------------------------------------------------------------- void Filter::writeFC_LO(reg8 fc_lo) { fc = fc & 0x7f8 | fc_lo & 0x007; set_w0(); } void Filter::writeFC_HI(reg8 fc_hi) { fc = (fc_hi << 3) & 0x7f8 | fc & 0x007; set_w0(); } void Filter::writeRES_FILT(reg8 res_filt) { res = (res_filt >> 4) & 0x0f; set_Q(); filt = res_filt & 0x0f; } void Filter::writeMODE_VOL(reg8 mode_vol) { voice3off = mode_vol & 0x80; hp_bp_lp = (mode_vol >> 4) & 0x07; vol = mode_vol & 0x0f; } // Set filter cutoff frequency. void Filter::set_w0() { const double pi = 3.1415926535897932385; // Multiply with 1.048576 to facilitate division by 1 000 000 by right- // shifting 20 times (2 ^ 20 = 1048576). w0 = static_cast(2*pi*f0[fc]*1.048576); // Limit f0 to 16kHz to keep 1 cycle filter stable. const sound_sample w0_max_1 = static_cast(2*pi*16000*1.048576); w0_ceil_1 = w0 <= w0_max_1 ? w0 : w0_max_1; // Limit f0 to 4kHz to keep delta_t cycle filter stable. const sound_sample w0_max_dt = static_cast(2*pi*4000*1.048576); w0_ceil_dt = w0 <= w0_max_dt ? w0 : w0_max_dt; } // Set filter resonance. void Filter::set_Q() { // Q is controlled linearly by res. Q has approximate range [0.707, 1.7]. // As resonance is increased, the filter must be clocked more often to keep // stable. // The coefficient 1024 is dispensed of later by right-shifting 10 times // (2 ^ 10 = 1024). _1024_div_Q = static_cast(1024.0/(0.707 + 1.0*res/0x0f)); } // ---------------------------------------------------------------------------- // Spline functions. // ---------------------------------------------------------------------------- // ---------------------------------------------------------------------------- // Return the array of spline interpolation points used to map the FC register // to filter cutoff frequency. // ---------------------------------------------------------------------------- void Filter::fc_default(const fc_point*& points, int& count) { points = f0_points; count = f0_count; } // ---------------------------------------------------------------------------- // Given an array of interpolation points p with n points, the following // statement will specify a new FC mapping: // interpolate(p, p + n - 1, filter.fc_plotter(), 1.0); // Note that the x range of the interpolation points *must* be [0, 2047], // and that additional end points *must* be present since the end points // are not interpolated. // ---------------------------------------------------------------------------- PointPlotter Filter::fc_plotter() { return PointPlotter(f0); } CheeseCutter-2.10/src/resid/filter.h000066400000000000000000000344661516216315000173670ustar00rootroot00000000000000// --------------------------------------------------------------------------- // This file is part of reSID, a MOS6581 SID emulator engine. // Copyright (C) 2004 Dag Lem // // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; either version 2 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public 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 __FILTER_H__ #define __FILTER_H__ #include "siddefs.h" #include "spline.h" // ---------------------------------------------------------------------------- // The SID filter is modeled with a two-integrator-loop biquadratic filter, // which has been confirmed by Bob Yannes to be the actual circuit used in // the SID chip. // // Measurements show that excellent emulation of the SID filter is achieved, // except when high resonance is combined with high sustain levels. // In this case the SID op-amps are performing less than ideally and are // causing some peculiar behavior of the SID filter. This however seems to // have more effect on the overall amplitude than on the color of the sound. // // The theory for the filter circuit can be found in "Microelectric Circuits" // by Adel S. Sedra and Kenneth C. Smith. // The circuit is modeled based on the explanation found there except that // an additional inverter is used in the feedback from the bandpass output, // allowing the summer op-amp to operate in single-ended mode. This yields // inverted filter outputs with levels independent of Q, which corresponds with // the results obtained from a real SID. // // We have been able to model the summer and the two integrators of the circuit // to form components of an IIR filter. // Vhp is the output of the summer, Vbp is the output of the first integrator, // and Vlp is the output of the second integrator in the filter circuit. // // According to Bob Yannes, the active stages of the SID filter are not really // op-amps. Rather, simple NMOS inverters are used. By biasing an inverter // into its region of quasi-linear operation using a feedback resistor from // input to output, a MOS inverter can be made to act like an op-amp for // small signals centered around the switching threshold. // // Qualified guesses at SID filter schematics are depicted below. // // SID filter // ---------- // // ----------------------------------------------- // | | // | ---Rq-- | // | | | | // | --------------|--R-----[A>--|--R-----[A>--| // | | | | // vi -----R1-- | | | // // vhp vbp vlp // // // vi - input voltage // vhp - highpass output // vbp - bandpass output // vlp - lowpass output // [A> - op-amp // R1 - summer resistor // Rq - resistor array controlling resonance (4 resistors) // R - NMOS FET voltage controlled resistor controlling cutoff frequency // Rs - shunt resitor // C - capacitor // // // // SID integrator // -------------- // // V+ // // | // | // -----| // | | // | ||-- // -|| // ---C--- ||-> // | | | // |---Rs-----------|---- vo // | | // | ||-- // vi ---- -----|------------|| // | ^ | ||-> // |___| | | // ----- | | // | | | // |---R2-- | // | // R1 V- // | // | // // Vw // // ---------------------------------------------------------------------------- class Filter { public: Filter(); void enable_filter(bool enable); void set_chip_model(chip_model model); RESID_INLINE void clock(sound_sample voice1, sound_sample voice2, sound_sample voice3, sound_sample ext_in); RESID_INLINE void clock(cycle_count delta_t, sound_sample voice1, sound_sample voice2, sound_sample voice3, sound_sample ext_in); void reset(); // Write registers. void writeFC_LO(reg8); void writeFC_HI(reg8); void writeRES_FILT(reg8); void writeMODE_VOL(reg8); // SID audio output (16 bits). sound_sample output(); // Spline functions. void fc_default(const fc_point*& points, int& count); PointPlotter fc_plotter(); protected: void set_w0(); void set_Q(); // Filter enabled. bool enabled; // Filter cutoff frequency. reg12 fc; // Filter resonance. reg8 res; // Selects which inputs to route through filter. reg8 filt; // Switch voice 3 off. reg8 voice3off; // Highpass, bandpass, and lowpass filter modes. reg8 hp_bp_lp; // Output master volume. reg4 vol; // Mixer DC offset. sound_sample mixer_DC; // State of filter. sound_sample Vhp; // highpass sound_sample Vbp; // bandpass sound_sample Vlp; // lowpass sound_sample Vnf; // not filtered // Cutoff frequency, resonance. sound_sample w0, w0_ceil_1, w0_ceil_dt; sound_sample _1024_div_Q; // Cutoff frequency tables. // FC is an 11 bit register. sound_sample f0_6581[2048]; sound_sample f0_8580[2048]; sound_sample* f0; static fc_point f0_points_6581[]; static fc_point f0_points_8580[]; fc_point* f0_points; int f0_count; friend class SID; }; // ---------------------------------------------------------------------------- // Inline functions. // The following functions are defined inline because they are called every // time a sample is calculated. // ---------------------------------------------------------------------------- #if RESID_INLINING || defined(__FILTER_CC__) // ---------------------------------------------------------------------------- // SID clocking - 1 cycle. // ---------------------------------------------------------------------------- RESID_INLINE void Filter::clock(sound_sample voice1, sound_sample voice2, sound_sample voice3, sound_sample ext_in) { // Scale each voice down from 20 to 13 bits. voice1 >>= 7; voice2 >>= 7; // NB! Voice 3 is not silenced by voice3off if it is routed through // the filter. if (voice3off && !(filt & 0x04)) { voice3 = 0; } else { voice3 >>= 7; } ext_in >>= 7; // This is handy for testing. if (!enabled) { Vnf = voice1 + voice2 + voice3 + ext_in; Vhp = Vbp = Vlp = 0; return; } // Route voices into or around filter. // The code below is expanded to a switch for faster execution. // (filt1 ? Vi : Vnf) += voice1; // (filt2 ? Vi : Vnf) += voice2; // (filt3 ? Vi : Vnf) += voice3; sound_sample Vi; switch (filt) { default: case 0x0: Vi = 0; Vnf = voice1 + voice2 + voice3 + ext_in; break; case 0x1: Vi = voice1; Vnf = voice2 + voice3 + ext_in; break; case 0x2: Vi = voice2; Vnf = voice1 + voice3 + ext_in; break; case 0x3: Vi = voice1 + voice2; Vnf = voice3 + ext_in; break; case 0x4: Vi = voice3; Vnf = voice1 + voice2 + ext_in; break; case 0x5: Vi = voice1 + voice3; Vnf = voice2 + ext_in; break; case 0x6: Vi = voice2 + voice3; Vnf = voice1 + ext_in; break; case 0x7: Vi = voice1 + voice2 + voice3; Vnf = ext_in; break; case 0x8: Vi = ext_in; Vnf = voice1 + voice2 + voice3; break; case 0x9: Vi = voice1 + ext_in; Vnf = voice2 + voice3; break; case 0xa: Vi = voice2 + ext_in; Vnf = voice1 + voice3; break; case 0xb: Vi = voice1 + voice2 + ext_in; Vnf = voice3; break; case 0xc: Vi = voice3 + ext_in; Vnf = voice1 + voice2; break; case 0xd: Vi = voice1 + voice3 + ext_in; Vnf = voice2; break; case 0xe: Vi = voice2 + voice3 + ext_in; Vnf = voice1; break; case 0xf: Vi = voice1 + voice2 + voice3 + ext_in; Vnf = 0; break; } // delta_t = 1 is converted to seconds given a 1MHz clock by dividing // with 1 000 000. // Calculate filter outputs. // Vhp = Vbp/Q - Vlp - Vi; // dVbp = -w0*Vhp*dt; // dVlp = -w0*Vbp*dt; sound_sample dVbp = (w0_ceil_1*Vhp >> 20); sound_sample dVlp = (w0_ceil_1*Vbp >> 20); Vbp -= dVbp; Vlp -= dVlp; Vhp = (Vbp*_1024_div_Q >> 10) - Vlp - Vi; } // ---------------------------------------------------------------------------- // SID clocking - delta_t cycles. // ---------------------------------------------------------------------------- RESID_INLINE void Filter::clock(cycle_count delta_t, sound_sample voice1, sound_sample voice2, sound_sample voice3, sound_sample ext_in) { // Scale each voice down from 20 to 13 bits. voice1 >>= 7; voice2 >>= 7; // NB! Voice 3 is not silenced by voice3off if it is routed through // the filter. if (voice3off && !(filt & 0x04)) { voice3 = 0; } else { voice3 >>= 7; } ext_in >>= 7; // Enable filter on/off. // This is not really part of SID, but is useful for testing. // On slow CPUs it may be necessary to bypass the filter to lower the CPU // load. if (!enabled) { Vnf = voice1 + voice2 + voice3 + ext_in; Vhp = Vbp = Vlp = 0; return; } // Route voices into or around filter. // The code below is expanded to a switch for faster execution. // (filt1 ? Vi : Vnf) += voice1; // (filt2 ? Vi : Vnf) += voice2; // (filt3 ? Vi : Vnf) += voice3; sound_sample Vi; switch (filt) { default: case 0x0: Vi = 0; Vnf = voice1 + voice2 + voice3 + ext_in; break; case 0x1: Vi = voice1; Vnf = voice2 + voice3 + ext_in; break; case 0x2: Vi = voice2; Vnf = voice1 + voice3 + ext_in; break; case 0x3: Vi = voice1 + voice2; Vnf = voice3 + ext_in; break; case 0x4: Vi = voice3; Vnf = voice1 + voice2 + ext_in; break; case 0x5: Vi = voice1 + voice3; Vnf = voice2 + ext_in; break; case 0x6: Vi = voice2 + voice3; Vnf = voice1 + ext_in; break; case 0x7: Vi = voice1 + voice2 + voice3; Vnf = ext_in; break; case 0x8: Vi = ext_in; Vnf = voice1 + voice2 + voice3; break; case 0x9: Vi = voice1 + ext_in; Vnf = voice2 + voice3; break; case 0xa: Vi = voice2 + ext_in; Vnf = voice1 + voice3; break; case 0xb: Vi = voice1 + voice2 + ext_in; Vnf = voice3; break; case 0xc: Vi = voice3 + ext_in; Vnf = voice1 + voice2; break; case 0xd: Vi = voice1 + voice3 + ext_in; Vnf = voice2; break; case 0xe: Vi = voice2 + voice3 + ext_in; Vnf = voice1; break; case 0xf: Vi = voice1 + voice2 + voice3 + ext_in; Vnf = 0; break; } // Maximum delta cycles for the filter to work satisfactorily under current // cutoff frequency and resonance constraints is approximately 8. cycle_count delta_t_flt = 8; while (delta_t) { if (delta_t < delta_t_flt) { delta_t_flt = delta_t; } // delta_t is converted to seconds given a 1MHz clock by dividing // with 1 000 000. This is done in two operations to avoid integer // multiplication overflow. // Calculate filter outputs. // Vhp = Vbp/Q - Vlp - Vi; // dVbp = -w0*Vhp*dt; // dVlp = -w0*Vbp*dt; sound_sample w0_delta_t = w0_ceil_dt*delta_t_flt >> 6; sound_sample dVbp = (w0_delta_t*Vhp >> 14); sound_sample dVlp = (w0_delta_t*Vbp >> 14); Vbp -= dVbp; Vlp -= dVlp; Vhp = (Vbp*_1024_div_Q >> 10) - Vlp - Vi; delta_t -= delta_t_flt; } } // ---------------------------------------------------------------------------- // SID audio output (20 bits). // ---------------------------------------------------------------------------- RESID_INLINE sound_sample Filter::output() { // This is handy for testing. if (!enabled) { return (Vnf + mixer_DC)*static_cast(vol); } // Mix highpass, bandpass, and lowpass outputs. The sum is not // weighted, this can be confirmed by sampling sound output for // e.g. bandpass, lowpass, and bandpass+lowpass from a SID chip. // The code below is expanded to a switch for faster execution. // if (hp) Vf += Vhp; // if (bp) Vf += Vbp; // if (lp) Vf += Vlp; sound_sample Vf; switch (hp_bp_lp) { default: case 0x0: Vf = 0; break; case 0x1: Vf = Vlp; break; case 0x2: Vf = Vbp; break; case 0x3: Vf = Vlp + Vbp; break; case 0x4: Vf = Vhp; break; case 0x5: Vf = Vlp + Vhp; break; case 0x6: Vf = Vbp + Vhp; break; case 0x7: Vf = Vlp + Vbp + Vhp; break; } // Sum non-filtered and filtered output. // Multiply the sum with volume. return (Vnf + Vf + mixer_DC)*static_cast(vol); } #endif // RESID_INLINING || defined(__FILTER_CC__) #endif // not __FILTER_H__ CheeseCutter-2.10/src/resid/pot.cpp000066400000000000000000000021341516216315000172220ustar00rootroot00000000000000// --------------------------------------------------------------------------- // This file is part of reSID, a MOS6581 SID emulator engine. // Copyright (C) 2004 Dag Lem // // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; either version 2 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public 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 "pot.h" reg8 Potentiometer::readPOT() { // NB! Not modeled. return 0xff; } CheeseCutter-2.10/src/resid/pot.h000066400000000000000000000021761516216315000166750ustar00rootroot00000000000000// --------------------------------------------------------------------------- // This file is part of reSID, a MOS6581 SID emulator engine. // Copyright (C) 2004 Dag Lem // // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; either version 2 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public 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 __POT_H__ #define __POT_H__ #include "siddefs.h" class Potentiometer { public: reg8 readPOT(); }; #endif CheeseCutter-2.10/src/resid/sid.cpp000066400000000000000000000762631516216315000172150ustar00rootroot00000000000000// --------------------------------------------------------------------------- // This file is part of reSID, a MOS6581 SID emulator engine. // Copyright (C) 2004 Dag Lem // // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; either version 2 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public 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 "sid.h" #include // Resampling constants. // The error in interpolated lookup is bounded by 1.234/L^2, // while the error in non-interpolated lookup is bounded by // 0.7854/L + 0.4113/L^2, see // http://www-ccrma.stanford.edu/~jos/resample/Choice_Table_Size.html // For a resolution of 16 bits this yields L >= 285 and L >= 51473, // respectively. #define FIR_N 125 #define FIR_RES_INTERPOLATE 285 #define FIR_RES_FAST 51473 #define FIR_SHIFT 15 #define RINGSIZE 16384 // Fixpoint constants (16.16 bits). #define FIXP_SHIFT 16 #define FIXP_MASK 0xffff // ---------------------------------------------------------------------------- // Constructor. // ---------------------------------------------------------------------------- SID::SID() { // Initialize pointers. sample = 0; fir = 0; voice[0].set_sync_source(&voice[2]); voice[1].set_sync_source(&voice[0]); voice[2].set_sync_source(&voice[1]); set_sampling_parameters(985248, SAMPLE_FAST, 44100); bus_value = 0; bus_value_ttl = 0; ext_in = 0; } // ---------------------------------------------------------------------------- // Destructor. // ---------------------------------------------------------------------------- SID::~SID() { delete[] sample; delete[] fir; } // ---------------------------------------------------------------------------- // Set chip model. // ---------------------------------------------------------------------------- void SID::set_chip_model(chip_model model) { for (int i = 0; i < 3; i++) { voice[i].set_chip_model(model); } filter.set_chip_model(model); extfilt.set_chip_model(model); } // ---------------------------------------------------------------------------- // SID reset. // ---------------------------------------------------------------------------- void SID::reset() { for (int i = 0; i < 3; i++) { voice[i].reset(); } filter.reset(); extfilt.reset(); bus_value = 0; bus_value_ttl = 0; } // ---------------------------------------------------------------------------- // Write 16-bit sample to audio input. // NB! The caller is responsible for keeping the value within 16 bits. // Note that to mix in an external audio signal, the signal should be // resampled to 1MHz first to avoid sampling noise. // ---------------------------------------------------------------------------- void SID::input(int sample) { // Voice outputs are 20 bits. Scale up to match three voices in order // to facilitate simulation of the MOS8580 "digi boost" hardware hack. ext_in = (sample << 4)*3; } // ---------------------------------------------------------------------------- // Read sample from audio output. // Both 16-bit and n-bit output is provided. // ---------------------------------------------------------------------------- int SID::output() { const int range = 1 << 16; const int half = range >> 1; int sample = extfilt.output()/((4095*255 >> 7)*3*15*2/range); if (sample >= half) { return half - 1; } if (sample < -half) { return -half; } return sample; } int SID::output(int bits) { const int range = 1 << bits; const int half = range >> 1; int sample = extfilt.output()/((4095*255 >> 7)*3*15*2/range); if (sample >= half) { return half - 1; } if (sample < -half) { return -half; } return sample; } // ---------------------------------------------------------------------------- // Read registers. // // Reading a write only register returns the last byte written to any SID // register. The individual bits in this value start to fade down towards // zero after a few cycles. All bits reach zero within approximately // $2000 - $4000 cycles. // It has been claimed that this fading happens in an orderly fashion, however // sampling of write only registers reveals that this is not the case. // NB! This is not correctly modeled. // The actual use of write only registers has largely been made in the belief // that all SID registers are readable. To support this belief the read // would have to be done immediately after a write to the same register // (remember that an intermediate write to another register would yield that // value instead). With this in mind we return the last value written to // any SID register for $2000 cycles without modeling the bit fading. // ---------------------------------------------------------------------------- reg8 SID::read(reg8 offset) { switch (offset) { case 0x19: return potx.readPOT(); case 0x1a: return poty.readPOT(); case 0x1b: return voice[2].wave.readOSC(); case 0x1c: return voice[2].envelope.readENV(); default: return bus_value; } } // ---------------------------------------------------------------------------- // Write registers. // ---------------------------------------------------------------------------- void SID::write(reg8 offset, reg8 value) { bus_value = value; bus_value_ttl = 0x2000; switch (offset) { case 0x00: voice[0].wave.writeFREQ_LO(value); break; case 0x01: voice[0].wave.writeFREQ_HI(value); break; case 0x02: voice[0].wave.writePW_LO(value); break; case 0x03: voice[0].wave.writePW_HI(value); break; case 0x04: voice[0].writeCONTROL_REG(value); break; case 0x05: voice[0].envelope.writeATTACK_DECAY(value); break; case 0x06: voice[0].envelope.writeSUSTAIN_RELEASE(value); break; case 0x07: voice[1].wave.writeFREQ_LO(value); break; case 0x08: voice[1].wave.writeFREQ_HI(value); break; case 0x09: voice[1].wave.writePW_LO(value); break; case 0x0a: voice[1].wave.writePW_HI(value); break; case 0x0b: voice[1].writeCONTROL_REG(value); break; case 0x0c: voice[1].envelope.writeATTACK_DECAY(value); break; case 0x0d: voice[1].envelope.writeSUSTAIN_RELEASE(value); break; case 0x0e: voice[2].wave.writeFREQ_LO(value); break; case 0x0f: voice[2].wave.writeFREQ_HI(value); break; case 0x10: voice[2].wave.writePW_LO(value); break; case 0x11: voice[2].wave.writePW_HI(value); break; case 0x12: voice[2].writeCONTROL_REG(value); break; case 0x13: voice[2].envelope.writeATTACK_DECAY(value); break; case 0x14: voice[2].envelope.writeSUSTAIN_RELEASE(value); break; case 0x15: filter.writeFC_LO(value); break; case 0x16: filter.writeFC_HI(value); break; case 0x17: filter.writeRES_FILT(value); break; case 0x18: filter.writeMODE_VOL(value); break; default: break; } } // ---------------------------------------------------------------------------- // Constructor. // ---------------------------------------------------------------------------- SID::State::State() { int i; for (i = 0; i < 0x20; i++) { sid_register[i] = 0; } bus_value = 0; bus_value_ttl = 0; for (i = 0; i < 3; i++) { accumulator[i] = 0; shift_register[i] = 0x7ffff8; rate_counter[i] = 0; rate_counter_period[i] = 9; exponential_counter[i] = 0; exponential_counter_period[i] = 1; envelope_counter[i] = 0; envelope_state[i] = EnvelopeGenerator::RELEASE; hold_zero[i] = true; } } // ---------------------------------------------------------------------------- // Read state. // ---------------------------------------------------------------------------- SID::State SID::read_state() { State state; int i, j; for (i = 0, j = 0; i < 3; i++, j += 7) { WaveformGenerator& wave = voice[i].wave; EnvelopeGenerator& envelope = voice[i].envelope; state.sid_register[j + 0] = wave.freq & 0xff; state.sid_register[j + 1] = wave.freq >> 8; state.sid_register[j + 2] = wave.pw & 0xff; state.sid_register[j + 3] = wave.pw >> 8; state.sid_register[j + 4] = (wave.waveform << 4) | (wave.test ? 0x08 : 0) | (wave.ring_mod ? 0x04 : 0) | (wave.sync ? 0x02 : 0) | (envelope.gate ? 0x01 : 0); state.sid_register[j + 5] = (envelope.attack << 4) | envelope.decay; state.sid_register[j + 6] = (envelope.sustain << 4) | envelope.release; } state.sid_register[j++] = filter.fc & 0x007; state.sid_register[j++] = filter.fc >> 3; state.sid_register[j++] = (filter.res << 4) | filter.filt; state.sid_register[j++] = (filter.voice3off ? 0x80 : 0) | (filter.hp_bp_lp << 4) | filter.vol; // These registers are superfluous, but included for completeness. for (; j < 0x1d; j++) { state.sid_register[j] = read(j); } for (; j < 0x20; j++) { state.sid_register[j] = 0; } state.bus_value = bus_value; state.bus_value_ttl = bus_value_ttl; for (i = 0; i < 3; i++) { state.accumulator[i] = voice[i].wave.accumulator; state.shift_register[i] = voice[i].wave.shift_register; state.rate_counter[i] = voice[i].envelope.rate_counter; state.rate_counter_period[i] = voice[i].envelope.rate_period; state.exponential_counter[i] = voice[i].envelope.exponential_counter; state.exponential_counter_period[i] = voice[i].envelope.exponential_counter_period; state.envelope_counter[i] = voice[i].envelope.envelope_counter; state.envelope_state[i] = voice[i].envelope.state; state.hold_zero[i] = voice[i].envelope.hold_zero; } return state; } // ---------------------------------------------------------------------------- // Write state. // ---------------------------------------------------------------------------- void SID::write_state(const State& state) { int i; for (i = 0; i <= 0x18; i++) { write(i, state.sid_register[i]); } bus_value = state.bus_value; bus_value_ttl = state.bus_value_ttl; for (i = 0; i < 3; i++) { voice[i].wave.accumulator = state.accumulator[i]; voice[i].wave.shift_register = state.shift_register[i]; voice[i].envelope.rate_counter = state.rate_counter[i]; voice[i].envelope.rate_period = state.rate_counter_period[i]; voice[i].envelope.exponential_counter = state.exponential_counter[i]; voice[i].envelope.exponential_counter_period = state.exponential_counter_period[i]; voice[i].envelope.envelope_counter = state.envelope_counter[i]; voice[i].envelope.state = state.envelope_state[i]; voice[i].envelope.hold_zero = state.hold_zero[i]; } } // ---------------------------------------------------------------------------- // Enable filter. // ---------------------------------------------------------------------------- void SID::enable_filter(bool enable) { filter.enable_filter(enable); } // ---------------------------------------------------------------------------- // Enable external filter. // ---------------------------------------------------------------------------- void SID::enable_external_filter(bool enable) { extfilt.enable_filter(enable); } // ---------------------------------------------------------------------------- // I0() computes the 0th order modified Bessel function of the first kind. // This function is originally from resample-1.5/filterkit.c by J. O. Smith. // ---------------------------------------------------------------------------- double SID::I0(double x) { // Max error acceptable in I0. const double I0e = 1e-6; double sum, u, halfx, temp; int n; sum = u = n = 1; halfx = x/2.0; do { temp = halfx/n++; u *= temp*temp; sum += u; } while (u >= I0e*sum); return sum; } // ---------------------------------------------------------------------------- // Setting of SID sampling parameters. // // Use a clock freqency of 985248Hz for PAL C64, 1022730Hz for NTSC C64. // The default end of passband frequency is pass_freq = 0.9*sample_freq/2 // for sample frequencies up to ~ 44.1kHz, and 20kHz for higher sample // frequencies. // // For resampling, the ratio between the clock frequency and the sample // frequency is limited as follows: // 125*clock_freq/sample_freq < 16384 // E.g. provided a clock frequency of ~ 1MHz, the sample frequency can not // be set lower than ~ 8kHz. A lower sample frequency would make the // resampling code overfill its 16k sample ring buffer. // // The end of passband frequency is also limited: // pass_freq <= 0.9*sample_freq/2 // E.g. for a 44.1kHz sampling rate the end of passband frequency is limited // to slightly below 20kHz. This constraint ensures that the FIR table is // not overfilled. // ---------------------------------------------------------------------------- bool SID::set_sampling_parameters(double clock_freq, sampling_method method, double sample_freq, double pass_freq, double filter_scale) { // Check resampling constraints. if (method == SAMPLE_RESAMPLE_INTERPOLATE || method == SAMPLE_RESAMPLE_FAST) { // Check whether the sample ring buffer would overfill. if (FIR_N*clock_freq/sample_freq >= RINGSIZE) { return false; } // The default passband limit is 0.9*sample_freq/2 for sample // frequencies below ~ 44.1kHz, and 20kHz for higher sample frequencies. if (pass_freq < 0) { pass_freq = 20000; if (2*pass_freq/sample_freq >= 0.9) { pass_freq = 0.9*sample_freq/2; } } // Check whether the FIR table would overfill. else if (pass_freq > 0.9*sample_freq/2) { return false; } // The filter scaling is only included to avoid clipping, so keep // it sane. if (filter_scale < 0.9 || filter_scale > 1.0) { return false; } } clock_frequency = clock_freq; sampling = method; cycles_per_sample = cycle_count(clock_freq/sample_freq*(1 << FIXP_SHIFT) + 0.5); sample_offset = 0; sample_prev = 0; // FIR initialization is only necessary for resampling. if (method != SAMPLE_RESAMPLE_INTERPOLATE && method != SAMPLE_RESAMPLE_FAST) { delete[] sample; delete[] fir; sample = 0; fir = 0; return true; } const double pi = 3.1415926535897932385; // 16 bits -> -96dB stopband attenuation. const double A = -20*log10(1.0/(1 << 16)); // A fraction of the bandwidth is allocated to the transition band, double dw = (1 - 2*pass_freq/sample_freq)*pi; // The cutoff frequency is midway through the transition band. double wc = (2*pass_freq/sample_freq + 1)*pi/2; // For calculation of beta and N see the reference for the kaiserord // function in the MATLAB Signal Processing Toolbox: // http://www.mathworks.com/access/helpdesk/help/toolbox/signal/kaiserord.html const double beta = 0.1102*(A - 8.7); const double I0beta = I0(beta); // The filter order will maximally be 124 with the current constraints. // N >= (96.33 - 7.95)/(2.285*0.1*pi) -> N >= 123 // The filter order is equal to the number of zero crossings, i.e. // it should be an even number (sinc is symmetric about x = 0). int N = int((A - 7.95)/(2.285*dw) + 0.5); N += N & 1; double f_samples_per_cycle = sample_freq/clock_freq; double f_cycles_per_sample = clock_freq/sample_freq; // The filter length is equal to the filter order + 1. // The filter length must be an odd number (sinc is symmetric about x = 0). fir_N = int(N*f_cycles_per_sample) + 1; fir_N |= 1; // We clamp the filter table resolution to 2^n, making the fixpoint // sample_offset a whole multiple of the filter table resolution. int res = method == SAMPLE_RESAMPLE_INTERPOLATE ? FIR_RES_INTERPOLATE : FIR_RES_FAST; int n = (int)ceil(log(res/f_cycles_per_sample)/log(2.0)); fir_RES = 1 << n; // Allocate memory for FIR tables. delete[] fir; fir = new short[fir_N*fir_RES]; // Calculate fir_RES FIR tables for linear interpolation. for (int i = 0; i < fir_RES; i++) { int fir_offset = i*fir_N + fir_N/2; double j_offset = double(i)/fir_RES; // Calculate FIR table. This is the sinc function, weighted by the // Kaiser window. for (int j = -fir_N/2; j <= fir_N/2; j++) { double jx = j - j_offset; double wt = wc*jx/f_cycles_per_sample; double temp = jx/(fir_N/2); double Kaiser = fabs(temp) <= 1 ? I0(beta*sqrt(1 - temp*temp))/I0beta : 0; double sincwt = fabs(wt) >= 1e-6 ? sin(wt)/wt : 1; double val = (1 << FIR_SHIFT)*filter_scale*f_samples_per_cycle*wc/pi*sincwt*Kaiser; fir[fir_offset + j] = short(val + 0.5); } } // Allocate sample buffer. if (!sample) { sample = new short[RINGSIZE*2]; } // Clear sample buffer. for (int j = 0; j < RINGSIZE*2; j++) { sample[j] = 0; } sample_index = 0; return true; } // ---------------------------------------------------------------------------- // Adjustment of SID sampling frequency. // // In some applications, e.g. a C64 emulator, it can be desirable to // synchronize sound with a timer source. This is supported by adjustment of // the SID sampling frequency. // // NB! Adjustment of the sampling frequency may lead to noticeable shifts in // frequency, and should only be used for interactive applications. Note also // that any adjustment of the sampling frequency will change the // characteristics of the resampling filter, since the filter is not rebuilt. // ---------------------------------------------------------------------------- void SID::adjust_sampling_frequency(double sample_freq) { cycles_per_sample = cycle_count(clock_frequency/sample_freq*(1 << FIXP_SHIFT) + 0.5); } // ---------------------------------------------------------------------------- // Return array of default spline interpolation points to map FC to // filter cutoff frequency. // ---------------------------------------------------------------------------- void SID::fc_default(const fc_point*& points, int& count) { filter.fc_default(points, count); } // ---------------------------------------------------------------------------- // Return FC spline plotter object. // ---------------------------------------------------------------------------- PointPlotter SID::fc_plotter() { return filter.fc_plotter(); } // ---------------------------------------------------------------------------- // SID clocking - 1 cycle. // ---------------------------------------------------------------------------- void SID::clock() { int i; // Age bus value. if (--bus_value_ttl <= 0) { bus_value = 0; bus_value_ttl = 0; } // Clock amplitude modulators. for (i = 0; i < 3; i++) { voice[i].envelope.clock(); } // Clock oscillators. for (i = 0; i < 3; i++) { voice[i].wave.clock(); } // Synchronize oscillators. for (i = 0; i < 3; i++) { voice[i].wave.synchronize(); } // Clock filter. filter.clock(voice[0].output(), voice[1].output(), voice[2].output(), ext_in); // Clock external filter. extfilt.clock(filter.output()); } // ---------------------------------------------------------------------------- // SID clocking - delta_t cycles. // ---------------------------------------------------------------------------- void SID::clock(cycle_count delta_t) { int i; if (delta_t <= 0) { return; } // Age bus value. bus_value_ttl -= delta_t; if (bus_value_ttl <= 0) { bus_value = 0; bus_value_ttl = 0; } // Clock amplitude modulators. for (i = 0; i < 3; i++) { voice[i].envelope.clock(delta_t); } // Clock and synchronize oscillators. // Loop until we reach the current cycle. cycle_count delta_t_osc = delta_t; while (delta_t_osc) { cycle_count delta_t_min = delta_t_osc; // Find minimum number of cycles to an oscillator accumulator MSB toggle. // We have to clock on each MSB on / MSB off for hard sync to operate // correctly. for (i = 0; i < 3; i++) { WaveformGenerator& wave = voice[i].wave; // It is only necessary to clock on the MSB of an oscillator that is // a sync source and has freq != 0. if (!(wave.sync_dest->sync && wave.freq)) { continue; } reg16 freq = wave.freq; reg24 accumulator = wave.accumulator; // Clock on MSB off if MSB is on, clock on MSB on if MSB is off. reg24 delta_accumulator = (accumulator & 0x800000 ? 0x1000000 : 0x800000) - accumulator; cycle_count delta_t_next = delta_accumulator/freq; if (delta_accumulator%freq) { ++delta_t_next; } if (delta_t_next < delta_t_min) { delta_t_min = delta_t_next; } } // Clock oscillators. for (i = 0; i < 3; i++) { voice[i].wave.clock(delta_t_min); } // Synchronize oscillators. for (i = 0; i < 3; i++) { voice[i].wave.synchronize(); } delta_t_osc -= delta_t_min; } // Clock filter. filter.clock(delta_t, voice[0].output(), voice[1].output(), voice[2].output(), ext_in); // Clock external filter. extfilt.clock(delta_t, filter.output()); } // ---------------------------------------------------------------------------- // SID clocking with audio sampling. // Fixpoint arithmetics is used. // // The example below shows how to clock the SID a specified amount of cycles // while producing audio output: // // while (delta_t) { // bufindex += sid.clock(delta_t, buf + bufindex, buflength - bufindex); // write(dsp, buf, bufindex*2); // bufindex = 0; // } // // ---------------------------------------------------------------------------- int SID::clock(cycle_count& delta_t, short* buf, int n, int interleave) { switch (sampling) { default: case SAMPLE_FAST: return clock_fast(delta_t, buf, n, interleave); case SAMPLE_INTERPOLATE: return clock_interpolate(delta_t, buf, n, interleave); case SAMPLE_RESAMPLE_INTERPOLATE: return clock_resample_interpolate(delta_t, buf, n, interleave); case SAMPLE_RESAMPLE_FAST: return clock_resample_fast(delta_t, buf, n, interleave); } } // ---------------------------------------------------------------------------- // SID clocking with audio sampling - delta clocking picking nearest sample. // ---------------------------------------------------------------------------- RESID_INLINE int SID::clock_fast(cycle_count& delta_t, short* buf, int n, int interleave) { int s = 0; for (;;) { cycle_count next_sample_offset = sample_offset + cycles_per_sample + (1 << (FIXP_SHIFT - 1)); cycle_count delta_t_sample = next_sample_offset >> FIXP_SHIFT; if (delta_t_sample > delta_t) { break; } if (s >= n) { return s; } clock(delta_t_sample); delta_t -= delta_t_sample; sample_offset = (next_sample_offset & FIXP_MASK) - (1 << (FIXP_SHIFT - 1)); buf[s++*interleave] = output(); } clock(delta_t); sample_offset -= delta_t << FIXP_SHIFT; delta_t = 0; return s; } // ---------------------------------------------------------------------------- // SID clocking with audio sampling - cycle based with linear sample // interpolation. // // Here the chip is clocked every cycle. This yields higher quality // sound since the samples are linearly interpolated, and since the // external filter attenuates frequencies above 16kHz, thus reducing // sampling noise. // ---------------------------------------------------------------------------- RESID_INLINE int SID::clock_interpolate(cycle_count& delta_t, short* buf, int n, int interleave) { int s = 0; int i; for (;;) { cycle_count next_sample_offset = sample_offset + cycles_per_sample; cycle_count delta_t_sample = next_sample_offset >> FIXP_SHIFT; if (delta_t_sample > delta_t) { break; } if (s >= n) { return s; } for (i = 0; i < delta_t_sample - 1; i++) { clock(); } if (i < delta_t_sample) { sample_prev = output(); clock(); } delta_t -= delta_t_sample; sample_offset = next_sample_offset & FIXP_MASK; short sample_now = output(); buf[s++*interleave] = sample_prev + (sample_offset*(sample_now - sample_prev) >> FIXP_SHIFT); sample_prev = sample_now; } for (i = 0; i < delta_t - 1; i++) { clock(); } if (i < delta_t) { sample_prev = output(); clock(); } sample_offset -= delta_t << FIXP_SHIFT; delta_t = 0; return s; } // ---------------------------------------------------------------------------- // SID clocking with audio sampling - cycle based with audio resampling. // // This is the theoretically correct (and computationally intensive) audio // sample generation. The samples are generated by resampling to the specified // sampling frequency. The work rate is inversely proportional to the // percentage of the bandwidth allocated to the filter transition band. // // This implementation is based on the paper "A Flexible Sampling-Rate // Conversion Method", by J. O. Smith and P. Gosset, or rather on the // expanded tutorial on the "Digital Audio Resampling Home Page": // http://www-ccrma.stanford.edu/~jos/resample/ // // By building shifted FIR tables with samples according to the // sampling frequency, this implementation dramatically reduces the // computational effort in the filter convolutions, without any loss // of accuracy. The filter convolutions are also vectorizable on // current hardware. // // Further possible optimizations are: // * An equiripple filter design could yield a lower filter order, see // http://www.mwrf.com/Articles/ArticleID/7229/7229.html // * The Convolution Theorem could be used to bring the complexity of // convolution down from O(n*n) to O(n*log(n)) using the Fast Fourier // Transform, see http://en.wikipedia.org/wiki/Convolution_theorem // * Simply resampling in two steps can also yield computational // savings, since the transition band will be wider in the first step // and the required filter order is thus lower in this step. // Laurent Ganier has found the optimal intermediate sampling frequency // to be (via derivation of sum of two steps): // 2 * pass_freq + sqrt [ 2 * pass_freq * orig_sample_freq // * (dest_sample_freq - 2 * pass_freq) / dest_sample_freq ] // // NB! the result of right shifting negative numbers is really // implementation dependent in the C++ standard. // ---------------------------------------------------------------------------- RESID_INLINE int SID::clock_resample_interpolate(cycle_count& delta_t, short* buf, int n, int interleave) { int s = 0; for (;;) { cycle_count next_sample_offset = sample_offset + cycles_per_sample; cycle_count delta_t_sample = next_sample_offset >> FIXP_SHIFT; if (delta_t_sample > delta_t) { break; } if (s >= n) { return s; } for (int i = 0; i < delta_t_sample; i++) { clock(); sample[sample_index] = sample[sample_index + RINGSIZE] = output(); ++sample_index; sample_index &= 0x3fff; } delta_t -= delta_t_sample; sample_offset = next_sample_offset & FIXP_MASK; int fir_offset = sample_offset*fir_RES >> FIXP_SHIFT; int fir_offset_rmd = sample_offset*fir_RES & FIXP_MASK; short* fir_start = fir + fir_offset*fir_N; short* sample_start = sample + sample_index - fir_N + RINGSIZE; // Convolution with filter impulse response. int v1 = 0; for (int j = 0; j < fir_N; j++) { v1 += sample_start[j]*fir_start[j]; } // Use next FIR table, wrap around to first FIR table using // previous sample. if (++fir_offset == fir_RES) { fir_offset = 0; --sample_start; } fir_start = fir + fir_offset*fir_N; // Convolution with filter impulse response. int v2 = 0; for (int j = 0; j < fir_N; j++) { v2 += sample_start[j]*fir_start[j]; } // Linear interpolation. // fir_offset_rmd is equal for all samples, it can thus be factorized out: // sum(v1 + rmd*(v2 - v1)) = sum(v1) + rmd*(sum(v2) - sum(v1)) int v = v1 + (fir_offset_rmd*(v2 - v1) >> FIXP_SHIFT); v >>= FIR_SHIFT; // Saturated arithmetics to guard against 16 bit sample overflow. const int half = 1 << 15; if (v >= half) { v = half - 1; } else if (v < -half) { v = -half; } buf[s++*interleave] = v; } for (int i = 0; i < delta_t; i++) { clock(); sample[sample_index] = sample[sample_index + RINGSIZE] = output(); ++sample_index; sample_index &= 0x3fff; } sample_offset -= delta_t << FIXP_SHIFT; delta_t = 0; return s; } // ---------------------------------------------------------------------------- // SID clocking with audio sampling - cycle based with audio resampling. // ---------------------------------------------------------------------------- RESID_INLINE int SID::clock_resample_fast(cycle_count& delta_t, short* buf, int n, int interleave) { int s = 0; for (;;) { cycle_count next_sample_offset = sample_offset + cycles_per_sample; cycle_count delta_t_sample = next_sample_offset >> FIXP_SHIFT; if (delta_t_sample > delta_t) { break; } if (s >= n) { return s; } for (int i = 0; i < delta_t_sample; i++) { clock(); sample[sample_index] = sample[sample_index + RINGSIZE] = output(); ++sample_index; sample_index &= 0x3fff; } delta_t -= delta_t_sample; sample_offset = next_sample_offset & FIXP_MASK; int fir_offset = sample_offset*fir_RES >> FIXP_SHIFT; short* fir_start = fir + fir_offset*fir_N; short* sample_start = sample + sample_index - fir_N + RINGSIZE; // Convolution with filter impulse response. int v = 0; for (int j = 0; j < fir_N; j++) { v += sample_start[j]*fir_start[j]; } v >>= FIR_SHIFT; // Saturated arithmetics to guard against 16 bit sample overflow. const int half = 1 << 15; if (v >= half) { v = half - 1; } else if (v < -half) { v = -half; } buf[s++*interleave] = v; } for (int i = 0; i < delta_t; i++) { clock(); sample[sample_index] = sample[sample_index + RINGSIZE] = output(); ++sample_index; sample_index &= 0x3fff; } sample_offset -= delta_t << FIXP_SHIFT; delta_t = 0; return s; } CheeseCutter-2.10/src/resid/sid.h000066400000000000000000000072061516216315000166510ustar00rootroot00000000000000// --------------------------------------------------------------------------- // This file is part of reSID, a MOS6581 SID emulator engine. // Copyright (C) 2004 Dag Lem // // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; either version 2 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public 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 __SID_H__ #define __SID_H__ #include "siddefs.h" #include "voice.h" #include "filter.h" #include "extfilt.h" #include "pot.h" class SID { public: SID(); ~SID(); void set_chip_model(chip_model model); void enable_filter(bool enable); void enable_external_filter(bool enable); bool set_sampling_parameters(double clock_freq, sampling_method method, double sample_freq, double pass_freq = -1, double filter_scale = 0.97); void adjust_sampling_frequency(double sample_freq); void fc_default(const fc_point*& points, int& count); PointPlotter fc_plotter(); void clock(); void clock(cycle_count delta_t); int clock(cycle_count& delta_t, short* buf, int n, int interleave = 1); void reset(); // Read/write registers. reg8 read(reg8 offset); void write(reg8 offset, reg8 value); // Read/write state. class State { public: State(); char sid_register[0x20]; reg8 bus_value; cycle_count bus_value_ttl; reg24 accumulator[3]; reg24 shift_register[3]; reg16 rate_counter[3]; reg16 rate_counter_period[3]; reg16 exponential_counter[3]; reg16 exponential_counter_period[3]; reg8 envelope_counter[3]; EnvelopeGenerator::State envelope_state[3]; bool hold_zero[3]; }; State read_state(); void write_state(const State& state); // 16-bit input (EXT IN). void input(int sample); // 16-bit output (AUDIO OUT). int output(); // n-bit output. int output(int bits); protected: static double I0(double x); RESID_INLINE int clock_fast(cycle_count& delta_t, short* buf, int n, int interleave); RESID_INLINE int clock_interpolate(cycle_count& delta_t, short* buf, int n, int interleave); RESID_INLINE int clock_resample_interpolate(cycle_count& delta_t, short* buf, int n, int interleave); RESID_INLINE int clock_resample_fast(cycle_count& delta_t, short* buf, int n, int interleave); Voice voice[3]; Filter filter; ExternalFilter extfilt; Potentiometer potx; Potentiometer poty; reg8 bus_value; cycle_count bus_value_ttl; double clock_frequency; // External audio input. int ext_in; // Sampling variables. sampling_method sampling; cycle_count cycles_per_sample; cycle_count sample_offset; int sample_index; short sample_prev; int fir_N; int fir_RES; // Ring buffer with overflow for contiguous storage of RINGSIZE samples. short* sample; // FIR_RES filter tables (FIR_N*FIR_RES). short* fir; }; #endif // not __SID_H__ CheeseCutter-2.10/src/resid/siddefs.h000066400000000000000000000047001516216315000175070ustar00rootroot00000000000000// --------------------------------------------------------------------------- // This file is part of reSID, a MOS6581 SID emulator engine. // Copyright (C) 1999 Dag Lem // // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; either version 2 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public 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 __SIDDEFS_H__ #define __SIDDEFS_H__ // From math.h #define M_LN2 0.69314718055994530942 /* log_e 2 */ #define M_PI 3.14159265358979323846 /* pi */ // Define bool, true, and false for C++ compilers that lack these keywords. #define RESID_HAVE_BOOL 1 #if !RESID_HAVE_BOOL typedef int bool; const bool true = 1; const bool false = 0; #endif // We could have used the smallest possible data type for each SID register, // however this would give a slower engine because of data type conversions. // An int is assumed to be at least 32 bits (necessary in the types reg24, // cycle_count, and sound_sample). GNU does not support 16-bit machines // (GNU Coding Standards: Portability between CPUs), so this should be // a valid assumption. typedef unsigned int reg4; typedef unsigned int reg8; typedef unsigned int reg12; typedef unsigned int reg16; typedef unsigned int reg24; typedef unsigned int reg32; typedef int cycle_count; typedef int sound_sample; typedef sound_sample fc_point[2]; enum chip_model { MOS6581 = 1, MOS8580 }; enum sampling_method { SAMPLE_FAST, SAMPLE_INTERPOLATE, SAMPLE_RESAMPLE_INTERPOLATE, SAMPLE_RESAMPLE_FAST }; extern "C" { #ifndef __VERSION_CC__ extern const char* resid_version_string; #else const char* resid_version_string = VERSION; #endif } // Inlining on/off. #define RESID_INLINING 1 #define RESID_INLINE inline #endif // not __SIDDEFS_H__ CheeseCutter-2.10/src/resid/spline.h000066400000000000000000000215211516216315000173600ustar00rootroot00000000000000// --------------------------------------------------------------------------- // This file is part of reSID, a MOS6581 SID emulator engine. // Copyright (C) 2004 Dag Lem // // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; either version 2 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public 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 __SPLINE_H__ #define __SPLINE_H__ // Our objective is to construct a smooth interpolating single-valued function // y = f(x). // // Catmull-Rom splines are widely used for interpolation, however these are // parametric curves [x(t) y(t) ...] and can not be used to directly calculate // y = f(x). // For a discussion of Catmull-Rom splines see Catmull, E., and R. Rom, // "A Class of Local Interpolating Splines", Computer Aided Geometric Design. // // Natural cubic splines are single-valued functions, and have been used in // several applications e.g. to specify gamma curves for image display. // These splines do not afford local control, and a set of linear equations // including all interpolation points must be solved before any point on the // curve can be calculated. The lack of local control makes the splines // more difficult to handle than e.g. Catmull-Rom splines, and real-time // interpolation of a stream of data points is not possible. // For a discussion of natural cubic splines, see e.g. Kreyszig, E., "Advanced // Engineering Mathematics". // // Our approach is to approximate the properties of Catmull-Rom splines for // piecewice cubic polynomials f(x) = ax^3 + bx^2 + cx + d as follows: // Each curve segment is specified by four interpolation points, // p0, p1, p2, p3. // The curve between p1 and p2 must interpolate both p1 and p2, and in addition // f'(p1.x) = k1 = (p2.y - p0.y)/(p2.x - p0.x) and // f'(p2.x) = k2 = (p3.y - p1.y)/(p3.x - p1.x). // // The constraints are expressed by the following system of linear equations // // [ 1 xi xi^2 xi^3 ] [ d ] [ yi ] // [ 1 2*xi 3*xi^2 ] * [ c ] = [ ki ] // [ 1 xj xj^2 xj^3 ] [ b ] [ yj ] // [ 1 2*xj 3*xj^2 ] [ a ] [ kj ] // // Solving using Gaussian elimination and back substitution, setting // dy = yj - yi, dx = xj - xi, we get // // a = ((ki + kj) - 2*dy/dx)/(dx*dx); // b = ((kj - ki)/dx - 3*(xi + xj)*a)/2; // c = ki - (3*xi*a + 2*b)*xi; // d = yi - ((xi*a + b)*xi + c)*xi; // // Having calculated the coefficients of the cubic polynomial we have the // choice of evaluation by brute force // // for (x = x1; x <= x2; x += res) { // y = ((a*x + b)*x + c)*x + d; // plot(x, y); // } // // or by forward differencing // // y = ((a*x1 + b)*x1 + c)*x1 + d; // dy = (3*a*(x1 + res) + 2*b)*x1*res + ((a*res + b)*res + c)*res; // d2y = (6*a*(x1 + res) + 2*b)*res*res; // d3y = 6*a*res*res*res; // // for (x = x1; x <= x2; x += res) { // plot(x, y); // y += dy; dy += d2y; d2y += d3y; // } // // See Foley, Van Dam, Feiner, Hughes, "Computer Graphics, Principles and // Practice" for a discussion of forward differencing. // // If we have a set of interpolation points p0, ..., pn, we may specify // curve segments between p0 and p1, and between pn-1 and pn by using the // following constraints: // f''(p0.x) = 0 and // f''(pn.x) = 0. // // Substituting the results for a and b in // // 2*b + 6*a*xi = 0 // // we get // // ki = (3*dy/dx - kj)/2; // // or by substituting the results for a and b in // // 2*b + 6*a*xj = 0 // // we get // // kj = (3*dy/dx - ki)/2; // // Finally, if we have only two interpolation points, the cubic polynomial // will degenerate to a straight line if we set // // ki = kj = dy/dx; // #if SPLINE_BRUTE_FORCE #define interpolate_segment interpolate_brute_force #else #define interpolate_segment interpolate_forward_difference #endif // ---------------------------------------------------------------------------- // Calculation of coefficients. // ---------------------------------------------------------------------------- inline void cubic_coefficients(double x1, double y1, double x2, double y2, double k1, double k2, double& a, double& b, double& c, double& d) { double dx = x2 - x1, dy = y2 - y1; a = ((k1 + k2) - 2*dy/dx)/(dx*dx); b = ((k2 - k1)/dx - 3*(x1 + x2)*a)/2; c = k1 - (3*x1*a + 2*b)*x1; d = y1 - ((x1*a + b)*x1 + c)*x1; } // ---------------------------------------------------------------------------- // Evaluation of cubic polynomial by brute force. // ---------------------------------------------------------------------------- template inline void interpolate_brute_force(double x1, double y1, double x2, double y2, double k1, double k2, PointPlotter plot, double res) { double a, b, c, d; cubic_coefficients(x1, y1, x2, y2, k1, k2, a, b, c, d); // Calculate each point. for (double x = x1; x <= x2; x += res) { double y = ((a*x + b)*x + c)*x + d; plot(x, y); } } // ---------------------------------------------------------------------------- // Evaluation of cubic polynomial by forward differencing. // ---------------------------------------------------------------------------- template inline void interpolate_forward_difference(double x1, double y1, double x2, double y2, double k1, double k2, PointPlotter plot, double res) { double a, b, c, d; cubic_coefficients(x1, y1, x2, y2, k1, k2, a, b, c, d); double y = ((a*x1 + b)*x1 + c)*x1 + d; double dy = (3*a*(x1 + res) + 2*b)*x1*res + ((a*res + b)*res + c)*res; double d2y = (6*a*(x1 + res) + 2*b)*res*res; double d3y = 6*a*res*res*res; // Calculate each point. for (double x = x1; x <= x2; x += res) { plot(x, y); y += dy; dy += d2y; d2y += d3y; } } template inline double x(PointIter p) { return (*p)[0]; } template inline double y(PointIter p) { return (*p)[1]; } // ---------------------------------------------------------------------------- // Evaluation of complete interpolating function. // Note that since each curve segment is controlled by four points, the // end points will not be interpolated. If extra control points are not // desirable, the end points can simply be repeated to ensure interpolation. // Note also that points of non-differentiability and discontinuity can be // introduced by repeating points. // ---------------------------------------------------------------------------- template inline void interpolate(PointIter p0, PointIter pn, PointPlotter plot, double res) { double k1, k2; // Set up points for first curve segment. PointIter p1 = p0; ++p1; PointIter p2 = p1; ++p2; PointIter p3 = p2; ++p3; // Draw each curve segment. for (; p2 != pn; ++p0, ++p1, ++p2, ++p3) { // p1 and p2 equal; single point. if (x(p1) == x(p2)) { continue; } // Both end points repeated; straight line. if (x(p0) == x(p1) && x(p2) == x(p3)) { k1 = k2 = (y(p2) - y(p1))/(x(p2) - x(p1)); } // p0 and p1 equal; use f''(x1) = 0. else if (x(p0) == x(p1)) { k2 = (y(p3) - y(p1))/(x(p3) - x(p1)); k1 = (3*(y(p2) - y(p1))/(x(p2) - x(p1)) - k2)/2; } // p2 and p3 equal; use f''(x2) = 0. else if (x(p2) == x(p3)) { k1 = (y(p2) - y(p0))/(x(p2) - x(p0)); k2 = (3*(y(p2) - y(p1))/(x(p2) - x(p1)) - k1)/2; } // Normal curve. else { k1 = (y(p2) - y(p0))/(x(p2) - x(p0)); k2 = (y(p3) - y(p1))/(x(p3) - x(p1)); } interpolate_segment(x(p1), y(p1), x(p2), y(p2), k1, k2, plot, res); } } // ---------------------------------------------------------------------------- // Class for plotting integers into an array. // ---------------------------------------------------------------------------- template class PointPlotter { protected: F* f; public: PointPlotter(F* arr) : f(arr) { } void operator ()(double x, double y) { // Clamp negative values to zero. if (y < 0) { y = 0; } f[F(x)] = F(y); } }; #endif // not __SPLINE_H__ CheeseCutter-2.10/src/resid/voice.cpp000066400000000000000000000116001516216315000175230ustar00rootroot00000000000000// --------------------------------------------------------------------------- // This file is part of reSID, a MOS6581 SID emulator engine. // Copyright (C) 2004 Dag Lem // // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; either version 2 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // --------------------------------------------------------------------------- #define __VOICE_CC__ #include "voice.h" // ---------------------------------------------------------------------------- // Constructor. // ---------------------------------------------------------------------------- Voice::Voice() { set_chip_model(MOS6581); } // ---------------------------------------------------------------------------- // Set chip model. // ---------------------------------------------------------------------------- void Voice::set_chip_model(chip_model model) { wave.set_chip_model(model); if (model == MOS6581) { // The waveform D/A converter introduces a DC offset in the signal // to the envelope multiplying D/A converter. The "zero" level of // the waveform D/A converter can be found as follows: // // Measure the "zero" voltage of voice 3 on the SID audio output // pin, routing only voice 3 to the mixer ($d417 = $0b, $d418 = // $0f, all other registers zeroed). // // Then set the sustain level for voice 3 to maximum and search for // the waveform output value yielding the same voltage as found // above. This is done by trying out different waveform output // values until the correct value is found, e.g. with the following // program: // // lda #$08 // sta $d412 // lda #$0b // sta $d417 // lda #$0f // sta $d418 // lda #$f0 // sta $d414 // lda #$21 // sta $d412 // lda #$01 // sta $d40e // // ldx #$00 // lda #$38 ; Tweak this to find the "zero" level //l cmp $d41b // bne l // stx $d40e ; Stop frequency counter - freeze waveform output // brk // // The waveform output range is 0x000 to 0xfff, so the "zero" // level should ideally have been 0x800. In the measured chip, the // waveform output "zero" level was found to be 0x380 (i.e. $d41b // = 0x38) at 5.94V. wave_zero = 0x380; // The envelope multiplying D/A converter introduces another DC // offset. This is isolated by the following measurements: // // * The "zero" output level of the mixer at full volume is 5.44V. // * Routing one voice to the mixer at full volume yields // 6.75V at maximum voice output (wave = 0xfff, sustain = 0xf) // 5.94V at "zero" voice output (wave = any, sustain = 0x0) // 5.70V at minimum voice output (wave = 0x000, sustain = 0xf) // * The DC offset of one voice is (5.94V - 5.44V) = 0.50V // * The dynamic range of one voice is |6.75V - 5.70V| = 1.05V // * The DC offset is thus 0.50V/1.05V ~ 1/2 of the dynamic range. // // Note that by removing the DC offset, we get the following ranges for // one voice: // y > 0: (6.75V - 5.44V) - 0.50V = 0.81V // y < 0: (5.70V - 5.44V) - 0.50V = -0.24V // The scaling of the voice amplitude is not symmetric about y = 0; // this follows from the DC level in the waveform output. voice_DC = 0x800*0xff; } else { // No DC offsets in the MOS8580. wave_zero = 0x800; voice_DC = 0; } } // ---------------------------------------------------------------------------- // Set sync source. // ---------------------------------------------------------------------------- void Voice::set_sync_source(Voice* source) { wave.set_sync_source(&source->wave); } // ---------------------------------------------------------------------------- // Register functions. // ---------------------------------------------------------------------------- void Voice::writeCONTROL_REG(reg8 control) { wave.writeCONTROL_REG(control); envelope.writeCONTROL_REG(control); } // ---------------------------------------------------------------------------- // SID reset. // ---------------------------------------------------------------------------- void Voice::reset() { wave.reset(); envelope.reset(); } CheeseCutter-2.10/src/resid/voice.h000066400000000000000000000046471516216315000172050ustar00rootroot00000000000000// --------------------------------------------------------------------------- // This file is part of reSID, a MOS6581 SID emulator engine. // Copyright (C) 2004 Dag Lem // // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; either version 2 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public 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 __VOICE_H__ #define __VOICE_H__ #include "siddefs.h" #include "wave.h" #include "envelope.h" class Voice { public: Voice(); void set_chip_model(chip_model model); void set_sync_source(Voice*); void reset(); void writeCONTROL_REG(reg8); // Amplitude modulated waveform output. // Range [-2048*255, 2047*255]. RESID_INLINE sound_sample output(); protected: WaveformGenerator wave; EnvelopeGenerator envelope; // Waveform D/A zero level. sound_sample wave_zero; // Multiplying D/A DC offset. sound_sample voice_DC; friend class SID; }; // ---------------------------------------------------------------------------- // Inline functions. // The following function is defined inline because it is called every // time a sample is calculated. // ---------------------------------------------------------------------------- #if RESID_INLINING || defined(__VOICE_CC__) // ---------------------------------------------------------------------------- // Amplitude modulated waveform output. // Ideal range [-2048*255, 2047*255]. // ---------------------------------------------------------------------------- RESID_INLINE sound_sample Voice::output() { // Multiply oscillator output with envelope output. return (wave.output() - wave_zero)*envelope.output() + voice_DC; } #endif // RESID_INLINING || defined(__VOICE_CC__) #endif // not __VOICE_H__ CheeseCutter-2.10/src/resid/w6__st.cpp000066400000000000000000001011021516216315000176140ustar00rootroot00000000000000// --------------------------------------------------------------------------- // This file is part of reSID, a MOS6581 SID emulator engine. // Copyright (C) 2004 Dag Lem // // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; either version 2 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public 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 "wave.h" reg8 WaveformGenerator::wave6581__ST[] = { /* 0x000: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x008: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x010: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x018: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x020: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x028: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x030: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x038: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x040: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x048: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x050: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x058: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x060: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x068: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x070: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x078: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x03, /* 0x080: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x088: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x090: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x098: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x0a0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x0a8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x0b0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x0b8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, /* 0x0c0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x0c8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x0d0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x0d8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x0e0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x0e8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x0f0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x0f8: */ 0x00, 0x00, 0x00, 0x00, 0x07, 0x07, 0x07, 0x07, /* 0x100: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x108: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x110: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x118: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x120: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x128: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x130: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x138: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, /* 0x140: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x148: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x150: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x158: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x160: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x168: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x170: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x178: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x03, /* 0x180: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x188: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x190: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x198: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1a0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1a8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1b0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1b8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, /* 0x1c0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1c8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1d0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1d8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1e0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1e8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1f0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1f8: */ 0x0e, 0x0e, 0x0e, 0x0e, 0x0f, 0x0f, 0x0f, 0x0f, /* 0x200: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x208: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x210: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x218: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x220: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x228: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x230: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x238: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x240: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x248: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x250: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x258: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x260: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x268: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x270: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x278: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x03, /* 0x280: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x288: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x290: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x298: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x2a0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x2a8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x2b0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x2b8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, /* 0x2c0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x2c8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x2d0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x2d8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x2e0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x2e8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x2f0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x2f8: */ 0x00, 0x00, 0x00, 0x00, 0x07, 0x07, 0x07, 0x07, /* 0x300: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x308: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x310: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x318: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x320: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x328: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x330: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x338: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, /* 0x340: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x348: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x350: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x358: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x360: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x368: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x370: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x378: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x03, /* 0x380: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x388: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x390: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x398: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x3a0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x3a8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x3b0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x3b8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, /* 0x3c0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x3c8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x3d0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x3d8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x3e0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x3e8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x3f0: */ 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, /* 0x3f8: */ 0x1e, 0x1e, 0x1e, 0x1e, 0x1f, 0x1f, 0x3f, 0x3f, /* 0x400: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x408: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x410: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x418: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x420: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x428: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x430: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x438: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x440: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x448: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x450: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x458: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x460: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x468: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x470: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x478: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x03, /* 0x480: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x488: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x490: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x498: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x4a0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x4a8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x4b0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x4b8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, /* 0x4c0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x4c8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x4d0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x4d8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x4e0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x4e8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x4f0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x4f8: */ 0x00, 0x00, 0x00, 0x00, 0x07, 0x07, 0x07, 0x07, /* 0x500: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x508: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x510: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x518: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x520: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x528: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x530: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x538: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, /* 0x540: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x548: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x550: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x558: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x560: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x568: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x570: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x578: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x03, /* 0x580: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x588: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x590: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x598: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x5a0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x5a8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x5b0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x5b8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, /* 0x5c0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x5c8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x5d0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x5d8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x5e0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x5e8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x5f0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x5f8: */ 0x0e, 0x0e, 0x0e, 0x0e, 0x0f, 0x0f, 0x0f, 0x1f, /* 0x600: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x608: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x610: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x618: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x620: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x628: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x630: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x638: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x640: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x648: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x650: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x658: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x660: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x668: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x670: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x678: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x03, /* 0x680: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x688: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x690: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x698: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x6a0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x6a8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x6b0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x6b8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, /* 0x6c0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x6c8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x6d0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x6d8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x6e0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x6e8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x6f0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x6f8: */ 0x00, 0x00, 0x00, 0x00, 0x07, 0x07, 0x07, 0x07, /* 0x700: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x708: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x710: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x718: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x720: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x728: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x730: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x738: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, /* 0x740: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x748: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x750: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x758: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x760: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x768: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x770: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x778: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x03, /* 0x780: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x788: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x790: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x798: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x7a0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x7a8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x7b0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x7b8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, /* 0x7c0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x7c8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x7d0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x7d8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x7e0: */ 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, /* 0x7e8: */ 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, /* 0x7f0: */ 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, /* 0x7f8: */ 0x3e, 0x3e, 0x3f, 0x3f, 0x7f, 0x7f, 0x7f, 0x7f, /* 0x800: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x808: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x810: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x818: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x820: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x828: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x830: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x838: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x840: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x848: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x850: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x858: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x860: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x868: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x870: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x878: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x03, /* 0x880: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x888: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x890: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x898: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x8a0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x8a8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x8b0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x8b8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, /* 0x8c0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x8c8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x8d0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x8d8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x8e0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x8e8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x8f0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x8f8: */ 0x00, 0x00, 0x00, 0x00, 0x07, 0x07, 0x07, 0x07, /* 0x900: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x908: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x910: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x918: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x920: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x928: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x930: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x938: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, /* 0x940: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x948: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x950: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x958: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x960: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x968: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x970: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x978: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x03, /* 0x980: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x988: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x990: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x998: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x9a0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x9a8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x9b0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x9b8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, /* 0x9c0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x9c8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x9d0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x9d8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x9e0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x9e8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x9f0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x9f8: */ 0x0e, 0x0e, 0x0e, 0x0e, 0x0f, 0x0f, 0x0f, 0x0f, /* 0xa00: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa08: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa10: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa18: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa20: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa28: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa30: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa38: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa40: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa48: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa50: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa58: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa60: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa68: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa70: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa78: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x03, /* 0xa80: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa88: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa90: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa98: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xaa0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xaa8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xab0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xab8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, /* 0xac0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xac8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xad0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xad8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xae0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xae8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xaf0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xaf8: */ 0x00, 0x00, 0x00, 0x00, 0x07, 0x07, 0x07, 0x07, /* 0xb00: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb08: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb10: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb18: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb20: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb28: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb30: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb38: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, /* 0xb40: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb48: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb50: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb58: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb60: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb68: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb70: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb78: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x03, /* 0xb80: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb88: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb90: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb98: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xba0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xba8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xbb0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xbb8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, /* 0xbc0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xbc8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xbd0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xbd8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xbe0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xbe8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xbf0: */ 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, /* 0xbf8: */ 0x1e, 0x1e, 0x1e, 0x1e, 0x1f, 0x1f, 0x3f, 0x3f, /* 0xc00: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc08: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc10: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc18: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc20: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc28: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc30: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc38: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc40: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc48: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc50: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc58: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc60: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc68: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc70: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc78: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x03, /* 0xc80: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc88: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc90: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc98: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xca0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xca8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xcb0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xcb8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, /* 0xcc0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xcc8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xcd0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xcd8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xce0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xce8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xcf0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xcf8: */ 0x00, 0x00, 0x00, 0x00, 0x07, 0x07, 0x07, 0x07, /* 0xd00: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd08: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd10: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd18: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd20: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd28: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd30: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd38: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, /* 0xd40: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd48: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd50: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd58: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd60: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd68: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd70: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd78: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x03, /* 0xd80: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd88: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd90: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd98: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xda0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xda8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xdb0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xdb8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, /* 0xdc0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xdc8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xdd0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xdd8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xde0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xde8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xdf0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xdf8: */ 0x0e, 0x0e, 0x0e, 0x0e, 0x0f, 0x0f, 0x0f, 0x1f, /* 0xe00: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe08: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe10: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe18: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe20: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe28: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe30: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe38: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe40: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe48: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe50: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe58: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe60: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe68: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe70: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe78: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x03, /* 0xe80: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe88: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe90: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe98: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xea0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xea8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xeb0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xeb8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, /* 0xec0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xec8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xed0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xed8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xee0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xee8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xef0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xef8: */ 0x00, 0x00, 0x00, 0x00, 0x07, 0x07, 0x07, 0x07, /* 0xf00: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf08: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf10: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf18: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf20: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf28: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf30: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf38: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, /* 0xf40: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf48: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf50: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf58: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf60: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf68: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf70: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf78: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x03, /* 0xf80: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf88: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf90: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf98: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xfa0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xfa8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xfb0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xfb8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, /* 0xfc0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xfc8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xfd0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xfd8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xfe0: */ 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, /* 0xfe8: */ 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, /* 0xff0: */ 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, /* 0xff8: */ 0x3e, 0x3e, 0x3f, 0x3f, 0x7f, 0x7f, 0x7f, 0x7f, }; CheeseCutter-2.10/src/resid/w6_p_t.cpp000066400000000000000000001011021516216315000176110ustar00rootroot00000000000000// --------------------------------------------------------------------------- // This file is part of reSID, a MOS6581 SID emulator engine. // Copyright (C) 2004 Dag Lem // // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; either version 2 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public 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 "wave.h" reg8 WaveformGenerator::wave6581_P_T[] = { /* 0x000: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x008: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x010: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x018: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x020: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x028: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x030: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x038: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x040: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x048: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x050: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x058: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x060: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x068: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x070: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x078: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x080: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x088: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x090: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x098: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x0a0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x0a8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x0b0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x0b8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x0c0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x0c8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x0d0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x0d8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x0e0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x0e8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x0f0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x0f8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x100: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x108: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x110: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x118: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x120: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x128: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x130: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x138: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x140: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x148: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x150: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x158: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x160: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x168: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x170: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x178: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x180: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x188: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x190: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x198: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1a0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1a8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1b0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1b8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1c0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1c8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1d0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1d8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1e0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1e8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1f0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1f8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x38, 0x3f, /* 0x200: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x208: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x210: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x218: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x220: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x228: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x230: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x238: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x240: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x248: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x250: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x258: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x260: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x268: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x270: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x278: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x280: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x288: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x290: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x298: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x2a0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x2a8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x2b0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x2b8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x2c0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x2c8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x2d0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x2d8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x2e0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x2e8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x2f0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x2f8: */ 0x00, 0x00, 0x00, 0x40, 0x00, 0x40, 0x40, 0x5f, /* 0x300: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x308: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x310: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x318: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x320: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x328: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x330: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x338: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x340: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x348: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x350: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x358: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x360: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x368: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, /* 0x370: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, /* 0x378: */ 0x00, 0x00, 0x00, 0x60, 0x00, 0x60, 0x60, 0x6f, /* 0x380: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x388: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x390: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x398: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, /* 0x3a0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x3a8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, /* 0x3b0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, /* 0x3b8: */ 0x00, 0x00, 0x00, 0x60, 0x00, 0x60, 0x70, 0x77, /* 0x3c0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x3c8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, /* 0x3d0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, /* 0x3d8: */ 0x00, 0x00, 0x00, 0x70, 0x40, 0x70, 0x70, 0x7b, /* 0x3e0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x70, /* 0x3e8: */ 0x00, 0x40, 0x40, 0x70, 0x60, 0x70, 0x78, 0x7d, /* 0x3f0: */ 0x00, 0x40, 0x60, 0x78, 0x60, 0x78, 0x78, 0x7e, /* 0x3f8: */ 0x70, 0x7c, 0x7c, 0x7f, 0x7e, 0x7f, 0x7f, 0x7f, /* 0x400: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x408: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x410: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x418: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x420: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x428: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x430: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x438: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x440: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x448: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x450: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x458: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x460: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x468: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x470: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x478: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, /* 0x480: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x488: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x490: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x498: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x4a0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x4a8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x4b0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x4b8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, /* 0x4c0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x4c8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x4d0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x4d8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, /* 0x4e0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x4e8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, /* 0x4f0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, /* 0x4f8: */ 0x00, 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x9f, /* 0x500: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x508: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x510: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x518: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x520: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x528: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x530: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x538: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, /* 0x540: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x548: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x550: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x558: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, /* 0x560: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x568: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, /* 0x570: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, /* 0x578: */ 0x00, 0x80, 0x80, 0x80, 0x80, 0xa0, 0xa0, 0xaf, /* 0x580: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x588: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x590: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x598: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, /* 0x5a0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x5a8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x80, /* 0x5b0: */ 0x00, 0x00, 0x00, 0x80, 0x00, 0x80, 0x80, 0xa0, /* 0x5b8: */ 0x00, 0x80, 0x80, 0xa0, 0x80, 0xa0, 0xb0, 0xb7, /* 0x5c0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, /* 0x5c8: */ 0x00, 0x00, 0x00, 0x80, 0x00, 0x80, 0x80, 0xa0, /* 0x5d0: */ 0x00, 0x00, 0x00, 0x80, 0x00, 0x80, 0x80, 0xa0, /* 0x5d8: */ 0x00, 0x80, 0x80, 0xa0, 0x80, 0xb0, 0xb0, 0xbb, /* 0x5e0: */ 0x00, 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0xb0, /* 0x5e8: */ 0x80, 0x80, 0x80, 0xb0, 0x80, 0xb0, 0xb8, 0xbd, /* 0x5f0: */ 0x80, 0x80, 0x80, 0xb8, 0xa0, 0xb8, 0xb8, 0xbe, /* 0x5f8: */ 0xa0, 0xb8, 0xbc, 0xbf, 0xbe, 0xbf, 0xbf, 0xbf, /* 0x600: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x608: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x610: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x618: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x620: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x628: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x630: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x638: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, /* 0x640: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x648: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x650: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x658: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0xc0, /* 0x660: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x668: */ 0x00, 0x00, 0x00, 0x80, 0x00, 0x80, 0x80, 0xc0, /* 0x670: */ 0x00, 0x00, 0x00, 0x80, 0x00, 0x80, 0x80, 0xc0, /* 0x678: */ 0x00, 0x80, 0x80, 0xc0, 0xc0, 0xc0, 0xc0, 0xcf, /* 0x680: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x688: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, /* 0x690: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, /* 0x698: */ 0x00, 0x00, 0x00, 0x80, 0x00, 0x80, 0x80, 0xc0, /* 0x6a0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, /* 0x6a8: */ 0x00, 0x00, 0x00, 0x80, 0x00, 0x80, 0x80, 0xc0, /* 0x6b0: */ 0x00, 0x00, 0x00, 0x80, 0x00, 0x80, 0xc0, 0xc0, /* 0x6b8: */ 0x80, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xd0, 0xd7, /* 0x6c0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, /* 0x6c8: */ 0x00, 0x00, 0x00, 0x80, 0x80, 0x80, 0xc0, 0xc0, /* 0x6d0: */ 0x00, 0x80, 0x80, 0xc0, 0x80, 0xc0, 0xc0, 0xc0, /* 0x6d8: */ 0x80, 0xc0, 0xc0, 0xc0, 0xc0, 0xd0, 0xd0, 0xdb, /* 0x6e0: */ 0x00, 0x80, 0x80, 0xc0, 0x80, 0xc0, 0xc0, 0xd0, /* 0x6e8: */ 0x80, 0xc0, 0xc0, 0xd0, 0xc0, 0xd0, 0xd8, 0xdd, /* 0x6f0: */ 0xc0, 0xc0, 0xc0, 0xd0, 0xc0, 0xd8, 0xd8, 0xde, /* 0x6f8: */ 0xc0, 0xd8, 0xdc, 0xdf, 0xdc, 0xdf, 0xdf, 0xdf, /* 0x700: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x708: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, /* 0x710: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, /* 0x718: */ 0x00, 0x00, 0x00, 0x80, 0x80, 0xc0, 0xc0, 0xe0, /* 0x720: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, /* 0x728: */ 0x00, 0x80, 0x80, 0xc0, 0x80, 0xc0, 0xc0, 0xe0, /* 0x730: */ 0x00, 0x80, 0x80, 0xc0, 0x80, 0xc0, 0xc0, 0xe0, /* 0x738: */ 0x80, 0xc0, 0xc0, 0xe0, 0xc0, 0xe0, 0xe0, 0xe7, /* 0x740: */ 0x00, 0x00, 0x00, 0x80, 0x00, 0x80, 0x80, 0xc0, /* 0x748: */ 0x00, 0x80, 0x80, 0xc0, 0x80, 0xc0, 0xc0, 0xe0, /* 0x750: */ 0x00, 0x80, 0x80, 0xc0, 0x80, 0xc0, 0xc0, 0xe0, /* 0x758: */ 0xc0, 0xc0, 0xc0, 0xe0, 0xe0, 0xe0, 0xe0, 0xeb, /* 0x760: */ 0x80, 0x80, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xe0, /* 0x768: */ 0xc0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xed, /* 0x770: */ 0xc0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe8, 0xe8, 0xee, /* 0x778: */ 0xe0, 0xe8, 0xec, 0xef, 0xec, 0xef, 0xef, 0xef, /* 0x780: */ 0x00, 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0xc0, /* 0x788: */ 0x80, 0x80, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xf0, /* 0x790: */ 0x80, 0xc0, 0xc0, 0xc0, 0xc0, 0xe0, 0xe0, 0xf0, /* 0x798: */ 0xc0, 0xe0, 0xe0, 0xf0, 0xe0, 0xf0, 0xf0, 0xf3, /* 0x7a0: */ 0x80, 0xc0, 0xc0, 0xe0, 0xc0, 0xe0, 0xe0, 0xf0, /* 0x7a8: */ 0xc0, 0xe0, 0xe0, 0xf0, 0xe0, 0xf0, 0xf0, 0xf5, /* 0x7b0: */ 0xe0, 0xe0, 0xe0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf6, /* 0x7b8: */ 0xf0, 0xf0, 0xf4, 0xf7, 0xf4, 0xf7, 0xf7, 0xf7, /* 0x7c0: */ 0xc0, 0xc0, 0xc0, 0xe0, 0xe0, 0xe0, 0xe0, 0xf0, /* 0x7c8: */ 0xe0, 0xe0, 0xe0, 0xf8, 0xf0, 0xf8, 0xf8, 0xf9, /* 0x7d0: */ 0xe0, 0xf0, 0xf0, 0xf8, 0xf0, 0xf8, 0xf8, 0xfa, /* 0x7d8: */ 0xf0, 0xf8, 0xf8, 0xfb, 0xf8, 0xfb, 0xfb, 0xfb, /* 0x7e0: */ 0xe0, 0xf0, 0xf0, 0xf8, 0xf0, 0xf8, 0xfc, 0xfc, /* 0x7e8: */ 0xf8, 0xfc, 0xfc, 0xfd, 0xfc, 0xfd, 0xfd, 0xfd, /* 0x7f0: */ 0xf8, 0xfc, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, /* 0x7f8: */ 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 0x800: */ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, /* 0x808: */ 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfc, 0xf8, /* 0x810: */ 0xfd, 0xfd, 0xfd, 0xfc, 0xfd, 0xfc, 0xfc, 0xf8, /* 0x818: */ 0xfc, 0xfc, 0xfc, 0xf0, 0xf8, 0xf0, 0xf0, 0xe0, /* 0x820: */ 0xfb, 0xfb, 0xfb, 0xf8, 0xfb, 0xf8, 0xf8, 0xf0, /* 0x828: */ 0xfa, 0xf8, 0xf8, 0xf0, 0xf8, 0xf0, 0xf0, 0xe0, /* 0x830: */ 0xf9, 0xf8, 0xf8, 0xf0, 0xf8, 0xf0, 0xe0, 0xe0, /* 0x838: */ 0xf0, 0xe0, 0xe0, 0xe0, 0xe0, 0xc0, 0xc0, 0xc0, /* 0x840: */ 0xf7, 0xf7, 0xf7, 0xf4, 0xf7, 0xf4, 0xf0, 0xf0, /* 0x848: */ 0xf6, 0xf0, 0xf0, 0xf0, 0xf0, 0xe0, 0xe0, 0xe0, /* 0x850: */ 0xf5, 0xf0, 0xf0, 0xe0, 0xf0, 0xe0, 0xe0, 0xc0, /* 0x858: */ 0xf0, 0xe0, 0xe0, 0xc0, 0xe0, 0xc0, 0xc0, 0x80, /* 0x860: */ 0xf3, 0xf0, 0xf0, 0xe0, 0xf0, 0xe0, 0xe0, 0xc0, /* 0x868: */ 0xf0, 0xe0, 0xe0, 0xc0, 0xc0, 0xc0, 0xc0, 0x80, /* 0x870: */ 0xf0, 0xe0, 0xc0, 0xc0, 0xc0, 0xc0, 0x80, 0x80, /* 0x878: */ 0xc0, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00, /* 0x880: */ 0xef, 0xef, 0xef, 0xec, 0xef, 0xec, 0xe8, 0xe0, /* 0x888: */ 0xee, 0xe8, 0xe8, 0xe0, 0xe0, 0xe0, 0xe0, 0xc0, /* 0x890: */ 0xed, 0xe8, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xc0, /* 0x898: */ 0xe0, 0xe0, 0xc0, 0xc0, 0xc0, 0xc0, 0x80, 0x80, /* 0x8a0: */ 0xeb, 0xe0, 0xe0, 0xe0, 0xe0, 0xc0, 0xc0, 0xc0, /* 0x8a8: */ 0xe0, 0xc0, 0xc0, 0x80, 0xc0, 0x80, 0x80, 0x00, /* 0x8b0: */ 0xe0, 0xc0, 0xc0, 0x80, 0xc0, 0x80, 0x80, 0x00, /* 0x8b8: */ 0xc0, 0x80, 0x80, 0x00, 0x80, 0x00, 0x00, 0x00, /* 0x8c0: */ 0xe7, 0xe0, 0xe0, 0xc0, 0xe0, 0xc0, 0xc0, 0x80, /* 0x8c8: */ 0xe0, 0xc0, 0xc0, 0x80, 0xc0, 0x80, 0x80, 0x00, /* 0x8d0: */ 0xe0, 0xc0, 0xc0, 0x80, 0xc0, 0x80, 0x80, 0x00, /* 0x8d8: */ 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x8e0: */ 0xe0, 0xc0, 0xc0, 0x80, 0x80, 0x00, 0x00, 0x00, /* 0x8e8: */ 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x8f0: */ 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x8f8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x900: */ 0xdf, 0xdf, 0xdf, 0xdc, 0xdf, 0xdc, 0xd8, 0xc0, /* 0x908: */ 0xde, 0xd8, 0xd8, 0xc0, 0xd8, 0xc0, 0xc0, 0xc0, /* 0x910: */ 0xdd, 0xd8, 0xd0, 0xc0, 0xd0, 0xc0, 0xc0, 0x80, /* 0x918: */ 0xd0, 0xc0, 0xc0, 0x80, 0xc0, 0x80, 0x80, 0x00, /* 0x920: */ 0xdb, 0xd0, 0xd0, 0xc0, 0xc0, 0xc0, 0xc0, 0x80, /* 0x928: */ 0xc0, 0xc0, 0xc0, 0x80, 0xc0, 0x80, 0x80, 0x00, /* 0x930: */ 0xc0, 0xc0, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00, /* 0x938: */ 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x940: */ 0xd7, 0xd0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0x80, /* 0x948: */ 0xc0, 0xc0, 0x80, 0x00, 0x80, 0x00, 0x00, 0x00, /* 0x950: */ 0xc0, 0x80, 0x80, 0x00, 0x80, 0x00, 0x00, 0x00, /* 0x958: */ 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x960: */ 0xc0, 0x80, 0x80, 0x00, 0x80, 0x00, 0x00, 0x00, /* 0x968: */ 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x970: */ 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x978: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x980: */ 0xcf, 0xc0, 0xc0, 0xc0, 0xc0, 0x80, 0x80, 0x00, /* 0x988: */ 0xc0, 0x80, 0x80, 0x00, 0x80, 0x00, 0x00, 0x00, /* 0x990: */ 0xc0, 0x80, 0x80, 0x00, 0x80, 0x00, 0x00, 0x00, /* 0x998: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x9a0: */ 0xc0, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x9a8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x9b0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x9b8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x9c0: */ 0xc0, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x9c8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x9d0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x9d8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x9e0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x9e8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x9f0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x9f8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa00: */ 0xbf, 0xbf, 0xbf, 0xbe, 0xbf, 0xbc, 0xbc, 0xa0, /* 0xa08: */ 0xbe, 0xbc, 0xb8, 0xa0, 0xb8, 0xa0, 0x80, 0x80, /* 0xa10: */ 0xbd, 0xb8, 0xb0, 0x80, 0xb0, 0x80, 0x80, 0x80, /* 0xa18: */ 0xb0, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00, /* 0xa20: */ 0xbb, 0xb0, 0xb0, 0x80, 0xa0, 0x80, 0x80, 0x00, /* 0xa28: */ 0xa0, 0x80, 0x80, 0x00, 0x80, 0x00, 0x00, 0x00, /* 0xa30: */ 0xa0, 0x80, 0x80, 0x00, 0x80, 0x00, 0x00, 0x00, /* 0xa38: */ 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa40: */ 0xb7, 0xb0, 0xa0, 0x80, 0xa0, 0x80, 0x80, 0x00, /* 0xa48: */ 0xa0, 0x80, 0x80, 0x00, 0x80, 0x00, 0x00, 0x00, /* 0xa50: */ 0x80, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa58: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa60: */ 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa68: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa70: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa78: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa80: */ 0xaf, 0xa0, 0xa0, 0x80, 0x80, 0x80, 0x80, 0x00, /* 0xa88: */ 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa90: */ 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa98: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xaa0: */ 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xaa8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xab0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xab8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xac0: */ 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xac8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xad0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xad8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xae0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xae8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xaf0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xaf8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb00: */ 0x9f, 0x90, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00, /* 0xb08: */ 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb10: */ 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb18: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb20: */ 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb28: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb30: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb38: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb40: */ 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb48: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb50: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb58: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb60: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb68: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb70: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb78: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb80: */ 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb88: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb90: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb98: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xba0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xba8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xbb0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xbb8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xbc0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xbc8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xbd0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xbd8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xbe0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xbe8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xbf0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xbf8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc00: */ 0x7f, 0x7f, 0x7f, 0x7e, 0x7f, 0x7c, 0x7c, 0x70, /* 0xc08: */ 0x7e, 0x7c, 0x78, 0x60, 0x78, 0x60, 0x60, 0x00, /* 0xc10: */ 0x7d, 0x78, 0x78, 0x60, 0x70, 0x40, 0x40, 0x00, /* 0xc18: */ 0x70, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc20: */ 0x7b, 0x78, 0x70, 0x40, 0x70, 0x40, 0x00, 0x00, /* 0xc28: */ 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc30: */ 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc38: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc40: */ 0x77, 0x70, 0x70, 0x00, 0x60, 0x00, 0x00, 0x00, /* 0xc48: */ 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc50: */ 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc58: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc60: */ 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc68: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc70: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc78: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc80: */ 0x6f, 0x60, 0x60, 0x00, 0x60, 0x00, 0x00, 0x00, /* 0xc88: */ 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc90: */ 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc98: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xca0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xca8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xcb0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xcb8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xcc0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xcc8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xcd0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xcd8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xce0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xce8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xcf0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xcf8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd00: */ 0x5f, 0x58, 0x40, 0x00, 0x40, 0x00, 0x00, 0x00, /* 0xd08: */ 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd10: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd18: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd20: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd28: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd30: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd38: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd40: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd48: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd50: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd58: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd60: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd68: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd70: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd78: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd80: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd88: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd90: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd98: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xda0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xda8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xdb0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xdb8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xdc0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xdc8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xdd0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xdd8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xde0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xde8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xdf0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xdf8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe00: */ 0x3f, 0x3c, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe08: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe10: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe18: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe20: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe28: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe30: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe38: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe40: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe48: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe50: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe58: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe60: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe68: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe70: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe78: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe80: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe88: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe90: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe98: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xea0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xea8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xeb0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xeb8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xec0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xec8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xed0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xed8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xee0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xee8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xef0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xef8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf00: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf08: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf10: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf18: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf20: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf28: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf30: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf38: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf40: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf48: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf50: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf58: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf60: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf68: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf70: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf78: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf80: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf88: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf90: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf98: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xfa0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xfa8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xfb0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xfb8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xfc0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xfc8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xfd0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xfd8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xfe0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xfe8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xff0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xff8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, }; CheeseCutter-2.10/src/resid/w6_ps_.cpp000066400000000000000000001011021516216315000176100ustar00rootroot00000000000000// --------------------------------------------------------------------------- // This file is part of reSID, a MOS6581 SID emulator engine. // Copyright (C) 2004 Dag Lem // // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; either version 2 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public 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 "wave.h" reg8 WaveformGenerator::wave6581_PS_[] = { /* 0x000: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x008: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x010: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x018: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x020: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x028: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x030: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x038: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x040: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x048: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x050: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x058: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x060: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x068: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x070: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x078: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x080: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x088: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x090: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x098: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x0a0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x0a8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x0b0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x0b8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x0c0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x0c8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x0d0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x0d8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x0e0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x0e8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x0f0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x0f8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, /* 0x100: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x108: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x110: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x118: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x120: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x128: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x130: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x138: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x140: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x148: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x150: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x158: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x160: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x168: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x170: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x178: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, /* 0x180: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x188: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x190: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x198: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1a0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1a8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1b0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1b8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, /* 0x1c0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1c8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1d0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1d8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1e0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1e8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1f0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1f8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x1f, /* 0x200: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x208: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x210: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x218: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x220: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x228: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x230: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x238: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x240: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x248: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x250: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x258: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x260: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x268: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x270: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x278: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, /* 0x280: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x288: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x290: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x298: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x2a0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x2a8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x2b0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x2b8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, /* 0x2c0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x2c8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x2d0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x2d8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x2e0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x2e8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x2f0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x2f8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2f, /* 0x300: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x308: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x310: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x318: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x320: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x328: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x330: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x338: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x340: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x348: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x350: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x358: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x360: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x368: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x370: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x378: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x37, /* 0x380: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x388: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x390: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x398: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x3a0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x3a8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x3b0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x3b8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3b, /* 0x3c0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x3c8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x3d0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x3d8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3d, /* 0x3e0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x3e8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3e, /* 0x3f0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x3f, /* 0x3f8: */ 0x00, 0x30, 0x38, 0x3f, 0x3e, 0x3f, 0x3f, 0x3f, /* 0x400: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x408: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x410: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x418: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x420: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x428: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x430: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x438: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x440: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x448: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x450: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x458: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x460: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x468: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x470: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x478: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, /* 0x480: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x488: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x490: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x498: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x4a0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x4a8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x4b0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x4b8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x4c0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x4c8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x4d0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x4d8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x4e0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x4e8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x4f0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x4f8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4f, /* 0x500: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x508: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x510: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x518: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x520: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x528: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x530: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x538: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x540: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x548: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x550: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x558: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x560: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x568: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x570: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x578: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x57, /* 0x580: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x588: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x590: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x598: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x5a0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x5a8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x5b0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x5b8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5b, /* 0x5c0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x5c8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x5d0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x5d8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5d, /* 0x5e0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x5e8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5e, /* 0x5f0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x5f, /* 0x5f8: */ 0x00, 0x40, 0x40, 0x5f, 0x5c, 0x5f, 0x5f, 0x5f, /* 0x600: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x608: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x610: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x618: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x620: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x628: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x630: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x638: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x640: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x648: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x650: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x658: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x660: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x668: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x670: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x678: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x67, /* 0x680: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x688: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x690: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x698: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x6a0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x6a8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x6b0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x6b8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x6b, /* 0x6c0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x6c8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x6d0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x6d8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x40, 0x6d, /* 0x6e0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, /* 0x6e8: */ 0x00, 0x00, 0x00, 0x40, 0x00, 0x40, 0x40, 0x6e, /* 0x6f0: */ 0x00, 0x00, 0x00, 0x40, 0x00, 0x60, 0x60, 0x6f, /* 0x6f8: */ 0x00, 0x60, 0x60, 0x6f, 0x60, 0x6f, 0x6f, 0x6f, /* 0x700: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x708: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x710: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x718: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, /* 0x720: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x728: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, /* 0x730: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, /* 0x738: */ 0x00, 0x00, 0x00, 0x40, 0x00, 0x40, 0x60, 0x73, /* 0x740: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x748: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, /* 0x750: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, /* 0x758: */ 0x00, 0x00, 0x00, 0x40, 0x00, 0x60, 0x60, 0x75, /* 0x760: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, /* 0x768: */ 0x00, 0x00, 0x00, 0x60, 0x00, 0x60, 0x60, 0x76, /* 0x770: */ 0x00, 0x00, 0x00, 0x60, 0x00, 0x60, 0x60, 0x77, /* 0x778: */ 0x00, 0x70, 0x70, 0x77, 0x70, 0x77, 0x77, 0x77, /* 0x780: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x788: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, /* 0x790: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, /* 0x798: */ 0x00, 0x00, 0x00, 0x60, 0x00, 0x60, 0x60, 0x79, /* 0x7a0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, /* 0x7a8: */ 0x00, 0x00, 0x00, 0x60, 0x00, 0x70, 0x70, 0x7a, /* 0x7b0: */ 0x00, 0x00, 0x00, 0x70, 0x00, 0x70, 0x70, 0x7b, /* 0x7b8: */ 0x40, 0x70, 0x70, 0x7b, 0x78, 0x7b, 0x7b, 0x7b, /* 0x7c0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, /* 0x7c8: */ 0x00, 0x00, 0x00, 0x70, 0x00, 0x70, 0x70, 0x7c, /* 0x7d0: */ 0x00, 0x00, 0x00, 0x70, 0x40, 0x70, 0x70, 0x7d, /* 0x7d8: */ 0x40, 0x70, 0x78, 0x7d, 0x78, 0x7d, 0x7d, 0x7d, /* 0x7e0: */ 0x00, 0x40, 0x40, 0x78, 0x60, 0x78, 0x78, 0x7e, /* 0x7e8: */ 0x60, 0x78, 0x78, 0x7e, 0x7c, 0x7e, 0x7e, 0x7e, /* 0x7f0: */ 0x70, 0x7c, 0x7c, 0x7f, 0x7e, 0x7f, 0x7f, 0x7f, /* 0x7f8: */ 0x7e, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, /* 0x800: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x808: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x810: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x818: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x820: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x828: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x830: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x838: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x840: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x848: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x850: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x858: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x860: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x868: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x870: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x878: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x880: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x888: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x890: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x898: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x8a0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x8a8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x8b0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x8b8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x8c0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x8c8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x8d0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x8d8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x8e0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x8e8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x8f0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x8f8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, /* 0x900: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x908: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x910: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x918: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x920: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x928: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x930: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x938: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x940: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x948: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x950: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x958: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x960: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x968: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x970: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x978: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, /* 0x980: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x988: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x990: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x998: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x9a0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x9a8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x9b0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x9b8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, /* 0x9c0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x9c8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x9d0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x9d8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x9e0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x9e8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x9f0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x9f8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x1f, /* 0xa00: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa08: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa10: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa18: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa20: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa28: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa30: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa38: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa40: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa48: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa50: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa58: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa60: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa68: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa70: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa78: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, /* 0xa80: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa88: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa90: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa98: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xaa0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xaa8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xab0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xab8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, /* 0xac0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xac8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xad0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xad8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xae0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xae8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xaf0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xaf8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2f, /* 0xb00: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb08: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb10: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb18: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb20: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb28: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb30: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb38: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb40: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb48: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb50: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb58: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb60: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb68: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb70: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb78: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x37, /* 0xb80: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb88: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb90: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb98: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xba0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xba8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xbb0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xbb8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3b, /* 0xbc0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xbc8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xbd0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xbd8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3d, /* 0xbe0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xbe8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3e, /* 0xbf0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x3f, /* 0xbf8: */ 0x00, 0x30, 0x38, 0x3f, 0x3e, 0x3f, 0x3f, 0x3f, /* 0xc00: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc08: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc10: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc18: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc20: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc28: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc30: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc38: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc40: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc48: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc50: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc58: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc60: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc68: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc70: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc78: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, /* 0xc80: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc88: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc90: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc98: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xca0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xca8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xcb0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xcb8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xcc0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xcc8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xcd0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xcd8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xce0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xce8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xcf0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xcf8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4f, /* 0xd00: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd08: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd10: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd18: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd20: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd28: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd30: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd38: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd40: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd48: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd50: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd58: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd60: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd68: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd70: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd78: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x57, /* 0xd80: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd88: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd90: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd98: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xda0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xda8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xdb0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xdb8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5b, /* 0xdc0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xdc8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xdd0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xdd8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5d, /* 0xde0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xde8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5e, /* 0xdf0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x5f, /* 0xdf8: */ 0x00, 0x40, 0x40, 0x5f, 0x5c, 0x5f, 0x5f, 0x5f, /* 0xe00: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe08: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe10: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe18: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe20: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe28: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe30: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe38: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe40: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe48: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe50: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe58: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe60: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe68: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe70: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe78: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x67, /* 0xe80: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe88: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe90: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe98: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xea0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xea8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xeb0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xeb8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x6b, /* 0xec0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xec8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xed0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xed8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x6d, /* 0xee0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, /* 0xee8: */ 0x00, 0x00, 0x00, 0x40, 0x00, 0x40, 0x40, 0x6e, /* 0xef0: */ 0x00, 0x00, 0x00, 0x40, 0x00, 0x60, 0x60, 0x6f, /* 0xef8: */ 0x00, 0x60, 0x60, 0x6f, 0x60, 0x6f, 0x6f, 0x6f, /* 0xf00: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf08: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf10: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf18: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, /* 0xf20: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf28: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, /* 0xf30: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, /* 0xf38: */ 0x00, 0x00, 0x00, 0x40, 0x00, 0x40, 0x60, 0x73, /* 0xf40: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf48: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, /* 0xf50: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, /* 0xf58: */ 0x00, 0x00, 0x00, 0x40, 0x00, 0x60, 0x60, 0x75, /* 0xf60: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, /* 0xf68: */ 0x00, 0x00, 0x00, 0x60, 0x00, 0x60, 0x60, 0x76, /* 0xf70: */ 0x00, 0x00, 0x00, 0x60, 0x00, 0x60, 0x60, 0x77, /* 0xf78: */ 0x00, 0x70, 0x70, 0x77, 0x70, 0x77, 0x77, 0x77, /* 0xf80: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf88: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, /* 0xf90: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, /* 0xf98: */ 0x00, 0x00, 0x00, 0x60, 0x00, 0x60, 0x60, 0x79, /* 0xfa0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, /* 0xfa8: */ 0x00, 0x00, 0x00, 0x60, 0x00, 0x70, 0x70, 0x7a, /* 0xfb0: */ 0x00, 0x00, 0x00, 0x70, 0x00, 0x70, 0x70, 0x7b, /* 0xfb8: */ 0x40, 0x70, 0x70, 0x7b, 0x78, 0x7b, 0x7b, 0x7b, /* 0xfc0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, /* 0xfc8: */ 0x00, 0x00, 0x00, 0x70, 0x00, 0x70, 0x70, 0x7c, /* 0xfd0: */ 0x00, 0x00, 0x00, 0x70, 0x40, 0x70, 0x70, 0x7d, /* 0xfd8: */ 0x40, 0x70, 0x78, 0x7d, 0x78, 0x7d, 0x7d, 0x7d, /* 0xfe0: */ 0x00, 0x40, 0x40, 0x78, 0x60, 0x78, 0x78, 0x7e, /* 0xfe8: */ 0x60, 0x78, 0x78, 0x7e, 0x7c, 0x7e, 0x7e, 0x7e, /* 0xff0: */ 0x70, 0x7c, 0x7c, 0x7f, 0x7c, 0x7f, 0x7f, 0x7f, /* 0xff8: */ 0x7e, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, }; CheeseCutter-2.10/src/resid/w6_pst.cpp000066400000000000000000001011021516216315000176350ustar00rootroot00000000000000// --------------------------------------------------------------------------- // This file is part of reSID, a MOS6581 SID emulator engine. // Copyright (C) 2004 Dag Lem // // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; either version 2 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public 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 "wave.h" reg8 WaveformGenerator::wave6581_PST[] = { /* 0x000: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x008: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x010: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x018: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x020: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x028: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x030: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x038: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x040: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x048: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x050: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x058: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x060: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x068: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x070: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x078: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x080: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x088: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x090: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x098: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x0a0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x0a8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x0b0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x0b8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x0c0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x0c8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x0d0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x0d8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x0e0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x0e8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x0f0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x0f8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x100: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x108: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x110: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x118: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x120: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x128: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x130: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x138: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x140: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x148: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x150: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x158: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x160: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x168: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x170: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x178: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x180: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x188: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x190: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x198: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1a0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1a8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1b0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1b8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1c0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1c8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1d0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1d8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1e0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1e8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1f0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1f8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x200: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x208: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x210: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x218: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x220: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x228: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x230: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x238: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x240: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x248: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x250: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x258: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x260: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x268: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x270: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x278: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x280: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x288: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x290: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x298: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x2a0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x2a8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x2b0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x2b8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x2c0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x2c8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x2d0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x2d8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x2e0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x2e8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x2f0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x2f8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x300: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x308: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x310: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x318: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x320: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x328: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x330: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x338: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x340: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x348: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x350: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x358: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x360: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x368: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x370: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x378: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x380: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x388: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x390: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x398: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x3a0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x3a8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x3b0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x3b8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x3c0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x3c8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x3d0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x3d8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x3e0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x3e8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x3f0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x3f8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, /* 0x400: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x408: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x410: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x418: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x420: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x428: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x430: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x438: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x440: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x448: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x450: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x458: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x460: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x468: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x470: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x478: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x480: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x488: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x490: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x498: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x4a0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x4a8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x4b0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x4b8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x4c0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x4c8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x4d0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x4d8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x4e0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x4e8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x4f0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x4f8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x500: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x508: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x510: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x518: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x520: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x528: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x530: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x538: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x540: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x548: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x550: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x558: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x560: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x568: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x570: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x578: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x580: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x588: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x590: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x598: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x5a0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x5a8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x5b0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x5b8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x5c0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x5c8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x5d0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x5d8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x5e0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x5e8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x5f0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x5f8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x600: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x608: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x610: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x618: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x620: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x628: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x630: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x638: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x640: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x648: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x650: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x658: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x660: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x668: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x670: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x678: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x680: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x688: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x690: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x698: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x6a0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x6a8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x6b0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x6b8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x6c0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x6c8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x6d0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x6d8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x6e0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x6e8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x6f0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x6f8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x700: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x708: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x710: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x718: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x720: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x728: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x730: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x738: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x740: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x748: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x750: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x758: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x760: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x768: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x770: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x778: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x780: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x788: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x790: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x798: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x7a0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x7a8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x7b0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x7b8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x7c0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x7c8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x7d0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x7d8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x7e0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x7e8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, /* 0x7f0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, /* 0x7f8: */ 0x00, 0x00, 0x00, 0x78, 0x78, 0x7e, 0x7f, 0x7f, /* 0x800: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x808: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x810: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x818: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x820: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x828: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x830: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x838: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x840: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x848: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x850: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x858: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x860: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x868: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x870: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x878: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x880: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x888: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x890: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x898: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x8a0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x8a8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x8b0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x8b8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x8c0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x8c8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x8d0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x8d8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x8e0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x8e8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x8f0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x8f8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x900: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x908: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x910: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x918: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x920: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x928: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x930: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x938: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x940: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x948: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x950: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x958: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x960: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x968: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x970: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x978: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x980: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x988: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x990: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x998: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x9a0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x9a8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x9b0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x9b8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x9c0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x9c8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x9d0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x9d8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x9e0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x9e8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x9f0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x9f8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa00: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa08: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa10: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa18: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa20: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa28: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa30: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa38: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa40: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa48: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa50: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa58: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa60: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa68: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa70: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa78: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa80: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa88: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa90: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa98: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xaa0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xaa8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xab0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xab8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xac0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xac8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xad0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xad8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xae0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xae8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xaf0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xaf8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb00: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb08: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb10: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb18: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb20: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb28: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb30: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb38: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb40: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb48: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb50: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb58: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb60: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb68: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb70: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb78: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb80: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb88: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb90: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb98: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xba0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xba8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xbb0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xbb8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xbc0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xbc8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xbd0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xbd8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xbe0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xbe8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xbf0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xbf8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, /* 0xc00: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc08: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc10: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc18: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc20: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc28: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc30: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc38: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc40: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc48: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc50: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc58: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc60: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc68: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc70: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc78: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc80: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc88: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc90: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc98: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xca0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xca8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xcb0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xcb8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xcc0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xcc8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xcd0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xcd8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xce0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xce8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xcf0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xcf8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd00: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd08: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd10: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd18: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd20: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd28: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd30: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd38: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd40: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd48: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd50: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd58: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd60: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd68: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd70: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd78: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd80: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd88: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd90: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd98: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xda0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xda8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xdb0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xdb8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xdc0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xdc8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xdd0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xdd8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xde0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xde8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xdf0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xdf8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe00: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe08: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe10: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe18: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe20: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe28: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe30: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe38: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe40: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe48: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe50: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe58: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe60: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe68: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe70: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe78: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe80: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe88: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe90: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe98: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xea0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xea8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xeb0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xeb8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xec0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xec8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xed0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xed8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xee0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xee8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xef0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xef8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf00: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf08: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf10: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf18: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf20: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf28: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf30: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf38: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf40: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf48: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf50: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf58: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf60: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf68: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf70: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf78: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf80: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf88: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf90: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf98: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xfa0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xfa8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xfb0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xfb8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xfc0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xfc8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xfd0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xfd8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xfe0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xfe8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, /* 0xff0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, /* 0xff8: */ 0x00, 0x00, 0x00, 0x78, 0x78, 0x7e, 0x7f, 0x7f, }; CheeseCutter-2.10/src/resid/w8__st.cpp000066400000000000000000001011021516216315000176160ustar00rootroot00000000000000// --------------------------------------------------------------------------- // This file is part of reSID, a MOS6581 SID emulator engine. // Copyright (C) 2004 Dag Lem // // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; either version 2 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public 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 "wave.h" reg8 WaveformGenerator::wave8580__ST[] = { /* 0x000: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x008: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x010: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x018: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x020: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x028: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x030: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x038: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x040: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x048: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x050: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x058: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x060: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x068: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x070: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x078: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x03, /* 0x080: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x088: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x090: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x098: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x0a0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x0a8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x0b0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x0b8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x0c0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x0c8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x0d0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x0d8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x0e0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x0e8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x0f0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x0f8: */ 0x00, 0x00, 0x00, 0x00, 0x07, 0x07, 0x07, 0x07, /* 0x100: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x108: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x110: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x118: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x120: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x128: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x130: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x138: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x140: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x148: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x150: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x158: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x160: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x168: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x170: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x178: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x03, /* 0x180: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x188: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x190: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x198: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1a0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1a8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1b0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1b8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1c0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1c8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1d0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1d8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1e0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1e8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1f0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1f8: */ 0x0e, 0x0e, 0x0e, 0x0e, 0x0f, 0x0f, 0x0f, 0x0f, /* 0x200: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x208: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x210: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x218: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x220: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x228: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x230: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x238: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x240: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x248: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x250: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x258: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x260: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x268: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x270: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x278: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x03, /* 0x280: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x288: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x290: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x298: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x2a0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x2a8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x2b0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x2b8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x2c0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x2c8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x2d0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x2d8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x2e0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x2e8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x2f0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x2f8: */ 0x00, 0x00, 0x00, 0x00, 0x07, 0x07, 0x07, 0x07, /* 0x300: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x308: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x310: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x318: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x320: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x328: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x330: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x338: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x340: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x348: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x350: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x358: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x360: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x368: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x370: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x378: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x03, /* 0x380: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x388: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x390: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x398: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x3a0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x3a8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x3b0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x3b8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, /* 0x3c0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x3c8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x3d0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x3d8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x3e0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x3e8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x3f0: */ 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, /* 0x3f8: */ 0x1e, 0x1e, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, /* 0x400: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x408: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x410: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x418: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x420: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x428: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x430: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x438: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x440: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x448: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x450: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x458: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x460: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x468: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x470: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x478: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x03, /* 0x480: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x488: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x490: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x498: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x4a0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x4a8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x4b0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x4b8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x4c0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x4c8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x4d0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x4d8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x4e0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x4e8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x4f0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x4f8: */ 0x00, 0x00, 0x00, 0x00, 0x07, 0x07, 0x07, 0x07, /* 0x500: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x508: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x510: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x518: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x520: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x528: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x530: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x538: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x540: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x548: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x550: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x558: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x560: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x568: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x570: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x578: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x03, /* 0x580: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x588: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x590: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x598: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x5a0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x5a8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x5b0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x5b8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x5c0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x5c8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x5d0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x5d8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x5e0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x5e8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x5f0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x5f8: */ 0x0e, 0x0e, 0x0e, 0x0e, 0x0f, 0x0f, 0x0f, 0x1f, /* 0x600: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x608: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x610: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x618: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x620: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x628: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x630: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x638: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x640: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x648: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x650: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x658: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x660: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x668: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x670: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x678: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x03, /* 0x680: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x688: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x690: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x698: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x6a0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x6a8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x6b0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x6b8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x6c0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x6c8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x6d0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x6d8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x6e0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x6e8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x6f0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x6f8: */ 0x00, 0x00, 0x00, 0x00, 0x07, 0x07, 0x07, 0x07, /* 0x700: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x708: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x710: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x718: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x720: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x728: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x730: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x738: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x740: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x748: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x750: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x758: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x760: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x768: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x770: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x778: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x03, /* 0x780: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x788: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x790: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x798: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x7a0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x7a8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x7b0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x7b8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, /* 0x7c0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x7c8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x7d0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x7d8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x7e0: */ 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, /* 0x7e8: */ 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, /* 0x7f0: */ 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3e, /* 0x7f8: */ 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, /* 0x800: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x808: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x810: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x818: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x820: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x828: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x830: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x838: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x840: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x848: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x850: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x858: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x860: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x868: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x870: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x878: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x03, /* 0x880: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x888: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x890: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x898: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x8a0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x8a8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x8b0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x8b8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x8c0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x8c8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x8d0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x8d8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x8e0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x8e8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x8f0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x8f8: */ 0x00, 0x00, 0x00, 0x00, 0x07, 0x07, 0x07, 0x07, /* 0x900: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x908: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x910: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x918: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x920: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x928: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x930: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x938: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x940: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x948: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x950: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x958: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x960: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x968: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x970: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x978: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x03, /* 0x980: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x988: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x990: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x998: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x9a0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x9a8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x9b0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x9b8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x9c0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x9c8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x9d0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x9d8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x9e0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x9e8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x9f0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x9f8: */ 0x0e, 0x0e, 0x0e, 0x0e, 0x0f, 0x0f, 0x0f, 0x0f, /* 0xa00: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa08: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa10: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa18: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa20: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa28: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa30: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa38: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa40: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa48: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa50: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa58: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa60: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa68: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa70: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa78: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x03, /* 0xa80: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa88: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa90: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa98: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xaa0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xaa8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xab0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xab8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xac0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xac8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xad0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xad8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xae0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xae8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xaf0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xaf8: */ 0x00, 0x00, 0x00, 0x00, 0x07, 0x07, 0x07, 0x07, /* 0xb00: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb08: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb10: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb18: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb20: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb28: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb30: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb38: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb40: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb48: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb50: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb58: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb60: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb68: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb70: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb78: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x03, /* 0xb80: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb88: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb90: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb98: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xba0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xba8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xbb0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xbb8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, /* 0xbc0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xbc8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xbd0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xbd8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xbe0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xbe8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xbf0: */ 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, /* 0xbf8: */ 0x1e, 0x1e, 0x1f, 0x1f, 0x1f, 0x1f, 0x3f, 0x3f, /* 0xc00: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc08: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc10: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc18: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc20: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc28: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc30: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc38: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc40: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc48: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc50: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc58: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc60: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc68: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc70: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc78: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x03, /* 0xc80: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc88: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc90: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc98: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xca0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xca8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xcb0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xcb8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xcc0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xcc8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xcd0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xcd8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xce0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xce8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xcf0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xcf8: */ 0x00, 0x00, 0x00, 0x00, 0x07, 0x07, 0x07, 0x07, /* 0xd00: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd08: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd10: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd18: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd20: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd28: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd30: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd38: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd40: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd48: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd50: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd58: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd60: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd68: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd70: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd78: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x03, /* 0xd80: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd88: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd90: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd98: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xda0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xda8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xdb0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xdb8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, /* 0xdc0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xdc8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xdd0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xdd8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xde0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xde8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xdf0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xdf8: */ 0x0e, 0x0e, 0x0e, 0x0e, 0x0f, 0x0f, 0x1f, 0x1f, /* 0xe00: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe08: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe10: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe18: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe20: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe28: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe30: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe38: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe40: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe48: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe50: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe58: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe60: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe68: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe70: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe78: */ 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x83, 0x83, /* 0xe80: */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, /* 0xe88: */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, /* 0xe90: */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, /* 0xe98: */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, /* 0xea0: */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, /* 0xea8: */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, /* 0xeb0: */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, /* 0xeb8: */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, /* 0xec0: */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, /* 0xec8: */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, /* 0xed0: */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, /* 0xed8: */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, /* 0xee0: */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, /* 0xee8: */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, /* 0xef0: */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, /* 0xef8: */ 0x80, 0x80, 0x80, 0x80, 0x87, 0x87, 0x87, 0x8f, /* 0xf00: */ 0xc0, 0xe0, 0xe0, 0xc0, 0xc0, 0xe0, 0xe0, 0xe0, /* 0xf08: */ 0xe0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, /* 0xf10: */ 0xc0, 0xe0, 0xe0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, /* 0xf18: */ 0xe0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, /* 0xf20: */ 0xc0, 0xe0, 0xe0, 0xc0, 0xc0, 0xe0, 0xe0, 0xe0, /* 0xf28: */ 0xe0, 0xe0, 0xe0, 0xc0, 0xe0, 0xc0, 0xe0, 0xe0, /* 0xf30: */ 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, /* 0xf38: */ 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, /* 0xf40: */ 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, /* 0xf48: */ 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, /* 0xf50: */ 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, /* 0xf58: */ 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, /* 0xf60: */ 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, /* 0xf68: */ 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, /* 0xf70: */ 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, /* 0xf78: */ 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe3, 0xe3, /* 0xf80: */ 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, /* 0xf88: */ 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, /* 0xf90: */ 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, /* 0xf98: */ 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, /* 0xfa0: */ 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, /* 0xfa8: */ 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, /* 0xfb0: */ 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, /* 0xfb8: */ 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf1, /* 0xfc0: */ 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, /* 0xfc8: */ 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, /* 0xfd0: */ 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, /* 0xfd8: */ 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, /* 0xfe0: */ 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, /* 0xfe8: */ 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, /* 0xff0: */ 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, /* 0xff8: */ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, }; CheeseCutter-2.10/src/resid/w8_p_t.cpp000066400000000000000000001011021516216315000176130ustar00rootroot00000000000000// --------------------------------------------------------------------------- // This file is part of reSID, a MOS6581 SID emulator engine. // Copyright (C) 2004 Dag Lem // // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; either version 2 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public 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 "wave.h" reg8 WaveformGenerator::wave8580_P_T[] = { /* 0x000: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x008: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x010: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x018: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x020: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x028: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x030: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x038: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x040: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x048: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x050: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x058: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x060: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x068: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x070: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x078: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x080: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x088: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x090: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x098: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x0a0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x0a8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x0b0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x0b8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x0c0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x0c8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x0d0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x0d8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x0e0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x0e8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x0f0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x0f8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, /* 0x100: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x108: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x110: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x118: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x120: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x128: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x130: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x138: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x140: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x148: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x150: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x158: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x160: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x168: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x170: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x178: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x180: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x188: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x190: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x198: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1a0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1a8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1b0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1b8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1c0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1c8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1d0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1d8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1e0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1e8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1f0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1f8: */ 0x00, 0x00, 0x00, 0x1c, 0x00, 0x3c, 0x3f, 0x3f, /* 0x200: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x208: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x210: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x218: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x220: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x228: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x230: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x238: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x240: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x248: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x250: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x258: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x260: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x268: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x270: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x278: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x280: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x288: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x290: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x298: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x2a0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x2a8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x2b0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x2b8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x2c0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x2c8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x2d0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x2d8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x2e0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x2e8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x2f0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x2f8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x5e, 0x5f, /* 0x300: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x308: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x310: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x318: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x320: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x328: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x330: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x338: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x340: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x348: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x350: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x358: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x360: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x368: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x370: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, /* 0x378: */ 0x00, 0x00, 0x00, 0x40, 0x40, 0x60, 0x60, 0x6f, /* 0x380: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x388: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x390: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x398: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, /* 0x3a0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x3a8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x40, /* 0x3b0: */ 0x00, 0x00, 0x00, 0x40, 0x40, 0x40, 0x40, 0x60, /* 0x3b8: */ 0x40, 0x40, 0x60, 0x60, 0x60, 0x60, 0x70, 0x77, /* 0x3c0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x40, 0x40, /* 0x3c8: */ 0x40, 0x40, 0x40, 0x40, 0x40, 0x60, 0x60, 0x60, /* 0x3d0: */ 0x40, 0x40, 0x40, 0x60, 0x60, 0x60, 0x60, 0x70, /* 0x3d8: */ 0x60, 0x60, 0x60, 0x70, 0x70, 0x70, 0x78, 0x7b, /* 0x3e0: */ 0x60, 0x60, 0x60, 0x70, 0x60, 0x70, 0x70, 0x70, /* 0x3e8: */ 0x70, 0x70, 0x70, 0x78, 0x78, 0x78, 0x78, 0x7c, /* 0x3f0: */ 0x78, 0x78, 0x78, 0x7c, 0x78, 0x7c, 0x7c, 0x7e, /* 0x3f8: */ 0x7c, 0x7e, 0x7e, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, /* 0x400: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x408: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x410: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x418: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x420: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x428: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x430: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x438: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x440: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x448: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x450: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x458: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x460: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x468: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x470: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x478: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, /* 0x480: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x488: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x490: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x498: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x4a0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x4a8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x4b0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x4b8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x80, /* 0x4c0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x4c8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, /* 0x4d0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, /* 0x4d8: */ 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, /* 0x4e0: */ 0x00, 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x80, /* 0x4e8: */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, /* 0x4f0: */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, /* 0x4f8: */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x8e, 0x9f, /* 0x500: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x508: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x510: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x518: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, /* 0x520: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x528: */ 0x00, 0x00, 0x00, 0x80, 0x00, 0x80, 0x80, 0x80, /* 0x530: */ 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, /* 0x538: */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, /* 0x540: */ 0x00, 0x00, 0x00, 0x80, 0x00, 0x80, 0x80, 0x80, /* 0x548: */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, /* 0x550: */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, /* 0x558: */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, /* 0x560: */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, /* 0x568: */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, /* 0x570: */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, /* 0x578: */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0xaf, /* 0x580: */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, /* 0x588: */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, /* 0x590: */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, /* 0x598: */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, /* 0x5a0: */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, /* 0x5a8: */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, /* 0x5b0: */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, /* 0x5b8: */ 0x80, 0x80, 0x80, 0xa0, 0xa0, 0xa0, 0xa0, 0xb7, /* 0x5c0: */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, /* 0x5c8: */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0xa0, /* 0x5d0: */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0xa0, 0xa0, /* 0x5d8: */ 0xa0, 0xa0, 0xa0, 0xb0, 0xa0, 0xb0, 0xb0, 0xbb, /* 0x5e0: */ 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xb0, 0xb0, /* 0x5e8: */ 0xa0, 0xb0, 0xb0, 0xb8, 0xb0, 0xb8, 0xb8, 0xbc, /* 0x5f0: */ 0xb0, 0xb8, 0xb8, 0xb8, 0xb8, 0xbc, 0xbc, 0xbe, /* 0x5f8: */ 0xbc, 0xbc, 0xbe, 0xbf, 0xbe, 0xbf, 0xbf, 0xbf, /* 0x600: */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, /* 0x608: */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, /* 0x610: */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, /* 0x618: */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, /* 0x620: */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, /* 0x628: */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, /* 0x630: */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, /* 0x638: */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0xc0, 0xc0, /* 0x640: */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, /* 0x648: */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, /* 0x650: */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0xc0, /* 0x658: */ 0x80, 0x80, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, /* 0x660: */ 0x80, 0x80, 0x80, 0xc0, 0x80, 0xc0, 0xc0, 0xc0, /* 0x668: */ 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, /* 0x670: */ 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, /* 0x678: */ 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xcf, /* 0x680: */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0xc0, 0xc0, /* 0x688: */ 0xc0, 0x80, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, /* 0x690: */ 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, /* 0x698: */ 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, /* 0x6a0: */ 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, /* 0x6a8: */ 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, /* 0x6b0: */ 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, /* 0x6b8: */ 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xd7, /* 0x6c0: */ 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, /* 0x6c8: */ 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, /* 0x6d0: */ 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, /* 0x6d8: */ 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xd0, 0xd0, 0xd9, /* 0x6e0: */ 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xd0, /* 0x6e8: */ 0xc0, 0xd0, 0xd0, 0xd0, 0xd0, 0xd8, 0xd8, 0xdc, /* 0x6f0: */ 0xd0, 0xd0, 0xd8, 0xd8, 0xd8, 0xdc, 0xdc, 0xde, /* 0x6f8: */ 0xdc, 0xdc, 0xde, 0xdf, 0xde, 0xdf, 0xdf, 0xdf, /* 0x700: */ 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, /* 0x708: */ 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, /* 0x710: */ 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, /* 0x718: */ 0xc0, 0xc0, 0xc0, 0xe0, 0xc0, 0xe0, 0xe0, 0xe0, /* 0x720: */ 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xe0, /* 0x728: */ 0xc0, 0xc0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, /* 0x730: */ 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, /* 0x738: */ 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe7, /* 0x740: */ 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, /* 0x748: */ 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, /* 0x750: */ 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, /* 0x758: */ 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe8, /* 0x760: */ 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, /* 0x768: */ 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe8, 0xec, /* 0x770: */ 0xe0, 0xe0, 0xe0, 0xe8, 0xe8, 0xe8, 0xec, 0xee, /* 0x778: */ 0xec, 0xec, 0xec, 0xee, 0xee, 0xef, 0xef, 0xef, /* 0x780: */ 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, /* 0x788: */ 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xf0, 0xf0, 0xf0, /* 0x790: */ 0xe0, 0xe0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, /* 0x798: */ 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, /* 0x7a0: */ 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, /* 0x7a8: */ 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf4, /* 0x7b0: */ 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf4, /* 0x7b8: */ 0xf0, 0xf4, 0xf4, 0xf6, 0xf6, 0xf7, 0xf7, 0xf7, /* 0x7c0: */ 0xf0, 0xf0, 0xf0, 0xf8, 0xf0, 0xf8, 0xf8, 0xf8, /* 0x7c8: */ 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, /* 0x7d0: */ 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, /* 0x7d8: */ 0xf8, 0xf8, 0xf8, 0xfa, 0xfa, 0xfb, 0xfb, 0xfb, /* 0x7e0: */ 0xf8, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, /* 0x7e8: */ 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xfd, 0xfd, 0xfd, /* 0x7f0: */ 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, /* 0x7f8: */ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 0x800: */ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 0x808: */ 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfc, /* 0x810: */ 0xfd, 0xfd, 0xfd, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, /* 0x818: */ 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xf8, /* 0x820: */ 0xfb, 0xfb, 0xfb, 0xfa, 0xfa, 0xf8, 0xf8, 0xf8, /* 0x828: */ 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, /* 0x830: */ 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, /* 0x838: */ 0xf8, 0xf8, 0xf8, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, /* 0x840: */ 0xf7, 0xf7, 0xf7, 0xf6, 0xf6, 0xf4, 0xf4, 0xf0, /* 0x848: */ 0xf4, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, /* 0x850: */ 0xf4, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, /* 0x858: */ 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, /* 0x860: */ 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, /* 0x868: */ 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xe0, 0xe0, /* 0x870: */ 0xf0, 0xf0, 0xf0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, /* 0x878: */ 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, /* 0x880: */ 0xef, 0xef, 0xef, 0xee, 0xee, 0xec, 0xec, 0xe8, /* 0x888: */ 0xee, 0xec, 0xe8, 0xe8, 0xe8, 0xe0, 0xe0, 0xe0, /* 0x890: */ 0xec, 0xe8, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, /* 0x898: */ 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, /* 0x8a0: */ 0xe8, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, /* 0x8a8: */ 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, /* 0x8b0: */ 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, /* 0x8b8: */ 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, /* 0x8c0: */ 0xe7, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, /* 0x8c8: */ 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, /* 0x8d0: */ 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xc0, 0xc0, /* 0x8d8: */ 0xe0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, /* 0x8e0: */ 0xe0, 0xe0, 0xe0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, /* 0x8e8: */ 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, /* 0x8f0: */ 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, /* 0x8f8: */ 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, /* 0x900: */ 0xdf, 0xdf, 0xdf, 0xde, 0xdf, 0xde, 0xdc, 0xdc, /* 0x908: */ 0xde, 0xdc, 0xdc, 0xd8, 0xd8, 0xd8, 0xd0, 0xd0, /* 0x910: */ 0xdc, 0xd8, 0xd8, 0xd0, 0xd0, 0xd0, 0xd0, 0xc0, /* 0x918: */ 0xd0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, /* 0x920: */ 0xd9, 0xd0, 0xd0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, /* 0x928: */ 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, /* 0x930: */ 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, /* 0x938: */ 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, /* 0x940: */ 0xd7, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, /* 0x948: */ 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, /* 0x950: */ 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, /* 0x958: */ 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, /* 0x960: */ 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, /* 0x968: */ 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, /* 0x970: */ 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0x80, /* 0x978: */ 0xc0, 0xc0, 0xc0, 0x80, 0x80, 0x80, 0x80, 0x80, /* 0x980: */ 0xcf, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, /* 0x988: */ 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, /* 0x990: */ 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, /* 0x998: */ 0xc0, 0xc0, 0xc0, 0x80, 0xc0, 0x80, 0x80, 0x80, /* 0x9a0: */ 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0x80, 0x80, /* 0x9a8: */ 0xc0, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, /* 0x9b0: */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, /* 0x9b8: */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, /* 0x9c0: */ 0xc0, 0xc0, 0xc0, 0x80, 0x80, 0x80, 0x80, 0x80, /* 0x9c8: */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, /* 0x9d0: */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, /* 0x9d8: */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, /* 0x9e0: */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, /* 0x9e8: */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, /* 0x9f0: */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, /* 0x9f8: */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, /* 0xa00: */ 0xbf, 0xbf, 0xbf, 0xbe, 0xbf, 0xbe, 0xbc, 0xbc, /* 0xa08: */ 0xbe, 0xbc, 0xbc, 0xb8, 0xb8, 0xb8, 0xb8, 0xb0, /* 0xa10: */ 0xbc, 0xb8, 0xb8, 0xb0, 0xb8, 0xb0, 0xb0, 0xb0, /* 0xa18: */ 0xb0, 0xb0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, /* 0xa20: */ 0xbb, 0xb0, 0xb0, 0xa0, 0xb0, 0xa0, 0xa0, 0xa0, /* 0xa28: */ 0xa0, 0xa0, 0xa0, 0x80, 0x80, 0x80, 0x80, 0x80, /* 0xa30: */ 0xa0, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, /* 0xa38: */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, /* 0xa40: */ 0xb7, 0xb0, 0xa0, 0xa0, 0xa0, 0x80, 0x80, 0x80, /* 0xa48: */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, /* 0xa50: */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, /* 0xa58: */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, /* 0xa60: */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, /* 0xa68: */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, /* 0xa70: */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, /* 0xa78: */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, /* 0xa80: */ 0xaf, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, /* 0xa88: */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, /* 0xa90: */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, /* 0xa98: */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, /* 0xaa0: */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, /* 0xaa8: */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, /* 0xab0: */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, /* 0xab8: */ 0x80, 0x80, 0x80, 0x00, 0x80, 0x00, 0x00, 0x00, /* 0xac0: */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, /* 0xac8: */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, /* 0xad0: */ 0x80, 0x80, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, /* 0xad8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xae0: */ 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xae8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xaf0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xaf8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb00: */ 0x9f, 0x9e, 0x88, 0x80, 0x80, 0x80, 0x80, 0x80, /* 0xb08: */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, /* 0xb10: */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, /* 0xb18: */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00, /* 0xb20: */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00, /* 0xb28: */ 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb30: */ 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb38: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb40: */ 0x80, 0x80, 0x80, 0x00, 0x80, 0x00, 0x00, 0x00, /* 0xb48: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb50: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb58: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb60: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb68: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb70: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb78: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb80: */ 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb88: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb90: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb98: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xba0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xba8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xbb0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xbb8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xbc0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xbc8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xbd0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xbd8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xbe0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xbe8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xbf0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xbf8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc00: */ 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7e, 0x7e, 0x7c, /* 0xc08: */ 0x7e, 0x7c, 0x7c, 0x78, 0x7c, 0x78, 0x78, 0x78, /* 0xc10: */ 0x7c, 0x78, 0x78, 0x78, 0x78, 0x70, 0x70, 0x70, /* 0xc18: */ 0x78, 0x70, 0x70, 0x60, 0x70, 0x60, 0x60, 0x60, /* 0xc20: */ 0x7b, 0x78, 0x70, 0x70, 0x70, 0x60, 0x60, 0x60, /* 0xc28: */ 0x70, 0x60, 0x60, 0x60, 0x60, 0x40, 0x40, 0x40, /* 0xc30: */ 0x60, 0x60, 0x60, 0x40, 0x40, 0x40, 0x40, 0x40, /* 0xc38: */ 0x40, 0x40, 0x40, 0x00, 0x40, 0x00, 0x00, 0x00, /* 0xc40: */ 0x77, 0x70, 0x60, 0x60, 0x60, 0x60, 0x40, 0x40, /* 0xc48: */ 0x60, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, /* 0xc50: */ 0x40, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc58: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc60: */ 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc68: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc70: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc78: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc80: */ 0x6f, 0x64, 0x60, 0x40, 0x40, 0x00, 0x00, 0x00, /* 0xc88: */ 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc90: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc98: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xca0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xca8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xcb0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xcb8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xcc0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xcc8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xcd0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xcd8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xce0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xce8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xcf0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xcf8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd00: */ 0x5f, 0x5e, 0x4c, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd08: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd10: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd18: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd20: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd28: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd30: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd38: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd40: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd48: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd50: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd58: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd60: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd68: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd70: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd78: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd80: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd88: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd90: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd98: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xda0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xda8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xdb0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xdb8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xdc0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xdc8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xdd0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xdd8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xde0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xde8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xdf0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xdf8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe00: */ 0x3f, 0x3f, 0x3e, 0x00, 0x1c, 0x00, 0x00, 0x00, /* 0xe08: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe10: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe18: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe20: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe28: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe30: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe38: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe40: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe48: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe50: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe58: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe60: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe68: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe70: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe78: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe80: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe88: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe90: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe98: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xea0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xea8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xeb0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xeb8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xec0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xec8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xed0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xed8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xee0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xee8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xef0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xef8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf00: */ 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf08: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf10: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf18: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf20: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf28: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf30: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf38: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf40: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf48: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf50: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf58: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf60: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf68: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf70: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf78: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf80: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf88: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf90: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf98: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xfa0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xfa8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xfb0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xfb8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xfc0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xfc8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xfd0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xfd8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xfe0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xfe8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xff0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xff8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, }; CheeseCutter-2.10/src/resid/w8_ps_.cpp000066400000000000000000001011021516216315000176120ustar00rootroot00000000000000// --------------------------------------------------------------------------- // This file is part of reSID, a MOS6581 SID emulator engine. // Copyright (C) 2004 Dag Lem // // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; either version 2 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public 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 "wave.h" reg8 WaveformGenerator::wave8580_PS_[] = { /* 0x000: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x008: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x010: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x018: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x020: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x028: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x030: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x038: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x040: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x048: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x050: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x058: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x060: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x068: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x070: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x078: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, /* 0x080: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x088: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x090: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x098: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x0a0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x0a8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x0b0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x0b8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, /* 0x0c0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x0c8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x0d0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x0d8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x0e0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x0e8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x0f0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x0f8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, /* 0x100: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x108: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x110: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x118: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x120: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x128: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x130: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x138: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x140: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x148: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x150: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x158: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x160: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x168: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x170: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x178: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, /* 0x180: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x188: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x190: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x198: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1a0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1a8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1b0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1b8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, /* 0x1c0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1c8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1d0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1d8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, /* 0x1e0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1e8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1f0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1f8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x07, 0x1f, /* 0x200: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x208: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x210: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x218: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x220: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x228: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x230: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x238: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x240: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x248: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x250: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x258: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x260: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x268: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x270: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x278: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, /* 0x280: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x288: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x290: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x298: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x2a0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x2a8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x2b0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x2b8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, /* 0x2c0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x2c8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x2d0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x2d8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, /* 0x2e0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x2e8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x2f0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x2f8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x0f, /* 0x300: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x308: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x310: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x318: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x320: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x328: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x330: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x338: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, /* 0x340: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x348: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x350: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x358: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x360: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x368: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x370: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x378: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17, /* 0x380: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x388: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x390: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x398: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x3a0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x3a8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x3b0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x3b8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3b, /* 0x3c0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x3c8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x3d0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x3d8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3d, /* 0x3e0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x3e8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3e, /* 0x3f0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, /* 0x3f8: */ 0x00, 0x0c, 0x1c, 0x3f, 0x1e, 0x3f, 0x3f, 0x3f, /* 0x400: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x408: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x410: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x418: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x420: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x428: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x430: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x438: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x440: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x448: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x450: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x458: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x460: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x468: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x470: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x478: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, /* 0x480: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x488: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x490: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x498: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x4a0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x4a8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x4b0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x4b8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, /* 0x4c0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x4c8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x4d0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x4d8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x4e0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x4e8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x4f0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x4f8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, /* 0x500: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x508: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x510: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x518: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x520: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x528: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x530: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x538: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, /* 0x540: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x548: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x550: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x558: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x560: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x568: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x570: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x578: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, /* 0x580: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x588: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x590: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x598: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x5a0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x5a8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x5b0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x5b8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0b, /* 0x5c0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x5c8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x5d0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x5d8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, /* 0x5e0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x5e8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5e, /* 0x5f0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5f, /* 0x5f8: */ 0x00, 0x00, 0x00, 0x5f, 0x0c, 0x5f, 0x5f, 0x5f, /* 0x600: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x608: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x610: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x618: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x620: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x628: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x630: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x638: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, /* 0x640: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x648: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x650: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x658: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x660: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x668: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x670: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x678: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x47, /* 0x680: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x688: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x690: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x698: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x6a0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x6a8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x6b0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x6b8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x43, /* 0x6c0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x6c8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x6d0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x6d8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x65, /* 0x6e0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x6e8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6e, /* 0x6f0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6f, /* 0x6f8: */ 0x00, 0x40, 0x40, 0x6f, 0x40, 0x6f, 0x6f, 0x6f, /* 0x700: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x708: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x710: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x718: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x720: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x728: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x730: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x738: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x63, /* 0x740: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x748: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x750: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x758: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x61, /* 0x760: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, /* 0x768: */ 0x00, 0x00, 0x00, 0x40, 0x00, 0x40, 0x40, 0x70, /* 0x770: */ 0x00, 0x00, 0x40, 0x40, 0x40, 0x40, 0x40, 0x70, /* 0x778: */ 0x40, 0x60, 0x60, 0x77, 0x60, 0x77, 0x77, 0x77, /* 0x780: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x788: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, /* 0x790: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x60, /* 0x798: */ 0x00, 0x40, 0x40, 0x60, 0x40, 0x60, 0x60, 0x79, /* 0x7a0: */ 0x00, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x60, /* 0x7a8: */ 0x40, 0x40, 0x40, 0x60, 0x60, 0x60, 0x60, 0x78, /* 0x7b0: */ 0x40, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x78, /* 0x7b8: */ 0x60, 0x70, 0x70, 0x78, 0x70, 0x79, 0x7b, 0x7b, /* 0x7c0: */ 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x70, /* 0x7c8: */ 0x60, 0x60, 0x60, 0x70, 0x60, 0x70, 0x70, 0x7c, /* 0x7d0: */ 0x60, 0x70, 0x70, 0x70, 0x70, 0x70, 0x70, 0x7c, /* 0x7d8: */ 0x70, 0x78, 0x78, 0x7c, 0x78, 0x7c, 0x7c, 0x7d, /* 0x7e0: */ 0x70, 0x78, 0x78, 0x78, 0x78, 0x78, 0x78, 0x7c, /* 0x7e8: */ 0x78, 0x7c, 0x7c, 0x7e, 0x7c, 0x7e, 0x7e, 0x7e, /* 0x7f0: */ 0x7c, 0x7c, 0x7c, 0x7e, 0x7e, 0x7f, 0x7f, 0x7f, /* 0x7f8: */ 0x7e, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0xff, /* 0x800: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x808: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x810: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x818: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x820: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x828: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x830: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x838: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x840: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x848: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x850: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x858: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x860: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x868: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x870: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x878: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, /* 0x880: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x888: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x890: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x898: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x8a0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x8a8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x8b0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x8b8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, /* 0x8c0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x8c8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x8d0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x8d8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x8e0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x8e8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x8f0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x8f8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8f, /* 0x900: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x908: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x910: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x918: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x920: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x928: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x930: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x938: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, /* 0x940: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x948: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x950: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x958: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x960: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x968: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x970: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x978: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x87, /* 0x980: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x988: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x990: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x998: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x9a0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x9a8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x9b0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x9b8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x83, /* 0x9c0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x9c8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x9d0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x9d8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x8d, /* 0x9e0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, /* 0x9e8: */ 0x00, 0x00, 0x00, 0x80, 0x00, 0x80, 0x80, 0x8e, /* 0x9f0: */ 0x00, 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x8f, /* 0x9f8: */ 0x80, 0x80, 0x80, 0x9f, 0x80, 0x9f, 0x9f, 0x9f, /* 0xa00: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa08: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa10: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa18: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa20: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa28: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa30: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa38: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, /* 0xa40: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa48: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa50: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa58: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa60: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa68: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, /* 0xa70: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, /* 0xa78: */ 0x00, 0x00, 0x00, 0x80, 0x00, 0x80, 0x80, 0x87, /* 0xa80: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa88: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa90: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa98: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, /* 0xaa0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xaa8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, /* 0xab0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, /* 0xab8: */ 0x00, 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x83, /* 0xac0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xac8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, /* 0xad0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x80, /* 0xad8: */ 0x00, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x81, /* 0xae0: */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, /* 0xae8: */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x84, /* 0xaf0: */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x87, /* 0xaf8: */ 0x80, 0x80, 0x80, 0x87, 0x80, 0x8f, 0xaf, 0xaf, /* 0xb00: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb08: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, /* 0xb10: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, /* 0xb18: */ 0x00, 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x80, /* 0xb20: */ 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x80, 0x80, /* 0xb28: */ 0x00, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, /* 0xb30: */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, /* 0xb38: */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x83, /* 0xb40: */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, /* 0xb48: */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, /* 0xb50: */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, /* 0xb58: */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x81, /* 0xb60: */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, /* 0xb68: */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0xa0, /* 0xb70: */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0xa0, /* 0xb78: */ 0x80, 0x80, 0x80, 0xa0, 0x80, 0xa3, 0xb7, 0xb7, /* 0xb80: */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, /* 0xb88: */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, /* 0xb90: */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, /* 0xb98: */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0xb1, /* 0xba0: */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, /* 0xba8: */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0xb0, /* 0xbb0: */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0xb0, /* 0xbb8: */ 0x80, 0xa0, 0xa0, 0xb0, 0xa0, 0xb8, 0xb9, 0xbb, /* 0xbc0: */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0xa0, /* 0xbc8: */ 0x80, 0x80, 0x80, 0xa0, 0x80, 0xa0, 0xa0, 0xb8, /* 0xbd0: */ 0x80, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xb8, /* 0xbd8: */ 0xa0, 0xb0, 0xb0, 0xb8, 0xb0, 0xbc, 0xbc, 0xbd, /* 0xbe0: */ 0xa0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb8, 0xb8, 0xbc, /* 0xbe8: */ 0xb0, 0xb8, 0xb8, 0xbc, 0xb8, 0xbc, 0xbe, 0xbe, /* 0xbf0: */ 0xb8, 0xbc, 0xbc, 0xbe, 0xbc, 0xbe, 0xbe, 0xbf, /* 0xbf8: */ 0xbe, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, /* 0xc00: */ 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, /* 0xc08: */ 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, /* 0xc10: */ 0x00, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, /* 0xc18: */ 0x00, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, /* 0xc20: */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, /* 0xc28: */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, /* 0xc30: */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, /* 0xc38: */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x81, /* 0xc40: */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, /* 0xc48: */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, /* 0xc50: */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, /* 0xc58: */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, /* 0xc60: */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, /* 0xc68: */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, /* 0xc70: */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, /* 0xc78: */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0xc7, /* 0xc80: */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, /* 0xc88: */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, /* 0xc90: */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, /* 0xc98: */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, /* 0xca0: */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, /* 0xca8: */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, /* 0xcb0: */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, /* 0xcb8: */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0xc0, 0xc3, /* 0xcc0: */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, /* 0xcc8: */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0xc0, /* 0xcd0: */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0xc0, /* 0xcd8: */ 0x80, 0x80, 0x80, 0xc0, 0x80, 0xc0, 0xc0, 0xc1, /* 0xce0: */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0xc0, /* 0xce8: */ 0x80, 0x80, 0x80, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, /* 0xcf0: */ 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc7, /* 0xcf8: */ 0xc0, 0xc0, 0xc0, 0xc7, 0xc0, 0xcf, 0xcf, 0xcf, /* 0xd00: */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, /* 0xd08: */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, /* 0xd10: */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, /* 0xd18: */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0xc0, /* 0xd20: */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, /* 0xd28: */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0xc0, /* 0xd30: */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0xc0, 0xc0, /* 0xd38: */ 0x80, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc3, /* 0xd40: */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0xc0, /* 0xd48: */ 0x80, 0x80, 0x80, 0xc0, 0x80, 0xc0, 0xc0, 0xc0, /* 0xd50: */ 0x80, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, /* 0xd58: */ 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc1, /* 0xd60: */ 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, /* 0xd68: */ 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, /* 0xd70: */ 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, /* 0xd78: */ 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc1, 0xc7, 0xd7, /* 0xd80: */ 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, /* 0xd88: */ 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, /* 0xd90: */ 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, /* 0xd98: */ 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, /* 0xda0: */ 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, /* 0xda8: */ 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xd0, /* 0xdb0: */ 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xd0, /* 0xdb8: */ 0xc0, 0xc0, 0xc0, 0xd0, 0xc0, 0xd0, 0xd8, 0xdb, /* 0xdc0: */ 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, /* 0xdc8: */ 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xd8, /* 0xdd0: */ 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xd8, /* 0xdd8: */ 0xc0, 0xc0, 0xc0, 0xd8, 0xd0, 0xd8, 0xd8, 0xdd, /* 0xde0: */ 0xc0, 0xc0, 0xc0, 0xd0, 0xc0, 0xd0, 0xd0, 0xdc, /* 0xde8: */ 0xd0, 0xd8, 0xd8, 0xdc, 0xd8, 0xdc, 0xdc, 0xde, /* 0xdf0: */ 0xd8, 0xdc, 0xdc, 0xde, 0xdc, 0xde, 0xde, 0xdf, /* 0xdf8: */ 0xde, 0xdf, 0xdf, 0xdf, 0xdf, 0xdf, 0xdf, 0xdf, /* 0xe00: */ 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, /* 0xe08: */ 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, /* 0xe10: */ 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, /* 0xe18: */ 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, /* 0xe20: */ 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, /* 0xe28: */ 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, /* 0xe30: */ 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, /* 0xe38: */ 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xe3, /* 0xe40: */ 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, /* 0xe48: */ 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, /* 0xe50: */ 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xe0, /* 0xe58: */ 0xc0, 0xc0, 0xc0, 0xe0, 0xc0, 0xe0, 0xe0, 0xe1, /* 0xe60: */ 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xe0, /* 0xe68: */ 0xc0, 0xc0, 0xc0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, /* 0xe70: */ 0xc0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, /* 0xe78: */ 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe1, 0xe3, 0xe7, /* 0xe80: */ 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xe0, /* 0xe88: */ 0xc0, 0xc0, 0xc0, 0xe0, 0xc0, 0xe0, 0xe0, 0xe0, /* 0xe90: */ 0xc0, 0xc0, 0xc0, 0xe0, 0xc0, 0xe0, 0xe0, 0xe0, /* 0xe98: */ 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, /* 0xea0: */ 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, /* 0xea8: */ 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, /* 0xeb0: */ 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, /* 0xeb8: */ 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xeb, /* 0xec0: */ 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, /* 0xec8: */ 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, /* 0xed0: */ 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, /* 0xed8: */ 0xe0, 0xe0, 0xe0, 0xe8, 0xe0, 0xe8, 0xe8, 0xed, /* 0xee0: */ 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xec, /* 0xee8: */ 0xe0, 0xe0, 0xe0, 0xec, 0xe8, 0xec, 0xec, 0xee, /* 0xef0: */ 0xe8, 0xe8, 0xe8, 0xec, 0xec, 0xee, 0xee, 0xef, /* 0xef8: */ 0xec, 0xef, 0xef, 0xef, 0xef, 0xef, 0xef, 0xef, /* 0xf00: */ 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, /* 0xf08: */ 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, /* 0xf10: */ 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, /* 0xf18: */ 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xf0, /* 0xf20: */ 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xf0, /* 0xf28: */ 0xe0, 0xe0, 0xe0, 0xf0, 0xe0, 0xf0, 0xf0, 0xf0, /* 0xf30: */ 0xe0, 0xe0, 0xe0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, /* 0xf38: */ 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf3, /* 0xf40: */ 0xe0, 0xe0, 0xe0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, /* 0xf48: */ 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, /* 0xf50: */ 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, /* 0xf58: */ 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf5, /* 0xf60: */ 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, /* 0xf68: */ 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf4, 0xf4, 0xf6, /* 0xf70: */ 0xf0, 0xf0, 0xf0, 0xf4, 0xf0, 0xf4, 0xf6, 0xf7, /* 0xf78: */ 0xf4, 0xf6, 0xf6, 0xf7, 0xf7, 0xf7, 0xf7, 0xf7, /* 0xf80: */ 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf8, /* 0xf88: */ 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf8, 0xf8, 0xf8, /* 0xf90: */ 0xf0, 0xf0, 0xf0, 0xf8, 0xf0, 0xf8, 0xf8, 0xf8, /* 0xf98: */ 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf9, /* 0xfa0: */ 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, /* 0xfa8: */ 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xfa, /* 0xfb0: */ 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xfb, /* 0xfb8: */ 0xf8, 0xfa, 0xfa, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, /* 0xfc0: */ 0xf8, 0xf8, 0xf8, 0xfc, 0xf8, 0xfc, 0xfc, 0xfc, /* 0xfc8: */ 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, /* 0xfd0: */ 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xfd, /* 0xfd8: */ 0xfc, 0xfc, 0xfc, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, /* 0xfe0: */ 0xfc, 0xfc, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, /* 0xfe8: */ 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, /* 0xff0: */ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 0xff8: */ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, }; CheeseCutter-2.10/src/resid/w8_pst.cpp000066400000000000000000001011021516216315000176370ustar00rootroot00000000000000// --------------------------------------------------------------------------- // This file is part of reSID, a MOS6581 SID emulator engine. // Copyright (C) 2004 Dag Lem // // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; either version 2 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public 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 "wave.h" reg8 WaveformGenerator::wave8580_PST[] = { /* 0x000: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x008: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x010: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x018: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x020: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x028: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x030: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x038: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x040: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x048: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x050: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x058: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x060: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x068: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x070: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x078: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x080: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x088: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x090: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x098: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x0a0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x0a8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x0b0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x0b8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x0c0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x0c8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x0d0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x0d8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x0e0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x0e8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x0f0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x0f8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x100: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x108: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x110: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x118: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x120: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x128: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x130: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x138: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x140: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x148: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x150: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x158: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x160: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x168: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x170: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x178: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x180: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x188: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x190: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x198: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1a0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1a8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1b0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1b8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1c0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1c8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1d0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1d8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1e0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1e8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1f0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1f8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x200: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x208: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x210: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x218: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x220: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x228: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x230: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x238: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x240: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x248: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x250: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x258: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x260: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x268: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x270: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x278: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x280: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x288: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x290: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x298: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x2a0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x2a8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x2b0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x2b8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x2c0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x2c8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x2d0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x2d8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x2e0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x2e8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x2f0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x2f8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x300: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x308: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x310: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x318: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x320: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x328: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x330: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x338: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x340: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x348: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x350: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x358: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x360: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x368: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x370: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x378: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x380: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x388: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x390: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x398: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x3a0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x3a8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x3b0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x3b8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x3c0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x3c8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x3d0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x3d8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x3e0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x3e8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x3f0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x3f8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, /* 0x400: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x408: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x410: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x418: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x420: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x428: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x430: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x438: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x440: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x448: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x450: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x458: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x460: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x468: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x470: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x478: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x480: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x488: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x490: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x498: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x4a0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x4a8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x4b0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x4b8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x4c0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x4c8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x4d0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x4d8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x4e0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x4e8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x4f0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x4f8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x500: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x508: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x510: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x518: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x520: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x528: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x530: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x538: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x540: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x548: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x550: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x558: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x560: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x568: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x570: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x578: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x580: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x588: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x590: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x598: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x5a0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x5a8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x5b0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x5b8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x5c0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x5c8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x5d0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x5d8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x5e0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x5e8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x5f0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x5f8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x600: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x608: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x610: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x618: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x620: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x628: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x630: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x638: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x640: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x648: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x650: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x658: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x660: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x668: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x670: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x678: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x680: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x688: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x690: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x698: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x6a0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x6a8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x6b0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x6b8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x6c0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x6c8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x6d0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x6d8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x6e0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x6e8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x6f0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x6f8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x700: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x708: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x710: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x718: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x720: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x728: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x730: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x738: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x740: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x748: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x750: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x758: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x760: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x768: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x770: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x778: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x780: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x788: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x790: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x798: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x7a0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x7a8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x7b0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x7b8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x7c0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x7c8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x7d0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x7d8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x7e0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x7e8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x70, /* 0x7f0: */ 0x60, 0x20, 0x70, 0x70, 0x70, 0x70, 0x70, 0x78, /* 0x7f8: */ 0x78, 0x78, 0x7c, 0x7c, 0x7e, 0x7e, 0x7f, 0x7f, /* 0x800: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x808: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x810: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x818: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x820: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x828: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x830: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x838: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x840: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x848: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x850: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x858: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x860: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x868: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x870: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x878: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x880: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x888: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x890: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x898: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x8a0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x8a8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x8b0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x8b8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x8c0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x8c8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x8d0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x8d8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x8e0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x8e8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x8f0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x8f8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x900: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x908: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x910: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x918: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x920: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x928: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x930: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x938: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x940: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x948: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x950: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x958: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x960: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x968: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x970: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x978: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x980: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x988: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x990: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x998: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x9a0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x9a8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x9b0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x9b8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x9c0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x9c8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x9d0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x9d8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x9e0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x9e8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x9f0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x9f8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa00: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa08: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa10: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa18: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa20: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa28: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa30: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa38: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa40: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa48: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa50: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa58: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa60: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa68: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa70: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa78: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa80: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa88: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa90: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa98: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xaa0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xaa8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xab0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xab8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xac0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xac8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xad0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xad8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xae0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xae8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xaf0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xaf8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb00: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb08: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb10: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb18: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb20: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb28: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb30: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb38: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb40: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb48: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb50: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb58: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb60: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb68: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb70: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb78: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb80: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb88: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb90: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb98: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xba0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xba8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xbb0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xbb8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xbc0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xbc8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xbd0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xbd8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xbe0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xbe8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xbf0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xbf8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x1e, 0x3f, /* 0xc00: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc08: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc10: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc18: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc20: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc28: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc30: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc38: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc40: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc48: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc50: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc58: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc60: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc68: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc70: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc78: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc80: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc88: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc90: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc98: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xca0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xca8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xcb0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xcb8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xcc0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xcc8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xcd0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xcd8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xce0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xce8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xcf0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xcf8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd00: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd08: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd10: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd18: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd20: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd28: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd30: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd38: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd40: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd48: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd50: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd58: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd60: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd68: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd70: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd78: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd80: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd88: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd90: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd98: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xda0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xda8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xdb0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xdb8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xdc0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xdc8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xdd0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xdd8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xde0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xde8: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xdf0: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, /* 0xdf8: */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x8c, 0x9f, /* 0xe00: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe08: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe10: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe18: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe20: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe28: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe30: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe38: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, /* 0xe40: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe48: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe50: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe58: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, /* 0xe60: */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, /* 0xe68: */ 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, /* 0xe70: */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, /* 0xe78: */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, /* 0xe80: */ 0x00, 0x00, 0x80, 0x00, 0x00, 0x80, 0x80, 0x80, /* 0xe88: */ 0x80, 0x00, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, /* 0xe90: */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, /* 0xe98: */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, /* 0xea0: */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, /* 0xea8: */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, /* 0xeb0: */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, /* 0xeb8: */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, /* 0xec0: */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, /* 0xec8: */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, /* 0xed0: */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, /* 0xed8: */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, /* 0xee0: */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, /* 0xee8: */ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0xc0, 0xc0, /* 0xef0: */ 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, /* 0xef8: */ 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xcf, /* 0xf00: */ 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, /* 0xf08: */ 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, /* 0xf10: */ 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, /* 0xf18: */ 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, /* 0xf20: */ 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, /* 0xf28: */ 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, /* 0xf30: */ 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, /* 0xf38: */ 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, /* 0xf40: */ 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, /* 0xf48: */ 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, /* 0xf50: */ 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, /* 0xf58: */ 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, /* 0xf60: */ 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, /* 0xf68: */ 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xe0, /* 0xf70: */ 0xc0, 0xc0, 0xc0, 0xc0, 0xe0, 0xe0, 0xe0, 0xe0, /* 0xf78: */ 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe3, /* 0xf80: */ 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, /* 0xf88: */ 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, /* 0xf90: */ 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, /* 0xf98: */ 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, /* 0xfa0: */ 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, /* 0xfa8: */ 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, /* 0xfb0: */ 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xf0, 0xf0, /* 0xfb8: */ 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, /* 0xfc0: */ 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, /* 0xfc8: */ 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, /* 0xfd0: */ 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, /* 0xfd8: */ 0xf0, 0xf0, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, /* 0xfe0: */ 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, /* 0xfe8: */ 0xf8, 0xf8, 0xf8, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, /* 0xff0: */ 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xfe, 0xfe, 0xfe, /* 0xff8: */ 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, }; CheeseCutter-2.10/src/resid/wave.cpp000066400000000000000000000104301516216315000173600ustar00rootroot00000000000000// --------------------------------------------------------------------------- // This file is part of reSID, a MOS6581 SID emulator engine. // Copyright (C) 2004 Dag Lem // // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; either version 2 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // --------------------------------------------------------------------------- #define __WAVE_CC__ #include "wave.h" // ---------------------------------------------------------------------------- // Constructor. // ---------------------------------------------------------------------------- WaveformGenerator::WaveformGenerator() { sync_source = this; set_chip_model(MOS6581); reset(); } // ---------------------------------------------------------------------------- // Set sync source. // ---------------------------------------------------------------------------- void WaveformGenerator::set_sync_source(WaveformGenerator* source) { sync_source = source; source->sync_dest = this; } // ---------------------------------------------------------------------------- // Set chip model. // ---------------------------------------------------------------------------- void WaveformGenerator::set_chip_model(chip_model model) { if (model == MOS6581) { wave__ST = wave6581__ST; wave_P_T = wave6581_P_T; wave_PS_ = wave6581_PS_; wave_PST = wave6581_PST; } else { wave__ST = wave8580__ST; wave_P_T = wave8580_P_T; wave_PS_ = wave8580_PS_; wave_PST = wave8580_PST; } } // ---------------------------------------------------------------------------- // Register functions. // ---------------------------------------------------------------------------- void WaveformGenerator::writeFREQ_LO(reg8 freq_lo) { freq = freq & 0xff00 | freq_lo & 0x00ff; } void WaveformGenerator::writeFREQ_HI(reg8 freq_hi) { freq = (freq_hi << 8) & 0xff00 | freq & 0x00ff; } void WaveformGenerator::writePW_LO(reg8 pw_lo) { pw = pw & 0xf00 | pw_lo & 0x0ff; } void WaveformGenerator::writePW_HI(reg8 pw_hi) { pw = (pw_hi << 8) & 0xf00 | pw & 0x0ff; } void WaveformGenerator::writeCONTROL_REG(reg8 control) { waveform = (control >> 4) & 0x0f; ring_mod = control & 0x04; sync = control & 0x02; reg8 test_next = control & 0x08; // Test bit set. // The accumulator and the shift register are both cleared. // NB! The shift register is not really cleared immediately. It seems like // the individual bits in the shift register start to fade down towards // zero when test is set. All bits reach zero within approximately // $2000 - $4000 cycles. // This is not modeled. There should fortunately be little audible output // from this peculiar behavior. if (test_next) { accumulator = 0; shift_register = 0; } // Test bit cleared. // The accumulator starts counting, and the shift register is reset to // the value 0x7ffff8. // NB! The shift register will not actually be set to this exact value if the // shift register bits have not had time to fade to zero. // This is not modeled. else if (test) { shift_register = 0x7ffff8; } test = test_next; // The gate bit is handled by the EnvelopeGenerator. } reg8 WaveformGenerator::readOSC() { return output() >> 4; } // ---------------------------------------------------------------------------- // SID reset. // ---------------------------------------------------------------------------- void WaveformGenerator::reset() { accumulator = 0; shift_register = 0x7ffff8; freq = 0; pw = 0; test = 0; ring_mod = 0; sync = 0; msb_rising = false; } CheeseCutter-2.10/src/resid/wave.h000066400000000000000000000371261516216315000170400ustar00rootroot00000000000000// --------------------------------------------------------------------------- // This file is part of reSID, a MOS6581 SID emulator engine. // Copyright (C) 2004 Dag Lem // // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; either version 2 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public 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 __WAVE_H__ #define __WAVE_H__ #include "siddefs.h" // ---------------------------------------------------------------------------- // A 24 bit accumulator is the basis for waveform generation. FREQ is added to // the lower 16 bits of the accumulator each cycle. // The accumulator is set to zero when TEST is set, and starts counting // when TEST is cleared. // The noise waveform is taken from intermediate bits of a 23 bit shift // register. This register is clocked by bit 19 of the accumulator. // ---------------------------------------------------------------------------- class WaveformGenerator { public: WaveformGenerator(); void set_sync_source(WaveformGenerator*); void set_chip_model(chip_model model); RESID_INLINE void clock(); RESID_INLINE void clock(cycle_count delta_t); RESID_INLINE void synchronize(); void reset(); void writeFREQ_LO(reg8); void writeFREQ_HI(reg8); void writePW_LO(reg8); void writePW_HI(reg8); void writeCONTROL_REG(reg8); reg8 readOSC(); // 12-bit waveform output. RESID_INLINE reg12 output(); protected: const WaveformGenerator* sync_source; WaveformGenerator* sync_dest; // Tell whether the accumulator MSB was set high on this cycle. bool msb_rising; reg24 accumulator; reg24 shift_register; // Fout = (Fn*Fclk/16777216)Hz reg16 freq; // PWout = (PWn/40.95)% reg12 pw; // The control register right-shifted 4 bits; used for output function // table lookup. reg8 waveform; // The remaining control register bits. reg8 test; reg8 ring_mod; reg8 sync; // The gate bit is handled by the EnvelopeGenerator. // 16 possible combinations of waveforms. RESID_INLINE reg12 output____(); RESID_INLINE reg12 output___T(); RESID_INLINE reg12 output__S_(); RESID_INLINE reg12 output__ST(); RESID_INLINE reg12 output_P__(); RESID_INLINE reg12 output_P_T(); RESID_INLINE reg12 output_PS_(); RESID_INLINE reg12 output_PST(); RESID_INLINE reg12 outputN___(); RESID_INLINE reg12 outputN__T(); RESID_INLINE reg12 outputN_S_(); RESID_INLINE reg12 outputN_ST(); RESID_INLINE reg12 outputNP__(); RESID_INLINE reg12 outputNP_T(); RESID_INLINE reg12 outputNPS_(); RESID_INLINE reg12 outputNPST(); // Sample data for combinations of waveforms. static reg8 wave6581__ST[]; static reg8 wave6581_P_T[]; static reg8 wave6581_PS_[]; static reg8 wave6581_PST[]; static reg8 wave8580__ST[]; static reg8 wave8580_P_T[]; static reg8 wave8580_PS_[]; static reg8 wave8580_PST[]; reg8* wave__ST; reg8* wave_P_T; reg8* wave_PS_; reg8* wave_PST; friend class Voice; friend class SID; }; // ---------------------------------------------------------------------------- // Inline functions. // The following functions are defined inline because they are called every // time a sample is calculated. // ---------------------------------------------------------------------------- #if RESID_INLINING || defined(__WAVE_CC__) // ---------------------------------------------------------------------------- // SID clocking - 1 cycle. // ---------------------------------------------------------------------------- RESID_INLINE void WaveformGenerator::clock() { // No operation if test bit is set. if (test) { return; } reg24 accumulator_prev = accumulator; // Calculate new accumulator value; accumulator += freq; accumulator &= 0xffffff; // Check whether the MSB is set high. This is used for synchronization. msb_rising = !(accumulator_prev & 0x800000) && (accumulator & 0x800000); // Shift noise register once for each time accumulator bit 19 is set high. if (!(accumulator_prev & 0x080000) && (accumulator & 0x080000)) { reg24 bit0 = ((shift_register >> 22) ^ (shift_register >> 17)) & 0x1; shift_register <<= 1; shift_register &= 0x7fffff; shift_register |= bit0; } } // ---------------------------------------------------------------------------- // SID clocking - delta_t cycles. // ---------------------------------------------------------------------------- RESID_INLINE void WaveformGenerator::clock(cycle_count delta_t) { // No operation if test bit is set. if (test) { return; } reg24 accumulator_prev = accumulator; // Calculate new accumulator value; reg24 delta_accumulator = delta_t*freq; accumulator += delta_accumulator; accumulator &= 0xffffff; // Check whether the MSB is set high. This is used for synchronization. msb_rising = !(accumulator_prev & 0x800000) && (accumulator & 0x800000); // Shift noise register once for each time accumulator bit 19 is set high. // Bit 19 is set high each time 2^20 (0x100000) is added to the accumulator. reg24 shift_period = 0x100000; while (delta_accumulator) { if (delta_accumulator < shift_period) { shift_period = delta_accumulator; // Determine whether bit 19 is set on the last period. // NB! Requires two's complement integer. if (shift_period <= 0x080000) { // Check for flip from 0 to 1. if (((accumulator - shift_period) & 0x080000) || !(accumulator & 0x080000)) { break; } } else { // Check for flip from 0 (to 1 or via 1 to 0) or from 1 via 0 to 1. if (((accumulator - shift_period) & 0x080000) && !(accumulator & 0x080000)) { break; } } } // Shift the noise/random register. // NB! The shift is actually delayed 2 cycles, this is not modeled. reg24 bit0 = ((shift_register >> 22) ^ (shift_register >> 17)) & 0x1; shift_register <<= 1; shift_register &= 0x7fffff; shift_register |= bit0; delta_accumulator -= shift_period; } } // ---------------------------------------------------------------------------- // Synchronize oscillators. // This must be done after all the oscillators have been clock()'ed since the // oscillators operate in parallel. // Note that the oscillators must be clocked exactly on the cycle when the // MSB is set high for hard sync to operate correctly. See SID::clock(). // ---------------------------------------------------------------------------- RESID_INLINE void WaveformGenerator::synchronize() { // A special case occurs when a sync source is synced itself on the same // cycle as when its MSB is set high. In this case the destination will // not be synced. This has been verified by sampling OSC3. if (msb_rising && sync_dest->sync && !(sync && sync_source->msb_rising)) { sync_dest->accumulator = 0; } } // ---------------------------------------------------------------------------- // Output functions. // NB! The output from SID 8580 is delayed one cycle compared to SID 6581, // this is not modeled. // ---------------------------------------------------------------------------- // No waveform: // Zero output. // RESID_INLINE reg12 WaveformGenerator::output____() { return 0x000; } // Triangle: // The upper 12 bits of the accumulator are used. // The MSB is used to create the falling edge of the triangle by inverting // the lower 11 bits. The MSB is thrown away and the lower 11 bits are // left-shifted (half the resolution, full amplitude). // Ring modulation substitutes the MSB with MSB EOR sync_source MSB. // RESID_INLINE reg12 WaveformGenerator::output___T() { reg24 msb = (ring_mod ? accumulator ^ sync_source->accumulator : accumulator) & 0x800000; return ((msb ? ~accumulator : accumulator) >> 11) & 0xfff; } // Sawtooth: // The output is identical to the upper 12 bits of the accumulator. // RESID_INLINE reg12 WaveformGenerator::output__S_() { return accumulator >> 12; } // Pulse: // The upper 12 bits of the accumulator are used. // These bits are compared to the pulse width register by a 12 bit digital // comparator; output is either all one or all zero bits. // NB! The output is actually delayed one cycle after the compare. // This is not modeled. // // The test bit, when set to one, holds the pulse waveform output at 0xfff // regardless of the pulse width setting. // RESID_INLINE reg12 WaveformGenerator::output_P__() { return (test || (accumulator >> 12) >= pw) ? 0xfff : 0x000; } // Noise: // The noise output is taken from intermediate bits of a 23-bit shift register // which is clocked by bit 19 of the accumulator. // NB! The output is actually delayed 2 cycles after bit 19 is set high. // This is not modeled. // // Operation: Calculate EOR result, shift register, set bit 0 = result. // // ----------------------->--------------------- // | | // ----EOR---- | // | | | // 2 2 2 1 1 1 1 1 1 1 1 1 1 | // Register bits: 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 <--- // | | | | | | | | // OSC3 bits : 7 6 5 4 3 2 1 0 // // Since waveform output is 12 bits the output is left-shifted 4 times. // RESID_INLINE reg12 WaveformGenerator::outputN___() { return ((shift_register & 0x400000) >> 11) | ((shift_register & 0x100000) >> 10) | ((shift_register & 0x010000) >> 7) | ((shift_register & 0x002000) >> 5) | ((shift_register & 0x000800) >> 4) | ((shift_register & 0x000080) >> 1) | ((shift_register & 0x000010) << 1) | ((shift_register & 0x000004) << 2); } // Combined waveforms: // By combining waveforms, the bits of each waveform are effectively short // circuited. A zero bit in one waveform will result in a zero output bit // (thus the infamous claim that the waveforms are AND'ed). // However, a zero bit in one waveform will also affect the neighboring bits // in the output. The reason for this has not been determined. // // Example: // // 1 1 // Bit # 1 0 9 8 7 6 5 4 3 2 1 0 // ----------------------- // Sawtooth 0 0 0 1 1 1 1 1 1 0 0 0 // // Triangle 0 0 1 1 1 1 1 1 0 0 0 0 // // AND 0 0 0 1 1 1 1 1 0 0 0 0 // // Output 0 0 0 0 1 1 1 0 0 0 0 0 // // // This behavior would be quite difficult to model exactly, since the SID // in this case does not act as a digital state machine. Tests show that minor // (1 bit) differences can actually occur in the output from otherwise // identical samples from OSC3 when waveforms are combined. To further // complicate the situation the output changes slightly with time (more // neighboring bits are successively set) when the 12-bit waveform // registers are kept unchanged. // // It is probably possible to come up with a valid model for the // behavior, however this would be far too slow for practical use since it // would have to be based on the mutual influence of individual bits. // // The output is instead approximated by using the upper bits of the // accumulator as an index to look up the combined output in a table // containing actual combined waveform samples from OSC3. // These samples are 8 bit, so 4 bits of waveform resolution is lost. // All OSC3 samples are taken with FREQ=0x1000, adding a 1 to the upper 12 // bits of the accumulator each cycle for a sample period of 4096 cycles. // // Sawtooth+Triangle: // The sawtooth output is used to look up an OSC3 sample. // // Pulse+Triangle: // The triangle output is right-shifted and used to look up an OSC3 sample. // The sample is output if the pulse output is on. // The reason for using the triangle output as the index is to handle ring // modulation. Only the first half of the sample is used, which should be OK // since the triangle waveform has half the resolution of the accumulator. // // Pulse+Sawtooth: // The sawtooth output is used to look up an OSC3 sample. // The sample is output if the pulse output is on. // // Pulse+Sawtooth+Triangle: // The sawtooth output is used to look up an OSC3 sample. // The sample is output if the pulse output is on. // RESID_INLINE reg12 WaveformGenerator::output__ST() { return wave__ST[output__S_()] << 4; } RESID_INLINE reg12 WaveformGenerator::output_P_T() { return (wave_P_T[output___T() >> 1] << 4) & output_P__(); } RESID_INLINE reg12 WaveformGenerator::output_PS_() { return (wave_PS_[output__S_()] << 4) & output_P__(); } RESID_INLINE reg12 WaveformGenerator::output_PST() { return (wave_PST[output__S_()] << 4) & output_P__(); } // Combined waveforms including noise: // All waveform combinations including noise output zero after a few cycles. // NB! The effects of such combinations are not fully explored. It is claimed // that the shift register may be filled with zeroes and locked up, which // seems to be true. // We have not attempted to model this behavior, suffice to say that // there is very little audible output from waveform combinations including // noise. We hope that nobody is actually using it. // RESID_INLINE reg12 WaveformGenerator::outputN__T() { return 0; } RESID_INLINE reg12 WaveformGenerator::outputN_S_() { return 0; } RESID_INLINE reg12 WaveformGenerator::outputN_ST() { return 0; } RESID_INLINE reg12 WaveformGenerator::outputNP__() { return 0; } RESID_INLINE reg12 WaveformGenerator::outputNP_T() { return 0; } RESID_INLINE reg12 WaveformGenerator::outputNPS_() { return 0; } RESID_INLINE reg12 WaveformGenerator::outputNPST() { return 0; } // ---------------------------------------------------------------------------- // Select one of 16 possible combinations of waveforms. // ---------------------------------------------------------------------------- RESID_INLINE reg12 WaveformGenerator::output() { // It may seem cleaner to use an array of member functions to return // waveform output; however a switch with inline functions is faster. switch (waveform) { default: case 0x0: return output____(); case 0x1: return output___T(); case 0x2: return output__S_(); case 0x3: return output__ST(); case 0x4: return output_P__(); case 0x5: return output_P_T(); case 0x6: return output_PS_(); case 0x7: return output_PST(); case 0x8: return outputN___(); case 0x9: return outputN__T(); case 0xa: return outputN_S_(); case 0xb: return outputN_ST(); case 0xc: return outputNP__(); case 0xd: return outputNP_T(); case 0xe: return outputNPS_(); case 0xf: return outputNPST(); } } #endif // RESID_INLINING || defined(__WAVE_CC__) #endif // not __WAVE_H__ CheeseCutter-2.10/src/seq/000077500000000000000000000000001516216315000153765ustar00rootroot00000000000000CheeseCutter-2.10/src/seq/fplay.d000066400000000000000000000062551516216315000166660ustar00rootroot00000000000000/* CheeseCutter v2 (C) Abaddon. Licensed under GNU GPL. */ module seq.fplay; import ui.ui; import seq.sequencer; import seq.seqtable; import ui.input; import ct.base; import com.session; import com.fb; import audio.audio, audio.player, audio.timer; import derelict.sdl2.sdl; private int mode; protected class FPlayVoice : SeqVoice { this(VoiceInitParams v) { super(v); assert(pos !is null); } override protected void scroll(int steps) { int lasttrk = tracks.trackLength; int seqofs = pos.seqOffset + steps; int trkofs2 = pos.trkOffset; Sequence seq; Track trk; int getRows() { Sequence seq = song.seqs[tracks[trkofs2].number]; if(tracks[trkofs2].trans >= 0xf0) return 1; return seq.rows; } pos.rowCounter = pos.rowCounter + steps; while(seqofs >= getRows()) { seqofs -= getRows(); trkofs2++; trk = tracks[trkofs2]; if(trk.trans >= 0xf0) { if(song.ver >= 6) jump(Jump.toWrapMark); else jump(mode); trkofs2 = pos.trkOffset; trk = tracks[trkofs2]; assert(trk.trans < 0xf0); } seq = song.seqs[trk.number]; assert(seqofs >= 0); } pos.seqOffset = seqofs; pos.trkOffset = trkofs2; } } protected class FPlayVoiceTable : SequenceTable { this(Rectangle a) { super(a, fplayPos); int x = 5 + com.fb.border + a.x; for(int v=0;v<3;v++) { Rectangle na = Rectangle(x, a.y, a.height, 13 + com.fb.border); x += 13 + com.fb.border; voices[v] = new FPlayVoice(VoiceInitParams(song.tracks[v], na, fplayPos[v])); } } override void step(int st) { foreach(v; cast(FPlayVoice[])voices) { v.scroll(st); } } } class Fplay : Window { private FPlayVoiceTable ftable; this(Rectangle a) { assert(fplayPos !is null); ftable = new FPlayVoiceTable(a); super(a); } void timerEvent() { if(!audio.player.isPlaying) return; int c = audio.timer.readRowTick(); if(c > 0) ftable.step(c); } override void update() { ftable.update(); } override int keypress(Keyinfo key) { switch(key.raw) { case SDLK_HOME: int m1, m2, m3; if(!key.mods & KMOD_CTRL) break; m1 = fplayPos.pos[0].mark; m2 = fplayPos.pos[1].mark; m3 = fplayPos.pos[2].mark; stop(); audio.player.start([m1, m2, m3], [0, 0, 0]); ftable.jump(Jump.toMark,true); break; /+ jump forward/backward disabled for now ... case SDLK_PLUS: int m1, m2, m3; m1 = ++fplayPos.pos[0].trkOffset; m2 = ++fplayPos.pos[1].trkOffset; m3 = ++fplayPos.pos[2].trkOffset; stop(); audio.player.start([m1, m2, m3], [0, 0, 0]); int[] m = [m1 , m2, m3]; ftable.jump(m1,true); update(); break; case SDLK_MINUS: int m1, m2, m3; m1 = --fplayPos.pos[0].trkOffset; m2 = --fplayPos.pos[1].trkOffset; m3 = --fplayPos.pos[2].trkOffset; stop(); audio.player.start([m1, m2, m3], [0, 0, 0]); int[] m = [m1 , m2, m3]; ftable.jump(m1,true); update(); break; +/ case SDLK_SPACE: audio.player.fastForward(25); break; default: break; } return OK; } void start(int p) { fplayPos.copyFrom(seqPos); ftable.jump(p,true); mode = p; } void startFromCursor() { fplayPos.copyFrom(seqPos); ftable.centerTo(0); mode = Jump.toBeginning; } void stop() { } } CheeseCutter-2.10/src/seq/seqtable.d000066400000000000000000000214111516216315000173420ustar00rootroot00000000000000/* CheeseCutter v2 (C) Abaddon. Licensed under GNU GPL. */ module seq.seqtable; import main; import ui.ui; import com.fb; import com.util; import seq.sequencer; import com.session; import ct.base; import ui.input; import derelict.sdl2.sdl; import std.string; import audio.player; class SeqVoice : Voice, Undoable { InputSeq seqinput; this(VoiceInitParams v) { super(v); activeRow = getRowData(0, 0); seqinput = new InputSeq(); (cast(InputSeq)seqinput).setElement(activeRow.element); seqinput.setCoord(area.x + 4, 0); (cast(InputSeq)seqinput).setPointer(area.x + 4, 0); activeInput = seqinput; } override int keyrelease(Keyinfo key) { return seqinput.keyrelease(key); } override int keypress(Keyinfo key) { if(key.mods & KMOD_SHIFT) { switch(key.raw) { case SDLK_RETURN: saveState(); int r = activeRow.seq.rows; int t = 4 * song.highlight; activeRow.seq.expand(activeRow.seqOffset, (t - (r + t) % t)); break; case SDLK_INSERT: saveState(); activeRow.seq.expand(activeRow.seqOffset, 1); break; case SDLK_DELETE: saveState(); activeRow.seq.shrink(activeRow.seqOffset, 1, true); break; default: return seqinput.keypress(key); } } else if(key.mods & KMOD_CTRL) { switch(key.raw) { case SDLK_INSERT: saveState(); activeRow.seq.expand(0, 1, false); break; case SDLK_DELETE: saveState(); if(activeRow.seqOffset < activeRow.seq.rows - 1) activeRow.seq.shrink(0, 1, false); break; case SDLK_q: saveState(); activeRow.seq.transpose(activeRow.seqOffset, 1); break; case SDLK_a: saveState(); activeRow.seq.transpose(activeRow.seqOffset, -1); break; case SDLK_w: saveState(); activeRow.seq.transpose(activeRow.seqOffset, 12); break; case SDLK_s: saveState(); activeRow.seq.transpose(activeRow.seqOffset, -12); break; default: return seqinput.keypress(key); } } else switch(key.raw) { case SDLK_LEFT: return seqinput.step(-1); case SDLK_RIGHT: return seqinput.step(1); case SDLK_INSERT: saveState(); activeRow.seq.insert(activeRow.seqOffset); break; case SDLK_DELETE: saveState(); activeRow.seq.remove(activeRow.seqOffset); break; default: return seqinput.keypress(key); } return OK; } override void refreshPointer(int y) { assert(seqinput !is null); assert(pos !is null); activeRow = getRowData(pos.trkOffset, pos.seqOffset + y); activeInput.setCoord(0, 1 + area.y + y + anchor); (cast(InputSeq)seqinput).setElement(activeRow.element); } override void update() { RowData wseq; int scry = area.y + area.height; int trkofs = pos.trkOffset, seqofs = pos.seqOffset - anchor; int lasttrk = tracks.trackLength; int hcount = pos.rowCounter - anchor + area.height - 1; int row = area.height; Sequence seq; seqofs += area.height;// - pos.delta; wseq = getRowData(trkofs, seqofs); trkofs = wseq.trkOffset2; seqofs = wseq.seqOffset; seq = new Sequence(wseq.seq.data.raw[0 .. $], seqofs); void printEmpty() { import std.array; screen.cprint(area.x - 1, scry, 1, 0, replicate(" ", 16)); } void printTrack() { screen.cprint(area.x - 1, scry, 1, 0, " " ~ formatTrackValue(wseq.track.smashedValue)); if(trkofs == pos.mark) { for(int i = 0; i < 13; i++) { int xpos = area.x + i; if(screen.getbg(xpos, scry) == 0) screen.setbg(xpos, scry, playbackBarColor); } } if(trkofs == tracks.wrapOffset) { for(int i = 0; i < 15; i++) { int xpos = area.x + i - 1; if(screen.getbg(xpos, scry) == 0) screen.setbg(xpos, scry, wrapBarColor); } } } int rows = seq.rows; while(scry >= area.y + 1) { if(trkofs < 0) { printEmpty(); scry--; row--; } else if(trkofs >= lasttrk+1) { printEmpty(); if(trkofs == lasttrk+1) { wseq = getRowData(trkofs, 0); printTrack(); } hcount--; scry--; trkofs--; if(trkofs >= 0) rows = 0; continue; } else { for(int i = rows - 1; i >= 0; i--, scry--, hcount--, row--) { printEmpty(); if(scry < area.y + 1) break; Element d = seq.data[i]; screen.fprint(area.x + 4, scry, d.toString(wseq.element.transpose)); if(i == 0) printTrack(); else { if(.seq.sequencer.displaySequenceRowcounter == true) { int c = (hcount - song.highlightOffset) % song.highlight ? 11 : 12; screen.cprint(area.x, scry, c, 0, format(" %02X ", i)); } else screen.cprint(area.x, scry, 0, 0, " "); } } } trkofs--; if(trkofs >= 0) { wseq = getRowData(trkofs, 0); seq = wseq.seq; rows = seq.rows; } } } protected: override final void undo(UndoValue entry) { auto data = entry.array.target; auto target = entry.array.source; target[] = data; assert(parent !is null); entry.seq.refresh(); parent.step(0); } void saveState() { UndoValue v; import std.typecons; v.array = UndoValue.Array(activeRow.seq.data.raw.dup, activeRow.seq.data.raw); v.seq = activeRow.seq; com.session.insertUndo(this, v); } override final UndoValue createRedoState(UndoValue value) { value.array.target = value.array.source.dup; return value; } } class SequenceTable : VoiceTable { this(Rectangle a, PosDataTable pi) { int x = 5 + com.fb.border + a.x; for(int v=0;v<3;v++) { Rectangle na = Rectangle(x, a.y, a.height, 13 + com.fb.border); x += 13 + com.fb.border; voices[v] = new SeqVoice(VoiceInitParams(song.tracks[v], na, pi[v], this)); } super(a, pi); } override void activate() { super.activate(); // works as scroll(1) would but does not store variables int steps = 0; foreach(Voice v; voices) { with(v.pos) { RowData s = v.getRowData(trkOffset); if(trkOffset >= v.tracks.trackLength) { trkOffset = 0; rowCounter = -pointerOffset; } } } } override void update() { super.update(); if(!audio.player.isPlaying || audio.player.keyjamEnabled) return; // trackbar for(int i = 0 ; i < 3; i++) { PosData fp = fplayPos[i]; PosData vp = posTable[i]; int tp = fp.rowCounter - vp.rowCounter + anchor; if(tp >= 0 && tp < area.height) { for(int x = voices[i].area.x; x < voices[i].area.x + voices[i].area.width; x++) { screen.setColor(x, 1 + area.y + tp, 1,0); } } } } override void stepVoice(int i) { int n = activeVoiceNum + i; int c = (n - activeVoiceNum) > 0 ? 0 : 1; n = umod(n, 0, 2); if(!voices[n].atEnd()) super.stepVoice(i); SeqVoice v = cast(SeqVoice)voices[n]; (cast(InputSeq)v.seqinput).columnReset(-c); } // for positioning the cursor using mouse. x is not used override void clickedAt(int x, int y, int button) { y -= 1; step(y-posTable.normalPointerOffset); } override int keypress(Keyinfo key) { // globals super.keypress(key); if(!key.mods) { switch(key.raw) { case SDLK_HOME: SeqVoice v = cast(SeqVoice)activeVoice; InputSeq i = cast(InputSeq)v.seqinput; if(i.activeColumn > 0) { (cast(InputSeq)v.seqinput).columnReset(0); break; } int ofs = activeVoice.activeRow.seqOffset; int cy = posTable.normalPointerOffset; int m; if(cy == 0) m = 1; else if(ofs == 0) break; else if(ofs > 0 && ofs > cy) { m = 0; } else m = 1; if(m) { toSeqStart(); } else toScreenTop(); break; case SDLK_END: SeqVoice v = cast(SeqVoice)activeVoice; InputSeq i = cast(InputSeq)v.seqinput; if(i.activeColumn < i.columns) { (cast(InputSeq)v.seqinput).columnReset(i.columns,0); break; } // something might be wrong here... int scrend = tableTop - posTable.pointerOffset - 1; assert(scrend >= 0); int rows = activeVoice.activeRow.seq.rows; int seqend = rows - activeVoice.activeRow.seqOffset - 1; int m; if(scrend == 0) toSeqEnd(); else if(seqend == 0) toScreenBot(); else if(seqend >= scrend) { toScreenBot(); } else { toSeqEnd(); } break; case SDLK_KP_0: audio.player.playRow(voices); step(1); break; default: break; } } else if(key.mods & KMOD_CTRL) { switch(key.raw) { case SDLK_p: RowData r = activeVoice.activeRow; // bad coding because all the rowcountergetters are flawed one way or another int rowcount = activeVoice.getRowcounter(r.trkOffset) + r.seqOffset; song.splitSequence(r.track.number, r.seqOffset); jump(Jump.toBeginning,false); step(rowcount); centerTo(0); break; default: break; } } int r; if((r = activeVoice.keypress(key)) != OK) { switch(r) { case WRAPL: stepVoice(-1); break; case WRAPR: stepVoice(1); break; default: step(stepValue); break; } } return OK; } } CheeseCutter-2.10/src/seq/sequencer.d000066400000000000000000000511651516216315000175450ustar00rootroot00000000000000/* CheeseCutter v2 (C) Abaddon. Licensed under GNU GPL. */ module seq.sequencer; import main; import com.fb; import ui.ui, ui.help; import ct.base; import com.session; import com.util; import ui.input; import ui.dialogs; import seq.fplay; import seq.tracktable; import seq.seqtable; import seq.trackmap; import derelict.sdl2.sdl; import std.string; import std.stdio; import audio.audio, audio.player; enum PAGESTEP = 2; enum Jump { toBeginning = 0, toMark = -1, toEnd = -2, toWrapMark = -3 }; enum playbackBarColor = 6; enum wrapBarColor = 4; bool displaySequenceRowcounter = true; int stepValue = 1; int activeVoiceNum; private int stepCounter; int tableTop = 15, tableBot = -16; enum anchor = 16; Clip[] clip; private { bool useRelativeNotes = true; } struct RowData { Track trk; alias trk track; // offset in tracklist, checked against endmark int trkOffset; // offset in tracklist, not checked int trkOffset2; int seqOffset; Sequence seq; // full sequence, cursor is at seq[seqOffset] //Sequence clipped; // clipped sequence, from cursor downwards int clippedRows; Element element; // data entry under cursor } struct VoiceInitParams { Tracklist t; Rectangle a; PosData p; VoiceTable voiceTable; } class PosData { int pointerOffsetValue = anchor; int trkOffset = 0; int seqOffset; int mark; int rowCounter; Tracklist tracks; @property int pointerOffset() { return pointerOffsetValue - anchor; } @property int pointerOffset(int i) { return pointerOffsetValue = i + anchor; } @property int rowOnCursor() { return seqOffset + pointerOffset; } int getRowCounter() { int counter; for(int i = 0; i <= trkOffset; i++) { Track t = tracks[i]; counter += song.sequence(t).rows; } return counter + seqOffset; } } class PosDataTable { PosData[] pos; PosData opIndex(int idx) { return pos[idx]; } this() { pos.length = 3; foreach(ref p; pos) p = new PosData; } @property int pointerOffset(int o) { foreach(ref p; pos) { p.pointerOffset = o; } return 0; } @property int pointerOffset() { return pos[0].pointerOffset; } @property int normalPointerOffset() { int r = tableTop + pos[0].pointerOffset; return r; } @property int rowCounter() { return pos[0].rowCounter; } @property int rowCounter(int o) { foreach(ref p; pos) { p.rowCounter = o; } return 0; } PosDataTable dup() { auto pt = new PosDataTable(); pt.copyFrom(this); return pt; } void copyFrom(PosDataTable pt) { for(int i = 0 ; i < 3; i++) { PosData p = pos[i]; PosData t = pt[i]; p.pointerOffset = t.pointerOffset; p.seqOffset = t.seqOffset; p.trkOffset = t.trkOffset; p.rowCounter = t.rowCounter; p.mark = t.mark; } } } // ------------------------------------------------------------------------ // ------------------------------------------------------------------------ abstract class Voice : Window { Tracklist tracks; PosData pos; RowData activeRow; Input input; alias input activeInput; VoiceTable parent; this(ref VoiceInitParams v) { super(v.a); tracks = v.t; pos = v.p; parent = v.voiceTable; } public: bool atBeg() { return pos.trkOffset <= 0 && (pos.seqOffset + pos.pointerOffset) <= 0; } bool atEnd() { RowData s = getRowData(pos.trkOffset, pos.seqOffset + pos.pointerOffset); return (s.trk.trans >= 0xf0); } bool pastEnd() { return pastEnd(0); } bool pastEnd(int y) { RowData s = getRowData(pos.trkOffset, pos.seqOffset + y); int t = s.trkOffset2 - 1; if(t < 0) return false; Track trk = tracks[t]; return (trk.trans >= 0xf0); } void trackFlush(int y) { return; } override void refresh() { refreshPointer(0); } RowData getRowData(int trkofs, int seqofs) { static RowData s; int trkofs2 = trkofs; Sequence seq; int lasttrk = tracks.trackLength; Sequence getSeq(Track t) { if(t.trans >= 0xf0) return song.seqs[0]; else return song.seqs[t.number]; } int numRowsInSeq() { if(tracks[trkofs2].trans >= 0xf0) return 1; return getSeq(tracks[trkofs2]).rows; } if(trkofs > lasttrk) trkofs = lasttrk; s.trk = tracks[trkofs]; seq = getSeq(s.trk); while (seqofs < 0) { seqofs += numRowsInSeq(); if(--trkofs < 0) { trkofs = 0; seqofs = 0; break; } --trkofs2; s.trk = tracks[trkofs]; seq = song.seqs[s.trk.number]; } assert(seqofs >= 0); while(seqofs >= numRowsInSeq()) { seqofs -= numRowsInSeq(); if(trkofs < lasttrk) trkofs++; trkofs2++; s.trk = tracks[trkofs2]; seq = getSeq(s.trk); } s.seqOffset = seqofs; s.clippedRows = seq.rows - seqofs; s.trkOffset = trkofs; s.trkOffset2 = trkofs2; s.element = seq.data[seqofs]; if(useRelativeNotes) { int t = trkofs; while(t >= 0 && tracks[t].trans == 0x80) t--; if(t >= 0) s.element.transpose = tracks[t].trans - 0xa0; } s.seq = seq; return s; } RowData getRowData(int tofs) { return getRowData(tofs, 0); } void scroll(int steps) { scroll(steps, true); } void scroll(int steps, bool canWrap) { int oldRowcounter; RowData s = getRowData(pos.trkOffset); assert(s.seq.rows == s.clippedRows); with(pos) { seqOffset = seqOffset + steps; oldRowcounter = rowCounter; rowCounter += steps; while(seqOffset + pointerOffset < 0) { if(--trkOffset < 0) { if(canWrap) { trkOffset = tracks.trackLength - 1; rowCounter = getRowCounter(); } else trkOffset = 0; } s = getRowData(trkOffset); seqOffset += s.clippedRows; steps += s.clippedRows; } while(seqOffset + pointerOffset >= s.clippedRows) { seqOffset -= s.clippedRows; steps -= s.clippedRows; if(++trkOffset >= tracks.trackLength) { if(canWrap) { trkOffset = 0; rowCounter = seqOffset; } else { trkOffset = tracks.trackLength - 1; rowCounter = oldRowcounter; } } s = getRowData(trkOffset); } } } // TODO: move elsewhere... int getRowcounter(int trkofs) { int counter = 0; for(int i = 0; i < trkofs; i++) { Track t = tracks[i]; counter += song.sequence(t).rows; } return counter; } protected: override void update(); void refreshPointer() { refreshPointer(pos.pointerOffset); } void refreshPointer(int y); void jump(int jumpto) { if(jumpto == Jump.toMark) jumpto = pos.mark; else if(jumpto == Jump.toWrapMark) jumpto = tracks.wrapOffset; assert(jumpto >= 0); pos.trkOffset = jumpto; pos.seqOffset = 0; pos.rowCounter = getRowcounter(jumpto); } void setMark() { setMark(1); } // when m == 1, sets mark to current trkOffsets // when m == 0, zeroes it out void setMark(int m) { pos.mark = m ? activeRow.trkOffset : 0; } alias setMark setPositionMark; void setWrapMark() { tracks.wrapOffset = cast(ushort) (activeRow.trkOffset); } string formatTrackValue(int trknum) { if(trknum >= 0xf000) return "LOOP"; return format("%04X", trknum); } } abstract class VoiceTable : Window { Voice[3] voices; Voice active; alias active activeVoice; PosDataTable posTable; this(Rectangle a, PosDataTable pi) { super(a); posTable = pi; activeVoice = voices[0]; } override void activate() { activeVoice = voices[activeVoiceNum]; input = activeVoice.activeInput; refresh(); } override void deactivate() { activeVoice.trackFlush(posTable.pointerOffset); } override void refresh() { foreach(v; voices) { v.refresh(); } } void centralize() { jump(activeVoice.activeRow.trkOffset,true); } override int keypress(Keyinfo key) { if(key.mods & KMOD_SHIFT) { switch(key.raw) { case SDLK_HOME: jump(Jump.toBeginning,true); break; case SDLK_END: jump(Jump.toEnd,true); break; case SDLK_PAGEUP: step(-PAGESTEP * 2 * song.highlight); break; case SDLK_PAGEDOWN: step(PAGESTEP * 2 * song.highlight); break; default: break; } } else if(key.mods & KMOD_CTRL) { switch(key.raw) { case SDLK_h, SDLK_HOME: jump(Jump.toMark,true); break; case SDLK_l: centralize(); break; case SDLK_m: if(song.highlight < 16) song.highlight++; break; case SDLK_n: if(song.highlight > 1) song.highlight--; break; case SDLK_0: song.highlightOffset = posTable.rowCounter+posTable.pointerOffset; break; case SDLK_e: displaySequenceRowcounter ^= 1; break; case SDLK_t: useRelativeNotes ^= 1; UI.statusline.display(format("Relative notes %s.", useRelativeNotes ? "enabled" : "disabled")); break; case SDLK_F1: setPositionMark(); break; case SDLK_BACKSPACE: setWrapMark(); break; default: break; } } else switch(key.raw) { case SDLK_BACKSPACE, SDLK_PLUS: setPositionMark(); break; default: break; } // we don't care about mods with these keys switch(key.raw) { case SDLK_DOWN: if(key.mods & KMOD_SHIFT) goto case SDLK_PAGEDOWN; else if(key.mods & KMOD_CTRL) { scroll(1); step(-1); } else step(1); break; case SDLK_UP: if(key.mods & KMOD_SHIFT) goto case SDLK_PAGEUP; else if(key.mods & KMOD_CTRL) { scroll(-1); step(1); } else step(-1); break; case SDLK_PAGEUP: step(-PAGESTEP * song.highlight); break; case SDLK_PAGEDOWN: step(PAGESTEP * song.highlight); break; case SDLK_TAB: foreach(v; voices) { v.input.nibble = 0; } if(key.mods & KMOD_SHIFT) stepVoice(-1); else stepVoice(); break; default: break; } return OK; } void stepVoice() { stepVoice(1); } void stepVoice(int i) { // safety check - if we're past endmark on all voices, // exit the method -- can happen if all tracklists // contain only FF00 bool pastAll = true; foreach(voice; voices) { if(!voice.pastEnd(posTable.pointerOffset)) pastAll = false; } if(pastAll) return; int nv = umod(activeVoiceNum + i, 0, 2); while(voices[nv].pastEnd(posTable.pointerOffset)) { nv = umod(nv + i, 0, 2); } activateVoice(nv); } void scroll(int st) { foreach(v; voices) { v.scroll(st); } } void activateVoice(int voice) { deactivate(); activeVoiceNum = voice; activate(); voices[voice].refreshPointer(); step(0); } void jumpToVoice(int voice) { deactivate(); activeVoiceNum = voice; activate(); // making sure cursor is not past endmark step(0); } override void update() { input = activeVoice.activeInput; foreach(v; voices) { v.refreshPointer(posTable.pointerOffset); v.update(); } // statusline screen.cprint(area.x + 1, area.y, 1, 0, format("#%02X",song.subtune)); for(int i = 0, x = area.x + 5 + com.fb.border; i < 3; i++) { Voice v = voices[i]; RowData c = v.activeRow; screen.cprint(x, area.y, 1, 0, format("+%03X %02X %s", c.trkOffset, c.trk.number, audio.player.muted[i] ? "Off" : " ") ); x += 13 + com.fb.border; } // row counter int r = activeVoice.pos.rowCounter - anchor; for(int y = 0; y < area.height; y++) { string s = " "; if(r >= 0) s = format("%+4X", r); r++; screen.cprint(area.x, area.y + y + 1, 12, 0, s); } } void setPositionMark() { int rows = -1; foreach(v; voices) { if(rows < 0) rows = v.pos.rowOnCursor; if(rows != v.pos.rowOnCursor) UI.statusline.display("Warning: The start point is not aligned! The song will play incorrectly."); v.setPositionMark(); } } void setWrapMark() { int rows = -1; foreach(v; voices) { if(rows < 0) rows = v.pos.rowOnCursor; if(rows != v.pos.rowOnCursor) UI.statusline.display("Warning: The loop point is not aligned! The song will loop incorrectly."); v.setWrapMark(); } } void jump(int to, bool doCtr) { switch(to) { case Jump.toBeginning: posTable.pointerOffset = 0; foreach(v; voices) { v.jump(Jump.toBeginning); } if(doCtr) centerTo(0); break; case Jump.toMark: posTable.pointerOffset = 0; foreach(v; voices) { v.jump(Jump.toBeginning); v.jump(v.pos.mark); } if(doCtr) centerTo(0); break; case Jump.toWrapMark: posTable.pointerOffset = 0; foreach(v; voices) { v.jump(Jump.toBeginning); v.jump(v.tracks.wrapOffset); } if(doCtr) centerTo(0); break; case Jump.toEnd: centralize(); toSeqStart(); foreach(v; voices) { v.jump(Jump.toBeginning); } int e = activeVoice.tracks.trackLength - 1; for(int i = 0; i < e; i++) { activeVoice.refreshPointer(posTable.pointerOffset); RowData s = activeVoice.getRowData(i); step(s.seq.rows); } activeVoice.refreshPointer(posTable.pointerOffset); toSeqEnd(); break; default: if(to < 0) { to = activeVoice.pos.mark; } foreach(v; voices) { v.jump(Jump.toBeginning); } Voice v = activeVoice; posTable.pointerOffset = 0; for(int i = 0; i < to; i++) { activeVoice.refreshPointer(0); int trk = v.tracks[i].number; Sequence s = song.seqs[trk]; step(s.rows); } if(doCtr) centerTo(0); break; } refresh(); } void toSeqStart() { int st = -activeVoice.activeRow.seqOffset; this.step(st,0); } void toSeqEnd() { int rows = activeVoice.activeRow.seq.rows; int seqend = rows - activeVoice.activeRow.seqOffset - 1; step(seqend); } void toScreenTop() { step(-posTable.normalPointerOffset); } void toScreenBot() { int scrend = tableTop - posTable.pointerOffset - 1; step(scrend); } void centerTo(int center) { assert(center < tableTop && center >= tableBot); int steps = center - posTable.pointerOffset; foreach(v; voices) { v.scroll(-steps); } posTable.pointerOffset = center; step(0,1,1); } void step(int s) { step(s, 0); } void step(int s, int e) { step(s, e, area.height); } void step(int st, int extra, int height) { bool wrapOk = true; bool atBeg = activeVoice.atBeg(); if(st < 0 && atBeg && stepCounter > 0) { st = 0; wrapOk = false; } posTable.pointerOffset = posTable.pointerOffset + st; bool atEnd = activeVoice.atEnd(); if(atEnd && stepCounter > 1) { posTable.pointerOffset = posTable.pointerOffset - st; st = 0; wrapOk = false; } int r; if(posTable.pointerOffset >= tableTop) { r = -(height/2-posTable.pointerOffset-1); posTable.pointerOffset = tableTop - 1; } else if(posTable.pointerOffset < tableBot) { r = (posTable.pointerOffset+height/2); posTable.pointerOffset = tableBot; } stepCounter++; int d = r > 0 ? 1 : - 1; if(r == 0) d = 0; int i; doStep(wrapOk,r); if(d <= 0) return; assert(extra >= 0); posTable.pointerOffset = posTable.pointerOffset - extra; doStep(true,extra); } protected void doStep(bool wrapOk, int r) { foreach(v; voices) { bool wrap = wrapOk; v.scroll(r,wrap); } } // for seq copy/insert/etc RowData getRowData() { return activeVoice.activeRow; } Sequence getActiveSequence() { return activeVoice.activeRow.seq; } // helper for trackcopy/paste Tracklist getTracklist(Voice v) { return v.tracks[v.activeRow.trkOffset .. v.tracks.length]; } } // ------------------------------------------------------------------- final class Sequencer : Window, Undoable { private { VoiceTable[] voiceTables; TrackmapTable trackmapTable; SequenceTable sequenceTable; TrackTable trackTable; QueryDialog queryCopy, queryAppend; PosDataTable[] postables; } VoiceTable activeView; //private Clip[] clip; this(Rectangle a) { int h = screen.height - 10; super(a,ui.help.HELPSEQUENCER); trackmapTable = new TrackmapTable(a, seqPos); sequenceTable = new SequenceTable(a, seqPos); trackTable = new TrackTable(a, seqPos); voiceTables = [cast(VoiceTable)trackmapTable, sequenceTable, trackTable]; activeView = sequenceTable; activeView.activate(); activateVoice(0); queryAppend = new QueryDialog("Insert this sequence to cursor pos: $", &insertCallback, 0x80); queryCopy = new QueryDialog("Copy this sequence to cursor seq: $", ©Callback, 0x80); // top & bottom tableBot = -area.height / 2; tableTop = area.height / 2; sequenceTable.centerTo(0); postables.length = 32; foreach(ref p; postables) { p = new PosDataTable; } } void activateVoice(int n) { activeView.jumpToVoice(n); input = activeView.input; } void reset() { reset(true); } void reset(bool tostart) { activeView.deactivate(); if(tostart) { foreach(b; voiceTables) { b.toSeqStart(); } sequenceTable.jump(Jump.toBeginning,true); foreach(ref p; postables) { p = new PosDataTable; } } activeView = sequenceTable; activeView.activate(); } void resetMark() { foreach(v; activeView.voices) { v.setPositionMark(0); } } Voice[] getVoices() { return activeView.voices; } override int keypress(Keyinfo key) { if(key.raw >= SDLK_KP_0 && key.raw <= SDLK_KP_9) { stepValue = key.raw - SDLK_KP_0; return OK; } if(key.mods & KMOD_ALT) { switch(key.raw) { case SDLK_a: mainui.activateDialog(queryAppend); break; case SDLK_c: mainui.activateDialog(queryCopy); break; case SDLK_RIGHT: changeSubtune(1); break; case SDLK_LEFT: changeSubtune(0); break; default: return activeView.keypress(key); } } else if(key.mods & KMOD_CTRL) { switch(key.raw) { case SDLK_F12: mainui.activateDialog( new DebugDialog(activeView.activeVoice.activeRow.seq)); break; default: return activeView.keypress(key); } } else switch(key.raw) { case SDLK_F5: void activateTracktable() { activeView.deactivate(); activeView.toSeqStart(); activeView = trackTable; activeView.activate(); } if(activeView != trackTable) { activateTracktable(); trackTable.displayTracklist = (key.mods & KMOD_SHIFT) > 0; break; } if(key.mods & KMOD_SHIFT) { activateTracktable(); trackTable.displayTracklist(true); break; } goto case SDLK_F6; case SDLK_F6: activeView.deactivate(); activeView = sequenceTable; activeView.activate(); // making sure cursor is not past endmark activeView.step(0); break; case SDLK_F7: activeView.deactivate(); if(activeView == trackmapTable) { activeView.toSeqStart(); activeView = trackTable; } else { activeView.toSeqStart(); activeView.centerTo(0); // scroll to upmost pos activeView = trackmapTable; } activeView.activate(); break; /+ case SDLK_MINUS: if(octave > 0) octave--; break; case SDLK_PLUS: if(octave < 6) octave++; break; +/ default: return activeView.keypress(key); } return OK; } override int keyrelease(Keyinfo key) { stepCounter = 0; // lazily skipping the "view" layer (so no keyrelease event ever gets there at the moment) activeView.activeVoice.keyrelease(key); return OK; } override void clickedAt(int x, int y, int button) { foreach(idx, Voice v; activeView.voices) { if(v.area.overlaps(x, y)) { activateVoice(cast(int)idx); activeView.clickedAt(x - area.x, y - area.y, button); } } } protected: void changeSubtune(int direction) { postables[song.subtune].copyFrom(activeView.posTable); refresh(); mainui.stop(); activeView.jump(0,false); resetMark(); direction > 0 ? song.incSubtune() : song.decSubtune(); activeView.posTable.copyFrom(postables[song.subtune]); activeView.activate(); refresh(); activeView.step(0); } override void update() { activeView.update(); input = activeView.input; } override void activate() {} override void deactivate() { activeView.deactivate(); } override void refresh() { foreach(b; voiceTables) { b.refresh(); } } override final void undo(UndoValue entry) { if(entry.subtuneNum != song.subtune) return; with(entry) { auto data = array.target; auto target = array.source; target[] = data; seq.refresh(); activeView.posTable.copyFrom(entry.posTable); } refresh(); activeView.step(0); } override final UndoValue createRedoState(UndoValue value) { value.array.target = value.array.source.dup; return value; } private: void saveState() { UndoValue v; import std.typecons; RowData s = activeView.getRowData(); v.array = UndoValue.Array(s.seq.data.raw.dup, s.seq.data.raw); v.seq = s.seq; v.posTable = activeView.posTable.dup(); v.subtuneNum = song.subtune; com.session.insertUndo(this, v); } void insertCallback(int param) { saveState(); if(param >= MAX_SEQ_NUM) return; RowData s = activeView.getRowData(); Sequence fr = song.seqs[param]; Sequence to = s.seq; to.insertFrom(fr, s.seqOffset); activeView.step(0); } void copyCallback(int param) { saveState(); if(param >= MAX_SEQ_NUM) return; RowData s = activeView.getRowData(); Sequence fr = song.seqs[param]; Sequence to = s.seq; to.copyFrom(fr); activeView.step(0); } } CheeseCutter-2.10/src/seq/trackmap.d000066400000000000000000000066061516216315000173550ustar00rootroot00000000000000/* CheeseCutter v2 (C) Abaddon. Licensed under GNU GPL. */ module seq.trackmap; import main; import com.fb; import com.session; import ui.ui; import seq.sequencer; import seq.tracktable; import ui.input; import derelict.sdl2.sdl; import std.string : format; import ct.base; import std.array; class TrackmapVoice : TrackVoice { this(VoiceInitParams v) { super(v); } override void update() { RowData wseq, cseq; int h = area.y + area.h + 1; int y,i; int trkofs = pos.trkOffset; int lasttrk = tracks.trackLength; int counter; int scry = area.y + 1; void printEmpty() { screen.cprint(area.x - 1, scry, 1, 0, std.array.replicate(" ", 16)); } void printTrack() { int fpCounter = fplayPos.rowCounter; int delta = fpCounter - counter; int fgcol = (delta >= 0 && delta < wseq.seq.rows) ? 13 : 5; int trk = wseq.trk.smashedValue; int rows = wseq.seq.rows; int c = counter; if(scry == area.y + 1 + anchor) fgcol = 1; if(wseq.trk.trans >= 0xf0) { rows = 0; c = 0; } screen.fprint(area.x-1, scry, format(" `01%s `0%x%02X %04X ", formatTrackValue(trk), fgcol, rows, c)); if(trkofs == pos.mark) { for(int i = 0; i < 13; i++) { int xpos = area.x + i; if(screen.getbg(xpos, scry) == 0) screen.setbg(xpos, scry, playbackBarColor); } } if(trkofs == tracks.wrapOffset) { for(int i = 0; i < 15; i++) { int xpos = area.x + i - 1; if(screen.getbg(xpos, scry) == 0) screen.setbg(xpos, scry, wrapBarColor); } } } trkofs -= seq.sequencer.anchor; counter = getRowcounter(trkofs); if(trkofs >= 0) wseq = getRowData(trkofs); y = area.y + 1; while(scry <= area.y + area.height) { if(trkofs < 0) { printEmpty(); scry++; } else if(trkofs >= lasttrk+1) { printEmpty(); scry++; trkofs++; continue; } else { printTrack(); counter += wseq.seq.rows; scry++; } trkofs++; if(trkofs >= 0 && trkofs <= lasttrk) { wseq = getRowData(trkofs, 0); } } } } class TrackmapTable : BaseTrackTable { this(Rectangle a, PosDataTable pi) { int x = 5 + com.fb.border + a.x; for(int v=0;v<3;v++) { Rectangle na = Rectangle(x, a.y, a.height, 13 + com.fb.border); x += 13 + com.fb.border; voices[v] = new TrackmapVoice(VoiceInitParams(song.tracks[v], na, pi.pos[v], this)); } super(a, pi); } override void activate() { super.activate(); // FIX: scroll the screen to center, don't just set the offset vars centralize(); } override int keypress(Keyinfo key) { switch(key.raw) { case SDLK_z: mainui.activateDialog(queryClip); return OK; case SDLK_i: pasteCallback(true); return OK; default: return super.keypress(key); } } // centerTo() & jump() (?) do not work with this! override void step(int st) { step(st,0); } override void step(int st, int extra) { int steps, rows; RowData s; activeVoice.trackFlush(posTable.pointerOffset); if(st > 0) { if(activeVoice.atEnd()) return; rows = activeVoice.activeRow.seq.rows; foreach(v; voices) { v.scroll(rows, true); } } else if(st < 0) { int t = activeVoice.pos.trkOffset-1; if(t < 0) t = activeVoice.tracks.trackLength-1; s = activeVoice.getRowData(t,0); rows = s.seq.rows; foreach(v; voices) { v.scroll(-rows); } } super.refresh(); } override void toSeqStart() { return; } } CheeseCutter-2.10/src/seq/tracktable.d000066400000000000000000000266451516216315000176740ustar00rootroot00000000000000/* CheeseCutter v2 (C) Abaddon. Licensed under GNU GPL. */ module seq.tracktable; import main; import seq.sequencer; import seq.seqtable; import com.fb; import com.session; import com.util; import ui.ui; import ui.dialogs; import ui.input; import derelict.sdl2.sdl; import ct.base; class TrackVoice : SeqVoice { InputTrack trackinput; bool displayTracklist = false; this(VoiceInitParams v) { super(v); refreshPointer(0); trackinput = new InputTrack(activeRow, &(cast(BaseTrackTable)v.voiceTable).trackValueChanged); trackinput.setCoord(area.x,0); activeInput = trackinput; } override void trackFlush(int y) { trackinput.flush(); refreshPointer(y); } override int keypress(Keyinfo key) { return trackinput.keypress(key); } override void deactivate() { super.deactivate(); with(pos) { if(trkOffset >= tracks.trackLength) { trkOffset = 0; rowCounter = seqOffset; } } } override void update() { super.update(); RowData wseq, cseq; int h = area.y + area.h + 1; int y,i; int trkofs = pos.trkOffset; int rows = 0; int lasttrk = tracks.trackLength; int counter; int scry = area.y + 1; void printTrack() { if(!displayTracklist) return; screen.cprint(area.x - 1, scry, 1, 0, " " ~ formatTrackValue(wseq.track.smashedValue)); if(trkofs == pos.mark) { for(int i = 0; i < 13; i++) { int xpos = area.x + i; if(screen.getbg(xpos, scry) == 0) screen.setbg(xpos, scry, playbackBarColor); } } if(trkofs == tracks.wrapOffset) { for(int i = 0; i < 15; i++) { int xpos = area.x + i - 1; if(screen.getbg(xpos, scry) == 0) screen.setbg(xpos, scry, wrapBarColor); } } } trkofs -= pos.pointerOffset + seq.sequencer.anchor; counter = getRowcounter(trkofs); if(trkofs >= 0) wseq = getRowData(trkofs); y = area.y + 1; while(scry <= area.y + area.height) { if(trkofs < 0) { scry++; } else if(trkofs >= lasttrk+1) { scry++; trkofs++; continue; } else { printTrack(); counter += wseq.seq.rows; scry++; } trkofs++; if(trkofs >= 0 && trkofs <= lasttrk) { wseq = getRowData(trkofs, 0); } } } protected: void refreshTrack(int po) { refreshPointer(po); trackinput.refresh(activeRow); refreshPointer(po); } void trackInsert(bool doInsert) { Track trk = activeRow.track; trackinput.flush(); { if(!doInsert) { tracks.expand(); } else { tracks.insertAt(activeRow.trkOffset); if(pos.trkOffset <= pos.mark) pos.mark++; } } trackinput.init(activeRow); } void trackDelete(bool doDelete) { trackinput.flush(); { if(!doDelete) { if(tracks.trackLength == 1) { tracks[0].setValue(0xa0, 0); } tracks.shrink(); } else { if(tracks.trackLength == 1) { tracks[0].setValue(0xa0, 00); } else { tracks.deleteAt(activeRow.trkOffset); // TODO: add check that tracklist hasn't been shrunk below trkOffset /+ if(pos.trkOffset >= tracks.trackLength-1) super.step(-1);+/ } } } trackinput.init(activeRow); if(pos.mark > pos.trkOffset) pos.mark--; if(pos.mark < 0) pos.mark = 0; if(pos.mark >= tracks.trackLength) { pos.mark = tracks.trackLength - 1; } } void trackTrans(int d) { trackinput.flush(); { tracks.transposeAt(activeRow.trkOffset, tracks.length, d); } trackinput.init(activeRow); } } abstract class BaseTrackTable : VoiceTable, Undoable { QueryDialog queryClip; protected Clip[] clip; this(Rectangle a, PosDataTable pi) { super(a, pi); queryClip = new QueryDialog("Copy number of tracks to clipboard: $", &clipCallback, 0x80); } void trackValueChanged() { saveState(false); } override int keypress(Keyinfo key) { if(key.mods & KMOD_CTRL) { switch(key.raw) { case SDLK_INSERT, SDLK_RETURN: if(key.mods & KMOD_SHIFT) { saveState(true); for(int i = 0; i < voices.length; i++) { auto v = cast(TrackVoice)voices[i]; v.trackInsert(true); } } else { saveState(false); (cast(TrackVoice)activeVoice).trackInsert(false); jump(Jump.toEnd,true); } return OK; case SDLK_DELETE: saveState(true); if(key.mods & KMOD_SHIFT) { for(int i = 0; i < voices.length; i++) { auto v = cast(TrackVoice)voices[i]; v.trackDelete((key.mods & KMOD_SHIFT) > 0); } } else { (cast(TrackVoice)activeVoice).trackDelete(false); jump(Jump.toEnd,true); } return OK; case SDLK_q: saveState(true); (cast(TrackVoice)activeVoice).trackTrans(1); break; case SDLK_a: saveState(true); (cast(TrackVoice)activeVoice).trackTrans(-1); break; case SDLK_c: mainui.activateDialog(queryClip); return OK; case SDLK_v: mainui.activateDialog(new ConfirmationDialog("Paste tracks; insert or overwrite? (i/o) ", &pasteCallback, "oi", 1)); return OK; case SDLK_i: pasteTracks(clip, true); return OK; case SDLK_o: pasteTracks(clip, false); return OK; default: break; } } else if(key.mods & KMOD_ALT) { switch(key.key) { case SDLK_z: mainui.activateDialog(queryClip); return OK; case SDLK_b: pasteTracks(clip, true); return OK; default: break; } } if((key.mods & KMOD_CTRL) && (key.mods & KMOD_ALT)) { switch(key.raw) { case SDLK_1: trackSwap(0); break; case SDLK_2: trackSwap(1); break; case SDLK_3: trackSwap(2); break; default: break; } } else switch(key.raw) { case SDLK_INSERT: saveState(false); auto v = (cast(TrackVoice)activeVoice); v.trackInsert(true); return OK; case SDLK_DELETE: saveState(false); auto v = (cast(TrackVoice)activeVoice); v.trackDelete(true); if(v.pos.trkOffset >= v.tracks.trackLength-1) jump(Jump.toEnd,true); return OK; default: break; } super.keypress(key); switch(activeVoice.keypress(key)) { case WRAPL: stepVoice(-1); break; case WRAPR: stepVoice(1); break; default: break; } return OK; } override void toSeqEnd() { return; } override void toSeqStart() { return; } override void refresh() { foreach(v; voices) { (cast(TrackVoice)v).refreshTrack(posTable.pointerOffset); v.refresh(); } } override void jump(int jumpto, bool center) { activeVoice.trackFlush(posTable.pointerOffset); super.jump(jumpto,center); } override void activate() { super.activate(); } override void deactivate() { super.deactivate(); activeVoice.deactivate(); } /* custom voicestepper: voice resync needed because * tracks may not be aligned */ override void stepVoice(int i) { int nib = 3 ^ 3 - activeVoice.activeInput.nibble; super.stepVoice(i); super.step(-activeVoice.activeRow.seqOffset,0); activeVoice.activeInput.nibble = nib; } override void step(int st, int extra, int height) { activeVoice.trackFlush(posTable.pointerOffset); doStep(true, st); } protected void trackSwap(int withVoice) { saveState(true); Tracklist from = getTracklist(activeVoice); Tracklist to = getTracklist(voices[withVoice]); // TODO: calc new wrap points... /+ int wrap1, wrap2, pos1, pos2; pos1 = activeVoice.pos.trkOffset; pos2 = voices[withVoice].pos.trkOffset; wrap1 = from.wrapOffset - pos1; wrap2 = to.wrapOffset - pos2; +/ /+ int temp = voices[withVoice].pos.trkOffset; voices[withVoice].pos.trkOffset = activeVoice.pos.trkOffset; activeVoice.pos.trkOffset = temp; +/ for(int i = 0; i < from.length; i++) { if(i >= to.length) break; int temptrans, tempno; temptrans = to[i].trans; tempno = to[i].number; to[i].setValue(from[i].trans, from[i].number); from[i].setValue(temptrans, tempno); } refresh(); } void clipCallback(int num) { const int trackLength = activeVoice.tracks.trackLength; int curTrkOffset = activeVoice.activeRow.trkOffset; Tracklist tl = getTracklist(activeVoice)[0..num]; int length = tl.length; if(curTrkOffset + num >= trackLength) length = trackLength - curTrkOffset; assert(length >= 0); clip.length = length; for(int i = 0; i < length; i++) { clip[i].trans = tl[i].trans; clip[i].no = tl[i].number; } } void pasteCallback(int value) { pasteTracks(clip, value > 0); } private void pasteTracks(Clip[] clip, bool doInsert) { saveState(false); if(doInsert) { for(int i = 0; i < clip.length; i++) { auto v = cast(TrackVoice)activeVoice; v.trackInsert(true); } } Tracklist vtr = getTracklist(activeVoice)[0..clip.length]; // FIX: ADD .dup operator to Tracklist for(int i = 0; i < clip.length; i++) { vtr[i].setValue(clip[i].trans,clip[i].no); } // reinitialize trackinput for voices refresh(); // make sure cursor not past track end step(0,0,0); clip.length = 0; } protected void saveState(bool allVoices) { com.session.insertUndo(this, createState(allVoices)); } private UndoValue createState(bool allVoices) { import std.typecons; UndoValue v; v.trackValue = (cast(InputTrack)input).trk.dup; v.track = (cast(InputTrack)input).trk; if(allVoices) { for(int i = 0; i < voices.length; i++) { auto tl = getTracklist(voices[i]); auto t = TracklistStore(tl.deepcopy, tl); v.trackLists ~= t; } } else { auto tl = getTracklist(activeVoice); auto t = TracklistStore(tl.deepcopy, tl); v.trackLists = [t]; } v.posTable = posTable.dup(); v.subtuneNum = song.subtune; v.allVoices = allVoices; return v; } override protected final void undo(UndoValue v) { if(v.subtuneNum != song.subtune) return; foreach(t; v.trackLists) { t.source.overwriteFrom(t.store); } v.track = v.trackValue; posTable.copyFrom(v.posTable); refresh(); // make sure cursor not past track end step(0,0,0); } override protected UndoValue createRedoState(UndoValue value) { return createState(value.allVoices); } } class TrackTable : BaseTrackTable { this(Rectangle a, PosDataTable pi) { int x = 5 + com.fb.border + a.x; for(int v=0;v<3;v++) { Rectangle na = Rectangle(x, a.y, a.height, 13 + com.fb.border); x += 13 + com.fb.border; voices[v] = new TrackVoice(VoiceInitParams(song.tracks[v], na, pi.pos[v], this)); } super(a, pi); } override void refresh() { foreach(v; voices) { (cast(TrackVoice)v).refreshTrack(posTable.pointerOffset); v.refresh(); } } override protected void doStep(bool wrapOk, int r) { foreach(v; voices) { bool wrap = wrapOk; v.scroll(r,wrap); } } override int keypress(Keyinfo key) { if(key.mods & KMOD_CTRL) { switch(key.raw) { default: break; } } switch(key.raw) { case SDLK_DOWN, SDLK_PAGEDOWN: activeVoice.trackFlush(posTable.pointerOffset); if(activeVoice.atEnd()) return OK; int r = activeVoice.activeRow.seq.rows; step(r,area.height - 1,area.height); centerTo(tableBot); refresh(); return OK; case SDLK_UP, SDLK_PAGEUP: activeVoice.trackFlush(posTable.pointerOffset); int t = activeVoice.activeRow.trkOffset; if(t == 0) t = activeVoice.tracks.trackLength; RowData s = activeVoice.getRowData(t - 1, 0); step(-s.seq.rows, 0, area.height); centerTo(tableBot); refresh(); return OK; default: return super.keypress(key); } } @property void displayTracklist(bool toggleOrDisable) { foreach(voice; voices) { TrackVoice tv = cast(TrackVoice)voice; if(!toggleOrDisable) tv.displayTracklist = false; else tv.displayTracklist ^= 1; } } } CheeseCutter-2.10/src/ui/000077500000000000000000000000001516216315000152235ustar00rootroot00000000000000CheeseCutter-2.10/src/ui/dialogs.d000066400000000000000000000402151516216315000170140ustar00rootroot00000000000000/* CheeseCutter v2 (C) Abaddon. Licensed under GNU GPL. */ module ui.dialogs; import derelict.sdl2.sdl; import main; import com.fb; import com.util; import com.session; private import ct.base; import ui.help; import ui.ui; import ui.input; import std.algorithm; import std.string; import std.file; import std.utf; import std.array; import std.stdio; import std.process; abstract class QueryDialogBase(T) : Window { string query; ubyte[1] byt; alias void delegate(T) Callback; Callback callback; protected int frameWidth; this(string s, Callback fp) { super(Rectangle(0, 0, 1)); query = s; callback = fp; frameWidth = cast(int)query.length; } override void update() { int x = cast(int)(screen.width / 2 - (frameWidth + 6)/2); int y = cast(int)(screen.height / 2 - 11); drawFrame(Rectangle(x, y, 5, frameWidth + 9)); screen.cprint(x + 4, y + 2, 15, 0, query); input.setCoord(cast(int)(x + 4 + query.length), cast(int)( y + 2)); } override void activate() { return; } } class QueryDialog : QueryDialogBase!int { const int maxValue; this(string s,Callback fp, int m) { super(s, fp); input = new InputBoundedByte(byt); maxValue = m; } override int keypress(Keyinfo key) { if(key.mods & KMOD_ALT) return OK; int r = input.keypress(key); if(r == WRAP && (cast(InputBoundedByte)input).value >= maxValue) { input.setOutput(cast(ubyte[])[maxValue - 1]); return OK; } else if(r == RETURN) { input.nibble = 0; callback(input.toInt()); } else if(r == CANCEL) { // no callback } else r = OK; if(input.value >= maxValue) input.setOutput(cast(ubyte[])[maxValue - 1]); return r; } } class ConfirmationDialog : QueryDialogBase!int { this(string title, Callback cb, string keys, int defaultkey) { super(title, cb); input = new InputSingleChar(byt, keys, defaultkey); } this(string title, Callback cb) { this(title, cb, "yn", 1); } override int keypress(Keyinfo key) { if(key.mods & KMOD_ALT) return OK; int r = input.keypress(key); if(r == CANCEL) return CANCEL; // just close dialog if(r == RETURN) { // received legal key callback(input.toInt); return RETURN; } return OK; } } class StringDialog : QueryDialogBase!string { int inputLength; this(string query,Callback fp, string inp, int length) { super(query, fp); input = new InputString(inp, length); this.inputLength = length; frameWidth = cast(int)query.length + inputLength; } override int keypress(Keyinfo key) { if(key.mods & KMOD_ALT) return OK; int r = input.keypress(key); if(r == CANCEL) return CANCEL; // just close dialog if(r == RETURN) { input.nibble = 0; callback((cast(InputString)input).toString(false)); return RETURN; } return OK; } } class HelpDialog : Window { enum MAX_LINE_LENGTH = 80; string[][] pages; const string title; int numpages; int page = 1; int txt_x; this(Rectangle a, ContextHelp ctx) { super(a); pages.length = ctx.text.length; foreach(i,page; ctx.text) { pages[i] = std.string.splitLines(page); } numpages = cast(int)pages.length; // deprecate title = ctx.title; txt_x = area.x + (area.width / 2 - MAX_LINE_LENGTH / 2); } override void update() { int ypos = area.y + 2; drawFrame(area); screen.cprint(area.x + 2, area.y, 1, 0, format(" %s %d/%d (press SPACE for more) ", title, page,numpages)); screen.cprint(area.x + 1, area.y + 2, 1, 0, std.array.replicate(" ", area.width-3)); foreach(line; pages[page-1]) { screen.cprint(area.x+1, ypos, 1, 0, std.array.replicate(" ", area.width-3)); screen.fprint(txt_x, ypos, "`0f" ~ line); ypos++; } for(; ypos < 36; ypos++) { screen.cprint(area.x+1, ypos, 1, 0, std.array.replicate(" ", area.width-2)); } } override int keypress(Keyinfo key) { int k = key.key; if(k == SDLK_SPACE || k == SDLK_PLUS || k == SDLK_RIGHT || k == SDLK_PAGEDOWN) if(page++ >= numpages) page = 1; if(key.unicode == SDLK_RETURN || key.unicode == SDLK_ESCAPE) return RETURN; return OK; } } class DebugDialog : Window { Sequence seq; this(Sequence s) { super(Rectangle(screen.width / 2 - 24, screen.height / 2 - 10, 20, 55)); seq = s; } this(Rectangle a) { super(a); } override void update() { assert(seq !is null); ubyte[] data = seq.compact(); data.length = 256; int y,pos; string str; drawFrame(area); for(y=0;y= filelist.length) cursorEnd(); } } void reset() { fpos.offset = fpos.pos = 0; } override void update() { int y, i; for(y = area.y, i = 0; i < area.height; y++,i++) { int ofs = fpos.offset + i; string fs = null; int col = 15; if(ofs < filelist.length) { File f = filelist[ofs]; auto ind = 1+f.name.lastIndexOf(DIR_SEPARATOR); if( ofs < 2 || (f.exists && f.isdir) ) { col = 13; } fs = fstr(format(" %s", f.name[ind..$].leftJustify(area.width-2))); } screen.cprint(area.x+5,y,col,0,fs); } } void blink() { int y = area.y + fpos.pos; auto ind = 1 + filelist[num].name.lastIndexOf(DIR_SEPARATOR); screen.fprint(area.x+5,y,fstr("`b1 " ~ filelist[num].name[ind..$].leftJustify(area.width-3)) ~ " "); } int fileHandler() { if(isDir(selected)) { string s; if(selected == ".." ) { int i = cast(int) directory.lastIndexOf(DIR_SEPARATOR); if(i >= 0) { s = directory[0..i]; if(s.lastIndexOf(DIR_SEPARATOR) < 0) { s ~= DIR_SEPARATOR; } directory = s; } } else if(selected != ".") { directory = cast(string)(selected.dup); } reset(); refresh(); return OK; } return RETURN; } override int keypress(Keyinfo key) { switch(key.raw) { case SDLK_UP: step(-1); return WRAP; case SDLK_DOWN: step(1); return WRAP; case SDLK_PAGEUP: step(-area.height); return WRAP; case SDLK_PAGEDOWN: step(area.height); return WRAP; case SDLK_HOME: reset(); return WRAP; case SDLK_END: cursorEnd(); return WRAP; default: break; } return OK; } char[][] listdir(string udir) { char[][] ret; auto app = appender(ret); foreach (DirEntry e; dirEntries(udir, SpanMode.shallow)){ app.put( e.name.dup ); } return app.data; } void getdir(string udir) { char[][] dir; char[][] dirs, files; dir = listdir(udir); dirs.length = dir.length+2; files.length = dir.length; int idxd, idxf; foreach(i, d; dir) { char[] first = d[0..1]; // skip hidden / temp files if(first == "." || first == "#") continue; try { if(d.isDir()) { dirs[idxd++] = d; } else { files[idxf++] = d; } } catch(FileException) { // may occur if entry "d" does not // exist or is a dangling symlink continue; } } dirs.length = idxd; dirs.sort; files.length = idxf; files.sort; string[] all = cast(string[])(dirs ~ files); filelist.length = all.length + 2; filelist[0] = File(".", true, true); filelist[1] = File("..",true, true); for(int i = 0; i < all.length; i++) { filelist[i+2] = File(all[i], all[i].exists(), all[i].isDir()); } } // move the cursor to last entry & set scroll window pos void cursorEnd() { if(filelist.length >= area.height) { fpos.offset = cast(int)(filelist.length - area.height); fpos.pos = cast(int)(area.height-1); } else { fpos.offset = 0; fpos.pos = cast(int)(filelist.length - 1); } } void step(int st) { fpos.pos += st; if(fpos.pos >= filearea.height) { int r = fpos.pos-filearea.height; fpos.offset += r+1; fpos.pos -= r+1; if(num >= filelist.length && filelist.length > filearea.height) { fpos.offset = cast(int)(filelist.length - filearea.height); fpos.pos = cast(int)(filearea.height-1); } } else if(fpos.pos < 0) { int r = -fpos.pos; fpos.offset -= r; if(fpos.offset < 0) fpos.offset=0; fpos.pos += r; } if(num >= filelist.length) cursorEnd(); } @property string selected() { return filelist[num].name; } alias selected getSelected; private: @property int num() { return fpos.offset + fpos.pos; } string fstr(string fs) { if(fs.length > (area.width)) fs.length = area.width; return fs; } } // wraps inputstring class DialogString : Window { this(Rectangle a) { this(a, 50); } this(Rectangle a, int len) { input = new InputString("", len); input.setCoord(a.x, a.y); super(a); } override string toString() { return toString(false); } string toString(bool p) { return (cast(InputString)input).toString(p); } void setString(string s) { (cast(InputString)input).setOutput(s); } alias setString setOutputString; override void update() { input.update(); } override int keypress(Keyinfo key) { input.keypress(key); return OK; } } class FileSelectorDialog : WindowSwitcher { alias void delegate(string) CB; const CB callback; alias callback processFileCallback; private DialogString sfile, sdir; FileSelector fsel; private string header; private char[][] filelist; Rectangle filearea; this(Rectangle a, string h, CB cb) { header = h; if(a == Rectangle.init) { int dialog_width = screen.width - 32; int dialog_height = screen.height - 10; int dialog_x = screen.width / 2 - dialog_width / 2; int dialog_y = screen.height / 2 - dialog_height / 2; a = Rectangle(dialog_x, dialog_y, dialog_height, dialog_width); } filearea = Rectangle(a.x + 5, a.y + 2, a.height - 6, a.width - 10); fsel = new FileSelector(Rectangle(a.x + 5, a.y + 2, a.height - 6, a.width - 18)); sfile = new DialogString(Rectangle(a.x+3+11, a.y+a.height-2), 50); sdir = new DialogString(Rectangle(a.x+3+11, a.y+a.height-3), 50); sdir.setString(getcwd()); super(a, [cast(Window)fsel, sdir, sfile]); activateWindow(0); callback = cb; } void setFilename(string s) { sfile.setString(cast(string)s.dup); } void setDirectory(string s) { fsel.directory = cast(string)s.dup; sdir.setString(cast(string)s.dup); } @property string filename() { return sfile.toString(); } @property string fullname() { return getcwd() ~ DIR_SEPARATOR ~ sfile.toString(); } @property string directory() { return fsel.directory; } override void activate() { refresh(); fsel.refresh(); } override void refresh() { update(); } override void update() { int x,y,i; for(y = area.y; y < area.y+area.height; y++) { screen.cprint(area.x, y, 1, 0, std.array.replicate(" ",area.width)); } drawFrame(area); x = area.x + 3; y = area.y + 2; screen.cprint(x,area.y,1,0," " ~ header ~ " "); screen.fprint(x,area.y+area.height-3,format("`0fDirectory: `0d%s",sdir.toString())); string f = sfile.toString(); int ind = cast(int) (1+f.lastIndexOf(DIR_SEPARATOR)); screen.fprint(x,area.y+area.height-2,format("`0f Filename: `0d%s",f[ind..$])); activeWindow.update(); if(activeWindow == fsel) { fsel.blink(); } else { fsel.update(); } input = activeWindow.input; } override int keypress(Keyinfo key) { if(key.mods && !key.mods & KMOD_SHIFT) return OK; switch(key.raw) { case SDLK_TAB: return super.keypress(key); case SDLK_ESCAPE: return RETURN; case SDLK_RETURN: return returnPressed(callback); default: int r = activeWindow.keypress(key); if(r == WRAP){ int ind = cast(int) (1 + fsel.getSelected().lastIndexOf(DIR_SEPARATOR)); sfile.setString(cast(string)(fsel.getSelected()[ind..$])); } break; } return OK; } protected int returnPressed(CB cb) { if(activeWindow == fsel) { int r = fsel.fileHandler(); if(r == RETURN) cb(cast(string)(fsel.selected)); sdir.setString(getcwd()); return r; } else if(activeWindow == sfile) { // pressed RETURN in file dialog //string filename = getcwd() ~ DIR_SEPARATOR ~ sfile.toString(); cb(fullname); return RETURN; } else { fsel.directory = sdir.toString(); fsel.reset(); fsel.refresh(); } return OK; } } class LoadFileDialog : FileSelectorDialog { CB cbimport; this(Rectangle a, CB cbload, CB cbimp) { super(a, "Load Song", cbload); cbimport = cbimp; } override protected int returnPressed(CB cb) { if(activeWindow != fsel && activeWindow != sfile) return super.returnPressed(cb); if(std.file.exists(fullname) && !std.file.isDir(fullname) && shouldUpgrade(fullname)) { mainui.activateDialog(new ConfirmationDialog("Upgrade to latest player (Y/n)? ", &confirmCallback, "yn", 0)); return OK; } else return super.returnPressed(cb); } private bool shouldUpgrade(string fn) { try { Song newsong = new Song(); newsong.open(fn); return SONG_REVISION > newsong.ver; } catch(Exception e) { return false; } return true; } private void confirmCallback(int param) { auto cb = param ? callback : cbimport; if(activeWindow == fsel) { int r = fsel.fileHandler(); if(r == RETURN) cb(cast(string)(fsel.selected)); sdir.setString(getcwd()); } else if(activeWindow == sfile) { // pressed RETURN in file dialog string filename = getcwd() ~ DIR_SEPARATOR ~ sfile.toString(); cb(filename); } } } class SaveFileDialog : FileSelectorDialog { this(Rectangle a, CB cb) { super(a, "Save Song", cb); activateWindow(2); } override protected int returnPressed(CB cb) { if(activeWindow != fsel && activeWindow != sfile) return super.returnPressed(cb); if(std.file.exists(fullname) && !std.file.isDir(fullname)) { mainui.activateDialog(new ConfirmationDialog("Overwrite destination file (y/N)? ", &confirmCallback)); return OK; } else return super.returnPressed(cb); } private void confirmCallback(int param) { if(param != 0) return; // copypasted from super.returnPressed, ugh... // need to implement getSelectedFilename to cut repetition if(activeWindow == fsel) { int r = fsel.fileHandler(); if(r == RETURN) processFileCallback(cast(string)(fsel.selected)); sdir.setString(getcwd()); } else if(activeWindow == sfile) { // pressed RETURN in file dialog string filename = getcwd() ~ DIR_SEPARATOR ~ sfile.toString(); processFileCallback(filename); } } } CheeseCutter-2.10/src/ui/help.d000066400000000000000000000153701516216315000163260ustar00rootroot00000000000000/* CheeseCutter v2 (C) Abaddon. Licensed under GNU GPL. */ module ui.help; import std.string : format; import com.util; struct ContextHelp { string title; string[] text; } ContextHelp HELPMAIN = ContextHelp("Main help", [" Escape (x2).....Quit program F10.............Open the Load song dialog F11.............Open the Save song dialog F9..............Open the About dialog Ctrl-F11........Quick save song (doesn't ask a filename) `+dPlayback\n F1..............Play from playback mark Shift-F1........Play / resume from mark with tracking F2..............Play from the start Shift-F2........Play / resume from the start with tracking F3..............Play from cursor position F4..............Stop playback F8..............Fast forward (w/ Shift = Fast forward more) Scroll Lock.....Start/stop tracking (works only when playing) Ctrl-1,2,3......Toggle voices on/off Ctrl-F9.........Show/hide playback info (works only when playing) `+dSong variables\n Ctrl-Keypad - +.........Decrease/increase default song speed [ ] (AltGr-8 / AltGr-9).Decrease/increase default song speed Alt-Keypad - +..........Decrease/increase multispeed framecall counter { } (AltGr-7 / AltGr-0).Decrease/increase multispeed framecall counter Ctrl-F3.................Toggle SID type (6581/8580) Ctrl-F8.................Select next SID filter preset Ctrl-Shift-F8...........Select previous SID filter preset Alt-T...................Edit title / author / release info Ctrl-Alt-C..............Clear sequences (press TWICE to activate) Ctrl-Alt-O..............Optimize (clear unused sequences & data) ", " `+dMoving between tables\n Tab.....................Move cursor between subwindows Ctrl-Tab................Move cursor between main windows (sequencer, instrument table, subtables) Alt-V...................Jump to Sequencer Alt-I...................Jump to Instrument table Alt-M...................Jump to Cmd table Alt-P...................Jump to Pulse table Alt-F...................Jump to Filter table Alt-D...................Jump to Chord table Alt-1, 2, 3.............Jump to voice 1, 2 or 3 Alt-4-8 can also move between tables (in the aforementioned order, so Alt-4 = Sequencer, Alt-5 = Ins, ...) `+dInstrument table functions\n Ctrl-L..................Load current insturment from disk Ctrl-S..................Save current instrument to disk Ctrl-D..................Delete current instrument Ctrl-C..................Copy instrument to clipboard Ctrl-V..................Paste instrument from clipboard `+dPlayer reference\n Check out the player reference guide from the CheeseCutter homepage. `+dCheeseCutter homepage: http://theyamo.kapsi.fi/ccutter "]); ContextHelp HELPSEQUENCER = ContextHelp("Sequencer help", ["`+1Press F12 again to see the global help. `+dGeneral Alt-1,2,3...............Jump to voice 1, 2 or 3 Tab.....................Move cursor to the next voice Keypad / *..............Decrease/increase base octave value Ctrl-Keypad - +.........Decrease/increase default song speed [ ] (AltGr-8 / AltGr-9).Decrease/increase default song speed Keypad - +..............Decrease/increase active instrument number Keypad 1-9..............Set cursor step value (used when entering notes) Alt-Left/Right..........Activate previous/next subtune F5......................Enter to the track column Shift-F5................Display tracks alongside the sequences F6......................Enter to the note column F7......................Display tracks only ('overview mode') Home/End................Move cursor to SEQ start/end OR screen top/bottom Shift-Home/End..........Move cursor to song start/end Backspace...............Set playback start mark (the blue bar) to current position Ctrl-Home/Ctrl-H........Jump to playback mark position (also realigns the voices) Ctrl-Z..................Undo Ctrl-R..................Redo Alt-C...................Ask for a SEQ number and copy contents over current SEQ Alt-A...................Ask for a SEQ number and insert contents to cursor pos (Shift-)Insert/Delete...Insert/delete a row (Shift=w/ sequence expand/shrink) Ctrl-Insert/Delete......Expand/shrink the sequence Shift-Enter.............Quick expand sequence (expands by highlight value * 4) Ctrl-Q/A................Transpose semitone up/down ","Ctrl-W/S................Transpose octave up/down Ctrl-M/N................Increase/decrease row highlight value Ctrl-0(zero)............Reset highlighting to current row Ctrl-E..................Show/hide row counters for sequences Ctrl-T..................Toggle notes relative to current transpose Keypad 0................Play notes for all voices in current row Ctrl-P..................Split current sequence into two from cursor pos. `+dUse with caution. `+dIn the note column (F6) 2 3 5 6 7 9 0 Q W E R T Y U I O P.....Enter notes (base octave+1) S D G H J Z X C V B N M...........Enter notes (base octave) 1.......................Enter a gate off (===) A or !..................Enter a gate on (+++) Space or '.'............Clear Space...................Insert previously entered instrument/command value (in instrument/command column only) - +.....................Decrease/increase base octave ';'.....................Toggle insert instrument value automatically-mode ','.....................Change the note in current row to a tie note Enter...................Grab the instrument value in the current row `+dIn the track column (F5) Ctrl-F..................Find next unused sequence starting from current value < >.....................Select previous/next sequence Ctrl-Q/A................Transpose all tracks up/down from cursor down ", "`+dIn the track column (F5) (cont.) Ctrl-C..................Ask for a number and copy the N of tracks into clipboard Ctrl-V..................Paste copied tracks from the clipboard Space...................Write the cached sequence number to the track value Insert/Delete...........Insert empty track (A000) or delete track from cursor pos down Ctrl-Enter..............Insert a track to end of voice and move cursor there Ctrl-Insert/Delete......Insert/delete track to end of voice and move cursor there Ctrl-Shift-Insert/Del...Insert/delete a track for all voices Ctrl-Alt-1..............Swap voice's track with voice 1's tracks from crsr down Ctrl-Alt-2..............Swap voice's track with voice 2's tracks from crsr down Ctrl-Alt-3..............Swap voice's track with voice 3's tracks from crsr down "]); ContextHelp genPlayerContextHelp(string title, char*[] descriptions) { string text; text = "`+1Press F12 again to see the global help.\n\n`+d" ~ title ~ "\n"; foreach(idx, char* line; descriptions) { text ~= format("\n`0fByte %d: %s", idx + 1, petscii2D(line)); } text ~= "\n\nPress Alt-H to turn the byte descriptions off."; ContextHelp ctx = ContextHelp(title, [text]); return ctx; } CheeseCutter-2.10/src/ui/input.d000066400000000000000000000506301516216315000165330ustar00rootroot00000000000000/* CheeseCutter v2 (C) Abaddon. Licensed under GNU GPL. */ module ui.input; import derelict.sdl2.sdl; import com.fb; import com.session; import com.util; import ct.base; import seq.sequencer; import audio.player; import ui.ui; import std.string; import std.utf; import std.stdio : stderr; import std.conv; enum { RETURN = -1, CANCEL = -2, OK = 0, WRAP = 1, WRAPR, WRAPL, EXIT, IllegalValue } alias ValueChangedCallback = void delegate(); mixin template ValueChangedHandler() { private ValueChangedCallback valueChangedCallback = null; private void valueChanged() { if(valueChangedCallback !is null) valueChangedCallback(); } void setValueChangedCallback(ValueChangedCallback cb) { this.valueChangedCallback = cb; } } struct Keyinfo { int key, mods, unicode; alias key raw; } class Cursor { enum BLINK_VAL = 8; int x = -1, y = -1; private { int counter; int bg2, fg2; int bg, fg; } void set() { set(x,y); } alias set refresh; void set(int nx, int ny) { if(nx < 0 || ny < 0) return; if(x != nx || y != ny) { x = nx; y = ny; ushort col = screen.getChar(x, y); counter = BLINK_VAL; bg = fg2 = (col >> 8) & 15; fg = bg2 = (col >> 12) & 15; } screen.setColor(x,y,bg2,fg2); } void reset() { counter = BLINK_VAL; bg2 = fg; fg2 = bg; } void blink() { if(--counter < 0) { int t; counter = BLINK_VAL; t = bg2; bg2 = fg2; fg2 = t; } } } class Input { mixin ValueChangedHandler; Cursor cursor; const int width; int x, y, nibble; alias x pointerX; alias y pointerY; alias width inputLength; ubyte[] inarray, outarray; this(ubyte[] p, int len) { this(len); setOutput(p); } this(int len) { cursor = new Cursor(); width = len; inarray.length = len; } void setOutput(ubyte[] p) { outarray = p; } void setCoord(int nx, int ny) { if(nx) x = nx; if(ny) y = ny; } alias setCoord set; int keypress(Keyinfo key) { return 0 ;} int keyrelease(Keyinfo key) { return 0; } int setValue(int v) { assert(0); } int step(int st) { nibble += st; if(nibble < 0) { nibble = inputLength - 1; return WRAP; // should return WRAPL } else if(nibble >= inputLength) { nibble = 0; return WRAP; } return OK; } void update() { assert(0); } void refresh() { assert(0); } int toInt() { return toInt(inarray); } @property int value() { return toInt(inarray); } int toInt(ubyte[] ar) { int v; for(int i = cast(int)(ar.length-1), sh; i >= 0; i--) { v |= ar[i] << sh; sh += 4; } return v; } int toIntRange(int b, int e) { return toInt(inarray[b..e]); } private: int valueKeyReader(Keyinfo key, char[] keytab) { foreach(i, k; keytab) { if(key.raw == k) return cast(int)i; } return -1; } int keypressStepHandler(Keyinfo key, char[] keytab) { int v = valueKeyReader(key, keytab); if(v >= 0) { int r = setValue(v); // if 'setValue' returns > 0, don't step if(r) return r; // if shift is pressed, don't step if(key.mods & KMOD_SHIFT) return OK; return step(1); } return OK; } } class InputValue : Input { this(ubyte[] p, int len) { super(p, len); } override void setOutput(ubyte[] p) { super.setOutput(p); // initialize value for(int i=0; i < inputLength; i++) { int j = i / 2; int sh = (i & 1) ? 0 : 4; inarray[i] = (p[j] >> sh) & 15; } } override int keypress(Keyinfo key) { int v; if(key.mods & KMOD_CTRL) return 0; if(key.raw == SDLK_RETURN) return RETURN; else if(key.raw == SDLK_ESCAPE) return CANCEL; return keypressStepHandler(key, cast(char[])"0123456789abcdef"); } override int setValue(int v) { valueChanged(); inarray[nibble] = cast(ubyte)v; int c = toInt(); for(int i = cast(int)(inputLength/2-1); i >= 0; i--) { outarray[i] = c & 255; c >>= 8; } return OK; } override void update() { string fmt = std.string.format("0%dX",inputLength); screen.cprint(x, y, 1, -1, format("%" ~ fmt,toInt())); cursor.set(x + nibble, y); } } class InputByte : InputValue { this(ubyte[] p) { super(p, 2); } } class InputBoundedByte : InputValue { this(ubyte[] p) { super(p, 2); } override int keypress(Keyinfo key) { int v; if(key.mods & KMOD_CTRL) return 0; if(key.raw == SDLK_RETURN) return RETURN; else if(key.raw == SDLK_ESCAPE) return CANCEL; switch(key.raw) { case SDLK_LEFT: return step(-1); case SDLK_BACKSPACE: step(-1); setValue(0); return OK; case SDLK_RIGHT: return step(1); default: if(nibble < 2) return keypressStepHandler(key, cast(char[])"0123456789abcdef"); return OK; } } override int step(int st) { nibble += st; if(nibble < 0) nibble = 0; else if(nibble > 2) nibble = 2; return OK; } override void update() { screen.cprint(x, y, 1, -1, format("%02X ", toInt())); cursor.set(x + nibble, y); } } class InputSingleChar : InputValue { string keys; int defaultKey; this(ubyte[] p, string keys, int defaultKey) { super(p, 2); this.keys = keys; setValue(0); this.defaultKey = defaultKey; } override int keypress(Keyinfo key) { auto v = keys.indexOf(key.raw); if(key.mods & KMOD_CTRL) return 0; else if(key.raw == SDLK_ESCAPE) { return CANCEL; } else if(key.raw == SDLK_RETURN) { setValue(cast(ubyte)defaultKey); return RETURN; } else if(v >= 0) { setValue(cast(ubyte)(v)); return RETURN; } return IllegalValue; } override int step(int st) { return OK; } override void update() { //screen.cprint(x, y, 1, -1, format("%02X ", toInt())); screen.cprint(x + nibble, y, 1, -1, std.conv.to!string(keys[defaultKey])); cursor.set(x + nibble, y); } } class InputWord : InputValue { this(ubyte[] p) { super(p, 4); } } class InputTrack : InputWord { Track trk; ubyte[2] buf; this(RowData s, ValueChangedCallback cb) { super(buf); init(s); trk.setValue(buf[0], buf[1]); valueChangedCallback = cb; } void init(RowData s) { trk = s.trk; buf[] = valueCheck(trk.trans, trk.number); super.setOutput(buf); } alias init refresh; void flush() { if(trk.number != buf[1] || trk.trans != buf[0]) valueChanged(); trk.setValue(buf[0], buf[1]); } override int setValue(int v) { super.setValue(v); buf[] = valueCheckNoWrap(buf[0], buf[1]); super.setOutput(buf); return OK; } override int keypress(Keyinfo key) { if(key.mods & KMOD_ALT) return OK; switch(key.unicode) { case 6: // ctrl-f int s = song.getFreeSequence(buf[1] + 1); if(s > 0) buf[] = valueCheck(buf[0], s); setOutput(buf); flush(); break; case SDLK_LESS: int i = buf[1] - 1; buf[] = valueCheck(buf[0], i); setOutput(buf); flush(); break; case SDLK_GREATER: int i = buf[1] + 1; buf[] = valueCheck(buf[0], i); setOutput(buf); flush(); break; default: break; } switch(key.raw) { case SDLK_LEFT: if(--nibble < 0) { nibble = inputLength - 1; return WRAPL; } return OK; case SDLK_RIGHT: if(++nibble >= inputLength) { nibble = 0; return WRAPR; } return OK; case SDLK_SPACE: flush(); return OK; default: break; } if(buf[0] < 0xc0) { int r = super.keypress(key); return r; } return OK; } private: ubyte[] valueCheck(int tr, int no) { if(tr < 0x80) tr = 0x80; if(no < 0) no = 0; if(no > 0x80) no = 0x00; if(no >= MAX_SEQ_NUM) no = MAX_SEQ_NUM-1; return cast(ubyte[])[tr,no]; } // don't allow wrapmark ubyte[] valueCheckNoWrap(int tr, int no) { ubyte[] b = valueCheck(tr, no); if(b[0] > 0xbf) b[0] = 0xbf; return b; } } class InputString : Input { char[] instring; this(string s) { this(s, 80); } this(string s, int len) { super(len); setOutput(s); } override void setOutput(ubyte[] p) { assert(0); } void setOutput(string s) { int tl = cast(int)s.length; char[] str2 = std.utf.toUTF8(s.dup).dup; str2.length = inputLength; if(tl >= inputLength) tl = inputLength; str2[tl .. $] = ' '; instring = str2; nibble = stringLength; if(nibble >= inputLength) nibble = inputLength - 1; } override string toString() { return toString(false); } string toString(bool pad) { if(!pad) return cast(string)(instring[0..stringLength].dup); return cast(string)(instring); } override void update() { screen.cprint(x, y, 1, 0, toString(true)); cursor.set(x + nibble, y); } void setChar(dchar value) { instring[nibble] = cast(char)value; } override int keypress(Keyinfo key) { int i; switch(key.raw) { case SDLK_LEFT: if(step(-1)) nibble = 0; break; case SDLK_RIGHT: if(step(1)) nibble = inputLength-1; break; case SDLK_BACKSPACE: if(step(-1)) { nibble = 0; break; } goto case SDLK_DELETE; case SDLK_DELETE: instring[nibble .. $-1] = instring[nibble+1 .. $].dup; instring[$-1] = ' '; break; // slightly bugs when str.length == inputLength case SDLK_HOME: nibble = 0; break; case SDLK_END: nibble = stringLength; if(nibble >= inputLength) nibble = inputLength - 1; break; case SDLK_RETURN: return RETURN; case SDLK_ESCAPE: return CANCEL; default: void insert() { instring[nibble+1 .. $] = instring[nibble .. $-1].dup; } if(key.raw == SDLK_INSERT) { insert(); setChar(' '); } else if(key.unicode && key.unicode != '`') { string old = cast(string)(instring.dup); insert(); setChar(key.unicode); try { validate(instring); } catch(UTFException e) { stderr.writeln(e.toString); instring = old.dup; break; } if(step(1) == WRAP) nibble = inputLength - 1; } break; } return OK; } @property int stringLength() { for(int i = inputLength - 1; i >= 0; i--) { if(instring[i] != ' ') return i+1; } return 0; } } abstract class ExtendedInput : Input { protected { int nibble, memvalue; Element element; } int invalue; bool changed; //bool valueChanged() { return changed; } /+ protected this() { super(1); } protected this(int w) { super(w); } +/ this(ValueChangedCallback cb) { this(1, cb); } this(int w, ValueChangedCallback cb) { this.valueChangedCallback = cb; super(w); } override int step(int st) { nibble += st; if(nibble >= width) { nibble = width - 1; return WRAPR; } else if(nibble < 0) { nibble = 0; return WRAPL; } return OK; } override int keypress(Keyinfo key) { return keypress(key, "0123456789abcdef"); } int keypress(Keyinfo key, string keytab) { if(key.mods & KMOD_CTRL || key.mods & KMOD_ALT) return OK; switch(key.unicode) { case ' ': if(memvalue >= 0) { changed = (invalue != memvalue); invalue = memvalue; valueChanged(); setRowValue(memvalue); return WRAP; } goto case '.'; case '.': valueChanged(); clearRow(); return WRAP; default: if(keytab == null) return WRAP; int value = valueKeyReader(key, keytab); if(value < 0) { changed = false; return OK; } return valuekeyHandler(value); } //not reached } protected: int valuekeyHandler(int value) { if(width == 1) invalue = value; else { if(nibble == 0) { invalue &= 0x0f; invalue |= value << 4; } else { invalue &= 0xf0; invalue |= value & 255; } } valueChanged(); setRowValue(invalue); memvalue = invalue; if(++nibble >= width) { nibble = 0; invalue = 0; return WRAP; } return OK; } void clearRow() { memvalue = -1; } void setRowValue(int value) { } void setElement(Element e) { element = e; } override void update() { assert(0); } static int valueKeyReader(Keyinfo key, const char[] keytab) { foreach(i, k; keytab) { if(key.raw == k) { if(key.mods & KMOD_SHIFT) return cast(int)(i | 0x80); return cast(int)i; } } return -1; } } class InputOctave : ExtendedInput { this(ValueChangedCallback cb) { super(1, cb); } override int keypress(Keyinfo key) { return super.keypress(key,"012345678"); } override void setRowValue(int value) { if(element.note.value >= 3) { int note = ((element.note.value + element.transpose) % 12) + value * 12 - element.transpose; if(note >= 3 && note < 0x5f) element.note = cast(ubyte)note; } } } class InputInstrument : ExtendedInput { this(ValueChangedCallback cb) { super(2, cb); } override void clearRow() { super.clearRow(); element.instr = 0xc0; invalue = 0x30; } override void setElement(Element e) { super.setElement(e); if(e.instr.value < 0x30) invalue = e.instr.value; else invalue = 0; } override int keypress(Keyinfo key) { switch(key.unicode) { case SDLK_RETURN: if(element.instr.value < 0x30) mainui.activateInstrumentTable(element.instr.value); break; default: break; } return super.keypress(key); } override void setRowValue(int v) { element.instr = cast(ubyte)v; UI.activateInstrument(v); } } class InputCmd : ExtendedInput { this(ValueChangedCallback cb) { super(2, cb); } override void clearRow() { super.clearRow(); element.cmd = 0; } override void setElement(Element e) { super.setElement(e); invalue = e.cmd.rawValue; } override void setRowValue(int v) { element.cmd = cast(ubyte)v; } } class InputNote : ExtendedInput { InputKeyjam keyjam; private bool noteStarted = false; this(ValueChangedCallback cb) { super(1, cb); keyjam = new InputKeyjam(); } override int keyrelease(Keyinfo key) { import audio.player; if(!noteStarted || audio.player.getPlaystatus() == Status.Play) return OK; noteStarted = false; Element emt = Element([0x00,cast(ubyte)(0xc0+state.activeInstrument),1]); audio.player.playNote(emt); return OK; } override int keypress(Keyinfo key) { if(key.mods & KMOD_CTRL || key.mods & KMOD_ALT) { switch(key.raw) { case SDLK_g: if(element.instr.value < 0x30) UI.activateInstrument(element.instr.value); break; default: break; } return OK; } switch(key.unicode) { case SDLK_RETURN: if(element.instr.value < 0x30) UI.activateInstrument(element.instr.value); break; case SDLK_COMMA: if(element.note.value >= 3 && element.note.value < 0x5f) { valueChanged(); element.note.setTied(element.note.isTied() ? false : true); } return WRAP; case ' ', '.': valueChanged(); clearRow(); return WRAP; /+ case SDLK_SEMICOLON: if(element.note.rawValue >= 3 && element.note.rawValue < 0x5f) element.note.setTied(false); return WRAP; +/ default: break; } int r = super.keypress(key,"1!azsxdcvgbhnjmq2w3er5t6y7ui9o0p"); // r will be > 0 (in 'wrap') if valid data was entered if(r) { keyjam.element.transpose = element.transpose; keyjam.keypress(key); noteStarted = true; } // no cache for notecolumn memvalue = -1; return r; } override void clearRow() { super.clearRow(); element.note = 0; element.note.setTied(false); element.instr = 0x80; element.cmd = 0; } override void setRowValue(int value) { if(value < 0) return; switch(value) { case 0: element.note = NOTE_KEYOFF; element.note.setTied(false); element.instr = 0x80; break; case 2: case 0x80: element.note = NOTE_KEYON; element.note.setTied(false); element.instr = 0x80; break; default: int note = ((value - 3) & 0x7f) + 12 * state.octave - element.transpose; if(note > 0x5e) break; element.note = cast(ubyte)note; if(state.autoinsertInstrument && value < 0x80) { if(state.activeInstrument >= 0) element.instr = cast(ubyte)(state.activeInstrument); else element.instr = 0x80; } if(value >= 0x80) { element.note.setTied(true); } else element.note.setTied(false); break; } } override int step(int st) { if(st >= 0) return WRAPR; return WRAPL; } } class InputKeyjam : ExtendedInput { ubyte[4] dummy; this() { element = Element(dummy); super(1, null); } override void setRowValue(int value) { if(value < 0) return; switch(value) { case 0: element.note = NOTE_KEYOFF; element.note.setTied(false); // element.instr = 0x80; break; case 2: case 0x80: element.note = NOTE_KEYON; break; default: int note = ((value - 3) & 0x7f) + 12 * state.octave; if(note > 0x5e) return; element.note = cast(ubyte)note; if(value >= 0x80) { element.note.setTied(true); } else element.note.setTied(false); break; } if(state.activeInstrument >= 0) element.instr = cast(ubyte)(state.activeInstrument); audio.player.playNote(element); } override int keypress(Keyinfo key) { return super.keypress(key,"1!azsxdcvgbhnjmq2w3er5t6y7ui9o0p"); } override int keyrelease(Keyinfo key) { return OK; } } final class InputSeq : ExtendedInput, Undoable { Element element; private { ExtendedInput inputNote, inputInstrument, inputCmd, inputOctave; } ExtendedInput[] inputters; ExtendedInput activeInput; int activeInputNo; alias activeInputNo activeColumn; enum columns = 3; this() { super(1, null); inputNote = new InputNote(&valueChanged); inputInstrument = new InputInstrument(&valueChanged); inputCmd = new InputCmd(&valueChanged); inputOctave = new InputOctave(&valueChanged); activeInput = inputNote; inputters = [inputNote, inputOctave, inputInstrument, inputCmd]; } void setPointer(int x, int y) { if(x >0) pointerX = x; if(y > 0) pointerY = y; } override void setCoord(int x, int y) { setPointer(x, y); } override void setElement(Element e) { element = e; activeInput.setElement(e); } override int keyrelease(Keyinfo key) { return activeInput.keyrelease(key); } override int keypress(Keyinfo key) { switch(key.unicode) { case SDLK_SEMICOLON: state.autoinsertInstrument ^= 1; UI.statusline.display(format("Instrument autoinsert mode %s", state.autoinsertInstrument ? "enabled." : "disabled.")); return OK; case SDLK_LESS: state.octave = clamp(--state.octave, 0, 6); break; case SDLK_GREATER: state.octave = clamp(++state.octave, 0, 6); break; default: break; } int r = activeInput.keypress(key); return r; } void valueChanged() { UndoValue v; import std.typecons; v.array = UndoValue.Array(activeInput.element.data.dup, element.data); com.session.insertUndo(this, v); } override protected final void undo(UndoValue entry) { ubyte[] data = entry.array.target; ubyte[] target = entry.array.source; target[] = data; } override protected final UndoValue createRedoState(UndoValue value) { value.array.target = value.array.source.dup; return value; } void columnReset(int foo) { if(foo == 0) { inputInstrument.nibble = 0; inputCmd.nibble = 0; activeInputNo = 0; activeInput = inputNote; } else { inputInstrument.nibble = 1; inputCmd.nibble = 1; activeInputNo = 3; activeInput = inputCmd; } } // nibble arg is for END key void columnReset(int foo, int nibble) { if(foo == 0) { inputInstrument.nibble = 0; inputCmd.nibble = 0; activeInputNo = 0; activeInput = inputNote; } else { inputInstrument.nibble = 1; inputCmd.nibble = nibble; activeInputNo = 3; activeInput = inputCmd; } } override int step(int st) { int r = activeInput.step(st); if(r == WRAPR) { //activeInput.nibble = 0; foreach(inp; inputters) { inp.nibble = 0; } activeInputNo++; if(activeInputNo >= inputters.length) { activeInputNo = 0; activeInput = inputters[activeInputNo]; return WRAPR; } activeInput = inputters[activeInputNo]; activeInput.nibble = 0; } else if(r == WRAPL) { foreach(inp; inputters) { inp.nibble = inp.width - 1; } activeInputNo--; if(activeInputNo < 0) { activeInputNo = cast(int)(inputters.length - 1); activeInput = inputters[activeInputNo]; return WRAPL; } activeInput.nibble = activeInput.width - 1; activeInput = inputters[activeInputNo]; } return OK; } override void update() { screen.cprint(pointerX, pointerY, 1, -1, element.toPlainString()); assert(activeInput == inputters[activeInputNo]); int xofs = [0, 2, 4, 7][activeInputNo]; cursor.set(pointerX + xofs + activeInput.nibble, pointerY); } } class InputSpecial : InputValue { this(ubyte[] p) { super(p, 5); } override void setOutput(ubyte[] p) { } override int setValue(int v) { inarray[nibble] = v & 15; return OK; } override void update() { static immutable offsets = [0, 2, 3, 5, 6]; screen.cprint(x, y, 1, -1, format("%01X-%02X %02X",inarray[0],toInt(inarray[1..3]),toInt(inarray[3..5]))); cursor.set(pointerX + offsets[nibble], pointerY); } } CheeseCutter-2.10/src/ui/tables.d000066400000000000000000000526771516216315000166630ustar00rootroot00000000000000/* CheeseCutter v2 (C) Abaddon. Licensed under GNU GPL. */ module ui.tables; import ui.ui; import ui.dialogs; import ui.input; import ui.help; import com.session; import com.util; import ct.purge; import derelict.sdl2.sdl; import std.string; import std.stdio : stderr; import std.file; import com.fb; import std.conv, std.array; abstract class Table : Window { mixin ValueChangedHandler; const int columns, rows, visibleRows; protected { ubyte[] data; int column, row, cursorOffset, viewOffset; } this(Rectangle a, ubyte[] tbl, int c, int r) { super(a); columns = c; rows = r; data = tbl; input = new InputByte(tbl[0..1]); visibleRows = a.height - 1; } override void refresh() { update(); } protected: void adjustView(); } private class HexTable : Table, Undoable { this(Rectangle a, ubyte[] tbl, int c, int r) { super(a,tbl,c,r); (cast(InputValue)input).setValueChangedCallback(&valueChangedCallback); } void valueChangedCallback() { saveState(false); } override void activate() { initializeInput(); } void initializeInput() { input.setCoord(area.x + 3 + column * 3, area.y + cursorOffset + 1); } alias initializeInput set; override protected void adjustView() { if(column >= columns) { column -= columns; } else if(column < 0) { column += columns; } if(row >= rows) { row = row - rows; } else if(row < 0) { row = rows + row; } assert(row >= 0); if(cursorOffset >= visibleRows) { int i = cursorOffset - visibleRows + 1; viewOffset += i; if(viewOffset >= rows) { viewOffset -= rows; } cursorOffset -= i; } if(cursorOffset < 0) { int i = -cursorOffset; viewOffset -= i; if(viewOffset < 0) viewOffset += rows; cursorOffset += i; } initializeInput(); } void stepColumn(int n) { column += n; adjustView(); showByteDescription(); } void setColumn(int n) { column = n; adjustView(); } void stepColumnWrap(int n) { column += n; if(column >= columns) { stepRow(1); } adjustView(); } void stepRow(int n) { seekRow(n + row); } void setCursorOffset(int r) { row += r - cursorOffset; cursorOffset = r; adjustView(); } void seekRow(int r) { cursorOffset += r - row; row = r; adjustView(); } void seekTableEnd() { } void deleteRow() { } void insertRow() { } void seekColumn(int c) { column = c; } override int keypress(Keyinfo key) { /+ if(key.mods & KMOD_CTRL || key.mods & KMOD_ALT || key.mods & KMOD_META) return OK; +/ if(key.mods & KMOD_CTRL || key.mods & KMOD_ALT || key.mods & KMOD_GUI) return OK; switch(key.raw) { case SDLK_LEFT: if(input.step(-1) == WRAP) { stepColumn(-1); } break; case SDLK_RIGHT: if(input.step(1) == WRAP) { stepColumn(1); } break; case SDLK_INSERT: insertRow(); break; case SDLK_DELETE: deleteRow(); break; case SDLK_DOWN: stepRow(1); break; case SDLK_UP: stepRow(-1); break; case SDLK_PAGEUP: stepRow(-PAGESTEP / 2); break; case SDLK_PAGEDOWN: stepRow(PAGESTEP / 2); break; case SDLK_HOME: if(cursorOffset > 0) setCursorOffset(0); else seekRow(0); break; case SDLK_END: if(cursorOffset < visibleRows - 1) setCursorOffset(visibleRows - 1); else seekTableEnd(); break; case SDLK_h: showByteDescription(); break; default: if(input.keypress(key) == WRAP) { stepColumnWrap(1); } break; } initializeInput(); return OK; } override void clickedAt(int x, int y, int button) { int rx = x - area.x; int ry = y - area.y; int c = (rx - 3) / 3; setCursorOffset(ry - 1); if(c >= columns) c = columns - 1; setColumn(c); } protected: override final UndoValue createRedoState(UndoValue value) { return createState(true); } override final void undo(UndoValue v) { // if array has 1 child, assume to be data for this table if(v.tableData.length == 1) { this.data[] = v.tableData[0]; } else { int idx; song.tableIterator((ct.base.Song.Table t) { t.data[0..$] = v.tableData[idx++][0..$]; }); } initializeInput(); } void showByteDescription() { } void showByteDescription(PetString pet) { if(song.ver < 9 || !state.displayHelp) return; string[] s = com.util.petscii2D(pet).splitLines(); string outstr = s[0]; if(s.length > 1) outstr ~= " `01[F12 for more]"; UI.statusline.display(format("Byte %d: %s", column + 1, outstr)); } bool highlightRow(int row) { return false; } void saveState(bool allTables) { auto v = createState(allTables); com.session.insertUndo(this, v); } private: UndoValue createState(bool allTables) { UndoValue v; if(allTables) { song.tableIterator((ct.base.Song.Table t) { v.tableData ~= t.data.dup; }); } else v.tableData = [data.dup]; return v; } } class InsValueTable : HexTable { private { static ubyte[8] instrBuffer; static char[32] instrName; int mark = -1; int width; FileSelectorDialog loadDialog; } this(Rectangle a) { width = com.fb.mode ? 32 : 16; super(a, song.instrumentTable, 8, 48); loadDialog = new FileSelectorDialog(Rectangle(), "Load Instrument", &loadCallback); } override void refresh() { data = song.instrumentTable; } override int keypress(Keyinfo key) { if(key.mods & KMOD_ALT) return OK; if(key.mods & KMOD_CTRL) { switch(key.raw) { case SDLK_c: foreach(i, ref buf; instrBuffer) { buf = data[row + i * 48]; } instrName[0..32] = insName(row)[]; UI.statusline.display("Instrument copied to buffer."); break; case SDLK_v: foreach(i, ref buf; instrBuffer) { data[i * 48 + row] = buf; } song.insLabels[row][] = instrName[]; initializeInput(); break; case SDLK_s: void delegate(string) dg = (string fn) { if(fn == "") return; if(!fnIsSane(fn)) { UI.statusline.display("Illegal characters in filename!"); return; } try { com.session.song.savePatch(fn, state.activeInstrument); } catch(UserException e) { stderr.writeln(e.toString); UI.statusline.display(e.toString); return; } UI.statusline.display(format("Saved instrument %d", state.activeInstrument)); }; string fn = fnClean(std.string.stripRight (std.conv.to!string(song.insLabels[row]))); if(fn.length == 0) fn = "unnamed"; try { chdir(loadDialog.directory); } catch(FileException e) { stderr.writeln(e); UI.statusline.display(format("Could not change to directory %40s",loadDialog.directory)); break; } mainui.activateDialog(new StringDialog("Enter filename: ", dg, fn ~ ".cti", 32)); break; case SDLK_l: mainui.activateDialog(loadDialog); break; case SDLK_d: void delegate(int) dg = (int param) { if(param != 0) return; (new Purge(song)).deleteInstrument(state.activeInstrument); }; mainui.activateDialog(new ConfirmationDialog("Delete current instrument (y/n)? ", dg)); break; case SDLK_x: break; default: break; } } int r = super.keypress(key); if(r == WRAP) { stepColumn(1); } return OK; } private void loadCallback(string fn) { if(!std.file.exists(fn)) { UI.statusline.display("File does not exist or is not accessible!"); return; } if(fn.indexOf(".cti") == -1) { UI.statusline.display("Not loading; possibly not an instrument def file."); return; } try { song.insertPatch(fn, state.activeInstrument); } catch(Exception e) { stderr.writeln(e.toString); UI.statusline.display("Error in parsing instrument data!"); } } string insName(int row) { assert(row >= 0 && row < 48); return format(song.insLabels[row % 48][0..32]); } override void stepColumn(int n) { super.stepColumn(n); } override void stepColumnWrap(int n) { stepColumn(-7); adjustView(); } override void activate() { super.activate(); } override void update() { int b = 0; int i, j, ofs; int myrow = row; if(myrow > 48) myrow -= 48; screen.fprint(area.x,area.y, "`b1I`01nstruments"); for(i = 0; i < visibleRows; i++) { int p = (i + viewOffset); if(p > 47) p -= 48; assert(p >= 0 && p < 48); int c = (state.activeInstrument >= 0 && row == p) ? 15 : 12; screen.cprint(area.x,area.y + i + 1, c, 0, format("%02X:", p)); for(j=0; j<8; j++) { ofs = p + j * 48; int hl = p == mark ? 13 : 5; screen.cprint(area.x+3+j*3,area.y + i + 1,hl,0, format("%02X ", data[ofs])); } string label = insName(p)[0..width]; if(paddedStringLength(label, 32) == 0) screen.cprint(area.x + 27, area.y + 1 + i, 11, 0, format("No description" ~ std.array.replicate(" ", width-14))); else screen.cprint(area.x + 27, area.y + 1 + i, 15, 0, label); } } override void initializeInput() { super.set(); assert(row < 48); int ofs = column * 48 + row; input.setOutput(data[ofs .. ofs+1]); } override void stepRow(int n) { super.stepRow(n); UI.activateInstrument(row); } override void showByteDescription() { if(song.ver > 8) { super.showByteDescription(song.instrumentByteDescriptions[column]); } } } class InsTable : Window { private { DialogString insdesc; InsValueTable insinput; } Window active; this(Rectangle a) { super(a); insdesc = new DialogString(a, com.fb.mode ? 32 : 16); insinput = new InsValueTable(a); refresh(); activateInsValueTable(); } override const ContextHelp contextHelp() { if(song.ver > 8) return genPlayerContextHelp("Instrument table", song.instrumentByteDescriptions); return ui.help.HELPMAIN; } override void refresh() { super.refresh(); insdesc.refresh(); insinput.refresh(); } @property int row() { return insinput.row; } void stepRow(int n) { insinput.stepRow(n); } void seekRow(int r) { insinput.seekRow(r); } override void activate() { activateInsValueTable(); } override void deactivate() { if(active == insdesc) { string s = insdesc.toString(false); song.insLabels[insinput.row][0..s.length] = s; } activateInsValueTable(); active.update(); state.allowInstabNavigation = true; } void activateDescInput() { update(); active = insdesc; input = insdesc.input; input.setCoord(area.x + 9 * 3, 1 + area.y + insinput.cursorOffset); insdesc.setString(format(song.insLabels[insinput.row])); initializeInput(); state.allowInstabNavigation = false; } void activateInsValueTable() { active = insinput; input = insinput.input; active.activate(); initializeInput(); state.allowInstabNavigation = true; } override int keypress(Keyinfo key) { if(key.mods & KMOD_ALT) return OK; if(key.unicode == SDLK_RETURN || key.unicode == SDLK_TAB) { if(active == insinput) { activateDescInput(); } else { string s = insdesc.toString(true); song.insLabels[insinput.row][0..s.length] = s; activateInsValueTable(); } return OK; } int r; r = active.keypress(key); return r; } override void update() { active.update(); } void initializeInput() { if(active == insinput) insinput.initializeInput(); } alias initializeInput set; override void clickedAt(int x, int y, int button) { insinput.clickedAt(x,y,button); if((x - area.x) > 3 + 8 * 3) activateDescInput(); } } class CmdTable : HexTable { alias row position; this(Rectangle a) { super(a, song.superTable, 1, 64); input = new InputSpecial(song.superTable); } override void update() { int i; if(state.shortTitles) screen.fprint(area.x,area.y, "`01Co`b1m`01mand"); else screen.fprint(area.x,area.y, "`01Cmd (Alt-S)"); for(i = 0; i < visibleRows; i++) { int ofs = (viewOffset + i) & 0x3f; screen.fprint(area.x,area.y + i + 1, format("`0c%02X:`0d%01X-`05%02X %02X", ofs, song.superTable[ofs] & 15, song.superTable[ofs+64], song.superTable[ofs+128])); } } override int keypress(Keyinfo key) { if(key.mods & KMOD_ALT) return OK; switch(key.raw) { case SDLK_LEFT: input.step(-1); break; case SDLK_RIGHT: input.step(1); break; case SDLK_DOWN: stepRow(1); break; case SDLK_UP: stepRow(-1); break; case SDLK_PAGEUP: stepRow(-(PAGESTEP/2)); break; case SDLK_PAGEDOWN: stepRow((PAGESTEP/2)); break; case SDLK_HOME: seekRow(0); break; case SDLK_END: seekTableEnd(); break; default: break; } int r = input.keypress(key); song.superTable[position] = input.inarray[0]; song.superTable[position+64] = cast(ubyte)input.toIntRange(1, 3); song.superTable[position+128] = cast(ubyte)input.toIntRange(3, 5); if(r == WRAP) { stepRow(1); } return OK; } override void initializeInput() { super.initializeInput(); input.inarray[0] = song.superTable[position]; input.inarray[1] = song.superTable[position+64] >> 4; input.inarray[2] = song.superTable[position+64] & 15; input.inarray[3] = song.superTable[position+128] >> 4; input.inarray[4] = song.superTable[position+128] & 15; } override void seekTableEnd() { for(int i = 63; i >= 1; i--) { if(data[i-1] > 0) { seekRow(i); return; } } } override ContextHelp contextHelp() { if(song.ver > 9) return genPlayerContextHelp("Command table", song.cmdDescriptions); return ui.help.HELPMAIN; } override void showByteDescription() { if(song.ver > 9) { super.showByteDescription(song.cmdDescriptions[column]); } } } class ChordTable : HexTable { this(Rectangle a) { super(a, song.chordTable, 1, 128); } override void refresh() { super.refresh(); data = song.chordTable; } override void seekTableEnd() { for(int i = 127; i >= 1; i--) { if(data[i-1] > 0) { seekRow(i); return; } } } override void update() { int i; if(state.shortTitles) screen.fprint(area.x,area.y, "`01Chor`b1d`01"); else screen.fprint(area.x,area.y, "`01Chd (A-D)"); for(i = 0; i < visibleRows; i++) { int row = (i + viewOffset) & 0x7f; string col = "`05"; if(data[row] >= 0x80) col = "`0d"; screen.fprint(area.x, area.y + i + 1, format("`0c%02X:%s%02X", row, col, data[row])); } for(i = 0; i < visibleRows; i++) { screen.fprint(area.x + 5, area.y + i + 1, " "); } int[] chordno = getHighestChordIndex(); { int ct; for(i = 0; i < viewOffset; i++) { if(data[i] >= 0x80) ct++; } bool doPrint = true; int row = viewOffset & 127; for(i = 0; i < visibleRows; i++,row++) { if(row > 127) { row -= 128; ct = 0; doPrint = true; } if(doPrint) { screen.fprint(area.x + 5, area.y + i + 1, format("`0c%X ", ct)); doPrint = false; } if(data[row] >= 0x80) { if(ct >= chordno[0]) break; ct++; doPrint = true; if(row >= chordno[1]) { doPrint = false; } } } } } override void initializeInput() { super.initializeInput(); input.setOutput(data[row .. row + 1]); song.generateChordIndex(); } override void insertRow() { saveState(false); ubyte[] tmp = data[row .. $-1].dup; foreach(i, c; tmp) { if(/+row > 0 && +/ c >= (0x80 + row) && ++c < 0x100) { tmp[i] = c; } } data[row+1 .. $] = tmp; data[row] = 0; initializeInput(); } override void deleteRow() { saveState(false); ubyte[] tmp = data[row + 1 .. $].dup; foreach(i, c; tmp) { if(c > (0x80 + row) && --c >= 0x80) tmp[i] = c; } data[row .. $ - 1] = tmp; data[$-1] = 0; initializeInput(); } private: // returns number of chords and the offset of the last chord int[] getHighestChordIndex() { foreach_reverse(counter, idx; song.chordIndexTable) { if(idx == 0) continue; return cast(int[])[counter, idx]; } return [-1, -1]; } } class WaveTable : HexTable { this(Rectangle a) { super(a, song.waveTable, 2, 256); } override void refresh() { super.refresh(); data = song.waveTable; } override void seekTableEnd() { for(int i = 255; i >= 1; i--) { if(data[i-1] > 0) { seekRow(i); return; } } } void seekCurWave() { seekRow(song.instrumentTable[state.activeInstrument + 7 * 48]); } override int keypress(Keyinfo key) { if(key.mods & KMOD_SHIFT) { switch(key.raw) { case SDLK_HOME: seekRow(0); return OK; case SDLK_END: seekTableEnd(); return OK; default: break; } } else if(key.mods & KMOD_CTRL) { switch(key.raw) { case SDLK_g: seekCurWave(); return OK; default: break; } } else switch(key.raw) { case SDLK_g: seekCurWave(); return OK; case SDLK_DELETE: saveState(true); song.tWave.deleteRow(song, row); refresh(); set(); return OK; case SDLK_INSERT: saveState(true); song.tWave.insertRow(song, row); refresh(); set(); return OK; case '.': data[column ? (256 + row) : row] = 0; stepColumnWrap(1); return OK; default: break; } return super.keypress(key); } override void update() { int i; int t1, t2; if(state.shortTitles) screen.fprint(area.x,area.y, "`b1W`01ave"); else screen.fprint(area.x,area.y, "`01Wave (A-W)"); for(i = 0; i < visibleRows; i++) { int row = (i + viewOffset) & 255; t1 = data[row]; t2 = data[row+256]; int col = (t1 == 0x7e || t1 == 0x7f) ? 0x0d : 0x05; screen.fprint(area.x,area.y + i + 1, format("`0c%02X:`%02x%02X %02X", row, col, t1, t2)); } } override void initializeInput() { int offset = column ? (256 + row) : row; (cast(InputByte)input).setOutput(data[offset..offset+1]); super.set(); } override void stepColumnWrap(int n) { stepRow(1); adjustView(); } override void showByteDescription() { if(song.ver > 9) { super.showByteDescription(song.waveDescriptions[column]); } } override ContextHelp contextHelp() { if(song.ver > 9) return genPlayerContextHelp("Wave table", song.waveDescriptions); return ui.help.HELPMAIN; } } class SweepTable : HexTable { this(Rectangle a, ubyte[] d) { super(a, d, 4, 64); } override int keypress(Keyinfo key) { switch(key.raw) { case SDLK_DELETE: deleteRow(); refresh(); set(); return OK; case SDLK_INSERT: insertRow(); refresh(); set(); return OK; default: return super.keypress(key); } } override void update() { for(int i = 0; i < visibleRows; i++) { int curRow = (i + viewOffset) & 63; int p = curRow * 4; string col = "`05", col2 = "`05"; if(data[p+3] > 0) col = "`0d"; if(data[p+3] > 0x3f && data[p+3] != 0x7f) col = "`0a"; if(highlightRow(curRow)) { col2 = col = "`0d"; } screen.fprint(area.x,area.y + i + 1, format("`0c%02X:%s%02X %02X %02X %s%02X", curRow, col2, data[p], data[p+1], data[p+2], col, data[p+3])); } } override void initializeInput() { InputByte i = cast(InputByte)input; int ofs = row * 4 + column; i.setOutput(data[ofs..ofs+1]); super.initializeInput(); } override void seekTableEnd() { for(int i = 63; i >= 0; i--) { ubyte[] arr = data[i * 3 .. i * 3 + 3]; bool flag; foreach(a; arr) { if(a) { int row = i + 1; if(row > 63) row = 63; seekRow(row); return; } } } } protected bool highlightActiveFor(int startFrom, int currentRow) { if(startFrom > 0x3f || startFrom == 0) return false; if(startFrom == currentRow) return true; bool[0x40] visited; for(int row = startFrom; row < 0x40;) { if(visited[row]) break; visited[row] = true; if(row == currentRow) return true; int jumpValue = data[row * 4 + 3]; if(jumpValue > 0x3f && jumpValue != 0x7f) // if illegal, break break; if(jumpValue == 0x7f) break; // if loops or ends, break else if(jumpValue == 0) row++; else row = jumpValue; } return false; } } class PulseTable : SweepTable { this(Rectangle a) { super(a, song.pulseTable); } override void refresh() { super.refresh(); data = song.pulseTable; } override void update() { if(state.shortTitles) screen.fprint(area.x, area.y, "`b1P`01ulse"); else screen.fprint(area.x, area.y, "`01Pulse (Alt-P)"); super.update(); } override void showByteDescription() { if(song.ver > 8) { super.showByteDescription(song.pulseDescriptions[column]); } } override ContextHelp contextHelp() { if(song.ver > 8) return genPlayerContextHelp("Pulse table", song.pulseDescriptions); return ui.help.HELPMAIN; } override void deleteRow() { saveState(true); ct.purge.pulseDeleteRow(song, row); } override void insertRow() { saveState(true); ct.purge.pulseInsertRow(song, row); } override bool highlightRow(int row) { return highlightActiveFor(song.instrumentTable[state.activeInstrument + 5 * 48], row); } } class FilterTable : SweepTable { this(Rectangle a) { super(a, song.filterTable); refresh(); } override void refresh() { super.refresh(); data = song.filterTable; } override void update() { if(state.shortTitles) screen.fprint(area.x, area.y, "`b1F`01ilter"); else screen.fprint(area.x, area.y, "`01Filter (Alt-F)"); super.update(); } override ContextHelp contextHelp() { if(song.ver > 8) return genPlayerContextHelp("Filter table", song.filterDescriptions); return ui.help.HELPMAIN; } override void showByteDescription() { if(song.ver > 8) { super.showByteDescription(song.filterDescriptions[column]); } } override void deleteRow() { saveState(true); ct.purge.filterDeleteRow(song, row); } override void insertRow() { saveState(true); ct.purge.filterInsertRow(song, row); } override bool highlightRow(int row) { return highlightActiveFor(song.instrumentTable[state.activeInstrument + 4 * 48], row); } } CheeseCutter-2.10/src/ui/ui.d000066400000000000000000000717661516216315000160260ustar00rootroot00000000000000/* CheeseCutter v2 (C) Abaddon. Licensed under GNU GPL. */ module ui.ui; import derelict.sdl2.sdl; import std.conv; import main; import ct.base; import com.session; import ct.purge; import ui.help; import ui.input; import audio.player; import ui.tables; import ui.dialogs; import seq.fplay; import com.fb; import com.util; import seq.sequencer; import audio.audio; import std.string; import std.file; import std.stdio; import audio.audio, audio.timer, audio.callback; enum PAGESTEP = 16; enum CONFIRM_TIMEOUT = 90; enum UPDATE_RATE = 2; // 50 / n times per second private int tickcounter1, tickcounter3 = -1; private int clearcounter, optimizecounter, escapecounter, restartcounter; struct Rectangle { int x, y; int height, width; alias height h; alias width w; string toString() { return format("%d %d %d %d",x, y, h, w); } bool overlaps(int cx, int cy) { return cx >= x && cx < x + width && cy >= y && cy < y + height; } Rectangle relativeTo(int scrx, int scry) { return Rectangle(scrx - x, scry - y); } } abstract class Window { Rectangle area; Input input; protected ContextHelp help; this(Rectangle a) { this(a, ui.help.HELPMAIN); } this(Rectangle a, ContextHelp ctx) { contextHelp = ctx; area = a; } abstract void update(); int keypress(Keyinfo key) { return 0; } int keyrelease(Keyinfo key) { return 0; } void refresh() {} void deactivate() {} void activate() { refresh(); } void clickedAt(int scrx, int scry, int button) {} protected: @property void contextHelp(ContextHelp h) { help = h; } @property ContextHelp contextHelp() { return help; } final void drawFrame() { drawFrame(area); } static void drawFrame(Rectangle a) { int x,y; for(y=a.y;y= windows.length) activeWindowNum %= windows.length; +/ activeWindowNum = umod(activeWindowNum, 0, cast(int)windows.length - 1); activateWindow(); return OK; default: return activeWindow.keypress(key); } assert(0); } override ContextHelp contextHelp() { return activeWindow.contextHelp(); } override void clickedAt(int scrx, int scry, int button) { // activateAt(scrx - activeWindow.area.x, scry - activeWindow.area.y); } } class Infobar : Window { private { const int x1, x2; int idx; } InputString inputTitle, inputAuthor, inputReleased; this(Rectangle a) { super(a); x1 = area.x; x2 = x1 + (com.fb.mode > 0 ? 64 : 48); } override void update() { int headerColor = state.keyjamStatus ? 14 : 12; if(escapecounter) headerColor = 7; screen.clrtoeol(0, headerColor); enum hdr = "CheeseCutter 2.10" ~ com.util.versionInfo; screen.cprint(4, 0, 1, headerColor, hdr); screen.cprint(screen.width - 14, 0, 1, headerColor, "F12 = Help"); int c1 = audio.player.isPlaying ? 13 : 12; screen.fprint(x1,area.y,format("`05Time: `0%x%02d:%02d / $%02x", c1,audio.timer.min, audio.timer.sec, audio.callback.linesPerFrame & 255)); screen.fprint(x1 + 19,area.y, format("`05Oct: `0d%d `05Spd: `0d%X `05St: `0d%d ", state.octave, song.speed, seq.sequencer.stepValue)); screen.fprint(x2+3, area.y+1, format("`05Rate: `0d%-1d*%dhz `05SID: `0d%s%s ", song.multiplier, audio.player.ntsc ? 60 : 50, audio.player.usefp ? audio.player.curfp.id : audio.player.sidtype ? "8580" : "6581", audio.player.badline ? "&0fb" : " ")); screen.fprint(x1,area.y+1,format("`05Filename: `0d%s", state.filename.leftJustify(38))); //screen.fprint(x2,area.y,format("`05 `b1T`01itle: `0d%-32s", std.string.toString(cast(char *)song.title))); screen.fprint(x2,area.y, format("`05%s `0d%-32s", ([" `b1T`01itle:", " `01Author:", "`01Release:" ])[idx], song.title)); screen.fprint(x2,area.y+2,format("`05 Player: `0d%s", ztos(song.playerID))); } override void refresh() { inputTitle = new InputString(cast(string)(song.title), cast(int)(song.title.length)); inputReleased = new InputString(cast(string)(song.release), cast(int)( song.release.length)); inputAuthor = new InputString(cast(string)(song.author), cast(int)(song.author.length)); input = ([ inputTitle, inputAuthor, inputReleased ])[idx]; input.setCoord(x2 + 9,area.y); } override void activate() { idx = 0; refresh(); } override void deactivate() { outputStrings(); } private void outputStrings() { song.title[0..32] = (cast(InputString)inputTitle).toString(true)[0..32]; song.release[0..32] = (cast(InputString)inputReleased).toString(true)[0..32]; song.author[0..32] = (cast(InputString)inputAuthor).toString(true)[0..32]; } override int keypress(Keyinfo key) { int r = input.keypress(key); if(r == RETURN) { idx++; if(idx > 2) { idx = 0; return RETURN; } outputStrings(); refresh(); } else if(r == CANCEL) { idx = 0; update(); return RETURN; } return OK; } } class Statusline : Window { int counter; string message; this(Rectangle a) { super(a); } void display(string msg) { message = msg; counter = CONFIRM_TIMEOUT; screen.clrtoeol(2, 0); update(); } override void deactivate() { counter = 0; update(); } override void update() { if(counter) screen.fprint(4, 2, "`0f " ~ message); else screen.clrtoeol(2, 0); } void timerEvent() { if(counter > 0) { --counter; if(!counter) update(); } } } final private class Toplevel : WindowSwitcher { InputKeyjam inputKeyjam; InsTable instable; CmdTable cmdtable; WindowSwitcher bottomTabSwitcher; WaveTable wavetable; PulseTable pulsetable; FilterTable filtertable; ChordTable chordtable; Sequencer sequencer; Fplay fplay; UI ui; Hotspot[] hotspots; bool followplay; this(UI ui) { this.ui = ui; int zone1x = 0; int zone2x = screen.width / 2 + zone1x - 1; int zone1y = 4; int zone1h = screen.height / 2 - 5; int zone2y = screen.height / 2; int zone2h = screen.height - zone2y - 5; inputKeyjam = new InputKeyjam(); sequencer = new Sequencer(Rectangle(zone1x, zone1y, screen.height - 10, zone2x - zone1x)); fplay = new Fplay(Rectangle(zone1x, zone1y, screen.height - 10, zone2x - zone1x)); instable = new InsTable(Rectangle(zone2x, zone1y, zone1h, 3 + 8 * 3 + 12)); int tx = zone2x; wavetable = new WaveTable(Rectangle(tx, zone2y, zone2h, 8)); tx += com.fb.border + 8; pulsetable = new PulseTable(Rectangle(tx, zone2y, zone2h, 14)); tx += com.fb.border + 14; filtertable = new FilterTable(Rectangle(tx, zone2y, zone2h, 14)); tx += com.fb.border + 14; cmdtable = new CmdTable(Rectangle(tx, zone2y, zone2h, 10)); tx += com.fb.border + 10; Rectangle ca; if(com.fb.mode == 0) { ca = Rectangle(tx - 6, zone1y, zone1h, 6); } else ca = Rectangle(tx, zone2y, zone2h, 6); chordtable = new ChordTable(ca); bottomTabSwitcher = new WindowSwitcher(Rectangle(zone2x, zone2y, zone2h, tx + com.fb.border + 10), [cast(Window)wavetable, pulsetable, filtertable, cmdtable, chordtable], "wpfmd"); /+ super(Rectangle(), [cast(Window)sequencer, instable, wavetable, pulsetable, filtertable, cmdtable, chordtable], null); +/ super(Rectangle(), [cast(Window)sequencer, instable, bottomTabSwitcher]); { int x1 = 4; int x2 = x1 + (com.fb.mode > 0 ? 64 : 48); int y1 = screen.height - 4; hotspots = [ Hotspot(Rectangle(x2 + 3, y1, 1, 30), (int b){ ui.activateDialog(UI.infobar); }), Hotspot(Rectangle(x2 + 18, y1 + 1, 1, 10), (int b){ b > 1 ? audio.player.toggleSIDModel() : audio.player.nextFP(); }), Hotspot(Rectangle(x2 + 3, y1 + 1, 1, 14), (int b) { b == 1 ? audio.player.incMultiplier() : audio.player.decMultiplier(); }) ]; } refresh(); } override void clickedAt(int x, int y, int b) { foreach(idx, win; windows) { if(win.area.overlaps(x, y)) { activateWindow(idx); activeWindow.clickedAt(x, y, b); } } foreach(idx, win; bottomTabSwitcher.windows) { if(win.area.overlaps(x, y)) { bottomTabSwitcher.activateWindow(idx); bottomTabSwitcher.activeWindow.clickedAt(x, y, b); break; } } foreach(idx, spot; hotspots) { if(spot.area.overlaps(x, y)) spot.callback(b); } } override int keypress(Keyinfo key) { switch(key.unicode) { case ']': if(song.speed < 32) song.speed = song.speed + 1; return OK; case '[': if(song.speed > 0) song.speed = song.speed - 1; return OK; case '{': audio.player.setMultiplier(song.multiplier - 1); return OK; case '}': audio.player.setMultiplier(song.multiplier + 1); return OK; /+ case '(': if(octave > 0) octave--; return OK; case ')': if(octave < 6) octave++; return OK;+/ default: break; } if(key.mods & KMOD_ALT) { switch(key.raw) { case SDLK_v: activateWindow(0); break; case SDLK_1: if(!(key.mods & KMOD_CTRL)) { activateWindow(0); sequencer.activateVoice(0); } break; case SDLK_2: if(!(key.mods & KMOD_CTRL)) { activateWindow(0); sequencer.activateVoice(1); } break; case SDLK_3: if(!(key.mods & KMOD_CTRL)) { activateWindow(0); sequencer.activateVoice(2); } break; case SDLK_4: case SDLK_i: activateWindow(1); break; case SDLK_5, SDLK_w: activateWindow(2); key.key = SDLK_w; activeWindow.keypress(key); return OK; case SDLK_6, SDLK_p: activateWindow(2); key.key = SDLK_p; activeWindow.keypress(key); return OK; case SDLK_7, SDLK_f: activateWindow(2); key.key = SDLK_f; activeWindow.keypress(key); return OK; case SDLK_8, SDLK_m: activateWindow(2); key.key = SDLK_m; activeWindow.keypress(key); return OK; case SDLK_9, SDLK_d: activateWindow(2); key.key = SDLK_d; activeWindow.keypress(key); return OK; case SDLK_t: ui.activateDialog(UI.infobar); return OK; case SDLK_KP_0: clearSeqs(); return OK; case SDLK_KP_PERIOD: optimizeSong(); return OK; case SDLK_o: if(key.mods & KMOD_CTRL) { optimizeSong(); return OK; } break; case SDLK_n: if(key.mods & KMOD_CTRL) { return OK; } break; case SDLK_c: if(key.mods & KMOD_CTRL) { clearSeqs(); return OK; } break; case SDLK_h: state.displayHelp ^= 1; UI.statusline.display("Help texts " ~ (state.displayHelp ? "enabled." : "disabled.")); break; default: break; } } else if(key.mods & KMOD_CTRL) { switch(key.raw) { case SDLK_PLUS: case SDLK_KP_PLUS: song.speed = clamp(song.speed + 1, 0, 31); break; case SDLK_MINUS: case SDLK_KP_MINUS: song.speed = clamp(song.speed - 1, 0, 31); break; case SDLK_TAB: key.mods & KMOD_SHIFT ? activeWindowNum-- : activeWindowNum++ ; if(activeWindowNum < 0) activeWindowNum = cast(int)( windows.length - 1); if(activeWindowNum >= windows.length) activeWindowNum %= windows.length; activateWindow(); return OK; case SDLK_z: com.session.executeUndo(); return OK; case SDLK_r: com.session.executeRedo(); refresh(); return OK; default: break; } } else if(!key.mods & KMOD_SHIFT) { switch(key.raw) { case SDLK_KP_DIVIDE: if(state.octave > 0) state.octave--; break; case SDLK_KP_MULTIPLY: if(state.octave < 6) state.octave++; break; case SDLK_PLUS: case SDLK_KP_PLUS: if(state.allowInstabNavigation) { instable.stepRow(1); state.activeInstrument = instable.row; } break; case SDLK_MINUS: case SDLK_KP_MINUS: if(state.allowInstabNavigation) { instable.stepRow(-1); state.activeInstrument = instable.row; } break; default: break; } } else if(key.mods & KMOD_SHIFT) { version(OSX) { if(key.raw == SDLK_EQUALS && state.allowInstabNavigation) { instable.stepRow(1); state.activeInstrument = instable.row; } } } if(state.keyjamStatus == true) { inputKeyjam.keypress(key); } else { int r = activeWindow.keypress(key); if(r == RETURN || r == CANCEL) { assert(0); } } return OK; } override int keyrelease(Keyinfo key) { if(state.keyjamStatus == true) { inputKeyjam.keyrelease(key); } return activeWindow.keyrelease(key); } override void refresh() { foreach(t; windows) { t.refresh(); t.update(); } bottomTabSwitcher.refresh(); // needed because 'input' might be messed by a subdialog activeWindow.activate(); } override void update() { foreach(t; windows) { t.update(); } } bool fplayEnabled() { return followplay; } void activateByCoord(int x, int y) { foreach(idx, win; windows) { if(win.area.overlaps(x, y)) { activateWindow(idx); } } foreach(idx, win; bottomTabSwitcher.windows) { if(win.area.overlaps(x, y)) { bottomTabSwitcher.activateWindow(idx); break; } } } void timerEvent() { fplay.timerEvent(); } Window windowByCoord(int x, int y) { foreach(idx, win; windows ~ bottomTabSwitcher.windows) { if(win.area.overlaps(x, y)) return win; } return null; } void playFromCursor() { Voice[] v = sequencer.getVoices(); auto d1 = v[0].activeRow; auto d2 = v[1].activeRow; auto d3 = v[2].activeRow; audio.player.start([d1.trkOffset,d2.trkOffset,d3.trkOffset], [d1.seqOffset,d2.seqOffset,d3.seqOffset]); fplay.startFromCursor(); } void reset() { sequencer.reset(); sequencer.resetMark(); } void startFp() { followplay = true; windows[0] = fplay; if(activeWindow == sequencer) activateWindow(0); } void startFp(int mode) { startFp(); if(activeWindow == fplay) fplay.start(mode); } void startPlayback(int j) { fplay.start(j); } private void stopFp() { followplay = false; windows[0] = sequencer; activateWindow(activeWindowNum); } void stopPlayback() { fplay.stop(); if(followplay) { stopFp(); followplay = false; activate(); sequencer.reset(false); } } private void optimizeSong() { if(++optimizecounter > 1) { refresh(); // TODO: VALIDATION HERE BEFORE PURGING... PurgeExpception should be useless if validate covers all errorcases try { (new Purge(song,true)).purgeAll(); } catch(PurgeException e) { UI.statusline.display(e.toString); optimizecounter = 0; return; } refresh(); UI.statusline.display("Song data optimized."); optimizecounter = 0; } else { UI.statusline.display("Press again to confirm song data optimization..."); tickcounter3 = 0; } } private void clearSong() { if(++restartcounter > 1) { //song.open(cast(ubyte[])import("player.bin")); sequencer.reset(); refresh(); clearcounter = 0; //savedialog.setFilename(""); state.filename = ""; UI.statusline.display("Editor restarted."); } else { UI.statusline.display("Press again to confirm editor cold start..."); tickcounter3 = 0; } } private void clearSeqs() { if(++clearcounter > 1) { song.clearSeqs(); sequencer.reset(); clearcounter = 0; UI.statusline.display("Sequence data cleared."); } else { UI.statusline.display("Press again to confirm sequence data clearing..."); tickcounter3 = 0; } } } final class UI { private { Window dialog = null; //bool printSIDDump = false; enum VisMode { None, Regs, Oscilloscope } int vismode; AboutDialog aboutdialog; FileSelectorDialog loaddialog, savedialog; } static Statusline statusline; static Infobar infobar; static Toplevel toplevel; bool exitRequested = false; this() { statusline = new Statusline(Rectangle(0, 2, 1)); toplevel = new Toplevel(this); infobar = new Infobar(Rectangle(4, screen.height - 4, 1, screen.width - 8)); int dialog_width = screen.width - 32; int dialog_height = screen.height - 10; int dialog_x = screen.width / 2 - dialog_width / 2; int dialog_y = screen.height / 2 - dialog_height / 2; loaddialog = new LoadFileDialog(Rectangle(dialog_x, dialog_y, dialog_height, dialog_width), &loadCallback, &importCallback); savedialog = new SaveFileDialog(Rectangle(dialog_x, dialog_y, dialog_height, dialog_width), &saveCallback); int aboutdlg_width = screen.width - 18; int aboutdlg_height = 12; int aboutdlg_x = screen.width / 2 - aboutdlg_width / 2; int aboutdlg_y = screen.height / 2 - aboutdlg_height / 2; aboutdialog = new AboutDialog(Rectangle(aboutdlg_x, aboutdlg_y, aboutdlg_height, aboutdlg_width)); audio.player.setMultiplier(song.multiplier); if(com.fb.mode > 0) state.shortTitles = false; toplevel.activate(); activateDialog(aboutdialog); update(); } @property Window activeWindow() { if(dialog) return dialog; return toplevel.activeWindow; } @property Input activeInput() { return activeWindow.input; } void timerEvent(int n) { Exception e = audio.callback.getException(); if(e !is null) { writeln("error" ~ e.toString()); audio.player.stop(); statusline.display(e.toString()); } if((tickcounter3 >= 0) && ++tickcounter3 > 20) { clearcounter = optimizecounter = escapecounter = restartcounter = 0; infobar.update(); tickcounter3 = -1; } statusline.timerEvent(); tickcounter1 += n; if(tickcounter1 >= UPDATE_RATE) { infobar.update(); if(dialog) dialog.update(); tickcounter1 = 0; toplevel.timerEvent(); if(audio.player.isPlaying || audio.player.keyjamEnabled) { if(vismode == VisMode.Regs) { int x = screen.width - 42; screen.cprint(x, 1, 15, 0, "V1:"); screen.cprint(x, 2, 15, 0, "V2:"); screen.cprint(x, 3, 15, 0, "V3:"); screen.cprint(x+26, 1, 15, 0, "$D415 16 17 18"); for(int i = 0; i < 7; i++) { screen.cprint(x+3+i*3, 1, 5,0, format("%02X", audio.audio.sidreg[i])); screen.cprint(x+3+i*3, 2, 5,0, format("%02X", audio.audio.sidreg[i+7])); screen.cprint(x+3+i*3, 3, 5,0, format("%02X", audio.audio.sidreg[i+14])); } for(int i = 0; i < 4;i++) { screen.cprint(x+8+21+i*3, 2, 5,0, format("%02X", audio.audio.sidreg[i+0x15])); } } update(); // TESTME: just do video.updateFrame() } } if(vismode == VisMode.Oscilloscope && (audio.player.isPlaying || audio.player.keyjamEnabled)) video.drawVisualizer(n); } void update() { infobar.update(); toplevel.update(); if(dialog) dialog.update(); } private void F1orF2(Keyinfo key, bool fromStart) { if(audio.player.isPlaying) { if(key.mods & KMOD_SHIFT) { // already playing, reinit tracking stop(false); toplevel.startFp(); return; } else if(toplevel.fplayEnabled()) { // drop tracking stop(false); seqPos.copyFrom(fplayPos); toplevel.stopFp(); return; } // song is playing but plain F1 pressed; restart } int m1, m2, m3; m1 = seqPos.pos[0].mark; m2 = seqPos.pos[1].mark; m3 = seqPos.pos[2].mark; stop(); if(!fromStart) { audio.player.start([m1, m2, m3], [0, 0, 0]); if(key.mods & KMOD_SHIFT) { toplevel.startFp(); } toplevel.startPlayback(Jump.toMark); } else { audio.player.start(); if(key.mods & KMOD_SHIFT) { toplevel.startFp(Jump.toBeginning); } toplevel.startPlayback(Jump.toBeginning); } } int keypress(Keyinfo key) { /+ old buggy coldstart code if(key.mods & KMOD_ALT && key.mods & KMOD_CTRL && key.raw == SDLK_KP0) { if(++restartcounter > 1) { song = new Song(); toplevel.sequencer.reset(); refresh(); clearcounter = 0; UI.statusline.display("Editor restarted."); savedialog.setFilename(""); // TODO: find out why tracklist is not erased filename = ""; } else { UI.statusline.display("Press again to confirm editor cold start..."); tickcounter3 = 0; } return OK; } else+/ bool skip_imm_keypress = false; //workaround for F11 - crapchars in savedialog if(key.mods & KMOD_ALT) { switch(key.raw) { case SDLK_RETURN: video.toggleFullscreen(); //update(); break; case SDLK_KP_PLUS: audio.player.setMultiplier(song.multiplier + 1); break; case SDLK_KP_MINUS: audio.player.setMultiplier(song.multiplier - 1); break; case SDLK_F12: audio.player.dumpFrame(); break; default: break; } } else if(key.mods & KMOD_CTRL) { switch(key.raw) { case SDLK_1: audio.player.toggleVoice(0); break; case SDLK_2: audio.player.toggleVoice(1); break; case SDLK_3: audio.player.toggleVoice(2); break; case SDLK_F11: string s = savedialog.filename; if(s == "") statusline.display("Cannot Quicksave; give filename first by doing a regular save."); else { saveCallback(s); statusline.display(format("Saved \"%s\".",s)); } break; case SDLK_F12: break; case SDLK_F2: audio.player.interpolate ^= 1; audio.player.init(); break; case SDLK_F3: song.sidModel ^= 1; audio.player.setSidModel(song.sidModel); break; /+ case SDLK_F4, SDLK_b: audio.player.badline ^= 1; audio.player.init(); break; +/ case SDLK_F8: key.mods & KMOD_SHIFT ? audio.player.prevFP() : audio.player.nextFP(); break; case SDLK_F9: /+ if(printSIDDump) { screen.clrtoeol(55, 1, 0); screen.clrtoeol(55, 2, 0); screen.clrtoeol(55, 3, 0); } printSIDDump = !printSIDDump; +/ vismode = umod(vismode + 1, 0, VisMode.max); screen.clrtoeol(55, 1, 0); screen.clrtoeol(55, 2, 0); screen.clrtoeol(55, 3, 0); video.clearVisualizer(); break; case SDLK_SPACE: if(song.ver < 7) break; state.keyjamStatus ^= 1; enableKeyjamMode(state.keyjamStatus); statusline.display("Keyjam " ~ (state.keyjamStatus ? "enabled." : "disabled.") ~ " Press Ctrl-Space to toggle."); break; default: break; } } else switch(key.raw) { case SDLK_ESCAPE: if(dialog || activeWindow == infobar) break; if(++escapecounter > 1) { activateDialog(new ConfirmationDialog("Really exit (y/n)? ", (int param) { if(param != 0) return; audio.player.stop(); exitRequested = true; })); return OK; } tickcounter3 = 0; break; /+ case SDLK_PRINT: audio.player.dumpFrame(); break; +/ case SDLK_F1: F1orF2(key, false); break; case SDLK_F2: F1orF2(key, true); break; case SDLK_F3: toplevel.playFromCursor(); break; case SDLK_SCROLLLOCK: if(!audio.player.isPlaying) break; if(toplevel.fplayEnabled()) { stop(false); seqPos.copyFrom(fplayPos); toplevel.stopFp(); statusline.display("Tracking off."); } else { stop(false); toplevel.startFp(); statusline.display("Tracking on."); } break; case SDLK_F4: if(toplevel.fplayEnabled()) seqPos.copyFrom(fplayPos); stop(); if(toplevel.fplayEnabled()) toplevel.stopFp(); break; case SDLK_F8: if(key.mods & KMOD_SHIFT) audio.player.fastForward(25); else audio.player.fastForward(5); break; case SDLK_F9: activateDialog(aboutdialog); break; case SDLK_F10: activateDialog(loaddialog); break; case SDLK_F11: activateDialog(savedialog); skip_imm_keypress = true; break; case SDLK_F12: int helpdlg_width = screen.width - 10; int helpdlg_height = 36; int helpdlg_x = screen.width / 2 - helpdlg_width / 2; int helpdlg_y = screen.height / 2 - helpdlg_height / 2; HelpDialog helpdialog = new HelpDialog(Rectangle(helpdlg_x, helpdlg_y, helpdlg_height, helpdlg_width), activeWindow.contextHelp); activateDialog(helpdialog); break; default: break; } int r; if(dialog && !skip_imm_keypress) { if(key.mods & KMOD_ALT) return OK; r = dialog.keypress(key); if(r != OK) { closeDialog(); return r; } } else { toplevel.keypress(key); } return OK; } int keyrelease(Keyinfo key) { toplevel.keyrelease(key); return OK; } void clickedAt(int x, int y, int b) { if(dialog) dialog.clickedAt(x, y, b); else toplevel.clickedAt(x, y, b); } private void saveCallback(string s) { try { song.save(s); } catch(FileException e) { stderr.writeln(e.toString); statusline.display("Could not save file! Check your filename."); return; } string fn = s.strip(); auto ind = 1 + fn.lastIndexOf(DIR_SEPARATOR); fn = fn[ind..$]; state.filename = fn; // sync load filesel to save filesel if(loaddialog.directory != savedialog.directory) { foreach(d; [loaddialog, savedialog]) { d.setFilename(fn); d.setDirectory(getcwd()); } loaddialog.fsel.fpos.reset(); } } void importCallback(string s) { loadCallback(s, true); } void loadCallback(string s) { loadCallback(s, false); } private void loadCallback(string s, bool doImport) { stop(); if(std.file.exists(s) == 0 || std.file.isDir(s)) { statusline.display("File not found or not accessible: " ~ s); return; } try { if(!doImport) song.open(s); else { Song insong = new Song(); insong.open(s); song.importData(insong); } } catch(Exception e) { statusline.display("Error: " ~ e.toString); return; } refresh(); // all voices ON audio.player.setVoicon(0,0,0); string fn = s.strip(); auto ind = 1 + fn.lastIndexOf(DIR_SEPARATOR); fn = fn[ind .. $]; state.filename = fn; infobar.refresh(); // sync save filesel to load filesel in case dir was changed foreach(d; [loaddialog, savedialog]) { d.setFilename(fn); d.setDirectory(getcwd()); } savedialog.fsel.fpos = loaddialog.fsel.fpos; // set variables audio.player.setSidModel(song.sidModel); audio.player.setFP(song.fppres); audio.player.setMultiplier(song.multiplier); enableKeyjamMode(false); toplevel.reset(); if(doImport) { statusline.display("Song data imported."); } import com.session; com.session.state.undoQueue.clear(); com.session.state.redoQueue.clear(); } void activateDialog(Window d) { enableKeyjamMode(false); closeDialog(); dialog = d; d.activate(); } void closeDialog() { if(dialog) dialog.deactivate(); dialog = null; refresh(); } void enableKeyjamMode(bool doEnable) { if(audio.player.isPlaying) return; /+ doEnable ? com.fb.disableKeyRepeat() : com.fb.enableKeyRepeat();+/ state.keyjamStatus = doEnable; } void activateInstrumentTable(int ins) { UI.activateInstrument(ins); // just hacking away..... toplevel.activateWindow(2); toplevel.keypress(Keyinfo(SDLK_i, KMOD_ALT, 0)); } static void stop() { stop(true); } static void stop(bool doStop) { if(doStop) { audio.player.stop(); } infobar.update(); toplevel.stopPlayback(); } static void refresh() { screen.clrscr(); toplevel.refresh(); UI.statusline.update(); } static void activateInstrument(int ins) { if(ins > 47) ins = 47; if(ins < 0) ins = 0; toplevel.instable.seekRow(ins); state.activeInstrument = ins; toplevel.refresh(); } } CheeseCutter-2.10/tunes/000077500000000000000000000000001516216315000151555ustar00rootroot00000000000000CheeseCutter-2.10/tunes/abaddon-starfish.ct000066400000000000000000000133451516216315000207240ustar00rootroot00000000000000CC2x t՝ɋ],k RA6R*]][0@etT2+U-sCn_=]0O[Qϗ;}OԲ%rϠ cdp[9gp)|~g;/}WO0OSeI\M"|Dz7Lޛ:/^"_TKN:U2G(3jsgNMݛ*n* ~~$3w `Cw~_:hnI78g: <J&뙽zZ}z |+K%b/d%_큖odw6߶۝eOlMhݯU+7P{YKր&9q]r|9r.^SWT`hq{SޤVaj8tvanURO{Ӥȝ:v]uYko^T|nɗ*M^VYnik%߷oXP W>U\sXJg>tz2;{}~#S%l/7:s7 )9/e{Xȭ,e$[o=H_۳ڭaO6t;꼸U{OR:ZF|ɔߵQɉZ]Y$ }.q}ngQNgZe/}I7,u֞]gKTAZAYe^u0WLww/f'R[1s7:cdU>!-~5rKʻnT46 >)_}@l}H5?('zFZydyN7,+J_av0sAPe=#sΗGDUTRjIa%[Q#nݯo3+s?t\H?]h}o~7ꘕo}mg&gxG:ztgd</G_~ogOGmŊ`ocM~=K_-PP0pРE!C 12\Qc??nE|f^{\݇oֶW{үeZyF//NѯPE'uuuWdZ CrEҟ~z{cuْ8ut@˚>{$ue#Elɝ?x<~Bܿ4H qX!奲SE ?B(ORTn*?5,5P!Sߌ/pċ.dK|StYYӦ_1/_uW*Y_vq7o}{MʹUy#7/Y.%/e魷cMXbw}w{o}c7l|boiOs^~gǏxnY+a]&^%A Ih3ۯδ_\kjΩCl^wcwt]ōRoycv /rcLL{_)O$;+ui[]RG2wiw5n^iK k2+zڝ}gݝ+6ywoۺ˼NsQ)_~+ﶓRg7Kb^g|o`q-ˬž=ǧO]jWXG?)_7 K˽__ҏ8>B:ݧKy/}ԛ^g_7(׋r{ӫOھ{T჎[>GOR~_ݧs8&KޚQ&v佒{%j޺Ǥwv 3[mn˙q\|qyM/gBq^L8.֡ :]ϝo3Oy'ɤl9},_ϧ[,g|' s6YWw|xtcݓyI3_η[֝3iYyPªvo;^|bUik:~Ϥ{mJH𾧤]OzY?g;b#d;ubIok25<]o]&<'OH:9Ay?MN3CL|_-Wpeگz^煎5{A*M{^ʽ?'ܟ`?c`?c`?c`?c`?c`?c`?c`?c`?c`?c`?c`?c`?c`?c`?c`?c`?c`?c`?c`?c`?c`?c`?c`?c`?c`?c`?lx@|텒Z)y~[*Ǔo?p@L%]+(4ZrkY?kYy2?**!C ܫ#( eIJqQ5)gȱ rs_U?:>-+@Ѣֿ=}MMMwHH551Û_/ןd~??;חE'tGd*:g$'?q5pƔՀ|ߙ4/9e1YgFu?ov/NXv4oGˎZ޿5Yy+ZBF[}|/ yg?qʩf[_fxvmay^e9<Iy"oO -gͮK"Qɸ6\ՅY׆%+KkÒ׆ϏpjQT{=#Z3%"=;6/a{&/U=lݾdT )(*\Zj/}KBbD8n=TYkc|gͪ iL)3{v88\2#]/x(EPʮsqެ'ηGC*r8vb`ҶF=xlvI{;d]Ʃ2mr(⑪% Ę:齮c(vg"L(vv 쫦bDe=_̼$}̳/_* ;AI3Yb 3_X)&M(5ڪzizVŖhP_yHИMԋ sqYw).- u.vg{\%v;+_g≐^pws폳]` iWYM͘1ɽ:uQ'\RRIA6ŞP_ ''^Sh׌m F2dnez{MTEXVFȩv43dNN9qzeuvf^IښPTėJ1keA½׸=V5zgjBbqmiޕw}m}ή&"5/s3irA'~xzx\?a?ٴ65Q*VV|՚O^Z ՗R*Ur[$_SҤ'BrއGH]=VR+NY+PeJ~D</,0UN/ Յ'N]T-T q/YTW1>QOUWL?<[;JaY'-Ku%3N].՞}ƸSNwyIxnQ_%O>.k%Ցէ+-9Ykg?Ɲ@MpJ~;%4OZ.fN;EO;||O@$*'585(5@'˱B&(%KeRCS LQʟ |T~jXj?B(3@2W?B G\+!s#d2W?B G\+!s#d2W?B G\+!s#d2W?B G\+!s#d2W?B G\+!s#d2W?B G\+!s#d2W?B G\+!s#d2W?B G\+!s#d2W?B G\+!s#d2W?B G\+!s#d2W?B G\+!s#d2W?B /othCheeseCutter-2.10/tunes/abaddon-swingcat.ct000066400000000000000000000140001516216315000207050ustar00rootroot00000000000000CC2x{tU՝}<pyg[gy KbĢAJڱr!)&&74"B/OqHG*̔!fFBi,g\㣮vd~ Aўg>Z:8H ϧMkh+}/yW~?.?Sv0R1f7ffcq57.S9j2^\/N47oBr###c6cjMz0ct:_J۪ջ۷x*km/To*Wx嫃hԎQs6oA]cuyvTq0vjmo%M>lT;U5ua`Վ<,ɯ&]zsZ5/Ҷ٩?]dBRuƿ|#P&++c+dp̓ʺ}{C2Lrgi^V7d5Λ.b E*K]cj{GʪT:;zr))n0Rܦ϶UmCX:gWTi:Y_gmٝ}2 }{,nj ZT+ݴ{p 'lS5;HkN]'ڝwlIgj􀤜DW+e!lR$g[~ǿ|"o0RJH>~yѣG;?ĕ3 yGӽMFayRz KiG{;v؜޴L)FaH}ff35a~`԰ir>2Ev3RfozO4-귕QUY?~et \zo45baChzCg]2.0IW~{UWOfk_w 7~ছo[gn;ssBhApY]E,]v=k+]yߪ?nO6m޲uvug~6[t%)ݜT)y^V$_ֱZwO{zgfkI3u_Ū0Uf^9K? yb-r}\/jRXf|n*}X+|\GXl$PʗJ&ݏݤiVI*)[+'9䤗$;_ciV:~z?'ʺ6k}!-7$گ; D{ ]%Yiubmh>t};=󛝹^'ؒ`׌_oӛ>b6~v:h;r>`v{ϧ^N~Y]~w}D#O7tޫV*{[+?~mS]kܾ}uR=?_/F)_O_F}~6{}}ci{M&QM%oIWIyfW`}}}{}sq߮O{?]nHz׳׶t篳!{?{L7%t"O7%<۝=ڔvCMN_l-ے;d^o>_MMOw';۝?-h]GK?qXξe&=~Ze{YA-VYc!bx{?VYȯ_eWFk "E,1~緢[-W'6~cm\yk}}yNRo7oO{֓ҾHfS9_{)VlĞj+.i_mj+)IJ|I믷~t {\;67=OqNCD3N;/3޿3㲿ynz'֤I[{/{Ɏ:!~'~'~'~'~'~'~'~'~'~'~'~'~'~'~'~'7OOOOOOOOOOOOOOOOd˛~֘yX3|5^[T12;3) KHڜ?9#0Ca}<i:y+|{+ {񤥤Ǔ1iOaxla<3\Cх]|G8~M3}sͧ|s?m:j|4VA#QwTntx w)i)w}tKiFM+O3;sd8oW6}#ßat;yj$)Qß??տf H=TO5.Sf2 FCZٙ/s9fpG@WegKc?*;SfJ$؜\k̬K’qk4 $"bF$?XQ?̬,rG3'!3QY/3E̊:`EQW=S7] t\* .5KdмH¼-XX2Jrk̨* i)1sf((TZ&A%F]:ᴪ`,lEfQIEhuf=uQ6+sFM3 #BCWMuC$R,5 ;o.&7*FdBQNNGM4/Ϙ,RfCK"fe(b^9=,UFW͗I$#9P?΀I*q-IKnY8`8*5+tԹ] JsO)D?]V WuNYee.dIKd#]U:l, +J"R*\o^XΛ'¥fXőɖ&\+mKe0=ryf%eUfEⱉvI Yd;]T283tr,YTT- #c*ަu[ǔQLimD:;ÕS‘R=K*nq{ r49fCheeseCutter-2.10/tunes/abaddon-trouble.ct000066400000000000000000000154561516216315000205620ustar00rootroot00000000000000CC2x tTչ = AAT XmT^0!2f5$U#11=+נ2-y*kK]ۮe/cfI$:p{{s1Ӓ5'#5zoa8\Pؕ=J?W>xZ9/_~k>d1lștO}ɇ6lְ9r9kdoMdYFY{r'S&e\\ݖ9#{ {R;KIIٷ=7>ĤMfS:wvkm?;Tq?+X,ҜIʤgϊ?ەʱߥD3?=Du5RE6zȌg<]%w]l~ϳvܽ dI9ޑߑ {aVa}rRa`հ Ĥ䔔!CjX}Fu oΘvیwͽ}ɜ|O3뷾˯],ָs,q5z$LHͩgΜ^Ԛ.-q͌OplI[X*k2ڣ;#sӨܹs4)Sd-aY+cƬFuXR_BIIj -UHz YVVf,?Ǐ=/h_c= jkGMrkko3塲y|9Ma]U*&,G$s:BGVZ]'ϔ--+_~M?얭U(6Ez5tG^Z/@f.סl*=]ҵEZJ/zLn:3:^W{s#WNSfu>KuHZh>_xzfu~EM[vjhh>9N:臖/tTQAv1fuΏ(;uKZgGGh#^kJ="CQcKGzΨ6mj:@x[ >?߷agًbuTۓkQ?Qf;ZDޣiƹN'EqkjTz~78; 1ϫϟu"}\M׬?r:DZ^B5l9~ݬhu;: [QޗQ~^{9Ԭs=d/ުu)ϯm5|ip3 B_J]~ުoQe@πx |W>jZf?MgV.cl]ߎwrڿ^=;/ykUvbw~~c}' _N=}+jG?-jlS7Fou5({n FϨY=wiVmnj~vm(b~KHE^+C>ġ]麎CZ&k}kHmj__ǾNVK_jEߒ>HmQ/X?^V~kk""s{މ`yzF:Ni^'nEv~MtߛIڸ60ֿ^/ n`hZ9T7ƸA[kc+^2u sQ_Ot.aoW} ]->+8ާU=QߢQ_4Dq=ݳ}_׳]h7~hڛtۿ_4ԿǫRsH]}H~gQ!Qy9$/J*߮c*vQ}zuRi/>٣MѨϹ}^>ןab<,yQ,/cOZ.}^s5~]o>$KEެwu ӵQChg'Z"DV#?eP,Pv'(f_^6Vmڅ9xO΋7+9WkP i_^r]^K}ۯvOrwl߿m}|vwhfyHP_{\~}X?7/?7/?7/?7/?7/?7/?7/?7/?7/?7/Ῑgloh}uo:::֞P WJa):m#qHmJd\V>wy+X'+Djn:׍dӌDj07OǕLv6w˿}7e|qOGˈ2N!Y%rwm cK5bMℹ_ slI}2kk&OTGq]%eeMw\駧3k<J5^R|#_JqqΚ[{`aI̞eaY.W&e'XOmlkmcKX|ZP,VkR/9 8$uث49hLCȺ$.53%%~9"%Yñk37p.]."w-ugEEG].ߕuQ/  ]-s{%˕1qBf4G.-9W$2e&y/7S} ד `rY,tQեUΕ)x2RWX4>ui]]HӤ(Ӣs]V<4HHԋDHiOc ߑ?_|=ԐŽŽj/md^0UhHG;]Թ]hqe;t;ш˅^_)WrJ0H p)B=|ohC0\E1[wI:I~215;6[z lcRZU6Q"nhiԍH+]|V0|Ҥeቜ#y>Z+"CƤVY*țZ]XJS}Dl$zԈ)pDž'"w~v,h"_*4/K4s*-AV2tO:}PVX6~KIrp9o ,o\3ǙKĽqk[{-.6]w*p9s{.w s9~]ow8ލ|w3G#~E}\N_=BMu-ֿH'C߫ =K{mXp>5 gY7Xa_73舣&9QS7PJGW3ۍ猝lcqQ+75.PxN{>t]J5sJUKU^d&cեjU0U.V݇۾힭mcUM.9\JLV X'NWR{mZY)UQ[ǩNwtNc ܝ 7>_sxLiTg􃒐N^c xKU񼷨øߊR%wowkSuz jt*LRU3"QRM}_InIT#;{G'c:To;Qu8W&SKB_eg}Yaet+ѷ y<+_yD웯vݯ˒x {oTUG>SJUҳ,)LU ϵR|Š'fx@uJ[$W\WTٮ]=x6YsfWoUWTx6*=] Vy{JܨR:*YIWϸ ]Uׂ^oS^e>ߧnUt+TJƎ-bG<5"_FQߩrW]RrږZ_]/~H8LO6(,U2XWjGJyOKZ/G_Љ_;Rr~GAw:c7ܥկuf؝Lվ߯zVG)G&[j̮_(oeߩtwV.K؛[2v=;{/WuӨdk,kzRbdE[)-QUwZ9=o$VsZb6%Ma#e"&?(}d*cf9OJ7t;$ZO*ѩFS%֫2Wh=$GySߵyZtC׋V%W2.k6T޵ڽtC§>J}[%޿zqZ2-V~ũuͺa[VY@P71^ej!_5)k%b/e_Io{qv~ږ=5[4Oʶ#wG=*'tכr lwys=͗sJ#ZSb>Zjپe*]rRxڛ.ܣCU- hreg|2_gul/-;kKWyNo.DZDlxa+{T6'[w_>+ttfj{Q%^6^Er_/ "dgWIz=U?-i]|ƺ7Gձk`v\ԩ=uq^%x' ^`9g /'@Kgљ'#|KetgɢukJuDLsEYWpPq]Aqu=j`b~Zwqj~#e6ukwcjn122OuJU7^ԫ6_yޔ?[Rmɕ(o.sW:Z)i[#až)V 3}fC~N\$dim]|K(+jJ>diT>|oaH?G]|wq+}gϔO<~G>t϶xèy_G:^0w=Uw^ΣEfw&O/(((,,**..)9S 9j}ggg3&MvɌ˯su7ԇx}mؼkoo~珤_pzJǞ'_3?/_Bny_{{{RD*OL1ʋ%jOڝy3J"G-t嗖o'J2FEƲh$ Ft͘U|(e,6uY X9/4 7t c}OQ&L:\B(W(cz./V悊 Nt)S/oN͜u+uU߮z5ss뮿{xM߯^௩ ,\TyqÒPHSy[[qǝwGo[@zx#k]'cǟ϶t>OOoTjR!j2G~hǗb[u[|]/+UBZn-l/u>M&WsmjkXu NӏH|1et{:Z%ϽgW[ep:(\:(<̺ekΫpky:wN?(uWnʎ>W_}vC=dȌu}NpK_O|y؝zK:$Wq]JjfI{=2?I{]{#N59ؿ޶C_?g=*}<?*=0噴گɎ/u5{ߦ/>ގu\ ]7h0}Nw|gctzUgOj_>BǻSV:-W;mX:}ɵϵ˴?Z=(?kw ,UΡyCLulOk/j=t&m@C_{mx鶿?^:(m@\ߓTeG_yPPݶn{w -o8?N+G̹~ɍR}t@ɷl@~_Ze WN`O&}'i  gm}Cv@}}2uC?e9Og ӭ?߹`?cs~~؏ c?;~w.؏\߹`?cs~~؏ c?;~w.؏\߹`?cs~~؏ c?;~w.؏\߹`?csqDG|÷'[z9v#i^1 [2?{zsg;լ^f`7ӎrH.`CMH@(:)۬>1eSZ[3&T,;3s9Yp( 7, 6eFZ\n:CY.ooh{7 ˖NЇxrcfx}FBKjѤA[լ7mB6Y^B}u/ 5rBÒ7Q/R@6+`6G"G73c8zz!s5Klv;+ɹHԯ8lh0iqb \vȅ1m4$4m . I8a`Tm4sBST[4puL0h7. oes} 4F"[*ӈ-nt3YdNvd@[!iY.%ԞeA}׸yj4i/Pd_j4uA'~xzuáE͑m?iϮg9?K_`. koAD#pmtGpↀD~|ymTo 2P1Koɏe-.偨_ 9W\sL$jOT>y%Eq//3XS SB諮Wgʕ:cűG? BUGgʕ+! Gȹr+! Gȹr+! Gȹr+! Gȹr+! Gȹr+! Gȹr+! Gȹr+! Gȹr+! Gȹr+! Gȹr+! Gȹr+! Gȹr+! Gȹr+! Gȹr+! Gȹr+! Gȹr+! Gȹr+! Gȹr+! Gȹr+! Gȹr+! Gȹr+! Gȹr+! Gȹr>%9CheeseCutter-2.10/tunes/drvector-ftrcwby.ct000066400000000000000000000125031516216315000210140ustar00rootroot00000000000000CC2x tT՝!$×VY *q V).Ԯm L 3q2CT\F0njITP8[B*9e=st׳vA}o2 Ea,{7eKPwೣB-YcrYt_sW_`~߮߯3aQe_~o^WO-|vy}>`=mmvZ;3VUz:bTSz6|>j5g-׮.[eee۶Z\)-;uڧw}9Xe}=*wVocϞRg̅*TTj~w{:&뻫Vom`L$1[m^?unoZ}8Hc::Uǽ;1|lOKUz_eR%{mo,M?|ꙭrYOnx퇣jTyRwM2A`fZwhAl27콮\u8(W8]vJ7tߥ뺰;[;%ݹԓگ_HR{)tqv~ՙTjږ0ɽ8#mlw-oɶJrtO μk<;e{Tcd$V*yFO+yU3J:53?PS;:Ym ?x[wY wS3 ?, dOe6 q>Xv"|Ha.N]lT/TÏ臻Qetң+8QwuwU0>r>B־8Vm}mNypaºLn&랽$zZj=V+Y2NO^۳۝^*y:{Kn>"&&>i]oR++P[wXy0ok?ݙm,OhSmo*]h[ܪ4c$r;$v_mԇo<)٤[7uQglK'n۷t,+nvPJ>- { SvܗsJbqeEߔ}Or_*.U[Ϯ;uj}j#<=΅=G{ u:}JOK];'=e궾 }UNQ[)r#{ZwA˵2.^,[.gLd$&y(ǸiIM=j@f}TtIj~# pz:ژ$O+8*:oKܵ:?藋ۦWo~Y7ST2ìdl7i*OV:w_Yž-Vz %8*}N\"di <+QY,=j%=qcǩz樑S'J]w)ox(c.Kt}77ܛ~6iݻ_3{no..2yEo/䅮]OGssuso{ᒠ] Æ >|xqqIIiiY)#F,=fN&US5uY\~k_W,zmw=剧{{(׵,\~ij勓-.._Wh1&KՅ2Hݱi\O/],G]6j%,..]scĽdMjsM&2wɍ? ̣kDrX;{Orsޜ']$K]d'̕G<,O%%KEw?Jo?Ps^pӦ_pጙų/9s/wŗ+Wꂯ]h7_o]_n\,M+-֕VniO]wwso}?6>[Rcc[O~[驞r[?0ds[d$ۃm6ʶs?T7_g7:~{r7:}ڝkv9ɾE>}B||s'ל|ӀvnɭnԾuYA IYlZ/mA9?$ॺ NKc/=8BP_YA*g5?*4u?u|ߟwJSws>C']vnTy![P8o \OuC,Ϲo ΟlU~|oϟ,~]jZx_ uK-=sW_\6>`(rW~4wM9[uǾ?mUCպ;esW]jzwBsjߙp_EGeM=({E{]8ܧi%_?z<Ͼ3+07Gs ݧcwt ̄}t/qO}6 mmsZPǿ_y~/~Y~oǶϯϺЯ1J\\\\\\\\\\\\\\\\\\\\\\\\\\\2?R7ܒ'YXYbU^JڋHYVkDow0jmMF$Z5kk8U9]G[kNsԻ J%>yMWdw/?L)rƝvƄ1c&3&8axb:r,fn%>oWKZֈ#VlwWnYU_oG*,k_K}'>NL쭱:^.6pqZoY|jjВyК*kakK"J5p%\e]xNiKy(^4[ᆪA{=͞x.^kLBL]PpO'5}Wn7+CMr۫B+Í*k^)_7X$*M- mWw^x 7$_pnk<Ģv(`7D%SNݨoqB2a._Z$+-}j^WF#Hnv:NKg#҅yap%73fN1;^[ {J;&!;=kIĚ7hǖJ'#g5Pk_@l).MQ-p-yh($<%Bh^jYrBSq,4W})x({2Ukc|df2%2Ds1e}K5!'F#ѥhQ"7k쨌yoS)7qm~7˘Eb-v<|șez K Nv}.Tscˤ':MʤGv$ڒGZܫO[bKk'rA}'ξ>|^x\{N,ǚ,FZ\ܙy/gZ0%?9׎4ڗ;UO9+D.M:V=hS btȔƈ(R/34&eC `%<g꣛䩙+>cι饾/̷ Y O3!; 5I ւN³/t!9K=%4*N$d"eOmI|KϕuY}}'5M&цi2G-tWe(27ܜX& JFܞ\Y0h(.sE7>wֱOVW77 Fjz9o Y?uSY025󴗝qXG) _9NP7e߱`w}).=cUjx ?TzCøZTFZwj͔G'XH~#߲yuH}hS7x0y̞L䱰p!mg4 ;Zo ~B??e=Yx3F*'OVo3ۃ҂o?a3U:U/𣳇-bK";6h;~㩆yxm"?v6)Mֹ{0# dCƓfƎk*}6t2n:ِJ6Oۃeh#̶pZVm|9wj%L׉,-aXx+V#(+{ъV}#Zs#V0(S\+Mv\w1DkYv(6:lm4@&_eOS^/攆uszY-C5:‚p-HZ>2 CI9eٟD>e>1Faɍc*wffM',)o)xэ1oZ|{ʢeZ!o輤Y#y {#>e=M-|?仇~T5zkujj#y2^:4SzD =]t;tNY\|3r픗i-[ZVvb[VW=ʨ)S U-a9I}^=H99pM>vcZ]uXkW̱B5V}O}O+}O cL~cS>s@V 2eA2]TEmtbzSaR`7u:6,6F w"g?6!զW8ZmM hx:ϭZQ^tN+=JnRm˩/- uvz b.ҢԘ/2$_Ю1^ jLٜ&ql9#E784\nTnTѪ|)Jmq?5ph慎y:MoV7=̺ y:aқteӛ4dxSLSZ^xz7Rd[ mڡ ߤ9[L_bN^fFf f^dT}%V5"}v<9VeN6.k_.m~)_j/[^|syyYjë{ O߳^ÅI.YaIعZRޒO} Qx-v9ЌQI"fsJŒ/ց:/u߷1SiTBbuH!j%iIA;%|MvH0v_ޥCp|w^QQmR48@w )= ;(#1(eue2VW2Iw(,e2Y+U /bRRbQ+4)]Ɉ=z{EBeDY,PV*K,?3\_xqKW~?:??9ϪN9թ+uhnשe3>O_KWw݂M[w6kB:.[?~n7K]ԻIO$EXr=_W&Wit>ͶZ=6Iw/UFQ0Em#ޜJK?] g"kpE*k|f6w3k}}]K'8x$miί}}+ߣP}˷Eul>ѪP O+Nt}S($^9O'???r6GOO-i46qc7_z+]k_;Rږw~G$q _\?g#];zҾ)mq}o$zw#};t6/'oz\s~o\~߹?QJtw̾۷s缯h~eUj|?;j߭ȧ+5һ |U5?rn?M#ebm]vGꪴڶݦ?)R3,qumO6yW;/?ῸwϠn}3ҟnyA}[e6S\/ʿ޺^Pۜw}]qwq]}wUήMiUj4lϮӞqʳh~ZZ=[?;mK=yV7sZlσRR{wckן q6"6g՗~E/E{oVvggo>J:%'/o.vS_n߿x%Rڞ.{l['jVMWWwv~Ov`o&|]wmpSҾߟ4nZC߷ylu"~&_vgcsi&18WKbeټl$?f'REN|wkUTJǛ[][MYBOQ]"+r>>eIK6HOȹ+ewGNEFZMp~i+ye7_OYgjϗrޯ8iB^[(q4WJ42'qڄ±|ly'৅vlKv3.x&ʞy6Z)\%mψtS5qJM}m7_Iy'NʦErf%%ۇ7Ó3]_66wj=n8#Ҏ_4|gr_I'm1W C=6t!D]ݘqI:~/=̘ A86[y 'jqnwѸ21՛131oeͽw "B(y6lm* hNn;Y]T0HqK JQM5H{д k\O3E.8x)ygWzr7)}Y9Nٓt7P{3z ۷7 YV|nd*V+װZCp%~ĨIoOA 7on+ҷOq%ϴeQ69еhVj2ݚ[f婉/ڟ}wtܮ7zoLPͻzUtP_H_;vԽ>< >ևQTAkY߷;O\_}h'r>iKp=@ϿA_FQF)+8eICd)SɊ]J}_I%)HJFs g<,R*% eRYzd*+(ʚޞ#A=#gAPo A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A A $`oCheeseCutter-2.10/tunes/mch-cheesecatsgroove.ct000066400000000000000000000124531516216315000216100ustar00rootroot00000000000000CC2x ՝{f[>ٗʎp b4+a̙#:3ˇ+bLtuab9Fl]rS*ZN\j0*9`C~?z{w/eK=CE>K9܆\*,9{wFwa (˾\UR5dˆLR_Y_i=km^[۬1օVu[uUQ֋UۋAjkՌk&ᆴ__***6oB=POYvRW.S{~ӗ_9xX/v\Qs7xS{*qJ_5*}JLT]D.OXuKW୫e]혦6|ڗZeo˛Iu$I?v 혡Nu/'ϧ)-zO=sJY/˒P2 uWY_]jTMj4+xr%uUI/7AnNר5՚CGdr$3UO3Qv0M3W:q.*muBn u'ߔqU9j^sH⛧vܯ[2;+߹_s[x3Wkբ"m=W.եer5UCsj2Xzv3U"*&N_תת\ՎY?/e=)~2UtJ=jOЯÕu*=O}p^7>';6}LjM*u6Ζl}>ѭRs=ݣ96Z售kmKܦR5qW5rzj^*[W|C9PxK~\x[}+Lv9%~ҷ)Y:fܶHvZ/ϮHO~R;dvl#wlWHk/v9.aYs*'tG^Jݷ=[.+CEu_Yԩ9;\.-;GRu )qJ^ߥIL'{NzѳJf#}j}NɌ+^ʔÅ+{eN'dwY%/?k}vD';)ʿ4Tbˏ+Jo$f yt֡dm?%l:%~Jj=Ot Y.~BUy#A1ܨ˦/{KUW!ϯ =L{N(#J9q-~[{[TÿQn7?S)l-:57鶛túל|gA]&ҽIzdo+^N/FUdU[=a䩗O7xsp˝{dgS_χ_xzXC\(8韾Rksϧ&}*_]VeVg4<\?rxܸquQbʕzWVv6}z )FOO[[ioa,t_JzE8,Jzrqrޜ&,IzeO{D#b8ɳCDS<\T3≓.t˦~.v3f^5/\s뮛}/0<Ưk_K1`Э#ͷEc˖;[Wjkkkƽ}w<`C?{|'>w۰]O-?nL޺s-1ח;S/[;;~Rv"o~_rZs9)+|wGrT?ֵmoڛ[gYy>Ks~[Sl?Z?q뽧^9/Sxq.O$gevoכsqw(H}e|:u>w_;}ͭs;&u}?ټ^ q홾3mt\y&^oV^_{`nVfw{^(_g6B{?]ϟyS: _{?*GſC~ڝ=^%[+Fْnlon 1o_ԝ?vpd^Yo}x5ĿObޗ{_>N;~|~×Bc]7'L~X|Z7d6[wdr|~{M([{։Tɶ?}-Y˶J;=w[)C]~=p3=~}LSͅͅͅͅͅͅͅͅͅͅͅͅͅͅͅͅͅͅͅͅͅͅͅͅͅͅӿ̮z'+ZT<9q}kfYY}X5jO_%)y:GR4]yU|RPڔU귵ϊ6SQ^VQQQ^qr]<z,Ʌ)tOc<=\I:セX%o֮:}#9=-lU?"TkYGzNJ|}S![M=*^OegMcz<hXl_d 6VT[s[b@(,7Xں!(EѸ_@9pa(bǚ1kjiD{V4$h+K$]<7 nG{˦/l~Yraz`S`4"_^X\.f@}SnrVmii &.=;^lHP;(̖h @n E dgԍv^9!=KmG 񾋖5P<hcfGP !&. FcOۣ'MNGOTScG 0gU Y,iߠ9Y(ZN~HUF_é;4IZEӯ/H8n:հ(%⾐U{[j@ @8)L,պH9%,iLrjK8te}, -Px}AK8`DlWay>ަJn0*i$7nghdٸx פYez .vwuO}E2{&(Ơ і%p|lmf_r[Z;#&8 c=H84, ziq[O;2]0>@3-\!;A/ɳ%K ,D.M:&6F鄻X:ByzY)')(+h7D23o\D%(uK{{4Nh9h<8bx(Xhqb9s#/BH0Cr^°'\:>l=!v^S c.ƎÍjFoe{} 6ɋl #j_PZANÁ]LNVϬ.6-\K 2`N#r0rk`kܾ@>54$AIG}3?Sp?< -4Ӕ召Ǧc;<,He|]օx7Ū˗M˓ZիkixUI=xP <*>1E{1 X!0ߣa}".0^ ck}Vw__,-,5,>QN<|~ b]G} 1eok 4h M@?.pdQғ,MO{,D4dIқ,s~z#IXHB#bO?J#+h?J#+h?J#+h?J#+h?J#+h?J#+h?J#+h?J#+h?J#+h?J#+h?J#+h?J#+h?J#+h?J#+h?J#+h?J#+h?J#+h?J#+h?J#+h?J#+h?J#+h?J#+h?J#+hgCheeseCutter-2.10/tunes/scarzix-KnightsAndDames.ct000066400000000000000000000123601516216315000221740ustar00rootroot00000000000000CC2x}tT;3I&< O2=޵,$VbEÃ4b .֮- fdƒ]dPZFʴ%e,nJi79Cn`gf& $HCr3޹;hYWڤ\OШ{r*I}.3HKR#N'VX{bԉ/|'?߮;'aFWeߠo^*5m挪V{=Vo&[WZe25/r5U=؁Tg];mϿ; =Ekw6Q;nYuNg3~j/]~>yj[T=<񨼐tLޭ'U:)lOLH83v&?\{9*t |-Pg}?.'IJ'S{OzwRr9Btud{ge-OYW^.UۻUGe^eO&beOI}KǕPGiUwo}TAA|9srԑTx?Wd/QT`H\^tw}6Q*{-+վ1^KMOWwRqɛRW2蚒G.jJ]+^V [-{X>ٓfRz[ko>(d*ϗTd@R:]/Seͥ˽*Co}=Ǩ|53OɒQ%'KgT {clqqu*qhoJ-yJݬT{,s=ؕ~q"uIeo#CH\2YW~_y*~+/e|4%n;G_AݵH6|_׹KJӓm&Pug˄7q22׻o$7\JGץ5r(W\ƙ^35]nRm>N)_paWn?лTE9A\풒_T=ƷɽviK+*JoWTk_dfSzwYdzc7UhU-鋻UunLeFlS9J{_{GR~dW7˸w}x6ow,E {SIzf+^COLxKy}|uwmp| 5ሼyn|ᒝzyY;[7OOgl]>}]L?wY~%kun9QK/ӭn/|ΪѥIg,3{֎J4QwX?)}u)L vmVf۷e}+mf0QXs讂yD,u7?}]5[ad/GMT >s|$*ϻ]\R nQdgUң竑Of*)n_hjE=q}+ot}3^|0Tzd^c u|Y=^zWihX#m+,.-O݅EEŗ9rhϘOgrISJ?_6m7̽Eᄋ.=eG۞_q-ܣWLR~qK<_ںIӯ٘d]#qige=~)tJwžsNXh]6²JTVe9oY^ګb1.sy=~ 3/wh-l-.i-e#b#cbcexsS!!ΘMZ1w| |޽ݭ !LZ]1W| k 3!I]]>3ngsnb nZx-vEwV~iz_+sW_&P.B"Ѧk֮ >i|o=xOwp~~ ^?7?Nmr< :Gf57EVgg|nذ.?~^ }Popꉋ?/uo}p{뭾럹=,voytE~̩~ocذ\|cO2rezy]3x'};};Xu]O__ y ;>};Χ3=~/\$oBO;>:_ s%~7S?EO~~sQ?S\Oo.~7S?EO~~sQ?S\Oo.~7S?EO~~sQ?S\Oo.~7S? -oGvF|0z ׳͵6έȷUm|,XU럛} ΂}HgūqyNiyn^wg}/scMc?܅?+_e^hճ,qqv_SPQaOSTYܳ!s4)RѓqTm(yPIO=Thd]4"w3d\y\N븻pn+W,;-e67/_i_m/,+45F ,2kq@"Q;! HC`Ŋ`nlj&O*/Xg%ڨnGjS'/s{\WonԆ#ʬh b寮 `H^YMvkGN^VRTLwpAS C?Tc#UYf3ӳCv1]I hĿ<ڿқfuk( 3`LQ.t@f:i =i,9Y3˭leѰ ڍ])sa3k'hW$NG\BT+ɤu9rz|՜v,?<^P^o\_rvӾ]3qe*"PcCrʭ ]w[Z*79ڷiSUlAn 7EeP0.i kk@]sutiJ3o}dz Mv$|{P.ӷ/}end{lS-SLtvQ" Pc4Ҵ*NimAr[ND0\ ]g`/u=?FryV7!YY05^Uv֞N.4}\XfZPӪji4U^Wդߴi}/kkt]A{iZаM) oV^uHGwgi̅8ckӳG\w~gee8kv4]tm`Uu]y t.cv.i ruSQͶ5F~;'~=62ׄj=lIlh]|؋BvS(eyv5UnA'w PiY?a/n)jјxt[W߫WvW|jvGfSS=(%דa9\ùPpE]ўl/%O~l|D +"drהO.C|ע[jsͯ^'j7jD~n[u05C:m~d]c__g]mg;W`O֢XqXf9"626*6:]<11Gk^,?eB9spz\ϙɤsWkAM[>_@o9B>|\'sCbnB O 17?!'sCbnB O 17?!'sCbnB O 17?!'sCbnB O 17?!'sCbnB O 17?!'sCbnB O 17?!'sCbnB O 17?!'sCbnB O 17?!'sCbnB O 17?!'sCbnB O 17?!'sCbnB O 17?!'sCbn8O@wCheeseCutter-2.10/tunes/scarzix-cheese-around-the-clock.ct000066400000000000000000000124761516216315000235710ustar00rootroot00000000000000CC2x tT՝$䃏 se *HEÇXmT*֮-L8GE*VQQDnJKveev!vMOYzݞnϱ Ʉ yw{M9,s^|~ п|甪?t2oN`+>A/}G?߮ߛ0Ve_?>R*MvukevZX *zɺ*U&~ )V[fϾzזkkVyy-#רGIN\Õ{G>^;|۬=WmU-ޤǞ1Q%RWDJ]ST'Q^GuZY#xk#MP+:3ԖvZ%SMܡ:'nK~Y:[uZmQՙn{DNP5*i[OFɀƛۛ&Cm%]ڏ4Ӄu$Duv/U]ʊ<&׹SsT"˟N*wQy*1_nPʽAz ɚUy)Kչ6QCAW7my6SG)tOH!ZػT%+Aj^JTI!dGu\tJ+ڙK%w&*U.u*RUj _%R3fk>xW%%끭rb*uJnLL+Pdn}eDyye}#ܷ3- ueשěI.W ݓ}]5ɶek!w`kwzG_zY%vIn sغisGq$ݕk}ˤa \T]k%dOTH+=ʶGJɴ߻%;|o$V=&\hHR_T2#L\MQTBvq5oݱڋFudQ5j5-}}@6Ku jܡ.{lZksn;S!zA%WN*t  "tLv]6lٻ,ڨž_ݨ֦u2;w(׽RS]/U㷕QRXS-9}anP.[$x=D/CKݨ7#Vo^W+\i{'{G6k*uozaY"*?4EO*y^Y)L smerɶ=i)L(Ol\Y=7e~yOyYSYR%#YzuǺ|m_鲺G*>7G۱o7[Sg/Z9&!$ mJvL3z+tݢLA(QqyEr].}I7.鬫;8;IVM֑6yȤltDqSIM#jH55A*.?xK 股K2IJZ>7+VLL1q\׻2_I}3)vAyǒr,8WSh:cIoI~i  vm;Ýq39:G9ΰ\yG1ײ#lBNjmq_MG9{-4TOte_1uڕӿtՌ9kk^oJ7<﫷̿nkw|7, 7-^eh]xW\{V߻Y{{;}{o}ѶbÓOm|z3nN|o=[;_BBOB9޴V?u.ڮs/ߟWIDn}q=lO{mwBǿ?beƓ?ߗޕ-oS?"g%8V3}ɻ.|M)ߟ^G/kӔ-o6*x 78~g[lyc?>oY~gk3 uBsԟO{}ßjg^̱p٣?~OȮ7@zCM1/#Mk=yܧo|Ce[a[:>wޚwp?>0pߐymKv (|l3>> ׻q= g|;>zc[?}ކ6sǿ>iz7??>?/g.?w߁tGl̋By/ ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?̽u/l}޷ݏC߅ǚiu3g_k&Yա>slJ|%C*#Fۨ Hipx֠ҲO5tXcXBNX痞y𧂎_`5v}ks} >QXS1~uIb]x"exg jX-+& xʌz;;b/7!N7WoǂJK7H86M3oCu2f萌P9˦I]V]mFڑЊ3aέ;x){Xt xբu h\vrqWpy+z9/h$U$e楽!g.LWpS9E'ڭ`)3UkѦlddKKd\Ӗ3k6]˺hcK\D‘ĖHp"<`׭#>ަRn0ZQn$k4۱"w-,s7\fg۳I5'oDFlO3rlX!d#X˲P$>9ۜԱ.\D:\;p×ϱgG#XQgq94rŵ׺v:2#< &ex.ËY+eb'MOqz0 ")rK˝\M-Ȟg%%}-D(f3ص wF8#sQhg3蔷T8r-=\ˎ>- /">}H:ws^5yG缎~Z:^D쵽#@BI#+h?J#+h?J#+h?J#+h?J#+h?J#+h?J#+h?J#+h?J#+h?J#+h?J#+h?J#+h?J#+h?J#+h?J#+h?J#+h?J#+h?J#+h?J#+h?J#+h?J#+h?J#+h?J#+h? p?Rh5CheeseCutter-2.10/tunes/scarzix-visualbrothers.ct000066400000000000000000000120041516216315000222370ustar00rootroot00000000000000CC2xpgw_۟Y " V"jK dCVnlRF mW(#0Zioguj9Ϊי便g7!@J~ǰ<}}0Zf ),X>znϦV}e+`Nj>dÔQeߨdIWO)|fyg}^ kuUVi=o]EWՃjRz[*5gεi(Vz^lvYRoʲ׫Cu蝷<_T.nkj|;gNRϩ*WTbt%tOT:o*{}}N*ݝ]'XvsDiwGUg}aYrNح쳳T-IZ;0KɀwTHK힩ݮlQ*cr䮴_m86{;-[n21W=SաGَq_W_SgCEqSo[y"끍2 GSmI}Ձ宊wy{C#1EU5$Tr(ٝVH,p6{f}zJԡlsП٫TzJ,R[U@D\"e=]Ly9oUTD.V=\yM+GnΛUz귲ەK.w`J-VؙU'\5}TGwvYeڛG{qQB9KJTnPTb: ݕ%VW}wuįT%'KǕ,ݛUR+zTK/ꅟ{27^wJQm7e_g%6+uȧw9`9OJԮ{YhEVν3b>g_T6 ս.#%gxKʷֵO <8JL+:ɄKʌMkGH߫ZSrE'n>9IAtBfqUtJoñGw{=R5=UsO&Aߟ_m8!'H]R]cG2<)~FzV%QN*UU2BGscCv~z/ ~T=[}JueD)g4Pv{[>Tn*YKeo}?|w1p"?XHSIzd(^MOGƼQodVܧ=_ȟ]ގ:r_W)מoe{Z yxgR/ȘK+YRO('jTˊj|I>,={j^f8K?ΖOϓ5;g]u/'nx+L{a;m~ifw F==HM0/}ަ5wzks߮thaÇt1|}.?S6n%5 {MvI:.ǵ,*._1J)_B瑗\⒵>~'?fU6.د*)ozzz#֢{x/sqsOc z> uO_g~ө!_)~ 3g: `v`Gz>ʽ/?rp[O_ȿ`|,}$Puc;o;Bkh?_/S\Oo.~7S?EO~~sQ?S\Oo.~7S?EO~~sQ?S\Oo.~7S?EO~~sQ?S\Oo.~뷾5YwDޱȮ#zLQV[{}uY?c2E~ƍK";{p̊KϵAl_:|'s)) o<UV[UٰaYg:uzf$C~I{e;{wXŅ>IiT|jY!:32֥/Tm{:ĺYC=0VkWWsC֢x0 C`sZU_XShpnn *'T{^,2d7Ջq;ֿn^`;[?y|PwPcp*":*T㡘`Mcn#Ti-hilvN0>`E PdU1*EtmhFp,T*s挺ΎfZj`mć4["x8h79έ0?ͰkdrC2UXsN~o-WڑКۓreΫR3x)Xt b@=U}WP6p7rrF=NT3Xru`6\چ`$jWW(9iռ"T9/`)w9eѦ|edJKer4]gs{Yml-pd=%CuvZ;"ɧLImq7= G[XtU}&Yϙpɞl߼7ܨ>eDW1Şlvp]G㱖H|bshsO-geog$r)~}ξ1|^t\{N4E,7&g|tF{LЁ\ekNѓxڼJkNtJ=G"-+kdW}F]UiS뢫u]a{qFfhTM)$7+d׶br{>zw9G|ȩ傄N2Ѡ=֕K I,VV.JܬըxC.C=xp^Y..MPc8"Ύ/[}9gb˗BnҢ` kSʪw^}(Vv:4 6>4lN~<Cg`NC4VwckPn>"7 >ɒޤ+Y,L%%e˗$}dy"|Zt8<'6NIr@N^>C=~B'9# UB O 17?!'sCbnB O 17?!'sCbnB O 17?!'sCbnB O 17?!'sCbnB O 17?!'sCbnB O 17?!'sCbnB O 17?!'sCbnB O 17?!'sCbnB O 17?!'sCbnB O 17?!'sCbnB O 17?!'sCbnB O 17?!A?ȏFCheeseCutter-2.10/tunes/spider_jerusalem-KaeseKacker.ct000066400000000000000000000142751516216315000232220ustar00rootroot00000000000000CC2xtT՝! -OD a#$8"j&d#a&LE1N؄%p-cAd9e{Xgy97K&a@;Ӿ}{7$g=Y6ҥH++o+勫.xrq+?>q>MF,6I=ҟYQqiEE tTjޖKǤaiTKqw3'˞c҉g?aP5kRsJ]v*k]*((h8 4oJrx2k4Ƕ뺻Yd;"Q\:og,di,<5Zelic<`u9ɔɍֺRvRKx.kFk1x5o,(ճQr>7ftž^T0рĚ\!WcGJ(9+\ʘxgtdCɶ\Md[.dJglvI=\Ț] ?/~ƕ!Sؠڹ8wj*uץ Fi\%[.Eyɖd"vEFj*/w|Ԟ{qZO}<"mMCW} j$]^f5+NBw/c,1*Jos[oEE[߲ a<1\bEnŹgud1TJ]zn/[s>ˢsbɞcƿH4&JOX8b̙Mw`1 ?b+c3, e',z^#^c_ؓn 1YT90{䴨.sۿ HEOShֽ""o. yC1vj+٪&N˔-v!A`]/ :y]1a!j=NfmTн]RowoͧoZdPGuc2:qjY?iznLdpZmXJKf#mxьZ2^r$,LQʹ4ms`FKh/:rƱr l3wK.i!ۯS7.oh$wN`Yyp#Ɗ-<\cX,~}"kug_}MLn߬iDQu4P>Q}bv2Cd]-K] LwRcAw9$ ]5d_0{M.ߠr.c#&ְDцJ o2UĪds_ԷxhΧ*qwȊ4m4 njXP@GYV7>ԯo"Silm{.QV\n"Si+'6]mCω<:gÂNe:#Zz-zwRZ7xrT[:g[lk]CU|CR<ᵄ#l^AF;&5i־t{5jVV"묚(,ȧQNtkMg'DzG:l)oO9OooO7s>j_żw"'׳{MYMo6jS.cM`d999yy7Sޯ8nkCaGY2~ҔG?^W3^whl+ԯ$YYWra#FӋ̑r+ Z$˭s'iYD%yAkr.%+8];aVV|`Iw&,//eRV~ŜӏD}vyANnC-m<n 5y gewS,ʆ(NAo5N>^ ,Ex6!)>B)op '&R-ewp#.N^BCP)sDry")}xKa [2n,Cj§i|z[ǑqJ7'Lt)SMqw=359s`ރ?,|-cǿ%K*=UWxXYy2 ծ^vްqg>¶^^Wv~Ww_x?E~pƑQO= i$ZNۯNܟRޠ_aޠR=ʏqVvjAC:bH5Sm_wo,?|ۿ+#OS_vH{n=Ocy?~c/1Sesto?ϬkI[wخsBVr-N֌ZݞnƟ${{nUwҳ?3O~I[-uVVOKgװ_ͶYfm7k}6?yi?ӽ{HG][,B_b<]}IϿTw'DZSЙf{stMX;cFocdkk|(I^ʯ}/٧ϵyqK~ܰߍN-ޥiZz{FWɐz_[0L1m<ߩ=m1>$y03qOYdgt;mNgJ\/O΁{wj ރvvye?Qvޝ>v?3m}p?I-mK?-lO3{VCNEٕI?R@O"fXO=ېޕ~a齆Z~׻_Ov~B7a8}5zɤ?]%`|l΁fLǍ?&{}޳@um{=\zU6<~%{n˴O}̩3u鶿q;^kq]o6g2__w}ZӧcInmF/z'wk;kH<{ooYҬ=ӻʯ/3~}kKzҟi۟/o2w-L:zp>_e;sIߗ_~~}4Nۿ)ynݟkП}^C:s{^~~u{=nzHn^mHwm~S[v{=Cv>f{!m-|ጲC˙%kauڟi;hMā_>g1kko/ z~O2}s:Ykk~OmLC:ayayayayayayaylkC$,m,,ˍN5DZ7"gcznLڼ\qU^Υl$mW@Yz7~pןo.~@ǢKjجYRvG)ʲ.E.*VUe'Yoy;&h7&MMޔ!a}nܞGs ⭛g>r r3]Tr!Z~G~,|<3=0@ʔBe+ql2iam0(OHx(+Cj<x/`SY2b)9*UI"{*$򦊼݁ʶzh?vs=WzZ}jO?Dyj\(U"-z:g &Vi=i>"{|=~2Jbڀ;dRG/B텒7uW5#C|o !HѮᓦRçNr:e! AOH0sN'ՑC5rD{VUb źUQUO8dytfsyZyUvmM\)I26 }>U]~f]mi9VfLbfkYW׆B[.rO\N uM1`}Զn&]CkmzeLla=1X}iN5/nF"/0m#{}PvL6udLՑP㝢N} 3̖g}g7ض4>}nNZOWbd`#{{Ďxʜi*G|*ѨKV,dp ʋC7QL#/ h5hN|69zb"ԹKqu[v+K@-/ף7Pu pA7i0cfztʣ>O[ F .hFydS=rLLUjhh&NeԄVAGUx/o[R^ј;`̊lOuXښjQI9F>a4!c\E2nmQQO H/(BjZev: ]]Er'k.%$?e"9߮)|*Ƨz1| AHGAP A+?W2d^!ȼCy A+?W2d^!ȼCy A+?W2d^!ȼCy A+?W2d^!ȼCy A+?W2d^!ȼCy A+?W2d^!ȼCy A+?W2d^!ȼCy A+?W2d^!ȼCy A+?W2d^!ȼCy A+?W2d^!ȼCy A+?W2d^!ȼCy A+?W@?ёCheeseCutter-2.10/tunes/tempest-soyoudied.ct000066400000000000000000000132051516216315000211710ustar00rootroot00000000000000CC2x tTd!{^=ު J ĢAچ L %̄d" Eр_Nw%RA㴌dn)scng9a;aܹ}}\,cI=)-q2mT_2 hGw}GW}?>d(&(˾Z*.)R|e`UzilvY[xuɗU6(u*JXZj֬J˦vo(P{$@P2R%.UDz3ﭾjakݖSc\њco*^-`Sˆ=>+V{Mҭzd(^ICcmWo$*Bζ@Ka{-9ofƼ!k+!I`_*ml%:$|$.V韫Ȓ5N79QסlTM(m6TJ4u$r>;$NEt얶;R-ѯMɝCK۞";wJ8Vw@ ;"y{w(3βܲ{^CnYטYPwl\2} }Nr+.d3^Z6}~rT9 zs2B/Mɡx ^I&sO>ƕ>{WrXrtrxrDҟK Ez\\98B撲)_˯:W}yהϼv\njM7mow7nvPբ%Kkvy$Z!xʻVﮉ޺{o}nٴG{-[|.m~{?;~,~6ؓ0sz;?k^oUnv2N;ؗY]Uѩ?ͬ鴹B[r4yWw7*zow+̦0h{ׇݭm'Nن.s07Aydk=2gM'b@4׿szm9 y.{esA/_6BNg *r{z:w5};7{q1WS۾:޽_+<{zw^ݣ}Z/z]ܻǵ;{_|nܻqcGVyK|N}dˁ}sT#gɫʵr>v9}u@k]2ڞ{/:{Ϻ]Ͽqߋ^>?*;Y9Ԟ4>{ypypC<Pig ws;Uf#늗'׾?Oֽ\5<|e=~|Zy߾>U~0g5q}I9N9绠nCoez=N;9Nyyg@swX߃޹z7}i|f=w[Ί^۝:{Hn:nļ={@׿N'}v=]N>dž>L}Kk3z_}g߯QoyovmGԇB?<{O?p?1777777777777777777777777k{o%Xm_Upx \;u#&1gù=σV[/ɿmj|-,c;rYC֝#G;?? 51#p/XEB3[ccH`n5r1kc xvR*_{U]<*;3cТe%ЪRk^cC,T-p!\jS}̎ =T_^&j7ԅËK'\XVfϰ/ԇm/y]im_ /,g/,#7ff[^ 6J݋+CwK95p}k6lEk"rUjmm4NV{-yb#wk|iwChEۋkËU;Ψ/#vqqs}^cU>(uEnjBv3`8h,<ݾJ o/}eӤ ]VVf'`w;/fGuKe$ڋ)dMIP,5X}p$6mmvWҋ-HSt1\eϻa=+Gkez4t.ԸΩq} &{ ݟjU2StOSj͊._c$ҸJM^jWzѦt^. %uLoR=IaY^Y#<3gKq\˝Ql hh},8jXM8[]<': XsC:;F6Kh7{.9[=fIDS\U@nOiIKD`zvpv[RdWLb+6ݕt2;\[*ٝ2z{RU͒% 9Î%VLNgVõՓwՆ"R~1ވ't-I+S:'O;% u>x[# vc$VS+ i%DHI`?ai7OTr*>XE7w-e՟MZ՗^RwS#*=xL |>0(2 Q{UQ믕5RXxy]X-N5yQ{oo!{0iz~ohL9*X_~zHI)ǨO+{y#c!Ҕ,ɜdn2'/?cl\cljx%%G''G$ɼx^0^~ϕc`!4JB%!sE#d"2W?BG\+!sE#d"2W?BG\+!sE#d"2W?BG\+!sE#d"2W?BG\+!sE#d"2W?BG\+!sE#d"2W?BG\+!sE#d"2W?BG\+!sE#d"2W?BG\+!sE#d"2W?BG\+!sE#d"2W?BG\+!sE#d"2W?BG\+!sE#d8C٦uOCheeseCutter-2.10/tunes/vent-arkijuusto.ct000066400000000000000000000142661516216315000206700ustar00rootroot00000000000000CC2xtT՝_2 !?\C)+DiAFڵ 0&1PcS+F#0Œ]Yk-9=szYv{N y3R|{fr0 2%6eү9'$żb[cbҏxDZɒO'5\7 7]VMUgϪ_I 7_EqEh3^4v ƥPjZVƗJ*Sӧ_>tRjE^hV㡫Cv _*u=#P6oUlsXHETRJ'֜p:֜1j^k|n-/c]ٚQu4c ^z%Rm";Gz$c5Gǯ9&ݪTbt-r^ yCyUW2O;og[R}%Wfj76imCvoG =!+t۲-k-lw\[K|Yo;^*oK~G*TRIv^?m zzf;xɣy|u|ޥNrx4yB~~~^ z.,,*:O߾{ 4xȰ_0¼pԘp)ߜv 7ruZm;uT5N8g'B3 ݀` c ۟:TV?9;}_S[}2* QWEcOF[1!k%M;eG.c kXZօv|<dSV>З] M+'Mj׿1WMfkg^w U~M7-sۿw|s*//\8pʥjjCu˖߽b奔U׬?~`݃=G7<'6=yKXOo}۞vs,6E!2c8Mktxb|KSj|49 Os:G4\&O}}kpbssZ<:z#A7y687&s79!:XN;zUeMG9plSZañf9ZDwtc_rVJ|g?/9z}ޙ/y6ݟQߺƢJaιm0|7O3?Mrltέnηd'Bz8ORŸ}~~sߣ9~Y'sq=^5y$ѯ}1q|Z;vYy:Ng|x}Ͽ{gb[ NXk o8G 8iTww;LOoh'3C:z$;7uS'&'l8?O,&[ᖌ3v%g.ߙѹ9Os$R®֦ϩgC[zHC~N<+g<vW>9c(:VF{Oef덶ݯ:u3^}J\g{y9ɻK΁1%>ו8>|I؛y8϶'>$x%=|]'{~_eXH_Q>UgwaO<{eM[NL_넫3/xn{/Ȭl?G]\wԵ=]/9qߪON~3Vw9=:O|SޓӐmM7imy vȼM.9rD{xv4$YyOpl)زݸG|?!oYYYSW7zV =(}6z 9=eyS:<# )Qx&76Ne͝-:>7u4- %G[C[Wwi4 V?]g>lx S`l4 7x~rа#F6DL |󗘗3}+sjC@P"nW}-~ ~T- T~GS͉Rdu!&7Y]YgFΔi+}+e:i>5ܷ̿fxcf21㫨U\7fU#M Θsn1e*1i6<u5P*h |}5>Iv,0Bm}mQ3uPo~3YnB_Ymw89ySBP+.4G]>Y*5RccY 96nJL{VvZ$HGr-ׄA XjQWisJJ3'kcX21ۧ]=96!$LT11:ͱEA '\9"6ŜP_"+'hoS}4,+nj6˂ lFls⻲Fg-3աŲ-nԘc+%'rZƤOrbghq+}A)PBR}e@۸9Vn5zf*}bqurQRQOIǼ.XkCJrws1jkn‹Uj\|CNDxjoUFv՚NU;.~[Ilw>}#/d?(", YW'oؐfm y|^_Ne&;ed]X Mwήonw5Z_Mw 3~'i5'޼fQ$f#7Wǿ8}IPmBIO!ү=rp.c c ۟:TV?9;}_S[}2* QWEcOF[1!k%M;eG.c kXZօv|<dSV>З]V{ʖ+! GȽr+! GȽr+! GȽr+! GȽr+! GȽr+! GȽr+! GȽr+! GȽr+! GȽr+! GȽr+! GȽr+! GȽr+! GȽr+! GȽr+! GȽr+! GȽr+! GȽr+! GȽr+! GȽr+! GȽr+! GȽr+! GȽr+! GȽrN*gCheeseCutter-2.10/tunes/wisdom-Adrift.ct000066400000000000000000000121311516216315000202140ustar00rootroot00000000000000CC2xtT՝d"\{xkY *?*G#҅ҵI2)a&N& mX+eM\Y 2¸ݜSxUOw=n`~I Ïua8w}{eA)Kam>r)I}6=OK?SCVcc`}濿K>d:[MP}*P -:y3zknzk&XW[m֋ֵ7*U6(kêm_j5{US쾦SSSJKK;[oQ{Qևw=%oRɂn.k_j gNRϪč*ZUtrErOTK{{Aw䮉*ucWALG]Ul/*.V]х]g.C?Rcȉt3aϞEŭ}w(\)H]q.VfTqҕTsrxͼjZ4}WQ 3QOLQO9lKQUCuxww219z[8:J}u T[+\7*閇Qiz뼲xSrꔐwT=pS]g*JtR3J<= =El{t7Y\ޭzr7五QFwF ={*qT;U;J =Y():Ue;u۝a[N 3.[$x=J%֋|{k_*Y!iwgݝt NQ O wN>}Xi\딏&n4zJV7e(YQ0MV\7>O7Ug3|[Uަuj}Kboj:t6M+ܣN: y*{X+_$E}_ź댷anYPÊK^׺K {J={(]7].);.3w=+(~YȮ,\HIw7cVHy/8nu:v ,.Х3U9F.pEcw%+N&h^vu[w0j0]t)JGTseWAK_ҍMw,Iog+TUm$-4n):"Hu}$񆚹Am)Zre{Tm~*u4nMPTT4hР⒒KKRV6tgF^?g_5~b*'_?uͳns=]l{b=͇'_K.=eUv[nk%!'wq!抹v;NsX8X, IYj@tbQlP!3VeYlS,{,CċgjuSƩӦM3oz֭6; 5w/ݳpWח,-|cE`psemC{wޣxOMڲۢt;~wv=wTjj'!4hR>Kσdgr]?|}z溞|z#^?zվ~޿fsr?)fϱgns?:ϵ]?cOڟϳ'9=~g]kݬY˚|3tnϳ~[Yay ]HFAI3b{5I':m5TAwm~GtiKҭNYڧ 5XkNjXا.>u%ֆB"kc~t_0t1W^\̊D|u+k9:ߚJkAKsJ=F_i㗢pĎiK/_, 㫪{nطog*KxA!b˦;|zn_1j\sѷ^kl۟Y^[oWVZso7A946 4dz ^p7$̝Ii "P@_*ӣꌺ :f'ĊsuHW9}U33|v3ty=/P+ChhW_?M:?*k~&H=)r;$!;#k27h ΈGj5P?׾ٙUOT%-NGsF_2/Xwn/7+}+N4=]+MYоB})K&jDvn&KZ"tMqems%"Z2{RK 5vPϵ)LM6B-v8xI9 .Ӄ[wҷ\.#QL+t|QE8PHe?؜mԱ.vF"L8q;سCH8(ӳ,hmNۜ՜ί{AE恞5vuLdέfVk$زVM4ZCZZ:u*@АMѓ䗇ZaG73k$zz">RgU=ޘi7dt~(9>;5I |N /ku32!9[=9,(7V"2Ͱ'7GdE :1Ɖl`}L]^"e#[%ۓj˖?șv 71wGgV*75 F ̈7Z&z'ɫF?FD?y:(8)_<=-f% 4s,i?Y$Ӄ~^tOT jN.WIwu .T]VtrEo׿jU-崈I'X.]tv./)dV}8srGKI @=iQ>&Og}..s9藿Ss_[qrSkn>[9W\pW_1sw>% >\7 \\1qz+!) TnP, ybc#b#cbccbc=>DxƊ,weϕ{|x}/Ds%͕G4W\Ds%͕G4W\Ds%͕G4W\Ds%͕G4W\Ds%͕G4W\Ds%͕G4W\Ds%͕G4W\Ds%͕G4W\Ds%͕G4W\Ds%͕G4W\Ds%͕G4W\Ds%͕G4W\Ds%͕G4W\Ds%͕G4W\Ds%͕G4W\Ds%͕G4W\Ds%͕G4W\Ds%͕G4W\Ds%͕G4W\Ds%͕G4W\Ds%͕G4W\Ds%͕G4W\Ds%͕G4W\.ن