diff options
-rw-r--r-- | LICENCE | 340 | ||||
-rw-r--r-- | Makefile | 173 | ||||
-rw-r--r-- | README | 22 | ||||
-rw-r--r-- | data/alert.raw | bin | 0 -> 38264 bytes | |||
-rw-r--r-- | data/bigdrop.raw | bin | 0 -> 67456 bytes | |||
-rw-r--r-- | data/bigfont.ppm | bin | 0 -> 115215 bytes | |||
-rw-r--r-- | data/drop.raw | bin | 0 -> 25718 bytes | |||
-rw-r--r-- | data/gameover.raw | bin | 0 -> 101392 bytes | |||
-rw-r--r-- | data/illegal.raw | bin | 0 -> 31148 bytes | |||
-rw-r--r-- | data/row.raw | bin | 0 -> 26992 bytes | |||
-rw-r--r-- | data/swap.raw | bin | 0 -> 12130 bytes | |||
-rw-r--r-- | makefont/Makefile | 11 | ||||
-rw-r--r-- | makefont/hockey.ttf | bin | 0 -> 46560 bytes | |||
-rw-r--r-- | makefont/makefont.c | 330 | ||||
-rw-r--r-- | source/jewels.c | 2469 |
15 files changed, 3345 insertions, 0 deletions
@@ -0,0 +1,340 @@ + 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. + + <one line to give the program's name and a brief idea of what it does.> + Copyright (C) 19yy <name of author> + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public 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) 19yy 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. + + <signature of Ty Coon>, 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. diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..da03702 --- /dev/null +++ b/Makefile @@ -0,0 +1,173 @@ +#--------------------------------------------------------------------------------- +# Clear the implicit built in rules +#--------------------------------------------------------------------------------- +.SUFFIXES: +#--------------------------------------------------------------------------------- +# prevent deletion of implicit targets +#--------------------------------------------------------------------------------- +.SECONDARY: +#--------------------------------------------------------------------------------- + +ifeq ($(strip $(DEVKITPPC)),) +$(error "Please set DEVKITPPC in your environment. export DEVKITPPC=<path to>devkitPPC") +endif + +include $(DEVKITPPC)/wii_rules + +#--------------------------------------------------------------------------------- +# TARGET is the name of the output +# BUILD is the directory where object files & intermediate files will be placed +# SOURCES is a list of directories containing source code +# INCLUDES is a list of directories containing extra header files +#--------------------------------------------------------------------------------- +TARGET := $(notdir $(CURDIR)) +BUILD := build +SOURCES := source +DATA := data +TEXTURES := textures +INCLUDES := + +#--------------------------------------------------------------------------------- +# options for code generation +#--------------------------------------------------------------------------------- + +CFLAGS = -O3 -Wall $(MACHDEP) $(INCLUDE) +CXXFLAGS = $(CFLAGS) + +LDFLAGS = -g $(MACHDEP) -Wl,-Map,$(notdir $@).map + +#--------------------------------------------------------------------------------- +# any extra libraries we wish to link with the project +#--------------------------------------------------------------------------------- +LIBS := -lwiiuse -lbte -lasnd -lfat -logc -lm + +#--------------------------------------------------------------------------------- +# list of directories containing libraries, this must be the top level containing +# include and lib +#--------------------------------------------------------------------------------- +LIBDIRS := $(PORTLIBS) + +#--------------------------------------------------------------------------------- +# no real need to edit anything past this point unless you need to add additional +# rules for different file extensions +#--------------------------------------------------------------------------------- +ifneq ($(BUILD),$(notdir $(CURDIR))) +#--------------------------------------------------------------------------------- + +export OUTPUT := $(CURDIR)/$(TARGET) + +export VPATH := $(foreach dir,$(SOURCES),$(CURDIR)/$(dir)) \ + $(foreach dir,$(DATA),$(CURDIR)/$(dir)) \ + $(foreach dir,$(TEXTURES),$(CURDIR)/$(dir)) + + +export DEPSDIR := $(CURDIR)/$(BUILD) + +#--------------------------------------------------------------------------------- +# automatically build a list of object files for our project +#--------------------------------------------------------------------------------- +CFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.c))) +CPPFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.cpp))) +sFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.s))) +SFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.S))) +BINFILES := $(foreach dir,$(DATA),$(notdir $(wildcard $(dir)/*.*))) +SCFFILES := $(foreach dir,$(TEXTURES),$(notdir $(wildcard $(dir)/*.scf))) +TPLFILES := $(SCFFILES:.scf=.tpl) + +#--------------------------------------------------------------------------------- +# use CXX for linking C++ projects, CC for standard C +#--------------------------------------------------------------------------------- +ifeq ($(strip $(CPPFILES)),) + export LD := $(CC) +else + export LD := $(CXX) +endif + +export OFILES := $(addsuffix .o,$(BINFILES)) \ + $(addsuffix .o,$(TPLFILES)) \ + $(CPPFILES:.cpp=.o) $(CFILES:.c=.o) \ + $(sFILES:.s=.o) $(SFILES:.S=.o) + +#--------------------------------------------------------------------------------- +# build a list of include paths +#--------------------------------------------------------------------------------- +export INCLUDE := $(foreach dir,$(INCLUDES),-I$(CURDIR)/$(dir)) \ + $(foreach dir,$(LIBDIRS),-I$(dir)/include) \ + -I$(CURDIR)/$(BUILD) \ + -I$(LIBOGC_INC) + +#--------------------------------------------------------------------------------- +# build a list of library paths +#--------------------------------------------------------------------------------- +export LIBPATHS := $(foreach dir,$(LIBDIRS),-L$(dir)/lib) \ + -L$(LIBOGC_LIB) + +export OUTPUT := $(CURDIR)/$(TARGET) +.PHONY: $(BUILD) clean + +#--------------------------------------------------------------------------------- +$(BUILD): + @[ -d $@ ] || mkdir -p $@ + @$(MAKE) --no-print-directory -C $(BUILD) -f $(CURDIR)/Makefile + +#--------------------------------------------------------------------------------- +clean: + @echo clean ... + @rm -fr $(BUILD) $(OUTPUT).elf $(OUTPUT).dol +#--------------------------------------------------------------------------------- +run: + wiiload $(OUTPUT).dol + +#--------------------------------------------------------------------------------- +else + +#--------------------------------------------------------------------------------- +# main targets +#--------------------------------------------------------------------------------- +$(OUTPUT).dol: $(OUTPUT).elf +$(OUTPUT).elf: $(OFILES) + +#--------------------------------------------------------------------------------- +# This rule links in binary data with the .bin extension +#--------------------------------------------------------------------------------- +%.bin.o : %.bin +#--------------------------------------------------------------------------------- + @echo $(notdir $<) + $(bin2o) + +#--------------------------------------------------------------------------------- +%.tpl.o : %.tpl +#--------------------------------------------------------------------------------- + @echo $(notdir $<) + @$(bin2o) + + +-include $(DEPSDIR)/*.d + +#--------------------------------------------------------------------------------- +endif +#--------------------------------------------------------------------------------- + +#--------------------------------------------------------------------------------- +# This rule links in binary data with the .raw extension +#--------------------------------------------------------------------------------- +%.raw.o : %.raw +#--------------------------------------------------------------------------------- + @echo $(notdir $<) + $(bin2o) + +#--------------------------------------------------------------------------------- +# This rule links in binary data with the .ppm extension +#--------------------------------------------------------------------------------- +%.ppm.o : %.ppm +#--------------------------------------------------------------------------------- + @echo $(notdir $<) + $(bin2o) + +-include $(DEPENDS) + + + +test: + make + wiiload *.dol @@ -0,0 +1,22 @@ +Jewels by David Ashley +dashxdr@gmail.com +http://www.xdr.com/dash + +http://www.linuxmotors.com + +Game based on gljewels: +http://www.linuxmotors.com/gljewel/ + +Just do "make" in this directory and it should build, if you've got a +correct Wii devkitPro setup. + + +CHANGELOG: + +---- v100, September 2010 +Initial release + +---- v101, October 15, 2010 +Updated icon from bg4545 +Improved count mechanism, more accurate number of moves shown +Code for enabling cheat mode when 'b' is pressed, but disabled by default diff --git a/data/alert.raw b/data/alert.raw Binary files differnew file mode 100644 index 0000000..f0a5bf4 --- /dev/null +++ b/data/alert.raw diff --git a/data/bigdrop.raw b/data/bigdrop.raw Binary files differnew file mode 100644 index 0000000..384f512 --- /dev/null +++ b/data/bigdrop.raw diff --git a/data/bigfont.ppm b/data/bigfont.ppm Binary files differnew file mode 100644 index 0000000..2719080 --- /dev/null +++ b/data/bigfont.ppm diff --git a/data/drop.raw b/data/drop.raw Binary files differnew file mode 100644 index 0000000..4a5fced --- /dev/null +++ b/data/drop.raw diff --git a/data/gameover.raw b/data/gameover.raw Binary files differnew file mode 100644 index 0000000..46b9d27 --- /dev/null +++ b/data/gameover.raw diff --git a/data/illegal.raw b/data/illegal.raw Binary files differnew file mode 100644 index 0000000..17cfd1e --- /dev/null +++ b/data/illegal.raw diff --git a/data/row.raw b/data/row.raw Binary files differnew file mode 100644 index 0000000..03cc7b5 --- /dev/null +++ b/data/row.raw diff --git a/data/swap.raw b/data/swap.raw Binary files differnew file mode 100644 index 0000000..5613cd4 --- /dev/null +++ b/data/swap.raw diff --git a/makefont/Makefile b/makefont/Makefile new file mode 100644 index 0000000..28b5601 --- /dev/null +++ b/makefont/Makefile @@ -0,0 +1,11 @@ +CC = gcc +#DFLG = -g +CFLAGS = $(DFLG) -O2 -Wall $(shell sdl-config --cflags) +LDFLAGS = $(DFLG) $(shell sdl-config --libs) -lSDL_ttf + +all: makefont +makefont: makefont.c +clean: + rm -f *.o makefont +test: all + ./makefont diff --git a/makefont/hockey.ttf b/makefont/hockey.ttf Binary files differnew file mode 100644 index 0000000..ce7da93 --- /dev/null +++ b/makefont/hockey.ttf diff --git a/makefont/makefont.c b/makefont/makefont.c new file mode 100644 index 0000000..5480fb6 --- /dev/null +++ b/makefont/makefont.c @@ -0,0 +1,330 @@ +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> +#include <signal.h> +#include <stdarg.h> +#include <math.h> +#include <fcntl.h> + +#include <SDL.h> +#include <SDL/SDL_ttf.h> + +#define XSIZE 1200 +#define YSIZE 32 + +Uint32 gridcolor,xcolor,ocolor,white; + +int mousex,mousey; + +int bgr=0, bgg=00, bgb=0; +int fgr=255, fgg=255, fgb=255; + + +SDL_Surface *readppm(char *name) +{ +char line[1024*3], *p; +int width=0, height=0; +int len; +SDL_Surface *s; +int x; +unsigned char *put; +FILE *f; +void *res; + + f=fopen(name, "r"); + if(!f) + { + fprintf(stderr, "Couldn't open %s\n", name); + exit(-1); + } + p=fgets(line, sizeof(line), f); // P6 + if(!p || strncmp(p, "P6", 2)) + { + fclose(f); + fprintf(stderr, "Not ppm file %s\n", line); + exit(-1); + } + res=fgets(line, sizeof(line), f); // 480 270 + sscanf(line, "%d %d", &width, &height); + res=fgets(line, sizeof(line), f); // 255 + + s = SDL_AllocSurface(SDL_SWSURFACE, width, height, 24, + 0x0000ff, 0x00ff00, 0xff0000, 0x0); + + x=0; + put = s->pixels; + + while((len = fread(line, 1, sizeof(line), f)) > 0) + { + p=line; + while(len>0) + { + int r,g,b; + r=*p++; + g=*p++; + b=*p++; + put[x++] = r; + put[x++] = g; + put[x++] = b; + if(x==width*3) + { + x = 0; + put += s->pitch; + } + len-=3; + } + } + fclose(f); + return s; + +} + + + +SDL_Surface *thescreen; +void clear(SDL_Surface *s) +{ +int i,c; + c = SDL_MapRGB(s->format, bgr, bgg, bgb); + for(i=0;i<s->w;++i) + *(unsigned short *)(s->pixels+i*2) = c; + for(i=1;i<s->h;++i) + memcpy(s->pixels + i*s->pitch, s->pixels, s->w*2); + +} +inline void colordot(SDL_Surface *s, unsigned x,unsigned y,int c) +{ + if(x<s->w && y<s->h) + *((uint32_t *)s->pixels+y*thescreen->pitch/4+x)=c; +} + + +void scrlock(SDL_Surface *s) +{ + if(SDL_MUSTLOCK(s)) + { + if ( SDL_LockSurface(s) < 0 ) + { + fprintf(stderr, "Couldn't lock display surface: %s\n", + SDL_GetError()); + return; + } + } +} +void scrunlock(SDL_Surface *s) +{ + if(SDL_MUSTLOCK(s)) + SDL_UnlockSurface(s); +} +void copyup(SDL_Surface *s) +{ + SDL_UpdateRect(s, 0, 0, 0, 0); +} + +Uint32 maprgb(int r,int g,int b) +{ + return SDL_MapRGB(thescreen->format,r,g,b); +} + + +void circle(SDL_Surface *s, int cx,int cy,int radius,int c) +{ +int x,y,e; + + x=0; + y=radius; + e=3-(radius<<1); + while(x<=y) + { + colordot(s, cx+x,cy+y,c); + colordot(s, cx-x,cy+y,c); + colordot(s, cx+x,cy-y,c); + colordot(s, cx-x,cy-y,c); + colordot(s, cx+y,cy+x,c); + colordot(s, cx-y,cy+x,c); + colordot(s, cx+y,cy-x,c); + colordot(s, cx-y,cy-x,c); + if(e<0) + e+=(x<<2)+6; + else + { + e+=((x-y)<<2)+10; + --y; + } + ++x; + } +} + + +#define JUST_CENTER 0 +#define JUST_LEFT 1 +#define JUST_RIGHT 2 + +void text_to(SDL_Surface *dest, TTF_Font *font, int x, int y, int just, + char *fmt, ...) +{ +SDL_Surface *s; +SDL_Rect r; +char text[256]; +va_list ap; +SDL_Color tc = {fgr, fgg, fgb, 0}; + + + va_start(ap, fmt); + vsnprintf(text, sizeof(text), fmt, ap); + va_end(ap); + + s = TTF_RenderUTF8_Blended(font, text, tc); + r.x = x; + if(just == JUST_CENTER) + r.x -= s->w/2; + else if(just == JUST_RIGHT) + r.x -= s->w; + + r.y = y - s->h/2; + SDL_BlitSurface(s, 0, dest, &r); + SDL_FreeSurface(s); +} + +struct state { + SDL_Surface *surface; + SDL_Surface *pictures; + TTF_Font *bigfont, *smallfont; + int mousex, mousey; +}; + +int writeppm(SDL_Surface *thescreen, char *name) +{ +int ofile; +unsigned char text[8192],*p; +char temp[128]; + +uint32_t *take; +int i,j; +int res; + + ofile=open(name,O_WRONLY|O_CREAT|O_TRUNC,0644); + if(ofile<0) return -1; + sprintf(temp,"P6\n"); + res=write(ofile,temp,strlen(temp)); + sprintf(temp,"%d %d\n", thescreen->w, thescreen->h); + res=write(ofile,temp,strlen(temp)); + sprintf(temp,"255\n"); + res=write(ofile,temp,strlen(temp)); + take=(void *) thescreen->pixels; + j=thescreen->h; + while(j--) + { + p = text; + for(i=0;i<thescreen->w;++i) + { + SDL_GetRGB(take[i],thescreen->format,p,p+1,p+2); + p+=3; + } + res=write(ofile,text,p-text); + take+=thescreen->pitch / sizeof(*take); + } +//printf("%d\n", thescreen->format->BytesPerPixel); + return 0; +} + +void paint_all(struct state *st) +{ +SDL_Surface *s = st->surface; +int x, y; +char *p; +SDL_Surface *ts; +SDL_Color tc = {255, 255, 255, 0}; +SDL_Rect r; +int gap = maprgb(255,0,255); + + scrlock(s); + clear(s); + p="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789.!:>^@() + "; +// p="uvwxyz0123456789.!:>^@() + "; + +// text_to(s, st->bigfont, 0, 15, JUST_LEFT, "foo!"); + + x = 0; + while(*p) + { + char text[2]; + text[0] = *p++; + text[1] = 0; + ts = TTF_RenderUTF8_Blended(st->bigfont, text, tc); + r.x = x+1; + r.y = 15 - ts->h / 2; + SDL_BlitSurface(ts, 0, s, &r); + for(y=1;y<s->h-2;++y) + colordot(s, x, y, gap); + x += ts->w+1; + SDL_FreeSurface(ts); + } + + scrunlock(st->surface); + copyup(st->surface); + writeppm(s, "/tmp/font.ppm"); +exit(0); + +} + + + + +int main(int argc,char **argv) +{ +int first; +int code; +SDL_Event event; +Uint32 videoflags; +struct state st; + + if ( SDL_Init(SDL_INIT_VIDEO) < 0 ) + { + fprintf(stderr, "Couldn't initialize SDL: %s\n",SDL_GetError()); + exit(1); + } + videoflags = 0; + thescreen = SDL_SetVideoMode(XSIZE, YSIZE, 32, videoflags); + if ( thescreen == NULL ) + { + fprintf(stderr, "Couldn't set display mode: %s\n", + SDL_GetError()); + exit(5); + } + + TTF_Init(); + + memset(&st, 0, sizeof(st)); + st.surface = thescreen; +// st.pictures = readppm("animals.ppm"); + st.bigfont = TTF_OpenFont("hockey.ttf", 30); + st.smallfont = TTF_OpenFont("hockey.ttf", XSIZE/16); + + + first=0; + + for(;;) + { + usleep(50000); + paint_all(&st); + while(SDL_PollEvent(&event)) + { + switch(event.type) + { + case SDL_MOUSEMOTION: + mousex=event.motion.x; + mousey=event.motion.y; + break; + case SDL_MOUSEBUTTONDOWN: + break; + case SDL_KEYDOWN: + code=event.key.keysym.sym; + if(code==SDLK_ESCAPE) exit(0); + break; + } + } + } + return 0; +} diff --git a/source/jewels.c b/source/jewels.c new file mode 100644 index 0000000..906ad10 --- /dev/null +++ b/source/jewels.c @@ -0,0 +1,2469 @@ +/*--------------------------------------------------------------------------------- + + Jewels by David Ashley + +---------------------------------------------------------------------------------*/ + +#include <stdio.h> +#include <stdlib.h> +#include <stdarg.h> +#include <string.h> +#include <malloc.h> +#include <math.h> +#include <fcntl.h> +#include <unistd.h> +#include <gccore.h> +#include <wiiuse/wpad.h> +#include <asndlib.h> +#include "alert_raw.h" +#include "bigdrop_raw.h" +#include "drop_raw.h" +#include "gameover_raw.h" +#include "illegal_raw.h" +#include "row_raw.h" +#include "swap_raw.h" +#include "bigfont_ppm.h" + +#define DEFAULT_FIFO_SIZE (256*1024) + +static void *frameBuffer[2] = { NULL, NULL}; +GXRModeObj *rmode; + +void drawstring(Mtx44 view, f32 x, f32 y, f32 z, + f32 scale, int alignment, char *fmt, ...); +void jmap(f32 *destx, f32 *desty, f32 *destz, f32 x, f32 y); + +static GXColor litcolors[] = { + { 0xD0, 0xD0, 0xD0, 0xFF }, // Light color 1 + { 0x40, 0x40, 0x40, 0xFF }, // Ambient 1 + { 0x80, 0x80, 0x80, 0xFF } // Material 1 +}; + +void setlight(Mtx44 view,u32 theta,u32 phi,GXColor litcol, GXColor ambcol, + GXColor matcol) +{ + GXLightObj MyLight0; + + guVector l0pos={-100.0f, 100.0f, 200.0f}; + GX_InitLightPos(&MyLight0, l0pos.x, l0pos.y, l0pos.z); +//GX_InitLightShininess(&MyLight0, 255); // between 4 and 255 !!! +//GX_InitSpecularDir(&MyLight0, 0.0, 0.0, 0.0); +#define LC 240 + GX_InitLightColor(&MyLight0, (GXColor) { LC, LC, LC, 0xFF }); + GX_InitLightSpot(&MyLight0, 0.0f, GX_SP_OFF); + GX_InitLightDistAttn(&MyLight0, 20.0f, 1.0f, GX_DA_MEDIUM); // DistAttn = 20.0 & Brightness=1.0f (full) + GX_LoadLightObj(&MyLight0, GX_LIGHT0); + + /////////////////////// Turn light ON //////////////////////////////////////////////// + GX_SetNumChans(1); + GX_SetChanCtrl(GX_COLOR0A0, GX_ENABLE, GX_SRC_REG, GX_SRC_REG, GX_LIGHT0, GX_DF_CLAMP,GX_AF_SPOT); //4th param is where come from the material color (REG(with setChanMatColor or VTX (vertex)) same for ambiant (3th param) + + /////////////////////// Define MAterial and Ambiant color and draw object ///////////////////////////////////// +#define AMB 0x20 + GX_SetChanAmbColor(GX_COLOR0A0, (GXColor) { AMB, AMB, AMB, 0xFF}); +#define MAT 255 + GX_SetChanMatColor(GX_COLOR0A0, (GXColor) { MAT, MAT, MAT, 0xFF}); +} + +void light_brighter(void) +{ +#define BRIGHTER 0x80 + GX_SetChanAmbColor(GX_COLOR0A0, (GXColor) { BRIGHTER, BRIGHTER, BRIGHTER, 0xFF}); +} + +void light_regular(void) +{ + GX_SetChanAmbColor(GX_COLOR0A0, (GXColor) { AMB, AMB, AMB, 0xFF}); +} + +f32 coords[60][3]={ +{-0.449358F,0.730026F,0.514918F}, +{-0.277718F,0.201774F,0.939234F}, +{-0.277718F,-0.201774F,0.939234F}, +{-0.555436F,0.403548F,0.727076F}, +{-0.555436F,-0.403548F,0.727076F}, +{-0.833155F,0.201774F,0.514918F}, +{-0.833155F,-0.201774F,0.514918F}, +{0.106079F,-0.326477F,0.939234F}, +{0.212158F,-0.652955F,0.727076F}, +{-0.449358F,-0.730026F,0.514918F}, +{-0.065560F,-0.854729F,0.514918F}, +{0.343279F,0.000000F,0.939234F}, +{0.686557F,0.000000F,0.727076F}, +{0.555436F,-0.652955F,0.514918F}, +{0.792636F,-0.326477F,0.514918F}, +{0.661515F,0.730026F,-0.171639F}, +{0.898715F,0.403548F,-0.171639F}, +{0.489876F,0.854729F,0.171639F}, +{0.964275F,0.201774F,0.171639F}, +{0.555436F,0.652955F,0.514918F}, +{0.792636F,0.326477F,0.514918F}, +{-0.489876F,0.854729F,-0.171639F}, +{-0.106079F,0.979432F,-0.171639F}, +{-0.661515F,0.730026F,0.171639F}, +{0.106079F,0.979432F,0.171639F}, +{-0.065560F,0.854729F,0.514918F}, +{-0.964275F,-0.201774F,-0.171639F}, +{-0.964275F,0.201774F,-0.171639F}, +{-0.898715F,-0.403548F,0.171639F}, +{-0.898715F,0.403548F,0.171639F}, +{-0.106079F,-0.979432F,-0.171639F}, +{-0.489876F,-0.854729F,-0.171639F}, +{0.106079F,-0.979432F,0.171639F}, +{-0.661515F,-0.730026F,0.171639F}, +{0.898715F,-0.403548F,-0.171639F}, +{0.661515F,-0.730026F,-0.171639F}, +{0.964275F,-0.201774F,0.171639F}, +{0.489876F,-0.854729F,0.171639F}, +{0.065560F,0.854729F,-0.514918F}, +{0.449358F,0.730026F,-0.514918F}, +{-0.792636F,0.326477F,-0.514918F}, +{-0.555436F,0.652955F,-0.514918F}, +{-0.555436F,-0.652955F,-0.514918F}, +{-0.792636F,-0.326477F,-0.514918F}, +{0.449358F,-0.730026F,-0.514918F}, +{0.065560F,-0.854729F,-0.514918F}, +{0.833155F,0.201774F,-0.514918F}, +{0.833155F,-0.201774F,-0.514918F}, +{0.277718F,0.201774F,-0.939234F}, +{-0.106079F,0.326477F,-0.939234F}, +{0.555436F,0.403548F,-0.727076F}, +{-0.212158F,0.652955F,-0.727076F}, +{-0.343279F,0.000000F,-0.939234F}, +{-0.686557F,0.000000F,-0.727076F}, +{-0.106079F,-0.326477F,-0.939234F}, +{-0.212158F,-0.652955F,-0.727076F}, +{0.277718F,-0.201774F,-0.939234F}, +{0.555436F,-0.403548F,-0.727076F}, +{0.106079F,0.326477F,0.939234F}, +{0.212158F,0.652955F,0.727076F} +}; + +static f32 red[4] = {0.8, 0.1, 0.0, 1.0}; +static f32 green[4] = {0.0, 0.8, 0.2, 1.0}; +static f32 yellow[4] = {1.0, 1.0, 0.0, 1.0}; +static f32 blue[4] = {0.2, 0.2, 1.0, 1.0}; +static f32 white[4] = {1.0, 1.0, 1.0, 1.0}; +static f32 magenta[4] = {1.0, 0.0, 1.0, 1.0}; +static f32 orange[4] = {1.0, 0.5, 0.0, 1.0}; + +static f32 grey[4] = {.25, .25, .25, 1.0}; + +static f32 *colormaps[]={blue,orange,yellow,magenta,green,red,white}; + + +f32 buckyfix = 1.0; +f32 pr, pg, pb; +f32 nx, ny, nz; + +inline void set_normal(f32 x, f32 y, f32 z) +{ + nx=x; + ny=y; + nz=z; +} +inline void set_nnormal(f32 x, f32 y, f32 z) +{ +f32 f = 1.0 / sqrt(x*x + y*y + z*z); + set_normal(x*f, y*f, z*f); +} + +inline void point(f32 x, f32 y, f32 z) +{ + GX_Position3f32(x, y, z); + GX_Normal3f32(nx, ny, nz); + GX_Color3f32(pr, pg, pb); + +} +inline void npoint(int n) +{ + point(coords[n][0]*buckyfix,coords[n][1]*buckyfix,coords[n][2]*buckyfix); +} + +void norm(int p1,int p2,int p3) +{ +//f32 nx,ny,nz; +f32 x1,y1,z1; +f32 x2,y2,z2; + + x1=coords[p2][0]-coords[p1][0]; + y1=coords[p2][1]-coords[p1][1]; + z1=coords[p2][2]-coords[p1][2]; + + x2=coords[p3][0]-coords[p1][0]; + y2=coords[p3][1]-coords[p1][1]; + z2=coords[p3][2]-coords[p1][2]; + + nx=y1*z2-y2*z1; + ny=x2*z1-x1*z2; + nz=x1*y2-x2*y1; + +} +void hex(int p1,int p2,int p3,int p4,int p5,int p6) +{ + GX_Begin(GX_TRIANGLEFAN, GX_VTXFMT0, 6); + norm(p1,p3,p2); + npoint(p1); + npoint(p2); + npoint(p3); + npoint(p4); + npoint(p5); + npoint(p6); + GX_End(); +} +void pent(int p1,int p2,int p3,int p4,int p5) +{ + GX_Begin(GX_TRIANGLESTRIP, GX_VTXFMT0, 5); + norm(p1,p3,p2); + npoint(p3); + npoint(p4); + npoint(p2); + npoint(p5); + npoint(p1); + GX_End(); +} +void makebucky(f32 size) +{ + + buckyfix=size; + + pr = 1.0; pg = 0.0; pb = 0.0; + hex(2,7,8,10,9,4); + hex(1,2,4,6,5,3); + hex(7,11,12,14,13,8); + hex(9,10,32,30,31,33); + hex(5,6,28,26,27,29); + hex(0,25,59,58,1,3); + hex(11,58,59,19,20,12); + hex(21,22,24,25,00,23); + hex(30,32,37,35,44,45); + hex(26,28,33,31,42,43); + hex(15,17,24,22,38,39); + hex(15,16,18,20,19,17); + hex(38,51,49,48,50,39); + hex(13,14,36,34,35,37); + hex(16,46,47,34,36,18); + hex(21,23,29,27,40,41); + hex(40,53,52,49,51,41); + hex(44,57,56,54,55,45); + hex(46,50,48,56,57,47); + hex(42,55,54,52,53,43); + + + pr = 1.0; pg = 1.0; pb = 1.0; + pent(1,58,11,7,2); + pent(8,13,37,32,10); + pent(4,9,33,28,6); + pent(0,3,5,29,23); + pent(17,19,59,25,24); + pent(12,20,18,36,14); + pent(30,45,55,42,31); + pent(21,41,51,38,22); + pent(48,49,52,54,56); + pent(15,39,50,46,16); + pent(34,47,57,44,35); + pent(26,43,53,40,27); +} + + +void makebcube(f32 scale) +{ +f32 sizex,sizey,sizez; +f32 bsizex,bsizey,bsizez; +f32 bevel; + + sizex=sizey=sizez=0.6*scale; + bevel=0.15*scale; + bsizex=sizex+bevel; + bsizey=sizey+bevel; + bsizez=sizez+bevel; + + GX_Begin(GX_QUADS, GX_VTXFMT0, 72); + set_normal( 0.0, sizey, 0.0); + point(-sizex, bsizey, sizez); + point(-sizex, bsizey,-sizez); + point( sizex, bsizey,-sizez); + point( sizex, bsizey, sizez); + + set_normal( 0.0, 0.0, sizez); + point( sizex,-sizey, bsizez); + point(-sizex,-sizey, bsizez); + point(-sizex, sizey, bsizez); + point( sizex, sizey, bsizez); + + + set_normal( 0.0, 0.0,-sizez); + point( sizex,-sizey,-bsizez); + point( sizex, sizey,-bsizez); + point(-sizex, sizey,-bsizez); + point(-sizex,-sizey,-bsizez); + + set_normal( sizex, 0.0, 0.0); + point( bsizex, sizey,-sizez); + point( bsizex,-sizey,-sizez); + point( bsizex,-sizey, sizez); + point( bsizex, sizey, sizez); + + set_normal(-sizex, 0.0, 0.0); + point(-bsizex, sizey,-sizez); + point(-bsizex, sizey, sizez); + point(-bsizex,-sizey, sizez); + point(-bsizex,-sizey,-sizez); + + set_normal( 0.0,-sizey, 0.0); + point(-sizex,-bsizey, sizez); + point( sizex,-bsizey, sizez); + point( sizex,-bsizey,-sizez); + point(-sizex,-bsizey,-sizez); + + set_normal( 0.0, sizey, sizez); + point( sizex, bsizey, sizez); + point( sizex, sizey, bsizez); + point( -sizex, sizey, bsizez); + point( -sizex, bsizey, sizez); + + set_normal( sizex, 0.0, sizez); + point( bsizex, -sizey, sizez); + point( sizex, -sizey, bsizez); + point( sizex, sizey, bsizez); + point( bsizex, sizey, sizez); + + set_normal( sizex, sizey, 0.0); + point(bsizex, sizey, sizez); + point(sizex, bsizey, sizez); + point(sizex, bsizey, -sizez); + point(bsizex, sizey, -sizez); + + set_normal( 0.0, -sizey, -sizez); + point( sizex, -bsizey, -sizez); + point( sizex, -sizey, -bsizez); + point( -sizex, -sizey, -bsizez); + point( -sizex, -bsizey, -sizez); + + set_normal( -sizex, 0.0, -sizez); + point( -bsizex, -sizey, -sizez); + point( -sizex, -sizey, -bsizez); + point( -sizex, sizey, -bsizez); + point( -bsizex, sizey, -sizez); + + set_normal( -sizex, -sizey, 0.0); + point(-bsizex, -sizey, sizez); + point(-sizex, -bsizey, sizez); + point(-sizex, -bsizey, -sizez); + point(-bsizex, -sizey, -sizez); + + set_normal( 0.0, -sizey, sizez); + point( -sizex, -bsizey, sizez); + point( -sizex, -sizey, bsizez); + point( sizex, -sizey, bsizez); + point( sizex, -bsizey, sizez); + + set_normal( 0.0, sizey, -sizez); + point( sizex, sizey, -bsizez); + point( sizex, bsizey, -sizez); + point( -sizex, bsizey, -sizez); + point( -sizex, sizey, -bsizez); + + set_normal( -sizex, 0.0, sizez); + point( -bsizex,sizey, sizez); + point( -sizex, sizey, bsizez); + point( -sizex, -sizey, bsizez); + point( -bsizex, -sizey, sizez); + + set_normal( sizex, 0.0, -sizez); + point( sizex,-sizey, -bsizez); + point( bsizex, -sizey, -sizez); + point( bsizex, sizey, -sizez); + point( sizex, sizey, -bsizez); + + set_normal( -sizex, sizey, 0.0); + point( -bsizex, sizey, -sizez); + point( -sizex, bsizey, -sizez); + point( -sizex, bsizey, sizez); + point( -bsizex,sizey, sizez); + + set_normal( sizex, -sizey, 0.0); + point( sizex, -bsizey, sizez); + point( bsizex, -sizey, sizez); + point( bsizex, -sizey, -sizez); + point( sizex, -bsizey, -sizez); + + GX_End(); + + GX_Begin(GX_TRIANGLES, GX_VTXFMT0, 24); + + set_normal(sizex,sizey,sizez); + point(bsizex,sizey,sizez); + point(sizex,sizey,bsizez); + point(sizex,bsizey,sizez); + + set_normal(-sizex,sizey,sizez); + point(-sizex,bsizey,sizez); + point(-sizex,sizey,bsizez); + point(-bsizex,sizey,sizez); + + set_normal(-sizex,-sizey,sizez); + point(-bsizex,-sizey,sizez); + point(-sizex,-sizey,bsizez); + point(-sizex,-bsizey,sizez); + + set_normal(sizex,-sizey,sizez); + point(sizex,-bsizey,sizez); + point(sizex,-sizey,bsizez); + point(bsizex,-sizey,sizez); + + + set_normal(-sizex,-sizey,-sizez); + point(-sizex,-sizey,-bsizez); + point(-bsizex,-sizey,-sizez); + point(-sizex,-bsizey,-sizez); + + set_normal(sizex,-sizey,-sizez); + point(sizex,-sizey,-bsizez); + point(sizex,-bsizey,-sizez); + point(bsizex,-sizey,-sizez); + + set_normal(sizex,sizey,-sizez); + point(sizex,sizey,-bsizez); + point(bsizex,sizey,-sizez); + point(sizex,bsizey,-sizez); + + set_normal(-sizex,sizey,-sizez); + point(-sizex,sizey,-bsizez); + point(-sizex,bsizey,-sizez); + point(-bsizex,sizey,-sizez); + + GX_End(); +} + + +void makepyramid(f32 size) +{ + GX_Begin(GX_QUADS, GX_VTXFMT0, 4); + set_nnormal( 0.0, -size, 0.0); + point( size,-size,-size); + point(-size,-size,-size); + point(-size,-size, size); + point( size,-size, size); + GX_End(); + + GX_Begin(GX_TRIANGLES, GX_VTXFMT0, 12); + set_nnormal( 2.0, -1.0, 0.0); + point( 0.0, size, 0.0); + point( size,-size,-size); + point( size,-size, size); + + + set_nnormal( 0.0, -1.0,-2.0); + point( 0.0, size, 0.0); + point(-size,-size,-size); + point( size,-size,-size); + + set_nnormal( -2.0, -1.0, 0.0); + point( 0.0, size, 0.0); + point(-size,-size, size); + point(-size,-size,-size); + + set_nnormal( 0.0, -1.0, 2.0); + point( 0.0, size, 0.0); + point( size,-size, size); + point(-size,-size, size); + GX_End(); +} + +#define X .525731112119133606 +#define Z .850650808352039932 + +static f32 vdata [12][3] = { +{-X, 0.0, Z}, {X, 0.0, Z}, {-X, 0.0, -Z}, +{X, 0.0, -Z}, {0.0, Z, X}, {0.0, Z, -X}, +{0.0, -Z, X}, {0.0, -Z, -X}, {Z, X, 0.0}, +{-Z, X, 0.0}, {Z, -X, 0.0}, {-Z, -X, 0.0} +}; + +static int tindices [20][3] = { + {1, 4, 0}, {4, 9, 0}, + {4, 5, 9}, {8, 5, 4}, + {1, 8, 4}, {1, 10, 8}, + {10, 3, 8}, {8, 3, 5}, + {3, 2, 5}, {3, 7, 2}, + {3, 10, 7}, {10, 6, 7}, + {6, 11, 7}, {6, 0, 11}, + {6, 1, 0}, {10, 1, 6}, + {11, 0, 9}, {2, 11, 9}, + {5, 2, 9}, {11, 2, 7} +}; + +void dup3(float *a,float *b) +{ + *a++=*b++; + *a++=*b++; + *a=*b; +} + +void mid(float *a,float *b,float *c) +{ +float d; + a[0]=(*b++ + *c++)/2.0; + a[1]=(*b++ + *c++)/2.0; + a[2]=(*b + *c)/2.0; + d=1.0/sqrt(a[0]*a[0]+a[1]*a[1]+a[2]*a[2]); + a[0]*=d; + a[1]*=d; + a[2]*=d; + +} +void norm2(float *p1,float *p2,float *p3) +{ +float nx,ny,nz; +float x1,y1,z1; +float x2,y2,z2; + + x1=p2[0]-p1[0]; + y1=p2[1]-p1[1]; + z1=p2[2]-p1[2]; + + x2=p3[0]-p1[0]; + y2=p3[1]-p1[1]; + z2=p3[2]-p1[2]; + + nx=y1*z2-y2*z1; + ny=x2*z1-x1*z2; + nz=x1*y2-x2*y1; + set_nnormal(nx,ny,nz); +} + +void makeicosahedron(int sub,float scale) +{ +f32 tris[200][3]; +int i,j,p,q; +int numt; + numt=0; + j=0; + for(i=0;i<20;++i) + { + p=tindices[i][0]; + tris[j][0]=vdata[p][0]; + tris[j][1]=vdata[p][1]; + tris[j][2]=vdata[p][2]; + ++j; + p=tindices[i][1]; + tris[j][0]=vdata[p][0]; + tris[j][1]=vdata[p][1]; + tris[j][2]=vdata[p][2]; + ++j; + p=tindices[i][2]; + tris[j][0]=vdata[p][0]; + tris[j][1]=vdata[p][1]; + tris[j][2]=vdata[p][2]; + ++j; + ++numt; + } + while(sub--) + { + j=numt; + numt<<=2; + while(--j>=0) + { + float ttt[3][3]; + p=j*3; + q=p*4; + memcpy(ttt,tris[p],sizeof(ttt)); + + mid(tris[q++],ttt[0],ttt[1]); + dup3(tris[q++],ttt[1]); + mid(tris[q++],ttt[1],ttt[2]); + + dup3(tris[q++],ttt[0]); + mid(tris[q++],ttt[0],ttt[1]); + mid(tris[q++],ttt[0],ttt[2]); + + mid(tris[q++],ttt[1],ttt[2]); + dup3(tris[q++],ttt[2]); + mid(tris[q++],ttt[0],ttt[2]); + + mid(tris[q++],ttt[0],ttt[1]); + mid(tris[q++],ttt[1],ttt[2]); + mid(tris[q++],ttt[0],ttt[2]); + + } + } +void icpoint(f32 *p, f32 scale) {point(p[0]*scale,p[1]*scale,p[2]*scale);} + p=0; + GX_Begin(GX_TRIANGLES, GX_VTXFMT0, numt*3); + for(i=0;i<numt;++i) + { + norm2(tris[p],tris[p+1],tris[p+2]); + icpoint(tris[p], scale); + icpoint(tris[p+2], scale); + icpoint(tris[p+1], scale); + p+=3; + } + GX_End(); + + +} +#define CSQUEEZE 0.8 +void makecyllinder(f32 size) +{ +#define CSIDES 12 +f32 x[CSIDES],z[CSIDES]; +int i,j,k; +f32 a; + for(i=0;i<CSIDES;++i) + { + a=i*3.1415928*2.0/CSIDES; + x[i]=cos(a)*size*CSQUEEZE; + z[i]=sin(a)*size*CSQUEEZE; + } + + for(j=0;j<2;++j) + { + f32 p=(j&1) ? -size : size; + set_nnormal(0.0, p, 0.0); + GX_Begin(GX_TRIANGLEFAN, GX_VTXFMT0, CSIDES); + for(i=0;i<CSIDES;++i) + { + k=(j&1) ? (CSIDES-1-i) : i; + point(x[k],p,z[k]); + } + GX_End(); + } + GX_Begin(GX_QUADS, GX_VTXFMT0, CSIDES*4); + + for(i=0;i<CSIDES;++i) + { + j=i+1; + if(j>=CSIDES) j-=CSIDES; + set_nnormal((x[i]+x[j])/2.0, 0.0, (z[i]+z[j])/2.0); + + point(x[i], size, z[i]); + point(x[i], -size, z[i]); + + point(x[j], -size, z[j]); + point(x[j], size, z[j]); + + } + GX_End(); + +} + +void makediamond(f32 size) +{ +#define DSIDES 9 +f32 x[DSIDES],z[DSIDES]; +int i,j,t,o=0; +f32 a; +f32 c,s,d,h; +f32 p2; +f32 lx, ly, lz; + for(i=0;i<DSIDES;++i) + { + a=i*3.1415928*2.0/DSIDES; + x[i]=cos(a)*size; + z[i]=sin(a)*size; + } + + + p2=size*0.5; + for(t=0;t<2;++t) + { + f32 p1=(t&1) ? -size : size; + + GX_Begin(GX_TRIANGLES, GX_VTXFMT0, DSIDES*3); + d=(!t) ? size-p2 : size+p2; + h=sqrt(size*size+d*d); + c=(!t) ? size/h : -size/h; + s=d/h; + lx = ly = lz = 0.0; + for(i=0;i<DSIDES+1;++i) + { + j=(i<DSIDES) ? i : i-DSIDES; + if(!t) j=DSIDES-1-j; + if(i) + { + set_nnormal((x[j]+x[o])/2.0*s,size*c,(z[j]+z[o])/2.0*s); + point(lx, ly, lz); + point(0.0, p1, 0.0); + } + lx = x[j]; + ly = p2; + lz = z[j]; + if(i) + point(lx, ly, lz); + + o=j; + } + GX_End(); + } + +} + + +void makeuvsphere(f32 size) +{ +#define USIDES 15 +#define VSIDES 9 +f32 x[USIDES],z[USIDES]; +int i,j,t,o; +f32 a; +f32 c1,s1,c2,s2; +f32 lx1, ly1, lz1; +f32 lx2, ly2, lz2; + + for(i=0;i<USIDES;++i) + { + a=i*3.1415927*2.0/USIDES; + x[i]=cos(a)*size; + z[i]=sin(a)*size; + } + + for(i=0;i<VSIDES;++i) + { + a=i*3.1415927/VSIDES; + c1=cos(a); + s1=sin(a); + a=(i+1)*3.1415927/VSIDES; + c2=cos(a); + s2=sin(a); + GX_Begin(GX_QUADS, GX_VTXFMT0, USIDES*4); + lx1 = ly1 = lz1 = 0.0; + lx2 = ly2 = lz2 = 0.0; + for(j=0;j<USIDES+1;++j) + { + t=(j<USIDES) ? j : j-USIDES; + if(j) + { + f32 s,c; + a=(i+0.5)*3.1415927/VSIDES; + c=cos(a); + s=sin(a); + a=(j-0.5)*3.1415927*2.0/USIDES; + set_nnormal(cos(a)*s,c,sin(a)*s); + } + if(j) + { + point(lx2, ly2, lz2); + point(lx1, ly1, lz1); + } + lx1 = x[t]*s2; + ly1 = c2*size; + lz1 = z[t]*s2; + + lx2 = x[t]*s1; + ly2 = c1*size; + lz2 = z[t]*s1; + if(j) + { + point(lx1, ly1, lz1); + point(lx2, ly2, lz2); + } + + o=t; + } + GX_End(); + } +} + + +void makespiky(f32 scale) +{ +#define SPIKES 12 +#define SPIKEZ 0.5 +#define SPIKEIN 0.7 +f32 x1[SPIKES],y1[SPIKES]; +f32 x2[SPIKES],y2[SPIKES]; +f32 a,b,b2; +int i,j; +f32 p0[3],p1[3],p2[3]; + + b=3.1415927*2/SPIKES; + b2=b/2.0; + for(i=0;i<SPIKES;++i) + { + a=i*b; + x1[i]=cos(a)*scale*SPIKEIN; + y1[i]=sin(a)*scale*SPIKEIN; + x2[i]=cos(a+b2)*scale; + y2[i]=sin(a+b2)*scale; + } + + GX_Begin(GX_TRIANGLES, GX_VTXFMT0, SPIKES*6); + p0[0]=0.0; + p0[1]=0.0; + p0[2]=SPIKEZ*scale; + + p1[0]=x1[0]; + p1[1]=y1[0]; + p1[2]=0.0; + + for(i=0;i<SPIKES;++i) + { + j=i+1; + if(j>=SPIKES) j-=SPIKES; + + p2[0]=x2[i]; + p2[1]=y2[i]; + p2[2]=0.0; + + norm2(p0,p1,p2); + point(p0[0], p0[1], p0[2]); + point(p2[0], p2[1], p2[2]); + point(p1[0], p1[1], p1[2]); + + p1[0]=x1[j]; + p1[1]=y1[j]; + p1[2]=0.0; + + norm2(p0,p2,p1); + point(p0[0], p0[1], p0[2]); + point(p1[0], p1[1], p1[2]); + point(p2[0], p2[1], p2[2]); + + } + GX_End(); +} + +void makeselector(f32 scale) +{ +#define MS_TICKS 12 +#define MS_WIDE .15 +#define MS_LONG .3 +#define MS_HIGH .1 +f32 a, b; +f32 pc[3], p1[3], p2[3], p3[3], p4[3]; +int i; + + b = M_PI*2.0 / MS_TICKS; + + for(i=0;i<MS_TICKS;++i) + { + GX_Begin(GX_TRIANGLES, GX_VTXFMT0, 12); + a = i*b; + pc[0] = cos(a)*scale; + pc[1] = sin(a)*scale; + pc[2] = MS_HIGH*scale; + + p1[0] = cos(a)*scale*(1.0 - MS_LONG); + p1[1] = sin(a)*scale*(1.0 - MS_LONG); + p1[2] = 0.0; + + p3[0] = cos(a)*scale*(1.0 + MS_LONG); + p3[1] = sin(a)*scale*(1.0 + MS_LONG); + p3[2] = 0.0; + + a = b*(i+MS_WIDE); + p2[0] = cos(a)*scale; + p2[1] = sin(a)*scale; + p2[2] = 0.0; + + a = b*(i-MS_WIDE); + p4[0] = cos(a)*scale; + p4[1] = sin(a)*scale; + p4[2] = 0.0; + + norm2(pc, p2, p1); + point(pc[0], pc[1], pc[2]); + point(p1[0], p1[1], p1[2]); + point(p2[0], p2[1], p2[2]); + + norm2(pc, p3, p2); + point(pc[0], pc[1], pc[2]); + point(p2[0], p2[1], p2[2]); + point(p3[0], p3[1], p3[2]); + + norm2(pc, p4, p3); + point(pc[0], pc[1], pc[2]); + point(p3[0], p3[1], p3[2]); + point(p4[0], p4[1], p4[2]); + + norm2(pc, p1, p4); + point(pc[0], pc[1], pc[2]); + point(p4[0], p4[1], p4[2]); + point(p1[0], p1[1], p1[2]); + + GX_End(); + } +} + + + +int gamestate; +float life,decay; +int stage,score,level,highscore=0; +int nummoves; +int cumulative; +int cumulativebuildup; +float cumulativefade; +int enteringline; +int baseshow; +int chainreaction; +int alertcounter; +int actionmode; +float timeindicator; +int dropsound; +int waspicked; +int xsize, ysize; +int cposx, cposy; +f32 downx,downy,downz; +int isdown; + +enum actionstates { +ACTION_LOOKING, +ACTION_WAITING, +ACTION_SWAPPING, +ACTION_UNSWAPPING, +ACTION_REMOVING, +ACTION_DROPPING, +}; + +enum sounds { +ROWSOUND, +DROPSOUND, +BIGDROPSOUND, +SWAPSOUND, +GAMEOVERSOUND, +ALERTSOUND, +ILLEGALSOUND, +}; + + +enum gamestate { +GAMEOVER, +PLAYING, +ENTERHIGH, +}; +// position/scaling settings +#define SCALE 0.9 // size of each jewel +#define SPACING 1.8 // how much to move for each row/column +#define SHIFTX 4.0 // shift the jewels sideways so they're not centered +#define SHIFTY 0.0 + +#define SWAPTIME 20 + +#define SCORESPRITEFADE 0.01 +#define FALLRATE 0.02 +#define VANISHRATE 0.05 + +#define STARTLIFE 1000.0 +#define ALARMLEVEL 10.0 // seconds before death +#define CREDIT 50.0 +#define INITIALDECAY (0.4) +#define DECAYADD 0.02 +#define NEXTLEVEL 10 + +#define LIFEVISIBLE (STARTLIFE*2.0) + +#define EX 8 +#define EY 8 + +struct element { +int type; +float ax,ay,az; +float angle; +float fall,speed; +float vanish; +float dx,dy; +int swapping; +} elements[EY][EX]; + +#define MAXSCORESPRITES 12 +struct scoresprite { +float x,y,z; +float fade; +int value; +} scoresprites[MAXSCORESPRITES]; + +#define MAXHIGHSCORES 100 + +#define MAXNAMELENGTH 12 +struct highscore { +char name[MAXNAMELENGTH]; +int score; +int level; +} highscores[MAXHIGHSCORES]; +char lastentered[MAXNAMELENGTH]={0}; + + + +#define RLEN 55 +#define RTAP 31 + +static int tap = 0; + +static unsigned int rtab[RLEN], rmaster[RLEN] = { +0xce5b72a6,0xf142f1f0,0xe38c7808,0x9f6489d0, +0xfaae5295,0xb0756d37,0x71781266,0x12286b7b, +0xb3890fde,0xdb665594,0x3bf69e17,0xa7c13049, +0xe5bd5e62,0x31f90815,0xbf6382bc,0x7e4a5707, +0x0ee4c5e1,0xfc2c4931,0x7caca3ff,0x26ea64b5, +0x7be5e6bd,0xba4f37ad,0x33d4856f,0xfe82d5b8, +0x945bacae,0xf4ce5e24,0x15fd2334,0x05db20c3, +0xa5164863,0xd6a06874,0xc7199828,0xf1238636, +0xa4463b7e,0xccddfa34,0x03111ccf,0xe68ba5b0, +0xa8bff874,0x6ed71aad,0xed30825f,0x9e43caf5, +0x6db2f302,0x56437555,0x97f250fe,0x8375633b, +0x9c3b7d60,0x2edd849d,0xab376fcf,0x757e836b, +0x2e6c9cca,0x9db3695a,0xfbdc0f27,0xea41369b, +0xdfde1cce,0xb6d74760,0x7f67fc17 +}; + + +void myseed(unsigned int s) +{ +int i; +int is, ic; + + memcpy(rtab, rmaster, sizeof(rtab)); + tap = 0; + ic = 0; + is = s; + for(i=0;i<RLEN;++i) + { + rtab[i] ^= s; + rtab[i] += ic; + ic += is; + s ^= (s<<3) ^ (s>>29); + } +} + +unsigned int myrand(void) +{ +int j, v; + j = tap - RTAP; + if(j<0) j+=RLEN; + v = (rtab[tap] ^= rtab[j]); + ++tap; + if(tap==RLEN) tap = 0; + return v & 0x7fffffff; +} + +void playsound(int n) +{ + switch(n) + { + case ROWSOUND: + ASND_SetVoice(0, VOICE_MONO_16BIT, 22050, 0, (void *)row_raw, row_raw_size, 255, 255, 0); + break; + case DROPSOUND: + ASND_SetVoice(1, VOICE_MONO_16BIT, 22050, 0, (void *)drop_raw, drop_raw_size, 255, 255, 0); + break; + case BIGDROPSOUND: + ASND_SetVoice(2, VOICE_MONO_16BIT, 22050, 0, (void *)bigdrop_raw, bigdrop_raw_size, 255, 255, 0); + break; + case SWAPSOUND: + ASND_SetVoice(3, VOICE_MONO_16BIT, 22050, 0, (void *)swap_raw, swap_raw_size, 255, 255, 0); + break; + case GAMEOVERSOUND: + ASND_SetVoice(4, VOICE_MONO_16BIT, 22050, 0, (void *)gameover_raw, gameover_raw_size, 255, 255, 0); + break; + case ALERTSOUND: + ASND_SetVoice(5, VOICE_MONO_16BIT, 22050, 0, (void *)alert_raw, alert_raw_size, 255, 255, 0); + break; + case ILLEGALSOUND: + ASND_SetVoice(6, VOICE_MONO_16BIT, 22050, 0, (void *)illegal_raw, illegal_raw_size, 255, 255, 0); + break; + } +} + + +void illegal(struct element *e1,struct element *e2) +{ +struct element t; + t=*e1; + *e1=*e2; + *e2=t; + e1->dx=-e1->dx; + e1->dy=-e1->dy; + e1->swapping=1; + e2->dx=-e2->dx; + e2->dy=-e2->dy; + e2->swapping=1; + waspicked=0; +} + + +#define SWAPMAX 4 +int swapfifo[SWAPMAX][4]; +int swapput=0,swaptake=0; +void addswap(int px,int py,int dx,int dy) +{ +int *p; + if(((swapput+1) & (SWAPMAX-1)) == swaptake) return; + p=swapfifo[swapput++]; + swapput&=SWAPMAX-1; + *p++=px; + *p++=py; + *p++=dx; + *p=dy; +} + + +int tryswap(void) +{ +struct element t; +struct element *e1,*e2; +int *p; +int px,py,dx,dy; + if(swapput==swaptake) return 0; + + playsound(SWAPSOUND); + p=swapfifo[swaptake++]; + swaptake&=SWAPMAX-1; + px=*p++; + py=*p++; + dx=*p++; + dy=*p; + e1=elements[py]+px; + e2=elements[py+dy]+px+dx; + t=*e1; + *e1=*e2; + *e2=t; + e1->dx=dx; + e1->dy=-dy; + e1->swapping=1; + e2->dx=-dx; + e2->dy=dy; + e2->swapping=1; + return 1; +} + +int wins[4][4]={ +{-2,-1,-1,-1}, +{-1,-1,1,-1}, +{1,-1,2,-1}, +{0,-2,0,-3}, +}; +unsigned char movebits[EY][EX]; +int anymoves(void) +{ +unsigned char temp[EY][EX]; +struct element *e; +int i,j,k,t, dir; +int moves; +int dx1, dy1, dx2, dy2; + memset(temp,0xff,sizeof(temp)); + memset(movebits, 0, sizeof(movebits)); + e=elements[0]; + for(j=0;j<EY;++j) + for(i=0;i<EX;++i) + temp[j][i]=e++ -> type; + + moves=0; + for(j=0;j<EY;++j) + for(i=0;i<EX;++i) + for(k=0;k<16;++k) + { + int *p = wins[k&3]; + dir = k>>2; // 0=up, 1=left, 2=down, 3=right + dx1 = p[0]; + dy1 = p[1]; + dx2 = p[2]; + dy2 = p[3]; + if(dir&1) // transpose x + y + { + t=dx1; + dx1=dy1; + dy1=t; + + t=dx2; + dx2=dy2; + dy2=t; + } + if(dir&2) // negate x + y + { + dx1=-dx1; + dy1=-dy1; + dx2=-dx2; + dy2=-dy2; + } + if(i+dx1<0 || i+dx1>=EX) continue; + if(j+dy1<0 || j+dy1>=EY) continue; + if(i+dx2<0 || i+dx2>=EX) continue; + if(j+dy2<0 || j+dy2>=EY) continue; + t=temp[j][i]; + + if(t!=temp[j+dy1][i+dx1]) continue; + if(t!=temp[j+dy2][i+dx2]) continue; +// we know we've got a win, just want to make sure we don't count the move +// multiple times... + if(dir<2) dx1=0,dy1=0; // up or left + else if(dir==2) dx1=0,dy1=1; // down + else dx1=1,dy1=0; // right + t = (dir&1) ? 1 : 2; // bit0 = X, bit1 = Y + if(movebits[j+dy1][i+dx1]&t) continue; + ++moves; + movebits[j+dy1][i+dx1]|=t; + } + return nummoves=moves; +} +void tossall(void) +{ +int j; +struct element *e; + e=elements[0]; + j=EX*EY; + while(j--) e++ -> vanish=0.999; + playsound(BIGDROPSOUND); +} + +void randomvector(float *x,float *y,float *z) +{ +int ix,iy,iz; +float d; + + do + { + ix=(myrand()&1023)-512; + iy=(myrand()&1023)-512; + iz=(myrand()&1023)-512; + } while(ix==0 && iy==0 && iz==0); + d=1.0/sqrt((float)(ix*ix+iy*iy+iz*iz)); + *x=ix*d; + *y=iy*d; + *z=iz*d; +*x=*z=0;*y=1.0; +} + + +void addlife(int chain,int len,float x,float y) +{ +int value; +int i; +struct scoresprite *ss; + value=chain+len; + cumulative=cumulativebuildup+=value; + cumulativefade=1.0; + for(ss=scoresprites,i=0;i<MAXSCORESPRITES;++i,++ss) + { + if(ss->fade!=0.0) continue; + jmap(&ss->x, &ss->y, &ss->z, x, y); + ss->z += SCALE*2.0; + ss->fade=1.0; + ss->value=value; + break; + } + + score+=value; + if(score>highscore) highscore = score; + life+=(value)*CREDIT; + stage+=len; + if(stage>=NEXTLEVEL) + { + stage-=NEXTLEVEL; + decay+=DECAYADD; + ++level; + } +} +void endgame(void) +{ +struct highscore *h; + + gamestate=GAMEOVER; +return; + h=highscores+MAXHIGHSCORES; + while(h>highscores && h[-1].score<score) --h; + enteringline=h-highscores; + baseshow=enteringline-5; + if(baseshow<0) baseshow=0; + if(baseshow>MAXHIGHSCORES-10) baseshow=MAXHIGHSCORES-10; + if(enteringline==MAXHIGHSCORES) return; + memmove(h+1,h,(MAXHIGHSCORES-enteringline)*sizeof(struct highscore)); + strcpy(h->name,lastentered); + h->score=score; + h->level=level; + gamestate=ENTERHIGH; +} +void declife() +{ + timeindicator-=decay*5.0; + life-=decay; + if(life<0.0) + { + life=0.0; + if(gamestate!=GAMEOVER) + { + endgame(); + playsound(GAMEOVERSOUND); + } + } +} + + +int findwins(int justchecking) +{ +int i,j,k; +struct element *e; +int hadsome=0; +float x,y; + + for(j=0;j<EY;++j) + { + k=0; + for(i=1;i<EX+1;++i) + { + e=elements[j]+i; + if(i<EX && e->type==e[-1].type) ++k; + else if(k>=2) + { + hadsome=1; + if(!justchecking) + { + x=i-1-k/2.0; + y=j+0.5; + addlife(chainreaction,k-1,x,y); + } + ++k; + while(k) e[-k--].vanish=0.999; + k=0; + } else k=0; + } + } + + for(j=0;j<EX;++j) + { + k=0; + for(i=1;i<EY+1;++i) + { + e=elements[i]+j; + if(i<EY && e->type==e[-EX].type) ++k; + else if(k>=2) + { + hadsome=1; + if(!justchecking) + { + x=j; + y=i-0.5-k/2.0; + addlife(chainreaction,k-1,x,y); + } + ++k; + while(k) e[-EX*k--].vanish=0.999; + k=0; + } else k=0; + } + } + if(!justchecking) + { + if(hadsome) + { + playsound(ROWSOUND); + ++chainreaction; + } else chainreaction=0,cumulativebuildup=0; + } + return hadsome; +} + +void initelement(struct element *e) +{ + + memset(e,0,sizeof(*e)); + e->type=(myrand()&0xffff)%7; + e->angle=(myrand()&1023)*360.0/1024.0; + e->vanish=1.0; + e->fall=0.0; + randomvector(&e->ax,&e->ay,&e->az); +} + +void initelements(void) +{ +int i,j; +struct element *e; + e=elements[0]; + j=EX*EY; + for(i=0;i<j;++i) + initelement(e++); +} + +void replace(void) +{ +int i,j,k; +struct element *e,*e2; +int falls[EX]; + + for(i=0;i<EX;++i) + falls[i]=1; + for(j=EY-1;j>=0;--j) + { + for(i=0;i<EX;++i) + { + e=elements[j]+i; + if(e->vanish!=0.0) continue; + k=j; + while(--k>=0) + { + e2=elements[k]+i; + if(e2->vanish!=0.0) break; + } + if(k>=0) + { + *e=*e2; + e2->vanish=0.0; + e->fall=j-k; + } else + { + initelement(e); + e->fall=j+falls[i]++; + } + } + } +} + + +void initgame(void) +{ +int i; + life=STARTLIFE; + decay=INITIALDECAY; + do initelements(); while(findwins(1)); + chainreaction=swapput=swaptake=0; + stage=0; + score=0; + level=1; + gamestate=PLAYING; + cumulative=0; + cumulativebuildup=0; + cumulativefade=0.0; + alertcounter=0; + baseshow=0; + enteringline=-1; + for(i=0;i<MAXSCORESPRITES;++i) scoresprites[i].fade=0.0; + actionmode=ACTION_LOOKING; + cposx = cposy = -1; +} + +void action(void) +{ +struct element *e,*le; +struct element *e1=0,*e2=0; +int i; +int hadsome; +struct scoresprite *ss; + + if(gamestate==PLAYING && life<ALARMLEVEL*50*decay) + { + --alertcounter; + if(alertcounter<=0) + { + playsound(ALERTSOUND); + alertcounter=50; + } + } + + for(i=0,ss=scoresprites;i<MAXSCORESPRITES;++i,++ss) + { + ss->fade-=SCORESPRITEFADE; + if(ss->fade<0.0) ss->fade=0.0; + } + + cumulativefade-=SCORESPRITEFADE; + if(cumulativefade<0.0) cumulativefade=0.0; + + e=elements[0]; + le=e+EX*EY; + while(e<le) e++ ->angle+=3.0; + + switch(actionmode) + { + case ACTION_LOOKING: + if(findwins(0)) + actionmode=ACTION_REMOVING; + else + if(anymoves()) + actionmode=ACTION_WAITING; + else + {tossall();actionmode=ACTION_REMOVING;} + break; + case ACTION_WAITING: + if(gamestate!=PLAYING) break; + declife(); + if(tryswap()) actionmode=ACTION_SWAPPING; + break; + case ACTION_UNSWAPPING: + declife(); + case ACTION_SWAPPING: + e=elements[0]; + hadsome=0; + while(e<le) + { + if(e->swapping) + { + hadsome=1; + ++e->swapping; + if(e->swapping==SWAPTIME) + { + e->swapping=0; + e1=e2; + e2=e; + hadsome=2; + } + } + ++e; + } + if(hadsome==2) + { + if(findwins(0)) + actionmode=ACTION_REMOVING; + else if(actionmode==ACTION_SWAPPING) + { + playsound(ILLEGALSOUND); + illegal(e1,e2); + actionmode=ACTION_UNSWAPPING; + } else + actionmode=ACTION_WAITING; + } + break; + case ACTION_REMOVING: + hadsome=0; + e=elements[0]; + while(e<le) + { + if(e->vanish<1.0) + { + e->vanish-=VANISHRATE; + if(e->vanish<=0.0) + { + e->vanish=0.0; + ++hadsome; + } + } + ++e; + } + if(hadsome) + { + replace(); + dropsound=1; + actionmode=ACTION_DROPPING; + } + break; + case ACTION_DROPPING: + e=elements[0]; + hadsome=0; + while(e<le) + { + if(e->fall>0.0) + { + ++hadsome; + e->fall-=e->speed; + e->speed+=FALLRATE; + if(e->fall<=0.0) + { + e->fall=e->speed=0.0; + if(dropsound) + { + playsound(DROPSOUND); + dropsound=0; + } + } + } + ++e; + } + if(!hadsome) actionmode=ACTION_LOOKING; + break; + } +} + +void f0(void) {makebucky(0.9*SCALE);} +void f1(void) {makebcube(SCALE);} +void f2(void) {makepyramid(0.7*SCALE);} +void f3(void) {makeicosahedron(0, SCALE);} +void f4(void) {makecyllinder(0.8 * SCALE);} +void f5(void) {makediamond(0.9 * SCALE);} +void f6(void) {makeuvsphere(0.9 * SCALE);} + +void (*functab[])(void) = {f0, f1, f2, f3, f4, f5, f6}; + +void setmaterial(f32 *color) +{ +int r, g,b; + + r = color[0]*255; + g = color[1]*255; + b = color[2]*255; + + GX_SetChanMatColor(GX_COLOR0A0, (GXColor) {r, g, b, 255}); +} + +void showlife(Mtx44 view) +{ +float a,b; +int i; +guVector tvector; +f32 cutoff; +Mtx44 model, modelview; + +#define SECTIONS 24 +#define LIFEX -8.5 +#define LIFEY -3.0 +#define LIFEZ1 -18.0 +#define LIFEZ2 1.0 +#define LIFESIZE 3.5 +#define LIFENORMAL 0.7 + +#define SECTIONYELLOW 4 +#define SECTIONRED 1 + + + guMtxIdentity(model); + tvector.x = 0.0; + tvector.y = 1.0; + tvector.z = 0.0; + guMtxTransApply(model, model, LIFEX, LIFEY, LIFEZ1); + guMtxConcat(view,model,modelview); + GX_LoadPosMtxImm(modelview, GX_PNMTX0); + GX_LoadNrmMtxImm(modelview, GX_PNMTX0); + + b=3.1415927*2.0/SECTIONS; + + a=0; + set_normal(0.0, 0.0, 1.0); + + setmaterial(grey); + GX_Begin(GX_LINESTRIP, GX_VTXFMT0, SECTIONS+1); + for(i=0;i<=SECTIONS;++i) + { + point(sin(a)*LIFESIZE,cos(a)*LIFESIZE, 0.01); + a+=b; + } + GX_End(); + + cutoff = life * SECTIONS / LIFEVISIBLE; + + for(i=0;i<SECTIONS && i < cutoff;++i) + { + if(i<=SECTIONRED) + setmaterial(red); + else if(i<=SECTIONYELLOW) + setmaterial(yellow); + else + setmaterial(green); + a = (i+0.5) * b; + set_nnormal(sin(a), cos(a), LIFENORMAL); + GX_Begin(GX_TRIANGLES, GX_VTXFMT0, 3); + point(0.0, 0.0, LIFEZ2); + a = i * b; + point(sin(a) * LIFESIZE, cos(a) * LIFESIZE, 0.0); + a = i+1; + if(a > cutoff) a = cutoff; + a *= b; + point(sin(a) * LIFESIZE, cos(a) * LIFESIZE, 0.0); + GX_End(); + } + + setmaterial(blue); + guMtxIdentity(model); + tvector.x = 0.0; + tvector.y = 0.0; + tvector.z = 1.0; + guMtxRotAxisDeg(model, &tvector, timeindicator); + guMtxTransApply(model, model, LIFEX, LIFEY - 4.6, LIFEZ1); + guMtxConcat(view,model,modelview); + GX_LoadPosMtxImm(modelview, GX_PNMTX0); + GX_LoadNrmMtxImm(modelview, GX_PNMTX0); + + makespiky(LIFESIZE * .3); +} + +void figure2(Mtx44 view, f32 xp, f32 yp, f32 zp, f32 angle, + f32 *color, int orient) +{ +float nx; +float ny; +float nz; +int i,j,k; +float t1,t2; +guVector tvector; +Mtx44 model, trot, temp; + + tvector.x = 0.1; + tvector.y = 1.0; + tvector.z = 0.0; + guMtxIdentity(trot); + guMtxRotAxisDeg(trot, &tvector, angle); + + nx=ny=nz=0.0; + + setmaterial(color); + + + for(k=0;k<15;++k) + { + i=k%3; + j=k/3; + if(i==1 && j>=1 && j<4) continue; + +#define TSCALE .7 + + + t1=(i-1)*TSCALE; + t2=(j-2)*TSCALE; + switch(orient) + { + case 0: + nx = t1; + ny = t2; + nz = 0.0; + break; + case 1: + nx = t2; + nz = t1; + ny = 0.0; + break; + case 2: + ny = t1; + nz = t2; + nx = 0.0; + break; + } + +//void c_guMtxTransApply(Mtx src,Mtx dst,f32 xT,f32 yT,f32 zT); +//void c_guMtxConcat(Mtx a,Mtx b,Mtx ab); + + + guMtxTrans(model, xp, yp , zp); + guMtxConcat(model, trot, model); // model = model * trot + guMtxTrans(temp, nx, ny, nz); + guMtxConcat(model, temp, model); // model = model * temp + + guMtxConcat(view,model,model); // model = view * model + + GX_LoadPosMtxImm(model, GX_PNMTX0); + GX_LoadNrmMtxImm(model, GX_PNMTX0); + + makebcube(TSCALE*.65); + } + +} + +void figure(Mtx44 view, f32 xp, f32 yp, f32 zp) +{ +static float angle=0.0; + + figure2(view, xp, yp, zp, angle, blue, 0); + figure2(view, xp, yp, zp, angle, red, 1); + figure2(view, xp, yp, zp, angle, green, 2); + angle+=1.0; +} + + +void jmap(f32 *destx, f32 *desty, f32 *destz, f32 x, f32 y) +{ + *destx = SHIFTX + SPACING*( x - EX/2.0+0.5); + *desty = SHIFTY + SPACING*(-y + EY/2.0-0.5); + *destz = 0.0; +} + +static void draw(Mtx44 view, int cheat) +{ +int i,j,k; +struct element *e; +int c=0; +f32 a; +f32 nx,ny,nz; +Mtx44 model, modelview; + + if(gamestate==PLAYING) showlife(view); + + +#define SCOREX -10.5 +#define SCORETAB 7.1 +#define SCOREXC (SCOREX + SCORETAB*0.5) +#define SCOREY 5.5 +#define SCOREZ 6.0 +#define LINESPACE 1.0 +#define SCOREY1 (SCOREY - LINESPACE*0) +#define SCOREY2 (SCOREY - LINESPACE*1) +#define SCOREY3 (SCOREY - LINESPACE*2) +#define SCOREY4 (SCOREY - LINESPACE*3) +#define SCOREY5 (SCOREY - LINESPACE*4) +#define SCOREY6 (SCOREY - LINESPACE*5) +#define SCOREY7 (SCOREY - LINESPACE*6) +#define SCOREY8 (SCOREY - LINESPACE*7) +#define SCOREY9 (SCOREY - LINESPACE*8) +#define SCOREY10 (SCOREY - LINESPACE*9) +#define SCOREY11 (SCOREY - LINESPACE*10) +#define SCOREY12 (SCOREY - LINESPACE*11) + + setmaterial(white); + drawstring(view, SCOREX, SCOREY1, SCOREZ, SCALE, 0, "Score"); + drawstring(view, SCOREX+SCORETAB, SCOREY1, SCOREZ, SCALE, 2, "%d",score); + drawstring(view, SCOREX, SCOREY2, SCOREZ, SCALE, 0, "High"); + drawstring(view, SCOREX+SCORETAB, SCOREY2, SCOREZ, SCALE, 2, "%d", highscore); + + drawstring(view, SCOREX, SCOREY3, SCOREZ, SCALE, 0, "Level",level); + drawstring(view, SCOREX+SCORETAB, SCOREY3, SCOREZ, SCALE, 2, "%d",level); + drawstring(view, SCOREX, SCOREY4, SCOREZ, SCALE, 0, "Moves",level); + drawstring(view, SCOREX+SCORETAB, SCOREY4, SCOREZ, SCALE, 2, "%d",nummoves); + if(gamestate != PLAYING) + { + drawstring(view, SCOREXC, SCOREY6, SCOREZ, SCALE, 1, "Game Over"); + figure(view, SCOREXC, SCOREY11, SCOREZ); + setmaterial(green); + drawstring(view, SCOREXC, SCOREY8, SCOREZ, SCALE, 1, "Jewels"); + drawstring(view, SCOREXC, SCOREY9, SCOREZ, SCALE, 1, "by David Ashley"); + } + else if(cumulativefade>0.0) + { +// setgrey(cumulativefade); + GX_SetChanMatColor(GX_COLOR0A0, (GXColor) {255, 255, 255, 255 * cumulativefade}); + drawstring(view, SCOREXC, SCOREY6, SCOREZ, SCALE, 1, "+%d",cumulative); + GX_SetChanMatColor(GX_COLOR0A0, (GXColor) {255, 255, 255, 255}); + } + + + + +// t=SPACING; +// y=t*(EY/2.0-0.5); + e=elements[0]; + k=EX*EY; +// glDisable(GL_DEPTH_TEST); +// glEnable(GL_BLEND); + for(j=0;j<EY;++j) + { +// x=-t*(EX/2.0-0.5); + for(i=0;i<EX;++i) + { + guVector tvector; + + jmap(&nx, &ny, &nz, i, j); +// nx=x+SHIFTX; +// ny=y; +// nz=(1.0-e->vanish)*50.0; + nz += (1.0-e->vanish)*100.0; + if(e->swapping) + { + f32 s; + a=e->swapping*3.1415927/2.0/SWAPTIME; + s=SPACING*cos(a); + nx+=s*e->dx; + ny+=s*e->dy; + s=SPACING*sin(a*2.0); + if(c++ & 1) s=-s; + nz+=s; + } + ny+=e->fall*SPACING; + + + guMtxIdentity(model); + tvector.x = e->ax; + tvector.y = e->ay; + tvector.z = e->az; + guMtxRotAxisDeg(model, &tvector, e->angle); + guMtxTransApply(model, model, nx, ny, nz); + guMtxConcat(view,model,modelview); + // load the modelview matrix into matrix memory + GX_LoadPosMtxImm(modelview, GX_PNMTX0); + GX_LoadNrmMtxImm(modelview, GX_PNMTX0); + + + if(gamestate==PLAYING && cposx==i && cposy==j) + { + light_brighter(); + } + if(e->swapping) + { +// glDisable(GL_BLEND); +// glEnable(GL_DEPTH_TEST); + } + + if(e->type >=0 && e->type <= 6) + { + setmaterial(colormaps[e->type]); + functab[e->type](); + } + if(e->swapping) + { +// glEnable(GL_BLEND); +// glDisable(GL_DEPTH_TEST); + } + if(gamestate==PLAYING && cposx==i && cposy==j) + { + light_regular(); + } + ++e; + } + } +cheat = 0; + if(cheat && actionmode == ACTION_WAITING) + { + setmaterial(green); + GX_SetZMode(GX_TRUE, GX_ALWAYS, GX_FALSE); + for(j=0;j<EY;++j) + { + for(i=0;i<EX;++i) + { + for(k=0;k<2;++k) + { + f32 dx, dy; + if(~movebits[j][i]&(1<<k)) continue; + if(k==0) dx=-0.5, dy=0.0; + else dx=0.0, dy=-0.5; + jmap(&nx, &ny, &nz, i+dx, j+dy); + guMtxTrans(model, nx, ny, nz); + guMtxConcat(view,model,modelview); + GX_LoadPosMtxImm(modelview, GX_PNMTX0); + GX_LoadNrmMtxImm(modelview, GX_PNMTX0); + GX_SetZMode(GX_TRUE, GX_ALWAYS, GX_FALSE); + makebucky(SCALE*.2); + GX_SetZMode(GX_TRUE, GX_LEQUAL, GX_TRUE); + } + } + } + setmaterial(white); + GX_SetZMode(GX_TRUE, GX_LEQUAL, GX_TRUE); + } + + if(cposx>=0 && cposx<EX && cposy>=0 && cposy<EY) + { + jmap(&nx, &ny, &nz, cposx, cposy); + + setmaterial(white); + guMtxIdentity(model); + guMtxTransApply(model, model, nx, ny, nz); + guMtxConcat(view,model,modelview); + GX_LoadPosMtxImm(modelview, GX_PNMTX0); + GX_LoadNrmMtxImm(modelview, GX_PNMTX0); + GX_SetZMode(GX_TRUE, GX_ALWAYS, GX_FALSE); +// makeselector(SCALE*1.4); + GX_SetZMode(GX_TRUE, GX_LEQUAL, GX_TRUE); + } + + GX_SetZMode(GX_TRUE, GX_ALWAYS, GX_FALSE); + for(i=0;i<MAXSCORESPRITES;++i) + { + struct scoresprite *ss=scoresprites+i; + if(ss->fade==0.0) continue; + GX_SetChanMatColor(GX_COLOR0A0, (GXColor) {255, 255, 255, 255*ss->fade}); + drawstring(view, ss->x, ss->y-(1.0-ss->fade), ss->z, SCALE, 1,"+%d",ss->value); + } + GX_SetZMode(GX_TRUE, GX_LEQUAL, GX_TRUE); + GX_SetChanMatColor(GX_COLOR0A0, (GXColor) {255, 255, 255, 255}); + +} + +void getpos(int *dx, int *dy, f32 x, f32 y, f32 z) +{ +int u, v, bu=-1, bv=-1; +f32 bestdist = 100000000000.0, d; +f32 tx, ty, tz; + + for(v=0;v<EY;++v) + for(u=0;u<EX;++u) + { + jmap(&tx, &ty, &tz, u, v); + tx -= x; + ty -= y; + tz -= z; + d = tx*tx + ty*ty + tz*tz; + if(d < bestdist) + { + bestdist = d; + bu = u; + bv = v; + } + } + if(1 || bestdist < SPACING*SPACING) + *dx = bu, *dy = bv; + else + *dx = -1, *dy = -1; +} + +void down(f32 x,f32 y, f32 z) +{ + downx=x; + downy=y; + downz=z; + isdown=1; +} + +#define DIST 20 +#define ABS(x) (((x)<0) ? (-(x)) : (x)) +void moved(f32 x,f32 y, f32 z) +{ +f32 dx,dy,dz; +int px=-1, py=-1; + + getpos(&cposx,&cposy,x,y,z); + if(!isdown) return; + dx=x-downx; + dy=y-downy; + dz=z-downz; + if(dx*dx+dy*dy+dz*dz<SPACING*SPACING/4.0) return; + isdown=0; + if(ABS(dx)>ABS(dy)) + { + if(dx<0) dx=-1; + else dx=1; + dy=0; + } else + { + if(dy<0) dy=1; + else dy=-1; + dx=0; + } + getpos(&px,&py,downx,downy,downz); + + if(px<0 || px>=EX || py<0 || py>=EY) return; + if(px+dx<0 || px+dx>=EX || py+dy<0 || py+dy>=EY) return; + addswap(px,py,dx,dy); + +} + +void buttonup(f32 x, f32 y, f32 z) +{ + isdown=0; +} + +unsigned char *ppmtake; +int ppmin; +unsigned char ppmbuff[2048],*ppmp; +inline int ppmci() +{ + return *ppmtake++; +} + +void ppmline(unsigned char *put) +{ +int c; + while((c=ppmci())>=0) + if(c==0x0a) break; + else *put++=c; + *put=0; +} +struct pic { +unsigned char *image; +int w,h; +}; + +int readppm(unsigned char *data,struct pic *pic) +{ +unsigned char line[8192]; +int w,h; +unsigned int i,j; +unsigned char *put; + + ppmtake = data; + ppmin=0; + ppmline(line); + if(strcmp((char *)line,"P6")) return 1; + ppmline(line); + if(sscanf((char *)line,"%d %d",&w,&h)!=2) return 2; + pic->w=w; + pic->h=h; + pic->image=put=memalign(4, w*h*3); + if(!put) return -3; + ppmline(line); + for(j=0;j<h;++j) + { + for(i=0;i<w;++i) + { + *put++=ppmci(); + *put++=ppmci(); + *put++=ppmci(); + } + } + return 0; +} + + +#define TW 256 +#define TH TW +#define MAXCHARS 72 +unsigned char *fontcharacters=(void *)"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789.!:>^@() +"; +GXTexObj fonttexture; +struct fontchar { + f32 ulx, uly; + f32 lrx, lry; + int width; +} fontchars[MAXCHARS]; +unsigned char fontmap[128]; + + +void initfont(void) +{ + +// Texture setup +// RGBA format divides real texture into 4x4 pixel squares +// they are outputted left to right, top to bottom +// Each square is 4 rows of 4 pixels of AR (1 byte each) +// followed by 4 rows of 4 pixels of GB (1 byte each) +int x,y, base; +unsigned char *b2; +struct pic pic; +int nextx, nexty; +unsigned char keyr,keyg,keyb,*p; +unsigned char gapr,gapg,gapb,r,g,b,a; +unsigned char *txdata; +int wc; +int cc; +int u,v; + + memset(fontmap, 255, sizeof(fontmap)); + readppm((void *)bigfont_ppm, &pic); + txdata = memalign(32, TW*TH*4); + memset(txdata, 0, TW*TH*4); + + nextx = nexty = 0; + p=pic.image+3*(pic.w*pic.h-1); + keyr=*p++; + keyg=*p++; + keyb=*p++; + + p=pic.image+3*pic.w; + gapr=*p++; + gapg=*p++; + gapb=*p++; + + wc = pic.w - 1; + + for(cc=0;cc<MAXCHARS;++cc) + { + int cw; + struct fontchar *fc; + + fontmap[fontcharacters[cc]] = cc; + fc = fontchars+cc; + + cw = 0; + while(wc--) + { + r = *p++; + g = *p++; + b = *p++; + if(r==gapr && g==gapg && b==gapb) break; + ++cw; + } + if(!cw) break; + fc->width = cw; + + if(nextx + cw > TW) + { + nexty += pic.h; + nextx = 0; + } + fc->ulx = (f32)nextx / TW; + fc->uly = (f32)nexty / TH; + fc->lrx = (f32)(nextx + cw) / TW; + fc->lry = (f32)(nexty + pic.h-2) / TH; + for(v=0;v<pic.h-2;++v) + { + y=nexty+v; + for(u=0;u<cw;++u) + { + x=nextx+u; + base = (y&3)*8 + (x>>2)*64 + (x&3)*2 + (y>>2)*TW*16; + b2 = p + (u - cw - 1 + v*pic.w)*3; + r = b2[0]; + g = b2[1]; + b = b2[2]; + a = 255; + if(r==keyr && g==keyg && b==keyb) + r = g = b = a = 0; + txdata[base+ 0] = a; // alpha + txdata[base+ 1] = r; // red + txdata[base+32] = g; // green + txdata[base+33] = b; // blue + } + } + nextx += cw; + + } + + + DCFlushRange(txdata, TW*TH*4); + GX_InvVtxCache(); + GX_InvalidateTexAll(); + GX_InitTexObj(&fonttexture, txdata, TW, TH, GX_TF_RGBA8, GX_REPEAT, GX_REPEAT, GX_FALSE); + GX_LoadTexObj(&fonttexture, GX_TEXMAP0); +} + +void drawstring(Mtx44 view, f32 x, f32 y, f32 z, + f32 scale, int alignment, char *fmt, ...) +{ +char temp[128], *p; +va_list ap; +struct fontchar *fc; +Mtx44 model, modelview; + + va_start(ap, fmt); + vsprintf(temp,fmt,ap); + va_end(ap); + + GX_InvalidateTexAll(); + GX_SetTevOrder(GX_TEVSTAGE0, GX_TEXCOORD0, GX_TEXMAP0, GX_COLOR0A0); + GX_SetBlendMode(GX_BM_BLEND, GX_BL_SRCALPHA, GX_BL_INVSRCALPHA, GX_LO_SET); + + GX_SetNumTexGens(1); + GX_SetTexCoordGen(GX_TEXCOORD0, GX_TG_MTX2x4, GX_TG_TEX0, GX_IDENTITY); + GX_SetTevOp(GX_TEVSTAGE0,GX_MODULATE); //GX_REPLACE); + GX_SetTevOrder(GX_TEVSTAGE0, GX_TEXCOORD0, GX_TEXMAP0, GX_COLOR0A0); + + GX_LoadTexObj(&fonttexture, GX_TEXMAP0); + + GX_SetVtxDesc(GX_VA_TEX0, GX_DIRECT); + + +scale *= 10; + + if(alignment) + { + f32 advance = 0.0; + + p = temp; + while(*p) + { + fc = fontchars + (fontmap[(unsigned char)(*p++)] & 127); + advance += fc->lrx - fc->ulx; + } + advance *= scale; + if(alignment==1) advance *= .5; + x -= advance; + } + guMtxIdentity(model); + guMtxTransApply(model, model, x, y, z); + guMtxConcat(view,model,modelview); + GX_LoadPosMtxImm(modelview, GX_PNMTX0); + GX_LoadNrmMtxImm(modelview, GX_PNMTX0); + + x = y = z = 0.0; + p = temp; + while(*p) + { + f32 x2, y2; + + fc = fontchars + (fontmap[(unsigned char)(*p++)] & 127); + + x2 = x + scale*(fc->lrx - fc->ulx); + y2 = y + scale*(fc->lry - fc->uly); + + GX_Begin(GX_QUADS, GX_VTXFMT0, 4); + GX_Position3f32(x, y2, z);// -----POS + GX_Normal3f32(0.0f, 0.0f, 1.0f); + GX_Color3f32(1.0f, 1.0f, 1.0f); + GX_TexCoord2f32(fc->ulx, fc->uly); + + GX_Position3f32(x2, y2, z);// -----POS + GX_Normal3f32(0.0f, 0.0f, 1.0f); + GX_Color3f32(1.0f, 1.0f, 1.0f); + GX_TexCoord2f32(fc->lrx, fc->uly); + + GX_Position3f32(x2, y, z);// -----POS + GX_Normal3f32(0.0f, 0.0f, 1.0f); + GX_Color3f32(1.0f, 1.0f, 1.0f); + GX_TexCoord2f32(fc->lrx, fc->lry); + + GX_Position3f32(x, y, z);// -----POS + GX_Normal3f32(0.0f, 0.0f, 1.0f); + GX_Color3f32(1.0f, 1.0f, 1.0f); + GX_TexCoord2f32(fc->ulx, fc->lry); + GX_End(); + + x = x2; + } + + GX_SetVtxDesc(GX_VA_TEX0, GX_NONE); + GX_SetTevOp(GX_TEVSTAGE0, GX_PASSCLR); + GX_SetTevOrder(GX_TEVSTAGE0, GX_TEXCOORDNULL, GX_TEXMAP_NULL, GX_COLOR0A0); + GX_SetBlendMode(GX_BM_NONE, GX_BL_ONE, GX_BL_ZERO, GX_LO_CLEAR); +} + + +int main(int argc, char **argv) +{ +f32 yscale; +u32 xfbHeight; +Mtx44 view; +Mtx44 perspective; +Mtx44 model, modelview; +f32 rtri = 0.0f , rquad = 0.0f; +u32 fb = 0; // initial framebuffer index +GXColor background = {0, 0, 0, 0xff}; +f32 cx=0.0, cy=0.0, cz = 0.0; + + myseed(1); + + // init the vi. + VIDEO_Init(); + WPAD_Init(); + rmode = VIDEO_GetPreferredMode(NULL); + + // Initialise the audio subsystem + //ASND_Init(NULL); + ASND_Init(); + ASND_Pause(0); + + WPAD_SetDataFormat(0, WPAD_FMT_BTNS_ACC_IR); + WPAD_SetVRes(0, rmode->fbWidth, rmode->xfbHeight); + + // allocate 2 framebuffers for double buffering + frameBuffer[0] = MEM_K0_TO_K1(SYS_AllocateFramebuffer(rmode)); + frameBuffer[1] = MEM_K0_TO_K1(SYS_AllocateFramebuffer(rmode)); + + VIDEO_Configure(rmode); + VIDEO_SetNextFramebuffer(frameBuffer[fb]); + VIDEO_SetBlack(FALSE); + VIDEO_Flush(); + VIDEO_WaitVSync(); + if(rmode->viTVMode&VI_NON_INTERLACE) VIDEO_WaitVSync(); + + // setup the fifo and then init the flipper + void *gp_fifo = NULL; + gp_fifo = memalign(32,DEFAULT_FIFO_SIZE); + memset(gp_fifo,0,DEFAULT_FIFO_SIZE); + + GX_Init(gp_fifo,DEFAULT_FIFO_SIZE); + + // clears the bg to color and clears the z buffer + GX_SetCopyClear(background, 0x00ffffff); + + // other gx setup + GX_SetViewport(0,0,rmode->fbWidth,rmode->efbHeight,0,1); + yscale = GX_GetYScaleFactor(rmode->efbHeight,rmode->xfbHeight); + xfbHeight = GX_SetDispCopyYScale(yscale); + GX_SetScissor(0,0,rmode->fbWidth,rmode->efbHeight); + GX_SetDispCopySrc(0,0,rmode->fbWidth,rmode->efbHeight); + GX_SetDispCopyDst(rmode->fbWidth,xfbHeight); + GX_SetCopyFilter(rmode->aa,rmode->sample_pattern,GX_TRUE,rmode->vfilter); + GX_SetFieldMode(rmode->field_rendering,((rmode->viHeight==2*rmode->xfbHeight)?GX_ENABLE:GX_DISABLE)); + + GX_SetCullMode(GX_CULL_BACK); + GX_CopyDisp(frameBuffer[fb],GX_TRUE); + GX_SetDispCopyGamma(GX_GM_1_0); + + + // setup the vertex descriptor + // tells the flipper to expect direct data + GX_ClearVtxDesc(); + GX_SetVtxDesc(GX_VA_POS, GX_DIRECT); + GX_SetVtxDesc(GX_VA_NRM, GX_DIRECT); +// GX_SetVtxDesc(GX_VA_TEX0, GX_DIRECT); + GX_SetVtxDesc(GX_VA_TEX0, GX_NONE); + GX_SetVtxDesc(GX_VA_CLR0, GX_DIRECT); + + // setup the vertex attribute table + // describes the data + // args: vat location 0-7, type of data, data format, size, scale + // so for ex. in the first call we are sending position data with + // 3 values X,Y,Z of size F32. scale sets the number of fractional + // bits for non float data. + GX_SetVtxAttrFmt(GX_VTXFMT0, GX_VA_POS, GX_POS_XYZ, GX_F32, 0); + GX_SetVtxAttrFmt(GX_VTXFMT0, GX_VA_NRM, GX_NRM_XYZ, GX_F32, 0); + GX_SetVtxAttrFmt(GX_VTXFMT0, GX_VA_TEX0, GX_TEX_ST, GX_F32, 0); + GX_SetVtxAttrFmt(GX_VTXFMT0, GX_VA_CLR0, GX_CLR_RGBA, GX_RGB8, 0); + +// GX_SetNumChans(1); +// GX_SetNumTexGens(1); + GX_SetTevOp(GX_TEVSTAGE0, GX_PASSCLR); +// GX_SetTevOrder(GX_TEVSTAGE0, GX_TEXCOORDNULL, GX_TEXMAP_NULL, GX_COLOR0A0); + +// GX_SetTevOp(GX_TEVSTAGE0, GX_REPLACE); + GX_SetTevOrder(GX_TEVSTAGE0, GX_TEXCOORD0, GX_TEXMAP0, GX_COLOR0A0); + GX_SetTexCoordGen(GX_TEXCOORD0, GX_TG_MTX2x4, GX_TG_TEX0, GX_IDENTITY); + + + initfont(); + +#if 0 +{ +fatInitDefault(); +int fd = open("/davettt.foo", O_WRONLY|O_CREAT|O_TRUNC, 0644); + if(fd>=0) close(fd); +exit(0); +} +#endif + + + // setup our camera at the origin + // looking down the -z axis with y up + guVector cam = {0.0F, 0.0F, 100.0F}, + up = {0.0F, .1F, 0.0F}, + look = {0.0F, 0.0F, 90.0F}; + guLookAt(view, &cam, &up, &look); + + // setup our projection matrix + // this creates a perspective matrix with a view angle of 90, + // and aspect ratio based on the display resolution + f32 w = rmode->viWidth; + f32 h = rmode->viHeight; + guPerspective(perspective, 10, (f32)w/h, 0.1F, 300.0F); + GX_LoadProjectionMtx(perspective, GX_PERSPECTIVE); + + xsize = rmode->fbWidth; + ysize = rmode->xfbHeight; + + initgame(); + endgame(); + + while(1) { + int res; + u32 type; + WPADData *wd; + WPAD_ScanPads(); + myrand(); + + if (WPAD_ButtonsDown(0) & WPAD_BUTTON_HOME) exit(0); + if(gamestate==GAMEOVER && + (WPAD_ButtonsDown(0) & (WPAD_BUTTON_1 | WPAD_BUTTON_2))) + initgame(); + + res = WPAD_Probe(0, &type); + if(res == WPAD_ERR_NONE) + wd = WPAD_Data(0); + else + wd = 0; + + + // do this before drawing + GX_SetViewport(0,0,rmode->fbWidth,rmode->efbHeight,0,1); + + + setlight(view,8, 20, litcolors[0], litcolors[1], litcolors[2]); + + action(); + draw(view, WPAD_ButtonsHeld(0) & WPAD_BUTTON_B); + + if(wd) + { +#define IF 0.04 + f32 x = IF * (-rmode->fbWidth/2.0 + wd->ir.x); + f32 y = IF * (rmode->xfbHeight/2.0 - wd->ir.y); + f32 z = 0.0; + + moved(cx = x, cy = y, cz = z); + guMtxIdentity(model); + guMtxTransApply(model, model, x, y, 0.0); + guMtxConcat(view,model,modelview); + GX_LoadPosMtxImm(modelview, GX_PNMTX0); + GX_LoadNrmMtxImm(modelview, GX_PNMTX0); + setmaterial(white); + GX_SetZMode(GX_TRUE, GX_ALWAYS, GX_FALSE); + makebucky(0.2 * SCALE); + GX_SetZMode(GX_TRUE, GX_LEQUAL, GX_TRUE); + } + + if(WPAD_ButtonsDown(0) & WPAD_BUTTON_A) + down(cx, cy, cz); + if(WPAD_ButtonsUp(0) & WPAD_BUTTON_A) + buttonup(cx, cy, cz); + + // do this stuff after drawing + GX_DrawDone(); + + fb ^= 1; // flip framebuffer + GX_SetZMode(GX_TRUE, GX_LEQUAL, GX_TRUE); + GX_SetColorUpdate(GX_TRUE); + GX_CopyDisp(frameBuffer[fb],GX_TRUE); + + VIDEO_SetNextFramebuffer(frameBuffer[fb]); + + VIDEO_Flush(); + + VIDEO_WaitVSync(); + + rtri+=0.2f; // Increase The Rotation Variable For The Triangle ( NEW ) + rquad-=0.15*10.0f; // Decrease The Rotation Variable For The Quad ( NEW ) + + } + return 0; +} + |