runtime: CMake-ify gx

This commit is contained in:
Michael Fabian 'Xaymar' Dirks
2019-01-18 17:03:37 +01:00
parent 28598fae6b
commit a16218e1d5
74 changed files with 6493 additions and 5286 deletions
-74
View File
@@ -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
}
}
-330
View File
@@ -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
-566
View File
@@ -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;
}
-57
View File
@@ -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
-47
View File
@@ -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);
-286
View File
@@ -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;
}
-48
View File
@@ -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
-739
View File
@@ -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];
}
-138
View File
@@ -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
-6
View File
@@ -1,6 +0,0 @@
#include "std.hpp"
#include "gxchannel.hpp"
gxChannel::~gxChannel(){
}
-21
View File
@@ -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
-62
View File
@@ -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];
}
-40
View File
@@ -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
-20
View File
@@ -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;
}
-22
View File
@@ -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
-83
View File
@@ -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;
}
-37
View File
@@ -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
-71
View File
@@ -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;
}
-42
View File
@@ -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
-611
View File
@@ -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;
}
-126
View File
@@ -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
-335
View File
@@ -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;
}
-46
View File
@@ -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;
};
-60
View File
@@ -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;
}
-33
View File
@@ -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
-107
View File
@@ -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 );
}
-73
View File
@@ -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
-48
View File
@@ -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;
}
-40
View File
@@ -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
-57
View File
@@ -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;
}
-34
View File
@@ -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
-143
View File
@@ -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
-619
View File
@@ -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;
}
-157
View File
@@ -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
-51
View File
@@ -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;
}
-38
View File
@@ -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
-31
View File
@@ -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;
}
-27
View File
@@ -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
-2
View File
@@ -1,2 +0,0 @@
#include "std.hpp"
-25
View File
@@ -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