runtime: CMake-ify gx
This commit is contained in:
@@ -1,74 +0,0 @@
|
||||
// asmcoder.cpp
|
||||
// by simon@acid.co.nz
|
||||
|
||||
// testroutine for asmcoder class
|
||||
// see asmcoder.h for readme
|
||||
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <windows.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <time.h>
|
||||
|
||||
#include "asmcoder.hpp"
|
||||
|
||||
void (__fastcall *plot)(void *s,int argb);
|
||||
int (__fastcall *point)(void*s);
|
||||
void (__fastcall *span)(void *s,int *argb,int n);
|
||||
|
||||
void main()
|
||||
{
|
||||
void *pixmap;
|
||||
int n;
|
||||
|
||||
AsmCoder *coder=new AsmCoder();
|
||||
|
||||
pixmap=new int[640*480];
|
||||
|
||||
plot=(void (__fastcall *)(void*,int))new char[96];
|
||||
point=(int (__fastcall *)(void*))new char[96];
|
||||
span=(void (__fastcall *)(void*,int*,int))new char[96];
|
||||
|
||||
// n=coder->CodePlot(plot,16,0,0xf800,0x07e0,0x001f); //0:5:6:5
|
||||
// printf("plotcode size=%d\n",n);
|
||||
// n=coder->CodePoint(point,16,0,0xf800,0x07e0,0x001f); //0:5:6:5
|
||||
// printf("pointcode size=%d\n",n);
|
||||
|
||||
n=coder->CodePlot(plot,24,0,0xff0000,0xff00,0xff); //0:5:6:5
|
||||
printf("plotcode size=%d\n",n);
|
||||
|
||||
n=coder->CodePoint(point,24,0,0xff0000,0xff00,0x00ff); //0:5:6:5
|
||||
printf("pointcode size=%d\n",n);
|
||||
|
||||
n=coder->CodeSpan(span,24,0,0xff0000,0xff00,0x00ff); //0:5:6:5
|
||||
printf("scancode size=%d\n",n);
|
||||
|
||||
printf("&plot=0x%x\n",(int)plot);
|
||||
printf("&pixmap=0x%x\n",(int)pixmap);
|
||||
|
||||
plot(pixmap,0x818283);
|
||||
// short *b=(short *)pixmap;
|
||||
int *b=(int *)pixmap;
|
||||
printf("b[0]=0x%x\n",b[0]);
|
||||
n=point(pixmap);
|
||||
printf("point(0,0)=0x%x\n",n);
|
||||
|
||||
int pdat[]={0x8080,0x707070,0x606060};
|
||||
span(pixmap,pdat,3);
|
||||
|
||||
delete (void *)plot;
|
||||
delete (void *)point;
|
||||
delete pixmap;
|
||||
delete coder;
|
||||
return;
|
||||
}
|
||||
|
||||
// void (__fastcall *plot)(int x,int y,int argb,Surface *s)=(void (__fastcall *)(int,int,int,Surface*))code;
|
||||
|
||||
void ortest()
|
||||
{
|
||||
__asm{
|
||||
or eax,0xff00ff00
|
||||
or eax,-100
|
||||
}
|
||||
}
|
||||
@@ -1,330 +0,0 @@
|
||||
// asmcoder.h
|
||||
// by simon@acid.co.nz
|
||||
|
||||
// v0.5
|
||||
// point sets nonused bits to 1
|
||||
|
||||
// v0.4
|
||||
// direct pixel address now expected
|
||||
// x,y args removed span removed
|
||||
|
||||
// v0.3
|
||||
// span changed to bytes
|
||||
// pixfield indirect dropped, passed directy to plot
|
||||
// ret(n) added to remove args from fastcall stack
|
||||
// CodePoint() method added
|
||||
|
||||
/*
|
||||
|
||||
asmcoder provides inline assembly generator for high speed runtime tasks
|
||||
|
||||
methods:
|
||||
|
||||
CodePlot(codebase,depth,amask,rmask,gmask,bmask)
|
||||
CodePoint(codebase,depth,amask,rmask,gmask,bmask)
|
||||
CodeSpan(codebase,depth,amask,rmask,gmask,bmask)
|
||||
|
||||
codebase=executable memory (64 bytes)
|
||||
depth=pixel depth (8,16,24,32)
|
||||
amask=32bit alpha pixel mask
|
||||
rmask=32bit red pixel mask
|
||||
gmask=32bit green pixel mask
|
||||
bmask=32bit blue pixel mask
|
||||
|
||||
returns number of bytes of code generated (max 64 bytes)
|
||||
|
||||
call resulting code by typecasting codebase with
|
||||
|
||||
void (__fastcall *plot)(void *pix,int argb)
|
||||
int (__fastcall *point)(void *pix)
|
||||
void (__fastcall *span)(void *pix,int *argb,int count)
|
||||
|
||||
ToDo:
|
||||
|
||||
*/
|
||||
|
||||
#ifndef ASMCODER_H
|
||||
#define ASMCODER_H
|
||||
|
||||
class IA32
|
||||
{
|
||||
public:
|
||||
char *ptr;
|
||||
int off;
|
||||
|
||||
enum Reg32{eax,ecx,edx,ebx,esp,ebp,esi,edi};
|
||||
|
||||
void Reset(void *p) {ptr=(char *)p;off=0;}
|
||||
|
||||
void Code(int c){if (ptr) ptr[off]=c;off++;}
|
||||
void Code16(int c){if (ptr) *(short*)(ptr+off)=c;off+=2;}
|
||||
void Code32(int c){if (ptr) *(int*)(ptr+off)=c;off+=4;}
|
||||
|
||||
void push(Reg32 reg) {Code(0x50+reg);}
|
||||
void pop(Reg32 reg) {Code(0x58+reg);}
|
||||
void ret(int n=0) {if (n==0) Code(0xc3);else {Code(0xc2);Code(n);Code(0);}}
|
||||
void mov(Reg32 dest,Reg32 src) {Code(0x8b);Code((0xc0)|(dest<<3)|(src));}
|
||||
void or(Reg32 dest,Reg32 src) {Code(0x0b);Code((0xc0)|(dest<<3)|(src));}
|
||||
void add(Reg32 dest,Reg32 src) {Code(0x03);Code((0xc0)|(dest<<3)|(src));}
|
||||
void load32(Reg32 dest,Reg32 src,int disp=0)
|
||||
{
|
||||
if (disp==0 && src!=ebp) {Code(0x8b);Code((dest<<3)|(src));}
|
||||
else {Code(0x8b);Code((0x40)|(dest<<3)|(src));Code(disp);}
|
||||
}
|
||||
void load16(Reg32 dest,Reg32 src,int disp=0) {Code(0x66);load32(dest,src,disp);}
|
||||
void load8(Reg32 dest,Reg32 src,int disp=0)
|
||||
{
|
||||
Code(0x8a);if (disp==0 && src!=ebp) {Code((dest<<3)|(src));} else {Code((0x40)|(dest<<3)|(src));Code(disp);}
|
||||
}
|
||||
void store32(Reg32 dest,int disp,Reg32 src)
|
||||
{
|
||||
if (disp==0 && dest!=ebp) {Code(0x89);Code((src<<3)|(dest));Code(0);}
|
||||
else {Code(0x89);Code((0x40)|(src<<3)|(dest));Code(disp);}
|
||||
}
|
||||
void store16(Reg32 dest,int disp,Reg32 src) {Code(0x66);store32(dest,disp,src);}
|
||||
void store8(Reg32 dest,int disp,Reg32 src)
|
||||
{
|
||||
Code(0x88);
|
||||
if (disp==0 && dest!=ebp) {Code((src<<3)|(dest));Code(0);} else {Code((0x40)|(src<<3)|(dest));Code(disp);}
|
||||
}
|
||||
void lea(Reg32 dest,int scale,Reg32 src1,Reg32 src2,int disp=0)
|
||||
{
|
||||
int n,mod,sib;
|
||||
if (disp==0) n=0;else {if (disp>=-128 && disp<128) n=1;else n=2;}
|
||||
mod=(n<<6)|4;
|
||||
sib=(src1<<3)|src2;
|
||||
if (scale==2) sib|=0x40;
|
||||
if (scale==4) sib|=0x80;
|
||||
if (scale==8) sib|=0xc0;
|
||||
Code(0x8d);Code(mod);Code(sib);
|
||||
if (n==1) Code(disp);else if (n==2) Code32(disp);
|
||||
}
|
||||
void lea(Reg32 dest,int scale,Reg32 src,int disp=0)
|
||||
{
|
||||
int mod,sib;
|
||||
sib=(src<<3)|5;
|
||||
mod=(dest<<3)|4;
|
||||
if (scale==2) sib|=0x40;
|
||||
if (scale==4) sib|=0x80;
|
||||
if (scale==8) sib|=0xc0;
|
||||
Code(0x8d);Code(mod);Code(sib);Code32(disp);
|
||||
}
|
||||
void imul(Reg32 dest,int imm,Reg32 src)
|
||||
{
|
||||
Code(0x69);Code((0xc0)|(dest<<3)|(src));Code32(imm);
|
||||
}
|
||||
void shift(Reg32 reg,int imm) //+imm=left -imm=right
|
||||
{
|
||||
int op;
|
||||
if (imm==0) return;
|
||||
if (imm>0) {op=0xe0+reg;} else {op=0xe8+reg;imm=-imm;}
|
||||
if (imm==1) {Code(0xd1);Code(op);} else {Code(0xc1);Code(op);Code(imm);}
|
||||
}
|
||||
void and(Reg32 reg,int imm)
|
||||
{
|
||||
if (imm==0xffffffff) return;
|
||||
if (imm>=-128 && imm<128)
|
||||
{
|
||||
Code(0x83);Code(0xe0+reg);Code(imm);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (reg==eax) {Code(0x25);} else {Code(0x81);Code(0xe0+reg);}Code32(imm);
|
||||
}
|
||||
}
|
||||
void or(Reg32 reg,int imm)
|
||||
{
|
||||
if (imm==0) return;
|
||||
if (imm>=-128 && imm<128)
|
||||
{
|
||||
Code(0x83);Code(0xc0+reg);Code(imm);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (reg==eax) {Code(0x0d);} else {Code(0x81);Code(0xc0+reg);}
|
||||
Code32(imm);
|
||||
}
|
||||
}
|
||||
void jnz(int label) {Code(0x75);Code(label-(off+1));}
|
||||
void add(Reg32 reg,int imm) {Code(0x83);Code(0xc0+reg);Code(imm);}
|
||||
void neg(Reg32 reg) {Code(0xf7);Code(0xd8+reg);}
|
||||
};
|
||||
|
||||
class AsmCoder : IA32
|
||||
{
|
||||
public:
|
||||
int amsb,rmsb,gmsb,bmsb;
|
||||
|
||||
void CalcMSBs(int amask,int rmask,int gmask,int bmask)
|
||||
{
|
||||
unsigned int u;
|
||||
amsb=0;if (u=amask) {while (u!=1) {u>>=1;amsb++;}}
|
||||
rmsb=0;if (u=rmask) {while (u!=1) {u>>=1;rmsb++;}}
|
||||
gmsb=0;if (u=gmask) {while (u!=1) {u>>=1;gmsb++;}}
|
||||
bmsb=0;if (u=bmask) {while (u!=1) {u>>=1;bmsb++;}}
|
||||
}
|
||||
|
||||
// ecx=void *t pixel
|
||||
// edx=int argb
|
||||
|
||||
int CodePlot(void *code,int depth,int amask,int rmask,int gmask,int bmask)
|
||||
{
|
||||
Reset(code);
|
||||
CalcMSBs(amask,rmask,gmask,bmask);
|
||||
|
||||
push (ebx);
|
||||
push (ebp);
|
||||
mov (eax,edx);
|
||||
mov (ebp,ecx);
|
||||
if (rmask==0xff0000 && gmask==0xff00 && bmask==0xff)
|
||||
{
|
||||
if (amask==0 && depth>24) and(eax,0xffffff);
|
||||
}
|
||||
else
|
||||
{
|
||||
mov (ebx,eax); //eax=b ebx=g ecx=r edx=a
|
||||
shift (eax,bmsb-7); //3-0);
|
||||
mov (ecx,ebx);
|
||||
shift (ebx,gmsb-15);
|
||||
if (amask) mov (edx,ecx); //alph
|
||||
if (amask) shift (edx,amsb-31); //alph
|
||||
and (eax,bmask);
|
||||
shift (ecx,rmsb-23);
|
||||
if (amask) and (edx,amask); //alph
|
||||
and (ebx,gmask);
|
||||
if (amask) or (eax,edx); //alph
|
||||
and (ecx,rmask);
|
||||
or (eax,ebx);
|
||||
or (eax,ecx);
|
||||
}
|
||||
switch (depth)
|
||||
{
|
||||
case 16:store16(ebp,0,eax);break;
|
||||
// case 24:store16(ebp,0,eax);shift(eax,-16);store8(ebp,2,eax);break;
|
||||
case 24:store8(ebp,0,eax);shift(eax,-8);store16(ebp,1,eax);break;
|
||||
case 32:store32(ebp,0,eax);break;
|
||||
default:store8(ebp,0,eax);
|
||||
}
|
||||
pop(ebp);
|
||||
pop(ebx);
|
||||
ret();
|
||||
return off;
|
||||
}
|
||||
|
||||
// ecx=void*pix
|
||||
|
||||
int CodePoint(void *code,int depth,int amask,int rmask,int gmask,int bmask)
|
||||
{
|
||||
Reset(code);
|
||||
CalcMSBs(amask,rmask,gmask,bmask);
|
||||
|
||||
push (ebx);
|
||||
switch (depth)
|
||||
{
|
||||
case 16:load16(eax,ecx);break;
|
||||
// case 24:load16(eax,ecx);shift(eax,-16);load8(eax,ecx,2);break;
|
||||
case 24:load16(eax,ecx,1);shift(eax,8);load8(eax,ecx);break;
|
||||
case 32:load32(eax,ecx);break;
|
||||
default:load8(eax,ecx);
|
||||
}
|
||||
if ((amask==0 || amask==0xff000000) && (rmask==0xff0000 && gmask==0xff00 && bmask==0xff))
|
||||
{
|
||||
//
|
||||
}
|
||||
else
|
||||
{
|
||||
mov (ebx,eax); //eax=b ebx=g ecx=r edx=a
|
||||
mov (ecx,eax);
|
||||
if (amask) mov (edx,eax);
|
||||
and (eax,bmask);
|
||||
shift (eax,7-bmsb);
|
||||
and (ebx,gmask);
|
||||
shift (ebx,15-gmsb);
|
||||
and (ecx,rmask);
|
||||
shift (ecx,23-rmsb);
|
||||
if (amask) and (edx,amask);
|
||||
or (eax,ebx);
|
||||
if (amask) shift (edx,31-amsb);
|
||||
or (eax,ecx);
|
||||
if (amask) or (eax,edx);
|
||||
}
|
||||
pop(ebx);
|
||||
int oor=0;
|
||||
if( !amask ) oor|=0xff000000;
|
||||
if( !rmask ) oor|=0x00ff0000;
|
||||
if( !gmask ) oor|=0x0000ff00;
|
||||
if( !bmask ) oor|=0x000000ff;
|
||||
if( oor ) or( eax,oor );
|
||||
ret();
|
||||
return off;
|
||||
}
|
||||
|
||||
// ecx=void *t pixel
|
||||
// edx=int *argb
|
||||
// 8(esp)=count
|
||||
|
||||
int CodeSpan(void *code,int depth,int amask,int rmask,int gmask,int bmask)
|
||||
{
|
||||
int loop;
|
||||
|
||||
Reset(code);
|
||||
CalcMSBs(amask,rmask,gmask,bmask);
|
||||
|
||||
push (ebp);
|
||||
mov (ebp,esp);
|
||||
push (ebx);
|
||||
push (esi);
|
||||
push (edi);
|
||||
|
||||
load32 (edi,ebp,8); //edi=count
|
||||
mov (esi,edx); //esi=[argb]
|
||||
mov (ebp,ecx); //ebp=[pix]
|
||||
neg (edi);
|
||||
|
||||
loop=off;
|
||||
// loop
|
||||
load32 (eax,esi);
|
||||
add (esi,4);
|
||||
|
||||
if (rmask==0xff0000 && gmask==0xff00 && bmask==0xff)
|
||||
{
|
||||
if (amask==0 && depth>24) and(eax,0xffffff);
|
||||
}
|
||||
else
|
||||
{
|
||||
mov (ebx,eax); //eax=b ebx=g ecx=r edx=a
|
||||
shift (eax,bmsb-7); //3-0);
|
||||
mov (ecx,ebx);
|
||||
shift (ebx,gmsb-15);
|
||||
if (amask) mov (edx,ecx); //alph
|
||||
if (amask) shift (edx,amsb-31); //alph
|
||||
and (eax,bmask);
|
||||
shift (ecx,rmsb-23);
|
||||
if (amask) and (edx,amask); //alph
|
||||
and (ebx,gmask);
|
||||
if (amask) or (eax,edx); //alph
|
||||
and (ecx,rmask);
|
||||
or (eax,ebx);
|
||||
or (eax,ecx);
|
||||
}
|
||||
switch (depth)
|
||||
{
|
||||
case 16:store16(ebp,0,eax);add(ebp,2);break;
|
||||
case 24:store8(ebp,0,eax);shift(eax,-8);store16(ebp,1,eax);add(ebp,3);break;
|
||||
case 32:store32(ebp,0,eax);add(ebp,4);break;
|
||||
default:store8(ebp,0,eax);add(ebp,1);
|
||||
}
|
||||
add (edi,1);
|
||||
jnz (loop);
|
||||
|
||||
pop (edi);
|
||||
pop (esi);
|
||||
pop (ebx);
|
||||
pop (ebp);
|
||||
ret (4);
|
||||
return off;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -1,566 +0,0 @@
|
||||
|
||||
#include "GraphicsRuntime.hpp"
|
||||
#include "std.hpp"
|
||||
#include "ddutil.hpp"
|
||||
#include "asmcoder.hpp"
|
||||
#include "gxcanvas.hpp"
|
||||
#include "gxruntime.hpp"
|
||||
|
||||
#define FREEIMAGE_LIB
|
||||
#include <freeimage.h>
|
||||
|
||||
extern gxRuntime *gx_runtime;
|
||||
static AsmCoder asm_coder;
|
||||
|
||||
static void calcShifts(unsigned mask, unsigned char *shr, unsigned char *shl) {
|
||||
if (mask) {
|
||||
for (*shl = 0; !(mask & 1); ++*shl, mask >>= 1) {}
|
||||
for (*shr = 8; mask & 1; --*shr, mask >>= 1) {}
|
||||
}
|
||||
else *shr = *shl = 0;
|
||||
}
|
||||
|
||||
PixelFormat::~PixelFormat() {
|
||||
if (plot_code) {
|
||||
VirtualFree(plot_code, 0, MEM_RELEASE);
|
||||
}
|
||||
}
|
||||
|
||||
void PixelFormat::setFormat(const DDPIXELFORMAT &pf) {
|
||||
if (plot_code) {
|
||||
VirtualFree(plot_code, 0, MEM_RELEASE);
|
||||
}
|
||||
|
||||
if (!(pf.dwFlags & DDPF_RGB)) {
|
||||
memset(this, 0, sizeof(*this));
|
||||
return;
|
||||
}
|
||||
|
||||
plot_code = (char*)VirtualAlloc(0, 128, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
|
||||
point_code = plot_code + 64;
|
||||
|
||||
depth = pf.dwRGBBitCount;
|
||||
amask = pf.dwRGBAlphaBitMask;
|
||||
rmask = pf.dwRBitMask;
|
||||
gmask = pf.dwGBitMask;
|
||||
bmask = pf.dwBBitMask;
|
||||
pitch = depth / 8; argbfill = 0;
|
||||
if (!amask) argbfill |= 0xff000000;
|
||||
if (!rmask) argbfill |= 0x00ff0000;
|
||||
if (!gmask) argbfill |= 0x0000ff00;
|
||||
if (!bmask) argbfill |= 0x000000ff;
|
||||
calcShifts(amask, &ashr, &ashl); ashr += 24;
|
||||
calcShifts(rmask, &rshr, &rshl); rshr += 16;
|
||||
calcShifts(gmask, &gshr, &gshl); gshr += 8;
|
||||
calcShifts(bmask, &bshr, &bshl);
|
||||
plot = (Plot)(void*)plot_code;
|
||||
point = (Point)(void*)point_code;
|
||||
asm_coder.CodePlot(plot_code, depth, amask, rmask, gmask, bmask);
|
||||
asm_coder.CodePoint(point_code, depth, amask, rmask, gmask, bmask);
|
||||
}
|
||||
|
||||
static void adjustTexSize(int *width, int *height, IDirect3DDevice7 *dir3dDev, bool forcePOT = true) {
|
||||
D3DDEVICEDESC7 ddDesc = { 0 };
|
||||
if (dir3dDev->GetCaps(&ddDesc) < 0) {
|
||||
*width = *height = 256;
|
||||
return;
|
||||
}
|
||||
|
||||
int w = *width, h = *height, min, max;
|
||||
|
||||
if (ddDesc.dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_POW2 || ddDesc.dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_NONPOW2CONDITIONAL || forcePOT) {
|
||||
// DirectX Device doesn't support Non Power-Of-Two Textures.
|
||||
|
||||
for (w = 1; w < *width; w <<= 1) {}
|
||||
for (h = 1; h < *height; h <<= 1) {}
|
||||
}
|
||||
else if (ddDesc.dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_SQUAREONLY) {
|
||||
// DirectX Device only supports Square Textures;
|
||||
|
||||
if (w > h) h = w;
|
||||
else w = h;
|
||||
}
|
||||
|
||||
//check aspect ratio
|
||||
if (max = ddDesc.dwMaxTextureAspectRatio) {
|
||||
int asp = w > h ? w / h : h / w;
|
||||
if (asp > max) {
|
||||
if (w > h) h = w / max;
|
||||
else w = h / max;
|
||||
}
|
||||
}
|
||||
//clamp size
|
||||
if ((min = ddDesc.dwMinTextureWidth) && w < min) w = min;
|
||||
if ((min = ddDesc.dwMinTextureHeight) && h < min) h = min;
|
||||
if ((max = ddDesc.dwMaxTextureWidth) && w > max) w = max;
|
||||
if ((max = ddDesc.dwMaxTextureHeight) && h > max) h = max;
|
||||
|
||||
*width = w; *height = h;
|
||||
}
|
||||
|
||||
static IDirectDrawSurface7 *createSurface(int width, int height, int pitch, void *bits, IDirectDraw7 *dirDraw) {
|
||||
DDSURFACEDESC2 desc = { sizeof(desc) };
|
||||
desc.dwFlags = DDSD_WIDTH | DDSD_HEIGHT | DDSD_LPSURFACE | DDSD_PITCH | DDSD_PIXELFORMAT | DDSD_CAPS;
|
||||
desc.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_SYSTEMMEMORY;
|
||||
desc.dwWidth = width; desc.dwHeight = height;
|
||||
desc.lPitch = pitch; desc.lpSurface = bits;
|
||||
desc.ddpfPixelFormat.dwSize = sizeof(DDPIXELFORMAT);
|
||||
desc.ddpfPixelFormat.dwFlags = DDPF_RGB | DDPF_ALPHAPIXELS;
|
||||
desc.ddpfPixelFormat.dwRGBBitCount = 32;
|
||||
desc.ddpfPixelFormat.dwRBitMask = 0xff0000;
|
||||
desc.ddpfPixelFormat.dwGBitMask = 0x00ff00;
|
||||
desc.ddpfPixelFormat.dwBBitMask = 0x0000ff;
|
||||
desc.ddpfPixelFormat.dwRGBAlphaBitMask = 0xff000000;
|
||||
IDirectDrawSurface7 *surf;
|
||||
if (dirDraw->CreateSurface(&desc, &surf, 0) >= 0) return surf;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void buildMask(IDirectDrawSurface7 *surf) {
|
||||
DDSURFACEDESC2 desc = { sizeof(desc) };
|
||||
surf->Lock(0, &desc, DDLOCK_WAIT, 0);
|
||||
unsigned char *surf_p = (unsigned char*)desc.lpSurface;
|
||||
PixelFormat fmt(desc.ddpfPixelFormat);
|
||||
|
||||
for (DWORD y = 0; y < desc.dwHeight; ++y) {
|
||||
unsigned char *p = surf_p;
|
||||
for (DWORD x = 0; x < desc.dwWidth; ++x) {
|
||||
unsigned argb = fmt.getPixel(p);
|
||||
unsigned rgb = argb & 0xffffff;
|
||||
unsigned a = rgb ? 0xff000000 : 0;
|
||||
fmt.setPixel(p, a | rgb);
|
||||
p += fmt.getPitch();
|
||||
}
|
||||
surf_p += desc.lPitch;
|
||||
}
|
||||
surf->Unlock(0);
|
||||
}
|
||||
|
||||
static void buildAlpha(IDirectDrawSurface7 *surf, bool whiten) {
|
||||
|
||||
DDSURFACEDESC2 desc = { sizeof(desc) };
|
||||
surf->Lock(0, &desc, DDLOCK_WAIT, 0);
|
||||
unsigned char *surf_p = (unsigned char*)desc.lpSurface;
|
||||
PixelFormat fmt(desc.ddpfPixelFormat);
|
||||
|
||||
for (DWORD y = 0; y < desc.dwHeight; ++y) {
|
||||
unsigned char *p = surf_p;
|
||||
for (DWORD x = 0; x < desc.dwWidth; ++x) {
|
||||
unsigned argb = fmt.getPixel(p);
|
||||
unsigned alpha = (((argb >> 16) & 0xff) + ((argb >> 8) & 0xff) + (argb & 0xff)) / 3;
|
||||
argb = (alpha << 24) | (argb & 0xffffff);
|
||||
if (whiten) argb |= 0xffffff;
|
||||
fmt.setPixel(p, argb);
|
||||
p += fmt.getPitch();
|
||||
}
|
||||
surf_p += desc.lPitch;
|
||||
}
|
||||
surf->Unlock(0);
|
||||
}
|
||||
|
||||
void ddUtil::buildMipMaps(IDirectDrawSurface7 *surf) {
|
||||
|
||||
DDSURFACEDESC2 desc = { sizeof(desc) };
|
||||
surf->GetSurfaceDesc(&desc);
|
||||
if (!(desc.ddsCaps.dwCaps & DDSCAPS_TEXTURE)) return;
|
||||
if (!(desc.ddpfPixelFormat.dwFlags & DDPF_RGB)) return;
|
||||
|
||||
DDSCAPS2 caps = { 0 };
|
||||
caps.dwCaps = DDSCAPS_TEXTURE;
|
||||
caps.dwCaps2 = DDSCAPS2_MIPMAPSUBLEVEL;
|
||||
|
||||
IDirectDrawSurface7 *src = surf, *dest;
|
||||
|
||||
while (src->GetAttachedSurface(&caps, &dest) >= 0) {
|
||||
|
||||
DDSURFACEDESC2 src_desc = { sizeof(src_desc) };
|
||||
if (src->Lock(0, &src_desc, DDLOCK_WAIT, 0) < 0) abort();
|
||||
unsigned char *src_p = (unsigned char*)src_desc.lpSurface;
|
||||
PixelFormat src_fmt(src_desc.ddpfPixelFormat);
|
||||
|
||||
DDSURFACEDESC2 dest_desc = { sizeof(dest_desc) };
|
||||
if (dest->Lock(0, &dest_desc, DDLOCK_WAIT, 0) < 0) abort();
|
||||
unsigned char *dest_p = (unsigned char *)dest_desc.lpSurface;
|
||||
PixelFormat dest_fmt(dest_desc.ddpfPixelFormat);
|
||||
|
||||
if (src_desc.dwWidth == 1) {
|
||||
for (DWORD y = 0; y < dest_desc.dwHeight; ++y) {
|
||||
unsigned p1 = src_fmt.getPixel(src_p);
|
||||
unsigned p2 = src_fmt.getPixel(src_p + src_desc.lPitch);
|
||||
unsigned argb =
|
||||
((p1 & 0xfefefefe) >> 1) + ((p2 & 0xfefefefe) >> 1);
|
||||
argb += ((
|
||||
(p1 & 0x01010101) + (p2 & 0x01010101)) >> 1) & 0x01010101;
|
||||
dest_fmt.setPixel(dest_p, argb);
|
||||
src_p += src_desc.lPitch * 2;
|
||||
dest_p += dest_desc.lPitch;
|
||||
}
|
||||
}
|
||||
else if (src_desc.dwHeight == 1) {
|
||||
for (DWORD x = 0; x < dest_desc.dwWidth; ++x) {
|
||||
unsigned p1 = src_fmt.getPixel(src_p);
|
||||
unsigned p2 = src_fmt.getPixel(src_p + src_fmt.getPitch());
|
||||
unsigned argb =
|
||||
((p1 & 0xfefefefe) >> 1) + ((p2 & 0xfefefefe) >> 1);
|
||||
argb += ((
|
||||
(p1 & 0x01010101) + (p2 & 0x01010101)) >> 1) & 0x01010101;
|
||||
dest_fmt.setPixel(dest_p, argb);
|
||||
src_p += src_fmt.getPitch() * 2;
|
||||
dest_p += dest_fmt.getPitch();
|
||||
}
|
||||
}
|
||||
else {
|
||||
for (DWORD y = 0; y < dest_desc.dwHeight; ++y) {
|
||||
unsigned char *src_t = src_p;
|
||||
unsigned char *dest_t = dest_p;
|
||||
for (DWORD x = 0; x < dest_desc.dwWidth; ++x) {
|
||||
|
||||
unsigned p1 = src_fmt.getPixel(src_t);
|
||||
unsigned p2 = src_fmt.getPixel(src_t + src_fmt.getPitch());
|
||||
unsigned p3 = src_fmt.getPixel(src_t + src_desc.lPitch + src_fmt.getPitch());
|
||||
unsigned p4 = src_fmt.getPixel(src_t + src_desc.lPitch);
|
||||
|
||||
unsigned argb =
|
||||
((p1 & 0xfcfcfcfc) >> 2) + ((p2 & 0xfcfcfcfc) >> 2) +
|
||||
((p3 & 0xfcfcfcfc) >> 2) + ((p4 & 0xfcfcfcfc) >> 2);
|
||||
argb += ((
|
||||
(p1 & 0x03030303) + (p2 & 0x03030303) +
|
||||
(p3 & 0x03030303) + (p4 & 0x03030303)) >> 2) & 0x03030303;
|
||||
|
||||
dest_fmt.setPixel(dest_t, argb);
|
||||
src_t += src_fmt.getPitch() * 2;
|
||||
dest_t += dest_fmt.getPitch();
|
||||
}
|
||||
src_p += src_desc.lPitch * 2;
|
||||
dest_p += dest_desc.lPitch;
|
||||
}
|
||||
}
|
||||
src->Unlock(0);
|
||||
dest->Unlock(0);
|
||||
dest->Release();
|
||||
src = dest;
|
||||
}
|
||||
}
|
||||
|
||||
void ddUtil::copy(IDirectDrawSurface7 *dest, int dx, int dy, int dw, int dh, IDirectDrawSurface7 *src, int sx, int sy, int sw, int sh) {
|
||||
|
||||
DDSURFACEDESC2 src_desc = { sizeof(src_desc) };
|
||||
src->Lock(0, &src_desc, DDLOCK_WAIT, 0);
|
||||
PixelFormat src_fmt(src_desc.ddpfPixelFormat);
|
||||
unsigned char *src_p = (unsigned char*)src_desc.lpSurface;
|
||||
src_p += src_desc.lPitch*sy + src_fmt.getPitch()*sx;
|
||||
|
||||
DDSURFACEDESC2 dest_desc = { sizeof(dest_desc) };
|
||||
dest->Lock(0, &dest_desc, DDLOCK_WAIT, 0);
|
||||
PixelFormat dest_fmt(dest_desc.ddpfPixelFormat);
|
||||
unsigned char *dest_p = (unsigned char *)dest_desc.lpSurface;
|
||||
dest_p += dest_desc.lPitch*dy + dest_fmt.getPitch()*dx;
|
||||
|
||||
for (int y = 0; y < dh; ++y) {
|
||||
unsigned char *dest = dest_p;
|
||||
unsigned char *src = src_p + src_desc.lPitch*(y*sh / dh);
|
||||
for (int x = 0; x < dw; ++x) {
|
||||
dest_fmt.setPixel(dest, src_fmt.getPixel(src + src_fmt.getPitch()*(x*sw / dw)));
|
||||
dest += dest_fmt.getPitch();
|
||||
}
|
||||
dest_p += dest_desc.lPitch;
|
||||
}
|
||||
|
||||
src->Unlock(0);
|
||||
dest->Unlock(0);
|
||||
}
|
||||
|
||||
IDirectDrawSurface7 *ddUtil::createSurface(int w, int h, int flags, gxGraphics *gfx) {
|
||||
int hi = flags & gxCanvas::CANVAS_TEX_HICOLOR ? 1 : 0;
|
||||
DDSURFACEDESC2 desc = { sizeof(desc) };
|
||||
|
||||
// Texture Size
|
||||
desc.dwFlags = DDSD_CAPS;
|
||||
if (w) { desc.dwWidth = w; desc.dwFlags |= DDSD_WIDTH; }
|
||||
if (h) { desc.dwHeight = h; desc.dwFlags |= DDSD_HEIGHT; }
|
||||
|
||||
// Format
|
||||
if (flags & gxCanvas::CANVAS_TEXTURE) {
|
||||
// Flags guaranteed:
|
||||
// - CANVAS_TEX_RGB
|
||||
// - CANVAS_TEX_ALPHA
|
||||
// - CANVAS_TEXTURE
|
||||
desc.dwFlags |= DDSCAPS_3DDEVICE | DDSD_PIXELFORMAT;
|
||||
desc.ddsCaps.dwCaps |= DDSCAPS_TEXTURE | DDSCAPS_VIDEOMEMORY;
|
||||
if (flags & gxCanvas::CANVAS_TEXTURE) {
|
||||
desc.ddpfPixelFormat = gfx->primFmt;
|
||||
}
|
||||
else {
|
||||
desc.ddpfPixelFormat = gfx->texRGBAlphaFmt[hi];
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (flags & gxCanvas::CANVAS_TEX_MASK) {
|
||||
desc.dwFlags |= DDSD_PIXELFORMAT;
|
||||
desc.ddpfPixelFormat = gfx->texRGBMaskFmt[hi];
|
||||
}
|
||||
else if (flags & gxCanvas::CANVAS_TEX_RGB) {
|
||||
desc.dwFlags |= DDSD_PIXELFORMAT;
|
||||
desc.ddpfPixelFormat = (flags&gxCanvas::CANVAS_TEX_ALPHA) ? gfx->texRGBAlphaFmt[hi] : gfx->texRGBFmt[hi];
|
||||
}
|
||||
else if (flags & gxCanvas::CANVAS_TEX_ALPHA) {
|
||||
desc.dwFlags |= DDSD_PIXELFORMAT;
|
||||
desc.ddpfPixelFormat = gfx->texAlphaFmt[hi];
|
||||
}
|
||||
else if (flags & gxCanvas::CANVAS_TEXTURE) {
|
||||
desc.dwFlags |= DDSD_PIXELFORMAT;
|
||||
desc.ddpfPixelFormat = gfx->primFmt;
|
||||
}
|
||||
}
|
||||
|
||||
// Cube Map
|
||||
if (flags & (gxCanvas::CANVAS_TEX_CUBE)) {
|
||||
desc.ddsCaps.dwCaps |= DDSCAPS_COMPLEX;
|
||||
desc.ddsCaps.dwCaps2 |= DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_ALLFACES;
|
||||
}
|
||||
|
||||
// Video Memory
|
||||
if (!(flags & gxCanvas::CANVAS_TEX_VIDMEM)) {
|
||||
desc.ddsCaps.dwCaps2 |= DDSCAPS2_TEXTUREMANAGE;
|
||||
if (flags & gxCanvas::CANVAS_TEX_MIPMAP) {
|
||||
desc.ddsCaps.dwCaps |= DDSCAPS_MIPMAP | DDSCAPS_COMPLEX;
|
||||
}
|
||||
}
|
||||
|
||||
// Texture Move
|
||||
if ((flags & gxCanvas::CANVAS_TEXTURE) || (flags & gxCanvas::CANVAS_3DRENDER)) {
|
||||
desc.ddsCaps.dwCaps |= DDSCAPS_TEXTURE;
|
||||
if (!(flags & gxCanvas::CANVAS_TEX_VIDMEM)) {
|
||||
desc.ddsCaps.dwCaps2 |= DDSCAPS2_TEXTUREMANAGE;
|
||||
if (flags & gxCanvas::CANVAS_TEX_MIPMAP) {
|
||||
desc.ddsCaps.dwCaps |= DDSCAPS_MIPMAP | DDSCAPS_COMPLEX;
|
||||
}
|
||||
}
|
||||
if (flags & (gxCanvas::CANVAS_TEX_CUBE)) {
|
||||
desc.ddsCaps.dwCaps |= DDSCAPS_COMPLEX;
|
||||
desc.ddsCaps.dwCaps2 |= DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_ALLFACES;
|
||||
}
|
||||
adjustTexSize((int*)&desc.dwWidth, (int*)&desc.dwHeight, gfx->dir3dDev, !(flags & (gxCanvas::CANVAS_TEX_NPOT)));
|
||||
}
|
||||
else {
|
||||
desc.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
|
||||
if (flags & gxCanvas::CANVAS_HIGHCOLOR) {
|
||||
desc.dwFlags |= DDSD_PIXELFORMAT;
|
||||
desc.ddsCaps.dwCaps |= DDSCAPS_SYSTEMMEMORY;
|
||||
desc.ddpfPixelFormat.dwSize = sizeof(DDPIXELFORMAT);
|
||||
desc.ddpfPixelFormat.dwFlags = DDPF_RGB | DDPF_ALPHAPIXELS;
|
||||
desc.ddpfPixelFormat.dwRGBBitCount = 32;
|
||||
desc.ddpfPixelFormat.dwRBitMask = 0xff0000;
|
||||
desc.ddpfPixelFormat.dwGBitMask = 0x00ff00;
|
||||
desc.ddpfPixelFormat.dwBBitMask = 0x0000ff;
|
||||
desc.ddpfPixelFormat.dwRGBAlphaBitMask = 0xff000000;
|
||||
}
|
||||
else if (flags & gxCanvas::CANVAS_NONDISPLAY) {
|
||||
desc.ddsCaps.dwCaps |= DDSCAPS_SYSTEMMEMORY;
|
||||
}
|
||||
}
|
||||
|
||||
IDirectDrawSurface7 *surf;
|
||||
if (gfx->dirDraw->CreateSurface(&desc, &surf, 0) >= 0) {
|
||||
return surf;
|
||||
}
|
||||
if (desc.ddsCaps.dwCaps & DDSCAPS_OFFSCREENPLAIN) {
|
||||
if (!(desc.ddsCaps.dwCaps & DDSCAPS_SYSTEMMEMORY)) {
|
||||
//try again in system memory!
|
||||
desc.ddsCaps.dwCaps |= DDSCAPS_SYSTEMMEMORY;
|
||||
if (gfx->dirDraw->CreateSurface(&desc, &surf, 0) >= 0) return surf;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
//Tom Speed's DXTC loader
|
||||
//
|
||||
IDirectDrawSurface7 *loadDXTC(const char* filename, gxGraphics *gfx) {
|
||||
HRESULT hr;
|
||||
DDSURFACEDESC2 ddsd;
|
||||
DDSURFACEDESC2 fileddsd;
|
||||
char magicID[4];
|
||||
FILE *fp;
|
||||
|
||||
/* try to open the file */
|
||||
fp = fopen(filename, "rb");
|
||||
if (!fp) return NULL;
|
||||
|
||||
/* valid DDS? */
|
||||
fread(magicID, 1, 4, fp);
|
||||
if (strncmp(magicID, "DDS ", 4) != 0) {
|
||||
fclose(fp);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* get the DXTC file surface description */
|
||||
fread(&fileddsd, sizeof(DDSURFACEDESC2), 1, fp);
|
||||
|
||||
if (fileddsd.dwSize != sizeof(DDSURFACEDESC2)) {
|
||||
fclose(fp);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* copy the fileddsd before we manipulate it so you
|
||||
can get neccessary info you want about it later */
|
||||
memcpy(&ddsd, &fileddsd, sizeof(DDSURFACEDESC2));
|
||||
|
||||
/* remove unwanted flags if they exist */
|
||||
//not sure if this is needed, works without it though
|
||||
//ddsd.dwFlags &= ~DDSD_LINEARSIZE;
|
||||
|
||||
int blockSize = 0;
|
||||
int chunkSize = 0;
|
||||
|
||||
if (ddsd.ddpfPixelFormat.dwFourCC == FOURCC_DXT1)
|
||||
blockSize = 8; // DXT1
|
||||
if (ddsd.ddpfPixelFormat.dwFourCC == FOURCC_DXT3)
|
||||
blockSize = 16; // DXT3
|
||||
if (ddsd.ddpfPixelFormat.dwFourCC == FOURCC_DXT5)
|
||||
blockSize = 16; // DXT5
|
||||
|
||||
/* if it isn't a format we support, exit */
|
||||
if (blockSize == 0) {
|
||||
fclose(fp);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* add texture manage flag */
|
||||
ddsd.ddsCaps.dwCaps2 |= DDSCAPS2_TEXTUREMANAGE;
|
||||
|
||||
/* Create the new DXTC surface using the DDSURFACEDESC2
|
||||
we read in from the file */
|
||||
IDirectDrawSurface7 * newSurf = NULL;
|
||||
hr = gfx->dirDraw->CreateSurface(&ddsd, &newSurf, NULL);
|
||||
if (FAILED(hr)) {
|
||||
fclose(fp);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Define what type of child surfaces we may wish
|
||||
to access, in this case MipMaps */
|
||||
DDSCAPS2 mipmapddsd;
|
||||
ZeroMemory(&mipmapddsd, sizeof(DDSCAPS2));
|
||||
mipmapddsd.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_MIPMAP | DDSCAPS_COMPLEX;
|
||||
|
||||
/* pointers used when iterating through mipmaps */
|
||||
IDirectDrawSurface7 *topDDS = NULL;
|
||||
IDirectDrawSurface7 *nextDDS = NULL;
|
||||
|
||||
topDDS = newSurf;
|
||||
topDDS->AddRef();
|
||||
|
||||
while (TRUE) {
|
||||
/* get a description of this surface */
|
||||
hr = topDDS->Lock(NULL, &ddsd, DDLOCK_WAIT, NULL);
|
||||
if (FAILED(hr)) {
|
||||
fclose(fp);
|
||||
topDDS->Release();
|
||||
newSurf->Release();
|
||||
nextDDS->Release();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* how big the raw data is for this surface */
|
||||
chunkSize = ((ddsd.dwWidth + 3) / 4) * ((ddsd.dwHeight + 3) / 4) * blockSize;
|
||||
|
||||
/* read in the raw DXTC surface data */
|
||||
if (!fread(ddsd.lpSurface, chunkSize, 1, fp)) {
|
||||
fclose(fp);
|
||||
topDDS->Release();
|
||||
newSurf->Release();
|
||||
nextDDS->Release();
|
||||
return NULL;
|
||||
}
|
||||
topDDS->Unlock(NULL);
|
||||
|
||||
|
||||
/* Get next mipmap in chain, or exit the loop if there's no more */
|
||||
hr = topDDS->GetAttachedSurface(&mipmapddsd, &nextDDS);
|
||||
if (FAILED(hr)) {
|
||||
fclose(fp);
|
||||
topDDS->Release();
|
||||
break;
|
||||
}
|
||||
|
||||
topDDS->Release();
|
||||
topDDS = nextDDS;
|
||||
nextDDS->Release();
|
||||
}
|
||||
|
||||
return newSurf;
|
||||
}
|
||||
|
||||
IDirectDrawSurface7 *ddUtil::loadSurface(const std::string &f, int flags, gxGraphics *gfx) {
|
||||
|
||||
int i = f.find(".dds");
|
||||
if (i != string::npos && i + 4 == f.size()) {
|
||||
//dds file!
|
||||
IDirectDrawSurface7 *surf = loadDXTC(f.c_str(), gfx);
|
||||
return surf;
|
||||
}
|
||||
|
||||
FreeImage_Initialise();
|
||||
FREE_IMAGE_FORMAT fmt = FreeImage_GetFileType(f.c_str(), f.size());
|
||||
if (fmt == FIF_UNKNOWN) {
|
||||
int n = f.find("."); if (n == string::npos) return 0;
|
||||
fmt = FreeImage_GetFileType(f.c_str());
|
||||
if (fmt == FIF_UNKNOWN) return 0;
|
||||
}
|
||||
FIBITMAP *t_dib = FreeImage_Load(fmt, f.c_str(), 0);
|
||||
if (!t_dib) return 0;
|
||||
|
||||
bool trans = FreeImage_GetBPP(t_dib) == 32 || FreeImage_IsTransparent(t_dib);
|
||||
|
||||
FIBITMAP *dib = FreeImage_ConvertTo32Bits(t_dib);
|
||||
|
||||
if (dib) FreeImage_Unload(t_dib);
|
||||
else dib = t_dib;
|
||||
|
||||
int width = FreeImage_GetWidth(dib);
|
||||
int height = FreeImage_GetHeight(dib);
|
||||
int pitch = FreeImage_GetPitch(dib);
|
||||
void *bits = FreeImage_GetBits(dib);
|
||||
|
||||
IDirectDrawSurface7 *src = ::createSurface(width, height, pitch, bits, gfx->dirDraw);
|
||||
if (!src) {
|
||||
FreeImage_Unload(dib);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (flags & gxCanvas::CANVAS_TEX_ALPHA) {
|
||||
if (flags & gxCanvas::CANVAS_TEX_MASK) {
|
||||
buildMask(src);
|
||||
}
|
||||
else if (!trans) {
|
||||
buildAlpha(src, (flags & gxCanvas::CANVAS_TEX_RGB) ? false : true);
|
||||
}
|
||||
}
|
||||
else {
|
||||
unsigned char *p = (unsigned char *)bits;
|
||||
for (int k = 0; k < height; ++k) {
|
||||
unsigned char *t = p + 3;
|
||||
for (int j = 0; j < width; ++j) {
|
||||
*t = 0xff; t += 4;
|
||||
}
|
||||
p += pitch;
|
||||
}
|
||||
}
|
||||
|
||||
IDirectDrawSurface7 *dest = createSurface(width, height, flags, gfx);
|
||||
if (!dest) {
|
||||
src->Release();
|
||||
FreeImage_Unload(dib);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int t_w = width, t_h = height;
|
||||
if (flags & gxCanvas::CANVAS_TEXTURE) adjustTexSize(&t_w, &t_h, gfx->dir3dDev, !(flags & (gxCanvas::CANVAS_TEX_NPOT)));
|
||||
copy(dest, 0, 0, t_w, t_h, src, 0, height - 1, width, -height);
|
||||
|
||||
src->Release();
|
||||
FreeImage_Unload(dib);
|
||||
return dest;
|
||||
}
|
||||
@@ -1,57 +0,0 @@
|
||||
|
||||
#ifndef DDUTIL_H
|
||||
#define DDUTIL_H
|
||||
|
||||
#include "GraphicsRuntime.hpp"
|
||||
|
||||
class gxGraphics;
|
||||
|
||||
|
||||
struct ddUtil{
|
||||
|
||||
static void buildMipMaps( IDirectDrawSurface7 *surf );
|
||||
static void copy( IDirectDrawSurface7 *dest,int dx,int dy,int dw,int dh,IDirectDrawSurface7 *src,int sx,int sy,int sw,int sh );
|
||||
static IDirectDrawSurface7 *loadSurface( const std::string &f,int flags,gxGraphics *gfx );
|
||||
static IDirectDrawSurface7 *createSurface( int width,int height,int flags,gxGraphics *gfx );
|
||||
};
|
||||
|
||||
class PixelFormat{
|
||||
int depth,pitch;
|
||||
unsigned amask,rmask,gmask,bmask,argbfill;
|
||||
unsigned char ashr,ashl,rshr,rshl,gshr,gshl,bshr,bshl;
|
||||
typedef void (_fastcall *Plot)(void *pix,unsigned argb);
|
||||
typedef unsigned (_fastcall *Point)(void *pix);
|
||||
Plot plot;
|
||||
Point point;
|
||||
|
||||
char *plot_code,*point_code;
|
||||
|
||||
public:
|
||||
PixelFormat():plot_code(0){
|
||||
}
|
||||
|
||||
PixelFormat( const DDPIXELFORMAT &pf ):plot_code(0){
|
||||
setFormat( pf );
|
||||
}
|
||||
|
||||
~PixelFormat();
|
||||
|
||||
void setFormat( const DDPIXELFORMAT &pf );
|
||||
|
||||
int getDepth()const{
|
||||
return depth;
|
||||
}
|
||||
int getPitch()const{
|
||||
return pitch;
|
||||
}
|
||||
unsigned fromARGB( unsigned n )const{
|
||||
return ( (n>>ashr<<ashl)&amask ) | ( (n>>rshr<<rshl)&rmask ) | ( (n>>gshr<<gshl)&gmask ) | ( (n>>bshr<<bshl)&bmask );
|
||||
}
|
||||
unsigned toARGB( unsigned n )const{
|
||||
return ( (n&amask)>>ashl<<ashr ) | ( (n&rmask)>>rshl<<rshr ) | ( (n&gmask)>>gshl<<gshr ) | ( (n&bmask)>>bshl<<bshr ) | argbfill;
|
||||
}
|
||||
void setPixel( void *p,unsigned n )const{ plot(p,n); }
|
||||
unsigned getPixel( void *p )const{ return point(p); }
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -1,47 +0,0 @@
|
||||
#pragma once
|
||||
#include <windows.h>
|
||||
|
||||
// Direct Draw
|
||||
#define DIRECTDRAW_VERSION 0x0700
|
||||
#include <ddraw.h>
|
||||
|
||||
// Direct3D
|
||||
#define DIRECT3D_VERSION 0x0700
|
||||
#include <d3d.h>
|
||||
|
||||
// Direct Input
|
||||
#define DIRECTINPUT_VERSION 0x0800
|
||||
#include <dinput.h>
|
||||
|
||||
// Redefine GUIDs
|
||||
DEFINE_GUID(CLSID_DirectDraw, 0xD7B70EE0, 0x4340, 0x11CF, 0xB0, 0x63, 0x00, 0x20, 0xAF, 0xC2, 0xCD, 0x35);
|
||||
DEFINE_GUID(CLSID_DirectDraw7, 0x3c305196, 0x50db, 0x11d3, 0x9c, 0xfe, 0x00, 0xc0, 0x4f, 0xd9, 0x30, 0xc5);
|
||||
DEFINE_GUID(CLSID_DirectDrawClipper, 0x593817A0, 0x7DB3, 0x11CF, 0xA2, 0xDE, 0x00, 0xAA, 0x00, 0xb9, 0x33, 0x56);
|
||||
DEFINE_GUID(IID_IDirectDraw, 0x6C14DB80, 0xA733, 0x11CE, 0xA5, 0x21, 0x00, 0x20, 0xAF, 0x0B, 0xE5, 0x60);
|
||||
DEFINE_GUID(IID_IDirectDraw2, 0xB3A6F3E0, 0x2B43, 0x11CF, 0xA2, 0xDE, 0x00, 0xAA, 0x00, 0xB9, 0x33, 0x56);
|
||||
DEFINE_GUID(IID_IDirectDraw4, 0x9c59509a, 0x39bd, 0x11d1, 0x8c, 0x4a, 0x00, 0xc0, 0x4f, 0xd9, 0x30, 0xc5);
|
||||
DEFINE_GUID(IID_IDirectDraw7, 0x15e65ec0, 0x3b9c, 0x11d2, 0xb9, 0x2f, 0x00, 0x60, 0x97, 0x97, 0xea, 0x5b);
|
||||
DEFINE_GUID(IID_IDirectDrawSurface, 0x6C14DB81, 0xA733, 0x11CE, 0xA5, 0x21, 0x00, 0x20, 0xAF, 0x0B, 0xE5, 0x60);
|
||||
DEFINE_GUID(IID_IDirectDrawSurface2, 0x57805885, 0x6eec, 0x11cf, 0x94, 0x41, 0xa8, 0x23, 0x03, 0xc1, 0x0e, 0x27);
|
||||
DEFINE_GUID(IID_IDirectDrawSurface3, 0xDA044E00, 0x69B2, 0x11D0, 0xA1, 0xD5, 0x00, 0xAA, 0x00, 0xB8, 0xDF, 0xBB);
|
||||
DEFINE_GUID(IID_IDirectDrawSurface4, 0x0B2B8630, 0xAD35, 0x11D0, 0x8E, 0xA6, 0x00, 0x60, 0x97, 0x97, 0xEA, 0x5B);
|
||||
DEFINE_GUID(IID_IDirectDrawSurface7, 0x06675a80, 0x3b9b, 0x11d2, 0xb9, 0x2f, 0x00, 0x60, 0x97, 0x97, 0xea, 0x5b);
|
||||
DEFINE_GUID(IID_IDirectDrawPalette, 0x6C14DB84, 0xA733, 0x11CE, 0xA5, 0x21, 0x00, 0x20, 0xAF, 0x0B, 0xE5, 0x60);
|
||||
DEFINE_GUID(IID_IDirectDrawClipper, 0x6C14DB85, 0xA733, 0x11CE, 0xA5, 0x21, 0x00, 0x20, 0xAF, 0x0B, 0xE5, 0x60);
|
||||
DEFINE_GUID(IID_IDirectDrawColorControl, 0x4B9F0EE0, 0x0D7E, 0x11D0, 0x9B, 0x06, 0x00, 0xA0, 0xC9, 0x03, 0xA3, 0xB8);
|
||||
DEFINE_GUID(IID_IDirectDrawGammaControl, 0x69C11C3E, 0xB46B, 0x11D1, 0xAD, 0x7A, 0x00, 0xC0, 0x4F, 0xC2, 0x9B, 0x4E);
|
||||
DEFINE_GUID(CLSID_AMMultiMediaStream, 0x49c47ce5, 0x9ba4, 0x11d0, 0x82, 0x12, 0x00, 0xc0, 0x4f, 0xc3, 0x2c, 0x45);
|
||||
DEFINE_GUID(CLSID_AMDirectDrawStream, 0x49c47ce4, 0x9ba4, 0x11d0, 0x82, 0x12, 0x00, 0xc0, 0x4f, 0xc3, 0x2c, 0x45);
|
||||
DEFINE_GUID(CLSID_AMAudioStream, 0x8496e040, 0xaf4c, 0x11d0, 0x82, 0x12, 0x00, 0xc0, 0x4f, 0xc3, 0x2c, 0x45);
|
||||
DEFINE_GUID(CLSID_AMAudioData, 0xf2468580, 0xaf8a, 0x11d0, 0x82, 0x12, 0x00, 0xc0, 0x4f, 0xc3, 0x2c, 0x45);
|
||||
DEFINE_GUID(CLSID_AMMediaTypeStream, 0xcf0f2f7c, 0xf7bf, 0x11d0, 0x90, 0xd, 0x0, 0xc0, 0x4f, 0xd9, 0x18, 0x9d);
|
||||
DEFINE_GUID(MSPID_PrimaryVideo, 0xa35ff56a, 0x9fda, 0x11d0, 0x8f, 0xdf, 0x0, 0xc0, 0x4f, 0xd9, 0x18, 0x9d);
|
||||
DEFINE_GUID(MSPID_PrimaryAudio, 0xa35ff56b, 0x9fda, 0x11d0, 0x8f, 0xdf, 0x0, 0xc0, 0x4f, 0xd9, 0x18, 0x9d);
|
||||
DEFINE_GUID(IID_IDirect3D7, 0xf5049e77, 0x4861, 0x11d2, 0xa4, 0x7, 0x0, 0xa0, 0xc9, 0x6, 0x29, 0xa8);
|
||||
DEFINE_GUID(IID_IDirect3DRampDevice, 0xF2086B20, 0x259F, 0x11CF, 0xA3, 0x1A, 0x00, 0xAA, 0x00, 0xB9, 0x33, 0x56);
|
||||
DEFINE_GUID(IID_IDirect3DRGBDevice, 0xA4665C60, 0x2673, 0x11CF, 0xA3, 0x1A, 0x00, 0xAA, 0x00, 0xB9, 0x33, 0x56);
|
||||
DEFINE_GUID(IID_IDirect3DHALDevice, 0x84E63dE0, 0x46AA, 0x11CF, 0x81, 0x6F, 0x00, 0x00, 0xC0, 0x20, 0x15, 0x6E);
|
||||
DEFINE_GUID(IID_IDirect3DMMXDevice, 0x881949a1, 0xd6f3, 0x11d0, 0x89, 0xab, 0x00, 0xa0, 0xc9, 0x05, 0x41, 0x29);
|
||||
DEFINE_GUID(IID_IDirect3DRefDevice, 0x50936643, 0x13e9, 0x11d1, 0x89, 0xaa, 0x0, 0xa0, 0xc9, 0x5, 0x41, 0x29);
|
||||
DEFINE_GUID(IID_IDirect3DNullDevice, 0x8767df22, 0xbacc, 0x11d1, 0x89, 0x69, 0x0, 0xa0, 0xc9, 0x6, 0x29, 0xa8);
|
||||
DEFINE_GUID(IID_IDirect3DTnLHalDevice, 0xf5049e78, 0x4861, 0x11d2, 0xa4, 0x7, 0x0, 0xa0, 0xc9, 0x6, 0x29, 0xa8);
|
||||
@@ -1,286 +0,0 @@
|
||||
|
||||
#include "std.hpp"
|
||||
#include "gxaudio.hpp"
|
||||
#include <fmod.h>
|
||||
|
||||
struct StaticChannel : public gxChannel{
|
||||
virtual void play()=0;
|
||||
};
|
||||
|
||||
struct SoundChannel : public gxChannel{
|
||||
SoundChannel():channel(-1){
|
||||
}
|
||||
void set( int n ){
|
||||
channel=n;
|
||||
}
|
||||
void stop(){
|
||||
FSOUND_StopSound( channel );
|
||||
}
|
||||
void setPaused( bool paused ){
|
||||
FSOUND_SetPaused( channel,paused );
|
||||
}
|
||||
void setPitch( int pitch ){
|
||||
FSOUND_SetFrequency( channel,pitch );
|
||||
}
|
||||
void setVolume( float volume ){
|
||||
FSOUND_SetVolume( channel,volume * 255.0f );
|
||||
}
|
||||
void setPan( float pan ){
|
||||
FSOUND_SetPan( channel,(pan+1)*127.5f );
|
||||
}
|
||||
void set3d( const float pos[3],const float vel[3] ){
|
||||
FSOUND_3D_SetAttributes( channel,(float*)pos,(float*)vel );
|
||||
}
|
||||
bool isPlaying(){
|
||||
return FSOUND_IsPlaying( channel ) ? true : false;
|
||||
}
|
||||
private:
|
||||
int channel;
|
||||
};
|
||||
|
||||
struct CDChannel : public gxChannel{
|
||||
void play( int track,int mode ){
|
||||
stop();
|
||||
int cd_mode=FSOUND_CD_PLAYONCE;
|
||||
if( mode==gxAudio::CD_MODE_LOOP ) cd_mode=FSOUND_CD_PLAYLOOPED;
|
||||
else if( mode==gxAudio::CD_MODE_ALL ) cd_mode=FSOUND_CD_PLAYCONTINUOUS;
|
||||
FSOUND_CD_SetPlayMode( 0,cd_mode );
|
||||
FSOUND_CD_Play( 0,track );
|
||||
}
|
||||
void stop(){
|
||||
FSOUND_CD_Stop(0 );
|
||||
}
|
||||
void setPaused( bool paused ){
|
||||
FSOUND_CD_SetPaused( 0,paused );
|
||||
}
|
||||
void setPitch( int pitch ){
|
||||
}
|
||||
void setVolume( float volume ){
|
||||
FSOUND_CD_SetVolume( 0,volume*255.0f );
|
||||
}
|
||||
void setPan( float pan ){
|
||||
}
|
||||
void set3d( const float pos[3],const float vel[3] ){
|
||||
}
|
||||
bool isPlaying(){
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
struct StreamChannel : public StaticChannel{
|
||||
StreamChannel( FSOUND_STREAM *s ):stream(s){
|
||||
channel=FSOUND_Stream_Play( FSOUND_FREE,stream );
|
||||
}
|
||||
~StreamChannel(){
|
||||
FSOUND_Stream_Close( stream );
|
||||
}
|
||||
void play(){
|
||||
stop();
|
||||
channel=FSOUND_Stream_Play( FSOUND_FREE,stream );
|
||||
}
|
||||
void stop(){
|
||||
FSOUND_Stream_Stop( stream );
|
||||
channel=-1;
|
||||
}
|
||||
void setPaused( bool paused ){
|
||||
FSOUND_SetPaused( channel,paused );
|
||||
}
|
||||
void setPitch( int pitch ){
|
||||
FSOUND_SetFrequency( channel,pitch );
|
||||
}
|
||||
void setVolume( float volume ){
|
||||
FSOUND_SetVolume( channel,volume * 255.0f );
|
||||
}
|
||||
void setPan( float pan ){
|
||||
FSOUND_SetPan( channel,(pan+1)*127.5f );
|
||||
}
|
||||
void set3d( const float pos[3],const float vel[3] ){
|
||||
}
|
||||
bool isPlaying(){
|
||||
return FSOUND_IsPlaying( channel ) ? true : false;
|
||||
}
|
||||
private:
|
||||
FSOUND_STREAM *stream;
|
||||
int channel;
|
||||
};
|
||||
|
||||
struct MusicChannel : public StaticChannel{
|
||||
MusicChannel( FMUSIC_MODULE *m ):module(m){
|
||||
play();
|
||||
}
|
||||
~MusicChannel(){
|
||||
FMUSIC_FreeSong( module );
|
||||
}
|
||||
void play(){
|
||||
FMUSIC_PlaySong( module );
|
||||
}
|
||||
void stop(){
|
||||
FMUSIC_StopSong( module );
|
||||
}
|
||||
void setPaused( bool paused ){
|
||||
FMUSIC_SetPaused( module,paused );
|
||||
}
|
||||
void setPitch( int pitch ){
|
||||
}
|
||||
void setVolume( float volume ){
|
||||
FMUSIC_SetMasterVolume( module,volume*255.0f );
|
||||
}
|
||||
void setPan( float pan ){
|
||||
}
|
||||
void set3d( const float pos[3],const float vel[3] ){
|
||||
}
|
||||
bool isPlaying(){
|
||||
return FMUSIC_IsFinished( module ) ? false : true;
|
||||
}
|
||||
private:
|
||||
FMUSIC_MODULE *module;
|
||||
};
|
||||
|
||||
static set<gxSound*> sound_set;
|
||||
static vector<gxChannel*> channels;
|
||||
static map<string,StaticChannel*> songs;
|
||||
static CDChannel *cdChannel;
|
||||
|
||||
static int next_chan;
|
||||
static vector<SoundChannel*> soundChannels;
|
||||
|
||||
static gxChannel *allocSoundChannel( int n ){
|
||||
|
||||
SoundChannel *chan=0;
|
||||
for( int k=0;k<soundChannels.size();++k ){
|
||||
chan=soundChannels[next_chan];
|
||||
if( !chan ){
|
||||
chan=soundChannels[next_chan]=new SoundChannel();
|
||||
channels.push_back(chan);
|
||||
}else if( chan->isPlaying() ){
|
||||
chan=0;
|
||||
}
|
||||
if( ++next_chan==soundChannels.size() ) next_chan=0;
|
||||
if( chan ) break;
|
||||
}
|
||||
|
||||
if( !chan ){
|
||||
next_chan=soundChannels.size();
|
||||
soundChannels.resize(soundChannels.size()*2);
|
||||
for( int k=next_chan;k<soundChannels.size();++k ) soundChannels[k]=0;
|
||||
chan=soundChannels[next_chan++]=new SoundChannel();
|
||||
channels.push_back( chan );
|
||||
}
|
||||
|
||||
chan->set(n);
|
||||
return chan;
|
||||
}
|
||||
|
||||
gxAudio::gxAudio( gxRuntime *r ):
|
||||
runtime(r){
|
||||
next_chan=0;
|
||||
soundChannels.resize( 4096 );
|
||||
for( int k=0;k<4096;++k ) soundChannels[k]=0;
|
||||
|
||||
cdChannel=new CDChannel();
|
||||
channels.push_back( cdChannel );
|
||||
}
|
||||
|
||||
gxAudio::~gxAudio(){
|
||||
//free all channels
|
||||
for( ;channels.size();channels.pop_back() ) delete channels.back();
|
||||
//free all sound_set
|
||||
while( sound_set.size() ) freeSound( *sound_set.begin() );
|
||||
soundChannels.clear();
|
||||
songs.clear();
|
||||
|
||||
FSOUND_Close();
|
||||
}
|
||||
|
||||
gxChannel *gxAudio::play( FSOUND_SAMPLE *sample ){
|
||||
|
||||
int n=FSOUND_PlaySound( FSOUND_FREE,sample );
|
||||
return n>=0 ? allocSoundChannel( n ) : 0;
|
||||
}
|
||||
|
||||
gxChannel *gxAudio::play3d( FSOUND_SAMPLE *sample,const float pos[3],const float vel[3] ){
|
||||
|
||||
int n=FSOUND_PlaySoundEx( FSOUND_FREE,sample,0,true );
|
||||
if( n<0 ) return 0;
|
||||
FSOUND_3D_SetAttributes( n,(float*)pos,(float*)vel );
|
||||
FSOUND_SetPaused( n,false );
|
||||
return allocSoundChannel( n );
|
||||
}
|
||||
|
||||
void gxAudio::pause(){
|
||||
}
|
||||
|
||||
void gxAudio::resume(){
|
||||
}
|
||||
|
||||
gxSound *gxAudio::loadSound( const string &f,bool use3d ){
|
||||
|
||||
int flags=FSOUND_NORMAL | (use3d ? FSOUND_FORCEMONO : FSOUND_2D);
|
||||
|
||||
FSOUND_SAMPLE *sample=FSOUND_Sample_Load( FSOUND_FREE,f.c_str(),flags,0,0 );
|
||||
if( !sample ) return 0;
|
||||
|
||||
gxSound *sound=new gxSound( this,sample );
|
||||
sound_set.insert( sound );
|
||||
return sound;
|
||||
}
|
||||
|
||||
gxSound *gxAudio::verifySound( gxSound *s ){
|
||||
return sound_set.count( s ) ? s : 0;
|
||||
}
|
||||
|
||||
void gxAudio::freeSound( gxSound *s ){
|
||||
if( sound_set.erase( s ) ) delete s;
|
||||
}
|
||||
|
||||
void gxAudio::setPaused( bool paused ){
|
||||
FSOUND_SetPaused( FSOUND_ALL,paused );
|
||||
}
|
||||
|
||||
void gxAudio::setVolume( float volume ){
|
||||
}
|
||||
|
||||
void gxAudio::set3dOptions( float roll,float dopp,float dist ){
|
||||
FSOUND_3D_SetRolloffFactor( roll );
|
||||
FSOUND_3D_SetDopplerFactor( dopp );
|
||||
FSOUND_3D_SetDistanceFactor( dist );
|
||||
}
|
||||
|
||||
void gxAudio::set3dListener( const float pos[3],const float vel[3],const float forward[3],const float up[3] ){
|
||||
FSOUND_3D_Listener_SetAttributes( (float*)pos,(float*)vel,forward[0],forward[1],forward[2],up[0],up[1],up[2] );
|
||||
FSOUND_Update();
|
||||
}
|
||||
|
||||
gxChannel *gxAudio::playFile( const string &t,bool use_3d ){
|
||||
string f=tolower( t );
|
||||
StaticChannel *chan=0;
|
||||
map<string,StaticChannel*>::iterator it=songs.find(f);
|
||||
if( it!=songs.end() ){
|
||||
chan=it->second;
|
||||
chan->play();
|
||||
return chan;
|
||||
}else if(
|
||||
f.find( ".raw" )!=string::npos ||
|
||||
f.find( ".wav" )!=string::npos ||
|
||||
f.find( ".mp2" )!=string::npos ||
|
||||
f.find( ".mp3" )!=string::npos ||
|
||||
f.find( ".ogg" )!=string::npos ||
|
||||
f.find( ".wma" )!=string::npos ||
|
||||
f.find( ".asf" )!=string::npos ){
|
||||
FSOUND_STREAM *stream=FSOUND_Stream_Open( f.c_str(),use_3d,0,0 );
|
||||
if( !stream ) return 0;
|
||||
chan=new StreamChannel( stream );
|
||||
}else{
|
||||
FMUSIC_MODULE *module=FMUSIC_LoadSong( f.c_str() );
|
||||
if( !module ) return 0;
|
||||
chan=new MusicChannel( module );
|
||||
}
|
||||
channels.push_back( chan );
|
||||
songs[f]=chan;
|
||||
return chan;
|
||||
}
|
||||
|
||||
gxChannel *gxAudio::playCDTrack( int track,int mode ){
|
||||
cdChannel->play( track,mode );
|
||||
return cdChannel;
|
||||
}
|
||||
@@ -1,48 +0,0 @@
|
||||
|
||||
#ifndef GXAUDIO_H
|
||||
#define GXAUDIO_H
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "gxsound.hpp"
|
||||
|
||||
class gxRuntime;
|
||||
struct FSOUND_SAMPLE;
|
||||
|
||||
class gxAudio{
|
||||
public:
|
||||
gxRuntime *runtime;
|
||||
|
||||
gxAudio( gxRuntime *runtime );
|
||||
~gxAudio();
|
||||
|
||||
gxChannel *play( FSOUND_SAMPLE *sample );
|
||||
gxChannel *play3d( FSOUND_SAMPLE *sample,const float pos[3],const float vel[3] );
|
||||
|
||||
void pause();
|
||||
void resume();
|
||||
|
||||
private:
|
||||
|
||||
/***** GX INTERFACE *****/
|
||||
public:
|
||||
enum{
|
||||
CD_MODE_ONCE=1,CD_MODE_LOOP,CD_MODE_ALL
|
||||
};
|
||||
|
||||
gxSound *loadSound( const std::string &filename,bool use_3d );
|
||||
gxSound *verifySound( gxSound *sound );
|
||||
void freeSound( gxSound *sound );
|
||||
|
||||
void setPaused( bool paused ); //master pause
|
||||
void setVolume( float volume ); //master volume
|
||||
|
||||
void set3dOptions( float roll,float dopp,float dist );
|
||||
|
||||
void set3dListener( const float pos[3],const float vel[3],const float forward[3],const float up[3] );
|
||||
|
||||
gxChannel *playCDTrack( int track,int mode );
|
||||
gxChannel *playFile( const std::string &filename,bool use_3d );
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -1,739 +0,0 @@
|
||||
|
||||
#include "std.hpp"
|
||||
#include "gxcanvas.hpp"
|
||||
#include "gxgraphics.hpp"
|
||||
#include "gxruntime.hpp"
|
||||
#include "asmcoder.hpp"
|
||||
|
||||
#define DEBUG_BITMASK
|
||||
|
||||
static int canvas_cnt;
|
||||
static DDBLTFX bltfx = { sizeof(DDBLTFX) };
|
||||
|
||||
extern gxRuntime *gx_runtime;
|
||||
|
||||
static unsigned FWMS[] = {
|
||||
0xffffffff,0x7fffffff,0x3fffffff,0x1fffffff,
|
||||
0x0fffffff,0x07ffffff,0x03ffffff,0x01ffffff,
|
||||
0x00ffffff,0x007fffff,0x003fffff,0x001fffff,
|
||||
0x000fffff,0x0007ffff,0x0003ffff,0x0001ffff,
|
||||
0x0000ffff,0x00007fff,0x00003fff,0x00001fff,
|
||||
0x00000fff,0x000007ff,0x000003ff,0x000001ff,
|
||||
0x000000ff,0x0000007f,0x0000003f,0x0000001f,
|
||||
0x0000000f,0x00000007,0x00000003,0x00000001 };
|
||||
static unsigned LWMS[] = {
|
||||
0x80000000,0xc0000000,0xe0000000,0xf0000000,
|
||||
0xf8000000,0xfc000000,0xfe000000,0xff000000,
|
||||
0xff800000,0xffc00000,0xffe00000,0xfff00000,
|
||||
0xfff80000,0xfffc0000,0xfffe0000,0xffff0000,
|
||||
0xffff8000,0xffffc000,0xffffe000,0xfffff000,
|
||||
0xfffff800,0xfffffc00,0xfffffe00,0xffffff00,
|
||||
0xffffff80,0xffffffc0,0xffffffe0,0xfffffff0,
|
||||
0xfffffff8,0xfffffffc,0xfffffffe,0xffffffff };
|
||||
|
||||
static void calcShifts(unsigned mask, unsigned char *shr, unsigned char *shl) {
|
||||
if (mask) {
|
||||
for (*shl = 0; !(mask & 1); ++*shl, mask >>= 1) {}
|
||||
for (*shr = 8; mask & 1; --*shr, mask >>= 1) {}
|
||||
} else *shr = *shl = 0;
|
||||
}
|
||||
|
||||
struct Rect : public RECT {
|
||||
Rect() {}
|
||||
Rect(int x, int y, int w, int h) {
|
||||
left = x; top = y; right = x + w; bottom = y + h;
|
||||
}
|
||||
};
|
||||
|
||||
static bool clip(const RECT &viewport, RECT *d) {
|
||||
if (d->right <= d->left ||
|
||||
d->bottom <= d->top ||
|
||||
d->left >= viewport.right ||
|
||||
d->right <= viewport.left ||
|
||||
d->top >= viewport.bottom ||
|
||||
d->bottom <= viewport.top) return false;
|
||||
if (d->left < viewport.left) d->left = viewport.left;
|
||||
if (d->right > viewport.right) d->right = viewport.right;
|
||||
if (d->top < viewport.top) d->top = viewport.top;
|
||||
if (d->bottom > viewport.bottom) d->bottom = viewport.bottom;
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool clip(const RECT &viewport, RECT *d, RECT *s) {
|
||||
if (d->right <= d->left ||
|
||||
d->bottom <= d->top ||
|
||||
d->left >= viewport.right ||
|
||||
d->right <= viewport.left ||
|
||||
d->top >= viewport.bottom ||
|
||||
d->bottom <= viewport.top) return false;
|
||||
int dx, dy;
|
||||
if ((dx = viewport.left - d->left) > 0) { d->left += dx; s->left += dx; }
|
||||
if ((dx = viewport.right - d->right) < 0) { d->right += dx; s->right += dx; }
|
||||
if ((dy = viewport.top - d->top) > 0) { d->top += dy; s->top += dy; }
|
||||
if ((dy = viewport.bottom - d->bottom) < 0) { d->bottom += dy; s->bottom += dy; }
|
||||
return true;
|
||||
}
|
||||
|
||||
gxCanvas::gxCanvas(gxGraphics *g, IDirectDrawSurface7 *s, int f) :
|
||||
graphics(g), main_surf(s), surf(0), z_surf(0), flags(f), cube_mode(CUBEMODE_REFLECTION | CUBESPACE_WORLD),
|
||||
t_surf(0), cm_mask(0), locked_cnt(0), mod_cnt(0), remip_cnt(0) {
|
||||
|
||||
if (flags & CANVAS_TEX_CUBE) {
|
||||
cube_surfs[2] = main_surf;
|
||||
for (int k = 0; k < 6; ++k) {
|
||||
if (k == 2) continue;
|
||||
DWORD n;
|
||||
switch (k) {
|
||||
case 0:n = DDSCAPS2_CUBEMAP_NEGATIVEX; break;
|
||||
case 1:n = DDSCAPS2_CUBEMAP_POSITIVEZ; break;
|
||||
case 2:n = DDSCAPS2_CUBEMAP_POSITIVEX; break;
|
||||
case 3:n = DDSCAPS2_CUBEMAP_NEGATIVEZ; break;
|
||||
case 4:n = DDSCAPS2_CUBEMAP_POSITIVEY; break;
|
||||
case 5:n = DDSCAPS2_CUBEMAP_NEGATIVEY; break;
|
||||
default:return;
|
||||
}
|
||||
DDSCAPS2 caps = { 0 };
|
||||
caps.dwCaps2 = DDSCAPS2_CUBEMAP | n;
|
||||
main_surf->GetAttachedSurface(&caps, &cube_surfs[k]);
|
||||
}
|
||||
surf = cube_surfs[1];
|
||||
} else {
|
||||
surf = main_surf;
|
||||
memset(cube_surfs, 0, sizeof(cube_surfs));
|
||||
}
|
||||
|
||||
DDSURFACEDESC2 desc = { sizeof(desc) };
|
||||
surf->GetSurfaceDesc(&desc);
|
||||
format.setFormat(desc.ddpfPixelFormat);
|
||||
|
||||
// Create Z-Buffer
|
||||
if (flags & CANVAS_3DRENDER) {
|
||||
DDSURFACEDESC2 zdesc = { sizeof(zdesc) };
|
||||
zdesc.dwWidth = desc.dwWidth;
|
||||
zdesc.dwHeight = desc.dwHeight;
|
||||
zdesc.ddpfPixelFormat = g->zbuffFmt;
|
||||
zdesc.dwFlags = DDSD_PIXELFORMAT | DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS;
|
||||
zdesc.ddsCaps.dwCaps = DDSCAPS_VIDEOMEMORY | DDSCAPS_3DDEVICE | DDSD_PIXELFORMAT | DDSD_WIDTH | DDSD_HEIGHT | DDSCAPS_ZBUFFER;
|
||||
|
||||
if (g->dirDraw->CreateSurface(&zdesc, &z_surf, 0) >= 0) {
|
||||
surf->AddAttachedSurface(z_surf);
|
||||
}
|
||||
}
|
||||
|
||||
clip_rect.left = clip_rect.top = 0;
|
||||
clip_rect.right = desc.dwWidth;
|
||||
clip_rect.bottom = desc.dwHeight;
|
||||
cm_pitch = (clip_rect.right + 31) / 32 + 1;
|
||||
setMask(0);
|
||||
setColor(~0);
|
||||
setClsColor(0);
|
||||
setOrigin(0, 0);
|
||||
setHandle(0, 0);
|
||||
setFont(graphics->getDefaultFont());
|
||||
setViewport(0, 0, getWidth(), getHeight());
|
||||
if (flags & gxCanvas::CANVAS_TEXTURE) ddUtil::buildMipMaps(surf);
|
||||
}
|
||||
|
||||
gxCanvas::~gxCanvas() {
|
||||
delete[] cm_mask;
|
||||
if (locked_cnt) surf->Unlock(0);
|
||||
if (t_surf) t_surf->Release();
|
||||
releaseZBuffer();
|
||||
main_surf->Release();
|
||||
}
|
||||
|
||||
void gxCanvas::backup()const {
|
||||
if (flags & CANVAS_TEX_CUBE) return;
|
||||
|
||||
if (!t_surf) {
|
||||
DDSURFACEDESC2 desc = { sizeof(desc) };
|
||||
if (surf->GetSurfaceDesc(&desc) < 0) return;
|
||||
if (desc.ddsCaps.dwCaps & DDSCAPS_SYSTEMMEMORY) return;
|
||||
|
||||
DDSURFACEDESC2 t_desc = { sizeof(t_desc) };
|
||||
t_desc.dwFlags = DDSD_CAPS | DDSD_PIXELFORMAT | DDSD_WIDTH | DDSD_HEIGHT;
|
||||
t_desc.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_SYSTEMMEMORY;
|
||||
t_desc.dwWidth = desc.dwWidth; t_desc.dwHeight = desc.dwHeight;
|
||||
t_desc.ddpfPixelFormat = desc.ddpfPixelFormat;
|
||||
|
||||
if (graphics->dirDraw->CreateSurface(&t_desc, &t_surf, 0) < 0) {
|
||||
t_surf = 0;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (t_surf->Blt(0, surf, 0, DDBLT_WAIT, 0) < 0) return;
|
||||
}
|
||||
|
||||
void gxCanvas::restore()const {
|
||||
if (!t_surf) return;
|
||||
|
||||
if (surf->Blt(0, t_surf, 0, DDBLT_WAIT, 0) < 0) return;
|
||||
}
|
||||
|
||||
IDirectDrawSurface7 *gxCanvas::getSurface()const {
|
||||
return surf;
|
||||
}
|
||||
|
||||
IDirectDrawSurface7 *gxCanvas::getTexSurface()const {
|
||||
if (mod_cnt == remip_cnt) return main_surf;
|
||||
ddUtil::buildMipMaps(surf);
|
||||
remip_cnt = mod_cnt;
|
||||
return main_surf;
|
||||
}
|
||||
|
||||
bool gxCanvas::clip(RECT *d)const {
|
||||
return ::clip(viewport, d);
|
||||
}
|
||||
|
||||
bool gxCanvas::clip(RECT *d, RECT *s)const {
|
||||
return ::clip(viewport, d, s);
|
||||
}
|
||||
|
||||
void gxCanvas::updateBitMask(const RECT &r)const {
|
||||
|
||||
int w = r.right - r.left; if (w <= 0) return;
|
||||
int h = r.bottom - r.top; if (h <= 0) return;
|
||||
|
||||
lock();
|
||||
RECT t = r;
|
||||
t.left &= ~31;
|
||||
t.right = (t.right + 31)&~31;
|
||||
w = (t.right - t.left) / 32;
|
||||
unsigned char *src_row = locked_surf + t.top*locked_pitch + t.left*format.getPitch();
|
||||
unsigned *dest_row = cm_mask + t.top*cm_pitch + t.left / 32;
|
||||
unsigned mask_argb = format.toARGB(mask_surf) & 0xffffff;
|
||||
|
||||
#ifdef _DEBUG_BITMASK
|
||||
unsigned *cm_mask_end = cm_mask + cm_pitch*clip_rect.bottom;
|
||||
#endif
|
||||
|
||||
while (h--) {
|
||||
unsigned *dest = dest_row;
|
||||
unsigned char *src = src_row;
|
||||
for (int c = 0; c < w; ++c) {
|
||||
unsigned mask = 0;
|
||||
for (int x = 0; x < 32; ++x) {
|
||||
unsigned pix = format.getPixel(src) & 0xffffff;
|
||||
mask = (mask << 1) | (pix != mask_argb);
|
||||
src += format.getPitch();
|
||||
}
|
||||
#ifdef _DEBUG_BITMASK
|
||||
if (dest < cm_mask || dest >= cm_mask_end) {
|
||||
gx_runtime->debugError("gxCanvas::updateBitMask dest out of range");
|
||||
}
|
||||
#endif
|
||||
*dest++ = mask;
|
||||
}
|
||||
dest_row += cm_pitch;
|
||||
src_row += locked_pitch;
|
||||
}
|
||||
unlock();
|
||||
}
|
||||
|
||||
void gxCanvas::setModify(int n) {
|
||||
mod_cnt = n;
|
||||
}
|
||||
|
||||
int gxCanvas::getModify()const {
|
||||
return mod_cnt;
|
||||
}
|
||||
|
||||
bool gxCanvas::attachZBuffer() {
|
||||
if (z_surf) return true;
|
||||
DDSURFACEDESC2 desc = { sizeof(desc) };
|
||||
desc.dwFlags = DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS | DDSD_PIXELFORMAT;
|
||||
desc.dwWidth = getWidth();
|
||||
desc.dwHeight = getHeight();
|
||||
desc.ddsCaps.dwCaps = DDSCAPS_ZBUFFER | DDSCAPS_VIDEOMEMORY;
|
||||
desc.ddpfPixelFormat = graphics->zbuffFmt;
|
||||
if (graphics->dirDraw->CreateSurface(&desc, &z_surf, 0) < 0) return false;
|
||||
surf->AddAttachedSurface(z_surf);
|
||||
return true;
|
||||
}
|
||||
|
||||
void gxCanvas::releaseZBuffer() {
|
||||
if (!z_surf) return;
|
||||
surf->DeleteAttachedSurface(0, z_surf);
|
||||
z_surf->Release();
|
||||
z_surf = 0;
|
||||
}
|
||||
|
||||
void gxCanvas::damage(const RECT &r)const {
|
||||
++mod_cnt; if (cm_mask) updateBitMask(r);
|
||||
}
|
||||
|
||||
void gxCanvas::setFont(gxFont *f) {
|
||||
font = f;
|
||||
}
|
||||
|
||||
void gxCanvas::setMask(unsigned argb) {
|
||||
mask_surf = format.fromARGB(argb);
|
||||
}
|
||||
|
||||
void gxCanvas::setColor(unsigned argb) {
|
||||
argb |= 0xff000000;
|
||||
color_argb = argb;
|
||||
color_surf = format.fromARGB(argb);
|
||||
}
|
||||
|
||||
void gxCanvas::setClsColor(unsigned argb) {
|
||||
argb |= 0xff000000;
|
||||
clsColor_surf = format.fromARGB(argb);
|
||||
}
|
||||
|
||||
void gxCanvas::setOrigin(int x, int y) {
|
||||
origin_x = x; origin_y = y;
|
||||
}
|
||||
|
||||
void gxCanvas::setHandle(int x, int y) {
|
||||
handle_x = x; handle_y = y;
|
||||
}
|
||||
|
||||
void gxCanvas::setViewport(int x, int y, int w, int h) {
|
||||
Rect r(x, y, w, h);
|
||||
if (!::clip(clip_rect, &r)) r = Rect(0, 0, 0, 0);
|
||||
viewport = r;
|
||||
}
|
||||
|
||||
//renderering primitives
|
||||
void gxCanvas::cls() {
|
||||
bltfx.dwFillColor = clsColor_surf;
|
||||
surf->Blt(&viewport, 0, 0, DDBLT_WAIT | DDBLT_COLORFILL, &bltfx);
|
||||
damage(viewport);
|
||||
}
|
||||
|
||||
void gxCanvas::plot(int x, int y) {
|
||||
x += origin_x; if (x < viewport.left || x >= viewport.right) return;
|
||||
y += origin_y; if (y < viewport.top || y >= viewport.bottom) return;
|
||||
bltfx.dwFillColor = color_surf;
|
||||
Rect dest(x, y, 1, 1);
|
||||
surf->Blt(&dest, 0, 0, DDBLT_WAIT | DDBLT_COLORFILL, &bltfx);
|
||||
damage(dest);
|
||||
}
|
||||
|
||||
void gxCanvas::line(int x0, int y0, int x1, int y1) {
|
||||
int ddf, padj, sadj;
|
||||
int dx, dy, sx, sy, ax, ay;
|
||||
|
||||
x0 += origin_x; y0 += origin_y;
|
||||
x1 += origin_x; y1 += origin_y;
|
||||
|
||||
int cx0, cx1, cy0, cy1, clip0, clip1;
|
||||
|
||||
cx0 = viewport.left;
|
||||
cx1 = viewport.right - 1;
|
||||
cy0 = viewport.top;
|
||||
cy1 = viewport.bottom - 1;
|
||||
|
||||
while (true) {
|
||||
clip0 = 0; clip1 = 0;
|
||||
|
||||
if (y0 > cy1)clip0 |= 1; else if (y0 < cy0)clip0 |= 2;
|
||||
if (x0 > cx1)clip0 |= 4; else if (x0 < cx0)clip0 |= 8;
|
||||
if (y1 > cy1)clip1 |= 1; else if (y1 < cy0)clip1 |= 2;
|
||||
if (x1 > cx1)clip1 |= 4; else if (x1 < cx0)clip1 |= 8;
|
||||
|
||||
if ((clip0 | clip1) == 0) break; //draw line
|
||||
if ((clip0&clip1) != 0) return; //outside
|
||||
|
||||
if ((clip0 & 1) == 1) { x0 = x0 + ((x1 - x0)*(cy1 - y0)) / (y1 - y0); y0 = cy1; continue; }
|
||||
if ((clip0 & 2) == 2) { x0 = x0 + ((x1 - x0)*(cy0 - y0)) / (y1 - y0); y0 = cy0; continue; }
|
||||
if ((clip0 & 4) == 4) { y0 = y0 + ((y1 - y0)*(cx1 - x0)) / (x1 - x0); x0 = cx1; continue; }
|
||||
if ((clip0 & 8) == 8) { y0 = y0 + ((y1 - y0)*(cx0 - x0)) / (x1 - x0); x0 = cx0; continue; }
|
||||
|
||||
if ((clip1 & 1) == 1) { x1 = x0 + ((x1 - x0)*(cy1 - y0)) / (y1 - y0); y1 = cy1; continue; }
|
||||
if ((clip1 & 2) == 2) { x1 = x0 + ((x1 - x0)*(cy0 - y0)) / (y1 - y0); y1 = cy0; continue; }
|
||||
if ((clip1 & 4) == 4) { y1 = y0 + ((y1 - y0)*(cx1 - x0)) / (x1 - x0); x1 = cx1; continue; }
|
||||
if ((clip1 & 8) == 8) { y1 = y0 + ((y1 - y0)*(cx0 - x0)) / (x1 - x0); x1 = cx0; continue; }
|
||||
}
|
||||
|
||||
dx = x1 - x0; dy = y1 - y0;
|
||||
if ((dx | dy) == 0) {
|
||||
setPixel(x0, y0, color_argb);
|
||||
return;
|
||||
}
|
||||
|
||||
if (dx >= 0) { sx = 1; ax = dx; } else { sx = -1; ax = -dx; }
|
||||
if (dy >= 0) { sy = 1; ay = dy; } else { sy = -1; ay = -dy; }
|
||||
|
||||
lock();
|
||||
if (ax > ay) {
|
||||
ddf = -ax; sadj = ax + ax; padj = ay + ay;
|
||||
while (ax-- >= 0) {
|
||||
setPixelFast(x0, y0, color_argb);
|
||||
x0 += sx; ddf += padj; if (ddf >= 0) { y0 += sy; ddf -= sadj; }
|
||||
}
|
||||
} else {
|
||||
ddf = -ay; sadj = ay + ay; padj = ax + ax;
|
||||
while (ay-- >= 0) {
|
||||
setPixelFast(x0, y0, color_argb);
|
||||
y0 += sy; ddf += padj; if (ddf >= 0) { x0 += sx; ddf -= sadj; }
|
||||
}
|
||||
|
||||
}
|
||||
unlock();
|
||||
}
|
||||
|
||||
void gxCanvas::rect(int x, int y, int w, int h, bool solid) {
|
||||
x += origin_x; y += origin_y;
|
||||
Rect dest(x, y, w, h);
|
||||
if (!clip(&dest)) return;
|
||||
|
||||
bltfx.dwFillColor = color_surf;
|
||||
|
||||
if (solid) {
|
||||
surf->Blt(&dest, 0, 0, DDBLT_WAIT | DDBLT_COLORFILL, &bltfx);
|
||||
damage(dest);
|
||||
return;
|
||||
}
|
||||
Rect r1(x, y, w, 1); if (clip(&r1)) {
|
||||
surf->Blt(&r1, 0, 0, DDBLT_WAIT | DDBLT_COLORFILL, &bltfx);
|
||||
}
|
||||
Rect r2(x, y, 1, h); if (clip(&r2)) {
|
||||
surf->Blt(&r2, 0, 0, DDBLT_WAIT | DDBLT_COLORFILL, &bltfx);
|
||||
}
|
||||
Rect r3(x + w - 1, y, 1, h); if (clip(&r3)) {
|
||||
surf->Blt(&r3, 0, 0, DDBLT_WAIT | DDBLT_COLORFILL, &bltfx);
|
||||
}
|
||||
Rect r4(x, y + h - 1, w, 1); if (clip(&r4)) {
|
||||
surf->Blt(&r4, 0, 0, DDBLT_WAIT | DDBLT_COLORFILL, &bltfx);
|
||||
}
|
||||
damage(dest);
|
||||
}
|
||||
|
||||
void gxCanvas::oval(int x1, int y1, int w, int h, bool solid) {
|
||||
x1 += origin_x; y1 += origin_y;
|
||||
Rect dest(x1, y1, w, h);
|
||||
if (!clip(&dest)) return;
|
||||
|
||||
bltfx.dwFillColor = color_surf;
|
||||
|
||||
float xr = w*.5f, yr = h*.5f, ar = (float)w / (float)h;
|
||||
float cx = x1 + xr + .5f, cy = y1 + yr - .5f, rsq = yr*yr, y;
|
||||
|
||||
if (solid) {
|
||||
y = dest.top - cy;
|
||||
for (int t = dest.top; t < dest.bottom; ++y, ++t) {
|
||||
float x = sqrt(rsq - y*y)*ar;
|
||||
int xa = floor(cx - x), xb = floor(cx + x);
|
||||
if (xb <= xa || xa >= viewport.right || xb <= viewport.left) continue;
|
||||
Rect dr; dr.top = t; dr.bottom = t + 1;
|
||||
dr.left = xa < viewport.left ? viewport.left : xa;
|
||||
dr.right = xb > viewport.right ? viewport.right : xb;
|
||||
surf->Blt(&dr, 0, 0, DDBLT_WAIT | DDBLT_COLORFILL, &bltfx);
|
||||
}
|
||||
damage(dest);
|
||||
return;
|
||||
}
|
||||
|
||||
int p_xa, p_xb, t, hh = floor(cy);
|
||||
|
||||
p_xa = p_xb = cx;
|
||||
t = dest.top; y = t - cy;
|
||||
if (dest.top > y1) { --t; --y; }
|
||||
for (; t <= hh; ++y, ++t) {
|
||||
float x = sqrt(rsq - y*y)*ar;
|
||||
int xa = floor(cx - x), xb = floor(cx + x);
|
||||
Rect r1(xa, t, p_xa - xa, 1); if (r1.right <= r1.left) r1.right = r1.left + 1;
|
||||
if (clip(&r1)) surf->Blt(&r1, 0, 0, DDBLT_WAIT | DDBLT_COLORFILL, &bltfx);
|
||||
Rect r2(p_xb, t, xb - p_xb, 1); if (r2.left >= r2.right) r2.left = r2.right - 1;
|
||||
if (clip(&r2)) surf->Blt(&r2, 0, 0, DDBLT_WAIT | DDBLT_COLORFILL, &bltfx);
|
||||
p_xa = xa; p_xb = xb;
|
||||
}
|
||||
|
||||
p_xa = p_xb = cx;
|
||||
t = dest.bottom - 1; y = t - cy;
|
||||
if (dest.bottom < y1 + h) { ++t; ++y; }
|
||||
for (; t > hh; --y, --t) {
|
||||
float x = sqrt(rsq - y*y)*ar;
|
||||
int xa = floor(cx - x), xb = floor(cx + x);
|
||||
Rect r1(xa, t, p_xa - xa, 1); if (r1.right <= r1.left) r1.right = r1.left + 1;
|
||||
if (clip(&r1)) surf->Blt(&r1, 0, 0, DDBLT_WAIT | DDBLT_COLORFILL, &bltfx);
|
||||
Rect r2(p_xb, t, xb - p_xb, 1); if (r2.left >= r2.right) r2.left = r2.right - 1;
|
||||
if (clip(&r2)) surf->Blt(&r2, 0, 0, DDBLT_WAIT | DDBLT_COLORFILL, &bltfx);
|
||||
p_xa = xa; p_xb = xb;
|
||||
}
|
||||
damage(dest);
|
||||
}
|
||||
|
||||
void gxCanvas::blit(int x, int y, gxCanvas *src, int src_x, int src_y, int src_w, int src_h, bool solid) {
|
||||
x += origin_x - src->handle_x;
|
||||
y += origin_y - src->handle_y;
|
||||
Rect dest_r(x, y, src_w, src_h), src_r(src_x, src_y, src_w, src_h);
|
||||
if (!clip(&dest_r, &src_r)) return;
|
||||
if (!::clip(src->clip_rect, &src_r, &dest_r)) return;
|
||||
|
||||
if (solid) {
|
||||
surf->Blt(&dest_r, src->surf, &src_r, DDBLT_WAIT, 0);
|
||||
} else {
|
||||
bltfx.ddckSrcColorkey.dwColorSpaceLowValue =
|
||||
bltfx.ddckSrcColorkey.dwColorSpaceHighValue = src->mask_surf;
|
||||
surf->Blt(&dest_r, src->surf, &src_r, DDBLT_WAIT | DDBLT_KEYSRCOVERRIDE, &bltfx);
|
||||
}
|
||||
damage(dest_r);
|
||||
}
|
||||
|
||||
void gxCanvas::text(int x, int y, const string &t) {
|
||||
|
||||
int ty = y + origin_y;
|
||||
if (ty >= viewport.bottom) return;
|
||||
if (ty + font->getHeight() <= viewport.top) return;
|
||||
|
||||
int tx = x + origin_x;
|
||||
if (tx >= viewport.right) return;
|
||||
|
||||
int b = 0, w;
|
||||
while (b < t.size() && tx + (w = font->charWidth(t[b])) <= viewport.left) {
|
||||
tx += w; x += w; ++b;
|
||||
}
|
||||
int e = b;
|
||||
while (e < t.size() && tx < viewport.right) {
|
||||
tx += font->charWidth(t[e]); ++e;
|
||||
}
|
||||
|
||||
if (e > b) font->render(this, format.toARGB(color_surf), x, y, t.substr(b, e - b));
|
||||
}
|
||||
|
||||
int gxCanvas::getWidth()const {
|
||||
return clip_rect.right;
|
||||
}
|
||||
|
||||
int gxCanvas::getHeight()const {
|
||||
return clip_rect.bottom;
|
||||
}
|
||||
|
||||
int gxCanvas::getDepth()const {
|
||||
return format.getDepth();
|
||||
}
|
||||
|
||||
void gxCanvas::getOrigin(int *x, int *y)const {
|
||||
*x = origin_x; *y = origin_y;
|
||||
}
|
||||
|
||||
void gxCanvas::getHandle(int *x, int *y)const {
|
||||
*x = handle_x; *y = handle_y;
|
||||
}
|
||||
|
||||
void gxCanvas::getViewport(int *x, int *y, int *w, int *h)const {
|
||||
*x = viewport.left; *y = viewport.top;
|
||||
*w = viewport.right - viewport.left; *h = viewport.bottom - viewport.top;
|
||||
}
|
||||
|
||||
unsigned gxCanvas::getMask()const {
|
||||
return format.toARGB(mask_surf);
|
||||
}
|
||||
|
||||
unsigned gxCanvas::getColor()const {
|
||||
return format.toARGB(color_surf);
|
||||
}
|
||||
|
||||
unsigned gxCanvas::getClsColor()const {
|
||||
return format.toARGB(clsColor_surf);
|
||||
}
|
||||
|
||||
bool gxCanvas::collide(int x1, int y1, const gxCanvas *i2, int x2, int y2, bool solid)const {
|
||||
|
||||
x1 -= handle_x; x2 -= i2->handle_x;
|
||||
if (x1 + clip_rect.right <= x2 || x1 >= x2 + i2->clip_rect.right) return false;
|
||||
y1 -= handle_y; y2 -= i2->handle_y;
|
||||
if (y1 + clip_rect.bottom <= y2 || y1 >= y2 + i2->clip_rect.bottom) return false;
|
||||
|
||||
if (solid) return true;
|
||||
|
||||
if (!cm_mask) {
|
||||
cm_mask = new unsigned[cm_pitch*clip_rect.bottom];
|
||||
updateBitMask(clip_rect);
|
||||
}
|
||||
if (!i2->cm_mask) {
|
||||
i2->cm_mask = new unsigned[i2->cm_pitch*i2->clip_rect.bottom];
|
||||
i2->updateBitMask(i2->clip_rect);
|
||||
}
|
||||
|
||||
const gxCanvas *i1 = this;
|
||||
|
||||
//to keep me sane!
|
||||
if (x1 > x2) {
|
||||
std::swap(x1, x2);
|
||||
std::swap(y1, y2);
|
||||
std::swap(i1, i2);
|
||||
}
|
||||
|
||||
Rect r1, r2, ir;
|
||||
r1.left = x1; r1.top = y1; r1.right = x1 + i1->clip_rect.right; r1.bottom = y1 + i1->clip_rect.bottom;
|
||||
r2.left = x2; r2.top = y2; r2.right = x2 + i2->clip_rect.right; r2.bottom = y2 + i2->clip_rect.bottom;
|
||||
ir.left = r1.left > r2.left ? r1.left : r2.left;
|
||||
ir.right = r1.right < r2.right ? r1.right : r2.right;
|
||||
ir.top = r1.top > r2.top ? r1.top : r2.top;
|
||||
ir.bottom = r1.bottom < r2.bottom ? r1.bottom : r2.bottom;
|
||||
|
||||
unsigned *s1 = i1->cm_mask, *s2 = i2->cm_mask;
|
||||
int i1_pitch = i1->cm_pitch, i2_pitch = i2->cm_pitch;
|
||||
s1 += (ir.top - r1.top)*i1_pitch;
|
||||
s2 += (ir.top - r2.top)*i2_pitch;
|
||||
|
||||
int startx = ir.left - r1.left;
|
||||
int stopx = ir.right - r1.left - 1;
|
||||
int shr = startx & 31;
|
||||
int shl = 32 - shr;
|
||||
int cnt = stopx / 32 - startx / 32;
|
||||
unsigned lwm = LWMS[stopx & 31];
|
||||
|
||||
#ifdef _DEBUG_BITMASK
|
||||
unsigned *cm_mask_end1 = i1->cm_mask + i1_pitch*i1->clip_rect.bottom;
|
||||
unsigned *cm_mask_end2 = i2->cm_mask + i2_pitch*i2->clip_rect.bottom;
|
||||
#endif
|
||||
|
||||
s1 += startx / 32;
|
||||
for (int y = ir.top; y < ir.bottom; ++y) {
|
||||
unsigned p = 0;
|
||||
unsigned *row1 = s1, *row2 = s2;
|
||||
for (int x = 0; x < cnt; ++x) {
|
||||
#ifdef _DEBUG_BITMASK
|
||||
if (row1 < i1->cm_mask || row2 < i2->cm_mask) {
|
||||
gx_runtime->debugError("gxCanvas::collide row underflow");
|
||||
}
|
||||
if (row1 >= cm_mask_end1 || row2 >= cm_mask_end2) {
|
||||
gx_runtime->debugError("gxCanvas::collide row overflow");
|
||||
}
|
||||
#endif
|
||||
unsigned n = *row2++;
|
||||
if (((n >> shr) | p) & *row1++) return true;
|
||||
p = shl < 32 ? n << shl : 0;
|
||||
}
|
||||
#ifdef _DEBUG_BITMASK
|
||||
if (row1 < i1->cm_mask || row2 < i2->cm_mask) {
|
||||
gx_runtime->debugError("gxCanvas::collide row underflow");
|
||||
}
|
||||
if (row1 >= cm_mask_end1 || row2 >= cm_mask_end2) {
|
||||
gx_runtime->debugError("gxCanvas::collide row overflow");
|
||||
}
|
||||
#endif
|
||||
if (((*row2 >> shr) | p) & *row1 & lwm) return true;
|
||||
s1 += i1_pitch; s2 += i2_pitch;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool gxCanvas::rect_collide(int x1, int y1, int x2, int y2, int w2, int h2, bool solid)const {
|
||||
|
||||
x1 -= handle_x; if (x1 + clip_rect.right <= x2 || x1 >= x2 + w2) return false;
|
||||
y1 -= handle_y; if (y1 + clip_rect.bottom <= y2 || y1 >= y2 + h2) return false;
|
||||
|
||||
if (solid) return true;
|
||||
|
||||
Rect r1(x1, y1, clip_rect.right, clip_rect.bottom), r2(x2, y2, w2, h2), ir;
|
||||
|
||||
ir.left = r1.left > r2.left ? r1.left : r2.left;
|
||||
ir.right = r1.right < r2.right ? r1.right : r2.right;
|
||||
ir.top = r1.top > r2.top ? r1.top : r2.top;
|
||||
ir.bottom = r1.bottom < r2.bottom ? r1.bottom : r2.bottom;
|
||||
|
||||
if (!cm_mask) {
|
||||
cm_mask = new unsigned[cm_pitch*clip_rect.bottom];
|
||||
updateBitMask(clip_rect);
|
||||
}
|
||||
|
||||
unsigned *s1 = cm_mask + (ir.top - r1.top)*cm_pitch;
|
||||
|
||||
int startx = ir.left - r1.left;
|
||||
int stopx = ir.right - r1.left - 1;
|
||||
int cnt = stopx / 32 - startx / 32;
|
||||
unsigned fwm = FWMS[startx & 31];
|
||||
unsigned lwm = LWMS[stopx & 31];
|
||||
|
||||
if (!cnt) { fwm &= lwm; lwm = 0; }
|
||||
|
||||
s1 += startx / 32;
|
||||
for (int h = ir.top; h < ir.bottom; ++h) {
|
||||
unsigned *row = s1;
|
||||
if (*row & fwm) return true;
|
||||
for (int x = 1; x < cnt; ++x) {
|
||||
if (*++row) return true;
|
||||
}
|
||||
if (lwm && (*++row & lwm)) return true;
|
||||
s1 += cm_pitch;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool gxCanvas::lock()const {
|
||||
if (!locked_cnt++) {
|
||||
DDSURFACEDESC2 desc = { sizeof(desc) };
|
||||
if (surf->Lock(0, &desc, DDLOCK_WAIT | DDLOCK_NOSYSLOCK, 0) < 0) {
|
||||
--locked_cnt;
|
||||
return false;
|
||||
}
|
||||
locked_pitch = desc.lPitch;
|
||||
locked_surf = (unsigned char*)desc.lpSurface;
|
||||
lock_mod_cnt = mod_cnt;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void gxCanvas::unlock()const {
|
||||
if (locked_cnt == 1) {
|
||||
if (lock_mod_cnt != mod_cnt && cm_mask) updateBitMask(clip_rect);
|
||||
surf->Unlock(0);
|
||||
}
|
||||
--locked_cnt;
|
||||
}
|
||||
|
||||
void gxCanvas::setPixel(int x, int y, unsigned argb) {
|
||||
x += origin_x; if (x < viewport.left || x >= viewport.right) return;
|
||||
y += origin_y; if (y < viewport.top || y >= viewport.bottom) return;
|
||||
//lock();
|
||||
setPixelFast(x, y, argb);
|
||||
//unlock();
|
||||
}
|
||||
|
||||
unsigned gxCanvas::getPixel(int x, int y)const {
|
||||
x += origin_x; if (x < viewport.left || x >= viewport.right) return format.toARGB(mask_surf);
|
||||
y += origin_y; if (y < viewport.top || y >= viewport.bottom) return format.toARGB(mask_surf);
|
||||
//lock();
|
||||
unsigned p = getPixelFast(x, y);
|
||||
//unlock();
|
||||
return p;
|
||||
}
|
||||
|
||||
void gxCanvas::copyPixelFast(int x, int y, gxCanvas *src, int src_x, int src_y) {
|
||||
switch (format.getDepth()) {
|
||||
case 16:
|
||||
*(short*)(locked_surf + y*locked_pitch + x * 2) =
|
||||
*(short*)(src->locked_surf + src_y*src->locked_pitch + src_x * 2);
|
||||
break;
|
||||
case 24:
|
||||
{
|
||||
unsigned char *p = locked_surf + y*locked_pitch + x * 3;
|
||||
unsigned char *t = src->locked_surf + src_y*src->locked_pitch + src_x * 3;
|
||||
*(short*)p = *(short*)t; *(char*)(p + 2) = *(char*)(t + 2);
|
||||
}
|
||||
break;
|
||||
case 32:
|
||||
*(int*)(locked_surf + y*locked_pitch + x * 4) =
|
||||
*(int*)(src->locked_surf + src_y*src->locked_pitch + src_x * 4);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void gxCanvas::copyPixel(int x, int y, gxCanvas *src, int src_x, int src_y) {
|
||||
x += origin_x; if (x < viewport.left || x >= viewport.right) return;
|
||||
y += origin_y; if (y < viewport.top || y >= viewport.bottom) return;
|
||||
src_x += src->origin_x; if (src_x < src->viewport.left || src_x >= src->viewport.right) return;
|
||||
src_y += src->origin_y; if (src_y < src->viewport.top || src_y >= src->viewport.bottom) return;
|
||||
//lock();
|
||||
//src->lock();
|
||||
copyPixelFast(x, y, src, src_x, src_y);
|
||||
//src->unlock();
|
||||
//unlock();
|
||||
}
|
||||
|
||||
void gxCanvas::setCubeMode(int mode) {
|
||||
cube_mode = mode;
|
||||
}
|
||||
|
||||
void gxCanvas::setCubeFace(int face) {
|
||||
|
||||
getTexSurface();
|
||||
surf = cube_surfs[face];
|
||||
}
|
||||
@@ -1,138 +0,0 @@
|
||||
|
||||
#ifndef GXCANVAS_H
|
||||
#define GXCANVAS_H
|
||||
|
||||
#include "ddutil.hpp"
|
||||
|
||||
class gxFont;
|
||||
class gxGraphics;
|
||||
|
||||
|
||||
|
||||
class gxCanvas {
|
||||
public:
|
||||
gxCanvas(gxGraphics *graphics, IDirectDrawSurface7 *surface, int flags);
|
||||
~gxCanvas();
|
||||
|
||||
void backup()const;
|
||||
void restore()const;
|
||||
IDirectDrawSurface7 *getSurface()const;
|
||||
IDirectDrawSurface7 *getTexSurface()const;
|
||||
void setModify(int n);
|
||||
int getModify()const;
|
||||
|
||||
bool attachZBuffer();
|
||||
void releaseZBuffer();
|
||||
|
||||
bool clip(RECT *d)const;
|
||||
bool clip(RECT *d, RECT *s)const;
|
||||
void damage(const RECT &r)const;
|
||||
|
||||
private:
|
||||
int flags, cube_mode;
|
||||
gxGraphics *graphics;
|
||||
|
||||
IDirectDrawSurface7 *main_surf, *surf, *z_surf, *cube_surfs[6];
|
||||
|
||||
mutable int mod_cnt;
|
||||
mutable IDirectDrawSurface7 *t_surf;
|
||||
|
||||
mutable int locked_pitch, locked_cnt, lock_mod_cnt, remip_cnt;
|
||||
mutable unsigned char *locked_surf;
|
||||
|
||||
mutable int cm_pitch;
|
||||
mutable unsigned *cm_mask;
|
||||
|
||||
RECT clip_rect;
|
||||
|
||||
PixelFormat format;
|
||||
|
||||
gxFont *font;
|
||||
RECT viewport;
|
||||
int origin_x, origin_y, handle_x, handle_y;
|
||||
unsigned mask_surf, color_surf, color_argb, clsColor_surf;
|
||||
|
||||
void updateBitMask(const RECT &r)const;
|
||||
|
||||
/***** GX INTERFACE *****/
|
||||
public:
|
||||
enum {
|
||||
CANVAS_TEX_RGB = 0x0001,
|
||||
CANVAS_TEX_ALPHA = 0x0002,
|
||||
CANVAS_TEX_MASK = 0x0004,
|
||||
CANVAS_TEX_MIPMAP = 0x0008,
|
||||
CANVAS_TEX_CLAMPU = 0x0010,
|
||||
CANVAS_TEX_CLAMPV = 0x0020,
|
||||
CANVAS_TEX_SPHERE = 0x0040,
|
||||
CANVAS_TEX_CUBE = 0x0080,
|
||||
CANVAS_TEX_VIDMEM = 0x0100,
|
||||
CANVAS_TEX_HICOLOR = 0x0200,
|
||||
CANVAS_TEX_NPOT = 0x0400, // 1024
|
||||
CANVAS_3DRENDER = 0x0800, // 2048
|
||||
|
||||
CANVAS_TEXTURE = 0x10000,
|
||||
CANVAS_NONDISPLAY = 0x20000,
|
||||
CANVAS_HIGHCOLOR = 0x40000,
|
||||
};
|
||||
|
||||
enum {
|
||||
CUBEMODE_REFLECTION = 1,
|
||||
CUBEMODE_NORMAL = 2,
|
||||
CUBEMODE_POSITION = 3,
|
||||
|
||||
CUBESPACE_WORLD = 0,
|
||||
CUBESPACE_CAMERA = 4
|
||||
};
|
||||
|
||||
//MANIPULATORS
|
||||
void setFont(gxFont *font);
|
||||
void setMask(unsigned argb);
|
||||
void setColor(unsigned argb);
|
||||
void setClsColor(unsigned argb);
|
||||
void setOrigin(int x, int y);
|
||||
void setHandle(int x, int y);
|
||||
void setViewport(int x, int y, int w, int h);
|
||||
|
||||
void cls();
|
||||
void plot(int x, int y);
|
||||
void line(int x, int y, int x2, int y2);
|
||||
void rect(int x, int y, int w, int h, bool solid);
|
||||
void oval(int x, int y, int w, int h, bool solid);
|
||||
void text(int x, int y, const std::string &t);
|
||||
void blit(int x, int y, gxCanvas *src, int src_x, int src_y, int src_w, int src_h, bool solid);
|
||||
|
||||
bool collide(int x, int y, const gxCanvas *src, int src_x, int src_y, bool solid)const;
|
||||
bool rect_collide(int x, int y, int rect_x, int rect_y, int rect_w, int rect_h, bool solid)const;
|
||||
|
||||
bool lock()const;
|
||||
void setPixel(int x, int y, unsigned argb);
|
||||
void setPixelFast(int x, int y, unsigned argb) {
|
||||
format.setPixel(locked_surf + y*locked_pitch + x*format.getPitch(), argb);
|
||||
++mod_cnt;
|
||||
}
|
||||
void copyPixel(int x, int y, gxCanvas *src, int src_x, int src_y);
|
||||
void copyPixelFast(int x, int y, gxCanvas *src, int src_x, int src_y);
|
||||
unsigned getPixel(int x, int y)const;
|
||||
unsigned getPixelFast(int x, int y)const {
|
||||
return format.getPixel(locked_surf + y*locked_pitch + x*format.getPitch());
|
||||
};
|
||||
void unlock()const;
|
||||
|
||||
void setCubeMode(int mode);
|
||||
void setCubeFace(int face);
|
||||
|
||||
//ACCESSORS
|
||||
int getWidth()const;
|
||||
int getHeight()const;
|
||||
int getDepth()const;
|
||||
int getFlags()const { return flags; }
|
||||
int cubeMode()const { return cube_mode; }
|
||||
void getOrigin(int *x, int *y)const;
|
||||
void getHandle(int *x, int *y)const;
|
||||
void getViewport(int *x, int *y, int *w, int *h)const;
|
||||
unsigned getMask()const;
|
||||
unsigned getColor()const;
|
||||
unsigned getClsColor()const;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -1,6 +0,0 @@
|
||||
|
||||
#include "std.hpp"
|
||||
#include "gxchannel.hpp"
|
||||
|
||||
gxChannel::~gxChannel(){
|
||||
}
|
||||
@@ -1,21 +0,0 @@
|
||||
|
||||
#ifndef GXCHANNEL_H
|
||||
#define GXCHANNEL_H
|
||||
|
||||
class gxChannel{
|
||||
|
||||
/***** GX INTERFACE *****/
|
||||
public:
|
||||
virtual ~gxChannel();
|
||||
//modifiers
|
||||
virtual void stop()=0;
|
||||
virtual void setPaused( bool paused )=0;
|
||||
virtual void setPitch( int pitch )=0;
|
||||
virtual void setVolume( float volume )=0;
|
||||
virtual void setPan( float pan )=0;
|
||||
virtual void set3d( const float pos[3],const float vel[3] )=0;
|
||||
|
||||
virtual bool isPlaying()=0;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -1,62 +0,0 @@
|
||||
|
||||
#include "std.hpp"
|
||||
#include "gxdevice.hpp"
|
||||
#include "gxruntime.hpp"
|
||||
|
||||
gxDevice::gxDevice(){
|
||||
reset();
|
||||
}
|
||||
|
||||
gxDevice::~gxDevice(){
|
||||
}
|
||||
|
||||
void gxDevice::reset(){
|
||||
memset( down_state,0,sizeof(down_state) );
|
||||
memset( axis_states,0,sizeof(axis_states) );
|
||||
memset( hit_count,0,sizeof(hit_count) );
|
||||
put=get=0;
|
||||
}
|
||||
|
||||
void gxDevice::downEvent( int key ){
|
||||
down_state[key]=true;
|
||||
++hit_count[key];
|
||||
if( put-get<QUE_SIZE ) que[put++&QUE_MASK]=key;
|
||||
}
|
||||
|
||||
void gxDevice::upEvent( int key ){
|
||||
down_state[key]=false;
|
||||
}
|
||||
|
||||
void gxDevice::setDownState( int key,bool down ){
|
||||
if( down==down_state[key] ) return;
|
||||
if( down ) downEvent( key );
|
||||
else upEvent( key );
|
||||
}
|
||||
|
||||
void gxDevice::flush(){
|
||||
update();
|
||||
memset( hit_count,0,sizeof(hit_count) );
|
||||
put=get=0;
|
||||
}
|
||||
|
||||
bool gxDevice::keyDown( int key ){
|
||||
update();
|
||||
return down_state[key];
|
||||
}
|
||||
|
||||
int gxDevice::keyHit( int key ){
|
||||
update();
|
||||
int n=hit_count[key];
|
||||
hit_count[key]-=n;
|
||||
return n;
|
||||
}
|
||||
|
||||
int gxDevice::getKey(){
|
||||
update();
|
||||
return get<put ? que[get++ & QUE_MASK] : 0;
|
||||
}
|
||||
|
||||
float gxDevice::getAxisState( int axis ){
|
||||
update();
|
||||
return axis_states[axis];
|
||||
}
|
||||
@@ -1,40 +0,0 @@
|
||||
|
||||
#ifndef GXDEVICE_H
|
||||
#define GXDEVICE_H
|
||||
|
||||
class gxDevice{
|
||||
public:
|
||||
float axis_states[32];
|
||||
|
||||
gxDevice();
|
||||
virtual ~gxDevice();
|
||||
|
||||
virtual void update(){}
|
||||
|
||||
void reset();
|
||||
void downEvent( int key );
|
||||
void upEvent( int key );
|
||||
void setDownState( int key,bool down );
|
||||
|
||||
private:
|
||||
enum{
|
||||
QUE_SIZE=32,QUE_MASK=QUE_SIZE-1
|
||||
};
|
||||
int hit_count[256]; //how many hits of key
|
||||
bool down_state[256]; //time key went down
|
||||
int que[QUE_SIZE],put,get;
|
||||
|
||||
/***** GX INTERFACE *****/
|
||||
public:
|
||||
void flush();
|
||||
|
||||
bool keyDown( int key );
|
||||
|
||||
int keyHit( int key );
|
||||
|
||||
int getKey();
|
||||
|
||||
float getAxisState( int axis );
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -1,20 +0,0 @@
|
||||
|
||||
#include "std.hpp"
|
||||
#include "gxdir.hpp"
|
||||
|
||||
gxDir::gxDir( HANDLE h,const WIN32_FIND_DATA &f ):handle(h),findData(f){
|
||||
}
|
||||
|
||||
gxDir::~gxDir(){
|
||||
if( handle!=INVALID_HANDLE_VALUE ) FindClose( handle );
|
||||
}
|
||||
|
||||
string gxDir::getNextFile(){
|
||||
if( handle==INVALID_HANDLE_VALUE ) return "";
|
||||
string t=findData.cFileName;
|
||||
if( !FindNextFile( handle,&findData ) ){
|
||||
FindClose( handle );
|
||||
handle=INVALID_HANDLE_VALUE;
|
||||
}
|
||||
return t;
|
||||
}
|
||||
@@ -1,22 +0,0 @@
|
||||
|
||||
#ifndef GXDIR_H
|
||||
#define GXDIR_H
|
||||
|
||||
#include <string>
|
||||
#include <windows.h>
|
||||
|
||||
class gxDir{
|
||||
public:
|
||||
gxDir( HANDLE h,const WIN32_FIND_DATA &f );
|
||||
~gxDir();
|
||||
|
||||
private:
|
||||
HANDLE handle;
|
||||
WIN32_FIND_DATA findData;
|
||||
|
||||
/***** GX INTERFACE *****/
|
||||
public:
|
||||
std::string getNextFile();
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -1,83 +0,0 @@
|
||||
|
||||
#include "std.hpp"
|
||||
#include "gxfilesystem.hpp"
|
||||
|
||||
static set<gxDir*> dir_set;
|
||||
|
||||
gxFileSystem::gxFileSystem(){
|
||||
dir_set.clear();
|
||||
}
|
||||
|
||||
gxFileSystem::~gxFileSystem(){
|
||||
while( dir_set.size() ) closeDir( *dir_set.begin() );
|
||||
}
|
||||
|
||||
bool gxFileSystem::createDir( const std::string &dir ){
|
||||
return CreateDirectory( dir.c_str(),0 ) ? true : false;
|
||||
}
|
||||
|
||||
bool gxFileSystem::deleteDir( const std::string &dir ){
|
||||
return RemoveDirectory( dir.c_str() ) ? true : false;
|
||||
}
|
||||
|
||||
bool gxFileSystem::createFile( const std::string &file ){
|
||||
return false;
|
||||
}
|
||||
|
||||
bool gxFileSystem::deleteFile( const std::string &file ){
|
||||
return DeleteFile( file.c_str() ) ? true : false;
|
||||
}
|
||||
|
||||
bool gxFileSystem::copyFile( const std::string &src,const string &dest ){
|
||||
return CopyFile( src.c_str(),dest.c_str(),false ) ? true : false;
|
||||
}
|
||||
|
||||
bool gxFileSystem::renameFile( const std::string &src,const std::string &dest ){
|
||||
return MoveFile( src.c_str(),dest.c_str() ) ? true : false;
|
||||
}
|
||||
|
||||
bool gxFileSystem::setCurrentDir( const std::string &dir ){
|
||||
return SetCurrentDirectory( dir.c_str()) ? true : false;
|
||||
}
|
||||
|
||||
string gxFileSystem::getCurrentDir()const{
|
||||
char buff[MAX_PATH];
|
||||
if( !GetCurrentDirectory( MAX_PATH,buff ) ) return "";
|
||||
string t=buff;if( t.size() && t[t.size()-1]!='\\' ) t+='\\';
|
||||
return t;
|
||||
}
|
||||
|
||||
int gxFileSystem::getFileSize( const std::string &name )const{
|
||||
WIN32_FIND_DATA findData;
|
||||
HANDLE h=FindFirstFile( name.c_str(),&findData );
|
||||
if( h==INVALID_HANDLE_VALUE ) return 0;
|
||||
int n=findData.dwFileAttributes,sz=findData.nFileSizeLow;
|
||||
FindClose( h );return n & FILE_ATTRIBUTE_DIRECTORY ? 0 : sz;
|
||||
}
|
||||
|
||||
int gxFileSystem::getFileType( const std::string &name )const{
|
||||
DWORD t=GetFileAttributes( name.c_str() );
|
||||
return t==-1 ? FILE_TYPE_NONE :
|
||||
(t & FILE_ATTRIBUTE_DIRECTORY ? FILE_TYPE_DIR : FILE_TYPE_FILE);
|
||||
}
|
||||
|
||||
gxDir *gxFileSystem::openDir( const std::string &name,int flags ){
|
||||
string t=name;
|
||||
if( t[t.size()-1]=='\\' ) t+="*";
|
||||
else t+="\\*";
|
||||
WIN32_FIND_DATA f;
|
||||
HANDLE h=FindFirstFile( t.c_str(),&f );
|
||||
if( h!=INVALID_HANDLE_VALUE ){
|
||||
gxDir *d=new gxDir( h,f );
|
||||
dir_set.insert( d );
|
||||
return d;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
gxDir *gxFileSystem::verifyDir( gxDir *d ){
|
||||
return dir_set.count(d) ? d : 0;
|
||||
}
|
||||
|
||||
void gxFileSystem::closeDir( gxDir *d ){
|
||||
if( dir_set.erase( d ) ) delete d;
|
||||
}
|
||||
@@ -1,37 +0,0 @@
|
||||
|
||||
#ifndef GXFILESYSTEM_H
|
||||
#define GXFILESYSTEM_H
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "gxdir.hpp"
|
||||
|
||||
class gxFileSystem{
|
||||
public:
|
||||
gxFileSystem();
|
||||
~gxFileSystem();
|
||||
|
||||
/***** GX INTERFACE *****/
|
||||
public:
|
||||
enum{
|
||||
FILE_TYPE_NONE=0,FILE_TYPE_FILE=1,FILE_TYPE_DIR=2
|
||||
};
|
||||
|
||||
bool createDir( const std::string &dir );
|
||||
bool deleteDir( const std::string &dir );
|
||||
bool createFile( const std::string &file );
|
||||
bool deleteFile( const std::string &file );
|
||||
bool copyFile( const std::string &src,const std::string &dest );
|
||||
bool renameFile( const std::string &src,const std::string &dest );
|
||||
bool setCurrentDir( const std::string &dir );
|
||||
|
||||
std::string getCurrentDir()const;
|
||||
int getFileSize( const std::string &name )const;
|
||||
int getFileType( const std::string &name )const;
|
||||
|
||||
gxDir *openDir( const std::string &name,int flags );
|
||||
gxDir *verifyDir( gxDir *d );
|
||||
void closeDir( gxDir *dir );
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -1,71 +0,0 @@
|
||||
|
||||
#include "std.hpp"
|
||||
#include "gxfont.hpp"
|
||||
#include "gxcanvas.hpp"
|
||||
#include "gxgraphics.hpp"
|
||||
|
||||
gxFont::gxFont( gxGraphics *g,gxCanvas *c,int w,int h,int b,int e,int d,int *os,int *ws ):
|
||||
graphics(g),canvas(c),
|
||||
width(w),height(h),begin_char(b),end_char(e),def_char(d),
|
||||
offs(os),widths(ws){
|
||||
canvas->setMask( 0xffffff );
|
||||
t_canvas=graphics->createCanvas( graphics->getWidth(),height,0 );
|
||||
}
|
||||
|
||||
gxFont::~gxFont(){
|
||||
delete[] offs;
|
||||
delete[] widths;
|
||||
graphics->freeCanvas( t_canvas );
|
||||
graphics->freeCanvas( canvas );
|
||||
}
|
||||
|
||||
int gxFont::charWidth( int c )const{
|
||||
if( c<begin_char || c>=end_char ) c=def_char;
|
||||
return widths[c-begin_char];
|
||||
}
|
||||
|
||||
void gxFont::render( gxCanvas *dest,unsigned color_argb,int x,int y,const string &t ){
|
||||
int width=getWidth( t );
|
||||
if( width>t_canvas->getWidth() ){
|
||||
graphics->freeCanvas( t_canvas );
|
||||
t_canvas=graphics->createCanvas( width,height,0 );
|
||||
}
|
||||
|
||||
t_canvas->setColor( color_argb );
|
||||
if( !(t_canvas->getColor()&0xffffff) ) t_canvas->setColor( 0x10 );
|
||||
t_canvas->rect( 0,0,width,height,true );
|
||||
|
||||
int t_x=0;
|
||||
for( int k=0;k<t.size();++k ){
|
||||
int c=t[k]&0xff;
|
||||
if( c<begin_char || c>=end_char ) c=def_char;
|
||||
c-=begin_char;
|
||||
int sx=(offs[c]>>16)&0xffff,sy=offs[c]&0xffff;
|
||||
t_canvas->blit( t_x,0,canvas,sx,sy,widths[c],height,false );
|
||||
t_x+=widths[c];
|
||||
}
|
||||
|
||||
dest->blit( x,y,t_canvas,0,0,width,height,false );
|
||||
}
|
||||
|
||||
int gxFont::getWidth()const{
|
||||
return width;
|
||||
}
|
||||
|
||||
int gxFont::getHeight()const{
|
||||
return height;
|
||||
}
|
||||
|
||||
int gxFont::getWidth( const string &t )const{
|
||||
int w=0;
|
||||
for( int k=0;k<t.size();++k ){
|
||||
int c=t[k]&0xff;
|
||||
if( c<begin_char || c>=end_char ) c=def_char;
|
||||
w+=widths[c-begin_char];
|
||||
}
|
||||
return w;
|
||||
}
|
||||
|
||||
bool gxFont::isPrintable( int chr )const{
|
||||
return chr>=begin_char && chr<end_char;
|
||||
}
|
||||
@@ -1,42 +0,0 @@
|
||||
|
||||
#ifndef GXFONT_H
|
||||
#define GXFONT_H
|
||||
|
||||
class gxCanvas;
|
||||
class gxGraphics;
|
||||
|
||||
|
||||
|
||||
class gxFont{
|
||||
public:
|
||||
gxFont(
|
||||
gxGraphics *graphics,gxCanvas *canvas,
|
||||
int width,int height,int begin_char,int end_char,int def_char,
|
||||
int *offs,int *widths );
|
||||
~gxFont();
|
||||
|
||||
int charWidth( int c )const;
|
||||
void render( gxCanvas *dest,unsigned color_argb,int x,int y,const std::string &t );
|
||||
|
||||
private:
|
||||
gxGraphics *graphics;
|
||||
gxCanvas *canvas,*t_canvas;
|
||||
int width,height,begin_char,end_char,def_char;
|
||||
int *offs,*widths;
|
||||
|
||||
/***** GX INTERFACE *****/
|
||||
public:
|
||||
enum{
|
||||
FONT_BOLD=1,
|
||||
FONT_ITALIC=2,
|
||||
FONT_UNDERLINE=4
|
||||
};
|
||||
|
||||
//ACCESSORS
|
||||
int getWidth()const; //width of widest char
|
||||
int getHeight()const; //height of font
|
||||
int getWidth( const std::string &text )const; //width of string
|
||||
bool isPrintable( int chr )const; //printable char?
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -1,611 +0,0 @@
|
||||
|
||||
#include "std.hpp"
|
||||
#include "gxgraphics.hpp"
|
||||
#include "gxruntime.hpp"
|
||||
|
||||
extern gxRuntime *gx_runtime;
|
||||
|
||||
gxGraphics::gxGraphics(gxRuntime *rt, IDirectDraw7 *dd, IDirectDrawSurface7 *fs, IDirectDrawSurface7 *bs, bool d3d) :
|
||||
runtime(rt), dirDraw(dd), dir3d(0), dir3dDev(0), def_font(0), gfx_lost(false), dummy_mesh(0) {
|
||||
|
||||
dirDraw->QueryInterface(IID_IDirectDraw, (void**)&ds_dirDraw);
|
||||
|
||||
front_canvas = new gxCanvas(this, fs, 0);
|
||||
back_canvas = new gxCanvas(this, bs, 0);
|
||||
|
||||
front_canvas->cls();
|
||||
back_canvas->cls();
|
||||
|
||||
def_font = loadFont("courier", 12, 0);
|
||||
|
||||
front_canvas->setFont(def_font);
|
||||
back_canvas->setFont(def_font);
|
||||
|
||||
memset(&primFmt, 0, sizeof(primFmt));
|
||||
primFmt.dwSize = sizeof(primFmt);
|
||||
fs->GetPixelFormat(&primFmt);
|
||||
|
||||
//are we fullscreen?
|
||||
_gamma = 0;
|
||||
if (fs != bs) {
|
||||
if (fs->QueryInterface(IID_IDirectDrawGammaControl, (void**)&_gamma) >= 0) {
|
||||
if (_gamma->GetGammaRamp(0, &_gammaRamp) < 0) _gamma = 0;
|
||||
}
|
||||
}
|
||||
if (!_gamma) {
|
||||
for (int k = 0; k < 256; ++k) _gammaRamp.red[k] = _gammaRamp.blue[k] = _gammaRamp.green[k] = k;
|
||||
}
|
||||
}
|
||||
|
||||
gxGraphics::~gxGraphics() {
|
||||
if (_gamma) _gamma->Release();
|
||||
while (scene_set.size()) freeScene(*scene_set.begin());
|
||||
while (movie_set.size()) closeMovie(*movie_set.begin());
|
||||
while (font_set.size()) freeFont(*font_set.begin());
|
||||
while (canvas_set.size()) freeCanvas(*canvas_set.begin());
|
||||
|
||||
set<string>::iterator it;
|
||||
for (it = font_res.begin(); it != font_res.end(); ++it) RemoveFontResource((*it).c_str());
|
||||
font_res.clear();
|
||||
|
||||
delete back_canvas;
|
||||
delete front_canvas;
|
||||
|
||||
ds_dirDraw->Release();
|
||||
|
||||
dirDraw->RestoreDisplayMode();
|
||||
dirDraw->Release();
|
||||
}
|
||||
|
||||
void gxGraphics::setGamma(int r, int g, int b, float dr, float dg, float db) {
|
||||
_gammaRamp.red[r & 255] = dr*257.0f;
|
||||
_gammaRamp.green[g & 255] = dg*257.0f;
|
||||
_gammaRamp.blue[b & 255] = db*257.0f;
|
||||
}
|
||||
|
||||
void gxGraphics::updateGamma(bool calibrate) {
|
||||
if (!_gamma) return;
|
||||
_gamma->SetGammaRamp(calibrate ? DDSGR_CALIBRATE : 0, &_gammaRamp);
|
||||
}
|
||||
|
||||
void gxGraphics::getGamma(int r, int g, int b, float *dr, float *dg, float *db) {
|
||||
*dr = _gammaRamp.red[r & 255] / 257.0f;
|
||||
*dg = _gammaRamp.green[g & 255] / 257.0f;
|
||||
*db = _gammaRamp.blue[b & 255] / 257.0f;
|
||||
}
|
||||
|
||||
void gxGraphics::backup() {
|
||||
}
|
||||
|
||||
bool gxGraphics::restore() {
|
||||
|
||||
while (dirDraw->TestCooperativeLevel() != DD_OK) {
|
||||
|
||||
if (dirDraw->TestCooperativeLevel() == DDERR_WRONGMODE) return false;
|
||||
|
||||
Sleep(100);
|
||||
}
|
||||
|
||||
if (back_canvas->getSurface()->IsLost() == DD_OK) return true;
|
||||
|
||||
dirDraw->RestoreAllSurfaces();
|
||||
|
||||
//restore all canvases
|
||||
set<gxCanvas*>::iterator it;
|
||||
for (it = canvas_set.begin(); it != canvas_set.end(); ++it) {
|
||||
(*it)->restore();
|
||||
}
|
||||
|
||||
//restore all meshes (b3d surfaces)
|
||||
set<gxMesh*>::iterator mesh_it;
|
||||
for (mesh_it = mesh_set.begin(); mesh_it != mesh_set.end(); ++mesh_it) {
|
||||
(*mesh_it)->restore();
|
||||
}
|
||||
if (dir3d) dir3d->EvictManagedTextures();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
gxCanvas *gxGraphics::getFrontCanvas()const {
|
||||
return front_canvas;
|
||||
}
|
||||
|
||||
gxCanvas *gxGraphics::getBackCanvas()const {
|
||||
return back_canvas;
|
||||
}
|
||||
|
||||
gxFont *gxGraphics::getDefaultFont()const {
|
||||
return def_font;
|
||||
}
|
||||
|
||||
void gxGraphics::vwait() {
|
||||
dirDraw->WaitForVerticalBlank(DDWAITVB_BLOCKBEGIN, 0);
|
||||
}
|
||||
|
||||
void gxGraphics::flip(bool v) {
|
||||
runtime->flip(v);
|
||||
}
|
||||
|
||||
void gxGraphics::copy(gxCanvas *dest, int dx, int dy, int dw, int dh, gxCanvas *src, int sx, int sy, int sw, int sh) {
|
||||
RECT r = { dx,dy,dx + dw,dy + dh };
|
||||
ddUtil::copy(dest->getSurface(), dx, dy, dw, dh, src->getSurface(), sx, sy, sw, sh);
|
||||
dest->damage(r);
|
||||
}
|
||||
|
||||
int gxGraphics::getScanLine()const {
|
||||
DWORD t = 0;
|
||||
dirDraw->GetScanLine(&t);
|
||||
return t;
|
||||
}
|
||||
|
||||
int gxGraphics::getTotalVidmem()const {
|
||||
DDCAPS caps = { sizeof(caps) };
|
||||
dirDraw->GetCaps(&caps, 0);
|
||||
return caps.dwVidMemTotal;
|
||||
}
|
||||
|
||||
int gxGraphics::getAvailVidmem()const {
|
||||
DDCAPS caps = { sizeof(caps) };
|
||||
dirDraw->GetCaps(&caps, 0);
|
||||
return caps.dwVidMemFree;
|
||||
}
|
||||
|
||||
gxMovie *gxGraphics::openMovie(const string &file, int flags) {
|
||||
|
||||
/*IAMMultiMediaStream *iam_stream;
|
||||
|
||||
if (CoCreateInstance(
|
||||
CLSID_AMMultiMediaStream, NULL, CLSCTX_INPROC_SERVER,
|
||||
IID_IAMMultiMediaStream, (void **)&iam_stream) == S_OK) {
|
||||
|
||||
if (iam_stream->Initialize(STREAMTYPE_READ, AMMSF_NOGRAPHTHREAD, NULL) == S_OK) {
|
||||
|
||||
if (iam_stream->AddMediaStream(ds_dirDraw, &MSPID_PrimaryVideo, 0, NULL) == S_OK) {
|
||||
|
||||
iam_stream->AddMediaStream(NULL, &MSPID_PrimaryAudio, AMMSF_ADDDEFAULTRENDERER, NULL);
|
||||
|
||||
WCHAR *path = new WCHAR[file.size() + 1];
|
||||
MultiByteToWideChar(CP_ACP, 0, file.c_str(), -1, path, sizeof(WCHAR)*(file.size() + 1));
|
||||
int n = iam_stream->OpenFile(path, 0);
|
||||
delete path;
|
||||
|
||||
if (n == S_OK) {
|
||||
gxMovie *movie = new gxMovie(this, iam_stream);
|
||||
movie_set.insert(movie);
|
||||
return movie;
|
||||
}
|
||||
}
|
||||
}
|
||||
iam_stream->Release();
|
||||
}*/
|
||||
return 0;
|
||||
}
|
||||
|
||||
gxMovie *gxGraphics::verifyMovie(gxMovie *m) {
|
||||
return movie_set.count(m) ? m : 0;
|
||||
}
|
||||
|
||||
void gxGraphics::closeMovie(gxMovie *m) {
|
||||
if (movie_set.erase(m)) delete m;
|
||||
}
|
||||
|
||||
gxCanvas *gxGraphics::createCanvas(int w, int h, int flags) {
|
||||
IDirectDrawSurface7 *s = ddUtil::createSurface(w, h, flags, this);
|
||||
if (!s) return 0;
|
||||
gxCanvas *c = new gxCanvas(this, s, flags);
|
||||
canvas_set.insert(c);
|
||||
c->cls();
|
||||
return c;
|
||||
}
|
||||
|
||||
gxCanvas *gxGraphics::loadCanvas(const string &f, int flags) {
|
||||
IDirectDrawSurface7 *s = ddUtil::loadSurface(f, flags, this);
|
||||
if (!s) return 0;
|
||||
gxCanvas *c = new gxCanvas(this, s, flags);
|
||||
canvas_set.insert(c);
|
||||
return c;
|
||||
}
|
||||
|
||||
gxCanvas *gxGraphics::verifyCanvas(gxCanvas *c) {
|
||||
return canvas_set.count(c) || c == front_canvas || c == back_canvas ? c : 0;
|
||||
}
|
||||
|
||||
void gxGraphics::freeCanvas(gxCanvas *c) {
|
||||
if (canvas_set.erase(c)) delete c;
|
||||
}
|
||||
|
||||
int gxGraphics::getWidth()const {
|
||||
return front_canvas->getWidth();
|
||||
}
|
||||
|
||||
int gxGraphics::getHeight()const {
|
||||
return front_canvas->getHeight();
|
||||
}
|
||||
|
||||
int gxGraphics::getDepth()const {
|
||||
return front_canvas->getDepth();
|
||||
}
|
||||
|
||||
gxFont *gxGraphics::loadFont(const string &f, int height, int flags) {
|
||||
|
||||
int bold = flags & gxFont::FONT_BOLD ? FW_BOLD : FW_REGULAR;
|
||||
int italic = flags & gxFont::FONT_ITALIC ? 1 : 0;
|
||||
int underline = flags & gxFont::FONT_UNDERLINE ? 1 : 0;
|
||||
int strikeout = 0;
|
||||
|
||||
string t;
|
||||
int n = f.find('.');
|
||||
if (n != string::npos) {
|
||||
t = fullfilename(f);
|
||||
if (!font_res.count(t) && AddFontResource(t.c_str())) font_res.insert(t);
|
||||
t = filenamefile(f.substr(0, n));
|
||||
} else {
|
||||
t = f;
|
||||
}
|
||||
|
||||
//save and turn off font smoothing....
|
||||
BOOL smoothing = FALSE;
|
||||
SystemParametersInfo(SPI_GETFONTSMOOTHING, 0, &smoothing, 0);
|
||||
SystemParametersInfo(SPI_SETFONTSMOOTHING, FALSE, 0, 0);
|
||||
|
||||
HFONT hfont = CreateFont(
|
||||
height, 0, 0, 0,
|
||||
bold, italic, underline, strikeout,
|
||||
ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY,
|
||||
DEFAULT_PITCH | FF_DONTCARE, t.c_str());
|
||||
|
||||
if (!hfont) {
|
||||
//restore font smoothing
|
||||
SystemParametersInfo(SPI_SETFONTSMOOTHING, smoothing, 0, 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
HDC hdc = CreateCompatibleDC(0);
|
||||
HFONT pfont = (HFONT)SelectObject(hdc, hfont);
|
||||
|
||||
TEXTMETRIC tm = { 0 };
|
||||
if (!GetTextMetrics(hdc, &tm)) {
|
||||
SelectObject(hdc, pfont);
|
||||
DeleteDC(hdc);
|
||||
DeleteObject(hfont);
|
||||
SystemParametersInfo(SPI_SETFONTSMOOTHING, smoothing, 0, 0);
|
||||
return 0;
|
||||
}
|
||||
height = tm.tmHeight;
|
||||
|
||||
int first = tm.tmFirstChar, last = tm.tmLastChar;
|
||||
int sz = last - first + 1;
|
||||
int *offs = new int[sz];
|
||||
int *widths = new int[sz];
|
||||
int *as = new int[sz];
|
||||
|
||||
//calc size of canvas to hold font.
|
||||
int x = 0, y = 0, max_x = 0;
|
||||
for (int k = 0; k < sz; ++k) {
|
||||
|
||||
char t = k + first;
|
||||
|
||||
SIZE sz;
|
||||
GetTextExtentPoint32(hdc, &t, 1, &sz);
|
||||
int w = sz.cx;
|
||||
|
||||
as[k] = 0;
|
||||
|
||||
ABC abc;
|
||||
if (GetCharABCWidths(hdc, t, t, &abc)) {
|
||||
if (abc.abcA < 0) {
|
||||
as[k] = ceil(-abc.abcA);
|
||||
w += as[k];
|
||||
}
|
||||
if (abc.abcC < 0) w += (int)ceil(-abc.abcC);
|
||||
}
|
||||
|
||||
if (x && x + w > getWidth()) { x = 0; y += height; }
|
||||
offs[k] = (x << 16) | y;
|
||||
widths[k] = w;
|
||||
x += w; if (x > max_x) max_x = x;
|
||||
}
|
||||
SelectObject(hdc, pfont);
|
||||
DeleteDC(hdc);
|
||||
|
||||
int cw = max_x, ch = y + height;
|
||||
|
||||
if (gxCanvas *c = createCanvas(cw, ch, 0)) {
|
||||
IDirectDrawSurface7 *surf = c->getSurface();
|
||||
|
||||
HDC surf_hdc;
|
||||
if (surf->GetDC(&surf_hdc) >= 0) {
|
||||
HFONT pfont = (HFONT)SelectObject(surf_hdc, hfont);
|
||||
|
||||
SetBkColor(surf_hdc, 0x000000);
|
||||
SetTextColor(surf_hdc, 0xffffff);
|
||||
|
||||
for (int k = 0; k < sz; ++k) {
|
||||
int x = (offs[k] >> 16) & 0xffff, y = offs[k] & 0xffff;
|
||||
char t = k + first;
|
||||
RECT rect = { x,y,x + widths[k],y + height };
|
||||
ExtTextOut(surf_hdc, x + as[k], y, ETO_CLIPPED, &rect, &t, 1, 0);
|
||||
}
|
||||
|
||||
SelectObject(surf_hdc, pfont);
|
||||
surf->ReleaseDC(surf_hdc);
|
||||
DeleteObject(hfont);
|
||||
delete[] as;
|
||||
|
||||
c->backup();
|
||||
gxFont *font = new gxFont(this, c, tm.tmMaxCharWidth, height, first, last + 1, tm.tmDefaultChar, offs, widths);
|
||||
font_set.insert(font);
|
||||
|
||||
//restore font smoothing
|
||||
SystemParametersInfo(SPI_SETFONTSMOOTHING, smoothing, 0, 0);
|
||||
return font;
|
||||
} else {
|
||||
}
|
||||
freeCanvas(c);
|
||||
} else {
|
||||
}
|
||||
DeleteObject(hfont);
|
||||
delete[] as;
|
||||
delete[] widths;
|
||||
delete[] offs;
|
||||
|
||||
//restore font smoothing
|
||||
SystemParametersInfo(SPI_SETFONTSMOOTHING, smoothing, 0, 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
gxFont *gxGraphics::verifyFont(gxFont *f) {
|
||||
return font_set.count(f) ? f : 0;
|
||||
}
|
||||
|
||||
void gxGraphics::freeFont(gxFont *f) {
|
||||
if (font_set.erase(f)) delete f;
|
||||
}
|
||||
|
||||
//////////////
|
||||
// 3D STUFF //
|
||||
//////////////
|
||||
|
||||
static int maxDevType;
|
||||
|
||||
static HRESULT CALLBACK enumDevice(char *desc, char *name, D3DDEVICEDESC7 *devDesc, void *context) {
|
||||
gxGraphics *g = (gxGraphics*)context;
|
||||
int t = 0;
|
||||
GUID guid = devDesc->deviceGUID;
|
||||
if (guid == IID_IDirect3DRGBDevice) t = 1;
|
||||
else if (guid == IID_IDirect3DHALDevice) t = 2;
|
||||
else if (guid == IID_IDirect3DTnLHalDevice) t = 3;
|
||||
if (t > maxDevType) {
|
||||
g->dir3dDevDesc = *devDesc;
|
||||
maxDevType = t;
|
||||
}
|
||||
return D3DENUMRET_OK;
|
||||
}
|
||||
|
||||
static HRESULT CALLBACK enumZbuffFormat(LPDDPIXELFORMAT format, void *context) {
|
||||
gxGraphics *g = (gxGraphics*)context;
|
||||
if (format->dwZBufferBitDepth == g->primFmt.dwRGBBitCount) {
|
||||
g->zbuffFmt = *format;
|
||||
return D3DENUMRET_CANCEL;
|
||||
}
|
||||
if (format->dwZBufferBitDepth > g->zbuffFmt.dwZBufferBitDepth) {
|
||||
if (format->dwZBufferBitDepth < g->primFmt.dwRGBBitCount) {
|
||||
g->zbuffFmt = *format;
|
||||
}
|
||||
}
|
||||
return D3DENUMRET_OK;
|
||||
}
|
||||
|
||||
struct TexFmt {
|
||||
DDPIXELFORMAT fmt;
|
||||
int bits, a_bits, rgb_bits;
|
||||
};
|
||||
|
||||
static int cntBits(int mask) {
|
||||
int n = 0;
|
||||
for (int k = 0; k < 32; ++k) {
|
||||
if (mask & (1 << k)) ++n;
|
||||
}
|
||||
return n;
|
||||
}
|
||||
|
||||
static vector<TexFmt> tex_fmts;
|
||||
|
||||
static HRESULT CALLBACK enumTextureFormat(DDPIXELFORMAT *fmt, void *p) {
|
||||
TexFmt t;
|
||||
t.fmt = *fmt;
|
||||
t.bits = fmt->dwRGBBitCount;
|
||||
t.a_bits = (fmt->dwFlags & DDPF_ALPHAPIXELS) ? cntBits(fmt->dwRGBAlphaBitMask) : 0;
|
||||
t.rgb_bits = (fmt->dwFlags & DDPF_RGB) ? cntBits(fmt->dwRBitMask | fmt->dwGBitMask | fmt->dwBBitMask) : 0;
|
||||
|
||||
tex_fmts.push_back(t);
|
||||
|
||||
return D3DENUMRET_OK;
|
||||
}
|
||||
|
||||
static string itobin(int n) {
|
||||
string t;
|
||||
for (int k = 0; k < 32; n <<= 1, ++k) {
|
||||
t += (n & 0x80000000) ? '1' : '0';
|
||||
}
|
||||
return t;
|
||||
}
|
||||
|
||||
static void debugPF(const DDPIXELFORMAT &pf) {
|
||||
string t;
|
||||
t = "Bits:" + itoa(pf.dwRGBBitCount);
|
||||
gx_runtime->debugLog(t.c_str());
|
||||
t = "R Mask:" + itobin(pf.dwRBitMask);
|
||||
gx_runtime->debugLog(t.c_str());
|
||||
t = "G Mask:" + itobin(pf.dwGBitMask);
|
||||
gx_runtime->debugLog(t.c_str());
|
||||
t = "B Mask:" + itobin(pf.dwBBitMask);
|
||||
gx_runtime->debugLog(t.c_str());
|
||||
t = "A Mask:" + itobin(pf.dwRGBAlphaBitMask);
|
||||
gx_runtime->debugLog(t.c_str());
|
||||
}
|
||||
|
||||
static void pickTexFmts(gxGraphics *g, int hi) {
|
||||
//texRGBFmt.
|
||||
{
|
||||
int pick = -1, max = 0, bits;
|
||||
for (int d = g->primFmt.dwRGBBitCount; d <= 32; d += 8) {
|
||||
for (int k = 0; k < tex_fmts.size(); ++k) {
|
||||
const TexFmt &t = tex_fmts[k];
|
||||
if (t.bits > d || !t.rgb_bits || t.rgb_bits < max) continue;
|
||||
if (t.rgb_bits == max && t.bits >= bits) continue;
|
||||
pick = k; max = t.rgb_bits; bits = t.bits;
|
||||
}
|
||||
if (!hi && pick >= 0) break;
|
||||
}
|
||||
if (pick < 0) g->texRGBFmt[hi] = g->primFmt;
|
||||
else g->texRGBFmt[hi] = tex_fmts[pick].fmt;
|
||||
}
|
||||
//texAlphaFmt
|
||||
{
|
||||
int pick = -1, max = 0, bits;
|
||||
for (int d = g->primFmt.dwRGBBitCount; d <= 32; d += 8) {
|
||||
for (int k = 0; k < tex_fmts.size(); ++k) {
|
||||
const TexFmt &t = tex_fmts[k];
|
||||
if (t.bits > d || !t.a_bits || t.a_bits < max) continue;
|
||||
if (t.a_bits == max && t.bits >= bits) continue;
|
||||
pick = k; max = t.a_bits; bits = t.bits;
|
||||
}
|
||||
if (!hi && pick >= 0) break;
|
||||
}
|
||||
if (pick < 0) g->texAlphaFmt[hi] = g->primFmt;
|
||||
else g->texAlphaFmt[hi] = tex_fmts[pick].fmt;
|
||||
}
|
||||
//texRGBAlphaFmt
|
||||
{
|
||||
int pick = -1, a8rgb8 = -1, max = 0, bits;
|
||||
for (int d = g->primFmt.dwRGBBitCount; d <= 32; d += 8) {
|
||||
for (int k = 0; k < tex_fmts.size(); ++k) {
|
||||
const TexFmt &t = tex_fmts[k];
|
||||
if (t.a_bits == 8 && t.bits == 16) { a8rgb8 = k; continue; }
|
||||
if (t.bits > d || !t.a_bits || !t.rgb_bits || t.a_bits < max) continue;
|
||||
if (t.a_bits == max && t.bits >= bits) continue;
|
||||
pick = k; max = t.a_bits; bits = t.bits;
|
||||
}
|
||||
if (!hi && pick >= 0) break;
|
||||
}
|
||||
if (pick < 0) pick = a8rgb8;
|
||||
if (pick < 0) g->texRGBAlphaFmt[hi] = g->primFmt;
|
||||
else g->texRGBAlphaFmt[hi] = tex_fmts[pick].fmt;
|
||||
}
|
||||
//texRGBMaskFmt...
|
||||
{
|
||||
int pick = -1, max = 0, bits;
|
||||
for (int d = g->primFmt.dwRGBBitCount; d <= 32; d += 8) {
|
||||
for (int k = 0; k < tex_fmts.size(); ++k) {
|
||||
const TexFmt &t = tex_fmts[k];
|
||||
if (!t.a_bits || !t.rgb_bits || t.rgb_bits < max) continue;
|
||||
if (t.rgb_bits == max && t.bits >= bits) continue;
|
||||
pick = k; max = t.rgb_bits; bits = t.bits;
|
||||
}
|
||||
if (!hi && pick >= 0) break;
|
||||
}
|
||||
if (pick < 0) g->texRGBMaskFmt[hi] = g->primFmt;
|
||||
else g->texRGBMaskFmt[hi] = tex_fmts[pick].fmt;
|
||||
}
|
||||
}
|
||||
|
||||
gxScene *gxGraphics::createScene(int flags) {
|
||||
if (scene_set.size()) return 0;
|
||||
|
||||
//get d3d
|
||||
if (dirDraw->QueryInterface(IID_IDirect3D7, (void**)&dir3d) >= 0) {
|
||||
//enum devices
|
||||
maxDevType = 0;
|
||||
if (dir3d->EnumDevices(enumDevice, this) >= 0 && maxDevType > 1) {
|
||||
//enum zbuffer formats
|
||||
zbuffFmt.dwZBufferBitDepth = 0;
|
||||
if (dir3d->EnumZBufferFormats(dir3dDevDesc.deviceGUID, enumZbuffFormat, this) >= 0) {
|
||||
//create zbuff for back buffer
|
||||
if (back_canvas->attachZBuffer()) {
|
||||
//create 3d device
|
||||
if (dir3d->CreateDevice(dir3dDevDesc.deviceGUID, back_canvas->getSurface(), &dir3dDev) >= 0) {
|
||||
//enum texture formats
|
||||
tex_fmts.clear();
|
||||
if (dir3dDev->EnumTextureFormats(enumTextureFormat, this) >= 0) {
|
||||
pickTexFmts(this, 0);
|
||||
pickTexFmts(this, 1);
|
||||
tex_fmts.clear();
|
||||
#ifdef BETA
|
||||
gx_runtime->debugLog("Texture RGB format:");
|
||||
debugPF(texRGBFmt);
|
||||
gx_runtime->debugLog("Texture Alpha format:");
|
||||
debugPF(texAlphaFmt);
|
||||
gx_runtime->debugLog("Texture RGB Alpha format:");
|
||||
debugPF(texRGBAlphaFmt);
|
||||
gx_runtime->debugLog("Texture RGB Mask format:");
|
||||
debugPF(texRGBMaskFmt);
|
||||
gx_runtime->debugLog("Texture Primary format:");
|
||||
debugPF(primFmt);
|
||||
string ts = "ZBuffer Bit Depth:" + itoa(zbuffFmt.dwZBufferBitDepth);
|
||||
gx_runtime->debugLog(ts.c_str());
|
||||
#endif
|
||||
gxScene *scene = new gxScene(this, back_canvas);
|
||||
scene_set.insert(scene);
|
||||
|
||||
dummy_mesh = createMesh(8, 12, 0);
|
||||
|
||||
return scene;
|
||||
}
|
||||
dir3dDev->Release();
|
||||
dir3dDev = 0;
|
||||
}
|
||||
back_canvas->releaseZBuffer();
|
||||
}
|
||||
}
|
||||
}
|
||||
dir3d->Release();
|
||||
dir3d = 0;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
gxScene *gxGraphics::verifyScene(gxScene *s) {
|
||||
return scene_set.count(s) ? s : 0;
|
||||
}
|
||||
|
||||
void gxGraphics::freeScene(gxScene *scene) {
|
||||
if (!scene_set.erase(scene)) return;
|
||||
dummy_mesh = 0;
|
||||
while (mesh_set.size()) freeMesh(*mesh_set.begin());
|
||||
back_canvas->releaseZBuffer();
|
||||
if (dir3dDev) { dir3dDev->Release(); dir3dDev = 0; }
|
||||
if (dir3d) { dir3d->Release(); dir3d = 0; }
|
||||
delete scene;
|
||||
}
|
||||
|
||||
gxMesh *gxGraphics::createMesh(int max_verts, int max_tris, int flags) {
|
||||
|
||||
static const int VTXFMT =
|
||||
D3DFVF_XYZ | D3DFVF_NORMAL | D3DFVF_DIFFUSE | D3DFVF_TEX2 |
|
||||
D3DFVF_TEXCOORDSIZE2(0) | D3DFVF_TEXCOORDSIZE2(1);
|
||||
|
||||
int vbflags = 0;
|
||||
|
||||
//XP or less?
|
||||
/*if (runtime->osinfo.dwMajorVersion < 6) {
|
||||
vbflags |= D3DVBCAPS_WRITEONLY;
|
||||
}*/
|
||||
|
||||
D3DVERTEXBUFFERDESC desc = { sizeof(desc),vbflags,VTXFMT,max_verts };
|
||||
|
||||
IDirect3DVertexBuffer7 *buff;
|
||||
if (dir3d->CreateVertexBuffer(&desc, &buff, 0) < 0) return 0;
|
||||
WORD *indices = new WORD[max_tris * 3];
|
||||
gxMesh *mesh = new gxMesh(this, buff, indices, max_verts, max_tris);
|
||||
mesh_set.insert(mesh);
|
||||
return mesh;
|
||||
}
|
||||
|
||||
gxMesh *gxGraphics::verifyMesh(gxMesh *m) {
|
||||
return mesh_set.count(m) ? m : 0;
|
||||
}
|
||||
|
||||
void gxGraphics::freeMesh(gxMesh *mesh) {
|
||||
if (mesh_set.erase(mesh)) delete mesh;
|
||||
}
|
||||
@@ -1,126 +0,0 @@
|
||||
|
||||
#ifndef GXGRAPHICS_H
|
||||
#define GXGRAPHICS_H
|
||||
|
||||
#include <set>
|
||||
#include <string>
|
||||
|
||||
#include "GraphicsRuntime.hpp"
|
||||
#include <windows.h>
|
||||
#include <d3d.h>
|
||||
|
||||
#include "ddutil.hpp"
|
||||
|
||||
#include "gxfont.hpp"
|
||||
#include "gxcanvas.hpp"
|
||||
#include "gxscene.hpp"
|
||||
#include "gxmesh.hpp"
|
||||
#include "gxmovie.hpp"
|
||||
|
||||
class gxRuntime;
|
||||
|
||||
class gxGraphics {
|
||||
private:
|
||||
// Direct3D9
|
||||
//LPDIRECT3D9 d3d9;
|
||||
//LPDIRECT3DDEVICE9 d3d9dev;
|
||||
//IDirect3DDevice9* d3d9Device;
|
||||
|
||||
public:
|
||||
gxGraphics(gxRuntime* runtime);
|
||||
gxGraphics(gxRuntime* runtime, IDirectDraw7 *dirDraw, IDirectDrawSurface7 *front, IDirectDrawSurface7 *back, bool d3d);
|
||||
~gxGraphics();
|
||||
|
||||
IDirectDraw7 *dirDraw;
|
||||
IDirectDraw *ds_dirDraw;
|
||||
|
||||
IDirect3D7 *dir3d;
|
||||
IDirect3DDevice7 *dir3dDev;
|
||||
D3DDEVICEDESC7 dir3dDevDesc;
|
||||
DDPIXELFORMAT primFmt,zbuffFmt;
|
||||
|
||||
DDPIXELFORMAT texRGBFmt[2], texAlphaFmt[2], texRGBAlphaFmt[2], texRGBMaskFmt[2];
|
||||
|
||||
void backup();
|
||||
bool restore();
|
||||
|
||||
gxRuntime *runtime;
|
||||
|
||||
private:
|
||||
|
||||
gxCanvas *front_canvas, *back_canvas;
|
||||
gxFont *def_font;
|
||||
bool gfx_lost;
|
||||
gxMesh *dummy_mesh;
|
||||
|
||||
DDSURFACEDESC2 initDesc(int w, int h, int flags);
|
||||
IDirectDrawSurface7 *createSurface(int width, int height, int flags);
|
||||
IDirectDrawSurface7 *loadSurface(const std::string &f, int flags);
|
||||
|
||||
std::set<gxFont*> font_set;
|
||||
std::set<gxCanvas*> canvas_set;
|
||||
std::set<gxMesh*> mesh_set;
|
||||
std::set<gxScene*> scene_set;
|
||||
std::set<gxMovie*> movie_set;
|
||||
std::set<std::string> font_res;
|
||||
|
||||
DDGAMMARAMP _gammaRamp;
|
||||
IDirectDrawGammaControl *_gamma;
|
||||
|
||||
/***** GX INTERFACE *****/
|
||||
public:
|
||||
enum {
|
||||
GRAPHICS_WINDOWED = 1, //windowed mode
|
||||
GRAPHICS_SCALED = 2, //scaled window
|
||||
GRAPHICS_3D = 4, //3d mode! Hurrah!
|
||||
GRAPHICS_AUTOSUSPEND = 8 //suspend graphics when app suspended
|
||||
};
|
||||
|
||||
//MANIPULATORS
|
||||
void vwait();
|
||||
void flip(bool vwait);
|
||||
|
||||
//SPECIAL!
|
||||
void copy(gxCanvas *dest, int dx, int dy, int dw, int dh, gxCanvas *src, int sx, int sy, int sw, int sh);
|
||||
|
||||
//NEW! Gamma control!
|
||||
void setGamma(int r, int g, int b, float dr, float dg, float db);
|
||||
void getGamma(int r, int g, int b, float *dr, float *dg, float *db);
|
||||
void updateGamma(bool calibrate);
|
||||
|
||||
//ACCESSORS
|
||||
int getWidth()const;
|
||||
int getHeight()const;
|
||||
int getDepth()const;
|
||||
int getScanLine()const;
|
||||
int getAvailVidmem()const;
|
||||
int getTotalVidmem()const;
|
||||
|
||||
gxCanvas *getFrontCanvas()const;
|
||||
gxCanvas *getBackCanvas()const;
|
||||
gxFont *getDefaultFont()const;
|
||||
|
||||
//OBJECTS
|
||||
gxCanvas *createCanvas(int width, int height, int flags);
|
||||
gxCanvas *loadCanvas(const std::string &file, int flags);
|
||||
gxCanvas *verifyCanvas(gxCanvas *canvas);
|
||||
void freeCanvas(gxCanvas *canvas);
|
||||
|
||||
gxMovie *openMovie(const std::string &file, int flags);
|
||||
gxMovie *verifyMovie(gxMovie *movie);
|
||||
void closeMovie(gxMovie *movie);
|
||||
|
||||
gxFont *loadFont(const std::string &font, int height, int flags);
|
||||
gxFont *verifyFont(gxFont *font);
|
||||
void freeFont(gxFont *font);
|
||||
|
||||
gxScene *createScene(int flags);
|
||||
gxScene *verifyScene(gxScene *scene);
|
||||
void freeScene(gxScene *scene);
|
||||
|
||||
gxMesh *createMesh(int max_verts, int max_tris, int flags);
|
||||
gxMesh *verifyMesh(gxMesh *mesh);
|
||||
void freeMesh(gxMesh *mesh);
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -1,335 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "std.hpp"
|
||||
#include "gxinput.hpp"
|
||||
#include "gxruntime.hpp"
|
||||
|
||||
static const int QUE_SIZE = 32;
|
||||
|
||||
class Device : public gxDevice {
|
||||
public:
|
||||
bool acquired;
|
||||
gxInput *input;
|
||||
LPDIRECTINPUTDEVICE8 device;
|
||||
|
||||
Device(gxInput *i, LPDIRECTINPUTDEVICE8 d) :input(i), acquired(false), device(d) {
|
||||
}
|
||||
virtual ~Device() {
|
||||
device->Release();
|
||||
//device->Release();
|
||||
}
|
||||
bool acquire() {
|
||||
return device->Acquire() >= 0;
|
||||
//return acquired=device->Acquire()>=0;
|
||||
}
|
||||
void unacquire() {
|
||||
device->Unacquire();
|
||||
//device->Unacquire();
|
||||
acquired = false;
|
||||
}
|
||||
};
|
||||
|
||||
class Keyboard : public Device {
|
||||
public:
|
||||
Keyboard(gxInput *i, LPDIRECTINPUTDEVICE8 d) :Device(i, d) {
|
||||
}
|
||||
void update() {
|
||||
if (!acquired) {
|
||||
input->runtime->idle();
|
||||
return;
|
||||
}
|
||||
int k, cnt = 32;
|
||||
DIDEVICEOBJECTDATA data[32], *curr;
|
||||
if (device->GetDeviceData(sizeof(DIDEVICEOBJECTDATA), data, (DWORD*)&cnt, 0) < 0) return;
|
||||
curr = data;
|
||||
for (k = 0; k < cnt; ++curr, ++k) {
|
||||
int n = curr->dwOfs; if (!n || n > 255) continue;
|
||||
if (curr->dwData & 0x80) downEvent(n);
|
||||
else upEvent(n);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
class Mouse : public Device {
|
||||
public:
|
||||
Mouse(gxInput *i, LPDIRECTINPUTDEVICE8 d) :Device(i, d) {
|
||||
}
|
||||
void update() {
|
||||
if (!acquired) {
|
||||
input->runtime->idle();
|
||||
return;
|
||||
}
|
||||
DIMOUSESTATE state;
|
||||
if (device->GetDeviceState(sizeof(state), &state) < 0) return;
|
||||
if (gxGraphics *g = input->runtime->graphics) {
|
||||
int mx = axis_states[0] + state.lX;
|
||||
int my = axis_states[1] + state.lY;
|
||||
if (mx < 0) mx = 0;
|
||||
else if (mx >= g->getWidth()) mx = g->getWidth() - 1;
|
||||
if (my < 0) my = 0;
|
||||
else if (my >= g->getHeight()) my = g->getHeight() - 1;
|
||||
axis_states[0] = mx;
|
||||
axis_states[1] = my;
|
||||
axis_states[2] += state.lZ;
|
||||
}
|
||||
for (int k = 0; k < 3; ++k) {
|
||||
setDownState(k + 1, state.rgbButtons[k] & 0x80 ? true : false);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
class Joystick : public Device {
|
||||
public:
|
||||
int type, poll_time;
|
||||
int mins[12], maxs[12];
|
||||
Joystick(gxInput *i, LPDIRECTINPUTDEVICE8 d, int t) :Device(i, d), type(t), poll_time(0) {
|
||||
for (int k = 0; k < 12; ++k) {
|
||||
//initialize joystick axis ranges (d'oh!)
|
||||
DIPROPRANGE range;
|
||||
range.diph.dwSize = sizeof(DIPROPRANGE);
|
||||
range.diph.dwHeaderSize = sizeof(DIPROPHEADER);
|
||||
range.diph.dwObj = k * 4 + 12;
|
||||
range.diph.dwHow = DIPH_BYOFFSET;
|
||||
if (d->GetProperty(DIPROP_RANGE, &range.diph) < 0) {
|
||||
mins[k] = 0;
|
||||
maxs[k] = 65535;
|
||||
continue;
|
||||
}
|
||||
mins[k] = range.lMin;
|
||||
maxs[k] = range.lMax - range.lMin;
|
||||
}
|
||||
}
|
||||
void update() {
|
||||
unsigned tm = timeGetTime();
|
||||
if (tm - poll_time < 3) return;
|
||||
if (device->Poll() < 0) {
|
||||
acquired = false;
|
||||
input->runtime->idle();
|
||||
acquire(); if (device->Poll() < 0) return;
|
||||
}
|
||||
poll_time = tm;
|
||||
DIJOYSTATE state;
|
||||
if (device->GetDeviceState(sizeof(state), &state) < 0) return;
|
||||
axis_states[0] = (state.lX - mins[0]) / (float)maxs[0] * 2 - 1;
|
||||
axis_states[1] = (state.lY - mins[1]) / (float)maxs[1] * 2 - 1;
|
||||
axis_states[2] = (state.lZ - mins[2]) / (float)maxs[2] * 2 - 1;
|
||||
axis_states[3] = (state.rglSlider[0] - mins[6]) / (float)maxs[6] * 2 - 1;
|
||||
axis_states[4] = (state.rglSlider[1] - mins[7]) / (float)maxs[7] * 2 - 1;
|
||||
axis_states[5] = (state.lRx - mins[3]) / (float)maxs[3] * 2 - 1;
|
||||
axis_states[6] = (state.lRy - mins[4]) / (float)maxs[4] * 2 - 1;
|
||||
axis_states[7] = (state.lRz - mins[5]) / (float)maxs[5] * 2 - 1;
|
||||
if ((state.rgdwPOV[0] & 0xffff) == 0xffff) axis_states[8] = -1;
|
||||
else axis_states[8] = floor(state.rgdwPOV[0] / 100.0f + .5f);
|
||||
|
||||
for (int k = 0; k < 31; ++k) {
|
||||
setDownState(k + 1, state.rgbButtons[k] & 0x80 ? true : false);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
static Keyboard *keyboard;
|
||||
static Mouse *mouse;
|
||||
static vector<Joystick*> joysticks;
|
||||
|
||||
static Keyboard *createKeyboard(gxInput *input) {
|
||||
LPDIRECTINPUTDEVICE8 dev;
|
||||
if (input->dirInput->CreateDevice(GUID_SysKeyboard, &dev, NULL) >= 0) {
|
||||
if (dev->SetCooperativeLevel(input->runtime->hwnd, DISCL_FOREGROUND | DISCL_EXCLUSIVE) >= 0) {
|
||||
|
||||
if (dev->SetDataFormat(&c_dfDIKeyboard) >= 0) {
|
||||
DIPROPDWORD dword;
|
||||
memset(&dword, 0, sizeof(dword));
|
||||
dword.diph.dwSize = sizeof(DIPROPDWORD);
|
||||
dword.diph.dwHeaderSize = sizeof(DIPROPHEADER);
|
||||
dword.diph.dwObj = 0;
|
||||
dword.diph.dwHow = DIPH_DEVICE;
|
||||
dword.dwData = 32;
|
||||
if (dev->SetProperty(DIPROP_BUFFERSIZE, &dword.diph) >= 0) {
|
||||
return new Keyboard(input, dev);
|
||||
} else {
|
||||
// input->runtime->debugInfo( "keyboard: SetProperty failed" );
|
||||
}
|
||||
} else {
|
||||
// input->runtime->debugInfo( "keyboard: SetDataFormat failed" );
|
||||
}
|
||||
return new Keyboard(input, dev);
|
||||
|
||||
} else {
|
||||
input->runtime->debugInfo("keyboard: SetCooperativeLevel failed");
|
||||
}
|
||||
dev->Release();
|
||||
} else {
|
||||
input->runtime->debugInfo("keyboard: CreateDeviceEx failed");
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static Mouse *createMouse(gxInput *input) {
|
||||
LPDIRECTINPUTDEVICE8 dev;
|
||||
if (input->dirInput->CreateDevice(GUID_SysMouse, &dev, 0) >= 0) {
|
||||
if (dev->SetCooperativeLevel(input->runtime->hwnd, DISCL_FOREGROUND | DISCL_EXCLUSIVE) >= 0) {
|
||||
|
||||
if (dev->SetDataFormat(&c_dfDIMouse) >= 0) {
|
||||
return new Mouse(input, dev);
|
||||
} else {
|
||||
// input->runtime->debugInfo( "mouse: SetDataFormat failed" );
|
||||
}
|
||||
return new Mouse(input, dev);
|
||||
|
||||
} else {
|
||||
input->runtime->debugInfo("mouse: SetCooperativeLevel failed");
|
||||
}
|
||||
dev->Release();
|
||||
} else {
|
||||
input->runtime->debugInfo("mouse: CreateDeviceEx failed");
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static Joystick *createJoystick(gxInput *input, LPCDIDEVICEINSTANCE devinst) {
|
||||
LPDIRECTINPUTDEVICE8 dev;
|
||||
if (input->dirInput->CreateDevice(devinst->guidInstance, &dev, 0) >= 0) {
|
||||
if (dev->SetCooperativeLevel(input->runtime->hwnd, DISCL_FOREGROUND | DISCL_EXCLUSIVE) >= 0) {
|
||||
if (dev->SetDataFormat(&c_dfDIJoystick) >= 0) {
|
||||
int t = ((devinst->dwDevType >> 8) & 0xff) == DI8DEVCLASS_GAMECTRL ? 1 : 2;
|
||||
return new Joystick(input, dev, t);
|
||||
}
|
||||
}
|
||||
dev->Release();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static BOOL CALLBACK enumJoystick(LPCDIDEVICEINSTANCE devinst, LPVOID pvRef) {
|
||||
|
||||
if ((devinst->dwDevType & 0xff) != DI8DEVCLASS_GAMECTRL) return DIENUM_CONTINUE;
|
||||
|
||||
if (Joystick *joy = createJoystick((gxInput*)pvRef, devinst)) {
|
||||
joysticks.push_back(joy);
|
||||
}
|
||||
return DIENUM_CONTINUE;
|
||||
}
|
||||
|
||||
gxInput::gxInput(gxRuntime *rt, LPDIRECTINPUT8 di) : runtime(rt), dirInput(di) {
|
||||
keyboard = createKeyboard(this);
|
||||
mouse = createMouse(this);
|
||||
joysticks.clear();
|
||||
dirInput->EnumDevices(DI8DEVCLASS_GAMECTRL, enumJoystick, this, DIEDFL_ATTACHEDONLY);
|
||||
}
|
||||
|
||||
gxInput::~gxInput() {
|
||||
for (int k = 0; k < joysticks.size(); ++k) delete joysticks[k];
|
||||
joysticks.clear();
|
||||
delete mouse;
|
||||
delete keyboard;
|
||||
|
||||
dirInput->Release();
|
||||
}
|
||||
|
||||
void gxInput::wm_keydown(int key) {
|
||||
if (keyboard) keyboard->downEvent(key);
|
||||
}
|
||||
|
||||
void gxInput::wm_keyup(int key) {
|
||||
if (keyboard) keyboard->upEvent(key);
|
||||
}
|
||||
|
||||
void gxInput::wm_mousedown(int key) {
|
||||
if (mouse) mouse->downEvent(key);
|
||||
}
|
||||
|
||||
void gxInput::wm_mouseup(int key) {
|
||||
if (mouse) mouse->upEvent(key);
|
||||
}
|
||||
|
||||
void gxInput::wm_mousemove(int x, int y) {
|
||||
if (mouse) {
|
||||
mouse->axis_states[0] = x;
|
||||
mouse->axis_states[1] = y;
|
||||
}
|
||||
}
|
||||
|
||||
void gxInput::wm_mousewheel(int dz) {
|
||||
if (mouse) mouse->axis_states[2] += dz;
|
||||
}
|
||||
|
||||
void gxInput::reset() {
|
||||
if (mouse) mouse->reset();
|
||||
if (keyboard) keyboard->reset();
|
||||
for (int k = 0; k < joysticks.size(); ++k) joysticks[k]->reset();
|
||||
}
|
||||
|
||||
bool gxInput::acquire() {
|
||||
bool m_ok = true, k_ok = true;
|
||||
if (mouse) m_ok = mouse->acquire();
|
||||
if (keyboard) k_ok = keyboard->acquire();
|
||||
if (m_ok && k_ok) return true;
|
||||
if (k_ok) keyboard->unacquire();
|
||||
if (m_ok) mouse->unacquire();
|
||||
return false;
|
||||
}
|
||||
|
||||
void gxInput::unacquire() {
|
||||
if (keyboard) keyboard->unacquire();
|
||||
if (mouse) mouse->unacquire();
|
||||
}
|
||||
|
||||
void gxInput::moveMouse(int x, int y) {
|
||||
if (!mouse) return;
|
||||
mouse->axis_states[0] = x;
|
||||
mouse->axis_states[1] = y;
|
||||
runtime->moveMouse(x, y);
|
||||
}
|
||||
|
||||
gxDevice *gxInput::getMouse()const {
|
||||
return mouse;
|
||||
}
|
||||
|
||||
gxDevice *gxInput::getKeyboard()const {
|
||||
return keyboard;
|
||||
}
|
||||
|
||||
gxDevice *gxInput::getJoystick(int n)const {
|
||||
return n >= 0 && n < joysticks.size() ? joysticks[n] : 0;
|
||||
}
|
||||
|
||||
int gxInput::getJoystickType(int n)const {
|
||||
return n >= 0 && n < joysticks.size() ? joysticks[n]->type : 0;
|
||||
}
|
||||
|
||||
int gxInput::numJoysticks()const {
|
||||
return joysticks.size();
|
||||
}
|
||||
|
||||
int gxInput::toAscii(int scan)const {
|
||||
switch (scan) {
|
||||
case DIK_INSERT:return ASC_INSERT;
|
||||
case DIK_DELETE:return ASC_DELETE;
|
||||
case DIK_HOME:return ASC_HOME;
|
||||
case DIK_END:return ASC_END;
|
||||
case DIK_PGUP:return ASC_PAGEUP;
|
||||
case DIK_PGDN:return ASC_PAGEDOWN;
|
||||
case DIK_UP:return ASC_UP;
|
||||
case DIK_DOWN:return ASC_DOWN;
|
||||
case DIK_LEFT:return ASC_LEFT;
|
||||
case DIK_RIGHT:return ASC_RIGHT;
|
||||
}
|
||||
scan &= 0x7f;
|
||||
int virt = MapVirtualKey(scan, 1);
|
||||
if (!virt) return 0;
|
||||
|
||||
static unsigned char mat[256];
|
||||
mat[VK_LSHIFT] = keyboard->keyDown(DIK_LSHIFT) ? 0x80 : 0;
|
||||
mat[VK_RSHIFT] = keyboard->keyDown(DIK_RSHIFT) ? 0x80 : 0;
|
||||
mat[VK_SHIFT] = mat[VK_LSHIFT] | mat[VK_RSHIFT];
|
||||
mat[VK_LCONTROL] = keyboard->keyDown(DIK_LCONTROL) ? 0x80 : 0;
|
||||
mat[VK_RCONTROL] = keyboard->keyDown(DIK_RCONTROL) ? 0x80 : 0;
|
||||
mat[VK_CONTROL] = mat[VK_LCONTROL] | mat[VK_RCONTROL];
|
||||
mat[VK_LMENU] = keyboard->keyDown(DIK_LMENU) ? 0x80 : 0;
|
||||
mat[VK_RMENU] = keyboard->keyDown(DIK_RMENU) ? 0x80 : 0;
|
||||
mat[VK_MENU] = mat[VK_LMENU] | mat[VK_RMENU];
|
||||
|
||||
WORD ch;
|
||||
if (ToAscii(virt, scan, mat, &ch, 0) != 1) return 0;
|
||||
return ch & 255;
|
||||
}
|
||||
@@ -1,46 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "std.hpp"
|
||||
#include "gxdevice.hpp"
|
||||
#include "GraphicsRuntime.hpp"
|
||||
|
||||
class gxRuntime;
|
||||
|
||||
class gxInput{
|
||||
public:
|
||||
gxRuntime *runtime;
|
||||
LPDIRECTINPUT8 dirInput;
|
||||
|
||||
gxInput( gxRuntime *runtime, LPDIRECTINPUT8 di );
|
||||
~gxInput();
|
||||
|
||||
void reset();
|
||||
bool acquire();
|
||||
void unacquire();
|
||||
|
||||
void wm_keydown( int key );
|
||||
void wm_keyup( int key );
|
||||
void wm_mousedown( int key );
|
||||
void wm_mouseup( int key );
|
||||
void wm_mousemove( int x,int y );
|
||||
void wm_mousewheel( int dz );
|
||||
|
||||
private:
|
||||
|
||||
/***** GX INTERFACE *****/
|
||||
public:
|
||||
enum{
|
||||
ASC_HOME=1,ASC_END=2,ASC_INSERT=3,ASC_DELETE=4,
|
||||
ASC_PAGEUP=5,ASC_PAGEDOWN=6,
|
||||
ASC_UP=28,ASC_DOWN=29,ASC_RIGHT=30,ASC_LEFT=31
|
||||
};
|
||||
|
||||
void moveMouse( int x,int y );
|
||||
|
||||
gxDevice *getMouse()const;
|
||||
gxDevice *getKeyboard()const;
|
||||
gxDevice *getJoystick( int port )const;
|
||||
int getJoystickType( int port )const;
|
||||
int numJoysticks()const;
|
||||
int toAscii( int key )const;
|
||||
};
|
||||
@@ -1,60 +0,0 @@
|
||||
|
||||
#include "std.hpp"
|
||||
#include "gxlight.hpp"
|
||||
#include "gxscene.hpp"
|
||||
#include "gxgraphics.hpp"
|
||||
|
||||
const float PI=3.14159265359f; //180 degrees
|
||||
const float TWOPI=PI*2.0f; //360 degrees
|
||||
const float HALFPI=PI*.5f; //90 degrees
|
||||
|
||||
gxLight::gxLight( gxScene *s,int type ):
|
||||
scene(s){
|
||||
|
||||
memset(&d3d_light,0,sizeof(d3d_light));
|
||||
|
||||
switch( type ){
|
||||
case LIGHT_POINT:
|
||||
d3d_light.dltType=D3DLIGHT_POINT;
|
||||
break;
|
||||
case LIGHT_SPOT:
|
||||
d3d_light.dltType=D3DLIGHT_SPOT;
|
||||
break;
|
||||
default:
|
||||
d3d_light.dltType=D3DLIGHT_DIRECTIONAL;
|
||||
}
|
||||
|
||||
d3d_light.dcvDiffuse.a=1;
|
||||
d3d_light.dcvDiffuse.r=d3d_light.dcvDiffuse.g=d3d_light.dcvDiffuse.b=1;
|
||||
d3d_light.dcvSpecular.r=d3d_light.dcvSpecular.g=d3d_light.dcvSpecular.b=1;
|
||||
d3d_light.dvRange=D3DLIGHT_RANGE_MAX;
|
||||
d3d_light.dvTheta=0;
|
||||
d3d_light.dvPhi=HALFPI;
|
||||
d3d_light.dvFalloff=1;
|
||||
d3d_light.dvDirection.z=1;
|
||||
setRange( 1000 );
|
||||
}
|
||||
|
||||
gxLight::~gxLight(){
|
||||
}
|
||||
|
||||
void gxLight::setRange( float r ){
|
||||
d3d_light.dvAttenuation1=1.0f/r;
|
||||
}
|
||||
|
||||
void gxLight::setPosition( const float pos[3] ){
|
||||
d3d_light.dvPosition.x=pos[0];
|
||||
d3d_light.dvPosition.y=pos[1];
|
||||
d3d_light.dvPosition.z=pos[2];
|
||||
}
|
||||
|
||||
void gxLight::setDirection( const float dir[3] ){
|
||||
d3d_light.dvDirection.x=dir[0];
|
||||
d3d_light.dvDirection.y=dir[1];
|
||||
d3d_light.dvDirection.z=dir[2];
|
||||
}
|
||||
|
||||
void gxLight::setConeAngles( float inner,float outer ){
|
||||
d3d_light.dvTheta=inner;
|
||||
d3d_light.dvPhi=outer;
|
||||
}
|
||||
@@ -1,33 +0,0 @@
|
||||
|
||||
#include "GraphicsRuntime.hpp"
|
||||
|
||||
#ifndef GXLIGHT_H
|
||||
#define GXLIGHT_H
|
||||
|
||||
class gxScene;
|
||||
|
||||
class gxLight{
|
||||
public:
|
||||
gxLight( gxScene *scene,int type );
|
||||
~gxLight();
|
||||
|
||||
D3DLIGHT7 d3d_light;
|
||||
|
||||
private:
|
||||
gxScene *scene;
|
||||
|
||||
/***** GX INTERFACE *****/
|
||||
public:
|
||||
enum{
|
||||
LIGHT_DISTANT=1,LIGHT_POINT=2,LIGHT_SPOT=3
|
||||
};
|
||||
void setRange( float range );
|
||||
void setColor( const float rgb[3] ){ memcpy( &d3d_light.dcvDiffuse,rgb,12 ); }
|
||||
void setPosition( const float pos[3] );
|
||||
void setDirection( const float dir[3] );
|
||||
void setConeAngles( float inner,float outer );
|
||||
|
||||
void getColor( float rgb[3] ){ memcpy( rgb,&d3d_light.dcvDiffuse,12 ); }
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -1,107 +0,0 @@
|
||||
|
||||
#include "std.hpp"
|
||||
#include "gxmesh.hpp"
|
||||
#include "gxgraphics.hpp"
|
||||
|
||||
#include "gxruntime.hpp"
|
||||
|
||||
extern gxRuntime *gx_runtime;
|
||||
|
||||
gxMesh::gxMesh( gxGraphics *g,IDirect3DVertexBuffer7 *vs,WORD *is,int max_vs,int max_ts ):
|
||||
graphics(g),locked_verts(0),vertex_buff(vs),tri_indices(is),max_verts(max_vs),max_tris(max_ts),mesh_dirty(false){
|
||||
}
|
||||
|
||||
gxMesh::~gxMesh(){
|
||||
unlock();
|
||||
|
||||
vertex_buff->Release();
|
||||
|
||||
delete[] tri_indices;
|
||||
}
|
||||
|
||||
bool gxMesh::lock( bool all ){
|
||||
if( locked_verts ) return true;
|
||||
|
||||
//V1.104
|
||||
//int flags=all ? DDLOCK_DISCARDCONTENTS : 0;
|
||||
|
||||
//V1.105
|
||||
//int flags=all ? DDLOCK_DISCARDCONTENTS : DDLOCK_NOOVERWRITE;
|
||||
|
||||
//V1.104/1.105
|
||||
//if( vertex_buff->Lock( DDLOCK_WRITEONLY|DDLOCK_WAIT|flags,(void**)&locked_verts,0 )>=0 ){
|
||||
|
||||
//V1.1.06...
|
||||
int flags=DDLOCK_WAIT|DDLOCK_WRITEONLY;
|
||||
|
||||
//XP or less?
|
||||
/*if( graphics->runtime->osinfo.dwMajorVersion<6 ){
|
||||
flags|=(all ? DDLOCK_DISCARDCONTENTS : DDLOCK_NOOVERWRITE);
|
||||
}*/
|
||||
|
||||
if( vertex_buff->Lock( flags,(void**)&locked_verts,0 )>=0 ){
|
||||
mesh_dirty=false;
|
||||
return true;
|
||||
}
|
||||
|
||||
static dxVertex *err_verts=new dxVertex[32768];
|
||||
|
||||
locked_verts=err_verts;
|
||||
return true;
|
||||
}
|
||||
|
||||
void gxMesh::unlock(){
|
||||
if( locked_verts ){
|
||||
vertex_buff->Unlock();
|
||||
locked_verts=0;
|
||||
}
|
||||
}
|
||||
|
||||
void gxMesh::backup(){
|
||||
unlock();
|
||||
}
|
||||
|
||||
void gxMesh::restore(){
|
||||
mesh_dirty=true;
|
||||
}
|
||||
|
||||
/*
|
||||
void gxMesh::backup(){
|
||||
|
||||
unlock();
|
||||
|
||||
if( backup_verts ){
|
||||
delete[] backup_verts;
|
||||
backup_verts=0;
|
||||
}
|
||||
|
||||
dxVertex *verts;
|
||||
if( vertex_buff->Lock( DDLOCK_READONLY|DDLOCK_WAIT,(void**)&verts,0 )>=0 ){
|
||||
backup_verts=new dxVertex[ max_verts ];
|
||||
memcpy( backup_verts,verts,sizeof(dxVertex)*max_verts );
|
||||
vertex_buff->Unlock();
|
||||
}
|
||||
}
|
||||
|
||||
void gxMesh::restore(){
|
||||
|
||||
if( !backup_verts ) return;
|
||||
|
||||
dxVertex *verts;
|
||||
if( vertex_buff->Lock( DDLOCK_WRITEONLY|DDLOCK_WAIT,(void**)&verts,0 )>=0 ){
|
||||
memcpy( verts,backup_verts,sizeof(dxVertex)*max_verts );
|
||||
vertex_buff->Unlock();
|
||||
}
|
||||
|
||||
delete[] backup_verts;
|
||||
backup_verts=0;
|
||||
}
|
||||
*/
|
||||
|
||||
void gxMesh::render( int first_vert,int vert_cnt,int first_tri,int tri_cnt ){
|
||||
unlock();
|
||||
graphics->dir3dDev->DrawIndexedPrimitiveVB(
|
||||
D3DPT_TRIANGLELIST,
|
||||
vertex_buff,first_vert,vert_cnt,
|
||||
tri_indices+first_tri*3,tri_cnt*3,0 );
|
||||
}
|
||||
@@ -1,73 +0,0 @@
|
||||
|
||||
#ifndef GXMESH_H
|
||||
#define GXMESH_H
|
||||
|
||||
#include <windows.h>
|
||||
#include "GraphicsRuntime.hpp"
|
||||
#include <d3d.h>
|
||||
|
||||
class gxGraphics;
|
||||
|
||||
class gxMesh{
|
||||
public:
|
||||
|
||||
gxMesh( gxGraphics *graphics,IDirect3DVertexBuffer7 *verts,WORD *indicies,int max_verts,int max_tris );
|
||||
~gxMesh();
|
||||
|
||||
int maxVerts()const{ return max_verts; }
|
||||
int maxTris()const{ return max_tris; }
|
||||
|
||||
bool dirty()const{ return mesh_dirty; }
|
||||
|
||||
void render( int first_vert,int vert_cnt,int first_tri,int tri_cnt );
|
||||
|
||||
void backup();
|
||||
void restore();
|
||||
|
||||
private:
|
||||
struct dxVertex{
|
||||
float coords[3];
|
||||
float normal[3];
|
||||
unsigned argb;
|
||||
float tex_coords[4];
|
||||
};
|
||||
|
||||
gxGraphics *graphics;
|
||||
IDirect3DVertexBuffer7 *vertex_buff;
|
||||
WORD *tri_indices;
|
||||
|
||||
int max_verts,max_tris;
|
||||
bool mesh_dirty;
|
||||
dxVertex *locked_verts;
|
||||
|
||||
/***** GX INTERFACE *****/
|
||||
public:
|
||||
bool lock( bool all );
|
||||
void unlock();
|
||||
|
||||
//VERY NAUGHTY!!!!!
|
||||
void setVertex( int n,const void *v ){
|
||||
memcpy( locked_verts+n,v,sizeof(dxVertex) );
|
||||
}
|
||||
void setVertex( int n,const float coords[3],const float normal[3],const float tex_coords[2][2] ){
|
||||
dxVertex *t=locked_verts+n;
|
||||
memcpy( t->coords,coords,12 );
|
||||
memcpy( t->normal,normal,12 );
|
||||
t->argb=0xffffffff;
|
||||
memcpy( t->tex_coords,tex_coords,16 );
|
||||
}
|
||||
void setVertex( int n,const float coords[3],const float normal[3],unsigned argb,const float tex_coords[2][2] ){
|
||||
dxVertex *t=locked_verts+n;
|
||||
memcpy( t->coords,coords,12 );
|
||||
memcpy( t->normal,normal,12 );
|
||||
t->argb=argb;
|
||||
memcpy( t->tex_coords,tex_coords,16 );
|
||||
}
|
||||
void setTriangle( int n,int v0,int v1,int v2 ){
|
||||
tri_indices[n*3]=v0;
|
||||
tri_indices[n*3+1]=v1;
|
||||
tri_indices[n*3+2]=v2;
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -1,48 +0,0 @@
|
||||
|
||||
#include "std.hpp"
|
||||
#include "gxmovie.hpp"
|
||||
#include "gxgraphics.hpp"
|
||||
|
||||
gxMovie::gxMovie(gxGraphics *g, IMultiMediaStream *mm)
|
||||
:gfx(g), mm_stream(mm), playing(true) {
|
||||
|
||||
////mm_stream->GetMediaStream( MSPID_PrimaryVideo,&vid_stream );
|
||||
////vid_stream->QueryInterface(IID_IDirectDrawMediaStream, (void**)&dd_stream);
|
||||
|
||||
//DDSURFACEDESC desc = { sizeof(desc) };
|
||||
//dd_stream->GetFormat(&desc, 0, 0, 0);
|
||||
|
||||
//canvas = gfx->createCanvas(desc.dwWidth, desc.dwHeight, 0); //gxCanvas::CANVAS_NONDISPLAY );
|
||||
//canvas->getSurface()->QueryInterface(IID_IDirectDrawSurface, (void**)&dd_surf);
|
||||
|
||||
//src_rect.left = src_rect.top = 0;
|
||||
//src_rect.right = desc.dwWidth; src_rect.bottom = desc.dwHeight;
|
||||
|
||||
//dd_stream->CreateSample(dd_surf, &src_rect, 0, &dd_sample);
|
||||
|
||||
//mm_stream->SetState(STREAMSTATE_RUN);
|
||||
}
|
||||
|
||||
gxMovie::~gxMovie() {
|
||||
/*mm_stream->SetState(STREAMSTATE_STOP);
|
||||
|
||||
dd_sample->Release();
|
||||
dd_surf->Release();
|
||||
dd_stream->Release();
|
||||
vid_stream->Release();
|
||||
mm_stream->Release();
|
||||
|
||||
gfx->freeCanvas(canvas);*/
|
||||
}
|
||||
|
||||
bool gxMovie::draw(gxCanvas *dest, int x, int y, int w, int h) {
|
||||
if (!playing) return false;
|
||||
/*if (!dd_sample->Update(0, 0, 0, 0)) {
|
||||
RECT dest_rect = { x,y,x + w,y + h };
|
||||
dest->getSurface()->Blt(&dest_rect, canvas->getSurface(), &src_rect, DDBLT_WAIT, 0);
|
||||
dest->damage(dest_rect);
|
||||
} else {
|
||||
playing = false;
|
||||
}*/
|
||||
return playing;
|
||||
}
|
||||
@@ -1,40 +0,0 @@
|
||||
|
||||
#ifndef GXMOVIE_H
|
||||
#define GXMOVIE_H
|
||||
|
||||
#include "mmstream.h" // multimedia stream interfaces
|
||||
#include "amstream.h" // DirectShow multimedia stream interfaces
|
||||
#include "ddstream.h" // DirectDraw multimedia stream interfaces
|
||||
|
||||
#include "gxcanvas.hpp"
|
||||
|
||||
class gxGraphics;
|
||||
|
||||
class gxMovie{
|
||||
|
||||
public:
|
||||
gxMovie( gxGraphics *gfx,IMultiMediaStream *mm_stream );
|
||||
~gxMovie();
|
||||
|
||||
private:
|
||||
bool playing;
|
||||
RECT src_rect;
|
||||
gxGraphics *gfx;
|
||||
gxCanvas *canvas;
|
||||
IDirectDrawSurface *dd_surf;
|
||||
IMediaStream *vid_stream;
|
||||
IDirectDrawMediaStream *dd_stream;
|
||||
IDirectDrawStreamSample *dd_sample;
|
||||
IMultiMediaStream *mm_stream;
|
||||
|
||||
/***** GX INTERFACE *****/
|
||||
public:
|
||||
|
||||
bool draw( gxCanvas *dest,int x,int y,int w,int h );
|
||||
|
||||
bool isPlaying()const{ return playing; }
|
||||
int getWidth()const{ return src_rect.right; }
|
||||
int getHeight()const{ return src_rect.bottom; }
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -1,57 +0,0 @@
|
||||
|
||||
#include "std.hpp"
|
||||
#include "gxmusic.hpp"
|
||||
#include <fmod.h>
|
||||
|
||||
gxMusic::gxMusic( gxAudio *a,FMUSIC_MODULE *m,FSOUND_STREAM *s ):
|
||||
audio(a),module(m),stream(s),stream_channel(-1){
|
||||
}
|
||||
|
||||
gxMusic::~gxMusic(){
|
||||
if( module ) FMUSIC_FreeSong( module );
|
||||
else FSOUND_Stream_Close( stream );
|
||||
}
|
||||
|
||||
void gxMusic::play(){
|
||||
if( module ){
|
||||
FMUSIC_PlaySong( module );
|
||||
}else{
|
||||
stream_channel=FSOUND_Stream_Play( FSOUND_FREE,stream );
|
||||
}
|
||||
}
|
||||
|
||||
void gxMusic::stop(){
|
||||
if( module ){
|
||||
FMUSIC_StopSong( module );
|
||||
}else{
|
||||
FSOUND_Stream_Stop( stream );
|
||||
stream_channel=-1;
|
||||
}
|
||||
}
|
||||
|
||||
void gxMusic::setVolume( float volume ){
|
||||
if( module ){
|
||||
FMUSIC_SetMasterVolume( module,volume*255.0f );
|
||||
}else{
|
||||
FSOUND_SetVolume( stream_channel,volume*255.0f );
|
||||
}
|
||||
}
|
||||
|
||||
void gxMusic::setPaused( bool paused){
|
||||
if( module ){
|
||||
FMUSIC_SetPaused( module,paused );
|
||||
}else{
|
||||
FSOUND_SetPaused( stream_channel,paused );
|
||||
}
|
||||
}
|
||||
|
||||
bool gxMusic::isPlaying()const{
|
||||
if( module ){
|
||||
return FMUSIC_IsPlaying( module ) ? true : false;
|
||||
}else{
|
||||
return FSOUND_IsPlaying( stream_channel ) ? true : false;
|
||||
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -1,34 +0,0 @@
|
||||
|
||||
#ifndef GXMUSIC_H
|
||||
#define GXMUSIC_H
|
||||
|
||||
class gxAudio;
|
||||
|
||||
struct FMUSIC_MODULE;
|
||||
struct FSOUND_STREAM;
|
||||
|
||||
class gxMusic{
|
||||
public:
|
||||
gxAudio *audio;
|
||||
|
||||
gxMusic( gxAudio *audio,FMUSIC_MODULE *module,FSOUND_STREAM *stream );
|
||||
~gxMusic();
|
||||
|
||||
private:
|
||||
FMUSIC_MODULE *module;
|
||||
FSOUND_STREAM *stream;
|
||||
int stream_channel;
|
||||
|
||||
/***** GX INTERFACE *****/
|
||||
public:
|
||||
//modifiers
|
||||
void play();
|
||||
void stop();
|
||||
void setPaused( bool paused );
|
||||
void setVolume( float volume );
|
||||
|
||||
//accessors
|
||||
bool isPlaying()const;
|
||||
};
|
||||
|
||||
#endif
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,143 +0,0 @@
|
||||
|
||||
#ifndef GXRUNTIME_H
|
||||
#define GXRUNTIME_H
|
||||
|
||||
#include <windows.h>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "gxaudio.hpp"
|
||||
#include "gxinput.hpp"
|
||||
#include "gxgraphics.hpp"
|
||||
#include "gxfilesystem.hpp"
|
||||
#include "gxtimer.hpp"
|
||||
|
||||
class gxRuntime{
|
||||
/***** INTERNAL INTERFACE *****/
|
||||
public:
|
||||
|
||||
HWND hwnd;
|
||||
HINSTANCE hinst;
|
||||
|
||||
gxAudio *audio;
|
||||
gxInput *input;
|
||||
gxGraphics *graphics;
|
||||
gxFileSystem *fileSystem;
|
||||
|
||||
void flip( bool vwait );
|
||||
void moveMouse( int x,int y );
|
||||
|
||||
LRESULT windowProc( HWND hwnd,UINT msg,WPARAM w,LPARAM l );
|
||||
|
||||
struct GfxMode;
|
||||
struct GfxDriver;
|
||||
|
||||
private:
|
||||
gxRuntime( HINSTANCE hinst,const std::string &cmd_line,HWND hwnd );
|
||||
~gxRuntime();
|
||||
|
||||
void paint();
|
||||
void suspend();
|
||||
void forceSuspend();
|
||||
void resume();
|
||||
void forceResume();
|
||||
void backupWindowState();
|
||||
void restoreWindowState();
|
||||
|
||||
RECT t_rect;
|
||||
int t_style;
|
||||
std::string cmd_line;
|
||||
bool pointer_visible;
|
||||
std::string app_title;
|
||||
std::string app_close;
|
||||
|
||||
bool setDisplayMode( int w,int h,int d,bool d3d,IDirectDraw7 *dd );
|
||||
gxGraphics *openWindowedGraphics( int w,int h,int d,bool d3d );
|
||||
gxGraphics *openExclusiveGraphics( int w,int h,int d,bool d3d );
|
||||
|
||||
bool enum_all;
|
||||
std::vector<GfxDriver*> drivers;
|
||||
GfxDriver *curr_driver;
|
||||
int use_di;
|
||||
|
||||
void enumGfx();
|
||||
void denumGfx();
|
||||
|
||||
void resetInput();
|
||||
void pauseAudio();
|
||||
void resumeAudio();
|
||||
void backupGraphics();
|
||||
void restoreGraphics();
|
||||
void acquireInput();
|
||||
void unacquireInput();
|
||||
|
||||
/***** APP INTERFACE *****/
|
||||
public:
|
||||
static gxRuntime *openRuntime( HINSTANCE hinst,const std::string &cmd_line, void* d );
|
||||
static void closeRuntime( gxRuntime *runtime );
|
||||
|
||||
void asyncStop();
|
||||
void asyncRun();
|
||||
void asyncEnd();
|
||||
|
||||
/***** GX INTERFACE *****/
|
||||
public:
|
||||
enum{
|
||||
GFXMODECAPS_3D=1
|
||||
};
|
||||
|
||||
//return true if program should continue, or false for quit.
|
||||
bool idle();
|
||||
bool delay( int ms );
|
||||
|
||||
bool execute( const std::string &cmd );
|
||||
void setTitle( const std::string &title,const std::string &close );
|
||||
int getMilliSecs();
|
||||
void setPointerVisible( bool vis );
|
||||
|
||||
std::string commandLine();
|
||||
|
||||
std::string systemProperty( const std::string &t );
|
||||
|
||||
void debugStop();
|
||||
void debugProfile( int per );
|
||||
void debugStmt( int pos,const char *file );
|
||||
void debugEnter( void *frame,void *env,const char *func );
|
||||
void debugLeave();
|
||||
void debugInfo( const char *t );
|
||||
void debugError( const char *t );
|
||||
void debugLog( const char *t );
|
||||
|
||||
int enumerateGraphicsDrivers();
|
||||
void graphicsDriverInfo( int driver,std::string *name,int *caps );
|
||||
|
||||
int countGraphicsModes( int driver );
|
||||
void graphicsModeInfo( int driver,int mode,int *w,int *h,int *d,int *caps );
|
||||
|
||||
void windowedModeInfo( int *caps );
|
||||
|
||||
gxAudio *openAudio( int flags );
|
||||
void closeAudio( gxAudio *audio );
|
||||
|
||||
gxInput *openInput( int flags );
|
||||
void closeInput( gxInput *input );
|
||||
|
||||
gxGraphics *openGraphics( int w,int h,int d,int driver,int flags );
|
||||
void closeGraphics( gxGraphics *graphics );
|
||||
bool graphicsLost();
|
||||
|
||||
gxFileSystem *openFileSystem( int flags );
|
||||
void closeFileSystem( gxFileSystem *filesys );
|
||||
|
||||
gxTimer *createTimer( int hertz );
|
||||
void freeTimer( gxTimer *timer );
|
||||
|
||||
void enableDirectInput( bool use );
|
||||
int directInputEnabled(){ return use_di; }
|
||||
|
||||
int callDll( const std::string &dll,const std::string &func,const void *in,int in_sz,void *out,int out_sz );
|
||||
|
||||
OSVERSIONINFO osinfo;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -1,619 +0,0 @@
|
||||
|
||||
#include "std.hpp"
|
||||
#include "gxscene.hpp"
|
||||
#include "gxgraphics.hpp"
|
||||
#include "gxruntime.hpp"
|
||||
|
||||
static bool can_wb;
|
||||
static int hw_tex_stages,tex_stages;
|
||||
static float BLACK[]={0,0,0};
|
||||
static float WHITE[]={1,1,1};
|
||||
static float GRAY[]={.5f,.5f,.5f};
|
||||
static D3DMATRIX sphere_mat,nullmatrix;
|
||||
|
||||
void gxScene::setRS( int n,int t ){
|
||||
if( d3d_rs[n]==t ) return;
|
||||
dir3dDev->SetRenderState( (D3DRENDERSTATETYPE)n,t );
|
||||
d3d_rs[n]=t;
|
||||
}
|
||||
|
||||
void gxScene::setTSS( int n,int s,int t ){
|
||||
if( d3d_tss[n][s]==t ) return;
|
||||
dir3dDev->SetTextureStageState( n,(D3DTEXTURESTAGESTATETYPE)s,t );
|
||||
d3d_tss[n][s]=t;
|
||||
}
|
||||
|
||||
gxScene::gxScene( gxGraphics *g,gxCanvas *t ):
|
||||
graphics(g),target(t),dir3dDev( g->dir3dDev ),
|
||||
n_texs(0),tris_drawn(0){
|
||||
|
||||
memset( d3d_rs,0x55,sizeof(d3d_rs) );
|
||||
memset( d3d_tss,0x55,sizeof(d3d_tss) );
|
||||
|
||||
//nomalize normals
|
||||
setRS( D3DRENDERSTATE_NORMALIZENORMALS,TRUE );
|
||||
|
||||
//vertex coloring
|
||||
setRS( D3DRENDERSTATE_COLORVERTEX,FALSE );
|
||||
setRS( D3DRENDERSTATE_DIFFUSEMATERIALSOURCE,D3DMCS_COLOR1 );
|
||||
setRS( D3DRENDERSTATE_AMBIENTMATERIALSOURCE,D3DMCS_COLOR1 );
|
||||
setRS( D3DRENDERSTATE_EMISSIVEMATERIALSOURCE,D3DMCS_MATERIAL );
|
||||
setRS( D3DRENDERSTATE_SPECULARMATERIALSOURCE,D3DMCS_MATERIAL );
|
||||
|
||||
//Alpha test
|
||||
setRS( D3DRENDERSTATE_ALPHATESTENABLE,false );
|
||||
setRS( D3DRENDERSTATE_ALPHAFUNC,D3DCMP_GREATER );
|
||||
setRS( D3DRENDERSTATE_ALPHAREF,128 );
|
||||
|
||||
//source/dest blending modes
|
||||
setRS( D3DRENDERSTATE_SRCBLEND,D3DBLEND_SRCALPHA );
|
||||
setRS( D3DRENDERSTATE_DESTBLEND,D3DBLEND_INVSRCALPHA );
|
||||
|
||||
//suss out caps
|
||||
can_wb=false;
|
||||
hw_tex_stages=1;
|
||||
D3DDEVICEDESC7 devDesc={0};
|
||||
if( dir3dDev->GetCaps( &devDesc )>=0 ){
|
||||
DWORD caps=devDesc.dpcTriCaps.dwRasterCaps;
|
||||
//texture stages
|
||||
hw_tex_stages=devDesc.wMaxSimultaneousTextures;
|
||||
//depth buffer mode
|
||||
if( (caps & D3DPRASTERCAPS_WBUFFER) && graphics->zbuffFmt.dwRGBBitCount==16 ) can_wb=true;
|
||||
//fog mode
|
||||
if( (caps&D3DPRASTERCAPS_FOGTABLE)&&(caps&D3DPRASTERCAPS_WFOG) ){
|
||||
setRS( D3DRENDERSTATE_FOGVERTEXMODE,D3DFOG_NONE );
|
||||
setRS( D3DRENDERSTATE_FOGTABLEMODE,D3DFOG_LINEAR );
|
||||
}else{
|
||||
setRS( D3DRENDERSTATE_FOGTABLEMODE,D3DFOG_NONE );
|
||||
setRS( D3DRENDERSTATE_FOGVERTEXMODE,D3DFOG_LINEAR );
|
||||
}
|
||||
}
|
||||
tex_stages=hw_tex_stages;
|
||||
|
||||
caps_level=100;
|
||||
if( devDesc.dpcTriCaps.dwTextureCaps & D3DPTEXTURECAPS_CUBEMAP ){
|
||||
caps_level=110;
|
||||
}
|
||||
|
||||
//default texture states
|
||||
for( int n=0;n<hw_tex_stages;++n ){
|
||||
setTSS( n,D3DTSS_COLORARG1,D3DTA_TEXTURE );
|
||||
setTSS( n,D3DTSS_COLORARG2,D3DTA_CURRENT );
|
||||
setTSS( n,D3DTSS_ALPHAARG1,D3DTA_TEXTURE );
|
||||
setTSS( n,D3DTSS_ALPHAARG2,D3DTA_CURRENT );
|
||||
setTSS( n,D3DTSS_MINFILTER,D3DTFN_LINEAR );
|
||||
setTSS( n,D3DTSS_MAGFILTER,D3DTFG_LINEAR );
|
||||
setTSS( n,D3DTSS_MIPFILTER,D3DTFP_LINEAR );
|
||||
}
|
||||
setHWMultiTex( true );
|
||||
|
||||
//ATI lighting hack
|
||||
dir3dDev->LightEnable( 0,true );
|
||||
dir3dDev->LightEnable( 0,false );
|
||||
|
||||
//globals
|
||||
sphere_mat._11=.5f;sphere_mat._22=-.5f;sphere_mat._33=.5f;
|
||||
sphere_mat._41=.5f;sphere_mat._42=.5f;sphere_mat._43=.5f;
|
||||
nullmatrix._11=nullmatrix._22=nullmatrix._33=nullmatrix._44=1;
|
||||
|
||||
//set null renderstate
|
||||
memset(&material,0,sizeof(material));
|
||||
shininess=0;blend=BLEND_REPLACE;fx=0;
|
||||
for( int k=0;k<MAX_TEXTURES;++k ) memset( &texstate[k],0,sizeof(texstate[k]) );
|
||||
|
||||
wbuffer=can_wb;
|
||||
dither=false;setDither( true );
|
||||
antialias=true;setAntialias( false );
|
||||
wireframe=true;setWireframe( false );
|
||||
flipped=true;setFlippedTris( false );
|
||||
ambient=~0;setAmbient( GRAY );
|
||||
ambient2=~0;setAmbient2( BLACK );
|
||||
fogcolor=~0;setFogColor( BLACK );
|
||||
fogrange_nr=fogrange_fr=0;setFogRange( 1,1000 );
|
||||
fogmode=FOG_LINEAR;setFogMode( FOG_NONE );
|
||||
zmode=-1;setZMode( ZMODE_NORMAL );
|
||||
memset(&projmatrix,0,sizeof(projmatrix));
|
||||
ortho_proj=true;frustum_nr=frustum_fr=frustum_w=frustum_h=0;setPerspProj( 1,1000,1,1 );
|
||||
memset(&viewport,0,sizeof(viewport));viewport.dvMaxZ=1;setViewport( 0,0,target->getWidth(),target->getHeight() );
|
||||
viewmatrix=nullmatrix;setViewMatrix( 0 );
|
||||
worldmatrix=nullmatrix;setWorldMatrix( 0 );
|
||||
|
||||
//set default renderstate
|
||||
blend=fx=~0;shininess=1;
|
||||
RenderState state;memset(&state,0,sizeof(state));
|
||||
state.color[0]=state.color[1]=state.color[2]=state.alpha=1;
|
||||
state.blend=BLEND_REPLACE;
|
||||
setRenderState( state );
|
||||
}
|
||||
|
||||
gxScene::~gxScene(){
|
||||
while( _allLights.size() ) freeLight( *_allLights.begin() );
|
||||
}
|
||||
|
||||
void gxScene::setTexState( int n,const TexState &state,bool tex_blend ){
|
||||
|
||||
int flags=state.canvas->getFlags();
|
||||
int tc_index=state.flags & TEX_COORDS2 ? 1 : 0;
|
||||
|
||||
//set canvas
|
||||
dir3dDev->SetTexture( n,state.canvas->getTexSurface() );
|
||||
|
||||
//set addressing modes
|
||||
setTSS( n,D3DTSS_ADDRESSU,(flags & gxCanvas::CANVAS_TEX_CLAMPU) ? D3DTADDRESS_CLAMP : D3DTADDRESS_WRAP );
|
||||
setTSS( n,D3DTSS_ADDRESSV,(flags & gxCanvas::CANVAS_TEX_CLAMPV) ? D3DTADDRESS_CLAMP : D3DTADDRESS_WRAP );
|
||||
|
||||
//texgen
|
||||
switch( flags&(
|
||||
gxCanvas::CANVAS_TEX_SPHERE|
|
||||
gxCanvas::CANVAS_TEX_CUBE) ){
|
||||
|
||||
case gxCanvas::CANVAS_TEX_SPHERE:
|
||||
setTSS( n,D3DTSS_TEXCOORDINDEX,D3DTSS_TCI_CAMERASPACENORMAL );//|tc_index );
|
||||
setTSS( n,D3DTSS_TEXTURETRANSFORMFLAGS,D3DTTFF_COUNT2 );
|
||||
dir3dDev->SetTransform( (D3DTRANSFORMSTATETYPE)(D3DTRANSFORMSTATE_TEXTURE0+n),&sphere_mat );
|
||||
break;
|
||||
case gxCanvas::CANVAS_TEX_CUBE:
|
||||
switch( state.canvas->cubeMode() & 3 ){
|
||||
case gxCanvas::CUBEMODE_NORMAL:
|
||||
setTSS( n,D3DTSS_TEXCOORDINDEX,D3DTSS_TCI_CAMERASPACENORMAL );//|tc_index );
|
||||
break;
|
||||
case gxCanvas::CUBEMODE_POSITION:
|
||||
setTSS( n,D3DTSS_TEXCOORDINDEX,D3DTSS_TCI_CAMERASPACEPOSITION );//|tc_index );
|
||||
break;
|
||||
default:
|
||||
setTSS( n,D3DTSS_TEXCOORDINDEX,D3DTSS_TCI_CAMERASPACEREFLECTIONVECTOR );//|tc_index );
|
||||
break;
|
||||
}
|
||||
if( state.canvas->cubeMode() & 4 ){
|
||||
setTSS( n,D3DTSS_TEXTURETRANSFORMFLAGS,D3DTTFF_DISABLE );
|
||||
}else{
|
||||
setTSS( n,D3DTSS_TEXTURETRANSFORMFLAGS,D3DTTFF_COUNT3 );//COUNT4|D3DTTFF_PROJECTED );
|
||||
dir3dDev->SetTransform( (D3DTRANSFORMSTATETYPE)(D3DTRANSFORMSTATE_TEXTURE0+n),&inv_viewmatrix );
|
||||
}
|
||||
break;
|
||||
default:
|
||||
setTSS( n,D3DTSS_TEXCOORDINDEX,D3DTSS_TCI_PASSTHRU|tc_index );
|
||||
if( state.mat_valid){
|
||||
setTSS( n,D3DTSS_TEXTURETRANSFORMFLAGS,D3DTTFF_COUNT2 );
|
||||
dir3dDev->SetTransform( (D3DTRANSFORMSTATETYPE)(D3DTRANSFORMSTATE_TEXTURE0+n),(D3DMATRIX*)&state.matrix );
|
||||
}else{
|
||||
setTSS( n,D3DTSS_TEXTURETRANSFORMFLAGS,D3DTTFF_DISABLE );
|
||||
}
|
||||
}
|
||||
|
||||
if( !tex_blend ) return;
|
||||
|
||||
//blending
|
||||
switch( state.blend ){
|
||||
case BLEND_ALPHA:
|
||||
setTSS( n,D3DTSS_COLOROP,D3DTOP_BLENDTEXTUREALPHA );
|
||||
break;
|
||||
case BLEND_MULTIPLY:
|
||||
setTSS( n,D3DTSS_COLOROP,D3DTOP_MODULATE);
|
||||
break;
|
||||
case BLEND_ADD:
|
||||
setTSS( n,D3DTSS_COLOROP,D3DTOP_ADD );
|
||||
break;
|
||||
case BLEND_DOT3:
|
||||
setTSS( n,D3DTSS_COLOROP,D3DTOP_DOTPRODUCT3 );
|
||||
break;
|
||||
case BLEND_MULTIPLY2:
|
||||
setTSS( n,D3DTSS_COLOROP,D3DTOP_MODULATE2X );
|
||||
break;
|
||||
}
|
||||
setTSS( n,D3DTSS_ALPHAOP,(flags & gxCanvas::CANVAS_TEX_ALPHA) ? D3DTOP_MODULATE : D3DTOP_SELECTARG2 );
|
||||
}
|
||||
|
||||
int gxScene::hwTexUnits(){
|
||||
return tex_stages;
|
||||
}
|
||||
|
||||
int gxScene::gfxDriverCaps3D(){
|
||||
return caps_level;
|
||||
}
|
||||
|
||||
void gxScene::setZMode(){
|
||||
switch( zmode ){
|
||||
case ZMODE_NORMAL:
|
||||
setRS( D3DRENDERSTATE_ZENABLE,wbuffer ? D3DZB_USEW : D3DZB_TRUE );
|
||||
setRS( D3DRENDERSTATE_ZWRITEENABLE,true );
|
||||
break;
|
||||
case ZMODE_DISABLE:
|
||||
setRS( D3DRENDERSTATE_ZENABLE,D3DZB_FALSE );
|
||||
setRS( D3DRENDERSTATE_ZWRITEENABLE,false );
|
||||
break;
|
||||
case ZMODE_CMPONLY:
|
||||
setRS( D3DRENDERSTATE_ZENABLE,wbuffer ? D3DZB_USEW : D3DZB_TRUE );
|
||||
setRS( D3DRENDERSTATE_ZWRITEENABLE,false );
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void gxScene::setLights(){
|
||||
if( fx & FX_FULLBRIGHT ){
|
||||
//no lights on
|
||||
for( int n=0;n<_curLights.size();++n ) dir3dDev->LightEnable( n,false );
|
||||
}else if( fx & FX_CONDLIGHT ){
|
||||
//some lights on
|
||||
for( int n=0;n<_curLights.size();++n ){
|
||||
gxLight *light=_curLights[n];
|
||||
bool enable=light->d3d_light.dltType!=D3DLIGHT_DIRECTIONAL;
|
||||
dir3dDev->LightEnable( n,enable );
|
||||
}
|
||||
}else{
|
||||
//all lights on
|
||||
for( int n=0;n<_curLights.size();++n ) dir3dDev->LightEnable( n,true );
|
||||
}
|
||||
}
|
||||
|
||||
void gxScene::setAmbient(){
|
||||
int n=(fx & FX_FULLBRIGHT) ? 0xffffff : ((fx & FX_CONDLIGHT) ? ambient2 : ambient);
|
||||
setRS( D3DRENDERSTATE_AMBIENT,n );
|
||||
}
|
||||
|
||||
void gxScene::setFogMode(){
|
||||
bool fog= fogmode==FOG_LINEAR && !(fx&FX_NOFOG);
|
||||
setRS( D3DRENDERSTATE_FOGENABLE,fog );
|
||||
}
|
||||
|
||||
void gxScene::setTriCull(){
|
||||
if( fx & FX_DOUBLESIDED ){
|
||||
setRS( D3DRENDERSTATE_CULLMODE,D3DCULL_NONE );
|
||||
}else if( flipped ){
|
||||
setRS( D3DRENDERSTATE_CULLMODE,D3DCULL_CW );
|
||||
}else{
|
||||
setRS( D3DRENDERSTATE_CULLMODE,D3DCULL_CCW );
|
||||
}
|
||||
}
|
||||
|
||||
void gxScene::setHWMultiTex( bool e ){
|
||||
for( int n=0;n<8;++n ){
|
||||
setTSS( n,D3DTSS_COLOROP,D3DTOP_DISABLE );
|
||||
setTSS( n,D3DTSS_ALPHAOP,D3DTOP_DISABLE );
|
||||
dir3dDev->SetTexture( n,0 );
|
||||
}
|
||||
for( int k=0;k<MAX_TEXTURES;++k ){
|
||||
memset( &texstate[k],0,sizeof(texstate[k]) );
|
||||
}
|
||||
tex_stages=e ? hw_tex_stages : 1;
|
||||
n_texs=0;
|
||||
}
|
||||
|
||||
void gxScene::setWBuffer( bool n ){
|
||||
if( n==wbuffer || !can_wb ) return;
|
||||
wbuffer=n;setZMode();
|
||||
}
|
||||
|
||||
void gxScene::setDither( bool n ){
|
||||
if( n==dither ) return;
|
||||
dither=n;setRS( D3DRENDERSTATE_DITHERENABLE,dither ? true : false );
|
||||
}
|
||||
|
||||
void gxScene::setAntialias( bool n ){
|
||||
if( n==antialias ) return;
|
||||
antialias=n;setRS( D3DRENDERSTATE_ANTIALIAS,antialias ? D3DANTIALIAS_SORTINDEPENDENT : D3DANTIALIAS_NONE );
|
||||
}
|
||||
|
||||
void gxScene::setWireframe( bool n ){
|
||||
if( n==wireframe ) return;
|
||||
wireframe=n;setRS( D3DRENDERSTATE_FILLMODE,wireframe ? D3DFILL_WIREFRAME : D3DFILL_SOLID );
|
||||
}
|
||||
|
||||
void gxScene::setFlippedTris( bool n ){
|
||||
if( n==flipped ) return;
|
||||
flipped=n;setTriCull();
|
||||
}
|
||||
|
||||
void gxScene::setAmbient( const float rgb[] ){
|
||||
int n=(int(rgb[0]*255.0f)<<16)|(int(rgb[1]*255.0f)<<8)|int(rgb[2]*255.0f);
|
||||
ambient=n;setAmbient();
|
||||
}
|
||||
|
||||
void gxScene::setAmbient2( const float rgb[] ){
|
||||
int n=(int(rgb[0]*255.0f)<<16)|(int(rgb[1]*255.0f)<<8)|int(rgb[2]*255.0f);
|
||||
ambient2=n;setAmbient();
|
||||
}
|
||||
|
||||
void gxScene::setViewport( int x,int y,int w,int h ){
|
||||
if( x==viewport.dwX && y==viewport.dwY && w==viewport.dwWidth && h==viewport.dwHeight ) return;
|
||||
viewport.dwX=x;viewport.dwY=y;viewport.dwWidth=w;viewport.dwHeight=h;
|
||||
dir3dDev->SetViewport( &viewport );
|
||||
}
|
||||
|
||||
void gxScene::setOrthoProj( float nr,float fr,float w,float h ){
|
||||
if( ortho_proj && nr==frustum_nr && fr==frustum_fr && w==frustum_w && h==frustum_h ) return;
|
||||
frustum_nr=nr;frustum_fr=fr;frustum_w=w;frustum_h=h;ortho_proj=true;
|
||||
float W=2/w;
|
||||
float H=2/h;
|
||||
float Q=1/(fr-nr);
|
||||
projmatrix._11=W;
|
||||
projmatrix._22=H;
|
||||
projmatrix._33=Q;
|
||||
projmatrix._34=0;
|
||||
projmatrix._43=-Q*nr;
|
||||
projmatrix._44=1;
|
||||
dir3dDev->SetTransform( D3DTRANSFORMSTATE_PROJECTION,&projmatrix );
|
||||
}
|
||||
|
||||
void gxScene::setPerspProj( float nr,float fr,float w,float h ){
|
||||
if( !ortho_proj && nr==frustum_nr && fr==frustum_fr && w==frustum_w && h==frustum_h ) return;
|
||||
frustum_nr=nr;frustum_fr=fr;frustum_w=w;frustum_h=h;ortho_proj=false;
|
||||
float W=2*nr/w;
|
||||
float H=2*nr/h;
|
||||
float Q=fr/(fr-nr);
|
||||
projmatrix._11=W;
|
||||
projmatrix._22=H;
|
||||
projmatrix._33=Q;
|
||||
projmatrix._34=1;
|
||||
projmatrix._43=-Q*nr;
|
||||
projmatrix._44=0;
|
||||
dir3dDev->SetTransform( D3DTRANSFORMSTATE_PROJECTION,&projmatrix );
|
||||
}
|
||||
|
||||
void gxScene::setFogColor( const float rgb[3] ){
|
||||
int n=(int(rgb[0]*255.0f)<<16)|(int(rgb[1]*255.0f)<<8)|int(rgb[2]*255.0f);
|
||||
if( n==fogcolor ) return;
|
||||
fogcolor=n;setRS( D3DRENDERSTATE_FOGCOLOR,fogcolor );
|
||||
}
|
||||
|
||||
void gxScene::setFogRange( float nr,float fr ){
|
||||
if( nr==fogrange_nr && fr==fogrange_fr ) return;
|
||||
fogrange_nr=nr;fogrange_fr=fr;
|
||||
setRS( D3DRENDERSTATE_FOGSTART,*(DWORD*)&fogrange_nr );
|
||||
setRS( D3DRENDERSTATE_FOGEND,*(DWORD*)&fogrange_fr );
|
||||
}
|
||||
|
||||
void gxScene::setFogMode( int n ){
|
||||
if( n==fogmode ) return;
|
||||
fogmode=n;setFogMode();
|
||||
}
|
||||
|
||||
void gxScene::setZMode( int n ){
|
||||
if( n==zmode ) return;
|
||||
zmode=n;setZMode();
|
||||
}
|
||||
|
||||
void gxScene::setViewMatrix( const Matrix *m ){
|
||||
if( m ){
|
||||
memcpy( &viewmatrix._11,m->elements[0],12 );
|
||||
memcpy( &viewmatrix._21,m->elements[1],12 );
|
||||
memcpy( &viewmatrix._31,m->elements[2],12 );
|
||||
memcpy( &viewmatrix._41,m->elements[3],12 );
|
||||
inv_viewmatrix._11=viewmatrix._11;inv_viewmatrix._21=viewmatrix._12;inv_viewmatrix._31=viewmatrix._13;
|
||||
inv_viewmatrix._12=viewmatrix._21;inv_viewmatrix._22=viewmatrix._22;inv_viewmatrix._32=viewmatrix._23;
|
||||
inv_viewmatrix._13=viewmatrix._31;inv_viewmatrix._23=viewmatrix._32;inv_viewmatrix._33=viewmatrix._33;
|
||||
inv_viewmatrix._44=viewmatrix._44;
|
||||
}else{
|
||||
viewmatrix=inv_viewmatrix=nullmatrix;
|
||||
}
|
||||
|
||||
dir3dDev->SetTransform( D3DTRANSFORMSTATE_VIEW,&viewmatrix );
|
||||
}
|
||||
|
||||
void gxScene::setWorldMatrix( const Matrix *m ){
|
||||
if( m ){
|
||||
memcpy( &worldmatrix._11,m->elements[0],12 );
|
||||
memcpy( &worldmatrix._21,m->elements[1],12 );
|
||||
memcpy( &worldmatrix._31,m->elements[2],12 );
|
||||
memcpy( &worldmatrix._41,m->elements[3],12 );
|
||||
}else worldmatrix=nullmatrix;
|
||||
dir3dDev->SetTransform( D3DTRANSFORMSTATE_WORLD,&worldmatrix );
|
||||
}
|
||||
|
||||
void gxScene::setRenderState( const RenderState &rs ){
|
||||
bool setmat=false;
|
||||
if( memcmp( rs.color,&material.diffuse.r,12 ) ){
|
||||
memcpy( &material.diffuse.r,rs.color,12 );
|
||||
memcpy( &material.ambient.r,rs.color,12 );
|
||||
setmat=true;
|
||||
}
|
||||
if( rs.alpha!=material.diffuse.a ){
|
||||
material.diffuse.a=rs.alpha;
|
||||
if( rs.fx&FX_ALPHATEST ){
|
||||
int alpharef=(rs.fx&FX_VERTEXALPHA)?0:128*rs.alpha;
|
||||
setRS( D3DRENDERSTATE_ALPHAREF,alpharef );
|
||||
}
|
||||
setmat=true;
|
||||
}
|
||||
if( rs.shininess!=shininess ){
|
||||
shininess=rs.shininess;
|
||||
float t=shininess>0 ? (shininess<1 ? shininess : 1) : 0;
|
||||
material.specular.r=material.specular.g=material.specular.b=t;
|
||||
material.power=shininess*128;
|
||||
setRS( D3DRENDERSTATE_SPECULARENABLE,shininess>0 ? true : false );
|
||||
setmat=true;
|
||||
}
|
||||
if( rs.blend!=blend ){
|
||||
blend=rs.blend;
|
||||
switch( blend ){
|
||||
case BLEND_REPLACE:
|
||||
setRS( D3DRENDERSTATE_ALPHABLENDENABLE,false );
|
||||
break;
|
||||
case BLEND_ALPHA:
|
||||
setRS( D3DRENDERSTATE_ALPHABLENDENABLE,true );
|
||||
setRS( D3DRENDERSTATE_SRCBLEND,D3DBLEND_SRCALPHA );
|
||||
setRS( D3DRENDERSTATE_DESTBLEND,D3DBLEND_INVSRCALPHA );
|
||||
break;
|
||||
case BLEND_MULTIPLY:
|
||||
setRS( D3DRENDERSTATE_ALPHABLENDENABLE,true );
|
||||
setRS( D3DRENDERSTATE_SRCBLEND,D3DBLEND_DESTCOLOR );
|
||||
setRS( D3DRENDERSTATE_DESTBLEND,D3DBLEND_ZERO );
|
||||
break;
|
||||
case BLEND_ADD:
|
||||
setRS( D3DRENDERSTATE_ALPHABLENDENABLE,true );
|
||||
setRS( D3DRENDERSTATE_SRCBLEND,D3DBLEND_SRCALPHA );
|
||||
setRS( D3DRENDERSTATE_DESTBLEND,D3DBLEND_ONE );
|
||||
break;
|
||||
}
|
||||
}
|
||||
if( rs.fx!=fx ){
|
||||
int t=rs.fx^fx;fx=rs.fx;
|
||||
if( t & (FX_FULLBRIGHT|FX_CONDLIGHT) ){
|
||||
setLights();
|
||||
setAmbient();
|
||||
}
|
||||
if( t&FX_VERTEXCOLOR ){
|
||||
setRS( D3DRENDERSTATE_COLORVERTEX,fx & FX_VERTEXCOLOR ? true : false );
|
||||
}
|
||||
if( t&FX_FLATSHADED ){
|
||||
setRS( D3DRENDERSTATE_SHADEMODE,fx & FX_FLATSHADED ? D3DSHADE_FLAT : D3DSHADE_GOURAUD );
|
||||
}
|
||||
if( t&FX_NOFOG ){
|
||||
setFogMode();
|
||||
}
|
||||
if( t&FX_DOUBLESIDED ){
|
||||
setTriCull();
|
||||
}
|
||||
if( t&FX_EMISSIVE ){
|
||||
//Q3 Hack!
|
||||
int n=fx & FX_EMISSIVE;
|
||||
setRS( D3DRENDERSTATE_DIFFUSEMATERIALSOURCE,n ? D3DMCS_MATERIAL : D3DMCS_COLOR1 );
|
||||
setRS( D3DRENDERSTATE_AMBIENTMATERIALSOURCE,n ? D3DMCS_MATERIAL : D3DMCS_COLOR1 );
|
||||
setRS( D3DRENDERSTATE_EMISSIVEMATERIALSOURCE,n ? D3DMCS_COLOR1 : D3DMCS_MATERIAL );
|
||||
setRS( D3DRENDERSTATE_COLORVERTEX,n ? true : false );
|
||||
}
|
||||
if( t&FX_ALPHATEST ){
|
||||
if( fx&FX_ALPHATEST ){
|
||||
int alpharef=(rs.fx&FX_VERTEXALPHA)?0:128*rs.alpha;
|
||||
setRS( D3DRENDERSTATE_ALPHAREF,alpharef );
|
||||
}
|
||||
setRS( D3DRENDERSTATE_ALPHATESTENABLE,fx & FX_ALPHATEST ? true : false );
|
||||
}
|
||||
}
|
||||
if( setmat ){
|
||||
dir3dDev->SetMaterial( &material );
|
||||
}
|
||||
|
||||
n_texs=0;
|
||||
TexState *hw=texstate;
|
||||
for( int k=0;k<MAX_TEXTURES;++k ){
|
||||
const RenderState::TexState &ts=rs.tex_states[k];
|
||||
if( !ts.canvas || !ts.blend ) continue;
|
||||
bool settex=false;
|
||||
ts.canvas->getTexSurface(); //force mipmap rebuild
|
||||
if( ts.canvas!=hw->canvas ){ hw->canvas=ts.canvas;settex=true; }
|
||||
if( ts.blend!=hw->blend ){ hw->blend=ts.blend;settex=true; }
|
||||
if( ts.flags!=hw->flags ){ hw->flags=ts.flags;settex=true; }
|
||||
if( ts.matrix || hw->mat_valid ){
|
||||
if( ts.matrix ){
|
||||
memcpy( &hw->matrix._11,ts.matrix->elements[0],12 );
|
||||
memcpy( &hw->matrix._21,ts.matrix->elements[1],12 );
|
||||
memcpy( &hw->matrix._31,ts.matrix->elements[2],12 );
|
||||
memcpy( &hw->matrix._41,ts.matrix->elements[3],12 );
|
||||
hw->mat_valid=true;
|
||||
}else{
|
||||
hw->mat_valid=false;
|
||||
}
|
||||
settex=true;
|
||||
}
|
||||
if( settex && n_texs<tex_stages ){
|
||||
setTexState( n_texs,*hw,true );
|
||||
}
|
||||
++hw;++n_texs;
|
||||
}
|
||||
if( n_texs<tex_stages && hw->canvas ){
|
||||
hw->canvas=0;
|
||||
setTSS( n_texs,D3DTSS_COLOROP,D3DTOP_DISABLE );
|
||||
setTSS( n_texs,D3DTSS_ALPHAOP,D3DTOP_DISABLE );
|
||||
dir3dDev->SetTexture( n_texs,0 );
|
||||
}
|
||||
}
|
||||
|
||||
bool gxScene::begin( const vector<gxLight*> &lights ){
|
||||
|
||||
if( dir3dDev->BeginScene()!=D3D_OK ) return false;
|
||||
|
||||
//clear textures!
|
||||
int n;
|
||||
for( n=0;n<tex_stages;++n ){
|
||||
texstate[n].canvas=0;
|
||||
setTSS( n,D3DTSS_COLOROP,D3DTOP_DISABLE );
|
||||
setTSS( n,D3DTSS_ALPHAOP,D3DTOP_DISABLE );
|
||||
dir3dDev->SetTexture( n,0 );
|
||||
}
|
||||
|
||||
//set light states
|
||||
_curLights.clear();
|
||||
for( n=0;n<8;++n ){
|
||||
if( n<lights.size() ){
|
||||
_curLights.push_back( lights[n] );
|
||||
dir3dDev->SetLight( n,&_curLights[n]->d3d_light );
|
||||
}else{
|
||||
dir3dDev->LightEnable( n,false );
|
||||
}
|
||||
}
|
||||
setLights();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void gxScene::clear( const float rgb[3],float alpha,float z,bool clear_argb,bool clear_z ){
|
||||
if( !clear_argb && !clear_z ) return;
|
||||
int flags=(clear_argb ? D3DCLEAR_TARGET : 0) | (clear_z ? D3DCLEAR_ZBUFFER : 0);
|
||||
unsigned argb=(int(alpha*255.0f)<<24)|(int(rgb[0]*255.0f)<<16)|(int(rgb[1]*255.0f)<<8)|int(rgb[2]*255.0f);
|
||||
dir3dDev->Clear( 0,0,flags,argb,z,0 );
|
||||
}
|
||||
|
||||
void gxScene::render( gxMesh *m,int first_vert,int vert_cnt,int first_tri,int tri_cnt ){
|
||||
|
||||
m->render( first_vert,vert_cnt,first_tri,tri_cnt );
|
||||
tris_drawn+=tri_cnt;
|
||||
if( n_texs<=tex_stages ) return;
|
||||
|
||||
|
||||
setTSS( 0,D3DTSS_COLOROP,D3DTOP_SELECTARG1 );
|
||||
setTSS( 0,D3DTSS_ALPHAOP,D3DTOP_SELECTARG1 );
|
||||
if( tex_stages>1 ){
|
||||
setTSS( 1,D3DTSS_COLOROP,D3DTOP_DISABLE );
|
||||
setTSS( 1,D3DTSS_ALPHAOP,D3DTOP_DISABLE );
|
||||
}
|
||||
|
||||
setRS( D3DRENDERSTATE_LIGHTING,false );
|
||||
setRS( D3DRENDERSTATE_ALPHABLENDENABLE,true );
|
||||
|
||||
for( int k=tex_stages;k<n_texs;++k ){
|
||||
const TexState &state=texstate[k];
|
||||
switch( state.blend ){
|
||||
case BLEND_ALPHA:
|
||||
setRS( D3DRENDERSTATE_SRCBLEND,D3DBLEND_SRCALPHA );
|
||||
setRS( D3DRENDERSTATE_DESTBLEND,D3DBLEND_INVSRCALPHA );
|
||||
break;
|
||||
case BLEND_MULTIPLY:case BLEND_DOT3:
|
||||
setRS( D3DRENDERSTATE_SRCBLEND,D3DBLEND_DESTCOLOR );
|
||||
setRS( D3DRENDERSTATE_DESTBLEND,D3DBLEND_ZERO );
|
||||
break;
|
||||
case BLEND_ADD:
|
||||
setRS( D3DRENDERSTATE_SRCBLEND,D3DBLEND_ONE );
|
||||
setRS( D3DRENDERSTATE_DESTBLEND,D3DBLEND_ONE );
|
||||
break;
|
||||
}
|
||||
setTexState( 0,state,false );
|
||||
m->render( first_vert,vert_cnt,first_tri,tri_cnt );
|
||||
tris_drawn+=tri_cnt;
|
||||
}
|
||||
|
||||
setRS( D3DRENDERSTATE_ALPHABLENDENABLE,false );
|
||||
setRS( D3DRENDERSTATE_LIGHTING,true );
|
||||
if( tex_stages>1 ) setTexState( 1,texstate[1],true );
|
||||
setTexState( 0,texstate[0],true );
|
||||
}
|
||||
|
||||
void gxScene::end(){
|
||||
dir3dDev->EndScene();
|
||||
RECT r={ viewport.dwX,viewport.dwY,viewport.dwX+viewport.dwWidth,viewport.dwY+viewport.dwHeight };
|
||||
target->damage( r );
|
||||
}
|
||||
|
||||
gxLight *gxScene::createLight( int flags ){
|
||||
gxLight *l=new gxLight( this,flags );
|
||||
_allLights.insert(l);
|
||||
return l;
|
||||
}
|
||||
|
||||
void gxScene::freeLight( gxLight *l ){
|
||||
_allLights.erase(l);
|
||||
}
|
||||
|
||||
int gxScene::getTrianglesDrawn()const{
|
||||
return tris_drawn;
|
||||
}
|
||||
@@ -1,157 +0,0 @@
|
||||
|
||||
|
||||
#ifndef GXSCENE_H
|
||||
#define GXSCENE_H
|
||||
|
||||
#include <map>
|
||||
#include "GraphicsRuntime.hpp"
|
||||
#include <windows.h>
|
||||
#include <d3d.h>
|
||||
|
||||
#include "gxlight.hpp"
|
||||
|
||||
class gxCanvas;
|
||||
|
||||
class gxMesh;
|
||||
class gxLight;
|
||||
class gxGraphics;
|
||||
class gxTexture;
|
||||
|
||||
class gxScene{
|
||||
public:
|
||||
gxGraphics *graphics;
|
||||
IDirect3DDevice7 *dir3dDev;
|
||||
|
||||
gxScene( gxGraphics *graphics,gxCanvas *target );
|
||||
~gxScene();
|
||||
|
||||
void setEnabled( gxLight *light,bool enabled );
|
||||
|
||||
/***** GX INTERFACE *****/
|
||||
public:
|
||||
enum{
|
||||
MAX_TEXTURES= 8
|
||||
};
|
||||
enum{
|
||||
FX_FULLBRIGHT= 0x0001,
|
||||
FX_VERTEXCOLOR= 0x0002,
|
||||
FX_FLATSHADED= 0x0004,
|
||||
FX_NOFOG= 0x0008,
|
||||
FX_DOUBLESIDED= 0x0010,
|
||||
FX_VERTEXALPHA= 0x0020,
|
||||
|
||||
FX_ALPHATEST= 0x2000,
|
||||
FX_CONDLIGHT= 0x4000,
|
||||
FX_EMISSIVE= 0x8000
|
||||
};
|
||||
enum{
|
||||
BLEND_REPLACE= 0,
|
||||
BLEND_ALPHA= 1,
|
||||
BLEND_MULTIPLY= 2,
|
||||
BLEND_ADD= 3,
|
||||
BLEND_DOT3= 4,
|
||||
BLEND_MULTIPLY2=5,
|
||||
};
|
||||
enum{
|
||||
ZMODE_NORMAL= 0,
|
||||
ZMODE_DISABLE= 1,
|
||||
ZMODE_CMPONLY= 2
|
||||
};
|
||||
enum{
|
||||
FOG_NONE= 0,
|
||||
FOG_LINEAR= 1
|
||||
};
|
||||
enum{
|
||||
TEX_COORDS2= 0x0001
|
||||
};
|
||||
struct Matrix{
|
||||
float elements[4][3];
|
||||
};
|
||||
struct RenderState{
|
||||
float color[3];
|
||||
float shininess,alpha;
|
||||
int blend,fx;
|
||||
struct TexState{
|
||||
gxCanvas *canvas;
|
||||
const Matrix *matrix;
|
||||
int blend,flags;
|
||||
}tex_states[MAX_TEXTURES];
|
||||
};
|
||||
|
||||
//state
|
||||
int hwTexUnits();
|
||||
int gfxDriverCaps3D();
|
||||
|
||||
void setWBuffer( bool enable );
|
||||
void setHWMultiTex( bool enable );
|
||||
void setDither( bool enable );
|
||||
void setAntialias( bool enable );
|
||||
void setWireframe( bool enable );
|
||||
void setFlippedTris( bool enable );
|
||||
void setAmbient( const float rgb[3] );
|
||||
void setAmbient2( const float rgb[3] );
|
||||
void setFogColor( const float rgb[3] );
|
||||
void setFogRange( float nr,float fr );
|
||||
void setFogMode( int mode );
|
||||
void setZMode( int mode );
|
||||
void setViewport( int x,int y,int w,int h );
|
||||
void setOrthoProj( float nr,float fr,float nr_w,float nr_h );
|
||||
void setPerspProj( float nr,float fr,float nr_w,float nr_h );
|
||||
void setViewMatrix( const Matrix *matrix );
|
||||
void setWorldMatrix( const Matrix *matrix );
|
||||
void setRenderState( const RenderState &state );
|
||||
|
||||
//rendering
|
||||
bool begin( const std::vector<gxLight*> &lights );
|
||||
void clear( const float rgb[3],float alpha,float z,bool clear_argb,bool clear_z );
|
||||
void render( gxMesh *mesh,int first_vert,int vert_cnt,int first_tri,int tri_cnt );
|
||||
void end();
|
||||
|
||||
//lighting
|
||||
gxLight *createLight( int flags );
|
||||
void freeLight( gxLight *l );
|
||||
|
||||
//info
|
||||
int getTrianglesDrawn()const;
|
||||
|
||||
private:
|
||||
gxCanvas *target;
|
||||
bool wbuffer,dither,antialias,wireframe,flipped;
|
||||
unsigned ambient,ambient2,fogcolor;
|
||||
int caps_level,fogmode,zmode;
|
||||
float fogrange_nr,fogrange_fr;
|
||||
D3DVIEWPORT7 viewport;
|
||||
bool ortho_proj;
|
||||
float frustum_nr,frustum_fr,frustum_w,frustum_h;
|
||||
D3DMATRIX projmatrix,viewmatrix,worldmatrix;
|
||||
D3DMATRIX inv_viewmatrix;
|
||||
D3DMATERIAL7 material;
|
||||
float shininess;
|
||||
int blend,fx;
|
||||
struct TexState{
|
||||
gxCanvas *canvas;
|
||||
int blend,flags;
|
||||
D3DMATRIX matrix;
|
||||
bool mat_valid;
|
||||
};
|
||||
TexState texstate[MAX_TEXTURES];
|
||||
int n_texs,tris_drawn;
|
||||
|
||||
std::set<gxLight*> _allLights;
|
||||
std::vector<gxLight*> _curLights;
|
||||
|
||||
int d3d_rs[160];
|
||||
int d3d_tss[8][32];
|
||||
|
||||
void setRS( int n,int t );
|
||||
void setTSS( int n,int s,int t );
|
||||
|
||||
void setLights();
|
||||
void setZMode();
|
||||
void setAmbient();
|
||||
void setFogMode();
|
||||
void setTriCull();
|
||||
void setTexState( int index,const TexState &state,bool set_blend );
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -1,51 +0,0 @@
|
||||
|
||||
#include "std.hpp"
|
||||
#include "gxsound.hpp"
|
||||
#include "gxaudio.hpp"
|
||||
#include <fmod.h>
|
||||
|
||||
gxSound::gxSound( gxAudio *a,FSOUND_SAMPLE *s ):
|
||||
audio(a),sample(s),defs_valid(true){
|
||||
FSOUND_Sample_GetDefaults( sample,&def_freq,&def_vol,&def_pan,&def_pri );
|
||||
}
|
||||
|
||||
gxSound::~gxSound(){
|
||||
FSOUND_Sample_Free( sample );
|
||||
}
|
||||
|
||||
void gxSound::setDefaults(){
|
||||
if( !defs_valid ){
|
||||
FSOUND_Sample_SetDefaults( sample,def_freq,def_vol,def_pan,def_pri );
|
||||
defs_valid=true;
|
||||
}
|
||||
}
|
||||
|
||||
gxChannel *gxSound::play(){
|
||||
setDefaults();
|
||||
return audio->play( sample );
|
||||
}
|
||||
|
||||
gxChannel *gxSound::play3d( const float pos[3],const float vel[3] ){
|
||||
setDefaults();
|
||||
return audio->play3d( sample,pos,vel );
|
||||
}
|
||||
|
||||
void gxSound::setLoop( bool loop ){
|
||||
FSOUND_Sample_SetMode( sample,loop ? FSOUND_LOOP_NORMAL : FSOUND_LOOP_OFF );
|
||||
}
|
||||
|
||||
void gxSound::setPitch( int hertz ){
|
||||
def_freq=hertz;
|
||||
defs_valid=false;
|
||||
}
|
||||
|
||||
void gxSound::setVolume( float volume ){
|
||||
def_vol=volume*255.0f;
|
||||
defs_valid=false;
|
||||
}
|
||||
|
||||
void gxSound::setPan( float pan ){
|
||||
def_pan=(pan+1.0f)*127.5f;
|
||||
defs_valid=false;
|
||||
}
|
||||
|
||||
@@ -1,38 +0,0 @@
|
||||
|
||||
#ifndef GXSOUND_H
|
||||
#define GXSOUND_H
|
||||
|
||||
#include "gxchannel.hpp"
|
||||
|
||||
class gxAudio;
|
||||
struct FSOUND_SAMPLE;
|
||||
|
||||
class gxSound{
|
||||
public:
|
||||
gxAudio *audio;
|
||||
|
||||
gxSound( gxAudio *audio,FSOUND_SAMPLE *sample );
|
||||
~gxSound();
|
||||
|
||||
private:
|
||||
bool defs_valid;
|
||||
int def_freq,def_vol,def_pan,def_pri;
|
||||
FSOUND_SAMPLE *sample;
|
||||
float pos[3],vel[3];
|
||||
|
||||
void setDefaults();
|
||||
|
||||
/***** GX INTERFACE *****/
|
||||
public:
|
||||
//actions
|
||||
gxChannel *play();
|
||||
gxChannel *play3d( const float pos[3],const float vel[3] );
|
||||
|
||||
//modifiers
|
||||
void setLoop( bool loop );
|
||||
void setPitch( int hertz );
|
||||
void setVolume( float volume );
|
||||
void setPan( float pan );
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -1,31 +0,0 @@
|
||||
|
||||
#include "std.hpp"
|
||||
#include "gxtimer.hpp"
|
||||
#include "gxruntime.hpp"
|
||||
|
||||
gxTimer::gxTimer( gxRuntime *rt,int hertz ):
|
||||
runtime(rt),ticks_get(0),ticks_put(0){
|
||||
event=CreateEvent( 0,false,false,0 );
|
||||
timerID=timeSetEvent( 1000/hertz,0,timerCallback,(DWORD)this,TIME_PERIODIC );
|
||||
}
|
||||
|
||||
gxTimer::~gxTimer(){
|
||||
timeKillEvent( timerID );
|
||||
CloseHandle( event );
|
||||
}
|
||||
|
||||
void CALLBACK gxTimer::timerCallback( UINT id,UINT msg,DWORD user,DWORD dw1,DWORD dw2 ){
|
||||
gxTimer *t=(gxTimer*)user;
|
||||
++t->ticks_put;
|
||||
SetEvent( t->event );
|
||||
}
|
||||
|
||||
int gxTimer::wait(){
|
||||
for(;;){
|
||||
if( WaitForSingleObject( event,1000 )==WAIT_OBJECT_0 ) break;
|
||||
}
|
||||
int n=ticks_put-ticks_get;
|
||||
ticks_get+=n;
|
||||
return n;
|
||||
}
|
||||
|
||||
@@ -1,27 +0,0 @@
|
||||
|
||||
#ifndef GXTIMER_H
|
||||
#define GXTIMER_H
|
||||
|
||||
#include <mmsyscom.h>
|
||||
|
||||
class gxRuntime;
|
||||
|
||||
class gxTimer{
|
||||
public:
|
||||
gxTimer( gxRuntime *rt,int hertz );
|
||||
~gxTimer();
|
||||
|
||||
static void CALLBACK timerCallback( UINT id,UINT msg,DWORD user,DWORD dw1,DWORD dw2 );
|
||||
|
||||
private:
|
||||
gxRuntime *runtime;
|
||||
HANDLE event;
|
||||
MMRESULT timerID;
|
||||
int ticks_put,ticks_get;
|
||||
|
||||
/***** GX INTERFACE *****/
|
||||
public:
|
||||
int wait();
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -1,2 +0,0 @@
|
||||
|
||||
#include "std.hpp"
|
||||
@@ -1,25 +0,0 @@
|
||||
|
||||
#ifndef STD_H
|
||||
#define STD_H
|
||||
|
||||
#include "stdutil.hpp"
|
||||
|
||||
#pragma warning( disable:4786 )
|
||||
|
||||
#define DIRECTSOUND_VERSION 0x700
|
||||
|
||||
#include <set>
|
||||
#include <map>
|
||||
#include <list>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
|
||||
#include <math.h>
|
||||
#include <windows.h>
|
||||
#include "GraphicsRuntime.hpp"
|
||||
|
||||
using namespace std;
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user