📄 tetris.c
字号:
/*************************************************************************** tetris.c - description ------------------- begin : Tue Dec 25 2001 copyright : (C) 2001 by Michael Speck email : kulkanie@gmx.net ***************************************************************************//*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/#include "ltris.h"#include "event.h"#include "chart.h"#include "bowl.h"#include "shrapnells.h"#include "tetris.h"SDL_Surface *blocks = 0;SDL_Surface *logo = 0;Font *font = 0, *large_font = 0;SDL_Surface *qmark = 0; /* question mark */SDL_Surface *bkgnd = 0; /* background + 3dframes */SDL_Surface *offscreen = 0; /* offscreen: background + blocks */int last_bkgnd_id = -99; /* last background chosen */#ifdef SOUNDSound_Chunk *wav_click = 0;#endifBowl *bowls[BOWL_COUNT]; /* all bowls */int *next_blocks, next_blocks_size = 0; /* buffered game blocks for games where all players will receive the same blocks */extern Sdl sdl;extern Config config;extern int term_game;/* a game type index is mapped to the specified highscore */char *chart_map[8] = { "Demo", "Classic", "Figures", "Two-Player", "Two-Player", "Three-Player", "Three-Player", "Three-Player"};/*====================================================================Locals====================================================================*//*====================================================================Draw the tetris logo to the offscreen.====================================================================*/void tetris_draw_logo(){ int x = 460, y = 100; draw_3dframe( offscreen, x - logo->w / 2 - 4, y - logo->h / 2 - 4, logo->w + 8, logo->h + 8, 6 ); DEST( offscreen, x - logo->w / 2, y - logo->h / 2, logo->w, logo->h ); FULL_SOURCE( logo ); blit_surf();}/*====================================================================Request confirmation.====================================================================*/enum{ CONFIRM_YES_NO, CONFIRM_ANY_KEY, CONFIRM_PAUSE };void draw_confirm_screen( Font *font, SDL_Surface *buffer, char *str ){ FULL_DEST(sdl.screen); fill_surf(0x0); font->align = ALIGN_X_CENTER | ALIGN_Y_CENTER; write_text(font, sdl.screen, sdl.screen->w / 2, sdl.screen->h / 2, str, 0);}int confirm( Font *font, char *str, int type ){ SDL_Event event; int go_on = 1; int ret = 0; SDL_Surface *buffer = create_surf(sdl.screen->w, sdl.screen->h, SDL_SWSURFACE); SDL_SetColorKey(buffer, 0, 0);#ifdef SOUND sound_play( wav_click );#endif FULL_DEST(buffer); FULL_SOURCE(sdl.screen); blit_surf(); draw_confirm_screen( font, buffer, str ); refresh_screen( 0, 0, 0, 0 ); while (go_on && !term_game) { SDL_WaitEvent(&event); /* TEST */ switch ( event.type ) { case SDL_QUIT: term_game = 1; break; case SDL_KEYUP: if ( type == CONFIRM_ANY_KEY ) { ret = 1; go_on = 0; break; } else if ( type == CONFIRM_PAUSE ) { if ( event.key.keysym.sym == SDLK_p ) { ret = 1; go_on = 0; break; } else if ( event.key.keysym.sym == SDLK_f ) { config.fullscreen = !config.fullscreen; set_video_mode( std_video_mode( config.fullscreen ) ); draw_confirm_screen( font, buffer, str ); refresh_screen( 0, 0, 0, 0 ); } } else switch (event.key.keysym.sym) { case SDLK_y: case SDLK_SPACE: go_on = 0; ret = 1; break; case SDLK_ESCAPE: case SDLK_RETURN: case SDLK_n: go_on = 0; ret = 0; default: break; } break; } }#ifdef SOUND sound_play( wav_click );#endif FULL_DEST(sdl.screen); FULL_SOURCE(buffer); blit_surf(); refresh_screen( 0, 0, 0, 0 ); SDL_FreeSurface(buffer); reset_timer(); return ret;}/*====================================================================Do a new background to bkgnd and add all nescessary frames for thespecified gametype in config::gametype.Id == -1 means to use a random background.Copy result to offscreen and screen. Draws bowl contents.====================================================================*/enum { BACK_COUNT = 6 };void tetris_recreate_bkgnd( int id ){ SDL_Surface *pic = 0; char name[32]; int i, j; /* load and wallpaper background */ if ( id == -1 ) { do { id = rand() % BACK_COUNT; } while ( id == last_bkgnd_id ); last_bkgnd_id = id; } FULL_DEST( bkgnd ); fill_surf( 0x0 ); /* load background */ sprintf( name, "back%i.bmp", id ); if ( ( pic = load_surf( name, SDL_SWSURFACE | SDL_NONFATAL ) ) != 0 ) { for ( i = 0; i < bkgnd->w; i += pic->w ) for ( j = 0; j < bkgnd->h; j += pic->h ) { DEST( bkgnd, i, j, pic->w, pic->h ); SOURCE( pic, 0, 0 ); blit_surf(); } SDL_FreeSurface( pic ); } /* let the bowls contribute to the background :) */ for ( i = 0; i < BOWL_COUNT; i++ ) if ( bowls[i] ) bowl_draw_frames( bowls[i] ); /* draw to offscreen */ FULL_DEST( offscreen ); FULL_SOURCE( bkgnd ); blit_surf(); /* add logo if place */ if ( config.gametype <= 2 ) tetris_draw_logo(); /* draw bowl contents */ for ( i = 0; i < BOWL_COUNT; i++ ) if ( bowls[i] ) bowl_draw_contents( bowls[i] ); /* put offscreen to screen */ FULL_DEST( sdl.screen ); FULL_SOURCE( offscreen ); blit_surf();}/*====================================================================Publics====================================================================*//*====================================================================Load/delete all tetris resources.====================================================================*/void tetris_create(){ logo = load_surf( "logo.bmp", SDL_SWSURFACE ); SDL_SetColorKey( logo, SDL_SRCCOLORKEY, get_pixel( logo, 0, 0 ) ); blocks = load_surf( "blocks.bmp", SDL_SWSURFACE ); qmark = load_surf( "quest.bmp", SDL_SWSURFACE ); SDL_SetColorKey( qmark, SDL_SRCCOLORKEY, get_pixel( qmark, 0, 0 ) ); font = load_fixed_font( "f_small_yellow.bmp", 32, 96, 8 ); large_font = load_fixed_font( "f_white.bmp", 32, 96, 10 ); bkgnd = create_surf( sdl.screen->w, sdl.screen->h, SDL_SWSURFACE ); SDL_SetColorKey( bkgnd, 0, 0 ); offscreen = create_surf( sdl.screen->w, sdl.screen->h, SDL_SWSURFACE ); SDL_SetColorKey( offscreen, 0, 0 ); bowl_load_figures(); bowl_init_block_masks();#ifdef SOUND wav_click = sound_chunk_load( "click.wav" );#endif}void tetris_delete(){ if ( logo ) SDL_FreeSurface( logo ); logo = 0; if ( blocks ) SDL_FreeSurface( blocks ); blocks = 0; if ( qmark ) SDL_FreeSurface( qmark ); qmark = 0; free_font( &font ); free_font( &large_font ); if ( offscreen ) SDL_FreeSurface( offscreen ); offscreen = 0; if ( bkgnd ) SDL_FreeSurface( bkgnd ); bkgnd = 0;#ifdef SOUND if ( wav_click ) sound_chunk_free( wav_click ); wav_click = 0;#endif }/*====================================================================Initiate/clear a new game from config data.After tetris_init() the screen is drawn completely though notupdated to use the fade effect.====================================================================*/int tetris_init(){ /* create next block list if desired and multiplayer */ if ( config.same_blocks_for_all && !config.expert && config.gametype >= 3 ) { next_blocks_size = NEXT_BLOCKS_CHUNK_SIZE; next_blocks = calloc( next_blocks_size, sizeof(int) ); fill_int_array_rand(next_blocks, 0,next_blocks_size, 0,BLOCK_COUNT-1); } /* create bowls according to the gametype */ switch ( config.gametype ) { case GAME_DEMO: bowls[0] = bowl_create( 70, 0, 460, 300, blocks, qmark, "Demo", 0 ); break; case GAME_CLASSIC: case GAME_FIGURES: bowls[0] = bowl_create( 70, 0, 460, 300, blocks, qmark, config.player1.name, &config.player1.controls ); break; case GAME_VS_HUMAN: case GAME_VS_CPU: if ( config.center_preview ) { bowls[0] = bowl_create( 20, 0, 273, 200, blocks, qmark, config.player1.name, &config.player1.controls ); if ( config.gametype == GAME_VS_HUMAN ) bowls[1] = bowl_create( 420, 0, 367, 200, blocks, qmark, config.player2.name, &config.player2.controls ); else bowls[1] = bowl_create( 420, 0, 367, 200, blocks, qmark, "CPU-1", 0 ); } else { bowls[0] = bowl_create( 20, 0, 290, 340, blocks, qmark, config.player1.name, &config.player1.controls ); if ( config.gametype == GAME_VS_HUMAN ) bowls[1] = bowl_create( 420, 0, 350, 60, blocks, qmark, config.player2.name, &config.player2.controls ); else bowls[1] = bowl_create( 420, 0, 350, 60, blocks, qmark, "CPU-1", 0 ); } break; case GAME_VS_HUMAN_HUMAN: case GAME_VS_HUMAN_CPU: case GAME_VS_CPU_CPU: bowls[0] = bowl_create( 10, 0, -1, -1, blocks, qmark, config.player1.name, &config.player1.controls ); if ( config.gametype != GAME_VS_CPU_CPU ) bowls[1] = bowl_create( 220, 0, -1, -1, blocks, qmark, config.player2.name, &config.player2.controls ); else bowls[1] = bowl_create( 220, 0, -1, -1, blocks, qmark, "CPU-1", 0 ); if ( config.gametype == GAME_VS_HUMAN_HUMAN ) bowls[2] = bowl_create( 430, 0, -1, -1, blocks, qmark, config.player3.name, &config.player3.controls ); else bowls[2] = bowl_create( 430, 0, -1, -1, blocks, qmark, "CPU-2", 0 ); break; } /* background */ tetris_recreate_bkgnd( 1 ); /* shrapnells */ shrapnells_init();
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -