diff --git a/ref_gu/gu_backend.c b/ref_gu/gu_backend.c index b8c34cea..88c0ed2f 100644 --- a/ref_gu/gu_backend.c +++ b/ref_gu/gu_backend.c @@ -95,7 +95,7 @@ void GL_BackendEndFrame( void ) case 1: Q_snprintf( r_speeds_msg, sizeof( r_speeds_msg ), "%3i wpoly, %3i apoly\n%3i epoly, %3i spoly", r_stats.c_world_polys, r_stats.c_alias_polys, r_stats.c_studio_polys, r_stats.c_sprite_polys ); - break; + break; case 2: R_Speeds_Printf( "visible leafs:\n%3i leafs\ncurrent leaf %3i\n", r_stats.c_world_leafs, curleaf - WORLDMODEL->leafs ); R_Speeds_Printf( "ReciusiveWorldNode: %3lf secs\nDrawTextureChains %lf\n", r_stats.t_world_node, r_stats.t_world_draw ); @@ -127,7 +127,7 @@ void GL_LoadTexMatrix( const matrix4x4 m ) sceGumMatrixMode( GU_TEXTURE ); GL_LoadMatrix( m ); sceGumUpdateMatrix(); - + glState.texIdentityMatrix = false; } @@ -143,7 +143,7 @@ void GL_LoadTexMatrixExt( const float *glmatrix ) sceGumMatrixMode( GU_TEXTURE ); sceGumLoadMatrix( ( const ScePspFMatrix4 * ) glmatrix ); sceGumUpdateMatrix(); - + glState.texIdentityMatrix = false; } @@ -169,11 +169,11 @@ void GL_LoadIdentityTexMatrix( void ) { if( glState.texIdentityMatrix ) return; - + sceGumMatrixMode( GU_TEXTURE ); - sceGumLoadIdentity(); + sceGumLoadIdentity(); sceGumUpdateMatrix(); - + glState.texIdentityMatrix = true; } @@ -282,7 +282,7 @@ void GL_Cull( GLenum cull ) void GL_SetRenderMode( int mode ) { sceGuTexFunc( GU_TFX_MODULATE, GU_TCC_RGBA ); - + switch( mode ) { case kRenderNormal: @@ -343,25 +343,38 @@ const envmap_t r_envMapInfo[6] = {{ 90, 0, 90}, 0 } }; + + qboolean VID_ScreenShot( const char *filename, int shot_type ) { -#if 0 rgbdata_t *r_shot; - uint flags = IMAGE_FLIP_Y; + uint flags = 0; int width = 0, height = 0; qboolean result; + int bpp; r_shot = Mem_Calloc( r_temppool, sizeof( rgbdata_t )); r_shot->width = (gpGlobals->width + 3) & ~3; r_shot->height = (gpGlobals->height + 3) & ~3; r_shot->flags = IMAGE_HAS_COLOR; r_shot->type = PF_RGB_24; - r_shot->size = r_shot->width * r_shot->height * gEngfuncs.Image_GetPFDesc( r_shot->type )->bpp; + bpp = gEngfuncs.Image_GetPFDesc( r_shot->type )->bpp; + r_shot->size = r_shot->width * r_shot->height * bpp; r_shot->palette = NULL; r_shot->buffer = Mem_Malloc( r_temppool, r_shot->size ); // get screen frame - pglReadPixels( 0, 0, r_shot->width, r_shot->height, GL_RGB, GL_UNSIGNED_BYTE, r_shot->buffer ); + byte *src = ( byte* )guRender.disp_buffer; + byte *dst = r_shot->buffer; + int cheight = r_shot->height; + + // stride copy + while( cheight-- ) + { + GL_PixelConverter( dst, src, r_shot->width, PC_HWF( guRender.buffer_format ), PC_SWF( r_shot->type ) ); + dst += r_shot->width * bpp; + src += guRender.buffer_width * guRender.buffer_bpp; + } switch( shot_type ) { @@ -403,9 +416,6 @@ qboolean VID_ScreenShot( const char *filename, int shot_type ) gEngfuncs.FS_FreeImage( r_shot ); return result; -#else - return 0; -#endif } /* @@ -507,7 +517,7 @@ was there. This is used to test for texture thrashing. */ void R_ShowTextures( void ) { -#if 0 +#if 0 gl_texture_t *image; float x, y, w, h; int total, start, end; @@ -609,7 +619,7 @@ rebuild_page: gEngfuncs.CL_DrawCenterPrint (); pglFinish(); -#endif +#endif } /* @@ -641,7 +651,7 @@ void SCR_TimeRefresh_f( void ) gpGlobals->viewangles[1] = i / 128.0f * 360.0f; R_RenderScene(); } -#if 0 +#if 0 pglFinish(); #endif R_EndFrame(); diff --git a/ref_gu/gu_image.c b/ref_gu/gu_image.c index 2066fdbd..d69e22ac 100644 --- a/ref_gu/gu_image.c +++ b/ref_gu/gu_image.c @@ -617,91 +617,133 @@ static void GL_BuildMipMap( byte *in, int srcWidth, int srcHeight, int srcDepth, /* =============== GL_PixelConverter + +32 <-> 16 bit Image converter + +Macro for inFormat/outFormat: +PC_HWF - PSP Hardware format mask +PC_SWF - Xash3d Software format mask =============== */ -static void GL_PixelConverter( byte *dst, const byte *src, int size, qboolean alpha, int format ) +void GL_PixelConverter( byte *dst, const byte *src, int size, int inFormat, int outFormat ) { -#if 0 // undone - if(alpha) - { - __asm__ volatile ( - ".set push\n" // save assembler option - ".set noreorder\n" // suppress reordering - "move $8, %0\n" // $8 = &dst[0] - "move $9, %1\n" // $9 = &src[0] - "move $10, %2\n" // $10 = size - "0:\n" - - "ulv.q C000, 0($8)\n" // Load 4 pixels from src - - "vt4444.q C010, C000\n" // Convert 4 -> 2 - - "sv.s S010, 0($9)\n" - "sv.s S010, 8($9)\n" - "addiu $8, $8, 16\n" // $8 = $8 + 16 - "addiu $9, $9, 8\n" // $9 = $9 + 8 - - "bne $10, $8, 0b\n" // if ( $11 != $8 ) jump to loop - "addiu $10, $10, -4\n" // $10 = $10 - 4 ( delay slot ) - ".set pop\n" // Restore assembler option - : "r"( dst ), "r"( src ), "r"( size ), "r"( format ) - : "$8", "$9", "$10" - ); - } - else - { - - } -#else int i; byte color[4]; + color[0] = color[1] = color[2] = color[3] = 0xff; + for( i = 0; i < size; i++ ) { - switch( format ) + // unpack + switch( inFormat ) { - case GU_PSM_4444: + case PC_HWF( GU_PSM_5650 ): + color[0] = ( *src & 0x1f ) << 3; + color[1] = ( *src & 0xe0 ) >> 3; src++; + color[1] |= ( *src & 0x07 ) << 5; + color[2] = ( *src & 0xf8 ); src++; + color[3] = 0xff; + break; + case PC_HWF( GU_PSM_5551 ): + color[0] = ( *src & 0x1f ) << 3; + color[1] = ( *src & 0xe0 ) >> 2; src++; + color[1] |= ( *src & 0x03 ) << 6; + color[2] = ( *src & 0x7c ) << 1; + color[3] = ( *src & 0x80 ) ? 0xff : 0x00; src++; + break; + case PC_HWF( GU_PSM_4444 ): + color[0] = ( *src & 0x0f ) << 4; + color[1] = ( *src & 0xf0 ); src++; + color[2] = ( *src & 0x0f ) << 4; + color[3] = ( *src & 0xf0 ); src++; + break; + case PC_SWF( PF_INDEXED_24 ): // palette !!! + case PC_SWF( PF_RGB_24 ): color[0] = *src; src++; color[1] = *src; src++; color[2] = *src; src++; - color[3] = alpha ? *src : 0xff; if( alpha ) src++; + color[3] = 0xff; + break; + case PC_SWF( PF_BGR_24 ): + color[2] = *src; src++; + color[1] = *src; src++; + color[0] = *src; src++; + color[3] = 0xff; + src += 3; + break; + case PC_SWF( PF_INDEXED_32 ): // palette !!! + case PC_SWF( PF_RGBA_32 ): + case PC_HWF( GU_PSM_8888 ): + color[0] = *src; src++; + color[1] = *src; src++; + color[2] = *src; src++; + color[3] = *src; src++; + break; + case PC_SWF( PF_BGRA_32 ): + color[2] = *src; src++; + color[1] = *src; src++; + color[0] = *src; src++; + color[3] = *src; src++; + break; + default: + gEngfuncs.Host_Error( "GL_PixelConverter: unknown input format\n"); + break; + } + + // pack + switch( outFormat ) + { + case PC_HWF( GU_PSM_5650 ): + *dst = ( color[0] >> 3 ) & 0x1f; + *dst |= ( color[1] << 3 ) & 0xe0; dst++; + *dst = ( color[1] >> 5 ) & 0x07; + *dst |= ( color[2] ) & 0xf8; dst++; + break; + case PC_HWF( GU_PSM_5551 ): + *dst = ( color[0] >> 3 ); + *dst |= ( color[1] << 2 ) & 0xe0; dst++; + *dst = ( color[1] >> 6 ) & 0x03; + *dst |= ( color[2] >> 1 ) & 0x7c; + *dst |= ( color[3] ) & 0x80; dst++; + break; + case PC_HWF( GU_PSM_4444 ): *dst = ( color[0] >> 4 ) & 0x0f; *dst |= ( color[1] ) & 0xf0; dst++; *dst = ( color[2] >> 4 ) & 0x0f; *dst |= ( color[3] ) & 0xf0; dst++; break; - case GU_PSM_5551: - color[0] = ( *src >> 3 ) & 0x1f; src++; - color[1] = ( *src >> 3 ) & 0x1f; src++; - color[2] = ( *src >> 3 ) & 0x1f; src++; - color[3] = alpha ? ( ( *src >> 7 ) & 0x01 ) : 0xff; if( alpha ) src++; - *dst = color[0]; - *dst |= ( color[1] << 5 ) & 0xe0; dst++; - *dst = ( color[1] >> 3 ) & 0x03; - *dst |= ( color[2] << 2 ) & 0x7c; - *dst |= ( color[3] << 7 ) & 0x80; dst++; + case PC_SWF( PF_INDEXED_24 ): // palette !!! + case PC_SWF( PF_RGB_24 ): + *dst = color[0]; dst++; + *dst = color[1]; dst++; + *dst = color[2]; dst++; break; - case GU_PSM_5650: - color[0] = ( *src >> 3 ) & 0x1f; src++; - color[1] = ( *src >> 2 ) & 0x3f; src++; - color[2] = ( *src >> 3 ) & 0x1f; src++; if( alpha ) src++; - *dst = color[0]; - *dst |= ( color[1] << 5 ) & 0xe0; dst++; - *dst = ( color[1] >> 3 ) & 0x07; - *dst |= ( color[2] << 3 ) & 0xf8; dst++; + case PC_SWF( PF_BGR_24 ): + *dst = color[2]; dst++; + *dst = color[1]; dst++; + *dst = color[0]; dst++; break; - case GU_PSM_8888: - *dst = *src; src++; dst++; - *dst = *src; src++; dst++; - *dst = *src; src++; dst++; - *dst = alpha ? *src : 0xff; if( alpha ) src++; dst++; + case PC_SWF( PF_INDEXED_32 ): // palette !!! + case PC_SWF( PF_RGBA_32 ): + case PC_HWF( GU_PSM_8888 ): + *dst = color[0]; dst++; + *dst = color[1]; dst++; + *dst = color[2]; dst++; + *dst = color[3]; dst++; + break; + case PC_SWF( PF_BGRA_32 ): + *dst = color[3]; dst++; + *dst = color[2]; dst++; + *dst = color[1]; dst++; + *dst = color[0]; dst++; break; default: + gEngfuncs.Host_Error( "GL_PixelConverter: unknown output format\n"); break; } } -#endif } + /* =============== GL_TextureSwizzle @@ -841,7 +883,7 @@ static qboolean GL_UploadTexture( gl_texture_t *tex, rgbdata_t *pic ) } // Load palette - GL_PixelConverter( tex->dstPalette, pic->palette, 256, (pic->type == PF_INDEXED_32) ? true : false, PALETTE_FORMAT ); + GL_PixelConverter( tex->dstPalette, pic->palette, 256, PC_SWF( pic->type ), PC_HWF( PALETTE_FORMAT ) ); sceKernelDcacheWritebackRange( tex->dstPalette, PALETTE_SIZE ); // Load base + mip texture @@ -889,7 +931,7 @@ static qboolean GL_UploadTexture( gl_texture_t *tex, rgbdata_t *pic ) // disable swizzling for lightmaps if ( IsLightMap( tex ) ) { - GL_PixelConverter( tex->dstTexture, volBuff, tex->width * tex->height, true, tex->format ); + GL_PixelConverter( tex->dstTexture, volBuff, tex->width * tex->height, PC_SWF( pic->type ), PC_HWF( tex->format ) ); } else { @@ -897,7 +939,7 @@ static qboolean GL_UploadTexture( gl_texture_t *tex, rgbdata_t *pic ) if( !FBitSet( tex->flags, TF_NOMIPMAP ) && FBitSet( pic->flags, IMAGE_ONEBIT_ALPHA )) volBuff = GL_ApplyFilter( volBuff, tex->width, tex->height ); */ - GL_PixelConverter( volBuff + offset, volBuff, tex->width * tex->height, true, tex->format ); + GL_PixelConverter( volBuff + offset, volBuff, tex->width * tex->height, PC_SWF( pic->type ), PC_HWF( tex->format ) ); GL_TextureSwizzle( tex->dstTexture, volBuff + offset, tex->width * 2, tex->height ); SetBits( tex->flags, TF_IMG_SWIZZLED ); } @@ -989,7 +1031,7 @@ qboolean GL_UpdateDlightTexture( int texnum, int xoff, int yoff, int width, int dst += ( yoff * tex->width + xoff ) * 2; while( height-- ) { - GL_PixelConverter( dst, src, width, true, tex->format ); + GL_PixelConverter( dst, src, width, PC_SWF( PF_RGBA_32 ), PC_HWF( tex->format ) ); dst += tex->width * 2; src += width * 4; } diff --git a/ref_gu/gu_local.h b/ref_gu/gu_local.h index 9064e367..6291e213 100644 --- a/ref_gu/gu_local.h +++ b/ref_gu/gu_local.h @@ -428,6 +428,9 @@ int GL_LoadTexture( const char *name, const byte *buf, size_t size, int flags ); int GL_LoadTextureArray( const char **names, int flags ); int GL_LoadTextureFromBuffer( const char *name, rgbdata_t *pic, texFlags_t flags, qboolean update ); byte *GL_ResampleTexture( const byte *source, int in_w, int in_h, int out_w, int out_h, qboolean isNormalMap ); +#define PC_SWF( X ) ( ( X ) | ( 1 << 15 ) ) +#define PC_HWF( X ) ( X ) +void GL_PixelConverter( byte *dst, const byte *src, int size, int inFormat, int outFormat ); int GL_CreateTexture( const char *name, int width, int height, const void *buffer, texFlags_t flags ); int GL_CreateTextureArray( const char *name, int width, int height, int depth, const void *buffer, texFlags_t flags ); void GL_ProcessTexture( int texnum, float gamma, int topColor, int bottomColor );