⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sdl.c

📁 LTris a tetris clone for Linux
💻 C
📖 第 1 页 / 共 3 页
字号:
/***************************************************************************                          sdl.c  -  description                             -------------------    begin                : Thu Apr 20 2000    copyright            : (C) 2000 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 <SDL.h>#include <stdlib.h>#include <string.h>#include "sdl.h"#ifdef USE_PNG#include <png.h>#endifextern int  term_game;Sdl sdl;SDL_Cursor *empty_cursor = 0;SDL_Cursor *std_cursor = 0;/*====================================================================Default video modes. The first value is the id and indicatesif a mode is a standard video mode. If the mode was created bydirectly by video_mode() this id is set to -1. The very lastvalue indicates if this is a valid mode and is checked byinit_sdl(). Init_sdl sets the available desktop bit depth.====================================================================*/int const mode_count = 2;Video_Mode modes[] = {    { 0, "640x480x16 Window",     640, 480, BITDEPTH, SDL_SWSURFACE, 0 },    { 1, "640x480x16 Fullscreen", 640, 480, BITDEPTH, SDL_SWSURFACE | SDL_FULLSCREEN, 0 },};Video_Mode *def_mode = &modes[0]; /* default resolution */Video_Mode cur_mode; /* current video mode set in set_video_mode *//* timer */int cur_time, last_time;/* sdl surface */#ifdef USE_PNG/* loads an image from png file and returns surface * or NULL in case of error; * you can get additional information with SDL_GetError * * stolen from SDL_image: * * Copyright (C) 1999  Sam Lantinga * * Sam Lantinga * 5635-34 Springhouse Dr. * Pleasanton, CA 94588 (USA) * slouken@devolution.com */SDL_Surface *load_png( const char *file ){	FILE		*volatile fp = NULL;	SDL_Surface	*volatile surface = NULL;	png_structp	png_ptr = NULL;	png_infop	info_ptr = NULL;	png_bytep	*volatile row_pointers = NULL;	png_uint_32	width, height;	int		bit_depth, color_type, interlace_type;	Uint32		Rmask;	Uint32		Gmask;	Uint32		Bmask;	Uint32		Amask;	SDL_Palette	*palette;	int		row, i;	volatile int	ckey = -1;	png_color_16	*transv;	/* create the PNG loading context structure */	png_ptr = png_create_read_struct( PNG_LIBPNG_VER_STRING,					  NULL, NULL, NULL );	if( png_ptr == NULL ) {		SDL_SetError( "Couldn't allocate memory for PNG file" );		goto done;	}	/* allocate/initialize the memory for image information.  REQUIRED. */	info_ptr = png_create_info_struct( png_ptr );	if( info_ptr == NULL ) {		SDL_SetError( "Couldn't create image information for PNG file" );		goto done;	}	/* set error handling if you are using setjmp/longjmp method (this is	 * the normal method of doing things with libpng).  REQUIRED unless you	 * set up your own error handlers in png_create_read_struct() earlier.	 */	if( setjmp( png_ptr->jmpbuf ) ) {		SDL_SetError( "Error reading the PNG file." );		goto done;	}	/* open file */	fp = fopen( file, "r" );	if( fp == NULL ) {		SDL_SetError( "Could not open png file." );		goto done;	}	png_init_io( png_ptr, fp );	/* read PNG header info */	png_read_info( png_ptr, info_ptr );	png_get_IHDR( png_ptr, info_ptr, &width, &height, &bit_depth,			&color_type, &interlace_type, NULL, NULL );	/* tell libpng to strip 16 bit/color files down to 8 bits/color */	png_set_strip_16( png_ptr );	/* extract multiple pixels with bit depths of 1, 2, and 4 from a single	 * byte into separate bytes (useful for paletted and grayscale images).	 */	png_set_packing( png_ptr );	/* scale greyscale values to the range 0..255 */	if( color_type == PNG_COLOR_TYPE_GRAY )		png_set_expand( png_ptr );	/* for images with a single "transparent colour", set colour key;	   if more than one index has transparency, use full alpha channel */	if( png_get_valid( png_ptr, info_ptr, PNG_INFO_tRNS ) ) {	        int num_trans;		Uint8 *trans;		png_get_tRNS( png_ptr, info_ptr, &trans, &num_trans,			      &transv );		if( color_type == PNG_COLOR_TYPE_PALETTE ) {			if( num_trans == 1 ) {				/* exactly one transparent value: set colour key */				ckey = trans[0];			} else				png_set_expand( png_ptr );		} else		    ckey = 0; /* actual value will be set later */	}	if( color_type == PNG_COLOR_TYPE_GRAY_ALPHA )		png_set_gray_to_rgb( png_ptr );	png_read_update_info( png_ptr, info_ptr );	png_get_IHDR( png_ptr, info_ptr, &width, &height, &bit_depth,			&color_type, &interlace_type, NULL, NULL );	/* allocate the SDL surface to hold the image */	Rmask = Gmask = Bmask = Amask = 0 ;	if( color_type != PNG_COLOR_TYPE_PALETTE ) {		if( SDL_BYTEORDER == SDL_LIL_ENDIAN ) {			Rmask = 0x000000FF;			Gmask = 0x0000FF00;			Bmask = 0x00FF0000;			Amask = (info_ptr->channels == 4) ? 0xFF000000 : 0;		} else {		        int s = (info_ptr->channels == 4) ? 0 : 8;			Rmask = 0xFF000000 >> s;			Gmask = 0x00FF0000 >> s;			Bmask = 0x0000FF00 >> s;			Amask = 0x000000FF >> s;		}	}	surface = SDL_AllocSurface( SDL_SWSURFACE, width, height,			bit_depth * info_ptr->channels, Rmask, Gmask, Bmask, Amask );	if( surface == NULL ) {		SDL_SetError( "Out of memory" );		goto done;	}	if( ckey != -1 ) {		if( color_type != PNG_COLOR_TYPE_PALETTE )			/* FIXME: should these be truncated or shifted down? */			ckey = SDL_MapRGB( surface->format,					   (Uint8)transv->red,					   (Uint8)transv->green,					   (Uint8)transv->blue );		SDL_SetColorKey( surface, SDL_SRCCOLORKEY, ckey );	}	/* create the array of pointers to image data */	row_pointers = (png_bytep*)malloc( sizeof( png_bytep ) * height );	if( ( row_pointers == NULL ) ) {		SDL_SetError( "Out of memory" );		SDL_FreeSurface( surface );		surface = NULL;		goto done;	}	for( row = 0; row < (int)height; row++ ) {		row_pointers[row] = (png_bytep)				(Uint8*)surface->pixels + row * surface->pitch;	}	/* read the entire image in one go */	png_read_image( png_ptr, row_pointers );	/* read rest of file, get additional chunks in info_ptr - REQUIRED */	png_read_end( png_ptr, info_ptr );	/* load the palette, if any */	palette = surface->format->palette;	if( palette ) {	    if( color_type == PNG_COLOR_TYPE_GRAY ) {		palette->ncolors = 256;		for( i = 0; i < 256; i++ ) {		    palette->colors[i].r = i;		    palette->colors[i].g = i;		    palette->colors[i].b = i;		}	    } else if( info_ptr->num_palette > 0 ) {		palette->ncolors = info_ptr->num_palette;		for( i = 0; i < info_ptr->num_palette; ++i ) {		    palette->colors[i].b = info_ptr->palette[i].blue;		    palette->colors[i].g = info_ptr->palette[i].green;		    palette->colors[i].r = info_ptr->palette[i].red;		}	    }	}done:	/* clean up and return */	png_destroy_read_struct( &png_ptr, info_ptr ? &info_ptr : (png_infopp)0,								  (png_infopp)0 );	if( row_pointers )		free( row_pointers );	if( fp )		fclose( fp );	return surface;}#endif/* return full path of bitmap */inline void get_full_bmp_path( char *full_path, char *file_name ){    sprintf(full_path,  "%s/gfx/%s", SRC_DIR, file_name );}/*    load a surface from file putting it in soft or hardware mem*/SDL_Surface* load_surf(char *fname, int f){    SDL_Surface *buf;    SDL_Surface *new_sur;    char path[ 512 ];    SDL_PixelFormat *spf;#ifdef USE_PNG    char png_name[32];#endif#ifdef USE_PNG    /* override file name as all graphics were changed from    bitmap to png so the extension must be corrected */    memset( png_name, 0, sizeof( png_name ) );    strncpy( png_name, fname, strlen( fname ) - 4 );    strcat( png_name, ".png" );    get_full_bmp_path( path, png_name );    buf = load_png( path );#else    get_full_bmp_path( path, fname );    buf = SDL_LoadBMP( path );#endif    if ( buf == 0 ) {        fprintf( stderr, "load_surf: file '%s' not found or not enough memory\n", path );        if ( f & SDL_NONFATAL )            return 0;        else            exit( 1 );    }/*    if ( !(f & SDL_HWSURFACE) ) {        SDL_SetColorKey( buf, SDL_SRCCOLORKEY, 0x0 );        return buf;    }    new_sur = create_surf(buf->w, buf->h, f);    SDL_BlitSurface(buf, 0, new_sur, 0);    SDL_FreeSurface(buf);*/    spf = SDL_GetVideoSurface()->format;    new_sur = SDL_ConvertSurface( buf, spf, f );    SDL_FreeSurface( buf );    SDL_SetColorKey( new_sur, SDL_SRCCOLORKEY, 0x0 );    SDL_SetAlpha( new_sur, 0, 0 ); /* no alpha */    return new_sur;}/*    create an surface    MUST NOT BE USED IF NO SDLSCREEN IS SET*/SDL_Surface* create_surf(int w, int h, int f){    SDL_Surface *sur;    SDL_PixelFormat *spf = SDL_GetVideoSurface()->format;    if ((sur = SDL_CreateRGBSurface(f, w, h, spf->BitsPerPixel, spf->Rmask, spf->Gmask, spf->Bmask, spf->Amask)) == 0) {        fprintf(stderr, "create_surf: not enough memory to create surface...\n");        exit(1);    }/*    if (f & SDL_HWSURFACE && !(sur->flags & SDL_HWSURFACE))        fprintf(stderr, "unable to create surface (%ix%ix%i) in hardware memory...\n", w, h, spf->BitsPerPixel);*/    SDL_SetColorKey(sur, SDL_SRCCOLORKEY, 0x0);    SDL_SetAlpha(sur, 0, 0); /* no alpha */    return sur;}/* * Free a surface if != NULL and set pointer to NULL */void free_surf( SDL_Surface **surf ){    if ( *surf ) SDL_FreeSurface( *surf );    *surf = 0;}/*    lock surface*/inline void lock_surf(SDL_Surface *sur){    if (SDL_MUSTLOCK(sur))        SDL_LockSurface(sur);}/*    unlock surface*/inline void unlock_surf(SDL_Surface *sur){    if (SDL_MUSTLOCK(sur))        SDL_UnlockSurface(sur);}/*    blit surface with destination DEST and source SOURCE using it's actual alpha and color key settings*/void blit_surf(void){#ifdef SDL_1_1_5    if (sdl.s.s->flags & SDL_SRCALPHA)        SDL_SetAlpha(sdl.s.s, SDL_SRCALPHA, 255 - sdl.s.s->format->alpha);#endif    SDL_BlitSurface(sdl.s.s, &sdl.s.r, sdl.d.s, &sdl.d.r);#ifdef SDL_1_1_5    if (sdl.s.s->flags & SDL_SRCALPHA)        SDL_SetAlpha(sdl.s.s, SDL_SRCALPHA, 255 - sdl.s.s->format->alpha);#endif}/*    do an alpha blit*/void alpha_blit_surf(int alpha){ #ifdef SDL_1_1_5    SDL_SetAlpha(sdl.s.s, SDL_SRCALPHA, 255 - alpha);#else    SDL_SetAlpha(sdl.s.s, SDL_SRCALPHA, alpha);#endif    SDL_BlitSurface(sdl.s.s, &sdl.s.r, sdl.d.s, &sdl.d.r);    SDL_SetAlpha(sdl.s.s, 0, 0);}/*    fill surface with color c*/void fill_surf(int c){    SDL_FillRect(sdl.d.s, &sdl.d.r, SDL_MapRGB(sdl.d.s->format, c >> 16, (c >> 8) & 0xFF, c & 0xFF));}/* set clipping rect */void set_surf_clip( SDL_Surface *surf, int x, int y, int w, int h ){#ifdef SDL_1_1_5    SDL_Rect rect = { x, y, w, h };    if ( w == h || h == 0 )        SDL_SetClipRect( surf, 0 );    else        SDL_SetClipRect( surf, &rect );#else    SDL_SetClipping( surf, x, y, w, h );#endif}/* set pixel */Uint32 set_pixel( SDL_Surface *surf, int x, int y, int pixel ){    int pos = 0;    pos = y * surf->pitch + x * surf->format->BytesPerPixel;    memcpy( surf->pixels + pos, &pixel, surf->format->BytesPerPixel );

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -