int glide64InitGfx(void) { rdp_reset (); if (!grSstWinOpen()) { ERRLOG("Error setting display mode"); return false; } // get the # of TMUs available voodoo.tex_max_addr = grTexMaxAddress(GR_TMU0); grStipplePattern(settings.stipple_pattern); InitCombine(); if (settings.fog) { guFogGenerateLinear(0.0f, 255.0f); } else settings.fog = false; grDepthBufferMode (GR_DEPTHBUFFER_ZBUFFER); grDepthBufferFunction(GR_CMP_LESS); grDepthMask(FXTRUE); settings.res_x = settings.scr_res_x; settings.res_y = settings.scr_res_y; ChangeSize(); guLoadTextures (); ClearCache (); return true; }
int main(int argc, char **argv) { char match; char **remArgs; int rv = -1; GrScreenResolution_t resolution = GR_RESOLUTION_640x480; float scrWidth = 640.0f; float scrHeight = 480.0f; int frames = -1; FxBool scrgrab = FXFALSE; char filename[256]; FxU32 wrange[2]; FxU32 multiBaseMode = 0, minTexSize = 1, maxTexSize = 256; const TlVertex3D srcVerts[4] = { { -0.5f, 0.0f, 0.5f, 1.0f, 0.0f, 0.0f }, { 0.5f, 0.0f, 0.5f, 1.0f, 1.0f, 0.0f }, { -0.5f, 0.0f, -0.5f, 1.0f, 0.0f, 1.0f }, { 0.5f, 0.0f, -0.5f, 1.0f, 1.0f, 1.0f } }; /* Initialize Glide */ grGlideInit(); if ((hwconfig = tlVoodooType()) == 0) { printf("Error getting 3Dfx hw type.\n"); exit(-1); } /* Process Command Line Arguments */ while(rv = tlGetOpt(argc, argv, "dmnrx", &match, &remArgs)) { if (rv == -1) { printf("Unrecognized command line argument\n"); printf("%s %s\n", name, usage); printf("Available resolutions:\n%s\n", tlGetResolutionList()); exit(-1); } switch(match) { case 'd': scrgrab = FXTRUE; if (scrgrab) { frames = 1; strcpy(filename, remArgs[0]); } break; case 'm': /* Do we want to test larger sizes if the hw supports it? */ if (!grGet(GR_MAX_TEXTURE_SIZE, sizeof(maxTexSize), (FxI32 *)&maxTexSize)) { printf("grGet(GR_MAX_TEXTURE_SIZE) failed.\n"); exit(-1); } break; case 'n': if (remArgs[0] != NULL) frames = atoi(remArgs[0]); break; case 'r': if (remArgs[0] != NULL) resolution = tlGetResolutionConstant(remArgs[0], &scrWidth, &scrHeight); break; } } tlSetScreen(scrWidth, scrHeight); version = grGetString(GR_VERSION); printf("%s:\n%s\n", name, purpose); printf("%s\n", version); printf("Resolution: %s\n", tlGetResolutionString(resolution)); if (frames == -1) { printf("Press A Key To Begin Test.\n"); tlGetCH(); } grSstSelect(0); if (grSstWinOpen(tlGethWnd(), resolution, GR_REFRESH_60Hz, GR_COLORFORMAT_ABGR, GR_ORIGIN_UPPER_LEFT, 2, 1) == 0) { printf("grSstWinOpen failed.\n"); goto __errExit; } tlConSet(0.0f, 0.0f, 1.0f, 1.0f, 60, 30, 0xffffff); /* Set up Render State */ grGet(GR_WDEPTH_MIN_MAX, 8, (FxI32 *)wrange); grVertexLayout(GR_PARAM_XY, 0, GR_PARAM_ENABLE); grVertexLayout(GR_PARAM_Q, GR_VERTEX_OOW_OFFSET << 2, GR_PARAM_ENABLE); grVertexLayout(GR_PARAM_ST0, GR_VERTEX_SOW_TMU0_OFFSET << 2, GR_PARAM_ENABLE); grColorCombine(GR_COMBINE_FUNCTION_SCALE_OTHER, GR_COMBINE_FACTOR_ONE, GR_COMBINE_LOCAL_CONSTANT, GR_COMBINE_OTHER_TEXTURE, FXFALSE); grTexCombine(GR_TMU0, GR_COMBINE_FUNCTION_LOCAL, GR_COMBINE_FACTOR_ONE, GR_COMBINE_FUNCTION_LOCAL, GR_COMBINE_FACTOR_ONE, FXFALSE, FXFALSE); /* Generate texture */ { GrLOD_t largeLod, smallLod; FxU16* texData = NULL; FxU32 totalMapSize, curMapSize; /* There's some closed form of this series thing, but I forget * what it is and am way to lazy to actually go look it up. This * is only a glide test after all. */ totalMapSize = 0; curMapSize = maxTexSize; while(curMapSize > 0) { totalMapSize += (curMapSize * curMapSize) * sizeof(FxU16); curMapSize >>= 1; } texData = (FxU16*)malloc(totalMapSize * sizeof(*texData)); if (texData == NULL) { printf("Unable to allocate texture data.\n"); exit(-1); } /* Figure out the supported log2(lod size) */ largeLod = GR_LOD_LOG2_1; while((0x01UL << largeLod) != maxTexSize) largeLod++; smallLod = GR_LOD_LOG2_1; while((0x01UL << smallLod) != minTexSize) smallLod++; /* Build simple texture w/ a different color for each map to help * distinguish the different maps when mipmapping. Additionally, * add a 'border' so that we can see if the start of the texture * gets mucked up due to an incorrect start address. */ { FxU16 colorVal = 0xF800, *curTexPtr = texData; FxU32 i, j, colorShift = (16 / largeLod); curMapSize = maxTexSize; while(curMapSize > 0) { for(j = 0; j < curMapSize; j++) *curTexPtr++ = 0xFFFF; for(i = 1; i < curMapSize - 1; i++) { *curTexPtr++ = 0xFFFF; for(j = 1; j < curMapSize - 1; j++) { *curTexPtr++ = colorVal; } *curTexPtr++ = 0xFFFF; } for(j = 0; j < curMapSize; j++) *curTexPtr++ = 0xFFFF; curMapSize >>= 1; colorVal >>= colorShift; } } { GrTexInfo texInfo = { GR_LOD_LOG2_1, 0, GR_ASPECT_LOG2_1x1, GR_TEXFMT_RGB_565, 0 }; FxU32 curTexAddr = 0x00UL, texMultiBaseOffset; texInfo.largeLodLog2 = largeLod; texInfo.data = texData; /* Determine the hw texture alignment and generate some random * offset for the texture base addressing. */ { FxU32 texAlign, maxTexMem = grTexMaxAddress(GR_TMU0), maxTexSize = grTexTextureMemRequired(GR_MIPMAPLEVELMASK_BOTH, &texInfo); if (!grGet(GR_TEXTURE_ALIGN, sizeof(texAlign), (FxI32 *)&texAlign)) { printf("grGet(GR_TEXTURE_ALIGN): Failed!\n"); exit(-1); } texAlign <<= 3UL; /* Get some offset that has to be smaller than the amount of * texxture space we have left divided by the # of times * that we're going to add it in. */ do { texMultiBaseOffset = rand(); } while ((texMultiBaseOffset < 0x1000UL) || (texMultiBaseOffset > ((maxTexMem - maxTexSize) / 4))); texMultiBaseOffset = (texMultiBaseOffset + texAlign) & ~(texAlign - 1UL); } /* Download the texture to the multibase address specified by * the current mode. We play a few games w/ offsetting the * texture start address by texMultiBaseOffset to try to make * sure that multi-base actually works inside of glide. */ /* Mmmm... multibase */ grTexMultibase(GR_TMU0, FXTRUE); /* Download and set the base addresses in descending map size * order offsetting by some dorky amount as we go. */ texInfo.smallLodLog2 = GR_LOD_LOG2_256; texInfo.largeLodLog2 = largeLod; grTexDownloadMipMap(GR_TMU0, curTexAddr, GR_MIPMAPLEVELMASK_BOTH, &texInfo); grTexMultibaseAddress(GR_TMU0, GR_TEXBASE_256, curTexAddr, GR_MIPMAPLEVELMASK_BOTH, &texInfo); curTexAddr += (texMultiBaseOffset + grTexTextureMemRequired(GR_MIPMAPLEVELMASK_BOTH, &texInfo)); texInfo.data = (void*)((FxU8*)texInfo.data + grTexTextureMemRequired(GR_MIPMAPLEVELMASK_BOTH, &texInfo)); texInfo.smallLodLog2 = GR_LOD_LOG2_128; texInfo.largeLodLog2 = GR_LOD_LOG2_128; grTexDownloadMipMap(GR_TMU0, curTexAddr, GR_MIPMAPLEVELMASK_BOTH, &texInfo); grTexMultibaseAddress(GR_TMU0, GR_TEXBASE_128, curTexAddr, GR_MIPMAPLEVELMASK_BOTH, &texInfo); curTexAddr += (texMultiBaseOffset + grTexTextureMemRequired(GR_MIPMAPLEVELMASK_BOTH, &texInfo)); texInfo.data = (void*)((FxU8*)texInfo.data + grTexTextureMemRequired(GR_MIPMAPLEVELMASK_BOTH, &texInfo)); texInfo.smallLodLog2 = GR_LOD_LOG2_64; texInfo.largeLodLog2 = GR_LOD_LOG2_64; grTexDownloadMipMap(GR_TMU0, curTexAddr, GR_MIPMAPLEVELMASK_BOTH, &texInfo); grTexMultibaseAddress(GR_TMU0, GR_TEXBASE_64, curTexAddr, GR_MIPMAPLEVELMASK_BOTH, &texInfo); curTexAddr += (texMultiBaseOffset + grTexTextureMemRequired(GR_MIPMAPLEVELMASK_BOTH, &texInfo)); texInfo.data = (void*)((FxU8*)texInfo.data + grTexTextureMemRequired(GR_MIPMAPLEVELMASK_BOTH, &texInfo)); texInfo.smallLodLog2 = GR_LOD_LOG2_1; texInfo.largeLodLog2 = GR_LOD_LOG2_32; grTexDownloadMipMap(GR_TMU0, curTexAddr, GR_MIPMAPLEVELMASK_BOTH, &texInfo); grTexMultibaseAddress(GR_TMU0, GR_TEXBASE_32_TO_1, curTexAddr, GR_MIPMAPLEVELMASK_BOTH, &texInfo); /* Source the whole texture. The large map start will reset * baseAddr0, but that should be fine since we did not adjust * its address because it came first. */ texInfo.smallLodLog2 = GR_LOD_LOG2_1; texInfo.largeLodLog2 = largeLod; grTexSource(GR_TMU0, 0x00UL, GR_MIPMAPLEVELMASK_BOTH, &texInfo); } free((void*)texData); } grTexMipMapMode(GR_TMU0, GR_MIPMAP_NEAREST, FXFALSE); tlConOutput("Press a key to quit\n"); while(frames-- && tlOkToRender()) { static float curOOW = 1.0f; if (hwconfig == TL_VOODOORUSH) { tlGetDimsByConst(resolution, &scrWidth, &scrHeight); grClipWindow(0, 0, (FxU32) scrWidth, (FxU32) scrHeight); } grBufferClear(0x808080, 0xFF, wrange[1]); { static float distance = 1.0f, dDelta = 0.1f; TlVertex3D xfVerts[4], prjVerts[4]; GrVertex vtxA, vtxB, vtxC, vtxD; /*---- A-B |\| C-D -----*/ vtxA.oow = 1.0f; vtxB = vtxC = vtxD = vtxA; #define MAX_DIST 30.5f #define MIN_DIST 1.0f distance += dDelta; if (distance > MAX_DIST || distance < MIN_DIST) { dDelta *= -1.0f; distance += dDelta; } tlSetMatrix(tlIdentity()); tlMultMatrix(tlXRotation(-20.0f)); tlMultMatrix(tlTranslation(0.0f, -0.3f, distance)); tlTransformVertices(xfVerts, srcVerts, 4); tlProjectVertices(prjVerts, xfVerts, 4); vtxA.x = tlScaleX(prjVerts[0].x); vtxA.y = tlScaleY(prjVerts[0].y); vtxA.oow = 1.0f / prjVerts[0].w; vtxA.tmuvtx[0].sow = prjVerts[0].s * 255.0f * vtxA.oow; vtxA.tmuvtx[0].tow = prjVerts[0].t * 255.0f * vtxA.oow; vtxB.x = tlScaleX(prjVerts[1].x); vtxB.y = tlScaleY(prjVerts[1].y); vtxB.oow = 1.0f / prjVerts[1].w; vtxB.tmuvtx[0].sow = prjVerts[1].s * 255.0f * vtxB.oow; vtxB.tmuvtx[0].tow = prjVerts[1].t * 255.0f * vtxB.oow; vtxC.x = tlScaleX(prjVerts[2].x); vtxC.y = tlScaleY(prjVerts[2].y); vtxC.oow = 1.0f / prjVerts[2].w; vtxC.tmuvtx[0].sow = prjVerts[2].s * 255.0f * vtxC.oow; vtxC.tmuvtx[0].tow = prjVerts[2].t * 255.0f * vtxC.oow; vtxD.x = tlScaleX(prjVerts[3].x); vtxD.y = tlScaleY(prjVerts[3].y); vtxD.oow = 1.0f / prjVerts[3].w; vtxD.tmuvtx[0].sow = prjVerts[3].s * 255.0f * vtxD.oow; vtxD.tmuvtx[0].tow = prjVerts[3].t * 255.0f * vtxD.oow; grDrawTriangle(&vtxA, &vtxB, &vtxD); grDrawTriangle(&vtxA, &vtxD, &vtxC); } tlConRender(); grBufferSwap(1); /* grab the frame buffer */ if (scrgrab) { if (!tlScreenDump(filename, (FxU16)scrWidth, (FxU16)scrHeight)) printf("Cannot open %s\n", filename); scrgrab = FXFALSE; } if (tlKbHit()) { char curKey = tlGetCH(); switch(curKey) { default: frames = 0; break; } } } rv = 0; __errExit: grGlideShutdown(); return rv; }
void main( int argc, char *argv[] ) { /*------------------------------------------------------------------ Data ------------------------------------------------------------------*/ char texFile[256]; char texFile_2[256]; FxU32 startAddress,nextAddress; FxU32 startAddress_2, nextAddress_2; GrTexInfo texInfo, texInfo_2; Gu3dfInfo info, info_2; GuNccTable nccTable, nccTable_2; GuTexPalette pal, pal_2; FxBool hasTable = FXFALSE, hasTable_2 = FXFALSE; FxBool hasPalette = FXFALSE, hasPalette_2 = FXFALSE; FxU32 numTmus = 1; FxU32 automate; FxU32 numFrames = -1; /*------------------------------------------------------------------ Glide State Initialization ------------------------------------------------------------------*/ grGlideInit(); grSstQueryHardware( &hwConfig ); grSstSelect( 0 ); grSstOpen( screenRes, GR_REFRESH_60Hz, GR_COLORFORMAT_ABGR, GR_ORIGIN_LOWER_LEFT, GR_SMOOTHING_ENABLE, 2 ); grColorCombine( GR_COMBINE_FUNCTION_SCALE_OTHER, GR_COMBINE_FACTOR_ONE, GR_COMBINE_LOCAL_NONE, GR_COMBINE_OTHER_TEXTURE, FXFALSE ); grAlphaCombine( 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_ZERO, GR_COMBINE_FUNCTION_LOCAL, GR_COMBINE_FACTOR_ZERO, FXFALSE, FXFALSE ); if ( hwConfig.SSTs[0].sstBoard.VoodooConfig.nTexelfx == 2 ) { printf( "Detected 2 TMUs\n" ); grTexCombine( GR_TMU1, GR_COMBINE_FUNCTION_LOCAL, GR_COMBINE_FACTOR_ZERO, GR_COMBINE_FUNCTION_LOCAL, GR_COMBINE_FACTOR_ZERO, FXFALSE, FXFALSE ); numTmus = 2; } /*------------------------------------------------------------------ Deal With Arguments ------------------------------------------------------------------*/ if ( numTmus == 1 ) { if ( argc < 2 ) { puts( usage_1tmu ); grGlideShutdown(); return; } else { if(strstr(argv[1], "-n")) { automate = 1; numFrames = atoi(argv[2]); if(argc >= 4) strcpy( texFile, argv[3] ); else { puts( usage_1tmu ); grGlideShutdown(); return; } } else { strcpy( texFile, argv[1] ); if(argc > 3) if(strstr(argv[2], "-n")) { automate = 1; numFrames = atoi(argv[3]); } else { puts( usage_1tmu ); grGlideShutdown(); return; } } } } else { if(argc >= 3) { if(strstr(argv[1], "-n")) { automate = 1; if(argc >= 5) { strcpy( texFile, argv[3] ); strcpy( texFile_2, argv[4] ); } else { puts( usage_2tmu ); grGlideShutdown(); return; } } else { strcpy( texFile, argv[1] ); strcpy( texFile_2, argv[2] ); if(argc >= 4) if(strstr(argv[3], "-n")) automate = 1; else { puts( usage_2tmu ); grGlideShutdown(); return; } } } else { puts( usage_2tmu ); grGlideShutdown(); return; } } grAlphaBlendFunction( GR_BLEND_ONE, GR_BLEND_ZERO, GR_BLEND_ONE, GR_BLEND_ZERO ); grDepthBufferMode( GR_DEPTHBUFFER_DISABLE ); grDepthBufferFunction( GR_CMP_LEQUAL ); grDepthMask( FXFALSE ); grCullMode( GR_CULL_DISABLE ); grBufferClear( 0x0, 0x0, 0x0 ); /*------------------------------------------------------------------ Load Texture(s) ------------------------------------------------------------------*/ if ( !gu3dfGetInfo( texFile, &info ) ) { printf( "Couldn't load %s.\n", texFile ); return; } info.data = calloc( info.mem_required, 1 ); gu3dfLoad( texFile, &info ); texInfo.smallLod = info.header.small_lod; texInfo.largeLod = info.header.large_lod; texInfo.aspectRatio = info.header.aspect_ratio; texInfo.format = info.header.format; texInfo.data = info.data; if ( texInfo.format == GR_TEXFMT_YIQ_422 || texInfo.format == GR_TEXFMT_AYIQ_8422 ) { puts( "*******************YIQ TEXTURE(TMU0)***************" ); nccTable = info.table.nccTable; hasTable = FXTRUE; } if ( texInfo.format == GR_TEXFMT_P_8 || texInfo.format == GR_TEXFMT_AP_88 ) { puts( "*******************PAL TEXTURE(TMU0)***************" ); pal = info.table.palette; hasPalette = FXTRUE; } if ( numTmus == 2 ) { if ( !gu3dfGetInfo( texFile_2, &info_2 ) ) { printf( "Couldn't load %s.\n", texFile_2 ); return; } info_2.data = calloc( info_2.mem_required, 1 ); gu3dfLoad( texFile_2, &info_2 ); texInfo_2.smallLod = info_2.header.small_lod; texInfo_2.largeLod = info_2.header.large_lod; texInfo_2.aspectRatio = info_2.header.aspect_ratio; texInfo_2.format = info_2.header.format; texInfo_2.data = info_2.data; if ( texInfo_2.format == GR_TEXFMT_YIQ_422 || texInfo_2.format == GR_TEXFMT_AYIQ_8422 ) { puts( "*******************YIQ TEXTURE(TMU1)***************" ); nccTable_2 = info_2.table.nccTable; hasTable_2 = FXTRUE; } if ( texInfo_2.format == GR_TEXFMT_P_8 || texInfo_2.format == GR_TEXFMT_AP_88 ) { puts( "*******************PAL TEXTURE(TMU1)***************" ); pal_2 = info_2.table.palette; hasPalette_2 = FXTRUE; } } /*------------------------------------------------------------------ Allocate Texture RAM ------------------------------------------------------------------*/ startAddress = nextAddress = grTexMinAddress( GR_TMU0 ); nextAddress = startAddress + grTexTextureMemRequired( GR_MIPMAPLEVELMASK_BOTH, &texInfo ); printf( "tex0: startAddress: %d nextAddress %d\n", startAddress, nextAddress ); if ( nextAddress > grTexMaxAddress( GR_TMU0 ) ) { printf( "Texture memory exhausted.\n" ); return; } if ( numTmus == 2 ) { startAddress_2 = nextAddress_2 = grTexMinAddress( GR_TMU1 ); nextAddress_2 = startAddress_2 + grTexTextureMemRequired( GR_MIPMAPLEVELMASK_BOTH, &texInfo_2 ); printf( "tex1: startAddress: %d nextAddress %d\n", startAddress_2, nextAddress_2 ); } /*------------------------------------------------------------------ Download Texture(s) ------------------------------------------------------------------*/ grTexDownloadMipMap( GR_TMU0, startAddress, GR_MIPMAPLEVELMASK_BOTH, &texInfo ); if ( hasTable ) { grTexNCCTable( GR_TMU0, GR_NCCTABLE_NCC1 ); grTexDownloadTable( GR_TMU0, GR_TEXTABLE_NCC1, &nccTable ); } if ( hasPalette ) { grTexDownloadTable( GR_TMU0, GR_TEXTABLE_PALETTE, &pal ); } if ( numTmus == 2 ) { grTexDownloadMipMap( GR_TMU1, startAddress_2, GR_MIPMAPLEVELMASK_BOTH, &texInfo_2 ); if ( hasTable_2 ) { grTexNCCTable( GR_TMU1, GR_NCCTABLE_NCC0 ); grTexDownloadTable( GR_TMU1, GR_TEXTABLE_NCC0, &nccTable_2 ); } if ( hasPalette_2 ) { grTexDownloadTable( GR_TMU1, GR_TEXTABLE_PALETTE, &pal_2 ); } } /*------------------------------------------------------------------ Set up Texture Params and Set Texture As Current ------------------------------------------------------------------*/ grTexFilterMode( GR_TMU0, GR_TEXTUREFILTER_BILINEAR, GR_TEXTUREFILTER_BILINEAR ); grTexClampMode( GR_TMU0, GR_TEXTURECLAMP_WRAP, GR_TEXTURECLAMP_WRAP ); grTexMipMapMode( GR_TMU0, GR_MIPMAP_NEAREST, FXFALSE ); grTexSource( GR_TMU0, startAddress, GR_MIPMAPLEVELMASK_BOTH, &texInfo ); if ( numTmus == 2 ) { grTexFilterMode( GR_TMU1, GR_TEXTUREFILTER_BILINEAR, GR_TEXTUREFILTER_BILINEAR ); grTexClampMode( GR_TMU1, GR_TEXTURECLAMP_WRAP, GR_TEXTURECLAMP_WRAP ); grTexMipMapMode( GR_TMU1, GR_MIPMAP_NEAREST, FXFALSE ); grTexSource( GR_TMU1, startAddress_2, GR_MIPMAPLEVELMASK_BOTH, &texInfo_2 ); } /*------------------------------------------------------------------ Render Triangles ------------------------------------------------------------------*/ puts("TEST39:\n"); puts("Tests the grTex routines\n"); if(!automate) { puts("Press any key to continue\n"); getch(); } while(numFrames) { square( 0.0f, 0.0f, 256.0f, 256.0f ); square( 255.0f, 0.0f, 128.0f, 128.0f ); square( 382.0f, 0.0f, 64.0f, 64.0f ); square( 445.0f, 0.0f, 32.0f, 32.0f ); square( 476.0f, 0.0f, 16.0f, 16.0f ); square( 491.0f, 0.0f, 8.0f, 8.0f ); square( 498.0f, 0.0f, 4.0f, 4.0f ); square( 501.0f, 0.0f, 2.0f, 2.0f ); square( 502.0f, 0.0f, 1.0f, 1.0f ); if ( numTmus == 2 ) { grTexCombine( GR_TMU0, GR_COMBINE_FUNCTION_SCALE_OTHER, GR_COMBINE_FACTOR_ONE, GR_COMBINE_FUNCTION_SCALE_OTHER, GR_COMBINE_FACTOR_ONE, FXFALSE, FXFALSE ); grTexCombine( GR_TMU1, GR_COMBINE_FUNCTION_LOCAL, GR_COMBINE_FACTOR_ZERO, GR_COMBINE_FUNCTION_LOCAL, GR_COMBINE_FACTOR_ZERO, FXFALSE, FXFALSE ); square( 0.0f, 300.0f, 256.0f, 256.0f ); square( 255.0f, 300.0f, 128.0f, 128.0f ); square( 382.0f, 300.0f, 64.0f, 64.0f ); square( 445.0f, 300.0f, 32.0f, 32.0f ); square( 476.0f, 300.0f, 16.0f, 16.0f ); square( 491.0f, 300.0f, 8.0f, 8.0f ); square( 498.0f, 300.0f, 4.0f, 4.0f ); square( 501.0f, 300.0f, 2.0f, 2.0f ); square( 502.0f, 300.0f, 1.0f, 1.0f ); } grBufferSwap( 1 ); if(numFrames > 0) numFrames--; if(kbhit()) { getch(); break; } } grGlideShutdown(); return; }
void main( int argc, char *argv[] ) { char texFile[256], texFile1[256], texFile2[256]; float theta; FxU32 numTmus = 1; FxBool paused = FXFALSE; Gu3dfInfo info, info2; FxU32 numFrames = 0xffffffff; puts("TEST44: Tests complex, multi-tmu textures\n"); puts("Press a key to continue...\n"); getch(); puts("Press q to quit\n"); /* Glide State Initialization */ grGlideInit(); grSstQueryHardware( &hwConfig ); grSstSelect( 0 ); grSstOpen( screenRes, GR_REFRESH_60Hz, GR_COLORFORMAT_ABGR, GR_ORIGIN_LOWER_LEFT, GR_SMOOTHING_ENABLE, 2 ); grColorCombine( GR_COMBINE_FUNCTION_SCALE_OTHER, GR_COMBINE_FACTOR_ONE, GR_COMBINE_LOCAL_NONE, GR_COMBINE_OTHER_TEXTURE, FXFALSE ); grAlphaCombine( 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_ZERO, GR_COMBINE_FUNCTION_LOCAL, GR_COMBINE_FACTOR_ZERO, FXFALSE, FXFALSE ); if ( hwConfig.SSTs[0].sstBoard.VoodooConfig.nTexelfx == 2 ) { printf( "Detected 2 TMUs\n" ); grTexCombine( GR_TMU1, GR_COMBINE_FUNCTION_LOCAL, GR_COMBINE_FACTOR_ZERO, GR_COMBINE_FUNCTION_LOCAL, GR_COMBINE_FACTOR_ZERO, FXFALSE, FXFALSE ); numTmus = 2; } /*------------------------------------------------------------------ Deal With Arguments ------------------------------------------------------------------*/ if ( numTmus == 1 ) { if ( argc < 2 ) { printf( "%s ", argv[0] ); puts( usage_1tmu ); grGlideShutdown(); return; } argc--;argv++; while(argc) { if(strcmp(argv[0], "-n") == 0) { argc--;argv++; if(argc) numFrames = atoi(argv[0]); else { puts( usage_1tmu ); return; } } strcpy( texFile, argv[0] ); strcpy( texFile1, argv[1] ); argc--;argv++; argc--;argv++; } } else { if ( argc < 4 ) { printf( "%s ", argv[0] ); puts( usage2tmu ); grGlideShutdown(); return; } argc--;argv++; while(argc) { if(strcmp(argv[0], "-n") == 0) { argc--;argv++; if(argc) numFrames = atoi(argv[0]); else { puts( usage_1tmu ); return; } } strcpy( texFile, argv[0] ); strcpy( texFile1, argv[1]); strcpy( texFile2, argv[2] ); argc -= 3; argv += 3; } } grAlphaBlendFunction( GR_BLEND_ONE, GR_BLEND_ZERO, GR_BLEND_ONE, GR_BLEND_ZERO ); grDepthBufferMode( GR_DEPTHBUFFER_DISABLE ); grDepthBufferFunction( GR_CMP_LEQUAL ); grDepthMask( FXFALSE ); grCullMode( GR_CULL_DISABLE ); grBufferClear( 0x0, 0x0, 0x0 ); /*------------------------------------------------------------------ Load Texture(s) ------------------------------------------------------------------*/ if ( !gu3dfGetInfo( texFile, &info ) ) { printf( "Couldn't load %s.\n", texFile ); return; } info.data = calloc( info.mem_required, 1 ); gu3dfLoad( texFile, &info ); texInfo.smallLod = info.header.small_lod; texInfo.largeLod = info.header.large_lod; texInfo.aspectRatio = info.header.aspect_ratio; texInfo.format = info.header.format; texInfo.data = info.data; if ( texInfo.format == GR_TEXFMT_YIQ_422 || texInfo.format == GR_TEXFMT_AYIQ_8422 ) { puts( "*******************YIQ TEXTURE(TMU0)***************" ); nccTable = info.table.nccTable; hasTable = FXTRUE; } if ( texInfo.format == GR_TEXFMT_P_8 || texInfo.format == GR_TEXFMT_AP_88 ) { puts( "*******************PAL TEXTURE(TMU0)***************" ); pal0 = info.table.palette; hasPalette = FXTRUE; } /* ++++ */ if ( !gu3dfGetInfo( texFile1, &info ) ) { printf( "Couldn't load %s.\n", texFile1 ); return; } info.data = calloc( info.mem_required, 1 ); gu3dfLoad( texFile1, &info ); texInfo1.smallLod = info.header.small_lod; texInfo1.largeLod = info.header.large_lod; texInfo1.aspectRatio = info.header.aspect_ratio; texInfo1.format = info.header.format; texInfo1.data = info.data; if ( texInfo1.format == GR_TEXFMT_YIQ_422 || texInfo1.format == GR_TEXFMT_AYIQ_8422 ) { puts( "*******************YIQ TEXTURE(TMU0)***************" ); nccTable = info.table.nccTable; hasTable = FXTRUE; } if ( texInfo1.format == GR_TEXFMT_P_8 || texInfo1.format == GR_TEXFMT_AP_88 ) { puts( "*******************PAL TEXTURE(TMU0)***************" ); pal0 = info.table.palette; hasPalette1 = FXTRUE; } /* ++++ */ if ( numTmus == 2 ) { if ( !gu3dfGetInfo( texFile2, &info2 ) ) { printf( "Couldn't load %s.\n", texFile2 ); return; } info2.data = calloc( info2.mem_required, 1 ); gu3dfLoad( texFile2, &info2 ); texInfo2.smallLod = info2.header.small_lod; texInfo2.largeLod = info2.header.large_lod; texInfo2.aspectRatio = info2.header.aspect_ratio; texInfo2.format = info2.header.format; texInfo2.data = info2.data; if ( texInfo2.format == GR_TEXFMT_YIQ_422 || texInfo2.format == GR_TEXFMT_AYIQ_8422 ) { puts( "*******************YIQ TEXTURE(TMU1)***************" ); nccTable2 = info2.table.nccTable; hasTable2 = FXTRUE; } if ( texInfo2.format == GR_TEXFMT_P_8 || texInfo2.format == GR_TEXFMT_AP_88 ) { puts( "*******************PAL TEXTURE(TMU1)***************" ); pal2 = info2.table.palette; hasPalette2 = FXTRUE; } } grHints(GR_HINT_STWHINT, GR_STWHINT_W_DIFF_TMU0 | GR_STWHINT_ST_DIFF_TMU0 | GR_STWHINT_W_DIFF_TMU1 | GR_STWHINT_ST_DIFF_TMU1); /*------------------------------------------------------------------ Allocate Texture RAM ------------------------------------------------------------------*/ tmu0Tex0Address = startAddress = nextAddress = grTexMinAddress( GR_TMU0 ); tmu0Tex1Address = nextAddress = startAddress + grTexTextureMemRequired( GR_MIPMAPLEVELMASK_BOTH, &texInfo ); printf( "tex0: tmu0Tex0Address: %d tmu0Tex1Address %d\n", tmu0Tex0Address, tmu0Tex1Address); if ( nextAddress > grTexMaxAddress( GR_TMU0 ) ) { printf( "Texture memory exhausted.\n" ); return; } if ( numTmus == 2 ) { startAddress2 = nextAddress2 = grTexMinAddress( GR_TMU1 ); nextAddress2 = startAddress2 + grTexTextureMemRequired( GR_MIPMAPLEVELMASK_BOTH, &texInfo2 ); printf( "tex1: startAddress: %d nextAddress %d\n", startAddress2, nextAddress2 ); } /*------------------------------------------------------------------ Download Texture(s) ------------------------------------------------------------------*/ grTexDownloadMipMap( GR_TMU0, tmu0Tex0Address, GR_MIPMAPLEVELMASK_BOTH, &texInfo ); /* ---- */ grTexDownloadMipMap( GR_TMU0, tmu0Tex1Address, GR_MIPMAPLEVELMASK_BOTH, &texInfo1 ); /* ---- */ if ( numTmus == 2 ) { grTexDownloadMipMap( GR_TMU1, startAddress2, GR_MIPMAPLEVELMASK_BOTH, &texInfo2 ); if ( hasTable2 ) { grTexNCCTable( GR_TMU1, GR_NCCTABLE_NCC0 ); grTexDownloadTable( GR_TMU1, GR_TEXTABLE_NCC0, &nccTable2 ); } if ( hasPalette2 ) { grTexDownloadTable( GR_TMU1, GR_TEXTABLE_PALETTE, &pal2 ); } } /*------------------------------------------------------------------ Set up Texture Params and Set Texture As Current ------------------------------------------------------------------*/ grTexFilterMode( GR_TMU0, GR_TEXTUREFILTER_BILINEAR, GR_TEXTUREFILTER_BILINEAR ); grTexClampMode( GR_TMU0, GR_TEXTURECLAMP_WRAP, GR_TEXTURECLAMP_WRAP ); grTexMipMapMode( GR_TMU0, GR_MIPMAP_NEAREST, FXFALSE ); grTexSource( GR_TMU0, startAddress, GR_MIPMAPLEVELMASK_BOTH, &texInfo ); if ( numTmus == 2 ) { grTexFilterMode( GR_TMU1, GR_TEXTUREFILTER_BILINEAR, GR_TEXTUREFILTER_BILINEAR ); grTexClampMode( GR_TMU1, GR_TEXTURECLAMP_WRAP, GR_TEXTURECLAMP_WRAP ); grTexMipMapMode( GR_TMU1, GR_MIPMAP_NEAREST, FXFALSE ); grTexSource( GR_TMU1, startAddress2, GR_MIPMAPLEVELMASK_BOTH, &texInfo2 ); } if ( numTmus == 2 ) { grTexCombine( GR_TMU1, GR_COMBINE_FUNCTION_LOCAL, GR_COMBINE_FACTOR_NONE, GR_COMBINE_FUNCTION_LOCAL, GR_COMBINE_FACTOR_NONE, FXFALSE, FXFALSE ); grTexCombine( GR_TMU0, GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, GR_COMBINE_FACTOR_ONE, GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL, GR_COMBINE_FACTOR_ONE, FXFALSE, FXFALSE ); } #define INC 0.5f theta = 0.f; while (1 && numFrames) { if (paused == FXFALSE) { theta += INC; if (theta > 180.f) theta -= 180.f; } square(0.f, 0.f, 640.3f, 480.f, DEG2RAD(theta)); grBufferSwap( 1 ); if (kbhit()) { char c; c = getch(); switch (c) { case '-': theta -= INC; break; case '+': theta += INC; break; case 'd': case 'D': printf("theta = %3.1f\n", theta); break; case 'P': case 'p': if (paused == FXFALSE) paused = FXTRUE; else paused = FXFALSE; break; case 'q': case 'Q': case 27: grGlideShutdown(); exit(0); break; } } /* input switch */ if(numFrames != -1) numFrames--; } /* render loop */ }/* main */