@ -1,6 +1,13 @@
@@ -1,6 +1,13 @@
# include "r_local.h"
# include "../ref_gl/gl_export.h"
struct swblit_s
{
uint stride ;
uint bpp ;
uint rmask , gmask , bmask ;
} swblit ;
/*
= = = = = = = = = = = = = = = = = = = = = = = =
@ -38,9 +45,35 @@ unsigned short *buffer;
@@ -38,9 +45,35 @@ unsigned short *buffer;
# define LOAD(x) p##x = gEngfuncs.GL_GetProcAddress(#x)
void R_BuildScreenMap ( )
static int FIRST_BIT ( uint mask )
{
uint i ;
for ( i = 0 ; ! ( BIT ( i ) & mask ) ; i + + ) ;
return i ;
}
static int COUNT_BITS ( uint mask )
{
uint i ;
for ( i = 0 ; mask ; mask = mask > > 1 )
i + = mask & 1 ;
return i ;
}
void R_BuildScreenMap ( void )
{
int i ;
uint rshift = FIRST_BIT ( swblit . rmask ) , gshift = FIRST_BIT ( swblit . gmask ) , bshift = FIRST_BIT ( swblit . bmask ) ;
uint rbits = COUNT_BITS ( swblit . rmask ) , gbits = COUNT_BITS ( swblit . gmask ) , bbits = COUNT_BITS ( swblit . bmask ) ;
uint rmult = BIT ( rbits ) , gmult = BIT ( gbits ) , bmult = BIT ( bbits ) ;
uint rdiv = MASK ( 5 ) , gdiv = MASK ( 6 ) , bdiv = MASK ( 5 ) ;
gEngfuncs . Con_Printf ( " Blit table: %d %d %d %d %d %d \n " , rmult , gmult , bmult , rdiv , gdiv , bdiv ) ;
# ifdef SEPARATE_BLIT
for ( i = 0 ; i < 256 ; i + + )
{
@ -69,16 +102,24 @@ void R_BuildScreenMap()
@@ -69,16 +102,24 @@ void R_BuildScreenMap()
r = ( ( i > > ( 8 - 3 ) ) < < 2 ) & MASK ( 5 ) ;
g = ( ( i > > ( 8 - 3 - 3 ) ) < < 3 ) & MASK ( 6 ) ;
b = ( ( i > > ( 8 - 3 - 3 - 2 ) ) < < 3 ) & MASK ( 5 ) ;
major = r < < ( 6 + 5 ) | ( g < < 5 ) | b ;
//major = r << (6 + 5) | (g << 5) | b;
major = ( r * rmult / rdiv ) < < rshift | ( g * gmult / gdiv ) < < gshift | ( b * bmult / bdiv ) < < bshift ;
for ( j = 0 ; j < 256 ; j + + )
{
uint minor ;
// restore minor GBRGBRGB
r = MOVE_BIT ( j , 5 , 1 ) | MOVE_BIT ( j , 2 , 0 ) ;
g = MOVE_BIT ( j , 7 , 2 ) | MOVE_BIT ( j , 4 , 1 ) | MOVE_BIT ( j , 1 , 0 ) ;
b = MOVE_BIT ( j , 6 , 2 ) | MOVE_BIT ( j , 3 , 1 ) | MOVE_BIT ( j , 0 , 0 ) ;
vid . screen [ ( i < < 8 ) | j ] = r < < ( 6 + 5 ) | ( g < < 5 ) | b | major ;
//vid.screen[(i<<8)|j] = r << (6 + 5) | (g << 5) | b | major;
minor = ( r * rmult / rdiv ) < < rshift | ( g * gmult / gdiv ) < < gshift | ( b * bmult / bdiv ) < < bshift ;
if ( swblit . bpp = = 2 )
vid . screen [ ( i < < 8 ) | j ] = major | minor ;
else
vid . screen32 [ ( i < < 8 ) | j ] = major | minor ;
}
@ -103,18 +144,18 @@ void R_BuildBlendMaps()
@@ -103,18 +144,18 @@ void R_BuildBlendMaps()
r = r1 + r2 ;
g = g1 + g2 ;
b = b1 + b2 ;
if ( r > MASK ( 2 ) )
r = MASK ( 2 ) ;
if ( g > MASK ( 2 ) )
g = MASK ( 2 ) ;
if ( b > MASK ( 1 ) )
b = MASK ( 1 ) ;
if ( r > MASK ( 3 ) )
r = MASK ( 3 ) ;
if ( g > MASK ( 3 ) )
g = MASK ( 3 ) ;
if ( b > MASK ( 2 ) )
b = MASK ( 2 ) ;
ASSERT ( ! vid . addmap [ index2 | index1 ] ) ;
vid . addmap [ index2 | index1 ] = r < < ( 2 + 3 ) | g < < 2 | b ;
r = r1 * r2 / MASK ( 2 ) ;
g = g1 * g2 / MASK ( 2 ) ;
b = b1 * b2 / MASK ( 1 ) ;
r = r1 * r2 / MASK ( 3 ) ;
g = g1 * g2 / MASK ( 3 ) ;
b = b1 * b2 / MASK ( 2 ) ;
vid . modmap [ index2 | index1 ] = r < < ( 2 + 3 ) | g < < 2 | b ;
@ -130,10 +171,12 @@ void R_BuildBlendMaps()
@@ -130,10 +171,12 @@ void R_BuildBlendMaps()
}
}
void R_AllocScreen ( ) ;
void R_InitBlit ( )
{
LOAD ( glBegin ) ;
/*LOAD(glBegin);
LOAD ( glEnd ) ;
LOAD ( glTexCoord2f ) ;
LOAD ( glVertex2f ) ;
@ -149,7 +192,7 @@ void R_InitBlit()
@@ -149,7 +192,7 @@ void R_InitBlit()
LOAD ( glDebugMessageControlARB ) ;
LOAD ( glGetError ) ;
LOAD ( glGenTextures ) ;
LOAD ( glTexParameteri ) ;
LOAD ( glTexParameteri ) ; */
# ifdef GLDEBUG
if ( gpGlobals - > developer )
{
@ -164,36 +207,100 @@ void R_InitBlit()
@@ -164,36 +207,100 @@ void R_InitBlit()
pglDebugMessageControlARB ( GL_DONT_CARE , GL_DONT_CARE , GL_DEBUG_SEVERITY_LOW_ARB , 0 , NULL , true ) ;
# endif
buffer = Mem_Malloc ( r_temppool , 1920 * 1080 * 2 ) ;
//buffer = Mem_Malloc( r_temppool, 1920*1080*2 );
R_BuildScreenMap ( ) ;
R_BuildBlendMaps ( ) ;
d_pzbuffer = malloc ( vid . width * vid . height * 2 ) ;
R_InitCaches ( ) ;
R_AllocScreen ( ) ;
}
void R_AllocScreen ( )
{
if ( gpGlobals - > width < 320 )
gpGlobals - > width = 320 ;
if ( gpGlobals - > height < 200 )
gpGlobals - > height = 200 ;
R_InitCaches ( ) ;
gEngfuncs . SW_CreateBuffer ( gpGlobals - > width , gpGlobals - > height , & swblit . stride , & swblit . bpp ,
& swblit . rmask , & swblit . gmask , & swblit . bmask ) ;
R_BuildScreenMap ( ) ;
vid . width = gpGlobals - > width ;
vid . height = gpGlobals - > height ;
vid . rowbytes = gpGlobals - > width ; // rowpixels
if ( d_pzbuffer )
Mem_Free ( d_pzbuffer ) ;
d_pzbuffer = Mem_Calloc ( r_temppool , vid . width * vid . height * 2 + 64 ) ;
if ( vid . buffer )
Mem_Free ( vid . buffer ) ;
vid . buffer = Mem_Malloc ( r_temppool , vid . width * vid . height * sizeof ( pixel_t ) ) ;
}
void R_BlitScreen ( )
{
//memset( vid.buffer, 10, vid.width * vid.height );
int i ;
byte * buf = vid . buffer ;
int u , v ;
void * buffer = gEngfuncs . SW_LockBuffer ( ) ;
if ( ! buffer | | gpGlobals - > width ! = vid . width | | gpGlobals - > height ! = vid . height )
{
R_AllocScreen ( ) ;
return ;
}
//byte *buf = vid.buffer;
# pragma omp parallel for schedule(static)
for ( i = 0 ; i < vid . width * vid . height ; i + + )
//#pragma omp parallel for schedule(static)
if ( swblit . bpp = = 2 )
{
# ifdef SEPARATE_BLIT
// need only 1024 bytes table, but slower
// wtf?? maybe some prefetch???
byte major = buf [ ( i < < 1 ) + 1 ] ;
byte minor = buf [ ( i < < 1 ) ] ;
unsigned short * pbuf = buffer ;
for ( v = 0 ; v < vid . height ; v + + )
{
uint start = vid . rowbytes * v ;
uint dstart = swblit . stride * v ;
buffer [ i ] = vid . screen_major [ major ] | vid . screen_minor [ minor ] ;
# else
buffer [ i ] = vid . screen [ vid . buffer [ i ] ] ;
# endif
for ( u = 0 ; u < vid . width ; u + + )
{
unsigned int s = vid . screen [ vid . buffer [ start + u ] ] ;
pbuf [ dstart + u ] = s ;
}
}
}
else if ( swblit . bpp = = 4 )
{
unsigned int * pbuf = buffer ;
for ( v = 0 ; v < vid . height ; v + + )
{
uint start = vid . rowbytes * v ;
uint dstart = swblit . stride * v ;
for ( u = 0 ; u < vid . width ; u + + )
{
unsigned int s = vid . screen32 [ vid . buffer [ start + u ] ] ;
pbuf [ dstart + u ] = s ;
}
}
}
else if ( swblit . bpp = = 3 )
{
byte * pbuf = buffer ;
for ( v = 0 ; v < vid . height ; v + + )
{
uint start = vid . rowbytes * v ;
uint dstart = swblit . stride * v ;
for ( u = 0 ; u < vid . width ; u + + )
{
unsigned int s = vid . screen32 [ vid . buffer [ start + u ] ] ;
pbuf [ ( dstart + u ) * 3 ] = s ;
s = s > > 8 ;
pbuf [ ( dstart + u ) * 3 + 1 ] = s ;
s = s > > 8 ;
pbuf [ ( dstart + u ) * 3 + 2 ] = s ;
}
}
}
#if 0
pglViewport ( 0 , 0 , gpGlobals - > width , gpGlobals - > height ) ;
pglMatrixMode ( GL_PROJECTION ) ;
pglLoadIdentity ( ) ;
@ -223,4 +330,7 @@ void R_BlitScreen()
@@ -223,4 +330,7 @@ void R_BlitScreen()
pglDisable ( GL_TEXTURE_2D ) ;
gEngfuncs . GL_SwapBuffers ( ) ;
// memset( vid.buffer, 0, vid.width * vid.height * 2 );
# else
gEngfuncs . SW_UnlockBuffer ( ) ;
# endif
}