Tennix 0.6.0 and documentation updates
[tennix.git] / tennix.c
blob16503d5ac35030981ae69ceae2acf2b8a4328264
2 /**
4 * Tennix! SDL Port
5 * Copyright (C) 2003, 2007, 2008 Thomas Perl <thp@perli.net>
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation; either version 2
10 * of the License, or (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
20 * MA 02110-1301, USA.
22 **/
24 #include <stdio.h>
25 #include <time.h>
26 #include <libgen.h>
28 #ifdef WIN32
29 #include <windows.h>
30 #endif
32 #include "tennix.h"
33 #include "game.h"
34 #include "graphics.h"
35 #include "sound.h"
36 #include "input.h"
38 SDL_Surface *screen;
40 static const char* help_text[] = {
41 "player 1 moves with <w>, <s> and <d>",
42 "player 2 moves with <o>, <l> and <k>",
43 "switch court in game with <c>, pause with <p>",
44 "" /* joystick help text comes here */,
45 #ifdef ENABLE_MOUSE
46 "press left mouse button to move racket",
47 "release left mouse button to swing racket",
48 #endif
51 /* Number of lines in help_text */
52 #ifdef ENABLE_MOUSE
53 #define HELP_LINES 6
54 #else
55 #define HELP_LINES 4
56 #endif
57 /* Height (in pixels) of the help text scroller */
58 #define HELP_PHASE 85
60 #ifdef WIN32
62 /* IDs from the resource file */
63 #define START_BUTTON 1
64 #define CHECKBOX_FULLSCREEN 2
65 #define QUIT_BUTTON 3
67 BOOL CALLBACK ConfigDialogProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
69 static int checkbox_is_checked;
71 switch (uMsg) {
72 case WM_CLOSE:
73 EndDialog(hwndDlg, IDCANCEL);
74 break;
75 case WM_COMMAND:
76 switch (wParam) {
77 case START_BUTTON:
78 EndDialog(hwndDlg, (checkbox_is_checked)?(IDYES):(IDNO));
79 break;
80 case QUIT_BUTTON:
81 EndDialog(hwndDlg, IDCANCEL);
82 break;
83 case CHECKBOX_FULLSCREEN:
84 checkbox_is_checked ^= 1;
85 break;
87 break;
88 default:
89 return FALSE;
91 return TRUE;
93 #endif
95 #ifdef WIN32
96 int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
97 LPSTR lpCmdLine, int nCmdShow) {
98 #else
99 int main( int argc, char** argv) {
100 #endif
101 int i;
102 int mx, my;
103 Uint8 *keys;
104 Uint8 mb;
105 SDL_Event e;
106 int sdl_flags = SDL_SWSURFACE;
107 int highlight_y = 0;
108 char copyright_line[100];
109 int copyright_line_width;
110 int help, help_line_widths[HELP_LINES], help_line_height, help_offset;
112 Point elektrons[ELEKTRONS];
113 int el;
115 #ifdef WIN32
116 int mb_result;
117 mb_result = DialogBox(hInstance, "CONFIG", 0, (DLGPROC)ConfigDialogProc);
119 switch (mb_result) {
120 case IDYES:
121 sdl_flags |= SDL_FULLSCREEN;
122 break;
123 case IDCANCEL:
124 return 0;
125 break;
126 default:
127 break;
129 #else
130 fprintf( stderr, "Tennix %s\n%s\n%s\n\n", VERSION, COPYRIGHT, URL);
132 bool do_help = false;
133 i = 1;
134 while (i < argc) {
135 /* A poor/lazy man's getopt */
136 #define OPTION_SET(longopt,shortopt) \
137 (strcmp(argv[i], longopt)==0 || strcmp(argv[i], shortopt)==0)
138 #define OPTION_VALUE \
139 ((i+1 < argc)?(argv[i+1]):(NULL))
140 #define OPTION_VALUE_PROCESSED \
141 (i++)
142 if (OPTION_SET("--fullscreen", "-f")) {
143 sdl_flags |= SDL_FULLSCREEN;
145 else if (OPTION_SET("--help", "-h")) {
146 do_help = true;
148 else if (OPTION_SET("--list-joysticks", "-J")) {
149 SDL_Init(SDL_INIT_JOYSTICK);
150 joystick_list();
151 return 0;
153 else if (OPTION_SET("--joystick", "-j")) {
154 SDL_Init(SDL_INIT_JOYSTICK);
155 if (OPTION_VALUE == NULL) {
156 fprintf(stderr, "Error: You need to specify the name of the joystick as parameter.\n");
157 do_help = true;
158 break;
160 if (joystick_open(OPTION_VALUE)==0) {
161 fprintf(stderr, "Warning: Cannot find joystick \"%s\" - Ignored.\n", OPTION_VALUE);
162 break;
164 OPTION_VALUE_PROCESSED;
166 else {
167 fprintf(stderr, "Ignoring unknown option: %s\n", argv[i]);
169 i++;
172 if (do_help == true) {
173 fprintf(stderr, "Usage: %s [--fullscreen|-f] [--help|-h] [--list-joysticks|-J] [--joystick|-j] [joystick name]\n", argv[0]);
174 return 0;
176 #endif
178 sprintf( copyright_line, "Tennix %s -- %s", VERSION, COPYRIGHT);
180 srand( (unsigned)time( NULL));
182 for( el=0; el<ELEKTRONS; el++) {
183 elektrons[el].x = elektrons[el].y = 0;
184 elektrons[el].w = 50+(rand()%120);
185 elektrons[el].h = 10+(rand()%10);
186 elektrons[el].current_x = WIDTH/2;
187 elektrons[el].current_y = HEIGHT/2;
188 elektrons[el].new_x = rand()%WIDTH;
189 elektrons[el].new_y = rand()%HEIGHT;
190 elektrons[el].phase = 4*2*PI*((rand()%1000)/1000.0);
191 elektrons[el].r = 100+rand()%155;
192 elektrons[el].g = 100+rand()%155;
193 elektrons[el].b = 0;
194 elektrons[el].size = 0;
195 elektrons[el].new_size = 5+rand()%10;
198 if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_JOYSTICK) == -1) {
199 fprintf( stderr, "Can't init SDL: %s\n", SDL_GetError());
200 exit( 1);
203 SDL_VideoInfo* vi = (SDL_VideoInfo*)SDL_GetVideoInfo();
204 if( (screen = SDL_SetVideoMode( WIDTH, HEIGHT, vi->vfmt->BitsPerPixel, sdl_flags)) == NULL) {
205 fprintf( stderr, "Can't set video mode: %s\n", SDL_GetError());
206 exit( 1);
209 SDL_WM_SetCaption( "Tennix! SDL", "Tennix");
210 SDL_ShowCursor( SDL_DISABLE);
211 SDL_EnableKeyRepeat (SDL_DEFAULT_REPEAT_DELAY, 1);
213 init_sound();
214 init_graphics();
215 init_joystick();
216 help_text[3] = get_joystick_help();
218 play_sample_background(SOUND_BACKGROUND);
220 copyright_line_width = font_get_string_width( GR_DKC2_FONT, copyright_line);
221 for( help=0; help<HELP_LINES; help++) {
222 help_line_widths[help] = font_get_string_width( GR_SMALLISH_FONT, help_text[help]);
224 help_line_height = get_image_height( GR_SMALLISH_FONT);
226 clear_screen();
227 show_image(GR_MENU, WIDTH/2-get_image_width(GR_MENU)/2, 0, 255);
228 store_screen();
230 i = 0;
231 while( 1) {
232 SDL_PollEvent( &e);
233 if( e.type == SDL_QUIT) {
234 break;
236 keys = SDL_GetKeyState( NULL);
237 mb = SDL_GetMouseState( &mx, &my);
239 if( keys[SDLK_ESCAPE] || keys['q']) {
240 break;
243 if( keys['f']) {
244 SDL_WM_ToggleFullScreen( screen);
247 if( highlight_y) {
248 for( el=0; el<ELEKTRONS; el++) {
249 elektrons[el].new_x = WIDTH/2 - ELEKTRONS_WIDTH;
250 elektrons[el].new_y = highlight_y;
251 if( elektrons[el].new_size >= 5) {
252 elektrons[el].new_size = 1+rand()%4;
257 for( el=0; el<ELEKTRONS; el++) {
258 elektrons[el].current_x += (1.0*(elektrons[el].new_x-elektrons[el].current_x)/ELEKTRON_LAZYNESS);
259 elektrons[el].current_y += (1.0*(elektrons[el].new_y-elektrons[el].current_y)/ELEKTRON_LAZYNESS);
260 if( i%4==0 && elektrons[el].size < elektrons[el].new_size) {
261 elektrons[el].size++;
263 if( i%4==0 && elektrons[el].size > elektrons[el].new_size) {
264 elektrons[el].size--;
266 elektrons[el].phase += 0.02+(rand()%20/100.0);
267 elektrons[el].x = elektrons[el].current_x + ELEKTRONS_WIDTH + elektrons[el].w*cosf(elektrons[el].phase/4);
268 elektrons[el].y = elektrons[el].current_y + elektrons[el].h*sinf(elektrons[el].phase);
271 if( M_POS_START_GAME(mx,my)) {
272 highlight_y = HIGHLIGHT_START_GAME;
273 } else if( M_POS_START_MULTI(mx,my)) {
274 highlight_y = HIGHLIGHT_START_MULTI;
275 /*} else if( M_POS_CREDITS(mx,my)) {
276 highlight_y = HIGHLIGHT_CREDITS;
277 */} else if( M_POS_QUIT(mx,my)) {
278 highlight_y = HIGHLIGHT_QUIT;
279 } else if( highlight_y == 0) {
280 if( i%20 == 0) {
281 for( el=0; el<ELEKTRONS; el++) {
282 elektrons[el].new_size = 5+rand()%10;
285 } else {
286 for( el=0; el<ELEKTRONS; el++) {
287 elektrons[el].new_x = rand()%(WIDTH-ELEKTRONS_WIDTH-elektrons[el].w/2);
288 elektrons[el].new_y = rand()%HEIGHT;
289 elektrons[el].new_size = 5+rand()%10;
291 highlight_y = 0;
294 for( el=0; el<ELEKTRONS; el++) {
295 if( elektrons[el].size > 0) {
296 rectangle( elektrons[el].x, elektrons[el].y, elektrons[el].size, elektrons[el].size, elektrons[el].r, elektrons[el].g, elektrons[el].b);
297 if( elektrons[el].size > 4) {
298 if( highlight_y != 0 || rand()%10 == 0) {
299 //draw_line_faded( elektrons[el].x+elektrons[el].size/2, elektrons[el].y+elektrons[el].size/2, mx+15, my+24, elektrons[el].r/3, elektrons[el].g/3, 0, 0 ,0 ,0);
301 rectangle( elektrons[el].x+2, elektrons[el].y+2, elektrons[el].size-4, elektrons[el].size-4, 0, 0, 0);
306 font_draw_string( GR_DKC2_FONT, copyright_line, (WIDTH-copyright_line_width)/2, HEIGHT-35, i, ((i/150)%ANIMATION_COUNT));
307 for( help=0; help<HELP_LINES; help++) {
308 help_offset = (help_line_height*(HELP_LINES-help)+i/3)%HELP_PHASE;
309 font_draw_string_alpha( GR_SMALLISH_FONT, help_text[help],
310 (WIDTH-help_line_widths[help])/2,
311 HEIGHT/2+45-help_offset,
312 i, ANIMATION_NONE,
313 255.0*fabsf( sinf( help_offset/((float)HELP_PHASE)*M_PI))
316 show_sprite( GR_RACKET, ((mb&SDL_BUTTON( SDL_BUTTON_LEFT))>0)+(((mb&SDL_BUTTON( SDL_BUTTON_RIGHT))>0)*2), 4, mx, my, 255);
317 updatescr();
319 if( mb & SDL_BUTTON( SDL_BUTTON_LEFT)) {
320 if( M_POS_START_GAME(mx,my)) {
321 stop_sample(SOUND_BACKGROUND);
322 play_sample_loop(SOUND_AUDIENCE);
323 start_fade();
324 game( true);
325 SDL_Delay( 150);
326 start_fade();
327 while( SDL_PollEvent( &e));
328 stop_sample(SOUND_AUDIENCE);
329 play_sample_background(SOUND_BACKGROUND);
330 clear_screen();
331 show_image(GR_MENU, WIDTH/2-get_image_width(GR_MENU)/2, 0, 255);
332 store_screen();
334 if( M_POS_START_MULTI(mx,my)) {
335 stop_sample(SOUND_BACKGROUND);
336 play_sample_loop(SOUND_AUDIENCE);
337 start_fade();
338 game( false);
339 SDL_Delay( 150);
340 start_fade();
341 while( SDL_PollEvent( &e));
342 stop_sample(SOUND_AUDIENCE);
343 play_sample_background(SOUND_BACKGROUND);
344 clear_screen();
345 show_image(GR_MENU, WIDTH/2-get_image_width(GR_MENU)/2, 0, 255);
346 store_screen();
348 if( M_POS_CREDITS(mx,my)) {
349 //introimage( "data/credits.bmp");
351 if( M_POS_QUIT(mx,my)) {
352 stop_sample(SOUND_BACKGROUND);
353 break;
356 i++;
357 SDL_Delay( 4);
360 start_fade();
361 store_screen();
362 while( is_fading()) {
363 clear_screen();
364 updatescr();
365 SDL_Delay( 10);
368 uninit_graphics();
369 uninit_joystick();
371 SDL_Quit();
372 return 0;