2009-05-08 13:28:41 +00:00
/*
* OpenClonk , http : //www.openclonk.org
*
2013-12-17 20:01:09 +00:00
* Copyright ( c ) 1998 - 2000 , Matthes Bender
* Copyright ( c ) 2001 - 2009 , RedWolf Design GmbH , http : //www.clonk.de/
2016-04-03 18:18:29 +00:00
* Copyright ( c ) 2009 - 2016 , The OpenClonk Team and contributors
2009-05-08 13:28:41 +00:00
*
2013-12-17 20:01:09 +00:00
* Distributed under the terms of the ISC license ; see accompanying file
* " COPYING " for details .
2009-05-08 13:28:41 +00:00
*
2013-12-17 20:01:09 +00:00
* " Clonk " is a registered trademark of Matthes Bender , used with permission .
* See accompanying file " TRADEMARK " for details .
2009-05-08 13:28:41 +00:00
*
2013-12-17 20:01:09 +00:00
* To redistribute this file separately , substitute the full license texts
* for the above references .
2009-05-08 13:28:41 +00:00
*/
/* NewGfx interfaces */
2009-10-20 03:39:24 +00:00
# include "C4Include.h"
2016-04-03 18:07:56 +00:00
# include "graphics/C4Draw.h"
2011-03-11 02:48:25 +00:00
2016-04-03 18:07:56 +00:00
# include "platform/C4App.h"
# include "graphics/C4FontLoader.h"
# include "platform/C4Window.h"
# include "graphics/C4DrawGL.h"
# include "graphics/C4DrawT.h"
# include "lib/C4Markup.h"
# include "lib/C4Rect.h"
# include "config/C4Config.h"
# include "lib/StdMesh.h"
# include "graphics/CSurface8.h"
2016-02-08 01:13:18 +00:00
# include "lib/StdColors.h"
2009-05-08 13:28:41 +00:00
# include <stdio.h>
2014-12-14 12:24:16 +00:00
// Instruct Optimus laptops to use nVidia GPU instead of integrated GPU
# if defined(_WIN32) && !defined(USE_CONSOLE)
extern " C " {
2014-12-14 12:43:58 +00:00
__declspec ( dllexport ) DWORD NvOptimusEnablement = 0x00000001 ;
2014-12-14 12:24:16 +00:00
}
# endif
2009-05-08 13:28:41 +00:00
// Global access pointer
2011-10-03 14:34:08 +00:00
C4Draw * pDraw = NULL ;
2009-05-08 13:28:41 +00:00
inline DWORD GetTextShadowClr ( DWORD dwTxtClr )
2010-03-28 18:58:01 +00:00
{
return RGBA ( ( ( dwTxtClr > > 0 ) % 256 ) / 3 , ( ( dwTxtClr > > 8 ) % 256 ) / 3 , ( ( dwTxtClr > > 16 ) % 256 ) / 3 , ( dwTxtClr > > 24 ) % 256 ) ;
}
2009-05-08 13:28:41 +00:00
2013-05-25 12:59:58 +00:00
void C4BltTransform : : SetRotate ( float iAngle , float fOffX , float fOffY ) // set by angle and rotation offset
2010-03-28 18:58:01 +00:00
{
2013-05-25 12:59:58 +00:00
// iAngle is in degrees (cycling from 0 to 360)
2009-05-08 13:28:41 +00:00
// determine sine and cos of reversed angle in radians
2013-05-25 12:59:58 +00:00
// fAngle = -iAngle * pi/180 = iAngle * -pi/180
float fAngle = iAngle * - 0.0174532925f ;
float fsin = sinf ( fAngle ) ; float fcos = cosf ( fAngle ) ;
2009-05-08 13:28:41 +00:00
// set matrix values
mat [ 0 ] = + fcos ; mat [ 1 ] = + fsin ; mat [ 2 ] = ( 1 - fcos ) * fOffX - fsin * fOffY ;
mat [ 3 ] = - fsin ; mat [ 4 ] = + fcos ; mat [ 5 ] = ( 1 - fcos ) * fOffY + fsin * fOffX ;
mat [ 6 ] = 0 ; mat [ 7 ] = 0 ; mat [ 8 ] = 1 ;
2010-03-28 18:58:01 +00:00
/* calculation of rotation matrix:
x2 = fcos * ( x1 - fOffX ) + fsin * ( y1 - fOffY ) + fOffX
= fcos * x1 - fcos * fOffX + fsin * y1 - fsin * fOffY + fOffX
= x1 * fcos + y1 * fsin + ( 1 - fcos ) * fOffX - fsin * fOffY
y2 = - fsin * ( x1 - fOffX ) + fcos * ( y1 - fOffY ) + fOffY
= x1 * - fsin + fsin * fOffX + y1 * fcos - fcos * fOffY + fOffY
= x1 * - fsin + y1 * fcos + fsin * fOffX + ( 1 - fcos ) * fOffY */
}
2009-05-08 13:28:41 +00:00
2011-09-30 20:15:51 +00:00
bool C4BltTransform : : SetAsInv ( C4BltTransform & r )
2010-03-28 18:58:01 +00:00
{
2009-05-08 13:28:41 +00:00
// calc inverse of matrix
float det = r . mat [ 0 ] * r . mat [ 4 ] * r . mat [ 8 ] + r . mat [ 1 ] * r . mat [ 5 ] * r . mat [ 6 ]
2010-03-28 18:58:01 +00:00
+ r . mat [ 2 ] * r . mat [ 3 ] * r . mat [ 7 ] - r . mat [ 2 ] * r . mat [ 4 ] * r . mat [ 6 ]
- r . mat [ 0 ] * r . mat [ 5 ] * r . mat [ 7 ] - r . mat [ 1 ] * r . mat [ 3 ] * r . mat [ 8 ] ;
2009-05-08 13:28:41 +00:00
if ( ! det ) { Set ( 1 , 0 , 0 , 0 , 1 , 0 , 0 , 0 , 1 ) ; return false ; }
mat [ 0 ] = ( r . mat [ 4 ] * r . mat [ 8 ] - r . mat [ 5 ] * r . mat [ 7 ] ) / det ;
mat [ 1 ] = ( r . mat [ 2 ] * r . mat [ 7 ] - r . mat [ 1 ] * r . mat [ 8 ] ) / det ;
mat [ 2 ] = ( r . mat [ 1 ] * r . mat [ 5 ] - r . mat [ 2 ] * r . mat [ 4 ] ) / det ;
mat [ 3 ] = ( r . mat [ 5 ] * r . mat [ 6 ] - r . mat [ 3 ] * r . mat [ 8 ] ) / det ;
mat [ 4 ] = ( r . mat [ 0 ] * r . mat [ 8 ] - r . mat [ 2 ] * r . mat [ 6 ] ) / det ;
mat [ 5 ] = ( r . mat [ 2 ] * r . mat [ 3 ] - r . mat [ 0 ] * r . mat [ 5 ] ) / det ;
mat [ 6 ] = ( r . mat [ 3 ] * r . mat [ 7 ] - r . mat [ 4 ] * r . mat [ 6 ] ) / det ;
mat [ 7 ] = ( r . mat [ 1 ] * r . mat [ 6 ] - r . mat [ 0 ] * r . mat [ 7 ] ) / det ;
mat [ 8 ] = ( r . mat [ 0 ] * r . mat [ 4 ] - r . mat [ 1 ] * r . mat [ 3 ] ) / det ;
return true ;
2010-03-28 18:58:01 +00:00
}
2009-05-08 13:28:41 +00:00
2011-09-30 20:15:51 +00:00
void C4BltTransform : : TransformPoint ( float & rX , float & rY ) const
2010-03-28 18:58:01 +00:00
{
2009-05-08 13:28:41 +00:00
// apply matrix
float fW = mat [ 6 ] * rX + mat [ 7 ] * rY + mat [ 8 ] ;
// store in temp, so original rX is used for calculation of rY
float fX = ( mat [ 0 ] * rX + mat [ 1 ] * rY + mat [ 2 ] ) / fW ;
rY = ( mat [ 3 ] * rX + mat [ 4 ] * rY + mat [ 5 ] ) / fW ;
rX = fX ; // apply temp
2010-03-28 18:58:01 +00:00
}
2009-05-08 13:28:41 +00:00
2011-09-30 20:15:51 +00:00
C4Pattern & C4Pattern : : operator = ( const C4Pattern & nPattern )
2010-03-28 18:58:01 +00:00
{
2009-05-08 13:28:41 +00:00
sfcPattern32 = nPattern . sfcPattern32 ;
if ( sfcPattern32 ) sfcPattern32 - > Lock ( ) ;
delete [ ] CachedPattern ;
if ( nPattern . CachedPattern )
2010-03-28 18:58:01 +00:00
{
2009-05-08 13:28:41 +00:00
CachedPattern = new uint32_t [ sfcPattern32 - > Wdt * sfcPattern32 - > Hgt ] ;
memcpy ( CachedPattern , nPattern . CachedPattern , sfcPattern32 - > Wdt * sfcPattern32 - > Hgt * 4 ) ;
2010-03-28 18:58:01 +00:00
}
2009-05-08 13:28:41 +00:00
else
2010-03-28 18:58:01 +00:00
{
2009-05-08 13:28:41 +00:00
CachedPattern = 0 ;
2010-03-28 18:58:01 +00:00
}
2009-05-08 13:28:41 +00:00
Wdt = nPattern . Wdt ;
Hgt = nPattern . Hgt ;
Zoom = nPattern . Zoom ;
return * this ;
2010-03-28 18:58:01 +00:00
}
2009-05-08 13:28:41 +00:00
2011-10-03 14:07:07 +00:00
bool C4Pattern : : Set ( C4Surface * sfcSource , int iZoom )
2010-03-28 18:58:01 +00:00
{
2009-05-08 13:28:41 +00:00
// Safety
if ( ! sfcSource ) return false ;
// Clear existing pattern
Clear ( ) ;
// new style: simply store pattern for modulation or shifting, which will be decided upon use
sfcPattern32 = sfcSource ;
sfcPattern32 - > Lock ( ) ;
Wdt = sfcPattern32 - > Wdt ;
Hgt = sfcPattern32 - > Hgt ;
// set zoom
Zoom = iZoom ;
// set flags
CachedPattern = new uint32_t [ Wdt * Hgt ] ;
if ( ! CachedPattern ) return false ;
for ( int y = 0 ; y < Hgt ; + + y )
for ( int x = 0 ; x < Wdt ; + + x )
2010-03-28 18:58:01 +00:00
{
2009-05-08 13:28:41 +00:00
CachedPattern [ y * Wdt + x ] = sfcPattern32 - > GetPixDw ( x , y , false ) ;
2010-03-28 18:58:01 +00:00
}
2009-05-08 13:28:41 +00:00
return true ;
2010-03-28 18:58:01 +00:00
}
2009-05-08 13:28:41 +00:00
2011-09-30 20:15:51 +00:00
C4Pattern : : C4Pattern ( )
2010-03-28 18:58:01 +00:00
{
2009-05-08 13:28:41 +00:00
// disable
sfcPattern32 = NULL ;
CachedPattern = 0 ;
Zoom = 0 ;
2010-03-28 18:58:01 +00:00
}
2009-05-08 13:28:41 +00:00
2011-09-30 20:15:51 +00:00
void C4Pattern : : Clear ( )
2010-03-28 18:58:01 +00:00
{
2009-05-08 13:28:41 +00:00
// pattern assigned
if ( sfcPattern32 )
2010-03-28 18:58:01 +00:00
{
2009-05-08 13:28:41 +00:00
// unlock it
sfcPattern32 - > Unlock ( ) ;
// clear field
sfcPattern32 = NULL ;
}
2010-03-28 18:58:01 +00:00
delete [ ] CachedPattern ; CachedPattern = 0 ;
}
2009-05-08 13:28:41 +00:00
2011-09-30 20:15:51 +00:00
DWORD C4Pattern : : PatternClr ( unsigned int iX , unsigned int iY ) const
2010-03-28 18:58:01 +00:00
{
2009-07-24 21:50:04 +00:00
if ( ! CachedPattern ) return 0 ;
// wrap position
iX % = Wdt ; iY % = Hgt ;
return CachedPattern [ iY * Wdt + iX ] ;
2010-03-28 18:58:01 +00:00
}
2009-05-08 13:28:41 +00:00
//--------------------------------------------------------------------
2011-10-03 14:34:08 +00:00
void C4Draw : : Default ( )
2010-03-28 18:58:01 +00:00
{
2009-05-08 13:28:41 +00:00
RenderTarget = NULL ;
ClipAll = false ;
Active = false ;
BlitModulated = false ;
dwBlitMode = 0 ;
2015-08-31 15:34:01 +00:00
ResetGamma ( ) ;
2014-11-06 16:19:41 +00:00
pFoW = NULL ;
2009-05-08 13:28:41 +00:00
ZoomX = 0 ; ZoomY = 0 ; Zoom = 1 ;
2010-03-17 12:43:17 +00:00
MeshTransform = NULL ;
2010-02-06 17:33:30 +00:00
fUsePerspective = false ;
2010-03-28 18:58:01 +00:00
}
2009-05-08 13:28:41 +00:00
2011-10-03 14:34:08 +00:00
void C4Draw : : Clear ( )
2010-03-28 18:58:01 +00:00
{
2013-11-09 16:11:29 +00:00
ResetGamma ( ) ;
2014-11-07 16:53:10 +00:00
Active = BlitModulated = false ;
2009-05-08 13:28:41 +00:00
dwBlitMode = 0 ;
2010-03-28 18:58:01 +00:00
}
2009-05-08 13:28:41 +00:00
2011-10-03 14:34:08 +00:00
bool C4Draw : : GetSurfaceSize ( C4Surface * sfcSurface , int & iWdt , int & iHgt )
2010-03-28 18:58:01 +00:00
{
2009-05-08 13:28:41 +00:00
return sfcSurface - > GetSurfaceSize ( iWdt , iHgt ) ;
2010-03-28 18:58:01 +00:00
}
2009-05-08 13:28:41 +00:00
2011-10-03 14:34:08 +00:00
bool C4Draw : : SubPrimaryClipper ( int iX1 , int iY1 , int iX2 , int iY2 )
2010-03-28 18:58:01 +00:00
{
2009-05-08 13:28:41 +00:00
// Set sub primary clipper
2015-11-15 12:53:01 +00:00
SetPrimaryClipper ( std : : max ( iX1 , iClipX1 ) , std : : max ( iY1 , iClipY1 ) , std : : min ( iX2 , iClipX2 ) , std : : min ( iY2 , iClipY2 ) ) ;
2009-08-15 18:50:32 +00:00
return true ;
2010-03-28 18:58:01 +00:00
}
2009-05-08 13:28:41 +00:00
2011-10-03 14:34:08 +00:00
bool C4Draw : : StorePrimaryClipper ( )
2010-03-28 18:58:01 +00:00
{
2009-05-08 13:28:41 +00:00
// Store current primary clipper
fStClipX1 = fClipX1 ; fStClipY1 = fClipY1 ; fStClipX2 = fClipX2 ; fStClipY2 = fClipY2 ;
2009-08-15 18:50:32 +00:00
return true ;
2010-03-28 18:58:01 +00:00
}
2009-05-08 13:28:41 +00:00
2011-10-03 14:34:08 +00:00
bool C4Draw : : RestorePrimaryClipper ( )
2010-03-28 18:58:01 +00:00
{
2009-05-08 13:28:41 +00:00
// Restore primary clipper
SetPrimaryClipper ( fStClipX1 , fStClipY1 , fStClipX2 , fStClipY2 ) ;
2009-08-15 18:50:32 +00:00
return true ;
2010-03-28 18:58:01 +00:00
}
2009-05-08 13:28:41 +00:00
2011-10-03 14:34:08 +00:00
bool C4Draw : : SetPrimaryClipper ( int iX1 , int iY1 , int iX2 , int iY2 )
2010-03-28 18:58:01 +00:00
{
2009-05-08 13:28:41 +00:00
// set clipper
fClipX1 = iX1 ; fClipY1 = iY1 ; fClipX2 = iX2 ; fClipY2 = iY2 ;
2010-04-26 23:32:45 +00:00
iClipX1 = iX1 ; iClipY1 = iY1 ; iClipX2 = iX2 ; iClipY2 = iY2 ;
2009-05-08 13:28:41 +00:00
UpdateClipper ( ) ;
// Done
2009-08-15 18:50:32 +00:00
return true ;
2010-03-28 18:58:01 +00:00
}
2009-05-08 13:28:41 +00:00
2011-10-03 14:34:08 +00:00
bool C4Draw : : ApplyPrimaryClipper ( C4Surface * sfcSurface )
2010-03-28 18:58:01 +00:00
{
2009-08-15 18:50:32 +00:00
return true ;
2010-03-28 18:58:01 +00:00
}
2009-05-08 13:28:41 +00:00
2011-10-03 14:34:08 +00:00
bool C4Draw : : DetachPrimaryClipper ( C4Surface * sfcSurface )
2010-03-28 18:58:01 +00:00
{
2009-08-15 18:50:32 +00:00
return true ;
2010-03-28 18:58:01 +00:00
}
2009-05-08 13:28:41 +00:00
2011-10-03 14:34:08 +00:00
bool C4Draw : : NoPrimaryClipper ( )
2010-03-28 18:58:01 +00:00
{
2009-05-08 13:28:41 +00:00
// apply maximum clipper
SetPrimaryClipper ( 0 , 0 , 439832 , 439832 ) ;
// Done
2009-08-15 18:50:32 +00:00
return true ;
2010-03-28 18:58:01 +00:00
}
2009-05-08 13:28:41 +00:00
2011-10-03 14:34:08 +00:00
void C4Draw : : BlitLandscape ( C4Surface * sfcSource , float fx , float fy ,
2014-11-02 16:10:08 +00:00
C4Surface * sfcTarget , float tx , float ty , float wdt , float hgt )
2010-03-28 18:58:01 +00:00
{
2009-08-15 18:50:32 +00:00
Blit ( sfcSource , fx , fy , wdt , hgt , sfcTarget , tx , ty , wdt , hgt , false ) ;
2010-03-28 18:58:01 +00:00
}
2009-05-08 13:28:41 +00:00
2011-10-03 14:34:08 +00:00
void C4Draw : : Blit8Fast ( CSurface8 * sfcSource , int fx , int fy ,
2011-10-03 14:07:07 +00:00
C4Surface * sfcTarget , int tx , int ty , int wdt , int hgt )
2010-03-28 18:58:01 +00:00
{
2009-05-08 13:28:41 +00:00
// blit 8bit-sfc
// lock surfaces
assert ( sfcTarget - > fPrimary ) ;
bool fRender = sfcTarget - > IsRenderTarget ( ) ;
if ( ! fRender ) if ( ! sfcTarget - > Lock ( ) )
2010-03-28 18:58:01 +00:00
{ return ; }
2010-09-07 15:00:27 +00:00
float tfx = tx , tfy = ty , twdt = wdt , thgt = hgt ;
if ( Zoom ! = 1.0 )
{
ApplyZoom ( tfx , tfy ) ;
twdt * = Zoom ;
thgt * = Zoom ;
}
2014-10-08 02:51:34 +00:00
// blit 8 bit pix in batches of 1024 pixels
static const int BUF_SIZE = 1024 ;
C4BltVertex * vertices = new C4BltVertex [ BUF_SIZE ] ;
int bufcnt = 0 ;
2010-09-07 15:00:27 +00:00
for ( int ycnt = 0 ; ycnt < thgt ; + + ycnt )
2014-10-08 02:51:34 +00:00
{
2010-09-07 15:00:27 +00:00
for ( int xcnt = 0 ; xcnt < twdt ; + + xcnt )
2010-03-28 18:58:01 +00:00
{
2010-09-07 15:00:27 +00:00
BYTE byPix = sfcSource - > GetPix ( fx + wdt * xcnt / twdt , fy + hgt * ycnt / thgt ) ;
2014-10-08 02:51:34 +00:00
DWORD dwClr = byPix ? sfcSource - > pPal - > GetClr ( byPix ) : 0x00000000 ;
vertices [ bufcnt ] . ftx = ( float ) ( tx + xcnt / Zoom ) ;
vertices [ bufcnt ] . fty = ( float ) ( ty + ycnt / Zoom ) ;
DwTo4UB ( dwClr , vertices [ bufcnt ] . color ) ;
+ + bufcnt ;
if ( bufcnt = = BUF_SIZE )
{
2015-09-12 22:14:18 +00:00
PerformMultiPix ( sfcTarget , vertices , BUF_SIZE , NULL ) ;
2014-10-08 02:51:34 +00:00
bufcnt = 0 ;
}
2010-03-28 18:58:01 +00:00
}
2014-10-08 02:51:34 +00:00
}
if ( bufcnt > 0 )
2015-09-12 22:14:18 +00:00
PerformMultiPix ( sfcTarget , vertices , bufcnt , NULL ) ;
2014-10-08 02:51:34 +00:00
delete [ ] vertices ;
2009-05-08 13:28:41 +00:00
// unlock
if ( ! fRender ) sfcTarget - > Unlock ( ) ;
2010-03-28 18:58:01 +00:00
}
2009-05-08 13:28:41 +00:00
2011-10-03 14:34:08 +00:00
bool C4Draw : : Blit ( C4Surface * sfcSource , float fx , float fy , float fwdt , float fhgt ,
2011-10-03 14:06:41 +00:00
C4Surface * sfcTarget , float tx , float ty , float twdt , float thgt ,
2011-09-30 20:15:51 +00:00
bool fSrcColKey , const C4BltTransform * pTransform )
2012-02-25 16:35:24 +00:00
{
return BlitUnscaled ( sfcSource , fx * sfcSource - > Scale , fy * sfcSource - > Scale , fwdt * sfcSource - > Scale , fhgt * sfcSource - > Scale ,
sfcTarget , tx , ty , twdt , thgt , fSrcColKey , pTransform ) ;
}
bool C4Draw : : BlitUnscaled ( C4Surface * sfcSource , float fx , float fy , float fwdt , float fhgt ,
C4Surface * sfcTarget , float tx , float ty , float twdt , float thgt ,
bool fSrcColKey , const C4BltTransform * pTransform )
2010-03-28 18:58:01 +00:00
{
2009-05-08 13:28:41 +00:00
// safety
2009-08-15 18:50:32 +00:00
if ( ! sfcSource | | ! sfcTarget | | ! twdt | | ! thgt | | ! fwdt | | ! fhgt ) return false ;
2009-05-08 13:28:41 +00:00
// emulated blit?
if ( ! sfcTarget - > IsRenderTarget ( ) )
2014-11-02 02:07:38 +00:00
{
C4BltTransform t ;
if ( pTransform & & Zoom ! = 1.0 )
{
t . Set ( pTransform - > mat [ 0 ] * Zoom , pTransform - > mat [ 1 ] * Zoom , pTransform - > mat [ 2 ] * Zoom + ZoomX * ( 1 - Zoom ) ,
pTransform - > mat [ 3 ] * Zoom , pTransform - > mat [ 4 ] * Zoom , pTransform - > mat [ 5 ] * Zoom + ZoomY * ( 1 - Zoom ) ,
pTransform - > mat [ 6 ] , pTransform - > mat [ 7 ] , pTransform - > mat [ 8 ] ) ;
pTransform = & t ;
}
else if ( Zoom ! = 1.0 )
{
ApplyZoom ( tx , ty ) ;
twdt * = Zoom ;
thgt * = Zoom ;
}
2009-05-08 13:28:41 +00:00
return Blit8 ( sfcSource , int ( fx ) , int ( fy ) , int ( fwdt ) , int ( fhgt ) , sfcTarget , int ( tx ) , int ( ty ) , int ( twdt ) , int ( thgt ) , fSrcColKey , pTransform ) ;
2014-11-02 02:07:38 +00:00
}
2014-11-02 03:11:35 +00:00
2009-05-08 13:28:41 +00:00
// calc stretch
float scaleX = twdt / fwdt ;
float scaleY = thgt / fhgt ;
// bound
2009-08-15 18:50:32 +00:00
if ( ClipAll ) return true ;
2009-05-08 13:28:41 +00:00
// inside screen?
2009-08-15 18:50:32 +00:00
if ( twdt < = 0 | | thgt < = 0 ) return false ;
2009-05-08 13:28:41 +00:00
// prepare rendering to surface
2009-08-15 18:50:32 +00:00
if ( ! PrepareRendering ( sfcTarget ) ) return false ;
2009-05-08 13:28:41 +00:00
// texture present?
2016-02-08 15:14:59 +00:00
if ( ! sfcSource - > texture )
2010-03-28 18:58:01 +00:00
{
2009-05-08 13:28:41 +00:00
// primary surface?
if ( sfcSource - > fPrimary )
2010-03-28 18:58:01 +00:00
{
2009-05-08 13:28:41 +00:00
// blit emulated
return Blit8 ( sfcSource , int ( fx ) , int ( fy ) , int ( fwdt ) , int ( fhgt ) , sfcTarget , int ( tx ) , int ( ty ) , int ( twdt ) , int ( thgt ) , fSrcColKey ) ;
}
2010-03-28 18:58:01 +00:00
return false ;
}
2009-05-08 13:28:41 +00:00
// blit with basesfc?
bool fBaseSfc = false ;
2016-02-08 15:14:59 +00:00
if ( sfcSource - > pMainSfc ) if ( sfcSource - > pMainSfc - > texture ) fBaseSfc = true ;
2009-05-08 13:28:41 +00:00
// get involved texture offsets
2010-09-04 17:30:45 +00:00
int iTexSizeX = sfcSource - > iTexSize ;
int iTexSizeY = sfcSource - > iTexSize ;
2016-02-08 15:14:59 +00:00
C4TexRef * pTex = sfcSource - > texture . get ( ) ;
// set up blit data
C4BltVertex vertices [ 6 ] ;
vertices [ 0 ] . ftx = tx ; vertices [ 0 ] . fty = ty ;
vertices [ 1 ] . ftx = tx + twdt ; vertices [ 1 ] . fty = ty ;
vertices [ 2 ] . ftx = tx + twdt ; vertices [ 2 ] . fty = ty + thgt ;
vertices [ 3 ] . ftx = tx ; vertices [ 3 ] . fty = ty + thgt ;
vertices [ 0 ] . tx = fx / pTex - > iSizeX ; vertices [ 0 ] . ty = fy / pTex - > iSizeY ;
vertices [ 1 ] . tx = ( fx + fwdt ) / pTex - > iSizeX ; vertices [ 1 ] . ty = fy / pTex - > iSizeY ;
vertices [ 2 ] . tx = ( fx + fwdt ) / pTex - > iSizeX ; vertices [ 2 ] . ty = ( fy + fhgt ) / pTex - > iSizeY ;
vertices [ 3 ] . tx = fx / pTex - > iSizeX ; vertices [ 3 ] . ty = ( fy + fhgt ) / pTex - > iSizeY ;
DwTo4UB ( 0xffffffff , vertices [ 0 ] . color ) ;
DwTo4UB ( 0xffffffff , vertices [ 1 ] . color ) ;
DwTo4UB ( 0xffffffff , vertices [ 2 ] . color ) ;
DwTo4UB ( 0xffffffff , vertices [ 3 ] . color ) ;
2014-11-02 02:07:38 +00:00
2016-02-08 15:14:59 +00:00
// duplicate vertices
vertices [ 4 ] = vertices [ 0 ] ; vertices [ 5 ] = vertices [ 2 ] ;
2014-11-07 20:28:52 +00:00
2016-02-08 15:14:59 +00:00
C4TexRef * pBaseTex = pTex ;
// is there a base-surface to be blitted first?
if ( fBaseSfc )
{
// then get this surface as same offset as from other surface
// assuming this is only valid as long as there's no texture management,
// organizing partially used textures together!
pBaseTex = sfcSource - > pMainSfc - > texture . get ( ) ;
2010-03-28 18:58:01 +00:00
}
2016-02-08 15:14:59 +00:00
C4TexRef * pNormalTex = NULL ;
if ( sfcSource - > pNormalSfc )
pNormalTex = sfcSource - > pNormalSfc - > texture . get ( ) ;
// ClrByOwner is always fully opaque
const DWORD dwOverlayClrMod = 0xff000000 | sfcSource - > ClrByOwnerClr ;
PerformMultiTris ( sfcTarget , vertices , 6 , pTransform , pBaseTex , fBaseSfc ? pTex : NULL , pNormalTex , dwOverlayClrMod , NULL ) ;
2009-05-08 13:28:41 +00:00
// success
2009-08-15 18:50:32 +00:00
return true ;
2010-03-28 18:58:01 +00:00
}
2009-05-08 13:28:41 +00:00
2011-10-03 14:34:08 +00:00
bool C4Draw : : RenderMesh ( StdMeshInstance & instance , C4Surface * sfcTarget , float tx , float ty , float twdt , float thgt , DWORD dwPlayerColor , C4BltTransform * pTransform )
2009-07-10 23:10:18 +00:00
{
// TODO: Emulate rendering
2009-08-28 01:35:55 +00:00
if ( ! sfcTarget - > IsRenderTarget ( ) ) return false ;
2009-07-10 23:10:18 +00:00
// TODO: Clip
// prepare rendering to surface
2009-08-28 01:35:55 +00:00
if ( ! PrepareRendering ( sfcTarget ) ) return false ;
2010-01-10 21:02:40 +00:00
// Update bone matrices and vertex data (note this also updates attach transforms and child transforms)
2010-01-06 01:11:56 +00:00
instance . UpdateBoneTransforms ( ) ;
2010-06-08 22:55:34 +00:00
// Order faces according to MeshTransformation (note pTransform does not affect Z coordinate, so does not need to be taken into account for correct ordering)
2015-08-05 03:16:36 +00:00
StdMeshMatrix mat = StdMeshMatrix : : Identity ( ) ;
2010-06-08 22:55:34 +00:00
if ( MeshTransform ) mat = * MeshTransform * mat ;
instance . ReorderFaces ( & mat ) ;
2010-01-06 01:11:56 +00:00
// Render mesh
2010-07-21 20:23:34 +00:00
PerformMesh ( instance , tx , ty , twdt , thgt , dwPlayerColor , pTransform ) ;
2009-07-10 23:10:18 +00:00
// success
2009-08-28 01:35:55 +00:00
return true ;
2009-07-10 23:10:18 +00:00
}
2011-10-03 14:34:08 +00:00
bool C4Draw : : Blit8 ( C4Surface * sfcSource , int fx , int fy , int fwdt , int fhgt ,
2011-10-03 14:07:07 +00:00
C4Surface * sfcTarget , int tx , int ty , int twdt , int thgt ,
2011-09-30 20:15:51 +00:00
bool fSrcColKey , const C4BltTransform * pTransform )
2010-03-28 18:58:01 +00:00
{
2013-05-25 12:18:20 +00:00
if ( ! pTransform ) return BlitSimple ( sfcSource , fx , fy , fwdt , fhgt , sfcTarget , tx , ty , twdt , thgt , fSrcColKey ! = false ) ;
2009-05-08 13:28:41 +00:00
// safety
2009-08-15 18:50:32 +00:00
if ( ! fwdt | | ! fhgt ) return true ;
2009-05-08 13:28:41 +00:00
// Lock the surfaces
if ( ! sfcSource - > Lock ( ) )
2009-08-15 18:50:32 +00:00
return false ;
2009-05-08 13:28:41 +00:00
if ( ! sfcTarget - > Lock ( ) )
2009-08-15 18:50:32 +00:00
{ sfcSource - > Unlock ( ) ; return false ; }
2009-05-08 13:28:41 +00:00
// transformed, emulated blit
// Calculate transform target rect
2011-09-30 20:15:51 +00:00
C4BltTransform Transform ;
2009-05-08 13:28:41 +00:00
Transform . SetMoveScale ( tx - ( float ) fx * twdt / fwdt , ty - ( float ) fy * thgt / fhgt , ( float ) twdt / fwdt , ( float ) thgt / fhgt ) ;
Transform * = * pTransform ;
2011-09-30 20:15:51 +00:00
C4BltTransform TransformBack ;
2009-05-08 13:28:41 +00:00
TransformBack . SetAsInv ( Transform ) ;
float ttx0 = ( float ) tx , tty0 = ( float ) ty , ttx1 = ( float ) ( tx + twdt ) , tty1 = ( float ) ( ty + thgt ) ;
float ttx2 = ( float ) ttx0 , tty2 = ( float ) tty1 , ttx3 = ( float ) ttx1 , tty3 = ( float ) tty0 ;
pTransform - > TransformPoint ( ttx0 , tty0 ) ;
pTransform - > TransformPoint ( ttx1 , tty1 ) ;
pTransform - > TransformPoint ( ttx2 , tty2 ) ;
pTransform - > TransformPoint ( ttx3 , tty3 ) ;
2015-11-15 12:53:01 +00:00
int ttxMin = std : : max < int > ( ( int ) floor ( std : : min ( std : : min ( ttx0 , ttx1 ) , std : : min ( ttx2 , ttx3 ) ) ) , 0 ) ;
int ttxMax = std : : min < int > ( ( int ) ceil ( std : : max ( std : : max ( ttx0 , ttx1 ) , std : : max ( ttx2 , ttx3 ) ) ) , sfcTarget - > Wdt ) ;
int ttyMin = std : : max < int > ( ( int ) floor ( std : : min ( std : : min ( tty0 , tty1 ) , std : : min ( tty2 , tty3 ) ) ) , 0 ) ;
int ttyMax = std : : min < int > ( ( int ) ceil ( std : : max ( std : : max ( tty0 , tty1 ) , std : : max ( tty2 , tty3 ) ) ) , sfcTarget - > Hgt ) ;
2009-05-08 13:28:41 +00:00
// blit within target rect
for ( int y = ttyMin ; y < ttyMax ; + + y )
for ( int x = ttxMin ; x < ttxMax ; + + x )
2010-03-28 18:58:01 +00:00
{
2009-05-08 13:28:41 +00:00
float ffx = ( float ) x , ffy = ( float ) y ;
TransformBack . TransformPoint ( ffx , ffy ) ;
int ifx = static_cast < int > ( ffx ) , ify = static_cast < int > ( ffy ) ;
if ( ifx < fx | | ify < fy | | ifx > = fx + fwdt | | ify > = fy + fhgt ) continue ;
sfcTarget - > BltPix ( x , y , sfcSource , ifx , ify , ! ! fSrcColKey ) ;
2010-03-28 18:58:01 +00:00
}
2009-05-08 13:28:41 +00:00
// Unlock the surfaces
sfcSource - > Unlock ( ) ;
sfcTarget - > Unlock ( ) ;
2009-08-15 18:50:32 +00:00
return true ;
2010-03-28 18:58:01 +00:00
}
2009-05-08 13:28:41 +00:00
2013-05-25 12:18:20 +00:00
bool C4Draw : : BlitSimple ( C4Surface * sfcSource , int fx , int fy , int fwdt , int fhgt ,
2011-10-03 14:07:07 +00:00
C4Surface * sfcTarget , int tx , int ty , int twdt , int thgt ,
2013-05-25 12:18:20 +00:00
bool fTransparency )
2010-03-28 18:58:01 +00:00
{
2009-05-08 13:28:41 +00:00
// rendertarget?
if ( sfcTarget - > IsRenderTarget ( ) )
2010-03-28 18:58:01 +00:00
{
2013-05-25 12:18:20 +00:00
return Blit ( sfcSource , float ( fx ) , float ( fy ) , float ( fwdt ) , float ( fhgt ) , sfcTarget , float ( tx ) , float ( ty ) , float ( twdt ) , float ( thgt ) , true ) ;
2010-03-28 18:58:01 +00:00
}
2013-05-25 12:18:20 +00:00
// Object is first stretched to dest rect
int xcnt , ycnt , tcx , tcy , cpcx , cpcy ;
2010-03-27 16:05:02 +00:00
if ( ! fwdt | | ! fhgt | | ! twdt | | ! thgt ) return false ;
// Lock the surfaces
if ( ! sfcSource - > Lock ( ) )
return false ;
if ( ! sfcTarget - > Lock ( ) )
{ sfcSource - > Unlock ( ) ; return false ; }
// Rectangle centers
tcx = twdt / 2 ; tcy = thgt / 2 ;
2013-05-25 12:18:20 +00:00
for ( ycnt = 0 ; ycnt < thgt ; ycnt + + )
if ( Inside ( cpcy = ty + tcy - thgt / 2 + ycnt , 0 , sfcTarget - > Hgt - 1 ) )
for ( xcnt = 0 ; xcnt < twdt ; xcnt + + )
if ( Inside ( cpcx = tx + tcx - twdt / 2 + xcnt , 0 , sfcTarget - > Wdt - 1 ) )
sfcTarget - > BltPix ( cpcx , cpcy , sfcSource , xcnt * fwdt / twdt + fx , ycnt * fhgt / thgt + fy , fTransparency ) ;
2010-03-27 16:05:02 +00:00
// Unlock the surfaces
2009-05-08 13:28:41 +00:00
sfcSource - > Unlock ( ) ;
sfcTarget - > Unlock ( ) ;
2010-03-27 16:05:02 +00:00
return true ;
2010-03-28 18:58:01 +00:00
}
2009-05-08 13:28:41 +00:00
2011-10-03 14:34:08 +00:00
bool C4Draw : : Error ( const char * szMsg )
2010-03-28 18:58:01 +00:00
{
2009-05-12 21:42:34 +00:00
if ( pApp ) pApp - > Error ( szMsg ) ;
2009-05-08 13:28:41 +00:00
Log ( szMsg ) ; return false ;
2010-03-28 18:58:01 +00:00
}
2009-05-08 13:28:41 +00:00
2011-10-03 14:34:08 +00:00
bool C4Draw : : CreatePrimaryClipper ( unsigned int iXRes , unsigned int iYRes )
2010-03-28 18:58:01 +00:00
{
2009-05-08 13:28:41 +00:00
// simply setup primary viewport
// assume no zoom has been set yet
assert ( Zoom = = 1.0f ) ;
2010-04-26 23:32:45 +00:00
SetPrimaryClipper ( 0 , 0 , iXRes - 1 , iYRes - 1 ) ;
2009-05-08 13:28:41 +00:00
StorePrimaryClipper ( ) ;
2009-08-15 18:50:32 +00:00
return true ;
2010-03-28 18:58:01 +00:00
}
2009-05-08 13:28:41 +00:00
2011-10-03 14:34:08 +00:00
bool C4Draw : : BlitSurface ( C4Surface * sfcSurface , C4Surface * sfcTarget , int tx , int ty , bool fBlitBase )
2010-03-28 18:58:01 +00:00
{
2009-05-08 13:28:41 +00:00
if ( fBlitBase )
2010-03-28 18:58:01 +00:00
{
2009-05-08 13:28:41 +00:00
Blit ( sfcSurface , 0.0f , 0.0f , ( float ) sfcSurface - > Wdt , ( float ) sfcSurface - > Hgt , sfcTarget , float ( tx ) , float ( ty ) , float ( sfcSurface - > Wdt ) , float ( sfcSurface - > Hgt ) , false ) ;
2009-08-15 18:50:32 +00:00
return true ;
2010-03-28 18:58:01 +00:00
}
2009-05-08 13:28:41 +00:00
else
2010-03-28 18:58:01 +00:00
{
2009-08-15 18:50:32 +00:00
if ( ! sfcSurface ) return false ;
2011-10-03 14:06:41 +00:00
C4Surface * pSfcBase = sfcSurface - > pMainSfc ;
2009-05-08 13:28:41 +00:00
sfcSurface - > pMainSfc = NULL ;
Blit ( sfcSurface , 0.0f , 0.0f , ( float ) sfcSurface - > Wdt , ( float ) sfcSurface - > Hgt , sfcTarget , float ( tx ) , float ( ty ) , float ( sfcSurface - > Wdt ) , float ( sfcSurface - > Hgt ) , false ) ;
sfcSurface - > pMainSfc = pSfcBase ;
2009-08-15 18:50:32 +00:00
return true ;
2010-03-27 16:05:02 +00:00
}
2010-03-28 18:58:01 +00:00
}
2009-05-08 13:28:41 +00:00
2015-09-12 22:14:18 +00:00
bool C4Draw : : BlitSurfaceTile ( C4Surface * sfcSurface , C4Surface * sfcTarget , float iToX , float iToY , float iToWdt , float iToHgt , float iOffsetX , float iOffsetY , C4ShaderCall * shader_call )
2015-09-12 20:07:01 +00:00
{
// Only direct rendering from single, tileable, texture
if ( ! sfcTarget - > IsRenderTarget ( ) ) return false ;
2016-02-08 15:14:59 +00:00
if ( ( sfcSurface - > texture - > iFlags & C4SF_Tileable ) = = 0 ) return false ;
2015-09-12 20:07:01 +00:00
// source surface dimensions
const float sourceWdt = sfcSurface - > Wdt ;
const float sourceHgt = sfcSurface - > Hgt ;
// vertex positions
C4BltVertex vertices [ 6 ] ;
vertices [ 0 ] . ftx = iToX ; vertices [ 0 ] . fty = iToY ; vertices [ 0 ] . ftz = 0.0f ;
vertices [ 0 ] . tx = ( 0.0f + iOffsetX ) / sourceWdt ; vertices [ 0 ] . ty = ( 0.0f + iOffsetY ) / sourceHgt ;
DwTo4UB ( 0xffffffff , vertices [ 0 ] . color ) ;
vertices [ 1 ] . ftx = iToX + iToWdt ; vertices [ 1 ] . fty = iToY ; vertices [ 1 ] . ftz = 0.0f ;
vertices [ 1 ] . tx = ( iToWdt + iOffsetX ) / sourceWdt ; vertices [ 1 ] . ty = ( 0.0f + iOffsetY ) / sourceHgt ;
DwTo4UB ( 0xffffffff , vertices [ 1 ] . color ) ;
vertices [ 2 ] . ftx = iToX + iToWdt ; vertices [ 2 ] . fty = iToY + iToHgt ; vertices [ 2 ] . ftz = 0.0f ;
vertices [ 2 ] . tx = ( iToWdt + iOffsetX ) / sourceWdt ; vertices [ 2 ] . ty = ( iToHgt + iOffsetY ) / sourceHgt ;
DwTo4UB ( 0xffffffff , vertices [ 2 ] . color ) ;
vertices [ 3 ] . ftx = iToX ; vertices [ 3 ] . fty = iToY + iToHgt ; vertices [ 3 ] . ftz = 0.0f ;
vertices [ 3 ] . tx = ( 0.0f + iOffsetX ) / sourceWdt ; vertices [ 3 ] . ty = ( iToHgt + iOffsetY ) / sourceHgt ;
DwTo4UB ( 0xffffffff , vertices [ 3 ] . color ) ;
// duplicate vertices
vertices [ 4 ] = vertices [ 0 ] ; vertices [ 5 ] = vertices [ 2 ] ;
// Draw
2016-02-08 15:14:59 +00:00
PerformMultiTris ( sfcTarget , vertices , 6 , NULL , sfcSurface - > texture . get ( ) , NULL , NULL , 0 , shader_call ) ;
2009-08-15 18:50:32 +00:00
return true ;
2010-03-28 18:58:01 +00:00
}
2009-05-08 13:28:41 +00:00
2011-10-03 14:34:08 +00:00
bool C4Draw : : TextOut ( const char * szText , CStdFont & rFont , float fZoom , C4Surface * sfcDest , float iTx , float iTy , DWORD dwFCol , BYTE byForm , bool fDoMarkup )
2010-03-28 18:58:01 +00:00
{
2011-08-27 19:13:15 +00:00
C4Markup Markup ( true ) ;
2009-05-08 13:28:41 +00:00
static char szLinebuf [ 2500 + 1 ] ;
2013-10-18 16:49:21 +00:00
for ( int cnt = 0 ; SCopySegmentEx ( szText , cnt , szLinebuf , fDoMarkup ? ' | ' : ' \n ' , ' \n ' , 2500 ) ; cnt + + , iTy + = int ( fZoom * rFont . GetLineHeight ( ) ) )
2009-08-15 18:50:32 +00:00
if ( ! StringOut ( szLinebuf , sfcDest , iTx , iTy , dwFCol , byForm , fDoMarkup , Markup , & rFont , fZoom ) ) return false ;
return true ;
2010-03-28 18:58:01 +00:00
}
2009-05-08 13:28:41 +00:00
2011-10-03 14:34:08 +00:00
bool C4Draw : : StringOut ( const char * szText , CStdFont & rFont , float fZoom , C4Surface * sfcDest , float iTx , float iTy , DWORD dwFCol , BYTE byForm , bool fDoMarkup )
2010-03-28 18:58:01 +00:00
{
2009-05-08 13:28:41 +00:00
// init markup
2011-08-27 19:13:15 +00:00
C4Markup Markup ( true ) ;
2009-05-08 13:28:41 +00:00
// output string
return StringOut ( szText , sfcDest , iTx , iTy , dwFCol , byForm , fDoMarkup , Markup , & rFont , fZoom ) ;
2010-03-28 18:58:01 +00:00
}
2009-05-08 13:28:41 +00:00
2011-10-03 14:34:08 +00:00
bool C4Draw : : StringOut ( const char * szText , C4Surface * sfcDest , float iTx , float iTy , DWORD dwFCol , BYTE byForm , bool fDoMarkup , C4Markup & Markup , CStdFont * pFont , float fZoom )
2010-03-28 18:58:01 +00:00
{
2009-05-08 13:28:41 +00:00
// clip
if ( ClipAll ) return true ;
// safety
if ( ! PrepareRendering ( sfcDest ) ) return false ;
// convert align
int iFlags = 0 ;
switch ( byForm )
2010-03-28 18:58:01 +00:00
{
case ACenter : iFlags | = STDFONT_CENTERED ; break ;
case ARight : iFlags | = STDFONT_RIGHTALGN ; break ;
}
2009-05-08 13:28:41 +00:00
if ( ! fDoMarkup ) iFlags | = STDFONT_NOMARKUP ;
// draw text
pFont - > DrawText ( sfcDest , iTx , iTy , dwFCol , szText , iFlags , Markup , fZoom ) ;
// done, success
return true ;
2010-03-28 18:58:01 +00:00
}
2009-05-08 13:28:41 +00:00
2011-10-03 14:34:08 +00:00
void C4Draw : : DrawPix ( C4Surface * sfcDest , float tx , float ty , DWORD dwClr )
2010-03-28 18:58:01 +00:00
{
2009-05-08 13:28:41 +00:00
// Draw
2014-10-08 02:51:34 +00:00
C4BltVertex vtx ;
vtx . ftx = tx ;
vtx . fty = ty ;
DwTo4UB ( dwClr , vtx . color ) ;
2015-09-12 22:14:18 +00:00
PerformMultiPix ( sfcDest , & vtx , 1 , NULL ) ;
2010-03-28 18:58:01 +00:00
}
2009-05-08 13:28:41 +00:00
2012-06-08 14:19:36 +00:00
void C4Draw : : DrawLineDw ( C4Surface * sfcTarget , float x1 , float y1 , float x2 , float y2 , DWORD dwClr , float width )
2010-03-28 18:58:01 +00:00
{
2014-10-08 04:38:16 +00:00
C4BltVertex vertices [ 2 ] ;
vertices [ 0 ] . ftx = x1 ; vertices [ 0 ] . fty = y1 ;
2014-10-18 17:02:14 +00:00
vertices [ 1 ] . ftx = x2 ; vertices [ 1 ] . fty = y2 ;
2014-10-08 04:38:16 +00:00
DwTo4UB ( dwClr , vertices [ 0 ] . color ) ;
DwTo4UB ( dwClr , vertices [ 1 ] . color ) ;
2015-09-12 22:14:18 +00:00
PerformMultiLines ( sfcTarget , vertices , 2 , width , NULL ) ;
2010-03-28 18:58:01 +00:00
}
2009-05-08 13:28:41 +00:00
2011-10-03 14:34:08 +00:00
void C4Draw : : DrawFrameDw ( C4Surface * sfcDest , int x1 , int y1 , int x2 , int y2 , DWORD dwClr ) // make these parameters float...?
2010-03-28 18:58:01 +00:00
{
2014-10-08 04:38:16 +00:00
C4BltVertex vertices [ 8 ] ;
vertices [ 0 ] . ftx = x1 ; vertices [ 0 ] . fty = y1 ;
vertices [ 1 ] . ftx = x2 ; vertices [ 1 ] . fty = y1 ;
vertices [ 2 ] = vertices [ 1 ] ;
vertices [ 3 ] . ftx = x2 ; vertices [ 3 ] . fty = y2 ;
vertices [ 4 ] = vertices [ 3 ] ;
vertices [ 5 ] . ftx = x1 ; vertices [ 5 ] . fty = y2 ;
vertices [ 6 ] = vertices [ 5 ] ;
vertices [ 7 ] = vertices [ 0 ] ;
for ( int i = 0 ; i < 8 ; + + i )
DwTo4UB ( dwClr , vertices [ i ] . color ) ;
2015-09-12 22:14:18 +00:00
PerformMultiLines ( sfcDest , vertices , 8 , 1.0f , NULL ) ;
2010-03-28 18:58:01 +00:00
}
2009-05-08 13:28:41 +00:00
2015-09-12 22:14:18 +00:00
void C4Draw : : DrawQuadDw ( C4Surface * sfcTarget , float * ipVtx , DWORD dwClr1 , DWORD dwClr2 , DWORD dwClr3 , DWORD dwClr4 , C4ShaderCall * shader_call )
2014-11-04 16:00:37 +00:00
{
C4BltVertex vertices [ 6 ] ;
vertices [ 0 ] . ftx = ipVtx [ 0 ] ; vertices [ 0 ] . fty = ipVtx [ 1 ] ;
vertices [ 1 ] . ftx = ipVtx [ 2 ] ; vertices [ 1 ] . fty = ipVtx [ 3 ] ;
vertices [ 2 ] . ftx = ipVtx [ 4 ] ; vertices [ 2 ] . fty = ipVtx [ 5 ] ;
vertices [ 3 ] . ftx = ipVtx [ 6 ] ; vertices [ 3 ] . fty = ipVtx [ 7 ] ;
DwTo4UB ( dwClr1 , vertices [ 0 ] . color ) ;
DwTo4UB ( dwClr2 , vertices [ 1 ] . color ) ;
DwTo4UB ( dwClr3 , vertices [ 2 ] . color ) ;
DwTo4UB ( dwClr4 , vertices [ 3 ] . color ) ;
vertices [ 4 ] = vertices [ 0 ] ;
vertices [ 5 ] = vertices [ 2 ] ;
2015-09-12 22:14:18 +00:00
PerformMultiTris ( sfcTarget , vertices , 6 , NULL , NULL , NULL , NULL , 0 , shader_call ) ;
2014-11-04 16:00:37 +00:00
}
2011-10-03 14:34:08 +00:00
void C4Draw : : DrawPatternedCircle ( C4Surface * sfcDest , int x , int y , int r , BYTE col , C4Pattern & Pattern , CStdPalette & rPal )
2010-03-28 18:58:01 +00:00
{
2014-12-14 14:20:57 +00:00
bool fRenderTarget = sfcDest - > IsRenderTarget ( ) ;
if ( ! fRenderTarget ) if ( ! sfcDest - > Lock ( ) ) return ;
2009-05-08 13:28:41 +00:00
for ( int ycnt = - r ; ycnt < r ; ycnt + + )
2010-03-28 18:58:01 +00:00
{
2014-12-14 14:20:57 +00:00
int lwdt = ( int ) sqrt ( float ( r * r - ycnt * ycnt ) ) ;
2009-05-08 13:28:41 +00:00
// Set line
2014-12-14 14:20:57 +00:00
if ( fRenderTarget )
2010-03-28 18:58:01 +00:00
{
2014-12-14 14:20:57 +00:00
for ( int xcnt = x - lwdt ; xcnt < x + lwdt ; + + xcnt )
{
DrawPix ( sfcDest , xcnt , y + ycnt , Pattern . PatternClr ( xcnt , y + ycnt ) ) ;
}
}
else
2010-03-28 18:58:01 +00:00
{
2014-12-14 14:20:57 +00:00
for ( int xcnt = x - lwdt ; xcnt < x + lwdt ; + + xcnt )
{
sfcDest - > SetPixDw ( xcnt , y + ycnt , Pattern . PatternClr ( xcnt , y + ycnt ) ) ;
}
2009-05-08 13:28:41 +00:00
}
}
2014-12-14 14:20:57 +00:00
if ( ! fRenderTarget ) sfcDest - > Unlock ( ) ;
2010-03-28 18:58:01 +00:00
}
2009-05-08 13:28:41 +00:00
2011-10-03 14:34:08 +00:00
void C4Draw : : Grayscale ( C4Surface * sfcSfc , int32_t iOffset )
2010-03-28 18:58:01 +00:00
{
2009-05-08 13:28:41 +00:00
// safety
if ( ! sfcSfc ) return ;
// change colors
int xcnt , ycnt , wdt = sfcSfc - > Wdt , hgt = sfcSfc - > Hgt ;
// Lock surface
if ( ! sfcSfc - > Lock ( ) ) return ;
for ( ycnt = 0 ; ycnt < hgt ; ycnt + + )
2010-03-28 18:58:01 +00:00
{
2009-05-08 13:28:41 +00:00
for ( xcnt = 0 ; xcnt < wdt ; xcnt + + )
2010-03-28 18:58:01 +00:00
{
2009-05-08 13:28:41 +00:00
DWORD dwColor = sfcSfc - > GetPixDw ( xcnt , ycnt , false ) ;
2011-03-11 02:37:27 +00:00
uint32_t r = GetRedValue ( dwColor ) , g = GetGreenValue ( dwColor ) , b = GetBlueValue ( dwColor ) , a = dwColor > > 24 ;
2015-02-12 22:05:55 +00:00
int32_t gray = Clamp < int32_t > ( ( r + g + b ) / 3 + iOffset , 0 , 255 ) ;
2009-05-08 13:28:41 +00:00
sfcSfc - > SetPixDw ( xcnt , ycnt , RGBA ( gray , gray , gray , a ) ) ;
}
}
2010-03-28 18:58:01 +00:00
sfcSfc - > Unlock ( ) ;
}
2009-05-08 13:28:41 +00:00
2011-10-03 14:34:08 +00:00
bool C4Draw : : GetPrimaryClipper ( int & rX1 , int & rY1 , int & rX2 , int & rY2 )
2010-03-28 18:58:01 +00:00
{
2009-05-08 13:28:41 +00:00
// Store drawing clip values
2010-03-28 18:58:01 +00:00
rX1 = fClipX1 ; rY1 = fClipY1 ; rX2 = fClipX2 ; rY2 = fClipY2 ;
2009-05-08 13:28:41 +00:00
// Done
2009-08-15 18:50:32 +00:00
return true ;
2010-03-28 18:58:01 +00:00
}
2009-05-08 13:28:41 +00:00
2014-11-23 21:26:09 +00:00
C4Rect C4Draw : : GetClipRect ( ) const
{
2015-11-15 12:53:01 +00:00
int iWdt = std : : min ( iClipX2 , RenderTarget - > Wdt - 1 ) - iClipX1 + 1 ;
int iHgt = std : : min ( iClipY2 , RenderTarget - > Hgt - 1 ) - iClipY1 + 1 ;
2014-11-23 21:26:09 +00:00
int iX = iClipX1 ; if ( iX < 0 ) { iWdt + = iX ; iX = 0 ; }
int iY = iClipY1 ; if ( iY < 0 ) { iHgt + = iY ; iY = 0 ; }
return C4Rect ( iX , iY , iWdt , iHgt ) ;
}
2014-12-26 15:16:09 +00:00
C4Rect C4Draw : : GetOutRect ( ) const
{
return C4Rect ( 0 , 0 , RenderTarget - > Wdt , RenderTarget - > Hgt ) ;
}
2015-08-31 15:34:01 +00:00
void C4Draw : : SetGamma ( float r , float g , float b , int32_t iRampIndex )
2010-03-28 18:58:01 +00:00
{
2015-08-31 15:34:01 +00:00
// Set
gamma [ iRampIndex ] [ 0 ] = r ;
gamma [ iRampIndex ] [ 1 ] = g ;
gamma [ iRampIndex ] [ 2 ] = b ;
// Recalculate resulting gamma. Note that we flip gamma direction here,
// because higher gammaOut means darker.
gammaOut [ 0 ] = gammaOut [ 1 ] = gammaOut [ 2 ] = 1.0f ;
for ( int i = 0 ; i < C4MaxGammaRamps ; i + + ) {
gammaOut [ 0 ] / = gamma [ i ] [ 0 ] ;
gammaOut [ 1 ] / = gamma [ i ] [ 1 ] ;
gammaOut [ 2 ] / = gamma [ i ] [ 2 ] ;
}
2010-10-01 21:36:48 +00:00
}
2013-11-09 16:11:29 +00:00
void C4Draw : : ResetGamma ( )
{
2015-08-31 15:34:01 +00:00
for ( int i = 0 ; i < C4MaxGammaRamps ; i + + ) {
gamma [ i ] [ 0 ] = 1.0f ;
gamma [ i ] [ 1 ] = 1.0f ;
gamma [ i ] [ 2 ] = 1.0f ;
2010-10-01 21:36:48 +00:00
}
2015-08-31 15:34:01 +00:00
gammaOut [ 0 ] = 1.0f ;
gammaOut [ 1 ] = 1.0f ;
gammaOut [ 2 ] = 1.0f ;
2010-03-28 18:58:01 +00:00
}
2009-05-08 13:28:41 +00:00
2011-10-03 14:34:08 +00:00
DWORD C4Draw : : ApplyGammaTo ( DWORD dwClr )
2010-03-28 18:58:01 +00:00
{
2015-08-31 15:34:01 +00:00
return C4RGB ( int ( pow ( float ( GetRedValue ( dwClr ) ) / 255.0f , gammaOut [ 0 ] ) * 255.0 ) ,
int ( pow ( float ( GetGreenValue ( dwClr ) ) / 255.0f , gammaOut [ 1 ] ) * 255.0 ) ,
int ( pow ( float ( GetBlueValue ( dwClr ) ) / 255.0f , gammaOut [ 2 ] ) * 255.0 ) ) ;
2010-03-28 18:58:01 +00:00
}
2009-05-08 13:28:41 +00:00
2015-01-07 16:29:48 +00:00
void C4Draw : : SetZoom ( float X , float Y , float Zoom )
2010-03-28 18:58:01 +00:00
{
2009-05-08 13:28:41 +00:00
this - > ZoomX = X ; this - > ZoomY = Y ; this - > Zoom = Zoom ;
2010-03-28 18:58:01 +00:00
}
2009-05-08 13:28:41 +00:00
2011-10-03 14:34:08 +00:00
void C4Draw : : ApplyZoom ( float & X , float & Y )
2010-03-28 18:58:01 +00:00
{
2009-05-08 13:28:41 +00:00
X = ( X - ZoomX ) * Zoom + ZoomX ;
Y = ( Y - ZoomY ) * Zoom + ZoomY ;
2010-03-28 18:58:01 +00:00
}
2009-05-08 13:28:41 +00:00
2011-10-03 14:34:08 +00:00
void C4Draw : : RemoveZoom ( float & X , float & Y )
2010-03-28 18:58:01 +00:00
{
2009-05-08 13:28:41 +00:00
X = ( X - ZoomX ) / Zoom + ZoomX ;
Y = ( Y - ZoomY ) / Zoom + ZoomY ;
2010-03-28 18:58:01 +00:00
}
2009-05-08 13:28:41 +00:00
2016-02-01 22:59:38 +00:00
bool DDrawInit ( C4AbstractApp * pApp , unsigned int iXRes , unsigned int iYRes , unsigned int iMonitor )
2010-03-28 18:58:01 +00:00
{
2009-05-08 13:28:41 +00:00
// create engine
2013-10-29 13:27:18 +00:00
# ifndef USE_CONSOLE
pDraw = new CStdGL ( ) ;
# else
pDraw = new CStdNoGfx ( ) ;
# endif
2011-10-03 14:30:18 +00:00
if ( ! pDraw ) return false ;
2009-05-08 13:28:41 +00:00
// init it
2016-02-01 22:59:38 +00:00
if ( ! pDraw - > Init ( pApp , iXRes , iYRes , iMonitor ) )
2010-03-28 18:58:01 +00:00
{
2011-10-03 14:30:18 +00:00
delete pDraw ;
2010-09-28 18:35:26 +00:00
return false ;
2010-03-28 18:58:01 +00:00
}
2009-05-08 13:28:41 +00:00
// done, success
2010-09-28 18:35:26 +00:00
return true ;
2010-03-28 18:58:01 +00:00
}
2009-05-08 13:28:41 +00:00
2016-02-01 22:59:38 +00:00
bool C4Draw : : Init ( C4AbstractApp * pApp , unsigned int iXRes , unsigned int iYRes , unsigned int iMonitor )
2010-03-28 18:58:01 +00:00
{
2009-05-08 13:28:41 +00:00
this - > pApp = pApp ;
2011-10-03 14:06:41 +00:00
pApp - > pWindow - > pSurface = new C4Surface ( pApp , pApp - > pWindow ) ;
2010-03-06 14:07:30 +00:00
2016-02-06 22:32:00 +00:00
if ( ! RestoreDeviceObjects ( ) )
2009-06-02 23:59:04 +00:00
return false ;
2009-05-08 13:28:41 +00:00
if ( ! CreatePrimaryClipper ( iXRes , iYRes ) )
return Error ( " Clipper failure. " ) ;
2009-08-15 18:50:32 +00:00
return true ;
2010-03-28 18:58:01 +00:00
}
2009-05-08 13:28:41 +00:00
2015-09-12 22:14:18 +00:00
void C4Draw : : DrawBoxFade ( C4Surface * sfcDest , float iX , float iY , float iWdt , float iHgt , DWORD dwClr1 , DWORD dwClr2 , DWORD dwClr3 , DWORD dwClr4 , C4ShaderCall * shader_call )
2010-03-28 18:58:01 +00:00
{
2009-05-08 13:28:41 +00:00
// set vertex buffer data
// vertex order:
// 0=upper left dwClr1
// 1=lower left dwClr3
// 2=lower right dwClr4
// 3=upper right dwClr2
float vtx [ 8 ] ;
vtx [ 0 ] = iX ; vtx [ 1 ] = iY ;
vtx [ 2 ] = iX ; vtx [ 3 ] = iY + iHgt ;
vtx [ 4 ] = iX + iWdt ; vtx [ 5 ] = iY + iHgt ;
vtx [ 6 ] = iX + iWdt ; vtx [ 7 ] = iY ;
2015-09-12 22:14:18 +00:00
DrawQuadDw ( sfcDest , vtx , dwClr1 , dwClr3 , dwClr4 , dwClr2 , shader_call ) ;
2010-03-28 18:58:01 +00:00
}
2009-05-08 13:28:41 +00:00
2011-10-03 14:34:08 +00:00
void C4Draw : : DrawBoxDw ( C4Surface * sfcDest , int iX1 , int iY1 , int iX2 , int iY2 , DWORD dwClr )
2010-03-28 18:58:01 +00:00
{
2014-12-13 14:14:51 +00:00
if ( ! sfcDest - > IsRenderTarget ( ) )
{
// Box on non-render target: Emulate by setting pixels
if ( ! sfcDest - > Lock ( ) ) return ;
for ( int y = iY1 ; y < = iY2 ; + + y )
for ( int x = iX1 ; x < = iX2 ; + + x )
sfcDest - > SetPixDw ( x , y , dwClr ) ;
sfcDest - > Unlock ( ) ;
}
else
{
2015-09-12 22:14:18 +00:00
DrawBoxFade ( sfcDest , float ( iX1 ) , float ( iY1 ) , float ( iX2 - iX1 + 1 ) , float ( iY2 - iY1 + 1 ) , dwClr , dwClr , dwClr , dwClr , NULL ) ;
2014-12-13 14:14:51 +00:00
}
2010-03-28 18:58:01 +00:00
}