35 #if defined(_WIN32) && !defined(USE_CONSOLE)
37 __declspec(dllexport)
DWORD NvOptimusEnablement = 0x00000001;
49 float fAngle = iAngle * -0.0174532925f;
50 float fsin = sinf(fAngle);
float fcos = cosf(fAngle);
52 mat[0] = +fcos;
mat[1] = +fsin;
mat[2] = (1-fcos)*fOffX - fsin*fOffY;
53 mat[3] = -fsin;
mat[4] = +fcos;
mat[5] = (1-fcos)*fOffY + fsin*fOffX;
71 if (!det) {
Set(1,0,0,0,1,0,0,0,1);
return false; }
87 float fW =
mat[6] * rX +
mat[7] * rY +
mat[8];
89 float fX = (
mat[0] * rX +
mat[1] * rY +
mat[2]) / fW;
90 rY = (
mat[3] * rX +
mat[4] * rY +
mat[5]) / fW;
96 sfcPattern32 = nPattern.sfcPattern32;
97 if (sfcPattern32) sfcPattern32->
Lock();
98 delete [] CachedPattern;
99 if (nPattern.CachedPattern)
101 CachedPattern =
new uint32_t[sfcPattern32->
Wdt * sfcPattern32->
Hgt];
102 memcpy(CachedPattern, nPattern.CachedPattern, sfcPattern32->
Wdt * sfcPattern32->
Hgt * 4);
106 CachedPattern =
nullptr;
110 Zoom = nPattern.Zoom;
117 if (!sfcSource)
return false;
121 sfcPattern32=sfcSource;
122 sfcPattern32->
Lock();
123 Wdt = sfcPattern32->
Wdt;
124 Hgt = sfcPattern32->
Hgt;
128 CachedPattern =
new uint32_t[Wdt * Hgt];
129 if (!CachedPattern)
return false;
130 for (
int y = 0; y < Hgt; ++y)
131 for (
int x = 0; x < Wdt; ++x)
133 CachedPattern[y * Wdt + x] = sfcPattern32->
GetPixDw(x, y,
false);
141 sfcPattern32=
nullptr;
142 CachedPattern =
nullptr;
154 sfcPattern32=
nullptr;
156 delete[] CachedPattern; CachedPattern =
nullptr;
161 if (!CachedPattern)
return 0;
163 iX %= Wdt; iY %= Hgt;
164 return CachedPattern[iY * Wdt + iX];
246 C4Surface * sfcTarget,
float tx,
float ty,
float wdt,
float hgt)
248 Blit(sfcSource, fx, fy, wdt, hgt, sfcTarget, tx, ty, wdt, hgt,
false);
252 C4Surface * sfcTarget,
int tx,
int ty,
int wdt,
int hgt)
258 if (!fRender)
if (!sfcTarget->
Lock())
261 float tfx = tx, tfy = ty, twdt = wdt, thgt = hgt;
270 static const int BUF_SIZE = 1024;
274 for (
int ycnt=0; ycnt<thgt; ++ycnt)
276 for (
int xcnt=0; xcnt<twdt; ++xcnt)
278 BYTE byPix = sfcSource->
GetPix(fx+wdt*xcnt/twdt, fy+hgt*ycnt/thgt);
281 vertices[bufcnt].
ftx = (float)(tx + xcnt /
Zoom);
282 vertices[bufcnt].
fty = (float)(ty + ycnt /
Zoom);
283 DwTo4UB(dwClr, vertices[bufcnt].color);
286 if(bufcnt == BUF_SIZE)
298 if (!fRender) sfcTarget->
Unlock();
302 C4Surface * sfcTarget,
float tx,
float ty,
float twdt,
float thgt,
306 sfcTarget, tx, ty, twdt, thgt, fSrcColKey, pTransform);
310 C4Surface * sfcTarget,
float tx,
float ty,
float twdt,
float thgt,
314 if (!sfcSource || !sfcTarget || !twdt || !thgt || !fwdt || !fhgt)
return false;
319 if(pTransform &&
Zoom != 1.0)
323 pTransform->
mat[6], pTransform->
mat[7], pTransform->
mat[8]);
333 return Blit8(sfcSource,
int(fx),
int(fy),
int(fwdt),
int(fhgt), sfcTarget,
int(tx),
int(ty),
int(twdt),
int(thgt), fSrcColKey, pTransform);
339 if (twdt<=0 || thgt<=0)
return false;
349 return Blit8(sfcSource,
int(fx),
int(fy),
int(fwdt),
int(fhgt), sfcTarget,
int(tx),
int(ty),
int(twdt),
int(thgt), fSrcColKey);
360 vertices[0].
ftx = tx; vertices[0].
fty = ty;
361 vertices[1].
ftx = tx + twdt; vertices[1].
fty = ty;
362 vertices[2].
ftx = tx + twdt; vertices[2].
fty = ty + thgt;
363 vertices[3].
ftx = tx; vertices[3].
fty = ty + thgt;
365 vertices[1].
tx = (fx + fwdt) / pTex->
iSizeX; vertices[1].
ty = fy / pTex->
iSizeY;
366 vertices[2].
tx = (fx + fwdt) / pTex->
iSizeX; vertices[2].
ty = (fy + fhgt) / pTex->
iSizeY;
367 vertices[3].
tx = fx / pTex->
iSizeX; vertices[3].
ty = (fy + fhgt) / pTex->
iSizeY;
368 DwTo4UB(0xffffffff, vertices[0].color);
369 DwTo4UB(0xffffffff, vertices[1].color);
370 DwTo4UB(0xffffffff, vertices[2].color);
371 DwTo4UB(0xffffffff, vertices[3].color);
374 vertices[4] = vertices[0]; vertices[5] = vertices[2];
392 PerformMultiTris(sfcTarget, vertices, 6, pTransform, pBaseTex, fBaseSfc ? pTex :
nullptr, pNormalTex, dwOverlayClrMod,
nullptr);
413 PerformMesh(instance, tx, ty, twdt, thgt, dwPlayerColor, pTransform);
419 C4Surface * sfcTarget,
int tx,
int ty,
int twdt,
int thgt,
422 if (!pTransform)
return BlitSimple(sfcSource, fx, fy, fwdt, fhgt, sfcTarget, tx, ty, twdt, thgt, fSrcColKey!=
false);
424 if (!fwdt || !fhgt)
return true;
426 if (!sfcSource->
Lock())
428 if (!sfcTarget->
Lock())
429 { sfcSource->
Unlock();
return false; }
433 Transform.
SetMoveScale(tx-(
float)fx*twdt/fwdt, ty-(
float)fy*thgt/fhgt, (
float) twdt/fwdt, (
float) thgt/fhgt);
434 Transform *=* pTransform;
437 auto ttx0=(float)tx, tty0=(
float)ty, ttx1=(float)(tx+twdt), tty1=(float)(ty+thgt);
438 auto ttx2=(float)ttx0, tty2=(
float)tty1, ttx3=(float)ttx1, tty3=(
float)tty0;
443 int ttxMin = std::max<int>((
int)floor(std::min(std::min(ttx0, ttx1), std::min(ttx2, ttx3))), 0);
444 int ttxMax = std::min<int>((
int)ceil(std::max(std::max(ttx0, ttx1), std::max(ttx2, ttx3))), sfcTarget->
Wdt);
445 int ttyMin = std::max<int>((
int)floor(std::min(std::min(tty0, tty1), std::min(tty2, tty3))), 0);
446 int ttyMax = std::min<int>((
int)ceil(std::max(std::max(tty0, tty1), std::max(tty2, tty3))), sfcTarget->
Hgt);
448 for (
int y = ttyMin; y < ttyMax; ++y)
449 for (
int x = ttxMin; x < ttxMax; ++x)
451 float ffx=(float)x, ffy=(
float)y;
453 int ifx=
static_cast<int>(ffx), ify=
static_cast<int>(ffy);
454 if (ifx<fx || ify<fy || ifx>=fx+fwdt || ify>=fy+fhgt)
continue;
455 sfcTarget->
BltPix(x,y, sfcSource, ifx,ify, !!fSrcColKey);
464 C4Surface * sfcTarget,
int tx,
int ty,
int twdt,
int thgt,
470 return Blit(sfcSource,
float(fx),
float(fy),
float(fwdt),
float(fhgt), sfcTarget,
float(tx),
float(ty),
float(twdt),
float(thgt),
true);
473 int xcnt,ycnt,tcx,tcy,cpcx,cpcy;
474 if (!fwdt || !fhgt || !twdt || !thgt)
return false;
476 if (!sfcSource->
Lock())
478 if (!sfcTarget->
Lock())
479 { sfcSource->
Unlock();
return false; }
481 tcx=twdt/2; tcy=thgt/2;
482 for (ycnt=0; ycnt<thgt; ycnt++)
483 if (
Inside(cpcy=ty+tcy-thgt/2+ycnt,0,sfcTarget->
Hgt-1))
484 for (xcnt=0; xcnt<twdt; xcnt++)
485 if (
Inside(cpcx=tx+tcx-twdt/2+xcnt,0,sfcTarget->
Wdt-1))
486 sfcTarget->
BltPix(cpcx, cpcy, sfcSource, xcnt*fwdt/twdt+fx, ycnt*fhgt/thgt+fy, fTransparency);
497 Log(szMsg);
return false;
515 Blit(sfcSurface, 0.0f, 0.0f, (
float)sfcSurface->
Wdt, (
float)sfcSurface->
Hgt, sfcTarget,
float(tx),
float(ty),
float(sfcSurface->
Wdt),
float(sfcSurface->
Hgt),
false);
520 if (!sfcSurface)
return false;
523 Blit(sfcSurface, 0.0f, 0.0f, (
float)sfcSurface->
Wdt, (
float)sfcSurface->
Hgt, sfcTarget,
float(tx),
float(ty),
float(sfcSurface->
Wdt),
float(sfcSurface->
Hgt),
false);
536 const float sourceWdt = sfcSurface->
Wdt;
537 const float sourceHgt = sfcSurface->
Hgt;
541 vertices[0].
ftx = iToX; vertices[0].
fty = iToY; vertices[0].
ftz = 0.0f;
542 vertices[0].
tx = (0.0f + iOffsetX) / sourceWdt; vertices[0].
ty = (0.0f + iOffsetY) / sourceHgt;
543 DwTo4UB(0xffffffff, vertices[0].color);
544 vertices[1].
ftx = iToX + iToWdt; vertices[1].
fty = iToY; vertices[1].
ftz = 0.0f;
545 vertices[1].
tx = (iToWdt + iOffsetX) / sourceWdt; vertices[1].
ty = (0.0f + iOffsetY) / sourceHgt;
546 DwTo4UB(0xffffffff, vertices[1].color);
547 vertices[2].
ftx = iToX + iToWdt; vertices[2].
fty = iToY + iToHgt; vertices[2].
ftz = 0.0f;
548 vertices[2].
tx = (iToWdt + iOffsetX) / sourceWdt; vertices[2].
ty = (iToHgt + iOffsetY) / sourceHgt;
549 DwTo4UB(0xffffffff, vertices[2].color);
550 vertices[3].
ftx = iToX; vertices[3].
fty = iToY + iToHgt; vertices[3].
ftz = 0.0f;
551 vertices[3].
tx = (0.0f + iOffsetX) / sourceWdt; vertices[3].
ty = (iToHgt + iOffsetY) / sourceHgt;
552 DwTo4UB(0xffffffff, vertices[3].color);
554 vertices[4] = vertices[0]; vertices[5] = vertices[2];
557 PerformMultiTris(sfcTarget, vertices, 6,
nullptr, sfcSurface->
texture.get(),
nullptr,
nullptr, 0, shader_call);
564 static char szLinebuf[2500+1];
565 for (
int cnt=0;
SCopySegmentEx(szText,cnt,szLinebuf,fDoMarkup ?
'|' :
'\n',
'\n',2500); cnt++,iTy+=int(fZoom*rFont.
GetLineHeight()))
566 if (!
StringOut(szLinebuf,sfcDest,iTx,iTy,dwFCol,byForm,fDoMarkup,Markup,&rFont,fZoom))
return false;
575 return StringOut(szText, sfcDest, iTx, iTy, dwFCol, byForm, fDoMarkup, Markup, &rFont, fZoom);
593 pFont->
DrawText(sfcDest, iTx , iTy , dwFCol, szText, iFlags, Markup, fZoom);
611 vertices[0].
ftx = x1; vertices[0].
fty = y1;
612 vertices[1].
ftx = x2; vertices[1].
fty = y2;
613 DwTo4UB(dwClr, vertices[0].color);
614 DwTo4UB(dwClr, vertices[1].color);
621 int32_t num_lines = 12 + int32_t(r / 10);
622 std::unique_ptr<C4BltVertex[]> vertices(
new C4BltVertex[num_lines * 2]);
623 for (int32_t i = 0; i < num_lines; ++i)
625 float ang = float(i) * 2 * M_PI / num_lines;
626 int32_t iv = i * 2 + 1;
627 vertices[iv].ftx = cx + sin(ang) * r;
628 vertices[iv].fty = cy + cos(ang) * r;
629 DwTo4UB(dwClr, vertices[iv].color);
630 vertices[(iv + 1) % (num_lines * 2)] = vertices[iv];
638 vertices[0].
ftx = x1; vertices[0].
fty = y1;
639 vertices[1].
ftx = x2; vertices[1].
fty = y1;
640 vertices[2] = vertices[1];
641 vertices[3].
ftx = x2; vertices[3].
fty = y2;
642 vertices[4] = vertices[3];
643 vertices[5].
ftx = x1; vertices[5].
fty = y2;
644 vertices[6] = vertices[5];
645 vertices[7] = vertices[0];
647 for(
auto & vertex : vertices)
656 vertices[0].
ftx = ipVtx[0]; vertices[0].
fty = ipVtx[1];
657 vertices[1].
ftx = ipVtx[2]; vertices[1].
fty = ipVtx[3];
658 vertices[2].
ftx = ipVtx[4]; vertices[2].
fty = ipVtx[5];
659 vertices[3].
ftx = ipVtx[6]; vertices[3].
fty = ipVtx[7];
660 DwTo4UB(dwClr1, vertices[0].color);
661 DwTo4UB(dwClr2, vertices[1].color);
662 DwTo4UB(dwClr3, vertices[2].color);
663 DwTo4UB(dwClr4, vertices[3].color);
664 vertices[4] = vertices[0];
665 vertices[5] = vertices[2];
666 PerformMultiTris(sfcTarget, vertices, 6,
nullptr,
nullptr,
nullptr,
nullptr, 0, shader_call);
672 if (!fRenderTarget)
if (!sfcDest->
Lock())
return;
673 for (
int ycnt = -r; ycnt < r; ycnt++)
675 int lwdt = (int)sqrt(
float(r * r - ycnt * ycnt));
679 for (
int xcnt = x - lwdt; xcnt < x + lwdt; ++xcnt)
686 for (
int xcnt = x - lwdt; xcnt < x + lwdt; ++xcnt)
692 if (!fRenderTarget) sfcDest->
Unlock();
700 int xcnt,ycnt,wdt=sfcSfc->
Wdt,hgt=sfcSfc->
Hgt;
702 if (!sfcSfc->
Lock())
return;
703 for (ycnt=0; ycnt<hgt; ycnt++)
705 for (xcnt=0; xcnt<wdt; xcnt++)
709 int32_t gray = Clamp<int32_t>((r + g +
b) / 3 + iOffset, 0, 255);
728 int iX=
iClipX1;
if (iX<0) { iWdt+=iX; iX=0; }
729 int iY=
iClipY1;
if (iY<0) { iHgt+=iY; iY=0; }
730 return C4Rect(iX, iY, iWdt, iHgt);
741 gamma[iRampIndex][0] = r;
742 gamma[iRampIndex][1] = g;
747 for (
auto & i :
gamma) {
756 for (
auto & i :
gamma) {
798 if (!
pDraw)
return false;
800 if (!
pDraw->
Init(pApp, iXRes, iYRes, iMonitor))
819 return Error(
" Clipper failure.");
833 vtx[0] = iX ; vtx[1] = iY;
834 vtx[2] = iX ; vtx[3] = iY+iHgt;
835 vtx[4] = iX+iWdt; vtx[5] = iY+iHgt;
836 vtx[6] = iX+iWdt; vtx[7] = iY;
837 DrawQuadDw(sfcDest, vtx, dwClr1, dwClr3, dwClr4, dwClr2, shader_call);
845 if (!sfcDest->
Lock())
return;
846 for (
int y = iY1; y <= iY2; ++y)
847 for (
int x = iX1; x <= iX2; ++x)
853 DrawBoxFade(sfcDest,
float(iX1),
float(iY1),
float(iX2 - iX1 + 1),
float(iY2 - iY1 + 1), dwClr, dwClr, dwClr, dwClr,
nullptr);
bool DDrawInit(C4AbstractApp *pApp, unsigned int iXRes, unsigned int iYRes, unsigned int iMonitor)
void DwTo4UB(DWORD dwClr, unsigned char(&r)[4])
#define STDFONT_RIGHTALGN
bool Log(const char *szMessage)
bool SCopySegmentEx(const char *szString, int iSegment, char *sTarget, char cSep1, char cSep2, int iMaxL, bool fSkipWhitespace)
bool Inside(T ival, U lbound, V rbound)
uint32_t RGBA(uint32_t r, uint32_t g, uint32_t b, uint32_t a)
#define GetGreenValue(rgb)
#define GetBlueValue(rgb)
void Error(const char *m)
bool SubPrimaryClipper(int iX1, int iY1, int iX2, int iY2)
virtual bool Error(const char *szMsg)
void DrawCircleDw(C4Surface *sfcTarget, float cx, float cy, float r, DWORD dwClr, float width=1.0f)
bool ApplyPrimaryClipper(C4Surface *sfcSurface)
void RemoveZoom(float &X, float &Y)
bool Blit(C4Surface *sfcSource, float fx, float fy, float fwdt, float fhgt, C4Surface *sfcTarget, float tx, float ty, float twdt, float thgt, bool fSrcColKey=false, const C4BltTransform *pTransform=nullptr)
void DrawFrameDw(C4Surface *sfcDest, int x1, int y1, int x2, int y2, DWORD dwClr, float width=1.0f)
void DrawPix(C4Surface *sfcDest, float tx, float ty, DWORD dwCol)
virtual void BlitLandscape(C4Surface *sfcSource, float fx, float fy, C4Surface *sfcTarget, float tx, float ty, float wdt, float hgt)
void Grayscale(C4Surface *sfcSfc, int32_t iOffset=0)
void DrawQuadDw(C4Surface *sfcTarget, float *ipVtx, DWORD dwClr1, DWORD dwClr2, DWORD dwClr3, DWORD dwClr4, C4ShaderCall *shader_call)
const StdMeshMatrix * MeshTransform
bool BlitSimple(C4Surface *sfcSource, int fx, int fy, int fwdt, int fhgt, C4Surface *sfcTarget, int tx, int ty, int twdt, int thgt, bool fTransparency=true)
C4Rect GetClipRect() const
bool RestorePrimaryClipper()
C4Rect GetOutRect() const
bool BlitUnscaled(C4Surface *sfcSource, float fx, float fy, float fwdt, float fhgt, C4Surface *sfcTarget, float tx, float ty, float twdt, float thgt, bool fSrcColKey=false, const C4BltTransform *pTransform=nullptr)
bool GetSurfaceSize(C4Surface *sfcSurface, int &iWdt, int &iHgt)
virtual bool RestoreDeviceObjects()=0
bool StringOut(const char *szText, CStdFont &rFont, float fZoom, C4Surface *sfcDest, float iTx, float iTy, DWORD dwFCol=0xffffffff, BYTE byForm=ALeft, bool fDoMarkup=true)
virtual bool UpdateClipper()=0
bool RenderMesh(StdMeshInstance &instance, C4Surface *sfcTarget, float tx, float ty, float twdt, float thgt, DWORD dwPlayerColor, C4BltTransform *pTransform)
bool BlitSurface(C4Surface *sfcSurface, C4Surface *sfcTarget, int tx, int ty, bool fBlitBase)
virtual void PerformMultiLines(C4Surface *sfcTarget, const C4BltVertex *vertices, unsigned int n_vertices, float width, C4ShaderCall *shader_call)=0
void DrawBoxFade(C4Surface *sfcDest, float iX, float iY, float iWdt, float iHgt, DWORD dwClr1, DWORD dwClr2, DWORD dwClr3, DWORD dwClr4, C4ShaderCall *shader_call)
void DrawBoxDw(C4Surface *sfcDest, int iX1, int iY1, int iX2, int iY2, DWORD dwClr)
bool GetPrimaryClipper(int &rX1, int &rY1, int &rX2, int &rY2)
void SetGamma(float r, float g, float b, int32_t iRampIndex)
bool DetachPrimaryClipper(C4Surface *sfcSurface)
bool StorePrimaryClipper()
void DrawLineDw(C4Surface *sfcTarget, float x1, float y1, float x2, float y2, DWORD dwClr, float width=1.0f)
bool CreatePrimaryClipper(unsigned int iXRes, unsigned int iYRes)
bool Init(C4AbstractApp *pApp, unsigned int iXRes, unsigned int iYRes, unsigned int iMonitor)
void Blit8Fast(CSurface8 *sfcSource, int fx, int fy, C4Surface *sfcTarget, int tx, int ty, int wdt, int hgt)
void SetZoom(float X, float Y, float Zoom)
void DrawPatternedCircle(C4Surface *sfcDest, int x, int y, int r, BYTE col, C4Pattern &Pattern, CStdPalette &rPal)
bool SetPrimaryClipper(int iX1, int iY1, int iX2, int iY2)
virtual void PerformMesh(StdMeshInstance &instance, float tx, float ty, float twdt, float thgt, DWORD dwPlayerColor, C4BltTransform *pTransform)=0
C4ScriptUniform scriptUniform
float gamma[C4MaxGammaRamps][3]
void ApplyZoom(float &X, float &Y)
DWORD ApplyGammaTo(DWORD dwClr)
bool Blit8(C4Surface *sfcSource, int fx, int fy, int fwdt, int fhgt, C4Surface *sfcTarget, int tx, int ty, int twdt, int thgt, bool fSrcColKey=false, const C4BltTransform *pTransform=nullptr)
virtual bool PrepareRendering(C4Surface *sfcToSurface)=0
virtual void PerformMultiTris(C4Surface *sfcTarget, const C4BltVertex *vertices, unsigned int n_vertices, const C4BltTransform *pTransform, C4TexRef *pTex, C4TexRef *pOverlay, C4TexRef *pNormal, DWORD dwOverlayClrMod, C4ShaderCall *shader_call)=0
bool BlitSurfaceTile(C4Surface *sfcSurface, C4Surface *sfcTarget, float iToX, float iToY, float iToWdt, float iToHgt, float iOffsetX, float iOffsetY, C4ShaderCall *shader_call)
virtual void PerformMultiPix(C4Surface *sfcTarget, const C4BltVertex *vertices, unsigned int n_vertices, C4ShaderCall *shader_call)=0
bool TextOut(const char *szText, CStdFont &rFont, float fZoom, C4Surface *sfcDest, float iTx, float iTy, DWORD dwFCol=0xffffffff, BYTE byForm=ALeft, bool fDoMarkup=true)
DWORD PatternClr(unsigned int iX, unsigned int iY) const
bool Set(class C4Surface *sfcSource, int iZoom=0)
C4Pattern & operator=(const C4Pattern &)
bool SetPixDw(int iX, int iY, DWORD dwCol)
DWORD GetPixDw(int iX, int iY, bool fApplyModulation)
std::unique_ptr< C4TexRef > texture
bool GetSurfaceSize(int &irX, int &irY)
bool BltPix(int iX, int iY, C4Surface *sfcSource, int iSrcX, int iSrcY, bool fTransparency)
int GetLineHeight() const
void DrawText(C4Surface *sfcDest, float iX, float iY, DWORD dwColor, const char *szText, DWORD dwFlags, C4Markup &Markup, float fZoom)
BYTE GetPix(int iX, int iY) const
void ReorderFaces(StdMeshMatrix *global_trans)
bool UpdateBoneTransforms()
static StdMeshMatrix Identity()