From fcaa8a35022258be256d738ae5fef9e5892499d6 Mon Sep 17 00:00:00 2001 From: Luis Michelena Date: Thu, 11 Jun 2009 07:01:57 +0000 Subject: Initial add, no changes. --- diff --git a/AUTHORS b/AUTHORS new file mode 100644 index 0000000..6c76773 --- /dev/null +++ b/AUTHORS @@ -0,0 +1 @@ +Fernando Sansberro diff --git a/COPYING b/COPYING new file mode 100644 index 0000000..d511905 --- /dev/null +++ b/COPYING @@ -0,0 +1,339 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Lesser General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) year name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. diff --git a/README b/README new file mode 100644 index 0000000..08f59b5 --- /dev/null +++ b/README @@ -0,0 +1,2 @@ +To compile execute: +g++ -o GameXO `sdl-config --libs` -I/usr/include/SDL -I./src -lSDL_mixer -lSDL_image ./src/*.cpp diff --git a/assets/data/maps/map001.bin b/assets/data/maps/map001.bin new file mode 100755 index 0000000..4dca8cc --- /dev/null +++ b/assets/data/maps/map001.bin Binary files differ diff --git a/assets/fonts/font1/font.dat b/assets/fonts/font1/font.dat new file mode 100755 index 0000000..5849d5c --- /dev/null +++ b/assets/fonts/font1/font.dat Binary files differ diff --git a/assets/fonts/font1/font.ini b/assets/fonts/font1/font.ini new file mode 100755 index 0000000..39886ae --- /dev/null +++ b/assets/fonts/font1/font.ini @@ -0,0 +1 @@ +512 \ No newline at end of file diff --git a/assets/fonts/font1/font.raw b/assets/fonts/font1/font.raw new file mode 100755 index 0000000..ae4ca56 --- /dev/null +++ b/assets/fonts/font1/font.raw Binary files differ diff --git a/assets/fonts/font2/font.dat b/assets/fonts/font2/font.dat new file mode 100755 index 0000000..af9108f --- /dev/null +++ b/assets/fonts/font2/font.dat Binary files differ diff --git a/assets/fonts/font2/font.ini b/assets/fonts/font2/font.ini new file mode 100755 index 0000000..ae4d10b --- /dev/null +++ b/assets/fonts/font2/font.ini @@ -0,0 +1 @@ +256 \ No newline at end of file diff --git a/assets/fonts/font2/font.raw b/assets/fonts/font2/font.raw new file mode 100755 index 0000000..6407495 --- /dev/null +++ b/assets/fonts/font2/font.raw Binary files differ diff --git a/assets/images/icon/icon.bmp b/assets/images/icon/icon.bmp new file mode 100755 index 0000000..455bb23 --- /dev/null +++ b/assets/images/icon/icon.bmp Binary files differ diff --git a/assets/images/tiles/tileset0.png b/assets/images/tiles/tileset0.png new file mode 100755 index 0000000..a34c58e --- /dev/null +++ b/assets/images/tiles/tileset0.png Binary files differ diff --git a/assets/images/xoxi/andy.bmp b/assets/images/xoxi/andy.bmp new file mode 100755 index 0000000..06e5081 --- /dev/null +++ b/assets/images/xoxi/andy.bmp Binary files differ diff --git a/assets/images/xoxi/andy.png b/assets/images/xoxi/andy.png new file mode 100755 index 0000000..35c08c0 --- /dev/null +++ b/assets/images/xoxi/andy.png Binary files differ diff --git a/assets/images/xoxi/andy2.png b/assets/images/xoxi/andy2.png new file mode 100755 index 0000000..432541e --- /dev/null +++ b/assets/images/xoxi/andy2.png Binary files differ diff --git a/assets/images/xoxi/xoxi_frames.png b/assets/images/xoxi/xoxi_frames.png new file mode 100755 index 0000000..7bbfdee --- /dev/null +++ b/assets/images/xoxi/xoxi_frames.png Binary files differ diff --git a/src/CBenchmark.cpp b/src/CBenchmark.cpp new file mode 100755 index 0000000..0fe0dfd --- /dev/null +++ b/src/CBenchmark.cpp @@ -0,0 +1,42 @@ +#include "CBenchmark.h" + +CBenchmark::CBenchmark(bool aVisible) +{ + mTime = 1.f; + mCounter = mDisplayCounter = 0; + mVisible = aVisible; +} + +CBenchmark::~CBenchmark(void) +{ +} + +void CBenchmark::update(float aDt) +{ + mTime -= aDt; + if (mTime > 0.f) + { + mCounter++; + } + else + { + mDisplayCounter = mCounter; + mTime = 1.f; + mCounter = 0; + } +} + +void CBenchmark::setVisible(bool aVisible) +{ + mVisible = aVisible; +} + +bool CBenchmark::getVisible(void) const +{ + return mVisible; +} + +unsigned int CBenchmark::getDisplayCounter(void) +{ + return mDisplayCounter; +} diff --git a/src/CBenchmark.h b/src/CBenchmark.h new file mode 100755 index 0000000..83f84fa --- /dev/null +++ b/src/CBenchmark.h @@ -0,0 +1,26 @@ +//-------------------------------------------------------------------------------------------------- +// CBenchmark. +// A class to represent a benchmark (used to show FPS for example). +//-------------------------------------------------------------------------------------------------- + +#ifndef __CBENCHMARK_H__ +#define __CBENCHMARK_H__ + +class CBenchmark +{ + public: + CBenchmark(bool aVisible); + ~CBenchmark(void); + void update(float aDt); + void setVisible(bool aVisible); + bool getVisible(void) const; + unsigned int getDisplayCounter(void); + + private: + float mTime; + unsigned int mCounter; + unsigned int mDisplayCounter; + bool mVisible; +}; + +#endif /* __CBENCHMARK_H__ */ diff --git a/src/CFont.cpp b/src/CFont.cpp new file mode 100755 index 0000000..5bb87c5 --- /dev/null +++ b/src/CFont.cpp @@ -0,0 +1,230 @@ +//-------------------------------------------------------------------------------------------------- +// CFont. +// Font routines. +// Cone3D SDL font routines by Marius Andra 2002, http://cone3d.gamedev.net. +//-------------------------------------------------------------------------------------------------- + +#include "CFont.h" + +// This function draws one part of an image to some other part of an other image it's only to be used +// inside the font.cpp file, so it's not available to any other source files (no prototype in CFont.h). +void fontDrawIMG(SDL_Surface *screen, SDL_Surface *img, int x, int y, int w, int h, int x2, int y2) +{ + SDL_Rect dest; + dest.x = x; + dest.y = y; + SDL_Rect src; + src.x = x2; + src.y = y2; + src.w = w; + src.h = h; + SDL_BlitSurface(img, &src, screen, &dest); +} + +// This function loads in our font file. +SDLFont *initFont(const char *fontdir, float r, float g, float b, float a) +{ + SDLFont *tempFont; // A temporary font. + FILE *fp; // File pointer - used when reading files. + char tempString[100]; // Temporary string. + unsigned char tmp; // Temporary unsigned char. + int width; // The width of the font. + SDL_Surface *tempSurface; // Temporary surface. + + // Find out about the size of a font from the ini file. + sprintf(tempString, "%s/%s", fontdir, "font.ini"); + fp = fopen(tempString, "rb"); + if(fp == NULL) + { + return 0; + } + fscanf(fp, "%d", &width); + fclose(fp); + + // Let's create our font structure now. + tempFont = new SDLFont; + // There are width*width pixels in our font image and since the image will have 4 channels - RGBA. + tempFont->data = new unsigned char[width*width*4]; + // Give the font structure the width of the font and the width of one character cell (width/16). + tempFont->width = width; + tempFont->charWidth = width/16; + + // Open the font raw data file and read everything in, font.raw contains the raw grayscale image data of the font. + sprintf(tempString, "%s/%s", fontdir, "font.raw"); + fp = fopen(tempString, "rb"); + if(fp != NULL) + { + // We then load in the font one pixel at a time. When reading in the font image, we store 255 in the rgb + // channels of the image multiplied by the r, g and b function parameters (to get the correct color). + // And in the alpha channel of the new SDL surface we store the brightness of the pixel (grayscale color) + // multiplied by the function parameter a (a as in alpha). We store 255*{r,g,b} instead of the font + // brightness*{r,g,b} in the rgb channels to get a good smooth font at the edges. + for(int i=0; i< width*width; i++) + { + tmp = fgetc(fp); + tempFont->data[i*4] = (unsigned char)255*(unsigned char)r; + tempFont->data[i*4+1] = (unsigned char)255*(unsigned char)g; + tempFont->data[i*4+2] = (unsigned char)255*(unsigned char)b; + tempFont->data[i*4+3] = (unsigned char)(((float)tmp)*a); + } + } + else + { + return 0; + } + fclose(fp); + + // Now let's create a SDL surface for the font. + // This process can be used elsewhere as well, not only in the creation of THIS SDL_Surface. + // Most of the following code comes from the SDL_CreateRGBSurfaceFrom and SDL_CreateRGBSurface SDL + // documentation pages. Check them out for more info on the subject. The r,g,b,a masks tell SDL the byte + // order of the r,g,b,a values. But what's with the #ifs? From the SDL Doc: SDL interprets each pixel as + // a 32-bit number, so our masks must depend on the endianness (byte order) of the machine. We create the + // real surface with the SDL_CreateRGBSurfaceFrom function. As you might have noticed, there's also a + // SDL_CreateRGBSurface function, that creates a new surface, but doesn't add any data to it. Now, to + // SDL_CreateRGBSurfaceFrom we pass rgw image data, the width and the height of the file, the number of bits + // per pixel, the number of bytes for one row of the image and the rgba masks. We also convert the surface to + // the display format for faster blitting. + Uint32 rmask,gmask,bmask,amask; + #if SDL_BYTEORDER == SDL_BIG_ENDIAN + rmask = 0xff000000; + gmask = 0x00ff0000; + bmask = 0x0000ff00; + amask = 0x000000ff; + #else + rmask = 0x000000ff; + gmask = 0x0000ff00; + bmask = 0x00ff0000; + amask = 0xff000000; + #endif + tempSurface = SDL_CreateRGBSurfaceFrom(tempFont->data, width, width, 32, width*4, rmask, gmask, bmask, amask); + tempFont->font = SDL_DisplayFormatAlpha(tempSurface); + SDL_FreeSurface(tempSurface); + + // Let's create a variable to hold all the widths of the font. + tempFont->widths = new int[256]; + + // Now read in the information about the width of each character. + sprintf(tempString, "%s/%s", fontdir, "font.dat"); + fp = fopen(tempString, "rb"); + if(fp != NULL) + { + for(int i=0; i<256; i++) + { + tmp = fgetc(fp); + tempFont->widths[i]=tmp; + } + } + fclose(fp); + + // Return the new font. + return tempFont; +} + +// Here we draw the string. +void drawString(SDL_Surface *screen, SDLFont *font, int x, int y,char *str, ...) +{ + char string[1024]; // Temporary string + + va_list ap; // Pointer To List Of Arguments. + va_start(ap, str); // Parses The String For Variables. + vsprintf(string, str, ap); // And Converts Symbols To Actual Numbers. + va_end(ap); // Results Are Stored In Text. + + int len = strlen(string); // Get the number of chars in the string. + int xx = 0; // This will hold the place where to draw the next char. + for(int i=0; ifont, + // We draw the char at pos [x+xx,y]. + // x+xx: this function's parameter x + the width of all the characters before + // this one, so we wouldn't overlap any of the previous characters in the string + // y: this function's y parameter. + xx + x, + y, + // For the width of the to-be-drawn character we take it's real width + 2. + font->widths[string[i]] + 2, + // And for the height we take the height of the character (height of the font/16). + font->charWidth, + // Now comes the tricky part. + // The font image DOES consist of 16x16 grid of characters. From left to + // right in the image, the ascii values of the characters increase: + // The character at block 0x0 in the font image is the character with the + // ascii code 0, the character at the pos 1x0 has the ascii code 1, the char + // at the pos 15x0 has the ascii code 15. And that's the end of the first row. + // Now in the second row on the image, the first character (0x1) has the ascii + // value 16, the fourth character on the second row of the image (3x1) has the ascii + // value 19. To calculate the ascii value of the character 3x1, we use the + // really simple equation: row*[number of thing in one row (=16)]+column pos. + // So the position 3x1 has the ascii value 1*16+3 = 19. The character in the + // image at the position 8x12 has the ascii value 12*16+8=200, and so on. + // But this isn't much of use to us since we KNOW the ascii value of a character, + // but we NEED to find out it's position on the image. + // First we'll get the column on the image. For that we'll divide the ascii value + // with 16 (the number of columns) and get it's remainder (we'll use the modulus + // operator). We'll do this equation to get the column: [ascii value]%16. + // Now to get to the position of the column in pixels, we multiply the ascii + // value by the width of one column ([font image width]/16). + // And so the equation to get the first pixel of the block becomes: + // [font image width]%16*[1/16th of the font image width]. + // Now, since all the letters are centered in each cell (1/16th of the image), + // we need to get the center of the cell. This is done by adding half the width + // of the cell to the number we got before. And the only thing left to do is to + // subtract half of the character's real width and we get the x position from where + // to draw our character on the font map. + (string[i]%16*font->charWidth)+((font->charWidth/2)-(font->widths[string[i]])/2), + // To get the row of the character in the image, we divide the ascii value of + // the character by 16 and get rid of all the numbers after the point (.) + // (if we get the number 7.125257.., we remove the .125157... and end up with 7). + // We then multiply the result with the height of one cell and voila - we get + // the y position! + (((int)string[i]/16)*font->charWidth) + ); + + // Now we increase the xx printed string width counter by the width of the drawn character. + xx += font->widths[string[i]]; + } +} + +// This function returns the width of a string. +int stringWidth(SDLFont *font,char *str,...) +{ + char string[1024]; // Temporary string. + + va_list ap; // Pointer To List Of Arguments. + va_start(ap, str); // Parses The String For Variables. + vsprintf(string, str, ap); // And Converts Symbols To Actual Numbers. + va_end(ap); // Results Are Stored In Text. + + // Now we just count up the width of all the characters. + int xx = 0; + int len = strlen(string); + for(int i=0; iwidths[string[i]]; + } + + // And then return the sum. + return xx; +} + +// Clear up. +void freeFont(SDLFont *font) +{ + delete [] font->widths; + delete [] font->data; + SDL_FreeSurface(font->font); + delete font; +} diff --git a/src/CFont.h b/src/CFont.h new file mode 100755 index 0000000..155cda2 --- /dev/null +++ b/src/CFont.h @@ -0,0 +1,43 @@ +//-------------------------------------------------------------------------------------------------- +// CFont. +// Font routines. +// Cone3D SDL font routines by Marius Andra 2002, http://cone3d.gamedev.net. +//-------------------------------------------------------------------------------------------------- + +#ifndef __CFONT_H__ +#define __CFONT_H__ + +#include +#include +#include +#include +#include + +// Structure to hold our font. +struct SDLFont +{ + SDL_Surface *font; // The SDL Surface for the font image. + int width; // Width of the SDL Surface (same as the height because the image font is a square). + int charWidth; // Width of one block character in the font (fontWidth/16). + int *widths; // Real widths of all the fonts. + unsigned char *data; // The raw font data. +}; + +// This function initalizes a font. +SDLFont *initFont(const char *fontdir, float r, float g, float b, float a); + +// Some overloaded functions to make your life easier. +inline SDLFont *initFont(const char *fontdir, float r, float g, float b) { return initFont(fontdir, r, g, b, 1); } +inline SDLFont *initFont(const char *fontdir) { return initFont(fontdir, 1, 1, 1, 1); } + +// This function draws a string. +void drawString(SDL_Surface *screen, SDLFont *font, int x, int y,char *str,...); + +// This function returns the width of a string. +int stringWidth(SDLFont *font, char *str,...); + +// This function destroys the font. +void freeFont(SDLFont *font); + +#endif /* __CFONT_H__ */ + diff --git a/src/CGame.cpp b/src/CGame.cpp new file mode 100755 index 0000000..aa1bb84 --- /dev/null +++ b/src/CGame.cpp @@ -0,0 +1,43 @@ +#include "CGame.h" + +CGame::CGame(CSurface *aScreenSurface) +{ + mScreenSurface = aScreenSurface; + mMap = new CTileMap(0); + mPlayer = new CPlayer(mScreenSurface, mMap); +} + +CGame::~CGame(void) +{ + destroy(); +} + +void CGame::destroy(void) +{ + if (mMap != NULL) + { + delete mMap; + mMap = NULL; + } + + if (mPlayer != NULL) + { + delete mPlayer; + mPlayer = NULL; + } +} + +void CGame::update(void) +{ + mPlayer->update(); +} + +void CGame::render(void) +{ + mPlayer->render(); +} + +void CGame::drawMap(void) +{ + mMap->draw(mScreenSurface, 0, 0); +} diff --git a/src/CGame.h b/src/CGame.h new file mode 100755 index 0000000..07c0996 --- /dev/null +++ b/src/CGame.h @@ -0,0 +1,37 @@ +//-------------------------------------------------------------------------------------------------- +// CGame. +// A class to represent the game. Is is also used to hold global references. +//-------------------------------------------------------------------------------------------------- + +#ifndef __CGAME_H__ +#define __CGAME_H__ + +#include +#include "CGameConstants.h" +#include "CTileMap.h" +#include "CPlayer.h" +#include "CSpriteAnimation.h" +#include "CSurface.h" + +class CGame +{ + public: + CGame(CSurface *aScreenSurface); + ~CGame(void); + void destroy(void); + + void update(void); + void render(void); + + void drawMap(void); + + private: + CSurface *mScreenSurface; + + + CTileMap *mMap; + CPlayer *mPlayer; +}; + +#endif /* __CGAME_H__ */ + diff --git a/src/CGameConstants.cpp b/src/CGameConstants.cpp new file mode 100755 index 0000000..866929f --- /dev/null +++ b/src/CGameConstants.cpp @@ -0,0 +1,10 @@ +#include "CGameConstants.h" + +CGameConstants::CGameConstants(void) +{ +} + +CGameConstants::~CGameConstants(void) +{ +} + diff --git a/src/CGameConstants.h b/src/CGameConstants.h new file mode 100755 index 0000000..c778937 --- /dev/null +++ b/src/CGameConstants.h @@ -0,0 +1,52 @@ +//-------------------------------------------------------------------------------------------------- +// CGameConstants. +// A class to hold game global variables. +//-------------------------------------------------------------------------------------------------- + +#ifndef __CGAMECONSTANTS_H__ +#define __CGAMECONSTANTS_H__ + +class CGameConstants +{ + public: + CGameConstants(void); + ~CGameConstants(void); + + // Width and height of the screen. + static const int SCREEN_WIDTH = 1200; + static const int SCREEN_HEIGHT = 900; + // Color depth of the screen. + static const int SCREEN_BPP = 32; + + // Width and height of the player (the image). + static const int PLAYER_IMAGE_WIDTH = 100; + static const int PLAYER_IMAGE_HEIGHT = 150; + + // Width and height of the player (on the map, the square under his foots). + static const int PLAYER_WIDTH = 100; + static const int PLAYER_HEIGHT = 100; + + // Offset of the player when rendered. + static const int PLAYER_OFFSET_RENDER_X = 0; + static const int PLAYER_OFFSET_RENDER_Y = -50; + + // Width and height of the tiles. + static const int TILE_WIDTH = 50; + static const int TILE_HEIGHT = 50; + + // Width and height of the map in tiles. + static const int MAP_WIDTH = 24; + static const int MAP_HEIGHT = 18; + + // Cantidad de tiles que hay en una fila en la imagen de tiles. + static const int TILE_IMAGE_WIDTH = 16; + + // Types of tiles. + static const int TILE_CLASS_WALL = 0; + static const int TILE_CLASS_WALL_ENDING = 1; + static const int TILE_CLASS_FLOOR = 2; + static const int TILE_CLASS_BENCH_TOP = 3; + static const int TILE_CLASS_BENCH_SIDE = 4; +}; + +#endif /* __CGAMECONSTANTS_H__ */ diff --git a/src/CParticle.cpp b/src/CParticle.cpp new file mode 100755 index 0000000..dd00e4f --- /dev/null +++ b/src/CParticle.cpp @@ -0,0 +1,76 @@ +#include "CParticle.h" + +CParticle::CParticle(void) +{ + mPos = new CVector(0, 0); + mVel = new CVector(0, 0); + mAccel = new CVector(0, 0); +} + +CParticle::CParticle(float aX, float aY, float aVelX, float aVelY, float aAccelX, float aAccelY) +{ + mPos = new CVector(aX, aY); + mVel = new CVector(aVelX, aVelY); + mAccel = new CVector(aAccelX, aAccelY); +} + +CParticle::~CParticle(void) +{ + destroy(); +} + +void CParticle::destroy(void) +{ + if (mPos != NULL) + { + delete mPos; + mPos = NULL; + } + + if (mVel != NULL) + { + delete mVel; + mVel = NULL; + } + + if (mAccel != NULL) + { + delete mAccel; + mAccel = NULL; + } +} + +float CParticle::getX(void) +{ + return mPos->x; +} + +float CParticle::getY(void) +{ + return mPos->y; +} + +void CParticle::setXVel(float aXVel) +{ + mVel->x = aXVel; +} + +void CParticle::setYVel(float aYVel) +{ + mVel->y = aYVel; +} + +void CParticle::update(void) +{ + mVel->x += mAccel->x; + mVel->y += mAccel->y; + + mPos->x += mVel->x; + mPos->y += mVel->y; +} + +void CParticle::setXY(int aX, int aY) +{ + mPos->x = aX; + mPos->y = aY; +} diff --git a/src/CParticle.h b/src/CParticle.h new file mode 100755 index 0000000..dfa2133 --- /dev/null +++ b/src/CParticle.h @@ -0,0 +1,40 @@ +//-------------------------------------------------------------------------------------------------- +// CParticle. +// A class to represent a particle with its position and the forces that can be applied to it. +//-------------------------------------------------------------------------------------------------- + +#ifndef __CPARTICLE_H__ +#define __CPARTICLE_H__ + +#include +#include "CVector.h" + +class CParticle +{ + public: + CParticle(void); + CParticle(float aX, float aY, float aVelX, float aVelY, float aAccelX, float aAccelY); + ~CParticle(void); + void destroy(void); + + void update(void); + + float getX(void); + float getY(void); + + void setXY(int aX, int aY); + + void setXVel(float aXVel); + void setYVel(float aYVel); + + private: + // Position vector. + CVector *mPos; + // Velocity vector. + CVector *mVel; + // Acceleration Vector. + CVector *mAccel; +}; + +#endif /* __CPARTICLE_H_ */ + diff --git a/src/CPlayer.cpp b/src/CPlayer.cpp new file mode 100755 index 0000000..719fe0f --- /dev/null +++ b/src/CPlayer.cpp @@ -0,0 +1,263 @@ +#include "CPlayer.h" + +CPlayer::CPlayer(CSurface *aScreenSurface, CTileMap *aMap) +{ + mScreenSurface = aScreenSurface; + mMap = aMap; + mXoxiAnimation = new CSpriteAnimation("assets/images/xoxi/xoxi_frames.png", 9, 9, 1, CGameConstants::PLAYER_IMAGE_WIDTH, CGameConstants::PLAYER_IMAGE_HEIGHT, false, false); + + mXoxiSpr = new CSprite(mXoxiAnimation, mScreenSurface); + mXoxiSpr->setRenderOffsets(CGameConstants::PLAYER_OFFSET_RENDER_X, CGameConstants::PLAYER_OFFSET_RENDER_Y); + + mXoxiSpr->setXY(400, 500); +// mXoxiSpr->setXY(0, 0); + + WALKING_SPEED = 1.0f; + mCurrentDirection = DOWN; + setState(STALE); +} + +CPlayer::~CPlayer(void) +{ + destroy(); +} + +void CPlayer::destroy(void) +{ + if (mXoxiAnimation != NULL) + { + delete mXoxiAnimation; + mXoxiAnimation = NULL; + } + + if (mXoxiSpr != NULL) + { + delete mXoxiSpr; + mXoxiSpr = NULL; + } +} + +void CPlayer::update(void) +{ + mKeys = SDL_GetKeyState(NULL); + + switch (mState) + { + case STALE: + if (mKeys[SDLK_LEFT]) + { + checkMapCollisions(mXoxiSpr->getIntX()-WALKING_SPEED, mXoxiSpr->getIntY()); + if (upLeft && centerLeft && downLeft) + { + setState(WALKING_LEFT); + break; + } + } + if (mKeys[SDLK_RIGHT]) + { + checkMapCollisions(mXoxiSpr->getIntX()+WALKING_SPEED, mXoxiSpr->getIntY()); + if (upRight && centerRight && downRight) + { + setState(WALKING_RIGHT); + break; + } + } + if (mKeys[SDLK_UP]) + { + checkMapCollisions(mXoxiSpr->getIntX(), mXoxiSpr->getIntY()-WALKING_SPEED); + if (upLeft && centerUp && upRight) + { + setState(WALKING_UP); + break; + } + } + if (mKeys[SDLK_DOWN]) + { + checkMapCollisions(mXoxiSpr->getIntX(), mXoxiSpr->getIntY()+WALKING_SPEED); + if (downLeft && centerDown && downRight) + { + setState(WALKING_DOWN); + break; + } + } + break; + + case WALKING_RIGHT: + if (!mKeys[SDLK_RIGHT]) + { + setState(STALE); + break; + } + else + { + checkMapCollisions(mXoxiSpr->getIntX()+WALKING_SPEED, mXoxiSpr->getIntY()); + if (!upRight || !centerRight || !downRight) + { + setState(STALE); + break; + } + } + break; + + case WALKING_LEFT: + if (!mKeys[SDLK_LEFT]) + { + setState(STALE); + break; + } + else + { + checkMapCollisions(mXoxiSpr->getIntX()-WALKING_SPEED, mXoxiSpr->getIntY()); + if (!upLeft || !centerLeft || !downLeft) + { + setState(STALE); + break; + } + } + break; + + case WALKING_UP: + if (!mKeys[SDLK_UP]) + { + setState(STALE); + break; + } + else + { + checkMapCollisions(mXoxiSpr->getIntX(), mXoxiSpr->getIntY()-WALKING_SPEED); + if (!upLeft || !centerUp || !upRight) + { + setState(STALE); + break; + } + } + break; + + case WALKING_DOWN: + if (!mKeys[SDLK_DOWN]) + { + setState(STALE); + break; + } + else + { + checkMapCollisions(mXoxiSpr->getIntX(), mXoxiSpr->getIntY()+WALKING_SPEED); + if (!downLeft || !centerDown || !downRight) + { + setState(STALE); + break; + } + } + break; + +/* case CLIMBING_STALE: + if (mKeys[SDLK_LEFT]) + { + setState(WALKING_LEFT); + break; + } + if (mKeys[SDLK_RIGHT]) + { + setState(WALKING_RIGHT); + break; + } + if (mKeys[SDLK_UP]) + { + setState(CLIMBING_UP); + break; + } + if (mKeys[SDLK_DOWN]) + { + setState(CLIMBING_DOWN); + break; + } + break; +*/ + case JUMPING: + break; + } + + // Debug------------------------------- + if (mKeys[SDLK_SPACE]) + { + + } + //------------------------------------- + + mXoxiSpr->update(); +} + +void CPlayer::render(void) +{ + mXoxiSpr->render(); +} + +void CPlayer::setState(int aState) +{ + mState = aState; + + switch (mState) + { + case STALE: + mXoxiSpr->setXVel(0); + mXoxiSpr->setYVel(0); + mXoxiSpr->setAnim(0, 0, false); + break; + + case WALKING_RIGHT: + mCurrentDirection = RIGHT; + mXoxiSpr->setXVel(WALKING_SPEED); + mXoxiSpr->setAnim(1, 2, true); + break; + + case WALKING_LEFT: + mCurrentDirection = LEFT; + mXoxiSpr->setXVel(-WALKING_SPEED); + mXoxiSpr->setAnim(3, 4, true); + break; + + case WALKING_UP: + mCurrentDirection = UP; + mXoxiSpr->setYVel(-WALKING_SPEED); + mXoxiSpr->setAnim(5, 6, true); + break; + + case WALKING_DOWN: + mCurrentDirection = DOWN; + mXoxiSpr->setYVel(WALKING_SPEED); + mXoxiSpr->setAnim(7, 8, true); + break; + + case JUMPING: + break; + } +} + +void CPlayer::checkMapCollisions(int aX, int aY) +{ + // TODO: Cambiar este valor por 0 cuando se mueva bien por los bordes. Remover esta vairable. + int v = 4; + + //int x = mXoxiSpr->getIntX(); + //int y = mXoxiSpr->getIntY(); + int leftX = (aX+v) / CGameConstants::TILE_WIDTH; + int upY = (aY+v) / CGameConstants::TILE_HEIGHT; + int rightX = ((aX + CGameConstants::PLAYER_WIDTH-1-v)) / CGameConstants::TILE_WIDTH; + int downY = ((aY + (CGameConstants::PLAYER_HEIGHT-1)-v)) / CGameConstants::TILE_HEIGHT; + int centerX = (aX + (CGameConstants::PLAYER_WIDTH / 2)) / CGameConstants::TILE_WIDTH; + int centerY = (aY + (CGameConstants::PLAYER_HEIGHT / 2)) / CGameConstants::TILE_HEIGHT; + + upLeft = mMap->isWalkable(leftX, upY); + upRight = mMap->isWalkable(rightX, upY); + downLeft = mMap->isWalkable(leftX, downY); + downRight = mMap->isWalkable(rightX, downY); + centerLeft = mMap->isWalkable(leftX, centerY); + centerRight = mMap->isWalkable(rightX, centerY); + centerUp = mMap->isWalkable(centerX, upY); + centerDown = mMap->isWalkable(centerX, downY); + + //fprintf(stdout, "upLeft = %d %d!\n", xTile, yTile); + //fprintf(stdout, "upLeft = %d!\n", upLeft); + //fprintf(stdout, "upRight = %d!\n", upRight); + fprintf(stdout, "upLeft = %d downLeft = %d!\n", upLeft, downLeft); +} diff --git a/src/CPlayer.h b/src/CPlayer.h new file mode 100755 index 0000000..4b1957d --- /dev/null +++ b/src/CPlayer.h @@ -0,0 +1,72 @@ +//-------------------------------------------------------------------------------------------------- +// CPlayer. +// A class to represent the player. +//-------------------------------------------------------------------------------------------------- + +#ifndef __CPLAYER_H__ +#define __CPLAYER_H__ + +#include "CGameConstants.h" +#include "CSprite.h" +#include "CTileMap.h" + +class CPlayer +{ + public: + CPlayer(CSurface *aScreenSurface, CTileMap *aMap); + ~CPlayer(void); + void destroy(void); + + void update(void); + void render(void); + + void setState(int aState); + + void checkMapCollisions(int aX, int aY); + + private: + // Used to get the state of the keyboard keys at a given moment. + Uint8 *mKeys; + + CSurface *mScreenSurface; + CSpriteAnimation *mXoxiAnimation; + CSprite *mXoxiSpr; + + // Directions. + static const int UP = 0; + static const int DOWN = 1; + static const int LEFT = 3; + static const int RIGHT = 4; + + // Current direction (where is facing). + int mCurrentDirection; + + // States of the player. + static const int STALE = 0; + static const int WALKING_RIGHT = 1; + static const int WALKING_LEFT = 2; + static const int WALKING_UP = 3; + static const int WALKING_DOWN = 4; + static const int JUMPING = 5; + + // Current state. + int mState; + + // Walking speed. + float WALKING_SPEED; + + // Reference to the tiled map. + CTileMap *mMap; + + // Variables to check collisions with the map. + bool upLeft; + bool upRight; + bool downLeft; + bool downRight; + bool centerLeft; + bool centerRight; + bool centerDown; + bool centerUp; +}; + +#endif /* __CPLAYER_H_ */ diff --git a/src/CSprite.cpp b/src/CSprite.cpp new file mode 100755 index 0000000..2814bd0 --- /dev/null +++ b/src/CSprite.cpp @@ -0,0 +1,177 @@ +#include "CSprite.h" + +CSprite::CSprite(void) +{ + mOldX = 0; + mOldY = 0; + mFrame = 0; + mLastUpdate = 0; + mDrawn = false; + mParticle = new CParticle(0, 0, 0, 0, 0, 0); + mStartFrame = 0; + mEndFrame = 0; + mIsLooping = false; +} + +CSprite::CSprite(CSpriteAnimation *aSpriteAnimation, CSurface *aScreen) +{ + mOldX = 0; + mOldY = 0; + mFrame = 0; + mLastUpdate = 0; + mDrawn = false; + mParticle = new CParticle(0, 0, 0, 0, 0, 0); + mStartFrame = 0; + mEndFrame = 0; + mIsLooping = false; + + mSpriteAnimation = aSpriteAnimation; + mScreen = aScreen; + + if (mSpriteAnimation != NULL) + { + // Create the background image. + mBackground = new CSurface(mSpriteAnimation->getWidth(), mSpriteAnimation->getHeight()); + + if (mSpriteAnimation->getNumFrames() > 1) + mAnimating = true; + else + mAnimating = false; + } + else + { + fprintf(stderr, "Sprite constructor failed!\n"); + fprintf(stderr, "Sprite animation is not built!\n"); + } +} + +CSprite::~CSprite(void) +{ + destroy(); +} + +void CSprite::destroy(void) +{ + if (mBackground != NULL) + { + mBackground->destroy(); + mBackground = NULL; + } + + if (mParticle != NULL) + { + delete mParticle; + mParticle = NULL; + } +} + +// Restore the background. +void CSprite::restoreBackground(void) +{ + // If the sprite has been drawn once before, then we can clear the screen. + // If we do not do this, the first time the backgrouns is restored and this results in a black rectangle. + if (mDrawn) + { + CSurface::drawImage(mScreen, mBackground, mOldX, mOldY); + } +} + +// Save the background. +void CSprite::saveBackground(void) +{ + CSurface::drawImage(mBackground, mScreen, 0, 0, getIntX()+mOffsetX, getIntY()+mOffsetY, mSpriteAnimation->getWidth(), mSpriteAnimation->getHeight()); + mOldX = getIntX()+mOffsetX; + mOldY = getIntY()+mOffsetY; +} + +// Draw the sprite in the screen. +void CSprite::draw(void) +{ + CSurface::drawImage(mScreen, mSpriteAnimation->getFrame(mFrame)->getImage(), getIntX()+mOffsetX, getIntY()+mOffsetY); + + if (!mDrawn) + mDrawn = true; +} + +void CSprite::update(void) +{ + if (mAnimating) + { + if (mLastUpdate + mSpriteAnimation->getFrame(mFrame)->getFrameTime() < SDL_GetTicks()) + { + mFrame++; + if (mFrame > mEndFrame) + { + if (mIsLooping) + { + mFrame = mStartFrame; + mAnimating = true; + } + else + { + mFrame = mEndFrame; + mAnimating = false; + } + } + mLastUpdate = SDL_GetTicks(); + } + } + + mParticle->update(); + +// fprintf(stdout, "mAnimating = %d.\n", mAnimating); +// fprintf(stdout, "mFrame = %d.\n", mFrame); +} + +void CSprite::render(void) +{ + restoreBackground(); + saveBackground(); + draw(); +} + +int CSprite::getIntX(void) +{ + return (int) floor(mParticle->getX()); +} + +int CSprite::getIntY(void) +{ + return (int) floor(mParticle->getY()); +} + +void CSprite::setXVel(float aXVel) +{ + mParticle->setXVel(aXVel); +} + +void CSprite::setYVel(float aYVel) +{ + mParticle->setYVel(aYVel); +} + +void CSprite::setAnim(int aStartFrame, int aEndFrame, bool aIsLooping) +{ + if (aStartFrame == aEndFrame) + mAnimating = false; + else + mAnimating = true; + + mIsLooping = aIsLooping; + mStartFrame = aStartFrame; + mEndFrame = aEndFrame; + + mFrame = mStartFrame; + mLastUpdate = SDL_GetTicks(); +} + +void CSprite::setRenderOffsets(int aOffsetX, int aOffsetY) +{ + mOffsetX = aOffsetX; + mOffsetY = aOffsetY; +} + +void CSprite::setXY(int aX, int aY) +{ + mParticle->setXY(aX, aY); +} diff --git a/src/CSprite.h b/src/CSprite.h new file mode 100755 index 0000000..fd3f99f --- /dev/null +++ b/src/CSprite.h @@ -0,0 +1,77 @@ +//-------------------------------------------------------------------------------------------------- +// CSprite. +// A class to represent a game sprite. +// The sprite system is simple: we grab the background from the screen and then store it in the +// CSurface *mBackroung variable. After that we draw the sprite frame onto the screen, and before we +// draw the next frame, we restore the screen from mBackground. +//-------------------------------------------------------------------------------------------------- + +#ifndef __CSPRITE_H__ +#define __CSPRITE_H__ + +#include +#include "CParticle.h" +#include "CSpriteAnimation.h" +#include "CSurface.h" + +class CSprite +{ + public: + CSprite(void); + CSprite(CSpriteAnimation *aSpriteAnimation, CSurface *aScreen); + ~CSprite(void); + void destroy(void); + + void update(void); + void render(void); + + void setXVel(float aXVel); + void setYVel(float aYVel); + + void setAnim(int startFrame, int endFrame, bool isLooping); + void setRenderOffsets(int aOffsetX, int aOffsetY); + + void setXY(int aX, int aY); + int getIntX(void); + int getIntY(void); + + private: + void saveBackground(void); + void restoreBackground(void); + void draw(void); + bool mDrawn; + + // A pointer to the sprite animation (all the frame images) for this sprite. + CSpriteAnimation *mSpriteAnimation; + // Used to redraw the background after drawing the frame. + CSurface *mBackground; + // Pointer to the screen surface. + CSurface *mScreen; + + // Tells us whether this sprite is currently animating or not. + bool mAnimating; + + // Used when clearing the screen. + int mOldX; + int mOldY; + + // Time of the last update. + long mLastUpdate; + + // Current frame of the animation. + int mFrame; + + // Position of the sprite and its forces. + CParticle *mParticle; + + // Variables for the animations. + int mStartFrame; + int mEndFrame; + bool mIsLooping; + + // Rendering offsets. + int mOffsetX; + int mOffsetY; +}; + +#endif /* __CSPRITE_H__ */ diff --git a/src/CSpriteAnimation.cpp b/src/CSpriteAnimation.cpp new file mode 100755 index 0000000..f759208 --- /dev/null +++ b/src/CSpriteAnimation.cpp @@ -0,0 +1,117 @@ +#include "CSpriteAnimation.h" + +CSpriteAnimation::CSpriteAnimation(void) +{ + mBuilt = false; +} + +CSpriteAnimation::CSpriteAnimation(const char *aFile, int aFrames, int aColumns, int aRows, int aFrameWidth, int aFrameHeight, bool aFlippableH, bool aFlippableV) +{ + int flipCounter = 0; + + mBuilt = false; + + mNumFrames = aFrames; + mWidth = aFrameWidth; + mHeight = aFrameHeight; + + CSurface *allFramesSurface = new CSurface(aFile); + + for (int i=0; i < mNumFrames; i++) + { + CSurface *tempSurface = new CSurface(mWidth, mHeight); + CSurface::drawImage(tempSurface, allFramesSurface, 0, 0, (i % aColumns) * aFrameWidth, (i / aColumns) * aFrameHeight, aFrameWidth, aFrameHeight); + mFrame.push_back(new CSpriteFrame(tempSurface)); + } + + allFramesSurface->destroy(); + allFramesSurface = NULL; + + mFlippableH = aFlippableH; + mFlippableV = aFlippableV; + + if (mFlippableH) + { + flipCounter++; + mStartFrameFlipH = mNumFrames * flipCounter; + + for (int i=0; i < mNumFrames; i++) + { + CSurface *tempSurface = new CSurface(getFrame(i)->getImage()->getImage(), CSurface::FLIP_HORIZONTAL); + mFrame.push_back(new CSpriteFrame(tempSurface)); + } + } + + if (mFlippableV) + { + flipCounter++; + mStartFrameFlipV = mNumFrames * flipCounter; + + for (int i=0; i < mNumFrames; i++) + { + CSurface *tempSurface = new CSurface(getFrame(i)->getImage()->getImage(), CSurface::FLIP_VERTICAL); + mFrame.push_back(new CSpriteFrame(tempSurface)); + } + } + + if (mFlippableH && mFlippableV) + { + flipCounter++; + mStartFrameFlipHV = mNumFrames * flipCounter; + + for (int i=0; i < mNumFrames; i++) + { + CSurface *tempSurface = new CSurface(getFrame(i)->getImage()->getImage(), CSurface::FLIP_HORIZONTAL | CSurface::FLIP_VERTICAL); + mFrame.push_back(new CSpriteFrame(tempSurface)); + } + } + + mBuilt = true; + + flipCounter++; + mNumFrames = mNumFrames * flipCounter; +} + +CSpriteAnimation::~CSpriteAnimation(void) +{ + destroy(); + mBuilt = false; +} + +void CSpriteAnimation::destroy(void) +{ + for (int i=0; i < mNumFrames; i++) + { + if (mFrame[i] != NULL) + { + mFrame[i]->destroy(); + mFrame[i] = NULL; + } + } + mFrame.clear(); +} + +int CSpriteAnimation::getWidth(void) +{ + return mWidth; +} + +int CSpriteAnimation::getHeight(void) +{ + return mHeight; +} + +int CSpriteAnimation::getNumFrames(void) +{ + return mNumFrames; +} + +bool CSpriteAnimation::isBuilt(void) +{ + return mBuilt; +} + +CSpriteFrame *CSpriteAnimation::getFrame(int aFrameIndex) +{ + return mFrame[aFrameIndex]; +} diff --git a/src/CSpriteAnimation.h b/src/CSpriteAnimation.h new file mode 100755 index 0000000..5154e34 --- /dev/null +++ b/src/CSpriteAnimation.h @@ -0,0 +1,49 @@ +//-------------------------------------------------------------------------------------------------- +// CSpriteAnimation. +// Clase que representa una animación hecha con frames. Un sprite va a tener varias una referencia a +// CSpriteAnimation para cada una de las animaciones que tenga (caminar, saltar, disparar, etc). +//-------------------------------------------------------------------------------------------------- + +#ifndef __CSPRITEANIMATION_H__ +#define __CSPRITEANIMATION_H__ + +#include "CSpriteFrame.h" +#include + +class CSpriteAnimation +{ + public: + CSpriteAnimation(void); + CSpriteAnimation(const char *aFile, int aFrames, int aRows, int aColumns, int aFrameWidth, int aFrameHeight, bool aFlippableH, bool aFlippableV); + ~CSpriteAnimation(void); + void destroy(void); + + int getWidth(void); + int getHeight(void); + int getNumFrames(void); + bool isBuilt(void); + + CSpriteFrame *getFrame(int aFrameIndex); + + private: + // Array with the animation frames. + std::vector mFrame; + + // Number of frames in the animation. + int mNumFrames; + + // Width and height del frame (todos los frames tienen el mismo ancho y alto). + int mWidth; + int mHeight; + + bool mBuilt; + + bool mFlippableH; + bool mFlippableV; + + int mStartFrameFlipH; + int mStartFrameFlipV; + int mStartFrameFlipHV; +}; + +#endif /* __CSPRITEANIMATION_H__ */ diff --git a/src/CSpriteFrame.cpp b/src/CSpriteFrame.cpp new file mode 100755 index 0000000..d0e898b --- /dev/null +++ b/src/CSpriteFrame.cpp @@ -0,0 +1,46 @@ +#include "CSpriteFrame.h" + +CSpriteFrame::CSpriteFrame(void) +{ + mImage = NULL; + mFrameTime = 100; +} + +CSpriteFrame::CSpriteFrame(CSurface *aImage) +{ + mImage = aImage; + mFrameTime = 100; +} + +CSpriteFrame::~CSpriteFrame(void) +{ + destroy(); +} + +void CSpriteFrame::destroy(void) +{ + if (mImage != NULL) + { + mImage->destroy(); + mImage = NULL; + } +} + +//-------------------------------------------------------------------------------------------------- +// getImage() +// Returns the image. +// +// Arguments: +// None. +// +// Returns: Pointer to the surface. +//-------------------------------------------------------------------------------------------------- +CSurface *CSpriteFrame::getImage(void) +{ + return mImage; +} + +int CSpriteFrame::getFrameTime(void) +{ + return mFrameTime; +} diff --git a/src/CSpriteFrame.h b/src/CSpriteFrame.h new file mode 100755 index 0000000..49e0053 --- /dev/null +++ b/src/CSpriteFrame.h @@ -0,0 +1,31 @@ +//-------------------------------------------------------------------------------------------------- +// CSpriteFrame. +// A class to represent a frame (image) of a aprite animation. +//-------------------------------------------------------------------------------------------------- + +#ifndef __CSPRITEFRAME_H__ +#define __CSPRITEFRAME_H__ + +#include +#include "CSurface.h" + +class CSpriteFrame +{ + public: + CSpriteFrame(void); + CSpriteFrame(CSurface *aImage); + ~CSpriteFrame(void); + void destroy(void); + + CSurface *getImage(void); + int getFrameTime(void); + + private: + // Image of the frame. + CSurface *mImage; + + // Time duration of the frame. + int mFrameTime; +}; + +#endif /* __CSPRITEFRAME_H__ */ diff --git a/src/CSurface.cpp b/src/CSurface.cpp new file mode 100755 index 0000000..645f089 --- /dev/null +++ b/src/CSurface.cpp @@ -0,0 +1,310 @@ +#include "CSurface.h" + +CSurface::CSurface(void) +{ + mImage = NULL; +} + +CSurface::CSurface(int aWidth, int aHeight) +{ + // create_blank_surface: Generates a new surface based on the +// current video settings. + + // Acquire the settings in the surface. + mImage = SDL_GetVideoSurface(); + + // Create the new surface using the Right-To_Left principle. + mImage = SDL_CreateRGBSurface (mImage->flags, aWidth, aHeight, + mImage->format->BitsPerPixel, + mImage->format->Rmask, + mImage->format->Gmask, + mImage->format->Bmask, + mImage->format->Amask); + + SDL_SetColorKey(mImage, SDL_SRCCOLORKEY, SDL_MapRGB(mImage->format, 255, 0, 255)); +} + +CSurface::CSurface(const char *aFile) +{ + mImage = CSurface::loadImage(aFile); +} + +CSurface::CSurface(SDL_Surface *aSDLSurface) +{ + mImage = aSDLSurface; +} + +CSurface::CSurface(SDL_Surface *aSDLSurface, int aFlipFlags) +{ + mImage = flipSurface(aSDLSurface, aFlipFlags); +} + +CSurface::~CSurface(void) +{ + destroy(); +} + +void CSurface::destroy(void) +{ + if (mImage != NULL) + { + SDL_FreeSurface(mImage); + mImage = NULL; + } +} + +//-------------------------------------------------------------------------------------------------- +// getImage() +// Returns the image. +// +// Arguments: +// None. +// +// Returns: Pointer to the image. +//-------------------------------------------------------------------------------------------------- +SDL_Surface *CSurface::getImage(void) +{ + return mImage; +} + +//-------------------------------------------------------------------------------------------------- +// draw() +// Blits the entire image on (x,y) coordinates. +// +// Arguments: +// aImgDst: Surface in which we draw the image. +// aX, aY: Coordinates where to draw. +// +// Returns: Nothing. +//-------------------------------------------------------------------------------------------------- +void CSurface::draw(SDL_Surface *aImgDst, int aX, int aY) +{ + CSurface::drawImage(aImgDst, mImage, aX, aY); +} + +//-------------------------------------------------------------------------------------------------- +// loadImage() +// It loads an image and returns a pointer to the image converted to the screen format. +// +// Arguments: +// aFile: Name of the image file to load. +// +// Returns: Pointer to the created surface. NULL if there is an error. +//-------------------------------------------------------------------------------------------------- +SDL_Surface *CSurface::loadImage(const char *aFile) +{ + SDL_Surface *loadedImg = NULL; + SDL_Surface *optimizedImg = NULL; + + //loadedImg = SDL_LoadBMP(file); + + // Load the image using SDL_image. + return loadedImg = IMG_Load(aFile); + + if (loadedImg != NULL) + { + optimizedImg = SDL_DisplayFormat(loadedImg); + // If the conversion fails or runs out of memory... + if (optimizedImg == NULL) + { + fprintf(stderr, "SDL_DisplayFormat() failed!\n"); + fprintf(stderr, "Error: %s\n", SDL_GetError()); + } + //else + //{ + // SDL_SetColorKey(optimizedImg, SDL_SRCCOLORKEY, SDL_MapRGB(optimizedImg->format, 0, 0xFF, 0xFF)); + //} + + SDL_FreeSurface(loadedImg); + } + else + { + fprintf(stderr, "loadImage() failed!\n"); + fprintf(stderr, "Error: %s\n", SDL_GetError()); + } + + return optimizedImg; +} + +//-------------------------------------------------------------------------------------------------- +// drawImage() +// Blits the entire image on (x,y) coordinates. +// +// Arguments: +// aImgDst: Surface in which we draw the image. +// aImgSrc: Image to be drawn. +// aX, aY: Coordinates where to draw. +// +// Returns: Nothing. +//-------------------------------------------------------------------------------------------------- +void CSurface::drawImage(SDL_Surface *aImgDst, SDL_Surface *aImgSrc, int aX, int aY) +{ + SDL_Rect dest; + dest.x = aX; + dest.y = aY; + SDL_BlitSurface(aImgSrc, NULL, aImgDst, &dest); +} + +//-------------------------------------------------------------------------------------------------- +// drawImage() +// Blits the rectangle (xSrc,ySrc,wSrc,hSrc) of the source image on (x,y) coordinates of the +// destination image. +// +// Arguments: +// aImgDst: Surface in which we draw the image. +// aImgSrc: Source image where the rectangle to be drawn resides in. +// xDest, yDest: Coordinates where to draw in the destination image. +// xSrc, ySrc: Coordinates of the rectangle to be drawn (in the source image). +// wSrc, hSrc: Width and height of the rectangle to be drawn (in the source image). +// +// Returns: Nothing. +//-------------------------------------------------------------------------------------------------- +void CSurface::drawImage(SDL_Surface *aImgDst, SDL_Surface *aImgSrc, int aXDest, int aYDest, int aXSrc, int aYSrc, int aWSrc, int aHSrc) +{ + SDL_Rect srcRect; + srcRect.x = aXSrc; + srcRect.y = aYSrc; + srcRect.w = aWSrc; + srcRect.h = aHSrc; + + SDL_Rect srcDest; + srcDest.x = aXDest; + srcDest.y = aYDest; + + SDL_BlitSurface(aImgSrc, &srcRect, aImgDst, &srcDest); +} + +//-------------------------------------------------------------------------------------------------- +// drawImage() +// Blits the entire image on (x,y) coordinates. +// +// Arguments: +// aImgDst: Surface in which we draw the image. +// aImgSrc: Image to be drawn. +// aX, aY: Coordinates where to draw. +// +// Returns: Nothing. +//-------------------------------------------------------------------------------------------------- +void CSurface::drawImage(CSurface *aImgDst, CSurface *aImgSrc, int aX, int aY) +{ + CSurface::drawImage(aImgDst->getImage(), aImgSrc->getImage(), aX, aY); +} + +//-------------------------------------------------------------------------------------------------- +// drawImage() +// Blits the rectangle (xSrc,ySrc,wSrc,hSrc) of the source image on (x,y) coordinates of the +// destination image. +// +// Arguments: +// aImgDst: Surface in which we draw the image. +// aImgSrc: Source image where the rectangle to be drawn resides in. +// xDest, yDest: Coordinates where to draw in the destination image. +// xSrc, ySrc: Coordinates of the rectangle to be drawn (in the source image). +// wSrc, hSrc: Width and height of the rectangle to be drawn (in the source image). +// +// Returns: Nothing. +//-------------------------------------------------------------------------------------------------- +void CSurface::drawImage(CSurface *aImgDst, CSurface *aImgSrc, int aXDest, int aYDest, int aXSrc, int aYSrc, int aWSrc, int aHSrc) +{ + CSurface::drawImage(aImgDst->getImage(), aImgSrc->getImage(), aXDest, aYDest, aXSrc, aYSrc, aWSrc, aHSrc); +} + +void CSurface::drawRect(SDL_Surface *aImgDst, int aX, int aY, int aW, int aH, int aColor) +{ + SDL_Rect dest; + dest.x = aX; + dest.y = aY; + dest.w = aW; + dest.h = aH; + SDL_FillRect(aImgDst, &dest, aColor); +} + +void CSurface::drawRect(CSurface *aImgDst, int aX, int aY, int aW, int aH, int aColor) +{ + CSurface::drawRect(aImgDst->getImage(), aX, aY, aW, aH, aColor); +} + + +Uint32 CSurface::get_pixel32(SDL_Surface *surface, int x, int y) +{ + //Convert the pixels to 32 bit + Uint32 *pixels = (Uint32 *)surface->pixels; + + //Get the requested pixel + return pixels[ ( y * surface->w ) + x ]; +} + +void CSurface::put_pixel32( SDL_Surface *surface, int x, int y, Uint32 pixel ) +{ + //Convert the pixels to 32 bit + Uint32 *pixels = (Uint32 *)surface->pixels; + + //Set the pixel + pixels[ ( y * surface->w ) + x ] = pixel; +} + +SDL_Surface *CSurface::flipSurface(SDL_Surface *surface, int flags) +{ + //Pointer to the soon to be flipped surface + SDL_Surface *flipped = NULL; + + //If the image is color keyed + if( surface->flags & SDL_SRCCOLORKEY ) + { + flipped = SDL_CreateRGBSurface( SDL_SWSURFACE, surface->w, surface->h, surface->format->BitsPerPixel, surface->format->Rmask, surface->format->Gmask, surface->format->Bmask, 0 ); + } + //Otherwise + else + { + flipped = SDL_CreateRGBSurface( SDL_SWSURFACE, surface->w, surface->h, surface->format->BitsPerPixel, surface->format->Rmask, surface->format->Gmask, surface->format->Bmask, surface->format->Amask ); + } + + //If the surface must be locked + if( SDL_MUSTLOCK( surface ) ) + { + //Lock the surface + SDL_LockSurface( surface ); + } + + //Go through columns + for( int x = 0, rx = flipped->w - 1; x < flipped->w; x++, rx-- ) + { + //Go through rows + for( int y = 0, ry = flipped->h - 1; y < flipped->h; y++, ry-- ) + { + //Get pixel + Uint32 pixel = get_pixel32( surface, x, y ); + + //Copy pixel + if( ( flags & FLIP_VERTICAL ) && ( flags & FLIP_HORIZONTAL ) ) + { + put_pixel32( flipped, rx, ry, pixel ); + } + else if( flags & FLIP_HORIZONTAL ) + { + put_pixel32( flipped, rx, y, pixel ); + } + else if( flags & FLIP_VERTICAL ) + { + put_pixel32( flipped, x, ry, pixel ); + } + } + } + + //Unlock surface + if( SDL_MUSTLOCK( surface ) ) + { + SDL_UnlockSurface( surface ); + } + + //Copy color key + if( surface->flags & SDL_SRCCOLORKEY ) + { + SDL_SetColorKey( flipped, SDL_RLEACCEL | SDL_SRCCOLORKEY, surface->format->colorkey ); + } + + //Return flipped surface + return flipped; +} + + diff --git a/src/CSurface.h b/src/CSurface.h new file mode 100755 index 0000000..24418c9 --- /dev/null +++ b/src/CSurface.h @@ -0,0 +1,46 @@ +//-------------------------------------------------------------------------------------------------- +// CSurface. +// A class to represent an image. +//-------------------------------------------------------------------------------------------------- + +#ifndef __CSURFACE_H__ +#define __CSURFACE_H__ + +#include +#include + +class CSurface +{ + public: + CSurface(void); + CSurface(int aWidth, int aHeight); + CSurface(const char *aFile); + CSurface(SDL_Surface *aSDLSurface); + CSurface(SDL_Surface *aSDLSurface, int aFlipFlags); + ~CSurface(void); + void destroy(void); + + static SDL_Surface *loadImage(const char *aFile); + static void drawImage(SDL_Surface *aImgDst, SDL_Surface *aImgSrc, int aX, int aY); + static void drawImage(SDL_Surface *aImgDst, SDL_Surface *aImgSrc, int aXDest, int aYDest, int aXSrc, int aYSrc, int aWSrc, int aHSrc); + static void drawImage(CSurface *aImgDst, CSurface *aImgSrc, int aX, int aY); + static void drawImage(CSurface *aImgDst, CSurface *aImgSrc, int aXDest, int aYDest, int aXSrc, int aYSrc, int aWSrc, int aHSrc); + static void drawRect(SDL_Surface *aImgDst, int aX, int aY, int aW, int aH, int aColor); + static void drawRect(CSurface *aImgDst, int aX, int aY, int aW, int aH, int aColor); + + SDL_Surface *getImage(void); + void draw(SDL_Surface *aImgDst, int aX, int aY); + + static const int FLIP_HORIZONTAL = 1; + static const int FLIP_VERTICAL = 2; + + private: + SDL_Surface *flipSurface(SDL_Surface *surface, int flags); + void put_pixel32(SDL_Surface *surface, int x, int y, Uint32 pixel); + Uint32 get_pixel32(SDL_Surface *surface, int x, int y); + + // Image surface. + SDL_Surface *mImage; +}; + +#endif /* __CSURFACE_H__ */ diff --git a/src/CTileMap.cpp b/src/CTileMap.cpp new file mode 100755 index 0000000..c75cb99 --- /dev/null +++ b/src/CTileMap.cpp @@ -0,0 +1,89 @@ +#include "CTileMap.h" + +CTileMap::CTileMap(void) +{ + CTileMap(0); +} + +CTileMap::CTileMap(int aMapIndex) +{ + mCurrentMap = aMapIndex; + mMapImage = new CSurface(CGameConstants::MAP_WIDTH * CGameConstants::TILE_WIDTH, CGameConstants::MAP_HEIGHT * CGameConstants::TILE_HEIGHT); + loadMap(mCurrentMap); +} + +CTileMap::~CTileMap(void) +{ + destroy(); +} + +void CTileMap::destroy(void) +{ + delete mMapImage; + mMapImage = NULL; +} + +void CTileMap::loadMap(int aMap) +{ + mCurrentMap = aMap; + + FILE *f; + int c; + + // Load the map. + if ((f = fopen("assets/data/maps/map001.bin", "rb")) != NULL) + { + c = fread(mMap, CGameConstants::MAP_WIDTH * CGameConstants::MAP_HEIGHT, 1, f); + fclose(f); + } + else + { + fprintf(stdout, "Unable to read map!\n"); + } + + fprintf(stdout, "mMap[15] = %d\n", mMap[0]); + fprintf(stdout, "mMap[62] = %d\n", mMap[62]); + fprintf(stdout, "mMap[63] = %d\n", mMap[63]); + fprintf(stdout, "mMap[64] = %d\n", mMap[64]); + + CSurface *tilesImage = new CSurface("assets/images/tiles/tileset0.png"); + + // Dibujar el mapa tileado. + for (int i=0; i < CGameConstants::MAP_HEIGHT; i++) + { + for (int j=0; j < CGameConstants::MAP_WIDTH; j++) + { + int tile = mMap[i*CGameConstants::MAP_WIDTH+j]; + + // Calculo la ubicación del tile en la imagen de tiles. + int xtile = (tile % CGameConstants::TILE_IMAGE_WIDTH) * CGameConstants::TILE_WIDTH; + int ytile = (tile / CGameConstants::TILE_IMAGE_WIDTH) * CGameConstants::TILE_HEIGHT; + + // Calculo de la posición del tile en pantalla. + int x = j * CGameConstants::TILE_WIDTH; + int y = i * CGameConstants::TILE_HEIGHT; + + CSurface::drawImage(mMapImage, tilesImage, x, y, xtile, ytile, CGameConstants::TILE_WIDTH, CGameConstants::TILE_HEIGHT); + //CSurface::drawImage(mMapImage, tilesImg, x, y, xtile, ytile, 72, 72); + } + } + + delete tilesImage; + tilesImage = NULL; +} + +void CTileMap::draw(CSurface *aImgDst, int aX, int aY) +{ + CSurface::drawImage(aImgDst, mMapImage, aX, aY); +} + +int CTileMap::getTile(int aTileX, int aTileY) +{ + return mMap[aTileY*CGameConstants::MAP_WIDTH+aTileX]; +} + +bool CTileMap::isWalkable(int aTileX, int aTileY) +{ + int tile = mMap[aTileY*CGameConstants::MAP_WIDTH+aTileX]; + return (tile == 2 || tile == 4 || tile == 1); +} diff --git a/src/CTileMap.h b/src/CTileMap.h new file mode 100755 index 0000000..ed3536c --- /dev/null +++ b/src/CTileMap.h @@ -0,0 +1,30 @@ +//-------------------------------------------------------------------------------------------------- +// CTileMap. +// A class to represent the tiled based map. +//-------------------------------------------------------------------------------------------------- + +#ifndef __CTILEMAP_H__ +#define __CTILEMAP_H__ + +#include "CGameConstants.h" +#include "CSurface.h" + +class CTileMap +{ + public: + CTileMap(void); + CTileMap(int aMapIndex); + ~CTileMap(void); + void destroy(void); + void loadMap(int aMap); + void draw(CSurface *aImgDst, int aX, int aY); + int getTile(int aTileX, int aTileY); + bool isWalkable(int aTileX, int aTileY); + + private: + int mCurrentMap; + CSurface *mMapImage; + char mMap[CGameConstants::MAP_WIDTH * CGameConstants::MAP_HEIGHT]; +}; + +#endif /* __CTILEMAP_H__ */ diff --git a/src/CTimer.cpp b/src/CTimer.cpp new file mode 100755 index 0000000..74e4035 --- /dev/null +++ b/src/CTimer.cpp @@ -0,0 +1,30 @@ +#include "CTimer.h" + +CTimer::CTimer(void) +{ + mPrevTime = SDL_GetTicks(); + mStartTime = mPrevTime; +} + +CTimer::~CTimer(void) +{ +} + +float CTimer::getTimeElapsed() +{ + static Uint32 currTime; + currTime = SDL_GetTicks(); + + float elapsed = (currTime - mPrevTime) * .001f; + mPrevTime = currTime; + + return elapsed; +} + +float CTimer::getTime() +{ + static Uint32 currTime; + currTime = SDL_GetTicks(); + + return (currTime - mStartTime) * .001f; +} diff --git a/src/CTimer.h b/src/CTimer.h new file mode 100755 index 0000000..b22b524 --- /dev/null +++ b/src/CTimer.h @@ -0,0 +1,26 @@ +//-------------------------------------------------------------------------------------------------- +// CTimer. +// A class to represent a simple timer (used to show FPS for example). +//-------------------------------------------------------------------------------------------------- + +#ifndef __TIMER_H__ +#define __TIMER_H__ + +#include + +class CTimer +{ + public: + CTimer(void); + ~CTimer(void); + + float getTimeElapsed(void); + float getTime(void); + + private: + Uint32 mStartTime; + Uint32 mPrevTime; +}; + +#endif /* __CTIMER_H__ */ + diff --git a/src/CVector.cpp b/src/CVector.cpp new file mode 100755 index 0000000..412cf93 --- /dev/null +++ b/src/CVector.cpp @@ -0,0 +1,20 @@ +#include "CVector.h" + +CVector::CVector(void) +{ +} + +CVector::CVector(float aX, float aY) +{ + x = aX; + y = aY; +} + +CVector::~CVector(void) +{ + destroy(); +} + +void CVector::destroy(void) +{ +} diff --git a/src/CVector.h b/src/CVector.h new file mode 100755 index 0000000..2cb8d32 --- /dev/null +++ b/src/CVector.h @@ -0,0 +1,21 @@ +//-------------------------------------------------------------------------------------------------- +// CVector. +// A class to represent a vector. +//-------------------------------------------------------------------------------------------------- + +#ifndef __CVECTOR_H__ +#define __CVECTOR_H__ + +class CVector +{ + public: + CVector(void); + CVector(float aX, float aY); + ~CVector(void); + void destroy(void); + + float x; + float y; +}; + +#endif /* __CVECTOR_H__ */ diff --git a/src/main.cpp b/src/main.cpp new file mode 100755 index 0000000..a90b08e --- /dev/null +++ b/src/main.cpp @@ -0,0 +1,383 @@ +//-------------------------------------------------------------------------------------------------- +// Arcade game for the XO computer (OLPC). +// by CeibalJAM. +// +// NOTE: This was made quickly with the purpose of testing the performance of the XO machine. +// The code is not optimized and it should be worked more in order to be used in a production environment. +// Please use it for learning purposes and/or as a starting point. +//-------------------------------------------------------------------------------------------------- + +// TODO: +// - Convert the CFont routines to a class CFont. +// - Add functions in CFont to draw in a CSurface object. + +#include +#include +#include +#include "CBenchmark.h" +#include "CFont.h" +#include "CGame.h" +#include "CGameConstants.h" +#include "CPlayer.h" +#include "CSurface.h" +#include "CSpriteAnimation.h" +#include "CSprite.h" +#include "CTimer.h" + +//The music that will be played +//Mix_Music *music = NULL; + +//The sound effects that will be used +//Mix_Chunk *sfx1 = NULL; +//Mix_Chunk *sfx2 = NULL; +//Mix_Chunk *sfx3 = NULL; +//Mix_Chunk *sfx4 = NULL; + +// Screen surface. +SDL_Surface *mScreen = NULL; +CSurface *mScreenSurface = NULL; + +//SDL_Surface *mImageBMP = NULL; +//SDL_Surface *mImagePNG = NULL; +//CSurface *mImageBMP2 = NULL; +//CSurface *mImagePNG2 = NULL; + + + +CBenchmark *mBenchmark; + +char *string = "Xoxi y los Derechos del Nino"; + +char *string2 = "Press 1, 2, 3, or 4 to play a sound effect"; +char *string3 = "Press 9 to play or pause the music"; + +SDLFont *font1; +SDLFont *font2; + +CGame *mGame; + +bool init() +{ + // SDL_Init is the first function of SDL we have to call. + // Initialize video, audio and joystick subsystems. + if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_JOYSTICK) == -1) + { + fprintf(stderr, "SDL initialization failed!\n"); + fprintf(stderr, "Error: %s\n", SDL_GetError()); + return false; + } + else + { + fprintf(stdout, "SDL initialized properly!\n"); + // When the program terminates (either normally or by calling the exit function), it will call each of the + // functions added to the list of functions sent by atexit in the reverse order of how they were sent. + // The function passed as a parameter to atexit() must not have arguments. + atexit(SDL_Quit); + } + + //Initialize SDL_mixer + if( Mix_OpenAudio( 22050, MIX_DEFAULT_FORMAT, 2, 2048/*4096*/ ) == -1 ) + { + return false; + } + + // Set the icon image as the icon of the program. + SDL_WM_SetIcon(SDL_LoadBMP("assets/images/icon/icon.bmp"), NULL); + + mScreen = SDL_SetVideoMode(CGameConstants::SCREEN_WIDTH, CGameConstants::SCREEN_HEIGHT, CGameConstants::SCREEN_BPP, SDL_ANYFORMAT); + if (mScreen == NULL) + { + fprintf(stderr, "Could not create screen surface (set video mode)!\n"); + fprintf(stderr, "Error: %s\n", SDL_GetError()); + return false; + } + + mScreenSurface = new CSurface(mScreen); + + // Set the window caption . + SDL_WM_SetCaption( "GameXO", NULL ); + + return true; +} + +bool loadImages() +{ +// mImageBMP = CSurface::loadImage("assets\\images\\andy\\andy.bmp"); +// if (mImageBMP == NULL) +// return false; +// mImagePNG = CSurface::loadImage("assets\\images\\andy\\andy.png"); +// if (mImagePNG == NULL) +// return false; +// +// mImageBMP2 = new CSurface("assets\\images\\andy\\andy.bmp"); +// if (mImageBMP2->getImage() == NULL) +// return false; +// mImagePNG2 = new CSurface("assets\\images\\andy\\andy.png"); +// if (mImagePNG2->getImage() == NULL) +// return false; + + + // Load in the fonts. + font1 = initFont("assets/fonts/font1", 1, 0, 0); + if (font1 == NULL) + { + fprintf(stderr, "Could not load font1!\n"); + exit(1); + } + font2 = initFont("assets/fonts/font2", 1, 1, 0); + if (font2 == NULL) + { + fprintf(stderr, "Could not load font2!\n"); + exit(1); + } + + + + + return true; +} + +void destroy() +{ + delete mGame; + mGame = NULL; + + freeFont(font1); + freeFont(font2); + + + // Free the surfaces. +// SDL_FreeSurface(mImageBMP); +// SDL_FreeSurface(mImagePNG); + +// mImageBMP2->destroy(); +// mImageBMP2 = NULL; +// mImagePNG2->destroy(); +// mImagePNG2 = NULL; + + + + delete mBenchmark; + mBenchmark = NULL; + + //Free the sound effects +/* Mix_FreeChunk( sfx1 ); + Mix_FreeChunk( sfx2 ); + Mix_FreeChunk( sfx3 ); + Mix_FreeChunk( sfx4 ); + + //Free the sound effects + Mix_FreeMusic( music ); +*/ + //Quit SDL. The screen surface is deleted here. + SDL_Quit(); +} + +void update(void) +{ + mGame->update(); +} + +void render(void) +{ + mGame->render(); + + + // CSurface::drawImage(mScreen, mImageBMP, 0, 0); + // CSurface::drawImage(mScreen, mImagePNG, 50, 50); + +// mImageBMP2->draw(mScreen, 100, 100); +// mImagePNG2->draw(mScreen, 150, 150); + + // TEST DE QUE NO HAY TRANSPARENCIA !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + //CSurface *t = new CSurface("assets\\images\\andy\\andy_animation.png"); + //t->draw(mScreen, 100, 100); + //delete t; + // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!1 + +// CSurface::drawImage(mScreenSurface, mAndyAnimation->getFrame(0)->getImage(), 400, 400); +// CSurface::drawImage(mScreen, mAndyAnimation->getFrame(1)->getImage()->getImage(), 300, 100); + + + if (mBenchmark->getVisible()) + { + CSurface::drawRect(mScreen, 290, 0, 130, 30, 0x000000); + drawString(mScreen, font1, 300, 0, "FPS: %d\n", mBenchmark->getDisplayCounter()); + } + + // Draw the text to the center of the screen. + drawString(mScreen,font2,600-stringWidth(font2,string)/2,50,string); + + // Sourn help. + drawString(mScreen,font2,600-stringWidth(font2,string2)/2,100,string2); + drawString(mScreen,font2,600-stringWidth(font2,string3)/2,150,string3); + + if (SDL_Flip(mScreen) == -1) + { + fprintf(stderr, "SDL_Flip() failed!\n"); + fprintf(stderr, "Error: %s\n", SDL_GetError()); + } +} + +int main(int argc, char* argv[]) +{ + bool mQuit = false; + SDL_Event mEvent; + + mBenchmark = new CBenchmark(true); + + CTimer timer; + + if (!init()) + { + exit(1); + } + + if (!loadImages()) + { + exit(2); + } + + + //Load the music + //music = Mix_LoadMUS( "assets/audio/music_adventure.ogg" ); + + //If there was a problem loading the music + //if( music == NULL ) + //{ + // fprintf(stderr, "Load music failed!\n"); + // return false; + //} + + //Load the sound effects + //sfx1 = Mix_LoadWAV( "assets/audio/sfx1.ogg" ); + //sfx2 = Mix_LoadWAV( "assets/audio/sfx2.ogg" ); + //sfx3 = Mix_LoadWAV( "assets/audio/sfx3.ogg" ); + //sfx4 = Mix_LoadWAV( "assets/audio/sfx4.ogg" ); + + //If there was a problem loading the sound effects + //if( ( sfx1 == NULL ) || ( sfx2 == NULL ) || ( sfx3 == NULL ) || ( sfx4 == NULL ) ) + //{ + // fprintf(stderr, "Load sfx failed!\n"); + // return false; + //} + + + mGame = new CGame(mScreenSurface); + + mGame->drawMap(); + render(); + + // While the user hasn't quit... + while (!mQuit) + { + float dt = timer.getTimeElapsed(); + mBenchmark->update(dt); + + // While there's an event to handle. + while (SDL_PollEvent(&mEvent)) + { + if (mEvent.type == SDL_QUIT) + { + fprintf(stdout, "Quit event has occurred.\n"); + mQuit = true; + } + + if (mEvent.type == SDL_KEYDOWN) + { + if (mEvent.key.keysym.sym == SDLK_ESCAPE ) + { + mQuit = true; + } + //If 1 was pressed +/* else if ( mEvent.key.keysym.sym == SDLK_1 ) + { + //Play the scratch effect + if( Mix_PlayChannel( -1, sfx1, 0 ) == -1 ) + { + fprintf(stderr, "sfx1 no se puede tocar!\n"); + //return 1; + } + } + //If 2 was pressed + else if( mEvent.key.keysym.sym == SDLK_2 ) + { + //Play the high hit effect + if( Mix_PlayChannel( -1, sfx2, 0 ) == -1 ) + { + fprintf(stderr, "sfx2 no se puede tocar!\n"); + //return 1; + } + } + //If 3 was pressed + else if( mEvent.key.keysym.sym == SDLK_3 ) + { + //Play the medium hit effect + if( Mix_PlayChannel( -1, sfx3, 0 ) == -1 ) + { + fprintf(stderr, "sfx3 no se puede tocar!\n"); + //return 1; + } + } + //If 4 was pressed + else if( mEvent.key.keysym.sym == SDLK_4 ) + { + //Play the low hit effect + if( Mix_PlayChannel( -1, sfx4, 0 ) == -1 ) + { + fprintf(stderr, "sfx4 no se puede tocar!\n"); + //return 1; + } + } + //If 9 was pressed + else if( mEvent.key.keysym.sym == SDLK_9 ) + { + //If there is no music playing + if( Mix_PlayingMusic() == 0 ) + { + //Play the music + if( Mix_PlayMusic( music, -1 ) == -1 ) + { + fprintf(stderr, "music no se puede tocar!\n"); + //return 1; + } + } + //If music is being played + else + { + //If the music is paused + if( Mix_PausedMusic() == 1 ) + { + //Resume the music + Mix_ResumeMusic(); + } + //If the music is playing + else + { + //Pause the music + Mix_PauseMusic(); + } + } + } + //If 0 was pressed4 + else if( mEvent.key.keysym.sym == SDLK_0 ) + { + //Stop the music + Mix_HaltMusic(); + } +*/ + } + } + + update(); + render(); + } + + destroy(); + + fprintf(stdout, "Terminating program normally.\n"); + + return 0; +} + + -- cgit v0.9.1