main.c - gnuskii - GNUSki improved for ascii skiing experience.
 (HTM) git clone git://bitreich.org/gnuskii git://enlrupgkhuxnvlhsf6lc3fziv5h2hhfrinws65d7roiv6bfj7d652fid.onion/gnuskii
 (DIR) Log
 (DIR) Files
 (DIR) Refs
 (DIR) Tags
 (DIR) README
 (DIR) LICENSE
       ---
       main.c (5070B)
       ---
            1 /*  GNUSki - a clone of the old game Skifree where you race downhill
            2     avoiding rocks and trees and try to score points by doing some
            3     tricks.
            4     Copyright (C) 2007 Rudolf Olah
            5 
            6     This program is free software; you can redistribute it and/or modify
            7     it under the terms of the GNU General Public License as published by
            8     the Free Software Foundation; either version 2 of the License, or
            9     (at your option) any later version.
           10 
           11     This program is distributed in the hope that it will be useful,
           12     but WITHOUT ANY WARRANTY; without even the implied warranty of
           13     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
           14     GNU General Public License for more details.
           15 
           16     You should have received a copy of the GNU General Public License
           17     along with this program; if not, write to the Free Software
           18     Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
           19 */
           20 
           21 #include "objects.h"
           22 #include <stdlib.h>
           23 #include <time.h>
           24 #include <stdio.h>
           25 #include <unistd.h>
           26 #include <ncurses.h>
           27 
           28 #define MAX_OBJECTS 128
           29 
           30 int main (int argc, char* argv[])
           31 {
           32   const long fps = argc != 2 ? 20l : strtol(argv[1], NULL, 10);
           33   struct Object player, objects[MAX_OBJECTS];
           34   unsigned int c = 0, i = 0, maxRows, maxCols, score = 0,
           35     distance = 0, speed = 2, style = 0, frame_counter = 0;
           36   enum mode {loop, lose, win} state = loop;
           37   char facing[2] = {'s', 'n'};   /* Player facing, object facing */
           38 
           39   srand ((unsigned)time (NULL)); /* Seed random-number generator */
           40   initscr ();             /* Start ncurses */
           41   cbreak ();              /* Allow control breaks (Ctrl+C) */
           42   noecho ();              /* Don't echo characters to screen */
           43   keypad (stdscr, true);  /* Allow cursor key usage */
           44   curs_set (0);           /* Hide the cursor */
           45   getmaxyx (stdscr, maxRows, maxCols); /* Get coordinates of the terminal */
           46   setupColors ();
           47 
           48   /* Create objects */
           49   player = makeObject (skier, maxCols/2, maxRows/2);
           50   for (i = 0; i < MAX_OBJECTS; i++) {
           51     objects[i] = makeObject (rand () % 3+1,
           52                              rand () % maxCols,
           53                              rand () % (maxRows*4 + maxRows/2));
           54   }
           55 
           56   objects[rand() % MAX_OBJECTS] = makeObject (bigfoot,
           57                              rand () % maxCols,
           58                              rand () % (maxRows*4 + maxRows/2));
           59   objects[rand() % MAX_OBJECTS] = makeObject (snowman,
           60                              rand () % maxCols,
           61                              rand () % (maxRows*4 + maxRows/2));
           62 
           63   /* Menu will go here */
           64   printw ("GNUSki 0.3 - Skifree clone using NCurses, licensed under the GNU GPL.\n");
           65   printw ("left, h, h - lean left\n");
           66   printw ("right, L, l - lean right\n");
           67   printw ("up, K, k - slow down\n");
           68   printw ("down, J, j - speed up\n");
           69   printw ("space - go into trick mode (beware, you can't move)\n");
           70   printw ("Press any key to start...");
           71   refresh ();
           72   getch ();
           73   nodelay (stdscr, true); /* No waiting for input from the user */
           74   while (state == loop)
           75     {
           76       switch (c)
           77         {
           78         case KEY_LEFT: case 'h': case 'H':
           79           if (player.trick) break;
           80           facing[0] = '4';
           81           facing[1] = '2';
           82           break;
           83         case KEY_RIGHT: case 'l': case 'L':
           84           if (player.trick) break;
           85           facing[0] = '3';
           86           facing[1] = '1';
           87           break;
           88         case KEY_UP: case 'k': case 'K':
           89           if (player.trick) break;
           90           if (speed > 0)
           91             speed--;
           92           break;
           93         case KEY_DOWN: case 'j': case 'J':
           94           if (player.trick) break;
           95           if (speed < 4)
           96             speed++;
           97           break;
           98         case ' ':
           99           player.trick++;
          100           break;
          101         case 'Q': case 'q':
          102           state = lose;
          103           break;
          104         }
          105 
          106           clear ();
          107 
          108           /* Check for collisions and draw the objects */
          109           for (i = 0; i < MAX_OBJECTS; i++)
          110             {
          111               if (objects[i].type != none && collision (player, objects[i]))
          112                 state = lose;
          113               /* Calculate actual movement based on speed and frame counter */
          114               int actual_speed = 0;
          115               if (speed == 0) actual_speed = 0;
          116               else if (speed == 1 && frame_counter % 4 == 0) actual_speed = 1;
          117               else if (speed == 2 && frame_counter % 3 == 0) actual_speed = 1;
          118               else if (speed == 3 && frame_counter % 2 == 0) actual_speed = 1;
          119               else if (speed == 4) actual_speed = 1;
          120               
          121               moveObject (&objects[i], facing[1], actual_speed);
          122               if (objects[i].y < 0)
          123                 setPosition (&objects[i], rand () % (maxCols*2),
          124                              rand () % maxRows + maxRows);
          125               if (objects[i].x > 2 && objects[i].x < maxCols-2
          126                   && objects[i].y > 2 && objects[i].y < maxRows-2)
          127                 draw (objects[i], facing[1]);
          128             }
          129           draw (player, facing[0]);
          130           if (player.trick) {
          131             style += 1;
          132             player.trick -= 0.10;
          133             if (player.trick < 0) player.trick = 0;
          134           }
          135           printw ("Time:   0:00:00.00\n");
          136           printw ("Dist:     %02im\n", distance);
          137           printw ("Speed:    %02im/s\n", speed);
          138           printw ("Style:    %4i (trick = %.2f%%)", style, player.trick*100);
          139           distance += speed;
          140           frame_counter++;
          141       refresh ();
          142       usleep(1000000 / fps);
          143       c = getch ();
          144     }
          145   clear ();
          146   if (state == win)
          147     printw ("You won.");
          148   else
          149     printw ("You lost.");
          150   printw ("Your score was %i. You traveled %im.\nPress any key to continue...",
          151           distance+style, distance);
          152   refresh ();
          153   nodelay (stdscr, false);
          154   getch ();
          155 
          156   endwin ();
          157   return 0;
          158 }