nsnake-1.5/0000775000175000017500000000000012135565363011347 5ustar kurekurensnake-1.5/README0000644000175000017500000001303712135565363012231 0ustar kurekurenSnake README ============= nSnake is the classic snake game playable on the console. It has two modes (with or without borders) and 9 speed levels. It uses the nCurses C library for text-like interface. README Index ------------ 1) Introduction 2) Controls 3) Installation 4) Installation Informations 5) Advanced Installation 6) Uninstallation 7) Advanced Uninstallation 8) Dependencies 9) Main Directory Structure 10) Credits/Contact 11) License Note: Make sure you have libncurses5-dev. See 'Dependences' for more details. 1) Introduction --------------- The rules are the same of any snake game: You control a hungry snake and the objective is to eat as many fruits you can. Each fruit eaten increases it's size by two units. The game ends when the snake collides with the walls or itself. Currently, nSnake has two modes: With Borders and without borders. To each fruit is given a bonus value, which decreases over time. So the challenge is to earn the biggest score possible by eating as many fruits as you can. Good luck! 2) Controls ----------- Numbers (1~9) Changes the game speed at the main menu Arrow Keys, WASD Moves the snake q Quits the game at any time p Pauses/Unpauses the game 3) Installation --------------- Briefly, the following shell commands should configure, build and install this package on the default directories: $ make $ sudo make install 4) Installation Informations ---------------------------- see INSTALL file 5) Advanced Installation ------------------------ see INSTALL file 6) Uninstallation ----------------- see INSTALL file 7) Advanced Uninstallation -------------------------- see INSTALL file 8) Dependences -------------- see INSTALL file 9) Main Directory Structure --------------------------- README General game information INSTALL Installation instructions and information COPYING Copyright and warranty info Doxyfile Doxygen file for generating the documentation Makefile Instructions to the 'make' program TODO Work that needs to be done or ideas for future versions BUGS Known bugs and information about where to submit new ones bin/ Location of the executable generated after compilation doc/ The documentation files (explaining the source code) and manpage obj/ Location of resulting object files after compilation src/ All of the source code files doc/index.html Complete source code documentation doc/nsnake.6.gz The manpage 10) Contact ----------- Hello there, I'm Alexandre Dantas (kure)! Thanks for downloading and playing this game. I'm glad you had interest on this project. You can send me comments, bugs, ideas or anything else by email. And if you have time, please visit my blog! My email: alex.dantas92@gmail.com My homepage: http://www.alexdantas.net/ nSnake main page: http://www.alexdantas.net/projects/nsnake/ I'd appreciate any commentary - even if it's just "Hello, I play your game!". 10) Credits ----------- Firstly, I'd like to thank you for playing this game. Hope you liked it! The whole game design, coding, documenting, packaging and testing were all made by me, on my free time. But I didn't do everything! Throughout the nSnake development, I found very interesting sources of ideas - such as games who also uses nCurses for displaying graphics. They have simple, short and commented source-codes that can be used as references to learn C programming. Special thanks to: nInvaders: A space invaders-like game using ncurses. homepage: http://ninvaders.sourceforge.net comments: "Thanks for the inspiration. If I haven't installed this in first place, I'd never have the idea for nSnake" pacman4console: A console-based pacman game. homepage: http://doctormike.googlepages.com/pacman.html comments: "The way this package was organized is incredible. Thanks for the general packaging ideas" vadorz: An addicting ncurses space-invaders game. homepage: http://code.google.com/p/vadorz/ comments: "This package is awesome, 'cause it uses ncurses AND pdcurses to be able to play in Windows and GNU/Linux" snake4: Fruit-eating snake game homepage: http://shh.thathost.com/ comments: "Thanks for the Makefile ideas. It's very well-written." ASCII Generator: A generator of awesome ASCII text arts homepage: http://www.network-science.de/ascii/ Text ASCII Art Generator: Another awesome ASCII text generator homepage: http://patorjk.com/software/taag/ comments: "I've used the Modular font to display the Game Over screen" 11) License ----------- nSnake - The classic snake game with ncurses. Copyright (C) 2011 Alexandre Dantas (kure) nSnake is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . homepage: http://www.alexdantas.net/projects/nsnake/ mailto: alex.dantas92@gmail.com nsnake-1.5/Doxyfile0000644000175000017500000002406112135565363013056 0ustar kurekure# Doxyfile 1.8.2 #--------------------------------------------------------------------------- # Project related configuration options #--------------------------------------------------------------------------- DOXYFILE_ENCODING = UTF-8 PROJECT_NAME = nSnake PROJECT_NUMBER = PROJECT_BRIEF = "A ncurses implementation of the classic Snake game" PROJECT_LOGO = ./doc/logo.png OUTPUT_DIRECTORY = ./doc CREATE_SUBDIRS = NO OUTPUT_LANGUAGE = English BRIEF_MEMBER_DESC = YES REPEAT_BRIEF = YES ABBREVIATE_BRIEF = ALWAYS_DETAILED_SEC = NO INLINE_INHERITED_MEMB = NO FULL_PATH_NAMES = YES STRIP_FROM_PATH = STRIP_FROM_INC_PATH = SHORT_NAMES = NO JAVADOC_AUTOBRIEF = YES QT_AUTOBRIEF = NO MULTILINE_CPP_IS_BRIEF = NO INHERIT_DOCS = YES SEPARATE_MEMBER_PAGES = NO TAB_SIZE = 4 ALIASES = TCL_SUBST = OPTIMIZE_OUTPUT_FOR_C = YES OPTIMIZE_OUTPUT_JAVA = NO OPTIMIZE_FOR_FORTRAN = NO OPTIMIZE_OUTPUT_VHDL = NO EXTENSION_MAPPING = MARKDOWN_SUPPORT = YES AUTOLINK_SUPPORT = YES BUILTIN_STL_SUPPORT = NO CPP_CLI_SUPPORT = NO SIP_SUPPORT = NO IDL_PROPERTY_SUPPORT = YES DISTRIBUTE_GROUP_DOC = NO SUBGROUPING = YES INLINE_GROUPED_CLASSES = NO INLINE_SIMPLE_STRUCTS = NO TYPEDEF_HIDES_STRUCT = YES SYMBOL_CACHE_SIZE = 0 LOOKUP_CACHE_SIZE = 0 #--------------------------------------------------------------------------- # Build related configuration options #--------------------------------------------------------------------------- EXTRACT_ALL = NO EXTRACT_PRIVATE = NO EXTRACT_PACKAGE = NO EXTRACT_STATIC = NO EXTRACT_LOCAL_CLASSES = YES EXTRACT_LOCAL_METHODS = NO EXTRACT_ANON_NSPACES = NO HIDE_UNDOC_MEMBERS = NO HIDE_UNDOC_CLASSES = NO HIDE_FRIEND_COMPOUNDS = NO HIDE_IN_BODY_DOCS = NO INTERNAL_DOCS = NO CASE_SENSE_NAMES = YES HIDE_SCOPE_NAMES = NO SHOW_INCLUDE_FILES = YES FORCE_LOCAL_INCLUDES = NO INLINE_INFO = YES SORT_MEMBER_DOCS = YES SORT_BRIEF_DOCS = NO SORT_MEMBERS_CTORS_1ST = NO SORT_GROUP_NAMES = NO SORT_BY_SCOPE_NAME = NO STRICT_PROTO_MATCHING = NO GENERATE_TODOLIST = YES GENERATE_TESTLIST = YES GENERATE_BUGLIST = YES GENERATE_DEPRECATEDLIST= YES ENABLED_SECTIONS = MAX_INITIALIZER_LINES = 30 SHOW_USED_FILES = YES SHOW_FILES = YES SHOW_NAMESPACES = YES FILE_VERSION_FILTER = LAYOUT_FILE = CITE_BIB_FILES = #--------------------------------------------------------------------------- # configuration options related to warning and progress messages #--------------------------------------------------------------------------- QUIET = NO WARNINGS = YES WARN_IF_UNDOCUMENTED = YES WARN_IF_DOC_ERROR = YES WARN_NO_PARAMDOC = NO WARN_FORMAT = "$file:$line: $text" WARN_LOGFILE = #--------------------------------------------------------------------------- # configuration options related to the input files #--------------------------------------------------------------------------- INPUT = ./src/ \ ./doc/doxygen_mainpage.h INPUT_ENCODING = UTF-8 FILE_PATTERNS = *.c \ *.h RECURSIVE = NO EXCLUDE = EXCLUDE_SYMLINKS = NO EXCLUDE_PATTERNS = EXCLUDE_SYMBOLS = EXAMPLE_PATH = EXAMPLE_PATTERNS = EXAMPLE_RECURSIVE = NO IMAGE_PATH = INPUT_FILTER = FILTER_PATTERNS = FILTER_SOURCE_FILES = NO FILTER_SOURCE_PATTERNS = #--------------------------------------------------------------------------- # configuration options related to source browsing #--------------------------------------------------------------------------- SOURCE_BROWSER = YES INLINE_SOURCES = NO STRIP_CODE_COMMENTS = YES REFERENCED_BY_RELATION = NO REFERENCES_RELATION = NO REFERENCES_LINK_SOURCE = YES USE_HTAGS = NO VERBATIM_HEADERS = YES #--------------------------------------------------------------------------- # configuration options related to the alphabetical class index #--------------------------------------------------------------------------- ALPHABETICAL_INDEX = YES COLS_IN_ALPHA_INDEX = 5 IGNORE_PREFIX = #--------------------------------------------------------------------------- # configuration options related to the HTML output #--------------------------------------------------------------------------- GENERATE_HTML = YES HTML_OUTPUT = html HTML_FILE_EXTENSION = .html HTML_HEADER = HTML_FOOTER = HTML_STYLESHEET = HTML_EXTRA_STYLESHEET = HTML_EXTRA_FILES = HTML_COLORSTYLE_HUE = 220 HTML_COLORSTYLE_SAT = 100 HTML_COLORSTYLE_GAMMA = 80 HTML_TIMESTAMP = YES HTML_DYNAMIC_SECTIONS = NO HTML_INDEX_NUM_ENTRIES = 100 GENERATE_DOCSET = NO DOCSET_FEEDNAME = "Doxygen generated docs" DOCSET_BUNDLE_ID = org.doxygen.Project DOCSET_PUBLISHER_ID = org.doxygen.Publisher DOCSET_PUBLISHER_NAME = Publisher GENERATE_HTMLHELP = NO CHM_FILE = HHC_LOCATION = GENERATE_CHI = NO CHM_INDEX_ENCODING = BINARY_TOC = NO TOC_EXPAND = NO GENERATE_QHP = NO QCH_FILE = QHP_NAMESPACE = org.doxygen.Project QHP_VIRTUAL_FOLDER = doc QHP_CUST_FILTER_NAME = QHP_CUST_FILTER_ATTRS = QHP_SECT_FILTER_ATTRS = QHG_LOCATION = GENERATE_ECLIPSEHELP = NO ECLIPSE_DOC_ID = org.doxygen.Project DISABLE_INDEX = NO GENERATE_TREEVIEW = NO ENUM_VALUES_PER_LINE = 4 TREEVIEW_WIDTH = 250 EXT_LINKS_IN_WINDOW = NO FORMULA_FONTSIZE = 10 FORMULA_TRANSPARENT = YES USE_MATHJAX = NO MATHJAX_RELPATH = http://www.mathjax.org/mathjax MATHJAX_EXTENSIONS = SEARCHENGINE = YES SERVER_BASED_SEARCH = NO #--------------------------------------------------------------------------- # configuration options related to the LaTeX output #--------------------------------------------------------------------------- GENERATE_LATEX = NO LATEX_OUTPUT = latex LATEX_CMD_NAME = latex MAKEINDEX_CMD_NAME = makeindex COMPACT_LATEX = NO PAPER_TYPE = a4 EXTRA_PACKAGES = LATEX_HEADER = LATEX_FOOTER = PDF_HYPERLINKS = YES USE_PDFLATEX = YES LATEX_BATCHMODE = NO LATEX_HIDE_INDICES = NO LATEX_SOURCE_CODE = NO LATEX_BIB_STYLE = plain #--------------------------------------------------------------------------- # configuration options related to the RTF output #--------------------------------------------------------------------------- GENERATE_RTF = NO RTF_OUTPUT = rtf COMPACT_RTF = NO RTF_HYPERLINKS = NO RTF_STYLESHEET_FILE = RTF_EXTENSIONS_FILE = #--------------------------------------------------------------------------- # configuration options related to the man page output #--------------------------------------------------------------------------- GENERATE_MAN = NO MAN_OUTPUT = man MAN_EXTENSION = .3 MAN_LINKS = NO #--------------------------------------------------------------------------- # configuration options related to the XML output #--------------------------------------------------------------------------- GENERATE_XML = NO XML_OUTPUT = xml XML_SCHEMA = XML_DTD = XML_PROGRAMLISTING = YES #--------------------------------------------------------------------------- # configuration options for the AutoGen Definitions output #--------------------------------------------------------------------------- GENERATE_AUTOGEN_DEF = NO #--------------------------------------------------------------------------- # configuration options related to the Perl module output #--------------------------------------------------------------------------- GENERATE_PERLMOD = NO PERLMOD_LATEX = NO PERLMOD_PRETTY = YES PERLMOD_MAKEVAR_PREFIX = #--------------------------------------------------------------------------- # Configuration options related to the preprocessor #--------------------------------------------------------------------------- ENABLE_PREPROCESSING = YES MACRO_EXPANSION = NO EXPAND_ONLY_PREDEF = NO SEARCH_INCLUDES = YES INCLUDE_PATH = INCLUDE_FILE_PATTERNS = PREDEFINED = EXPAND_AS_DEFINED = SKIP_FUNCTION_MACROS = YES #--------------------------------------------------------------------------- # Configuration::additions related to external references #--------------------------------------------------------------------------- TAGFILES = GENERATE_TAGFILE = ALLEXTERNALS = NO EXTERNAL_GROUPS = YES PERL_PATH = /usr/bin/perl #--------------------------------------------------------------------------- # Configuration options related to the dot tool #--------------------------------------------------------------------------- CLASS_DIAGRAMS = YES MSCGEN_PATH = HIDE_UNDOC_RELATIONS = YES HAVE_DOT = YES DOT_NUM_THREADS = 0 DOT_FONTNAME = Helvetica DOT_FONTSIZE = 10 DOT_FONTPATH = CLASS_GRAPH = YES COLLABORATION_GRAPH = YES GROUP_GRAPHS = YES UML_LOOK = NO UML_LIMIT_NUM_FIELDS = 10 TEMPLATE_RELATIONS = NO INCLUDE_GRAPH = YES INCLUDED_BY_GRAPH = YES CALL_GRAPH = NO CALLER_GRAPH = NO GRAPHICAL_HIERARCHY = YES DIRECTORY_GRAPH = YES DOT_IMAGE_FORMAT = png INTERACTIVE_SVG = NO DOT_PATH = DOTFILE_DIRS = MSCFILE_DIRS = DOT_GRAPH_MAX_NODES = 50 MAX_DOT_GRAPH_DEPTH = 0 DOT_TRANSPARENT = NO DOT_MULTI_TARGETS = YES GENERATE_LEGEND = YES DOT_CLEANUP = YES nsnake-1.5/src/0000775000175000017500000000000012135565363012136 5ustar kurekurensnake-1.5/src/arguments.h0000644000175000017500000000402012135565363014306 0ustar kurekure/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\ * nSnake - The classic snake game with ncurses. * * Copyright (C) 2011-2012 Alexandre Dantas (kure) * * * * This file is part of nSnake. * * * * nSnake is free software: you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation, either version 3 of the License, or * * any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program. If not, see . * * * * homepage: http://sourceforge.net/projects/nsnake/ * * * \* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /** @file arguments.h * * Defines the procedures related to handling the command-line arguments. */ #ifndef ARGUMENTS_H_DEFINED #define ARGUMENTS_H_DEFINED void args_handle (int argc, char* argv[]); void print_help (); void print_license (); void print_usage (); void print_version (); #endif nsnake-1.5/src/nsnake.c0000664000175000017500000000524212135565363013564 0ustar kurekure/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\ * nSnake - The classic snake game with ncurses. * * Copyright (C) 2011-2012 Alexandre Dantas (kure) * * * * This file is part of nSnake. * * * * nSnake is free software: you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation, either version 3 of the License, or * * any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program. If not, see . * * * * homepage: http://sourceforge.net/projects/nsnake/ * * * \* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /** @file nsnake.c * * The core functions of the game - except for the main. */ #include #include #include #include "nsnake.h" #include "engine.h" #include "fruit.h" #include "player.h" #include "hscores.h" struct game_t game; /** Aborts the game and displays the error message * * @note EXIT_FAILURE is a portable constant for indicating * failure upon exiting a program. */ void nsnake_abort (char* error_msg) { engine_exit (); printf ("%s", error_msg); exit (EXIT_FAILURE); } /** Interrupts the game and quits to the terminal. * * @note EXIT_SUCCESS is a portable constant for indicating * success upon exiting a program. */ void nsnake_exit () { if (snake.body != NULL) { free (snake.body); snake.body = NULL; } if (game.cant_open_hscore_file == 1) printf ("* Couldn't open Highscore file (%s)!\n" "Make sure the game is installed. " "Please see 'man nsnake' for bug reports\n", SCORE_PATH); exit (EXIT_SUCCESS); } /** Starts all the necessairy stuff. * * Sets all the global variables and call the initial functions so the * game may start. * @see hscore_init() * @see player_init() * @see fruit_init() * @see engine_show_screen() */ void nsnake_init () { player_init(); fruit_init(); hscore_init(); engine_show_screen(); } /** It, umm, pauses the game, i guess */ void nsnake_pause () { engine_show_pause (); } /*------------------------------END-------------------------------------------*/ nsnake-1.5/src/engine.h0000644000175000017500000000557412135565363013565 0ustar kurekure/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\ * nSnake - The classic snake game with ncurses. * * Copyright (C) 2011-2012 Alexandre Dantas (kure) * * * * This file is part of nSnake. * * * * nSnake is free software: you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation, either version 3 of the License, or * * any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program. If not, see . * * * * homepage: http://sourceforge.net/projects/nsnake/ * * * \* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /** @file engine.h * * Declaration of the graphical engine functions, defines and globals */ #ifndef ENGINE_DEFINED #define ENGINE_DEFINED /** Let's use the game engine, depending on the OS */ #define OS_IS_WINDOWS ((defined __WIN32__) && (!defined __CYGWIN__)) #if OS_IS_WINDOWS // Ugh... windows... #include #else // Yay! Anything else! #include #endif /** Global definitions related to the game screen */ struct screen_t { int width; /**< The fixed width of the game area */ int height; /**< The fixed height of the game area */ int delay; /**< The time (in microsseconds) that the game */ }; /** Global screen structure */ extern struct screen_t screen; void draw_background (); void draw_borders (); void draw_fruit (); void draw_fruit_bonus (); void draw_player (); void draw_score (); void engine_exit (); void engine_init (); void engine_show_game_over (); void engine_show_main_menu (); void engine_show_pause (); void engine_show_screen (); int get_main_menu_input (int* current_option); int engine_get_game_input (); void engine_clean_game_over (); void engine_clean_pause (); void start_atrribute (int attr); #endif nsnake-1.5/src/fruit.c0000644000175000017500000000563712135565363013444 0ustar kurekure/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\ * nSnake - The classic snake game with ncurses. * * Copyright (C) 2011-2012 Alexandre Dantas (kure) * * * * This file is part of nSnake. * * * * nSnake is free software: you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation, either version 3 of the License, or * * any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program. If not, see . * * * * homepage: http://sourceforge.net/projects/nsnake/ * * * \* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /** @file fruit.c * * Definition of the fruit functions */ #include #include #include "fruit.h" #include "engine.h" #include "player.h" struct fruit_t fruit; /** Creates a fruit in a random place * * @note It doesn't verify if there is another fruit on the game */ void fruit_init () { int top = 50; int bottom = 10; int valid_fruit = FALSE; // Create a seed for generating random numbers based on the time srand (time (NULL)); while (valid_fruit == FALSE) { // Generate a random number between the screen limits fruit.x = rand() % ((screen.width-2) - 1 + 1) + 1; fruit.y = rand() % ((screen.height-2) - 2 + 2) + 2; // Generates a random value between 'top' and 'bottom' fruit.bonus += rand() % (top - bottom + 1) + bottom; if (fruit.y != screen.height-1) valid_fruit = TRUE; // Lets make sure the fruit doesnt start at the snake body int i; for (i = 0; i < (snake.size-1); i++) { if ((fruit.x == snake.body[i].x) && (fruit.y == snake.body[i].y)) { valid_fruit = FALSE; break; } } } } /** Drops the bonus value of the fruit for each 'frame' */ void fruit_update_bonus () { if (fruit.bonus > 0) fruit.bonus--; } nsnake-1.5/src/nsnake.h0000664000175000017500000000476412135565363013601 0ustar kurekure/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\ * nSnake - The classic snake game with ncurses. * * Copyright (C) 2011-2012 Alexandre Dantas (kure) * * * * This file is part of nSnake. * * * * nSnake is free software: you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation, either version 3 of the License, or * * any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program. If not, see . * * * * homepage: http://sourceforge.net/projects/nsnake/ * * * \* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /** @file nsnake.h * * This file defines the core functions, variables and structures. */ #ifndef NSNAKE_DEFINED #define NSNAKE_DEFINED #ifndef TRUE /** Boolean type TRUE - this will make things easier to read */ #define TRUE 1 #endif #ifndef FALSE /** Boolean type FALSE - this will make things easier to read */ #define FALSE 0 #endif typedef enum { MAIN_MENU, GAME_INIT, GAME, PAUSED, GAME_OVER, EXIT } states; /** The possible Game Modes. * * In Normal Mode, the snake dies by colliding with itself or the borders. @n * In Teleport Mode, the snake only dies by colliding with itself. @n * @note Free Mode is for testing purposes only. */ typedef enum { FREE_MODE, BORDERS_ON, BORDERS_OFF } modes; /** Global definitions related to the game in general. */ struct game_t { modes mode; /**< The collision mode of the game */ int level; /**< How fast will the snake move */ states state; /**< The current game state */ int cant_open_hscore_file; /**< Flag that tells if we could open the highscores file */ }; /** The global game structure */ extern struct game_t game; /** Full absolute path to the highscore file */ extern char SCORE_PATH[255]; void nsnake_abort (char* error_msg); void nsnake_exit (); void nsnake_game_over (); void nsnake_init (); void nsnake_pause (); #endif nsnake-1.5/src/fruit.h0000644000175000017500000000454312135565363013444 0ustar kurekure/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\ * nSnake - The classic snake game with ncurses. * * Copyright (C) 2011-2012 Alexandre Dantas (kure) * * * * This file is part of nSnake. * * * * nSnake is free software: you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation, either version 3 of the License, or * * any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program. If not, see . * * * * homepage: http://sourceforge.net/projects/nsnake/ * * * \* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /** @file fruit.h * * Declaration of the fruit functions, defines and globals */ #ifndef FRUIT_DEFINED #define FRUIT_DEFINED /** The fruit structure. * * Each fruit has it x and y positions * and a bonus score - indicating how many extra points * will be rewarded to the snake when it eats the fruit. */ struct fruit_t { int x; /**< x position of the fruit on stage */ int y; /**< y position of the fruit on stage */ int bonus; /**< Bonus that the fruit adds to the score when eaten */ }; /** One global copy of the fruit */ extern struct fruit_t fruit; void fruit_init (); void fruit_update_bonus (); #endif nsnake-1.5/src/engine.c0000664000175000017500000003557112135565363013562 0ustar kurekure/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\ * nSnake - The classic snake game with ncurses. * * Copyright (C) 2011-2012 Alexandre Dantas (kure) * * * * This file is part of nSnake. * * * * nSnake is free software: you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation, either version 3 of the License, or * * any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program. If not, see . * * * * homepage: http://sourceforge.net/projects/nsnake/ * * * \* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /** @file engine.c * * Definition of the graphical engine functions * * This file presents the nCurses specifical implementation of the game`s * graphics. */ #include #include #include // for the usleep () function #include "engine.h" #include "fruit.h" #include "player.h" #include "hscores.h" #if (defined __WIN32__) && (!defined __CYGWIN__) // In Windows, the console has fixed width #define FIXED_WIDTH 80 #define FIXED_HEIGHT 25 #else // Now here we don't have to worry about that #define FIXED_WIDTH 80 #define FIXED_HEIGHT 24 #endif /** This formula determines a time (in microseconds) the game must wait * between each screen refresh. It is based on the current game level, * so the higher its value, the lowest is the delay and faster the game * will appear to be. * * @note 1,000,000 microseconds == 1 second */ #define REFRESH_DELAY (20000 + ((9 - game.level) * 25000)) static char PLAYER_HEAD_CHAR = '@'; ///< The 'image' of the snake head static char PLAYER_CHAR = 'o'; ///< The 'image' of the snake body static char FRUIT_CHAR = '$'; ///< The 'image' of the fruit static char BORDER_CHAR = '#'; ///< The 'image' of the border in normal mode static char NO_BORDER_CHAR = '.'; ///< The 'image' of the border in teleport mode static char MENU_BORDER_CHAR = '*'; ///< The 'image' of the border in the main menu /** Simple enum to make the colors easier to read: FOREGROUND_BACKGROUND */ enum Colors { BLACK_WHITE = 1, CYAN_BLACK, BLUE_BLACK, WHITE_BLACK, GREEN_BLACK, RED_BLACK, }; struct screen_t screen; /** Just erases everything to black */ void draw_background () { /* clear(); */ erase(); } /** Draws the window border, according to the game.mode. */ void draw_borders () { int i; start_atrribute (COLOR_PAIR (WHITE_BLACK)); if (game.mode == BORDERS_ON) { for (i = 0; i <= (screen.width-1); i++) //upper { mvaddch (1, i, BORDER_CHAR); mvaddch ((screen.height-1), i, BORDER_CHAR); } for (i = 1; i <= (screen.height-1); i++) //lower { mvaddch (i, 0, BORDER_CHAR); mvaddch (i, (screen.width-1), BORDER_CHAR); } } else if (game.mode == BORDERS_OFF) { for (i = 0; i <= (screen.width-1); i++) { mvaddch (1, i, NO_BORDER_CHAR); mvaddch ((screen.height-1), i, NO_BORDER_CHAR); } for (i = 1; i <= (screen.height-1); i++) { mvaddch (i, 0, NO_BORDER_CHAR); mvaddch (i, (screen.width-1), NO_BORDER_CHAR); } } } /** Draws the current fruit on screen */ void draw_fruit () { start_atrribute (COLOR_PAIR (CYAN_BLACK)); mvaddch (fruit.y, fruit.x, FRUIT_CHAR); } /** Draws the bonus value of the current fruit */ void draw_fruit_bonus () { start_atrribute (COLOR_PAIR (WHITE_BLACK)); mvprintw (0, (screen.width-1)/2, "Bonus: %d", fruit.bonus); } /** Draws the snake - from the head to the whole body */ void draw_player () { start_atrribute (COLOR_PAIR (GREEN_BLACK)); mvaddch (snake.body[0].y, snake.body[0].x, PLAYER_HEAD_CHAR); int i; for (i = 1; i < snake.size; i++) mvaddch (snake.body[i].y, snake.body[i].x, PLAYER_CHAR); } /** Prints the current score */ void draw_score () { start_atrribute (COLOR_PAIR (CYAN_BLACK)); mvprintw (0, 0, "nSnake v"); mvprintw (0, 9, VERSION); start_atrribute (COLOR_PAIR (WHITE_BLACK)); mvprintw (0, 17, "Lv%d", game.level); mvprintw (0, 23, "Score: %d", snake.score); if (game.mode == BORDERS_ON) mvprintw (0, 60, "High Score: %d", HIGH_SCORE_BORDERS); else if (game.mode == BORDERS_OFF) mvprintw (0, 60, "High Score: %d", HIGH_SCORE_BORDERS_OFF); } /** Exits and dealocates the memory required by ncurses. */ void engine_exit () { /* clear (); */ erase(); refresh (); // Effectively ends ncurses mode endwin (); } /** Get the user input during game and make the right decisions */ int engine_get_game_input () { // The input variable MUST be int to accept non-ascii characters return getch (); } /** Starts the game engine. Initializes all the stuff related to ncurses. * * @note If some engine-specific initialization fails, the game aborts. */ void engine_init () { screen.width = FIXED_WIDTH; screen.height = FIXED_HEIGHT; initscr (); // Starts the ncurses mode if (has_colors () == TRUE) { int bg_color; start_color (); // Start color support // Let's try grabbing the current terminal background color if (use_default_colors () == ERR) bg_color = COLOR_BLACK; else bg_color = -1; // Start support for colors (Name, Foreground, Background) init_pair (GREEN_BLACK, COLOR_GREEN, bg_color); init_pair (CYAN_BLACK, COLOR_CYAN, bg_color); init_pair (WHITE_BLACK, COLOR_WHITE, bg_color); init_pair (RED_BLACK, COLOR_RED, bg_color); init_pair (BLUE_BLACK, COLOR_BLUE, bg_color); init_pair (BLACK_WHITE, COLOR_BLACK, bg_color); } int current_height, current_width; // Gets the current width and height of the terminal getmaxyx (stdscr, current_height, current_width); if ((current_width < screen.width) || (current_height < screen.height)) nsnake_abort ("Your console screen is smaller than 80x24\n" "Please resize your window and try again\n\n"); raw (); // Character input doesnt require the key anymore curs_set (0); // Makes the blinking cursor invisible noecho (); // Wont print the keys received through input nodelay (stdscr, TRUE); // Wont wait for input - the game will run instantaneously keypad (stdscr, TRUE); // Support for extra keys (life F1, F2, ... ) refresh (); // Refresh the screen (prints whats in the screen buffer) /// @todo There must have a game init function or something /// where i could put this game.mode = BORDERS_ON; } /** Draws the Game Over screen. * * Besides drawing 'Game Over', it highlights where the player died. */ void engine_show_game_over () { int game_over_logo_height = 16; char* game_over_logo[] = { " _______ _______ __ __ _______ ", "| || _ || |_| || |", "| ___|| |_| || || ___|", "| | __ | || || |___ ", "| || || || || ___|", "| |_| || _ || ||_|| || |___ ", "|_______||__| |__||_| |_||_______|", " _______ __ __ _______ ______ ", "| || | | || || _ | ", "| _ || |_| || ___|| | || ", "| | | || || |___ | |_|| ", "| |_| || || ___|| __ |", "| | | | | |___ | | ||", "|_______| |___| |_______||___| ||", #if (defined __WIN32__) && (!defined __CYGWIN__) " Press to retry", #else " Press to retry", #endif " to Main Menu" }; int i; start_atrribute (COLOR_PAIR (RED_BLACK)); mvaddch (snake.body[0].y, snake.body[0].x, 'x'); for (i = 0; i < game_over_logo_height; i++) mvaddstr (3 + i, 22, game_over_logo[i]); draw_score (); refresh (); nodelay (stdscr, FALSE); } void engine_clean_game_over () { nodelay (stdscr, TRUE); } /** Displays the main menu and gets the user input from it. * * This function blocks the game execution and waits for user input, * refreshing the main menu screen according to the options selected. */ void engine_show_main_menu () { int speed_cur_option = 1; char speed_cur_options[9] = {'1', '2', '3', '4', '5', '6', '7', '8', '9'}; int menu_row_pos = 13; int option_row_pos = menu_row_pos + 17; int wait = TRUE; int i; int j; clear (); while (wait == TRUE) { // The borders start_atrribute (COLOR_PAIR (WHITE_BLACK)); for (i = 0; i < screen.width; i++) { mvaddch (0, i, MENU_BORDER_CHAR); mvaddch (screen.height - 1, i, MENU_BORDER_CHAR); } for (i = 0; i < screen.height; i++) { mvaddch (i, 0, MENU_BORDER_CHAR); mvaddch (i, screen.width - 1, MENU_BORDER_CHAR); } start_atrribute (COLOR_PAIR (GREEN_BLACK)); mvprintw(1, 3, " ,d8888b. 888"); mvprintw(2, 3, " d88P Y88b 888"); mvprintw(3, 3, " Y88b. 888"); mvprintw(4, 3, "88888b. Y888b. 88888b. 8888b. 888 888 .d88b."); mvprintw(5, 3, "888 88b 8Y88b. 888 88b 88b 888 .88P d8P Y8b"); mvprintw(6, 3, "888 888 888b 888 888 .d888888 888888K 88888888"); mvprintw(7, 3, "888 888 Y88b d88P 888 888 888 888 888 88b Y8b."); mvprintw(8, 3, "888 888 Y8888P 888 888 Y888888 888 888 Y88888"); start_atrribute (COLOR_PAIR (CYAN_BLACK)); mvaddch (8, 59, 'v'); mvprintw (8, 60, VERSION); start_atrribute (COLOR_PAIR (BLUE_BLACK)); mvprintw (10, 5, " ___________________________________________________ "); mvprintw (11, 5, "| |"); mvprintw (12, 5, "| |"); mvprintw (13, 5, "| |"); mvprintw (14, 5, "| |"); mvprintw (15, 5, "| |"); mvprintw (16, 5, "| |"); mvprintw (17, 5, "| |"); mvprintw (18, 5, "| |"); mvprintw (19, 5, "|___________________________________________________|"); #if (defined __WIN32__) && (!defined __CYGWIN__) mvprintw (12, menu_row_pos, "Press to start game"); #else mvprintw (12, menu_row_pos, "Press or to start game"); #endif mvprintw (13, menu_row_pos, "Press to quit game"); // Here we draw the game mode mvprintw (15, menu_row_pos, "Game Mode:"); if (game.mode == BORDERS_ON) { start_atrribute (COLOR_PAIR (WHITE_BLACK)); mvprintw (15, option_row_pos, "Borders On"); start_atrribute (COLOR_PAIR (BLUE_BLACK)); mvprintw (16, option_row_pos, "Borders Off"); } else { start_atrribute (COLOR_PAIR (BLUE_BLACK)); mvprintw (15, option_row_pos, "Borders On"); start_atrribute (COLOR_PAIR (WHITE_BLACK)); mvprintw (16, option_row_pos, "Borders Off"); } // And here we draw the level numbers start_atrribute (COLOR_PAIR (BLUE_BLACK)); mvprintw (18, menu_row_pos, "Starting speed:"); // Tricky, draw the options with the right colors for (i = 0, j = 0; i < 9; i++) { if (i == (speed_cur_option-1)) start_atrribute (COLOR_PAIR (WHITE_BLACK)); else start_atrribute (COLOR_PAIR (BLUE_BLACK)); mvprintw (18, option_row_pos+j, "%c", speed_cur_options [i]); j += 2; } start_atrribute (COLOR_PAIR (WHITE_BLACK)); mvprintw (screen.height-2, 2, "Use --help for guidelines"); // Now we wait for orders wait = get_main_menu_input (&speed_cur_option); // This function is so refreshing... refresh (); } game.level = speed_cur_option; } /** Prints the pause message */ void engine_show_pause () { curs_set (1); // Makes the cursor visible nodelay (stdscr, FALSE); // We'll wait for input again start_atrribute (COLOR_PAIR (RED_BLACK)); mvprintw ((screen.height-1)/2, ((screen.width-1)/2)-5, "Game Paused "); mvprintw (((screen.height-1)/2)+1, ((screen.width-1)/2)-11, "Press

to Continue..."); } /** Completely draws the screen during game. * * The usleep() function interrupts the program for 'n' microseconds. * It was difficult to get a stable value for the game progression. * * @note This is the main function of this file because it shows * logically how the process of drawing the screen sould be */ void engine_show_screen () { draw_background (); draw_borders (); draw_fruit (); draw_player (); draw_fruit_bonus(); draw_score (); usleep (REFRESH_DELAY); refresh(); } /** Waits for an user action during the 'Game Over' screen */ void get_game_over_input () { int wait = TRUE; nodelay (stdscr, FALSE); while (wait == TRUE) { int input = getch(); switch (input) { case 'q': case 'Q': engine_exit (); nsnake_exit (); break; case 'm': case 'M': wait = FALSE; engine_show_main_menu (); #if (defined __WIN32__) && (!defined __CYGWIN__) case ' ': #else case '\n': #endif wait = FALSE; break; default: break; } } nodelay (stdscr, TRUE); } /** Gets the input for the main menu. */ int get_main_menu_input (int* speed_cur_option) { nodelay (stdscr, FALSE); int input = getch(); switch (input) { case '\n': case ' ': nodelay (stdscr, TRUE); return FALSE; break; case 'q': case 'Q': engine_exit(); nsnake_exit(); break; case KEY_UP: if (game.mode == BORDERS_OFF) game.mode = BORDERS_ON; break; case KEY_DOWN: if (game.mode == BORDERS_ON) game.mode = BORDERS_OFF; break; case KEY_LEFT: if (*speed_cur_option > 1) (*speed_cur_option)--; break; case KEY_RIGHT: if (*speed_cur_option < 9) (*speed_cur_option)++; break; case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': *speed_cur_option = (input - '0'); // ASCII table value break; default: break; } return TRUE; } /** Cleans the pause menu effects */ void engine_clean_pause () { nodelay (stdscr, TRUE); // We'll no longer wait for input curs_set (0); // And here it becomes invisible again } /** Wrapper to the attron() function, in case the current terminal * doesn't support colors. */ void start_atrribute (int attr) { if (has_colors () == TRUE) { attron (attr); } } nsnake-1.5/src/player.h0000644000175000017500000000631712135565363013610 0ustar kurekure/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\ * nSnake - The classic snake game with ncurses. * * Copyright (C) 2011-2012 Alexandre Dantas (kure) * * * * This file is part of nSnake. * * * * nSnake is free software: you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation, either version 3 of the License, or * * any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program. If not, see . * * * * homepage: http://sourceforge.net/projects/nsnake/ * * * \* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /** @file player.h * * Declaration of the player functions, defines and globals */ #ifndef PLAYER_DEFINED #define PLAYER_DEFINED #include "nsnake.h" /** The structure of each part of the player. */ struct player_pieces { int x; /**< x position of this part */ int y; /**< y position of this part */ }; /** Simple enum to make the directions of the player easier to read. */ enum directions { UP = 0, LEFT, DOWN, RIGHT }; /** Represent the snake itself. * * @todo Currently the snake have no physical limit. Must implement one. * Maybe something like if the snake occupies the whole screen, a pop-up * says 'congratulations' or the size resets but not the score... */ struct player_t { int is_alive; /**< Indicates if the player is alive */ int speed; /**< How many chars will the player move by frame */ int size; /**< Current size of the snake's body */ int score; /**< The player's score :D */ int direction; /**< Which direction shoud the player go */ struct player_pieces* body; /**< All pieces of the snake (including the head) */ }; /** Global player structure */ extern struct player_t snake; void player_change_direction (int new_direction); int player_collided_with_borders (); void player_exit (); int player_hit_borders (); int player_hit_fruit (); int player_hit_self (); void player_increase_score (int add); void player_increase_size (int size); void player_init (); void player_teleport_borders (); void player_update (); #endif nsnake-1.5/src/hscores.c0000644000175000017500000001625312135565363013755 0ustar kurekure/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\ * nSnake - The classic snake game with ncurses. * * Copyright (C) 2011-2012 Alexandre Dantas (kure) * * * * This file is part of nSnake. * * * * nSnake is free software: you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation, either version 3 of the License, or * * any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program. If not, see . * * * * homepage: http://sourceforge.net/projects/nsnake/ * * * \* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /** @file hscores.c * * Definition of the functions related to high scores. */ // We get one define from the Makefile: // SCORE_FILE -> Filename of the high score file // // They can be changed by the user there, but the defaul is // SCORE_FILE -> high-scores.bin // If we're on Windows, there's no /var/games! // So we create the file on the same directory as the .exe #if (defined __WIN32__) && (!defined __CYGWIN__) #undef SCORE_FILE #define SCORE_FILE "hscores.bin" #endif #include #include #include #include /* mkdir(), stat() */ #include /* mkdir(), stat() */ #include /* errno */ #include "hscores.h" #include "player.h" /** The Default HighScore */ int HIGH_SCORE_DEFAULT = 500; /** The separate Highscore for the game mode with borders */ int HIGH_SCORE_BORDERS; /** The separate Highscore for the game mode without borders */ int HIGH_SCORE_BORDERS_OFF; /** The directory where we'll keep the highscore file */ char SCORE_DIR[255]; /** Full absolute path to the highscore file */ char SCORE_PATH[255]; /** Initializes all global variables needed for high scores. * @note Can be called multiple times, won't overwrite things. */ int hscore_globals_init() { static int initialized = 0; if (initialized) return -1; initialized = 1; game.cant_open_hscore_file = 0; memset(SCORE_DIR, '\0', 255); memset(SCORE_PATH, '\0', 255); if (getenv("HOME") == NULL) { strncpy(SCORE_DIR, "/dev", 254); strncpy(SCORE_PATH, "/dev/null", 254); game.cant_open_hscore_file = 1; return -1; } strncpy(SCORE_DIR, getenv("HOME"), 254); strncat(SCORE_DIR, "/.nsnake", 254); strncpy(SCORE_PATH, SCORE_DIR, 254); strncat(SCORE_PATH, "/", 1); strncat(SCORE_PATH, SCORE_FILE, 254); return 0; } /** Local function that tests if the directory #path exists. * @note Must be a null-terminated absolute path. * @return 1 if directory exists, 0 if it doesn't. */ int directory_exists(char* path) { struct stat s; int err = stat(path, &s); if (err == -1) { if (errno == ENOENT) /* doesn't exist */ return 0; } // else // { // if (S_ISDIR(s.st_mode)) // // exists and it's a directory // else // // exists but it's not a directory // } return 1; } /** Creates a directory on #path. * @return -1 on error, 0 on success. * @note Creates with permissions 755. */ int create_directory(char* path) { return mkdir(path, S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH); } /** Check if a file exists. * @return 0 if doesnt exist, 1 if exists */ int file_exists(char* path) { struct stat s; int err = stat(path, &s); if (err == -1) { if (errno == ENOENT) /* doesn't exist */ return 0; } else { // exists and it's not a directory if (!(S_ISDIR(s.st_mode))) return 1; } // it's a directory, WHAT return 1; } /** Creates a file. * @return 1 if successful, 0 if failed */ int create_file(char* path) { FILE* file = fopen(path, "wb"); if (!file) return 0; fclose(file); return 1; } /** Tells if the high score file is accessible. * @return 0 if success, 1 if failed. */ int hscore_file_check() { if (directory_exists(SCORE_DIR) == 1 && file_exists(SCORE_PATH) == 1) return 0; /* Try to create the directory */ int retval = create_directory(SCORE_DIR); if (retval == -1) return 1; /* Try to create the file */ retval = create_file(SCORE_PATH); if (retval == 0) return 1; retval = hscore_clean(); if (retval == -1) { game.cant_open_hscore_file = 1; return 0; } /* And now, after creating them both... */ if (directory_exists(SCORE_DIR) == 1 && file_exists(SCORE_PATH) == 1) return 0; return 1; } /** Restore the Highscores to the default. * @note Returns -1 if the highscore file doesn't exist. */ int hscore_clean() { hscore_globals_init(); HIGH_SCORE_BORDERS = HIGH_SCORE_DEFAULT; HIGH_SCORE_BORDERS_OFF = HIGH_SCORE_DEFAULT; FILE* file = fopen(SCORE_PATH, "wb"); if (!file) return -1; fwrite(&HIGH_SCORE_BORDERS , sizeof(int), 1, file); fwrite(&HIGH_SCORE_BORDERS_OFF, sizeof(int), 1, file); fclose(file); return 0; } /** Creates/reads from the High Score file * * First, we try to open for reading. If it doesn't exist, then we * open it for writing, effectively creating it. * * @note The path to the score file is defined by the Makefile. * Currently, it is /var/games/.nsnake.scores * @todo clean this code. Lots of useless ifs and elses. */ void hscore_init () { hscore_globals_init(); int retval = hscore_file_check(); if (retval == 1) { game.cant_open_hscore_file = 1; return; } FILE* file = fopen (SCORE_PATH, "rb"); if (!file) { retval = hscore_clean(); if (retval == -1) { game.cant_open_hscore_file = 1; return; } file = fopen (SCORE_PATH, "rb"); if (!file) /* This time it really couldnt open the score file */ { game.cant_open_hscore_file = 1; return; } } /* All right, opened the file! */ int items_read = fread(&HIGH_SCORE_BORDERS, sizeof (int), 1, file); if (items_read != 1) nsnake_abort("Highscore File I/O error!\n" "Try cleaning the scores file!"); items_read = fread(&HIGH_SCORE_BORDERS_OFF, sizeof (int), 1, file); if (items_read != 1) nsnake_abort("Highscore File I/O error!\n" "Try cleaning the scores file!"); fclose(file); } /** Records the player High Score */ void hscore_store () { game.cant_open_hscore_file = 0; int retval = hscore_file_check(); if (retval == 1) { retval = hscore_clean(); if (retval == -1) { game.cant_open_hscore_file = 1; return; } } FILE* file = fopen (SCORE_PATH, "r+b"); if (!file)// We really couldn't open the high scores file { game.cant_open_hscore_file = 1; return; } if (game.mode == BORDERS_ON) { HIGH_SCORE_BORDERS = snake.score; fwrite (&HIGH_SCORE_BORDERS, sizeof (int), 1, file); } else if (game.mode == BORDERS_OFF) { HIGH_SCORE_BORDERS_OFF = snake.score; fseek (file, sizeof (int), SEEK_SET); fwrite (&HIGH_SCORE_BORDERS_OFF, sizeof (int), 1, file); } else { // oh my god, what should i do? } fclose (file); } nsnake-1.5/src/player.c0000644000175000017500000001427312135565363013603 0ustar kurekure/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\ * nSnake - The classic snake game with ncurses. * * Copyright (C) 2011-2012 Alexandre Dantas (kure) * * * * This file is part of nSnake. * * * * nSnake is free software: you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation, either version 3 of the License, or * * any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program. If not, see . * * * * homepage: http://sourceforge.net/projects/nsnake/ * * * \* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /** @file player.c * * Definition of the player functions */ #include #include "nsnake.h" #include "engine.h" #include "player.h" #include "fruit.h" struct player_t snake; /** Changes the snake direction based on the input received */ void player_change_direction (int new_direction) { if ((new_direction == UP) && (snake.direction != DOWN) && (snake.direction != UP) ) snake.direction = UP; else if ((new_direction == LEFT) && (snake.direction != RIGHT) && (snake.direction != LEFT) ) snake.direction = LEFT; else if ((new_direction == DOWN) && (snake.direction != UP) && (snake.direction != DOWN) ) snake.direction = DOWN; else if ((new_direction == RIGHT) && (snake.direction != LEFT) && (snake.direction != RIGHT) ) snake.direction = RIGHT; } /** Depending on the game mode, the player may be able to hit borders * or not. If it is possible, we call player_hit_borders(). * * @see player_hit_borders() * @return FALSE, if the player didn't hit the borders, and * TRUE if it did. */ int player_collided_with_borders () { if (game.mode == BORDERS_ON) return player_hit_borders (); else if (game.mode == BORDERS_OFF) player_teleport_borders (); else if (game.mode == FREE_MODE) //secret debugging-mode {} return FALSE; } /** Free all memory associated with the player. */ void player_exit () { if (snake.body != NULL) { free (snake.body); snake.body = NULL; } } /** Checks collision between the snake and the walls. * * @warning Behind you! */ int player_hit_borders () { if ((snake.body[0].x < 1) || (snake.body[0].x > (screen.width-2)) || (snake.body[0].y < 2) || (snake.body[0].y > (screen.height-2))) { return TRUE; } return FALSE; } /** Checks if the snake has eaten the fruit. * * @return 1 if yes, 0 if no. */ int player_hit_fruit () { if ((snake.body[0].x == fruit.x) && (snake.body[0].y == fruit.y)) return TRUE; else return FALSE; } /** Checks if the snake have collided with itself */ int player_hit_self () { int i; for (i = (snake.size-1); i > 1; i--) { if ((snake.body[0].x == snake.body[i].x) && (snake.body[0].y == snake.body[i].y)) { return TRUE; } } return FALSE; } /** Simply increases the score by the value sent as the parameter. */ void player_increase_score (int add) { snake.score += add; } /** Increases the snake size. * * Here we have the core function of this file. Each time the snake * increases its size, we expand the array that represents its body. * * @note This is the main function of this file, because it shows * how i've implemented the snake. In the future, we could * use a linked list instead of an array. */ void player_increase_size (int size) { int piece_size = sizeof (struct player_pieces); snake.size += size; snake.body = realloc (snake.body, (snake.size * piece_size)); if (snake.body == NULL) nsnake_abort ("Memory Error!\n"); } /** Starts the player-related variables. */ void player_init () { snake.body = NULL; snake.is_alive = TRUE; snake.speed = 1; snake.score = 0; snake.direction = RIGHT; snake.size = 3; snake.body = malloc (snake.size * sizeof (struct player_pieces)); if (snake.body == NULL) nsnake_abort ("Memory Error!\n"); int i; for (i = 0; i < snake.size; i++) { snake.body[i].x = screen.width/2; snake.body[i].y = screen.height/2; } } /** Teleports the player around the borders. */ void player_teleport_borders () { if (snake.body[0].x < 1) snake.body[0].x = screen.width-2; if (snake.body[0].y < 2) snake.body[0].y = screen.height-2; if (snake.body[0].x > (screen.width-2)) snake.body[0].x = 1; if (snake.body[0].y > (screen.height-2)) snake.body[0].y = 2; } /** Updates the player position, one piece at a time * * Start by moving the snake pieces one at a time from the last to the * first, and then moves the head according to its direction. */ void player_update () { // body int i; for (i = (snake.size-1); i > 0; i--) { snake.body[i].x = snake.body[i-1].x; snake.body[i].y = snake.body[i-1].y; } // head if (snake.direction == UP) snake.body[0].y -= snake.speed; else if (snake.direction == LEFT) snake.body[0].x -= snake.speed; else if (snake.direction == DOWN) snake.body[0].y += snake.speed; else if (snake.direction == RIGHT) snake.body[0].x += snake.speed; } nsnake-1.5/src/main.c0000664000175000017500000001206012135565363013225 0ustar kurekure/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\ * nSnake - The classic snake game with ncurses. * * Copyright (C) 2011-2012 Alexandre Dantas (kure) * * * * This file is part of nSnake. * * * * nSnake is free software: you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation, either version 3 of the License, or * * any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program. If not, see . * * * * homepage: http://sourceforge.net/projects/nsnake/ * * * \* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /** @file main.c * * The 'main' function only */ #include "engine.h" #include "fruit.h" #include "nsnake.h" #include "player.h" #include "arguments.h" #include "hscores.h" /** The main function - contains the main loop of the game. * * * @note I tried to make this function as clear as possible, so anyone * could understaing the whole game logic starting by here. @n * Have fun with the source code! */ int main (int argc, char* argv[]) { int c = 0; int wait = FALSE; if (argc > 1) args_handle (argc, argv); engine_init (); game.state = MAIN_MENU; while (TRUE == TRUE) { switch (game.state) { case MAIN_MENU: engine_show_main_menu (); game.state = GAME_INIT; break; case GAME_INIT: nsnake_init (); game.state = GAME; break; case GAME: if (snake.is_alive == FALSE) { game.state = GAME_OVER; break; } switch (c = engine_get_game_input ()) { case ERR: // If we get no input break; case KEY_UP: case 'w': case 'W': player_change_direction (UP); break; case KEY_LEFT: case 'a': case 'A': player_change_direction (LEFT); break; case KEY_DOWN: case 's': case 'S': player_change_direction (DOWN); break; case KEY_RIGHT: case 'd': case 'D': player_change_direction (RIGHT); break; case 'q': case 'Q': game.state = EXIT; break; #ifdef DEBUG //debug key to increase score and size (gcc -DDEBUG) case 'e': case 'E': player_increase_score (100); player_increase_size (2); break; #endif case 'p': case 'P': game.state = PAUSED; break; default: break; } player_update (); fruit_update_bonus (); if (player_hit_fruit () == TRUE) { // Is this score arbitrary? player_increase_score (game.level*3 + fruit.bonus); player_increase_size (2); fruit_init (); } if (player_hit_self () == TRUE) snake.is_alive = FALSE; if (player_collided_with_borders () == TRUE) snake.is_alive = FALSE; engine_show_screen (); break; case PAUSED: engine_show_pause (); wait = TRUE; while (wait == TRUE) { int input = engine_get_game_input (); switch (input) { case 'p': case 'P': wait = FALSE; game.state = GAME; break; case 'q': case 'Q': wait = FALSE; game.state = EXIT; break; default: break; } engine_clean_pause (); } break; case GAME_OVER: if (game.mode == BORDERS_ON) { if (snake.score > HIGH_SCORE_BORDERS) hscore_store (); } else if (game.mode == BORDERS_OFF) { if (snake.score > HIGH_SCORE_BORDERS_OFF) hscore_store (); } engine_show_game_over (); wait = TRUE; while (wait == TRUE) { switch (c = engine_get_game_input()) { case 'q': case 'Q': wait = FALSE; game.state = EXIT; break; case 'm': case 'M': wait = FALSE; game.state = MAIN_MENU; break; #if OS_IS_WINDOWS case ' ': #else case '\n': #endif wait = FALSE; game.state = GAME_INIT; break; default: break; } } engine_clean_game_over(); break; case EXIT: engine_exit (); nsnake_exit (); break; default: break; } } // Even though we have this here, the game always quits during // the main loop engine_exit (); nsnake_exit (); return 0; } nsnake-1.5/src/arguments.c0000644000175000017500000001566412135565363014321 0ustar kurekure/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\ * nSnake - The classic snake game with ncurses. * * Copyright (C) 2011-2012 Alexandre Dantas (kure) * * * * This file is part of nSnake. * * * * nSnake is free software: you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation, either version 3 of the License, or * * any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program. If not, see . * * * * homepage: http://sourceforge.net/projects/nsnake/ * * * \* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /** @file arguments.c * * Defines the procedures related to handling the command-line arguments. * Version 1.0 (31/12/11) */ #include #include #include /* For getopt_long() */ #include "arguments.h" #include "hscores.h" /** Handles all the commandline arguments. * * This is the main function of this module. It processes * an argv[] array of argc elements based on the options * specified at the struct option. * * If you want to add another argument, follow these steps: * # Add an option on the struct option. * # Add the short equivalent (if it exists) on the getopt_long() call. * # Add a case on the switch specifying the action of that option. */ void args_handle (int argc, char* argv[]) { static struct option options[] = { {"help", no_argument, NULL, 'h'}, {"license", no_argument, NULL, 'l'}, {"version", no_argument, NULL, 'v'}, {"reset-scores", no_argument, NULL, 'r'}, /* The last element must be all zeroes */ {0, 0, 0, 0} }; /* The index of the current option */ int option_index; /* The character for comparison */ int c = 0; /* We keep checking the arguments untill they run out (c == -1) */ while (c != -1) { c = getopt_long (argc, argv, "hlvr", options, &option_index); switch (c) { case 'h': print_help (); exit (EXIT_SUCCESS); break; case 'l': print_license (); exit (EXIT_SUCCESS); break; case 'v': print_version (); exit (EXIT_SUCCESS); break; case 'r': // TODO TODO TODO TODO TODO TODO TODO TODO RESET SCORES hscore_clean (); printf ("* HighScores reseted\n"); exit (EXIT_SUCCESS); break; case '?': /* getopt_long() already printed an error message about * unrecognized option */ print_usage (); exit (EXIT_FAILURE); break; case -1: // There were no '-' parameters passed // or all the parameters were processed break; default: print_usage (); exit (EXIT_FAILURE); break; } } /* Just in case the user specified more arguments (not options) * than needed, you decide what to do. Here, we just ignore them */ while (optind < argc) optind++; } /** Prints Help instructions on standard output. */ void print_help () { printf("nSnake Help\n"); printf("\n"); printf("Synopsis:\n"); printf("\tThe classic snake game. You control a snake pursuing\n"); printf("\tASCII-like fruits.\n"); printf("Controls:\n"); printf("\tNumbers (1~9) Changes the game speed at the main menu\n"); printf("\tArrow Keys, WASD Control the snake directions\n"); printf("\tq Quits the game at any time\n"); printf("\tp Pauses/Unpauses the game\n"); printf("Usage:\n"); printf("\tnsnake [-h] [-l] [-v] [-r]\n"); printf("Commandline arguments:\n\n"); printf("\t-h, --help Displays the help guidelines.\n"); printf("\t-l, --license Displays this program's license and warranty.\n"); printf("\t-v, --version Displays the version and general information.\n"); printf("\t-r, --reset-scores Resets all the Highscores to default.\n"); printf("Type 'man nsnake' for more information.\n"); printf("\n"); } /** Prints the preamble of the GNU GPL license v3 on standard output. */ void print_license () { printf("nSnake - The classic snake game with ncurses.\n"); printf("Copyright (C) 2011-2012 Alexandre Dantas (kure)\n"); printf("\n"); printf("nSnake is free software: you can redistribute it and/or modify\n"); printf("it under the terms of the GNU General Public License as published by\n"); printf("the Free Software Foundation, either version 3 of the License, or\n"); printf("any later version.\n"); printf("\n"); printf("This program is distributed in the hope that it will be useful,\n"); printf("but WITHOUT ANY WARRANTY; without even the implied warranty of\n"); printf("MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n"); printf("GNU General Public License for more details.\n"); printf("\n"); printf("You should have received a copy of the GNU General Public License\n"); printf("along with this program. If not, see .\n"); printf("\n"); } /** Prints the program usage on standard output. */ void print_usage () { printf("nSnake v"VERSION" Usage:\n"); printf("\tnsnake [-h] [-l] [-v] [-r]\n"); printf("Commandline arguments:\n\n"); printf("\t-h, --help Displays the help guidelines.\n"); printf("\t-l, --license Displays this program's license and warranty.\n"); printf("\t-v, --version Displays the version and general information.\n"); printf("\t-r, --reset-scores Resets all the Highscores to default.\n"); printf("\n"); } /** Prints the program version on standard output. */ void print_version () { printf("nSnake v"VERSION"\t("DATE")\n"); printf("Copyright (C) 2011-2012 Alexandre Dantas (kure)\n"); printf("\n"); printf("This program comes with ABSOLUTELY NO WARRANTY\n"); printf("for warranty details type 'nsnake --license'.\n"); printf("This is free software, and you are welcome to redistribute it\n"); printf("under certain conditions; type 'nsnake --license' for license details.\n"); printf("\n"); printf("Mailto: alex.dantas92@gmail.com\n"); printf("Homepage: http://sourceforge.net/projects/nsnake\n"); printf("\n"); } nsnake-1.5/src/hscores.h0000644000175000017500000000314512135565363013756 0ustar kurekure/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\ * nSnake - The classic snake game with ncurses. * * Copyright (C) 2011-2012 Alexandre Dantas (kure) * * * * This file is part of nSnake. * * * * nSnake is free software: you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation, either version 3 of the License, or * * any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program. If not, see . * * * * homepage: http://sourceforge.net/projects/nsnake/ * * * \* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /** @file hscores.h * * Declaration of the functions and structures related to high scores. */ #ifndef HSCORES_DEFINED #define HSCORES_DEFINED /** HighScore of the game mode with borders */ extern int HIGH_SCORE_BORDERS; /** HighScore of the game mode without borders */ extern int HIGH_SCORE_BORDERS_OFF; int hscore_file_check(); int hscore_clean(); void hscore_init(); void hscore_store(); #endif nsnake-1.5/obj/0000775000175000017500000000000012135565363012121 5ustar kurekurensnake-1.5/ChangeLog0000644000175000017500000000511412135565363013120 0ustar kurekureXX-XX-XXXX VX.X * nSnake now uses Git for version control. * Changed all the root files (README, INSTALL, ChangeLog...) * Smoothed screen refresh 11-01-2012 V1.5 * Added arguments.c/.h: Now nSnake uses GNU getopt_long! See files for info. * Code changes: The main documentation page has a separate file now. * Code changes: Cleaned a lot the source files and reformatted pretty much everything. * Created manpage! Get help with nSnake will be as easy as 'man nsnake'. * Fixed another Highscore bug: fully functional now. * scores.c/.h now is hscores.c/.h * Now nSnake saves it's high scores in /var/games! And it now runs at setgid root:games. 12-04-2011 V1.3 * Added: arrow keys control over the speed levels at the main menu. * Added: Clean the screen when the user quits the game. * Separated the installation info from README to INSTALL * Fixed: Major memory leaks! * Cleaned the source code: function names now begin with the name of the module in which they are made. * Successfuly documented every function, variable and data structure on the whole source code. Speaking of this, when you type 'make dox', it creates a link to the whole documentation under /doc. * Changed: No mode 'Normal Mode' or 'Teleport mode'. It's now 'Borders On' and 'Borders Off' * Added: Option to return to main menu at the Game Over screen. * Added: Commandline option to display the GPLv3 preamble and Warranty informations. 11-24-2011 v1.0 * Changed the interface. Now the main menu is prettier than ever! Also the teleport mode! * Added speed levels! Now the user can select whitch level will the game start on the main menu * Fixed: Bug that allowed the snake to go offscreen. * Fixed: Bug that allowed a fruit start offscreen. * Fixed: Highscore bug! 11-19-2011 v0.8.5: * Dinamic memory allocation! No more [1000] arrays! * Licensed the software to GNU GPL v3 * Greatly cleaned up the source code. Arranged the functions by name and such. 11-17-2011 v0.8: * Added scores.h and scores.c * Added support to change snake speed * Fixed: Not opening scores.bin doesn't crash the game now. * Cleaned and Documented a lot of the code 11-16-2011 v0.7.8: * Greatly improved the Makefile, added the dist and backup options * Improved the installation process. Now we have support for the standard make targets. 11-03-2011 v0.7.4: * Improved Makefile, added the VERBOSE (V) option * Added the (beta) Highscore support * Improved the GUI * The control is now by the arrow keys - no longer `WASD` * Added two command-line interfaces '--help and --version' 09-10-2011 v0.5 * Initial release: game works. nsnake-1.5/INSTALL0000644000175000017500000000603012135565363012375 0ustar kurekurenSnake INSTALL ============== Installing information for the game nSnake. This applies to GNU/Linux systems. Microsoft Windows users have a precompiled executable. INSTALL Index ------------- Continuing from the README file: 3) Installation 4) Installation Informations 5) Advanced Installation 6) Uninstallation 7) Advanced Uninstallation 8) Dependencies 3) Installation --------------- Briefly, the following shell commands should configure, build, and install this package on the default directories: $ make $ sudo make install 4) Installation Informations ---------------------------- By default, 'make install' installs the package on the following directories: /usr/local/bin/ Executable files /usr/local/share/man/man6/ Man page /var/games/ HighScore files 5) Advanced Installation ------------------------ You can specify a custom root directory for the installation (other than '/'). To do this, give 'make install' the option DESTDIR=CUSTOM_ROOT, where CUSTOM_ROOT must be an absolute directory name. For example: $ make install DESTDIR=test/dir This way, the file hierarchy will be: test/dir/usr/local/bin/ Executable files test/dir/usr/local/share/man/man6/ Man page test/dir/var/games/nsnake/ HighScore files You can also specify an installation prefix other than '/usr/local' by giving 'make' the option PREFIX=CUSTOM_PREFIX, where CUSTOM_PREFIX must be an absolute directory name. For example: $ make install PREFIX=test/dir This way, the file hierarchy will be: test/dir/bin/ Executable files test/dir/share/ Man page /var/games/nsnake/ HighScore files To customize the highscores directory, modify SCOREDIR: $ make install SCOREDIR=test/dir This way, the highscore directory will be: test/dir/ HighScore files 6) Uninstallation ----------------- To uninstall this package, by default: $ sudo make uninstall To purge (remove also the HighScore files and Man page) go for: $ sudo make purge 7) Advanced Uninstallation -------------------------- If you specified a custom root directory for installation, 'make' needs to know about it to uninstall properly: $ make uninstall DESTDIR=test/dir The same logic applies to purging: $ make purge DESTDIR=test/dir If you installed it with a custom prefix, do the same: $ make uninstall PREFIX=test/dir $ make purge PREFIX=test/dir $ make purge SCOREDIR=test/dir 8) Dependences -------------- To build nSnake from source, it requires the ncurses developer library: libncurses5-dev (>= 5.7) Note that this is not the one that comes by default with the distribution. To get ncurses-dev, use your favorite package manager. An 'apt' example: $ sudo apt-get install libncurses5-dev or $ sudo apt-get install ncurses-dev nsnake-1.5/doc/0000775000175000017500000000000012135565363012114 5ustar kurekurensnake-1.5/doc/man/0000775000175000017500000000000012135565363012667 5ustar kurekurensnake-1.5/doc/man/nsnake.60000664000175000017500000000367312135565363014246 0ustar kurekure.\" ----------------------------- nSnake man page ------------------------------- .TH nsnake 6 "Fri, 20 Jan 2012" v1.5 "nSnake v1.5" .\"---------------------------------- NAME -------------------------------------- .SH NAME nsnake \- A snake game clone with nCurses .\"-------------------------------- SYNOPSIS ------------------------------------ .SH SYNOPSIS nsnake .RB [ -h ] .RB [ -l ] .RB [ -v ] .RB [ -r ] .\"------------------------------- DESCRIPTION ---------------------------------- .SH DESCRIPTION nSnake is a implementation of the classic snake game with textual interface. It is playable at command-line and uses the nCurses C library for graphics. The rules are the same of any snake game: .PP You control a hungry snake and the objective is to eat as many fruits you can. Each fruit eaten increases it's size by two units. .PP The game ends when the snake collides with the walls or itself. Currently, nSnake has two modes: With Borders and without borders. .PP The challenge is to earn the biggest score possible by eating as many fruits as you can. .B Controls: .RS Numbers (1~9) Changes the game speed at the main menu Arrow Keys, WASD Moves the snake q Quits the game at any time p Pauses/Unpauses the game .RE .\"--------------------------------- OPTIONS ------------------------------------ .SH OPTIONS .TP .B "-h, --help" Displays the quick help text. .TP .B "-l, --license" Displays the program license and warranty. .TP .B "-v, --version" Displays the version and general information. .TP .B "-r, --reset-scores" Resets all the Highscores to default. .\"----------------------------------- BUGS ------------------------------------- .SH BUGS If you find a bug, please email me at . .\"---------------------------------- AUTHOR ------------------------------------ .SH AUTHOR This manual page and nSnake were both written by Alexandre Dantas . nsnake-1.5/doc/doxygen_mainpage.h0000664000175000017500000000650012135565363015604 0ustar kurekure/** @mainpage Documentation Main Page *

Introduction

* This is the main documentation page of nSnake.
* It was made for programmers and people who want to understand * the source code.
*
* Here is the folder and file structure:
*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
General game information README file
Installation instructions and information INSTALL file
Known bugs and information about where to submit new ones BUGS file
Copyright and warranty info COPYING file
Doxygen file for generating this documentation. Doxyfile file
Instructions to the 'make' program. Makefile file
Work that needs to be done or ideas for future versions. TODO file
All of the source code files. /src folder
The documentation files (explaining the source code) and manpage /doc folder
Location of resulting object files after compilation /obj folder
Location of the executable generated after compilation /bin folder
* *
*

Description

* One important objective i kept in mind when coding nSnake, * was to make the source code as simple as it could be.
* I wished too that this code could be a guide to C programming * and nCurses learning for beginners. *
* But with time, the game structure got more complicated; i had * to break large chunks of code into more manageable files; the * folder structure wasn't as clean as before; the Makefile got * bigger and bigger... I kinda lost myself around somewhere. *
* So now i think this source code may be a guide to people who * are used to programming, but don't know about coding standards, * modularization, naming rules, and such.
* Then, if you already have a project (or if you are making one) * i highly recommend you take a time to read these source files * and consider at least some of the ideas i present.
* For example, the function names.

* Each group of .c and .h files represent an unique concept. * Player, Fruit and Scores, together with Main and * nSnake itself. Each of those has a responsability on the * game.
* So i renamed each function to this pattern: *
* modulename_action_provided_by_function () *
*
* This way, just by looking at it you know where this function is * from. * Also, this is the structure of external functions - functions * that can be called from other modules. If there is a function * that only serves the current module, it has simply the name * of the action provided by the function. * * I really need to continue this description. * * Any questions, please email me at . */ nsnake-1.5/doc/logo.png0000664000175000017500000002162712135565363013572 0ustar kurekurePNG  IHDR7IR pHYs   OiCCPPhotoshop ICC profilexڝSgTS=BKKoR RB&*! J!QEEȠQ, !{kּ> H3Q5 B.@ $pd!s#~<<+"x M0B\t8K@zB@F&S`cbP-`'{[! eDh;VEX0fK9-0IWfH  0Q){`##xFW<+*x<$9E[-qWW.(I+6aa@.y24x6_-"bbϫp@t~,/;m%h^ uf@Wp~<5j>{-]cK'Xto(hw?G%fIq^D$.Tʳ?D*A, `6B$BB dr`)B(Ͱ*`/@4Qhp.U=pa( Aa!ڈbX#!H$ ɈQ"K5H1RT UH=r9\F;2G1Q= C7F dt1r=6Ыhڏ>C03l0.B8, c˱" VcϱwE 6wB aAHXLXNH $4 7 Q'"K&b21XH,#/{C7$C2'ITFnR#,4H#dk9, +ȅ3![ b@qS(RjJ4e2AURݨT5ZBRQ4u9̓IKhhitݕNWGw Ljg(gwLӋT071oUX**| J&*/Tު UUT^S}FU3S ԖUPSSg;goT?~YYLOCQ_ cx,!k u5&|v*=9C3J3WRf?qtN (~))4L1e\kXHQG6EYAJ'\'GgSSݧ M=:.kDwn^Loy}/TmG X $ <5qo</QC]@Caaᄑ.ȽJtq]zۯ6iܟ4)Y3sCQ? 0k߬~OCOg#/c/Wװwa>>r><72Y_7ȷOo_C#dz%gA[z|!?:eAAA!h쐭!ΑiP~aa~ 'W?pX15wCsDDDޛg1O9-J5*>.j<74?.fYXXIlK9.*6nl {/]py.,:@LN8A*%w% yg"/6шC\*NH*Mz쑼5y$3,幄'L Lݛ:v m2=:1qB!Mggfvˬen/kY- BTZ(*geWf͉9+̳ې7ᒶKW-X潬j9(xoʿܔĹdff-[n ڴ VE/(ۻCɾUUMfeI?m]Nmq#׹=TR+Gw- 6 U#pDy  :v{vg/jBFS[b[O>zG499?rCd&ˮ/~јѡ򗓿m|x31^VwwO| (hSЧc3- cHRMz%u0`:o_FIDATxiwTǙR#B%+E!'q&Mrμȫ93/&gq&q2;Ď1bKkZR+nm"]Qw޺Oj*r+)[eCCCr+[],XB[~tk(/)-iLݒHMRŒ%UJrS ,#AeI %rI1())is&˓?l LK4\%C7~PX@*k+o e%]Bd`Io!D!Is%݉ !4͒r^t~I͝ـe[jgs!̩3TUF;rW׻{>}I\Tͫܦ=똈,lQy uhnI'[r+|2le^S1sԬtݒ4!yIm|KI{%-ܲ36r/;yR_oL11ߋ6Ij!mIggYCe}}}xSQ%˒a[$-} '(LHzK9iL|&^!CG~% H#v%V 9r; YآPYWW07xw  oA)󲙭ՒNJL"Pqo5֦KÒ~R-Y" /a< [T*kkoA s K*lv5wJ4kX/J4'DdXJB]LRҊ2Z%&i-x&3ogI8k<ĪfM]* ܨo/:ӦdӽG7eD.`Ŷ!DV ΈLj?hYڢ`dzWgPR^HlQp1/V _yLկwy'dz[Yy3 N_ 7_?-9Qyp:p eӴ'0 OȮ]+ꌷE$K.FMwn繹]`o`;H3FeKD"z!Tɶp; 8n 34{XTbAWE,F RMV <#Rn3.ɦu7OI٬K!F!dnIt\a4RM#'zCf`{*ID֢]]lZ}$;[T*''@ c{[Sh*id9~s&»eKNFxN=)@qMl9_EUc]N`Ģ-*-S7-R' (Av^l`\sgq0%X\0Jw.nXOCEh^rZy׷ym[?ղG%} )[{$[j Ak _J'IMVK$ߒ>_Mou'$='@'%}D;e4>Fm툤3a׋Q-/ >aFNJJv< *^0Na3^` y?-[4p0`ހg/(,g*U@ɴ 灛d_͋p] -.ol}}T3a152}hdkn%A \lzCa,p#<H@C*QJ# Fh0I "e\,GC0G_(xVn7iJ'DiH/3Q>~>k9&[5vl.&lb%o|kV+eISX.6\!4R1Jh:a4Ov1zZ#nhOQ B\ s؀7plr9kZƶ&Iйg;~𝜆YE_B }2 ((U.+ WGkFh |bܡC@LwUÿ&LXOXsn:v b0Ф(`wK?q30A(51/`yu:ݚGs&K-E\1U%:<*" }{2ahsI6Tsd| C[Lb:0: ':<&G9kz)*B7_~Lv+3}mc*e"Fh<^}φOz mXΔw.▹ZT*Y̬Xsw0AaVEJx=3PǘTq|%JfW@p h=d0fw=wp a5\|!QnnIV}?wKQyȱ 괕jAJE jO `Gܨ2|-*(

] dͧq.3>F Je\6PS`\ቑ7,S")ۓ/|Ͻ x xyGۻݢ ,( \ x1sL[tgn{>Խ 26XYL`Pa) ǽ`*Fd`aa;xkq8~[8XY+IegiXLv{琞L:2-y< x^%| 8Bq ոGXg*e …Qh쑱$x-R6IcZ`l9E|qN3hQݏs2qQⵓݡH~zӌy/u0:nI_R hQ#W˵'\sj+WS50*)zBvQ<{=4t"\HA7z<Yr>?ia+H03ҸΞ񛘱nQ-w֢b]%dk\Kdm7}a܄W}̄ƺ3=[Ĕo'.yFi_08PFoJE0ڂF/j? *HW>%uƺ7V<p_u?2n',AL㾄M\G}.@>p4"rS p=eyR[L7%\ud!.a FsҼQQ;4DEfs6dtA`IYhCS3ɘ@U6 |ޔ]0FC9[ &y)0zFyV;|;x12LGa‹3WCWx6h#mTK9렵أUaJ>PX+"s༑n]$ M>*[Rtt!^1h1ClllLjKd'RaiqZQ^JtI)GC/)Q/s!ra[ ^0JzHb.), ~4 ݘwm^7aW#v[撸x] REqgBga~aDQyشi'''^{{l2܏En$s]7-jfJun]ݼacݧZծOjX'Jv-z"c3a.ò\d^@e}G7Q}9I„nIvZcm)nWM7FaXF |WWaK ,PyjO{F0 xF(_bTJKe7%`tW SXM܉/! h-cYO@# 5qOx~KvBFkMFAxej|Z^sV~? tw3.Iww_`TamEInĩU~ T;PbGΜC^uy0+<YSXf3UF+Ńf@`2.3)3F)SA֧f*?1yR0K7^w&a/ɂčS^Sc$bo ]F׊gFqc]iYw#EF9gaθK{_^ ]( |΁q5 B0dD;CLYqa7HF׊gεk=<ݸJI%:xQ4\c%)8nl N!1_#i)8X^eM31?@ʺ!Aw \( /xNY?߉#tI4T:{MY8X!VfVZ+vuh䓁bc]S$W N2MT',ƺG { &f1qAG+<ǂ0:׹mR=iއ$[`^zc}N%KV$se&;[mܷiT2cNo&liLuZGen < ٪B2GW߻1Y`ZR0ZRFYd46b kkFKyؘ?TҚ2֟tc,FBQ`b-oWӴ&ɴ齈 ,^XZ^f)E2IcrҼ9AzѸ}|.k<\yfgFL`'nIǐN%dڊg҅h+^.Mhx8 ROQziIw Gƒi%Kó7F)RΝcnX\t3p;FK5'[Rϻy M~(<&/ef%w0W. e]Qyhiia:{j>eWoyNG2-[Fe2u|}^w0{G$szy}-(\%&ZSa(&&N4lYk,C f҅hE030F'MƎueXV0;q7 Dϑ]5`1jl*<<-2Y\&KYCʪ 6Ic3ү`ÃkA܆X0`oRTMEC.Q~_f3*g#LT(KbAZ;NB˹Ra&x rA-:mFJXumɽ-ƦwtxUG0+܎[,FVғ`ZDS&Lz a+qd+.;6bAz{Fqp_FLjP7256VV ԔeA9g-Ǜbs>݈#, # # Makefile Commandlines: # V Print all commands as they are called. # To turn on for the current make, add 'V=1' on the # commandline. # To turn on permanently, uncomment the line specified below # DESTDIR Installs the package on a custom root directory (other than /) # For example 'DESTDIR=~/'. # PREFIX Installs the package on a custom directory (overwrites root) # CFLAGS Changes the C flags used on compilation # CDEBUG If you wish to build on debug mode, add 'CDEBUG=-g' # # Makefile Targets: # all Compiles the package # run Compiles and runs the program # install Installs the package # clean Removes the binary and the resulting object files # uninstall Uninstalls the package # dist Creates the source code 'tarball' for distribution # doc Generates the documentation with doxygen # docclean Removes the documentation # Uncomment line below to tun on verbose mode permanently #V = 1; SHELL = /bin/sh # General Info PACKAGE = nsnake VERSION = 1.5 DATE = `date '+%b%Y'` # Local source code information LBIN = bin LOBJ = obj LDOC = doc LSRC = src LFILES = BUGS ChangeLog COPYING Doxyfile INSTALL Makefile README TODO # Install DESTDIR = PREFIX = $(DESTDIR)/usr EXEC_PREFIX = $(PREFIX) DATAROOTDIR = $(PREFIX)/share MANROOT = $(DATAROOTDIR)/man BINDIR = $(EXEC_PREFIX)/games MANDIR = $(MANROOT)/man6 MANNUMBER = 6 # Package score file name SCORE_FILE = high-scores.bin # Compiling information CC = gcc EXE = nsnake CDEBUG = CFLAGS = $(CDEBUG) -Wall -Wextra -O2 LIBS = -lncurses INCLUDESDIR = LIBSDIR = OBJ = $(LOBJ)/fruit.o \ $(LOBJ)/main.o \ $(LOBJ)/player.o \ $(LOBJ)/nsnake.o \ $(LOBJ)/engine.o \ $(LOBJ)/hscores.o \ $(LOBJ)/arguments.o MANFILE = $(PACKAGE).$(MANNUMBER) MANPAGE = $(LDOC)/man/$(MANFILE) DEFINES = -DVERSION=\""$(VERSION)"\" \ -DDATE=\""$(DATE)"\" \ -DSCORE_FILE=\""$(SCORE_FILE)"\" # Distribution tarball TARNAME = $(PACKAGE) DISTDIR = $(TARNAME)-$(VERSION) # Verbose mode check ifdef V MUTE = VTAG = -v else MUTE = @ endif ifdef DESTDIR ROOT = - else ROOT = endif # Make targets all: dirs $(EXE) # Build successful! install: all # Installing... $(MUTE)install -d --mode=755 $(BINDIR) $(MUTE)install $(LBIN)/$(EXE) $(BINDIR) $(MUTE)install -d $(MANDIR) $(MUTE)install $(MANPAGE) $(MANDIR) # $(PACKAGE) successfuly installed! uninstall: # Uninstalling... $(MUTE)rm -f $(BINDIR)/$(EXE) purge: uninstall # Purging configuration files... $(MUTE)rm -f $(MANDIR)/$(MANFILE) $(EXE): $(OBJ) # Linking... $(MUTE)$(CC) $(OBJ) -o $(LBIN)/$(EXE) $(LIBSDIR) $(LIBS) $(LOBJ)/%.o: $(LSRC)/%.c # Compiling $<... $(MUTE)$(CC) $(CFLAGS) $< -c -o $@ $(DEFINES) $(INCLUDESDIR) dist: clean $(DISTDIR).tar.gz $(DISTDIR).tar.gz: $(DISTDIR) $(MUTE)tar czf $(DISTDIR).tar.gz $(DISTDIR) $(MUTE)rm -rf $(DISTDIR) $(MUTE)cp $(DISTDIR).tar.gz .. $(MUTE)rm -f $(DISTDIR).tar.gz $(DISTDIR): $(MUTE)mkdir -p $(DISTDIR)/$(LSRC) $(DISTDIR)/$(LDOC) $(MUTE)mkdir -p $(DISTDIR)/$(LBIN) $(DISTDIR)/$(LOBJ) -$(MUTE)cp $(LFILES) -t $(DISTDIR) -$(MUTE)cp -r $(LSRC)/* $(DISTDIR)/$(LSRC) -$(MUTE)cp -r $(LBIN)/* $(DISTDIR)/$(LBIN) -$(MUTE)cp -r $(LDOC)/* $(DISTDIR)/$(LDOC) dirs: # Asserting source dirs... -$(MUTE)mkdir -p $(LOBJ) $(LBIN) run: all # Running... $(MUTE)./$(LBIN)/$(EXE) clean: # Cleaning files... $(MUTE)rm $(VTAG) -f $(LOBJ)/*.o $(MUTE)rm $(VTAG) -f $(LBIN)/* doc: # Generating documentation... $(MUTE)doxygen Doxyfile docclean: # Removing documentation... -$(MUTE)rm $(VTAG) -rf $(LDOC)/html .PHONY: clean doc docclean uninstall #------------------------------------------------------------------------------ nsnake-1.5/TODO0000644000175000017500000000604612135565363012043 0ustar kurekureI usually have lots of ideas that would take a loong time to implement. So i rely on friends and testers to give me their opinion about it. What do you think about those? -------------------------------------------------------------------------------- [easy] When the snake eats a frut, modify its body so that the place where the fruit was becomes big.. Just like when a snake eats it gets stuffed [medium] Attribute that changes the snake color Like -c [0 ~ 4], changes colors from 0 to 4 Change more colors? Key 'c' changes the color in-game [simple] Make the game speed changing more balanced Make the fruit give score equal to game level [medium] Make attribute that changes the game level size? Follow the other 'nsnake' path and handle the SIGWINCH signal? This way, whenever someone resize the window, i could do whatever i want, like resize the game window or move the screen... [hard] Change level to be a big char grid. Each cell will be able to be EMPTY, FRUIT, WALL or SNAKE. When checking collision, simply watch if snake's head is in a WALL cell Same for when snake's head is in a FRUIT cell And same when creating a fruit! Instead of checking each and every snake position, check only if the grid is a SNAKE. (the only exception would be the snake head. how can i check collision with it if it's a SNAKE cell?) This will make possible to create LEVELS for the game! Just read a text file with real grids on it, parse and voila! I wonder if this would be the game be complicated... Need to check other game's examples. [simple] Insert header when writing to score file so i can check if it is corrupted. Whenever i read from the score file, check if the header is ok. Maybe some special number like 666 or a string like "nSnAkE_sCoReFiLe" What will i do if i find a corrupted score file? Erase the score? Rewrite it? I need to warn the player, right? [hard as hell] Change the way highscores exist. Maybe implement a highscore screen, with the names of the players. Assume default name as getenv("USER") and such. [simple] Leave nsnake with the default background color of the user terminal, instead of COLOR_BLACK. Since use_default_colors is a ncurses extension, the man page recommends conditioning it to NCURSES_VERSION. What does that mean? [simple] Deal with signals, in case someone does Ctrl+C. Exit from ncurses and free() the snake memory :D [simple] Create function that will verify if the user pressed something (kbhit()) If the user did, go to the nonblocking input functions (saves memory) [simple] When clearing highscores, show if it worked or not (due to several reasons) Show the hscore directory? ------------------------------------------- * Campaign Mode? Change levels? > way ahead *** Increase or decrease movement speed according to the game * Possibility to change the controls (add config option - add controls.bin file) **** Include libncurses with the source? ***** True Highscore Support: For each mode, its own Highscore *** Windows support: PDCurses! ------------------------------------------ nsnake-1.5/BUGS0000644000175000017500000000141112135565363012025 0ustar kurekureBUGS ==== List of known bugs. I plan to fix them as soon as possible. Please send bug reports to (Mon Jan 16 11:38:16 BRT 2012) If you try to run nSnake with parameters that don't start with '-', they are completely ignored. (Fix probably at getopt_long at arguments.c) (Thu Jul 26 10:38:21 BRT 2012) When the fruit is at the bottom of the screen and the snake tries to eat it on the borderless mode teleporting from above, it doesn't get eaten - the snake goes through it. The same when the fruit is at the top left and the snake goes through the right. (Fix at collision detection) Wed Aug 22 10:17:51 BRT 2012 When the player holds a directional key, the snake keeps going for a while. Maybe holding the key fills the input buffer or something. nsnake-1.5/COPYING0000644000175000017500000010451312135565363012404 0ustar kurekure GNU GENERAL PUBLIC LICENSE Version 3, 29 June 2007 Copyright (C) 2007 Free Software Foundation, Inc. Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The GNU General Public License is a free, copyleft license for software and other kinds of works. The licenses for most software and other practical works are designed to take away your freedom to share and change the works. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change all versions of a program--to make sure it remains free software for all its users. We, the Free Software Foundation, use the GNU General Public License for most of our software; it applies also to any other work released this way by its authors. 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 them 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 prevent others from denying you these rights or asking you to surrender the rights. Therefore, you have certain responsibilities if you distribute copies of the software, or if you modify it: responsibilities to respect the freedom of others. For example, if you distribute copies of such a program, whether gratis or for a fee, you must pass on to the recipients the same freedoms that you received. 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. Developers that use the GNU GPL protect your rights with two steps: (1) assert copyright on the software, and (2) offer you this License giving you legal permission to copy, distribute and/or modify it. For the developers' and authors' protection, the GPL clearly explains that there is no warranty for this free software. For both users' and authors' sake, the GPL requires that modified versions be marked as changed, so that their problems will not be attributed erroneously to authors of previous versions. Some devices are designed to deny users access to install or run modified versions of the software inside them, although the manufacturer can do so. This is fundamentally incompatible with the aim of protecting users' freedom to change the software. The systematic pattern of such abuse occurs in the area of products for individuals to use, which is precisely where it is most unacceptable. Therefore, we have designed this version of the GPL to prohibit the practice for those products. If such problems arise substantially in other domains, we stand ready to extend this provision to those domains in future versions of the GPL, as needed to protect the freedom of users. Finally, every program is threatened constantly by software patents. States should not allow patents to restrict development and use of software on general-purpose computers, but in those that do, we wish to avoid the special danger that patents applied to a free program could make it effectively proprietary. To prevent this, the GPL assures that patents cannot be used to render the program non-free. The precise terms and conditions for copying, distribution and modification follow. TERMS AND CONDITIONS 0. Definitions. "This License" refers to version 3 of the GNU General Public License. "Copyright" also means copyright-like laws that apply to other kinds of works, such as semiconductor masks. "The Program" refers to any copyrightable work licensed under this License. Each licensee is addressed as "you". "Licensees" and "recipients" may be individuals or organizations. To "modify" a work means to copy from or adapt all or part of the work in a fashion requiring copyright permission, other than the making of an exact copy. The resulting work is called a "modified version" of the earlier work or a work "based on" the earlier work. A "covered work" means either the unmodified Program or a work based on the Program. To "propagate" a work means to do anything with it that, without permission, would make you directly or secondarily liable for infringement under applicable copyright law, except executing it on a computer or modifying a private copy. Propagation includes copying, distribution (with or without modification), making available to the public, and in some countries other activities as well. To "convey" a work means any kind of propagation that enables other parties to make or receive copies. Mere interaction with a user through a computer network, with no transfer of a copy, is not conveying. An interactive user interface displays "Appropriate Legal Notices" to the extent that it includes a convenient and prominently visible feature that (1) displays an appropriate copyright notice, and (2) tells the user that there is no warranty for the work (except to the extent that warranties are provided), that licensees may convey the work under this License, and how to view a copy of this License. If the interface presents a list of user commands or options, such as a menu, a prominent item in the list meets this criterion. 1. Source Code. The "source code" for a work means the preferred form of the work for making modifications to it. "Object code" means any non-source form of a work. A "Standard Interface" means an interface that either is an official standard defined by a recognized standards body, or, in the case of interfaces specified for a particular programming language, one that is widely used among developers working in that language. The "System Libraries" of an executable work include anything, other than the work as a whole, that (a) is included in the normal form of packaging a Major Component, but which is not part of that Major Component, and (b) serves only to enable use of the work with that Major Component, or to implement a Standard Interface for which an implementation is available to the public in source code form. A "Major Component", in this context, means a major essential component (kernel, window system, and so on) of the specific operating system (if any) on which the executable work runs, or a compiler used to produce the work, or an object code interpreter used to run it. The "Corresponding Source" for a work in object code form means all the source code needed to generate, install, and (for an executable work) run the object code and to modify the work, including scripts to control those activities. However, it does not include the work's System Libraries, or general-purpose tools or generally available free programs which are used unmodified in performing those activities but which are not part of the work. For example, Corresponding Source includes interface definition files associated with source files for the work, and the source code for shared libraries and dynamically linked subprograms that the work is specifically designed to require, such as by intimate data communication or control flow between those subprograms and other parts of the work. The Corresponding Source need not include anything that users can regenerate automatically from other parts of the Corresponding Source. The Corresponding Source for a work in source code form is that same work. 2. Basic Permissions. All rights granted under this License are granted for the term of copyright on the Program, and are irrevocable provided the stated conditions are met. This License explicitly affirms your unlimited permission to run the unmodified Program. The output from running a covered work is covered by this License only if the output, given its content, constitutes a covered work. This License acknowledges your rights of fair use or other equivalent, as provided by copyright law. You may make, run and propagate covered works that you do not convey, without conditions so long as your license otherwise remains in force. You may convey covered works to others for the sole purpose of having them make modifications exclusively for you, or provide you with facilities for running those works, provided that you comply with the terms of this License in conveying all material for which you do not control copyright. Those thus making or running the covered works for you must do so exclusively on your behalf, under your direction and control, on terms that prohibit them from making any copies of your copyrighted material outside their relationship with you. Conveying under any other circumstances is permitted solely under the conditions stated below. Sublicensing is not allowed; section 10 makes it unnecessary. 3. Protecting Users' Legal Rights From Anti-Circumvention Law. No covered work shall be deemed part of an effective technological measure under any applicable law fulfilling obligations under article 11 of the WIPO copyright treaty adopted on 20 December 1996, or similar laws prohibiting or restricting circumvention of such measures. When you convey a covered work, you waive any legal power to forbid circumvention of technological measures to the extent such circumvention is effected by exercising rights under this License with respect to the covered work, and you disclaim any intention to limit operation or modification of the work as a means of enforcing, against the work's users, your or third parties' legal rights to forbid circumvention of technological measures. 4. Conveying Verbatim Copies. You may convey 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; keep intact all notices stating that this License and any non-permissive terms added in accord with section 7 apply to the code; keep intact all notices of the absence of any warranty; and give all recipients a copy of this License along with the Program. You may charge any price or no price for each copy that you convey, and you may offer support or warranty protection for a fee. 5. Conveying Modified Source Versions. You may convey a work based on the Program, or the modifications to produce it from the Program, in the form of source code under the terms of section 4, provided that you also meet all of these conditions: a) The work must carry prominent notices stating that you modified it, and giving a relevant date. b) The work must carry prominent notices stating that it is released under this License and any conditions added under section 7. This requirement modifies the requirement in section 4 to "keep intact all notices". c) You must license the entire work, as a whole, under this License to anyone who comes into possession of a copy. This License will therefore apply, along with any applicable section 7 additional terms, to the whole of the work, and all its parts, regardless of how they are packaged. This License gives no permission to license the work in any other way, but it does not invalidate such permission if you have separately received it. d) If the work has interactive user interfaces, each must display Appropriate Legal Notices; however, if the Program has interactive interfaces that do not display Appropriate Legal Notices, your work need not make them do so. A compilation of a covered work with other separate and independent works, which are not by their nature extensions of the covered work, and which are not combined with it such as to form a larger program, in or on a volume of a storage or distribution medium, is called an "aggregate" if the compilation and its resulting copyright are not used to limit the access or legal rights of the compilation's users beyond what the individual works permit. Inclusion of a covered work in an aggregate does not cause this License to apply to the other parts of the aggregate. 6. Conveying Non-Source Forms. You may convey a covered work in object code form under the terms of sections 4 and 5, provided that you also convey the machine-readable Corresponding Source under the terms of this License, in one of these ways: a) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by the Corresponding Source fixed on a durable physical medium customarily used for software interchange. b) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by a written offer, valid for at least three years and valid for as long as you offer spare parts or customer support for that product model, to give anyone who possesses the object code either (1) a copy of the Corresponding Source for all the software in the product that is covered by this License, on a durable physical medium customarily used for software interchange, for a price no more than your reasonable cost of physically performing this conveying of source, or (2) access to copy the Corresponding Source from a network server at no charge. c) Convey individual copies of the object code with a copy of the written offer to provide the Corresponding Source. This alternative is allowed only occasionally and noncommercially, and only if you received the object code with such an offer, in accord with subsection 6b. d) Convey the object code by offering access from a designated place (gratis or for a charge), and offer equivalent access to the Corresponding Source in the same way through the same place at no further charge. You need not require recipients to copy the Corresponding Source along with the object code. If the place to copy the object code is a network server, the Corresponding Source may be on a different server (operated by you or a third party) that supports equivalent copying facilities, provided you maintain clear directions next to the object code saying where to find the Corresponding Source. Regardless of what server hosts the Corresponding Source, you remain obligated to ensure that it is available for as long as needed to satisfy these requirements. e) Convey the object code using peer-to-peer transmission, provided you inform other peers where the object code and Corresponding Source of the work are being offered to the general public at no charge under subsection 6d. A separable portion of the object code, whose source code is excluded from the Corresponding Source as a System Library, need not be included in conveying the object code work. A "User Product" is either (1) a "consumer product", which means any tangible personal property which is normally used for personal, family, or household purposes, or (2) anything designed or sold for incorporation into a dwelling. In determining whether a product is a consumer product, doubtful cases shall be resolved in favor of coverage. For a particular product received by a particular user, "normally used" refers to a typical or common use of that class of product, regardless of the status of the particular user or of the way in which the particular user actually uses, or expects or is expected to use, the product. A product is a consumer product regardless of whether the product has substantial commercial, industrial or non-consumer uses, unless such uses represent the only significant mode of use of the product. "Installation Information" for a User Product means any methods, procedures, authorization keys, or other information required to install and execute modified versions of a covered work in that User Product from a modified version of its Corresponding Source. The information must suffice to ensure that the continued functioning of the modified object code is in no case prevented or interfered with solely because modification has been made. If you convey an object code work under this section in, or with, or specifically for use in, a User Product, and the conveying occurs as part of a transaction in which the right of possession and use of the User Product is transferred to the recipient in perpetuity or for a fixed term (regardless of how the transaction is characterized), the Corresponding Source conveyed under this section must be accompanied by the Installation Information. But this requirement does not apply if neither you nor any third party retains the ability to install modified object code on the User Product (for example, the work has been installed in ROM). The requirement to provide Installation Information does not include a requirement to continue to provide support service, warranty, or updates for a work that has been modified or installed by the recipient, or for the User Product in which it has been modified or installed. Access to a network may be denied when the modification itself materially and adversely affects the operation of the network or violates the rules and protocols for communication across the network. Corresponding Source conveyed, and Installation Information provided, in accord with this section must be in a format that is publicly documented (and with an implementation available to the public in source code form), and must require no special password or key for unpacking, reading or copying. 7. Additional Terms. "Additional permissions" are terms that supplement the terms of this License by making exceptions from one or more of its conditions. Additional permissions that are applicable to the entire Program shall be treated as though they were included in this License, to the extent that they are valid under applicable law. If additional permissions apply only to part of the Program, that part may be used separately under those permissions, but the entire Program remains governed by this License without regard to the additional permissions. When you convey a copy of a covered work, you may at your option remove any additional permissions from that copy, or from any part of it. (Additional permissions may be written to require their own removal in certain cases when you modify the work.) You may place additional permissions on material, added by you to a covered work, for which you have or can give appropriate copyright permission. Notwithstanding any other provision of this License, for material you add to a covered work, you may (if authorized by the copyright holders of that material) supplement the terms of this License with terms: a) Disclaiming warranty or limiting liability differently from the terms of sections 15 and 16 of this License; or b) Requiring preservation of specified reasonable legal notices or author attributions in that material or in the Appropriate Legal Notices displayed by works containing it; or c) Prohibiting misrepresentation of the origin of that material, or requiring that modified versions of such material be marked in reasonable ways as different from the original version; or d) Limiting the use for publicity purposes of names of licensors or authors of the material; or e) Declining to grant rights under trademark law for use of some trade names, trademarks, or service marks; or f) Requiring indemnification of licensors and authors of that material by anyone who conveys the material (or modified versions of it) with contractual assumptions of liability to the recipient, for any liability that these contractual assumptions directly impose on those licensors and authors. All other non-permissive additional terms are considered "further restrictions" within the meaning of section 10. If the Program as you received it, or any part of it, contains a notice stating that it is governed by this License along with a term that is a further restriction, you may remove that term. If a license document contains a further restriction but permits relicensing or conveying under this License, you may add to a covered work material governed by the terms of that license document, provided that the further restriction does not survive such relicensing or conveying. If you add terms to a covered work in accord with this section, you must place, in the relevant source files, a statement of the additional terms that apply to those files, or a notice indicating where to find the applicable terms. Additional terms, permissive or non-permissive, may be stated in the form of a separately written license, or stated as exceptions; the above requirements apply either way. 8. Termination. You may not propagate or modify a covered work except as expressly provided under this License. Any attempt otherwise to propagate or modify it is void, and will automatically terminate your rights under this License (including any patent licenses granted under the third paragraph of section 11). However, if you cease all violation of this License, then your license from a particular copyright holder is reinstated (a) provisionally, unless and until the copyright holder explicitly and finally terminates your license, and (b) permanently, if the copyright holder fails to notify you of the violation by some reasonable means prior to 60 days after the cessation. Moreover, your license from a particular copyright holder is reinstated permanently if the copyright holder notifies you of the violation by some reasonable means, this is the first time you have received notice of violation of this License (for any work) from that copyright holder, and you cure the violation prior to 30 days after your receipt of the notice. Termination of your rights under this section does not terminate the licenses of parties who have received copies or rights from you under this License. If your rights have been terminated and not permanently reinstated, you do not qualify to receive new licenses for the same material under section 10. 9. Acceptance Not Required for Having Copies. You are not required to accept this License in order to receive or run a copy of the Program. Ancillary propagation of a covered work occurring solely as a consequence of using peer-to-peer transmission to receive a copy likewise does not require acceptance. However, nothing other than this License grants you permission to propagate or modify any covered work. These actions infringe copyright if you do not accept this License. Therefore, by modifying or propagating a covered work, you indicate your acceptance of this License to do so. 10. Automatic Licensing of Downstream Recipients. Each time you convey a covered work, the recipient automatically receives a license from the original licensors, to run, modify and propagate that work, subject to this License. You are not responsible for enforcing compliance by third parties with this License. An "entity transaction" is a transaction transferring control of an organization, or substantially all assets of one, or subdividing an organization, or merging organizations. If propagation of a covered work results from an entity transaction, each party to that transaction who receives a copy of the work also receives whatever licenses to the work the party's predecessor in interest had or could give under the previous paragraph, plus a right to possession of the Corresponding Source of the work from the predecessor in interest, if the predecessor has it or can get it with reasonable efforts. You may not impose any further restrictions on the exercise of the rights granted or affirmed under this License. For example, you may not impose a license fee, royalty, or other charge for exercise of rights granted under this License, and you may not initiate litigation (including a cross-claim or counterclaim in a lawsuit) alleging that any patent claim is infringed by making, using, selling, offering for sale, or importing the Program or any portion of it. 11. Patents. A "contributor" is a copyright holder who authorizes use under this License of the Program or a work on which the Program is based. The work thus licensed is called the contributor's "contributor version". A contributor's "essential patent claims" are all patent claims owned or controlled by the contributor, whether already acquired or hereafter acquired, that would be infringed by some manner, permitted by this License, of making, using, or selling its contributor version, but do not include claims that would be infringed only as a consequence of further modification of the contributor version. For purposes of this definition, "control" includes the right to grant patent sublicenses in a manner consistent with the requirements of this License. Each contributor grants you a non-exclusive, worldwide, royalty-free patent license under the contributor's essential patent claims, to make, use, sell, offer for sale, import and otherwise run, modify and propagate the contents of its contributor version. In the following three paragraphs, a "patent license" is any express agreement or commitment, however denominated, not to enforce a patent (such as an express permission to practice a patent or covenant not to sue for patent infringement). To "grant" such a patent license to a party means to make such an agreement or commitment not to enforce a patent against the party. If you convey a covered work, knowingly relying on a patent license, and the Corresponding Source of the work is not available for anyone to copy, free of charge and under the terms of this License, through a publicly available network server or other readily accessible means, then you must either (1) cause the Corresponding Source to be so available, or (2) arrange to deprive yourself of the benefit of the patent license for this particular work, or (3) arrange, in a manner consistent with the requirements of this License, to extend the patent license to downstream recipients. "Knowingly relying" means you have actual knowledge that, but for the patent license, your conveying the covered work in a country, or your recipient's use of the covered work in a country, would infringe one or more identifiable patents in that country that you have reason to believe are valid. If, pursuant to or in connection with a single transaction or arrangement, you convey, or propagate by procuring conveyance of, a covered work, and grant a patent license to some of the parties receiving the covered work authorizing them to use, propagate, modify or convey a specific copy of the covered work, then the patent license you grant is automatically extended to all recipients of the covered work and works based on it. A patent license is "discriminatory" if it does not include within the scope of its coverage, prohibits the exercise of, or is conditioned on the non-exercise of one or more of the rights that are specifically granted under this License. You may not convey a covered work if you are a party to an arrangement with a third party that is in the business of distributing software, under which you make payment to the third party based on the extent of your activity of conveying the work, and under which the third party grants, to any of the parties who would receive the covered work from you, a discriminatory patent license (a) in connection with copies of the covered work conveyed by you (or copies made from those copies), or (b) primarily for and in connection with specific products or compilations that contain the covered work, unless you entered into that arrangement, or that patent license was granted, prior to 28 March 2007. Nothing in this License shall be construed as excluding or limiting any implied license or other defenses to infringement that may otherwise be available to you under applicable patent law. 12. No Surrender of Others' Freedom. If 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 convey a covered work so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not convey it at all. For example, if you agree to terms that obligate you to collect a royalty for further conveying from those to whom you convey the Program, the only way you could satisfy both those terms and this License would be to refrain entirely from conveying the Program. 13. Use with the GNU Affero General Public License. Notwithstanding any other provision of this License, you have permission to link or combine any covered work with a work licensed under version 3 of the GNU Affero General Public License into a single combined work, and to convey the resulting work. The terms of this License will continue to apply to the part which is the covered work, but the special requirements of the GNU Affero General Public License, section 13, concerning interaction through a network will apply to the combination as such. 14. Revised Versions of this License. The Free Software Foundation may publish revised and/or new versions of the GNU 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 that a certain numbered version of the GNU General Public License "or any later version" applies to it, you have the option of following the terms and conditions either of that numbered version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of the GNU General Public License, you may choose any version ever published by the Free Software Foundation. If the Program specifies that a proxy can decide which future versions of the GNU General Public License can be used, that proxy's public statement of acceptance of a version permanently authorizes you to choose that version for the Program. Later license versions may give you additional or different permissions. However, no additional obligations are imposed on any author or copyright holder as a result of your choosing to follow a later version. 15. Disclaimer of Warranty. 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. 16. Limitation of Liability. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS 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. 17. Interpretation of Sections 15 and 16. If the disclaimer of warranty and limitation of liability provided above cannot be given local legal effect according to their terms, reviewing courts shall apply local law that most closely approximates an absolute waiver of all civil liability in connection with the Program, unless a warranty or assumption of liability accompanies a copy of the Program in return for a fee. 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 state 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 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . Also add information on how to contact you by electronic and paper mail. If the program does terminal interaction, make it output a short notice like this when it starts in an interactive mode: Copyright (C) This program 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, your program's commands might be different; for a GUI interface, you would use an "about box". You should also get your employer (if you work as a programmer) or school, if any, to sign a "copyright disclaimer" for the program, if necessary. For more information on this, and how to apply and follow the GNU GPL, see . The GNU 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. But first, please read .