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

📄 glide.cpp

📁 著名SFC模拟器Snes9x的源代码。
💻 CPP
字号:
#include <math.h>#include <glide.h>#include <signal.h>#include <setjmp.h>#include "snes9x.h"#include "gfx.h"#include "3d.h"GlideData Glide;#define TEXTURE_SIZE 256static uint16 *texture_download_buffer = NULL;static GrTexInfo texture_info;static int texture_mem_start [4];void S9xGlideDeinit ();static void S9xGlideCalcSquare (int snes_width, int snes_height, 				int x, int y, int width, int height,				GrVertex *square){    float virtual_height;    float virtual_width;    float virtual_x;    float virtual_y;#if 0    float snes_aspect_ratio = snes_width / (float) snes_height;    float voodoo_aspect_ratio = Glide.voodoo_width / (float) Glide.voodoo_height;    if (snes_aspect_ratio < voodoo_aspect_ratio)    {	virtual_height = (float) Glide.voodoo_height;	virtual_width = virtual_height * snes_aspect_ratio;	virtual_x = ((float) Glide.voodoo_width - virtual_width) / 2.0;	virtual_y = 0.0;    }    else    {	virtual_width = Glide.voodoo_width;	virtual_height = virtual_width / snes_aspect_ratio;	virtual_x = 0;	virtual_y = (Glide.voodoo_height - virtual_height) / 2.0;    }#endif    virtual_x = 0;    virtual_y = 0;    virtual_width = Glide.voodoo_width;    virtual_height = Glide.voodoo_height;    for (int i = 0; i < 4; i++)    {	square [i].oow = 1.0;	square [i].ooz = 65535.0;	square [i].tmuvtx [0].oow = 1.0;    }    square [0].tmuvtx [0].sow = 0.0;    square [0].tmuvtx [0].tow = 0.0;    square [1].tmuvtx [0].sow = width;    square [1].tmuvtx [0].tow = 0.0;    square [2].tmuvtx [0].sow = width;    square [2].tmuvtx [0].tow = height;    square [3].tmuvtx [0].sow = 0.0;    square [3].tmuvtx [0].tow = height;	    float texture_width_percent;    float texture_height_percent;    if ((texture_width_percent = virtual_width * TEXTURE_SIZE / snes_width) > virtual_width)	texture_width_percent = virtual_width;    if ((texture_height_percent = virtual_height * TEXTURE_SIZE / snes_height) > virtual_height)	texture_height_percent = virtual_height;    square [0].x = virtual_x + x * texture_width_percent;    square [0].y = virtual_y + y * texture_height_percent;    square [1].x = virtual_x + (x + 1) * texture_width_percent;    square [1].y = virtual_y + y * texture_height_percent;    square [2].x = virtual_x + (x + 1) * texture_width_percent;    square [2].y = virtual_y + (y + 1) * texture_height_percent;    square [3].x = virtual_x + x * texture_width_percent;    square [3].y = virtual_y + (y + 1) * texture_height_percent;}static void S9xGlideInitTextures (){    grColorCombine (GR_COMBINE_FUNCTION_SCALE_OTHER,		    GR_COMBINE_FACTOR_ONE,		    GR_COMBINE_LOCAL_NONE,		    GR_COMBINE_OTHER_TEXTURE,		    FXFALSE);    grTexCombine (GR_TMU0,		  GR_COMBINE_FUNCTION_LOCAL,		  GR_COMBINE_FACTOR_NONE,		  GR_COMBINE_FUNCTION_NONE,		  GR_COMBINE_FACTOR_NONE,		  FXFALSE, 		  FXFALSE);    grTexMipMapMode (GR_TMU0,		     GR_MIPMAP_DISABLE,		     FXFALSE);    grTexClampMode (GR_TMU0,		    GR_TEXTURECLAMP_CLAMP,		    GR_TEXTURECLAMP_CLAMP);    grTexFilterMode (GR_TMU0, 		     GR_TEXTUREFILTER_BILINEAR,		     GR_TEXTUREFILTER_BILINEAR);    /* XXX: trilinear */    grTexCombine (GR_TMU0,                  GR_COMBINE_FUNCTION_BLEND_LOCAL,                  GR_COMBINE_FACTOR_LOD_FRACTION,                  GR_COMBINE_FUNCTION_BLEND_LOCAL,                  GR_COMBINE_FACTOR_LOD_FRACTION,                  FXFALSE,                  FXFALSE);    texture_info.smallLod = GR_LOD_256;    texture_info.largeLod = GR_LOD_256;    texture_info.aspectRatio = GR_ASPECT_1x1;    texture_info.format = GR_TEXFMT_RGB_565;    Glide.texture.smallLod = GR_LOD_8;    Glide.texture.largeLod = GR_LOD_8;    Glide.texture.aspectRatio = GR_ASPECT_1x1;    Glide.texture.format = GR_TEXFMT_RGB_565;    Glide.texture_mem_size = grTexTextureMemRequired (GR_MIPMAPLEVELMASK_BOTH,						      &Glide.texture);    Glide.texture_mem_start = grTexMinAddress (GR_TMU0);    int texture_mem_size = grTexTextureMemRequired (GR_MIPMAPLEVELMASK_BOTH,						    &texture_info);    int address = grTexMinAddress (GR_TMU0);    // At maximum SNES resolution (512x478) four seperate Voodoo textures will    // be needed since the maximum texture size on Voodoo cards is 256x256.        for (int t = 0; t < 4; t++)    {	texture_mem_start [t] = address;	address += texture_mem_size;    }        texture_download_buffer = (uint16 *) malloc (texture_mem_size);    for (int i = 0; i < 4; i++)    {	Glide.sq [i].oow = 1.0;	Glide.sq [i].ooz = 65535.0;	Glide.sq [i].tmuvtx [0].oow = 1.0;    }    Glide.x_offset = 0.0;    Glide.y_offset = 0.0;    // XXX: Do this when the SNES screen resolution is known.    Glide.x_scale = Glide.voodoo_width * 8.0 / 256;    Glide.y_scale = Glide.voodoo_height * 8.0 / 224;}static jmp_buf restart_point;static void SegfaultHandler (int){    printf ("\n\No permission to access 3Dfx hardware or 3Dfx hardware not present.\n");    Glide.voodoo_present = FALSE;    longjmp (restart_point, 1);}bool8 S9xGlideInit (){    static GrHwConfiguration hwconfig;    // XXX:    GrScreenResolution_t resolution = GR_RESOLUTION_640x480;    GrScreenRefresh_t refresh_rate = GR_REFRESH_100Hz;    Glide.voodoo_present = TRUE;    setjmp (restart_point);    if (!Glide.voodoo_present)    {	signal (SIGSEGV, SIG_DFL);	return (FALSE);    }    signal (SIGSEGV, (SIG_PF) SegfaultHandler);    grGlideInit ();    if (grSstQueryHardware (&hwconfig))    {	grSstSelect (0);	if (grSstWinOpen (0, resolution, refresh_rate, GR_COLORFORMAT_ABGR,			  GR_ORIGIN_UPPER_LEFT, 2, 1))	{	    grBufferClear (0, 0, GR_ZDEPTHVALUE_FARTHEST);	    Glide.voodoo_width = grSstScreenWidth ();	    Glide.voodoo_height = grSstScreenHeight ();	    S9xGlideInitTextures ();	    signal (SIGSEGV, (SIG_PF) S9xGlideDeinit);	    return (TRUE);	}    }        Glide.voodoo_present = FALSE;    signal (SIGSEGV, SIG_DFL);    return (FALSE);}void S9xGlideDeinit (){    free ((char *) texture_download_buffer);    grGlideShutdown();}void S9xGlidePutImage (int snes_width, int snes_height){    GrVertex square [4];    grBufferClear (0, 0, GR_ZDEPTHVALUE_FARTHEST);    if (snes_width <= TEXTURE_SIZE && snes_height <= TEXTURE_SIZE)    {	// Special case 256x224 and 256x239 SNES resolutions.	texture_info.data = (void *) GFX.Screen;	grTexDownloadMipMapLevel (GR_TMU0, texture_mem_start [0],				  GR_LOD_256, GR_LOD_256, GR_ASPECT_1x1,				  GR_TEXFMT_RGB_565,				  GR_MIPMAPLEVELMASK_BOTH,				  (void *) GFX.Screen);	grTexSource (GR_TMU0, texture_mem_start [0],		     GR_MIPMAPLEVELMASK_BOTH, &texture_info);	S9xGlideCalcSquare (snes_width, snes_height, 0, 0, 			    snes_width, snes_height, square);	grDrawTriangle (&square [0], &square [3], &square [2]);	grDrawTriangle (&square [0], &square [1], &square [2]);    }    else    {	// Have to chop the rendered SNES screen into a maximum 256x256 size	// chunks because that's all the Voodoo card can cope with.	int t = 0;	int vert_squares = (snes_height + (TEXTURE_SIZE - 1)) / TEXTURE_SIZE;	int horiz_squares = (snes_width + (TEXTURE_SIZE - 1)) / TEXTURE_SIZE;	texture_info.data = (void *) texture_download_buffer;	for (int y = 0; y < vert_squares; y++)	{	    for (int x = 0; x < horiz_squares; x++, t++)	    {		int square_height = y != vert_squares - 1 ? TEXTURE_SIZE : 				    snes_height - (TEXTURE_SIZE * y);		int square_width = x != horiz_squares - 1 ? TEXTURE_SIZE :				   snes_width - (TEXTURE_SIZE * x);		int offset = x * TEXTURE_SIZE * sizeof (uint16) +			     y * TEXTURE_SIZE * GFX.Pitch;		for (int l = 0; l < square_height; l++)		{		    memmove ((void *) (texture_download_buffer + l * 256),			     GFX.Screen + l * GFX.RealPitch + offset,			     sizeof (uint16) * 256);		}		grTexDownloadMipMapLevel (GR_TMU0, texture_mem_start [t],					  GR_LOD_256, GR_LOD_256, 					  GR_ASPECT_1x1,					  GR_TEXFMT_RGB_565,					  GR_MIPMAPLEVELMASK_BOTH,					  (void *) texture_download_buffer);		grTexSource (GR_TMU0, texture_mem_start [t],			     GR_MIPMAPLEVELMASK_BOTH, &texture_info);		S9xGlideCalcSquare (snes_width, snes_height, x, y,				    square_width, square_height,				    square);		grDrawTriangle (&square [0], &square [3], &square [2]);		grDrawTriangle (&square [0], &square [1], &square [2]);	    }	}    }    grBufferSwap(1);}bool8 S9xGlideEnable (bool8 enable){    static uint32 previous_graphic_format = RGB565;    static bool8 previous_sixteenbit = FALSE;    extern uint32 current_graphic_format;    if (Settings.GlideEnable != enable)    {	if (enable)	{	    if (S9xGlideInit ())	    {		previous_graphic_format = current_graphic_format;		previous_sixteenbit = Settings.SixteenBit;		S9xGraphicsDeinit ();		S9xSetRenderPixelFormat (RGB565);		Settings.SixteenBit = TRUE;		Settings.Transparency = TRUE;		S9xGraphicsInit ();		Settings.GlideEnable = TRUE;	    }	}	else	{	    Settings.GlideEnable = FALSE;	    S9xGlideDeinit ();	    S9xGraphicsDeinit ();	    S9xSetRenderPixelFormat (previous_graphic_format);	    if (!(Settings.SixteenBit = previous_sixteenbit))		Settings.Transparency = FALSE;	    S9xGraphicsInit ();	}    }    return (TRUE);}

⌨️ 快捷键说明

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