Complete disaster-recovery snapshot: engine/game source, game data assets, VC6 toolchain + DX SDKs, build outputs, deployed game, and _UNUSED archive. Large binaries in Git LFS; text preserved byte-for-byte (core.autocrlf=false, no eol attributes). See RECOVERY.md for the one-clone rebuild procedure.
1438 lines
37 KiB
C++
1438 lines
37 KiB
C++
#define STRICT
|
|
#define D3D_OVERLOADS
|
|
#include <math.h>
|
|
#include <d3d.h>
|
|
#include <malloc.h>
|
|
#include <stdio.h>
|
|
//#include "directx.hpp"
|
|
#include "dxrasterizer.hpp"
|
|
#define SAFE_RELEASE(p) { if(p) { (p)->Release(); (p)=NULL; } }
|
|
|
|
#include "render.hpp"
|
|
|
|
static LPDIRECTDRAWSURFACE7 CreateATextureFromFile(LPDIRECTDRAW7 pDD, CHAR* strName );
|
|
static LPDIRECTDRAWSURFACE7 CreateRGBATextureFromFile(LPDIRECTDRAW7 pDD,CHAR* strName ,CHAR* strNamea,int bitcount=16);
|
|
static LPDIRECTDRAWSURFACE7 CreateSurfaceFromFile( LPDIRECTDRAW7 pdd,CHAR* strName );
|
|
static LPDIRECTDRAWSURFACE7 CreateTargetTexture(LPDIRECTDRAW7 pDD,DWORD tresx,DWORD tresy);
|
|
static LPDIRECTDRAWSURFACE7 CreateRGBATexture(LPDIRECTDRAW7 pDD,DWORD dwWidth,DWORD dwHeight,int bitcount=16);
|
|
static LPDIRECTDRAWSURFACE7 CreateRGBA16TextureFromBitmap(LPDIRECTDRAW7 pDD,HBITMAP hbm ,HBITMAP hbma);
|
|
static LPDIRECTDRAWSURFACE7 CreateRGBA32TextureFromBitmap(LPDIRECTDRAW7 pDD,HBITMAP hbm ,HBITMAP hbma);
|
|
static LPDIRECTDRAWSURFACE7 CreateATextureFromBitmap(LPDIRECTDRAW7 pDD,HBITMAP hbm );
|
|
static LPDIRECTDRAWSURFACE7 CreatePixelFormatTexture(LPDIRECTDRAW7 pDD,DWORD dwWidth,DWORD dwHeight,const DDPIXELFORMAT* pformat );
|
|
|
|
const DDPIXELFORMAT DDPF_R4G4B4A4=
|
|
{
|
|
sizeof(DDPIXELFORMAT),
|
|
DDPF_ALPHAPIXELS|DDPF_RGB,
|
|
0,
|
|
16,
|
|
0x0F00,
|
|
0x00F0,
|
|
0x000F,
|
|
0xF000
|
|
};
|
|
|
|
const DDPIXELFORMAT DDPF_R8G8B8A8=
|
|
{
|
|
sizeof(DDPIXELFORMAT),
|
|
DDPF_ALPHAPIXELS|DDPF_RGB,
|
|
0,
|
|
32,
|
|
0x00FF0000,
|
|
0x0000FF00,
|
|
0x000000FF,
|
|
0xFF000000
|
|
};
|
|
|
|
const DDPIXELFORMAT DDPF_R5G6B5=
|
|
{
|
|
sizeof(DDPIXELFORMAT),
|
|
DDPF_RGB,
|
|
0,
|
|
16,
|
|
0xF800,
|
|
0x07E0,
|
|
0x001F,
|
|
};
|
|
|
|
|
|
//Utility Functions
|
|
static LPVOID GetSurfacePointer(LPDIRECTDRAWSURFACE7 psurf)
|
|
{
|
|
DDSURFACEDESC2 desc={0,};
|
|
desc.dwSize=sizeof(desc);
|
|
|
|
psurf->Lock(NULL,&desc,DDLOCK_WAIT ,NULL);
|
|
return desc.lpSurface;
|
|
}
|
|
|
|
static void ReleaseSurfacePointer(LPDIRECTDRAWSURFACE7 psurf)
|
|
{
|
|
psurf->Unlock(NULL);
|
|
}
|
|
|
|
static bool IsTextureDimension(int n)
|
|
{
|
|
for(int i=5;i<10;i++)
|
|
if(n==(1<<i))return true;
|
|
return false;
|
|
}
|
|
|
|
static LPDIRECTDRAWSURFACE7 CreateRGBATexture(LPDIRECTDRAW7 pDD,DWORD dwWidth,DWORD dwHeight,int bitcount)
|
|
{
|
|
if(!(bitcount==16 || bitcount==32))return NULL;
|
|
|
|
LPDIRECTDRAWSURFACE7 pddsTexture;
|
|
HRESULT hr;
|
|
|
|
DDSURFACEDESC2 ddsd;
|
|
ZeroMemory( &ddsd, sizeof(DDSURFACEDESC2) );
|
|
ddsd.dwSize = sizeof(DDSURFACEDESC2);
|
|
ddsd.dwFlags = DDSD_CAPS|DDSD_HEIGHT|DDSD_WIDTH|DDSD_PIXELFORMAT|DDSD_TEXTURESTAGE;
|
|
ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
|
|
ddsd.dwWidth = dwWidth;
|
|
ddsd.dwHeight = dwHeight;
|
|
ddsd.ddsCaps.dwCaps2 = DDSCAPS2_TEXTUREMANAGE;
|
|
ddsd.ddpfPixelFormat = bitcount==16 ? DDPF_R4G4B4A4:DDPF_R8G8B8A8;
|
|
|
|
|
|
if( FAILED( hr = pDD->CreateSurface( &ddsd, &pddsTexture, NULL ) ) ){
|
|
return NULL;
|
|
}
|
|
return pddsTexture;
|
|
}
|
|
|
|
static LPDIRECTDRAWSURFACE7 CreatePixelFormatTexture(LPDIRECTDRAW7 pDD,DWORD dwWidth,DWORD dwHeight,const DDPIXELFORMAT* pformat )
|
|
{
|
|
LPDIRECTDRAWSURFACE7 pddsTexture;
|
|
HRESULT hr;
|
|
|
|
DDSURFACEDESC2 ddsd;
|
|
ZeroMemory( &ddsd, sizeof(DDSURFACEDESC2) );
|
|
ddsd.dwSize = sizeof(DDSURFACEDESC2);
|
|
ddsd.dwFlags = DDSD_CAPS|DDSD_HEIGHT|DDSD_WIDTH|DDSD_PIXELFORMAT|DDSD_TEXTURESTAGE;
|
|
ddsd.ddsCaps.dwCaps = DDSCAPS_TEXTURE;
|
|
ddsd.dwWidth = dwWidth;
|
|
ddsd.dwHeight = dwHeight;
|
|
ddsd.ddsCaps.dwCaps2 = DDSCAPS2_TEXTUREMANAGE;
|
|
ddsd.ddpfPixelFormat = *pformat;
|
|
|
|
|
|
if( FAILED( hr = pDD->CreateSurface( &ddsd, &pddsTexture, NULL ) ) ){
|
|
return NULL;
|
|
}
|
|
return pddsTexture;
|
|
}
|
|
|
|
static bool IsValidAlphaPair( DIBSECTION& dib,DIBSECTION& diba)
|
|
{
|
|
BITMAP& bm=dib.dsBm;
|
|
BITMAP& bma=diba.dsBm;
|
|
int w=bm.bmWidth;
|
|
int h=bm.bmHeight;
|
|
|
|
if(dib.dsBmih.biHeight<0 || diba.dsBmih.biHeight<0)return false;
|
|
|
|
//픽셀 포맷을 일단 만족하는가?
|
|
if(!(bm.bmBitsPixel==24 && bma.bmBitsPixel==8))return false;
|
|
|
|
//비트맵의 크기가 X,Y모두 2의 지수승인가?
|
|
if(!(IsTextureDimension(w) && IsTextureDimension(h)))return false;
|
|
|
|
//RGB와 A비트맵의 크기가 같은가?
|
|
if(bma.bmWidth!=w || bma.bmHeight!=h)return NULL;
|
|
|
|
return true;
|
|
}
|
|
|
|
//Main Functions
|
|
LPDIRECTDRAWSURFACE7 CreateRGBA16TextureFromBitmap(LPDIRECTDRAW7 pDD,HBITMAP hbm ,HBITMAP hbma)
|
|
{
|
|
DIBSECTION dib,diba;
|
|
if(GetObject(hbm,sizeof(DIBSECTION),&dib)!=sizeof(DIBSECTION))return NULL;
|
|
if(GetObject(hbma,sizeof(DIBSECTION),&diba)!=sizeof(DIBSECTION))return NULL;
|
|
BITMAP& bm=dib.dsBm;
|
|
BITMAP& bma=diba.dsBm;
|
|
int w=bm.bmWidth;
|
|
int h=bm.bmHeight;
|
|
|
|
if(!IsValidAlphaPair(dib,diba))return NULL;
|
|
|
|
LPDIRECTDRAWSURFACE7 pddsTexture;
|
|
pddsTexture=CreateRGBATexture(pDD,w,h,16);
|
|
|
|
if(pddsTexture)return NULL;
|
|
|
|
// Get a DC for the bitmap
|
|
BYTE* bits = (BYTE*)bm.bmBits;
|
|
BYTE* bitsa = (BYTE*)bma.bmBits;
|
|
|
|
WORD* bit=(WORD*)GetSurfacePointer(pddsTexture);
|
|
DWORD wA,wR,wG,wB;
|
|
|
|
bits+=bm.bmWidthBytes*(h-1);
|
|
bitsa+=bma.bmWidthBytes*(h-1);
|
|
for(int y=0; y < h; y++ ){
|
|
BYTE* b=bits;
|
|
for(int x=0; x < w; x++ ){
|
|
wA= bitsa[x];
|
|
wA= (wA<<8)&0xF000;
|
|
|
|
wB=*b++;
|
|
wG=*b++;
|
|
wR=*b++;
|
|
wR=(wR<<4)&0x0F00;
|
|
wG=(wG)&0x00F0;
|
|
wB=(wB>>4);
|
|
*bit++=(WORD)(wA|wR|wG|wB);
|
|
}
|
|
bits-=bm.bmWidthBytes;
|
|
bitsa-=bma.bmWidthBytes;
|
|
}
|
|
ReleaseSurfacePointer(pddsTexture);
|
|
|
|
//delete data;
|
|
return pddsTexture;
|
|
}
|
|
|
|
//Main Functions
|
|
LPDIRECTDRAWSURFACE7 CreateRGBA32TextureFromBitmap(LPDIRECTDRAW7 pDD,HBITMAP hbm ,HBITMAP hbma)
|
|
{
|
|
DIBSECTION dib,diba;
|
|
if(GetObject(hbm,sizeof(DIBSECTION),&dib)!=sizeof(DIBSECTION))return NULL;
|
|
if(GetObject(hbma,sizeof(DIBSECTION),&diba)!=sizeof(DIBSECTION))return NULL;
|
|
BITMAP& bm=dib.dsBm;
|
|
BITMAP& bma=diba.dsBm;
|
|
int w=bm.bmWidth;
|
|
int h=bm.bmHeight;
|
|
|
|
if(!IsValidAlphaPair(dib,diba))return NULL;
|
|
|
|
LPDIRECTDRAWSURFACE7 pddsTexture;
|
|
pddsTexture=CreateRGBATexture(pDD,w,h,32);
|
|
|
|
if(pddsTexture)return NULL;
|
|
|
|
// Get a DC for the bitmap
|
|
BYTE* bits = (BYTE*)bm.bmBits;
|
|
BYTE* bitsa = (BYTE*)bma.bmBits;
|
|
|
|
DWORD* bit=(DWORD*)GetSurfacePointer(pddsTexture);
|
|
DWORD wA,wR,wG,wB;
|
|
|
|
bits+=bm.bmWidthBytes*(h-1);
|
|
bitsa+=bma.bmWidthBytes*(h-1);
|
|
for(int y=0; y < h; y++ ){
|
|
BYTE* b=bits;
|
|
for(int x=0; x < w; x++ ){
|
|
wA= bitsa[x];
|
|
wB=*b++;
|
|
wG=*b++;
|
|
wR=*b++;
|
|
*bit++ = (wA<<24)|(wR<<16)|(wG<<8)|wB;
|
|
}
|
|
bits-=bm.bmWidthBytes;
|
|
bitsa-=bma.bmWidthBytes;
|
|
}
|
|
ReleaseSurfacePointer(pddsTexture);
|
|
|
|
//delete data;
|
|
return pddsTexture;
|
|
}
|
|
|
|
LPDIRECTDRAWSURFACE7 CreateRGBATextureFromFile(LPDIRECTDRAW7 pDD,CHAR* strName ,CHAR* strNamea,int bitcount)
|
|
{
|
|
HBITMAP hbm,hbma;
|
|
LPDIRECTDRAWSURFACE7 t=NULL;
|
|
hbm = (HBITMAP)LoadImage( NULL, strName, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE|LR_CREATEDIBSECTION );
|
|
if(hbm ){
|
|
hbma = (HBITMAP)LoadImage( NULL, strNamea, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE|LR_CREATEDIBSECTION );
|
|
if(hbma){
|
|
if(bitcount==16){
|
|
t=CreateRGBA16TextureFromBitmap(pDD,hbm,hbma);
|
|
}else{
|
|
t=CreateRGBA32TextureFromBitmap(pDD,hbm,hbma);
|
|
}//else t==NULL;
|
|
DeleteObject(hbma);
|
|
}
|
|
DeleteObject(hbm);
|
|
}
|
|
return t;
|
|
}
|
|
|
|
static LPDIRECTDRAWSURFACE7 CreateTargetTexture(LPDIRECTDRAW7 pDD,DWORD tresx,DWORD tresy)
|
|
{
|
|
LPDIRECTDRAWSURFACE7 pddsTexture;
|
|
HRESULT hr;
|
|
|
|
DDSURFACEDESC2 ddsd;
|
|
ZeroMemory( &ddsd, sizeof(DDSURFACEDESC2) );
|
|
ddsd.dwSize = sizeof(DDSURFACEDESC2);
|
|
ddsd.dwFlags = DDSD_CAPS|DDSD_HEIGHT|DDSD_WIDTH|DDSD_TEXTURESTAGE;
|
|
ddsd.ddsCaps.dwCaps = DDSCAPS_VIDEOMEMORY |DDSCAPS_TEXTURE|DDSCAPS_3DDEVICE;
|
|
ddsd.dwWidth = tresx;
|
|
ddsd.dwHeight = tresy;
|
|
// ddsd.ddsCaps.dwCaps2 = DDSCAPS2_TEXTUREMANAGE;
|
|
|
|
|
|
if( FAILED( hr = pDD->CreateSurface( &ddsd, &pddsTexture, NULL ) ) )
|
|
return NULL;
|
|
|
|
return pddsTexture;
|
|
}
|
|
|
|
|
|
static LPDIRECTDRAWSURFACE7 CreateSurfaceFromFile( LPDIRECTDRAW7 pdd,CHAR* strName )
|
|
{
|
|
|
|
HBITMAP hbm;
|
|
BITMAP bm;
|
|
DDSURFACEDESC2 ddsd;
|
|
LPDIRECTDRAWSURFACE7 pddsTexture;
|
|
|
|
hbm = (HBITMAP)LoadImage( NULL, strName, IMAGE_BITMAP, 0, 0,LR_LOADFROMFILE|LR_CREATEDIBSECTION );
|
|
|
|
GetObject( hbm, sizeof(BITMAP), &bm );
|
|
|
|
ZeroMemory( &ddsd, sizeof(DDSURFACEDESC2) );
|
|
ddsd.dwSize = sizeof(DDSURFACEDESC2);
|
|
ddsd.dwFlags = DDSD_HEIGHT|DDSD_WIDTH|DDSD_CAPS;
|
|
ddsd.ddsCaps.dwCaps = DDSCAPS_VIDEOMEMORY |DDSCAPS_OFFSCREENPLAIN;
|
|
ddsd.dwWidth = bm.bmWidth;
|
|
ddsd.dwHeight = bm.bmHeight;
|
|
|
|
pdd->CreateSurface( &ddsd, &pddsTexture, NULL ) ;
|
|
|
|
// Get a DC for the bitmap
|
|
|
|
HDC hdcBitmap = CreateCompatibleDC( NULL );
|
|
HBITMAP holdbitmap=(HBITMAP)SelectObject( hdcBitmap, hbm );
|
|
|
|
HDC hdcTexture;
|
|
pddsTexture->GetDC( &hdcTexture );
|
|
BitBlt( hdcTexture, 0, 0, bm.bmWidth, bm.bmHeight, hdcBitmap,0, 0, SRCCOPY );
|
|
pddsTexture->ReleaseDC( hdcTexture );
|
|
SelectObject(hdcBitmap,holdbitmap);
|
|
DeleteObject(hbm);
|
|
DeleteDC( hdcBitmap );
|
|
|
|
return pddsTexture;
|
|
}
|
|
|
|
|
|
bool DrawBitmapToSurface(LPDIRECTDRAWSURFACE7 pddsTexture,int x,int y,const char* strName )
|
|
{
|
|
HBITMAP hbm;
|
|
hbm = (HBITMAP)LoadImage( NULL, strName, IMAGE_BITMAP, 0, 0,LR_LOADFROMFILE|LR_CREATEDIBSECTION );
|
|
|
|
BITMAP bm;
|
|
GetObject( hbm, sizeof(BITMAP), &bm );
|
|
|
|
HDC hdcBitmap = CreateCompatibleDC( NULL );
|
|
HBITMAP holdbitmap=(HBITMAP)SelectObject( hdcBitmap, hbm );
|
|
|
|
HDC hdcTexture;
|
|
pddsTexture->GetDC( &hdcTexture );
|
|
BitBlt( hdcTexture, x, y, bm.bmWidth, bm.bmHeight, hdcBitmap,0, 0, SRCCOPY );
|
|
pddsTexture->ReleaseDC( hdcTexture );
|
|
SelectObject(hdcBitmap,holdbitmap);
|
|
DeleteObject(hbm);
|
|
DeleteDC( hdcBitmap );
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//8Bit Bitmap으로부터.. Alpha를 가진 텍스쳐를 만든다.
|
|
static LPDIRECTDRAWSURFACE7 CreateATextureFromBitmap(LPDIRECTDRAW7 pDD,HBITMAP hbm )
|
|
{
|
|
BITMAP bm={0,};
|
|
GetObject(hbm,sizeof(bm),&bm);
|
|
DWORD w=bm.bmWidth;
|
|
DWORD h=bm.bmHeight;
|
|
|
|
LPDIRECTDRAWSURFACE7 pddsTexture;
|
|
pddsTexture=CreateRGBATexture(pDD,w,h,16);
|
|
|
|
BYTE* data=(BYTE*)bm.bmBits;
|
|
|
|
WORD* bits=(WORD*)GetSurfacePointer(pddsTexture);
|
|
|
|
|
|
data+=bm.bmWidthBytes*(h-1);
|
|
WORD wA;
|
|
for(DWORD y=0; y < h; y++ ){
|
|
for(DWORD x=0; x < w; x++ ){
|
|
wA= data[x];
|
|
WORD wBit=(WORD)((wA<<8)&0xF000|0x0FFF);
|
|
*bits++=(WORD)((wA>0)?wBit:0);
|
|
|
|
}
|
|
data-=bm.bmWidthBytes;
|
|
}
|
|
ReleaseSurfacePointer(pddsTexture);
|
|
|
|
return pddsTexture;
|
|
}
|
|
|
|
LPDIRECTDRAWSURFACE7 CreateATextureFromFile(LPDIRECTDRAW7 pDD, CHAR* strName )
|
|
{
|
|
HBITMAP hbm;
|
|
hbm = (HBITMAP)LoadImage( NULL, strName, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE|LR_CREATEDIBSECTION );
|
|
if( NULL == hbm ){
|
|
return NULL;
|
|
}
|
|
|
|
LPDIRECTDRAWSURFACE7 t;
|
|
t=CreateATextureFromBitmap( pDD, hbm );
|
|
DeleteObject(hbm);
|
|
return t;
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//realize static member variable...
|
|
D3DTLVERTEX CHSHFont::m_pVB[300];
|
|
|
|
|
|
|
|
|
|
|
|
/////////////////////////////////// CHSH_Device ///////////////////////////////////
|
|
|
|
void CHSH_Device::SetRenderTargetBackbuffer()
|
|
{
|
|
LPDIRECTDRAWSURFACE7 target;
|
|
pD3DDevice->GetRenderTarget(&target);
|
|
|
|
if(target!=pDDSBack){
|
|
pD3DDevice->SetRenderTarget(pDDSBack,0);
|
|
D3DVIEWPORT7 vp = { 0, 0, size_back.cx, size_back.cy, 0.0f, 1.0f };
|
|
pD3DDevice->SetViewport( &vp );
|
|
}
|
|
}
|
|
|
|
|
|
void CHSH_Device::SetRenderTargetTexture()
|
|
{
|
|
LPDIRECTDRAWSURFACE7 target;
|
|
pD3DDevice->GetRenderTarget(&target);
|
|
|
|
if(target!=pDDSTarget){
|
|
pD3DDevice->SetRenderTarget(pDDSTarget,0);
|
|
D3DVIEWPORT7 vp = { 0, 0, size_target.cx, size_target.cy, 0.0f, 1.0f };
|
|
pD3DDevice->SetViewport( &vp );
|
|
}
|
|
}
|
|
|
|
|
|
CHSH_Device::CHSH_Device()
|
|
{
|
|
pDD=0;
|
|
pDDSFront=0;
|
|
pDDSBack=0;
|
|
pDDSTarget=0;
|
|
pD3DDevice=0;
|
|
}
|
|
|
|
#pragma warning(disable:4100)
|
|
#pragma warning(disable:4505)
|
|
|
|
const DWORD dwFlags = DDSCL_SETFOCUSWINDOW | DDSCL_CREATEDEVICEWINDOW |
|
|
DDSCL_ALLOWREBOOT | DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN;
|
|
|
|
extern HRESULT wDirectDrawCreateEx( GUID* lpGUID, void** lplpDD, REFIID iid, IUnknown* pUnkOuter );
|
|
|
|
bool CHSH_Device::Init(int devicenum,DWORD resx,DWORD resy,DWORD tresx,DWORD tresy,char* textureimage)
|
|
{
|
|
HRESULT hr;
|
|
|
|
//1. 해상도 변경.
|
|
wDirectDrawCreateEx( &DeviceArray[devicenum].DeviceGUID , (VOID**) &(pDD), IID_IDirectDraw7, NULL );
|
|
pDD->SetCooperativeLevel(hWindow, dwFlags );
|
|
hr=pDD->SetDisplayMode( resx, resy, 16, 60, 0 );
|
|
|
|
//2. Create Surfaces(Primary,Back,BackgroundImage,Texture)
|
|
//////Front Buffer
|
|
DDSURFACEDESC2 ddsd={0,};
|
|
DDSCAPS2 ddsCaps;
|
|
|
|
ddsd.dwSize = sizeof(ddsd);
|
|
ddsd.dwFlags = DDSD_BACKBUFFERCOUNT | DDSD_CAPS;
|
|
ddsd.dwBackBufferCount = 1;
|
|
ddsd.ddsCaps.dwCaps = DDSCAPS_COMPLEX | DDSCAPS_FLIP | DDSCAPS_PRIMARYSURFACE| DDSCAPS_3DDEVICE;
|
|
|
|
pDD->CreateSurface( &ddsd, &pDDSFront, NULL );
|
|
|
|
|
|
//////BackBuffer
|
|
ZeroMemory( &ddsCaps, sizeof(ddsCaps) );
|
|
ddsCaps.dwCaps = DDSCAPS_BACKBUFFER;
|
|
pDDSFront->GetAttachedSurface( &ddsCaps, &pDDSBack );
|
|
|
|
//////3D Device
|
|
LPDIRECT3D7 pD3D;
|
|
pDD->QueryInterface( IID_IDirect3D7, (VOID**)&(pD3D) );
|
|
pD3D->CreateDevice(IID_IDirect3DHALDevice,pDDSBack,&pD3DDevice);
|
|
pD3D->Release();
|
|
|
|
D3DVIEWPORT7 vp = { 0, 0, resx, resy, 0.0f, 1.0f };
|
|
pD3DDevice->SetViewport( &vp );
|
|
|
|
//////Texture
|
|
char temppath[MAX_PATH];
|
|
printf(temppath,"%s\\hsh\\%s",AssetsDirectory1,textureimage);
|
|
pDDSTexture=CreateATextureFromFile(pDD, temppath);
|
|
|
|
//3. Create Target Buffer(Texture)
|
|
pDDSTarget=CreateTargetTexture(pDD,tresx,tresy);
|
|
|
|
//4. Create Font Objects
|
|
|
|
pFont[0].Init(pDD,pD3DDevice,"Arial",30,false,false);
|
|
pFont[1].Init(pDD,pD3DDevice,"Arial",40,false,false);
|
|
pFont[2].Init(pDD,pD3DDevice,"Arial",50,false,false);
|
|
|
|
//5. Etc
|
|
size_back.cx=resx;
|
|
size_back.cy=resy;
|
|
size_target.cx=tresx;
|
|
size_target.cy=tresy;
|
|
|
|
return true;//success
|
|
}
|
|
|
|
bool CHSH_Device::Release()
|
|
{
|
|
if(pDD){
|
|
for(int i=0;i<3;i++)pFont[i].Cleanup();
|
|
|
|
SAFE_RELEASE(pDDSTarget);
|
|
SAFE_RELEASE(pD3DDevice);
|
|
SAFE_RELEASE(pDDSBack);
|
|
SAFE_RELEASE(pDDSFront);
|
|
|
|
pDD->RestoreDisplayMode();
|
|
pDD->SetCooperativeLevel(hWindow, DDSCL_NORMAL);
|
|
pDD->Release();
|
|
}
|
|
return true;
|
|
}
|
|
|
|
void CHSH_Device::DrawQuad(int x1,int y1,int x2,int y2,DWORD dwColor)
|
|
{
|
|
D3DTLVERTEX Vertices[4]; // Vertices for the cube
|
|
|
|
Vertices[0] = D3DTLVERTEX(D3DVECTOR( (float)x1-0.5f, (float)y2-0.5f,0.9f),1.0f,dwColor,0, 0.0f, 1.0f );
|
|
Vertices[1] = D3DTLVERTEX(D3DVECTOR( (float)x1-0.5f, (float)y1-0.5f,0.9f),1.0f,dwColor,0, 0.0f, 0.0f );
|
|
Vertices[2] = D3DTLVERTEX(D3DVECTOR( (float)x2-0.5f, (float)y2-0.5f,0.9f),1.0f,dwColor,0, 1.0f, 1.0f );
|
|
Vertices[3] = D3DTLVERTEX(D3DVECTOR( (float)x2-0.5f, (float)y1-0.5f,0.9f),1.0f,dwColor,0, 1.0f, 0.0f );
|
|
|
|
pD3DDevice->DrawPrimitive( D3DPT_TRIANGLESTRIP, D3DFVF_TLVERTEX , Vertices, 4, NULL );
|
|
}
|
|
|
|
void CHSH_Device::DrawQuadList(int quadcount,RECT * prc,DWORD dwColor)
|
|
{
|
|
int cvertex=quadcount*6;
|
|
D3DTLVERTEX *Vertices=(D3DTLVERTEX*)malloc(cvertex*sizeof(D3DTLVERTEX));
|
|
|
|
//012 213
|
|
for(int i=0,n=0;i<quadcount;i++,prc++){
|
|
int x1=prc->left;
|
|
int y1=prc->top;
|
|
int x2=prc->right;
|
|
int y2=prc->bottom;
|
|
Vertices[n++] = D3DTLVERTEX(D3DVECTOR( (float)x1-0.5f, (float)y2-0.5f,0.9f),1.0f,dwColor,0, 0.0f, 1.0f );//0
|
|
Vertices[n++] = D3DTLVERTEX(D3DVECTOR( (float)x1-0.5f, (float)y1-0.5f,0.9f),1.0f,dwColor,0, 0.0f, 0.0f );//1
|
|
Vertices[n++] = D3DTLVERTEX(D3DVECTOR( (float)x2-0.5f, (float)y2-0.5f,0.9f),1.0f,dwColor,0, 1.0f, 1.0f );//2
|
|
Vertices[n++] = D3DTLVERTEX(D3DVECTOR( (float)x2-0.5f, (float)y2-0.5f,0.9f),1.0f,dwColor,0, 1.0f, 1.0f );//2
|
|
Vertices[n++] = D3DTLVERTEX(D3DVECTOR( (float)x1-0.5f, (float)y1-0.5f,0.9f),1.0f,dwColor,0, 0.0f, 0.0f );//1
|
|
Vertices[n++] = D3DTLVERTEX(D3DVECTOR( (float)x2-0.5f, (float)y1-0.5f,0.9f),1.0f,dwColor,0, 1.0f, 0.0f );//3
|
|
}
|
|
pD3DDevice->DrawPrimitive( D3DPT_TRIANGLESTRIP, D3DFVF_TLVERTEX , Vertices, cvertex, NULL );
|
|
free(Vertices);
|
|
}
|
|
|
|
void CHSH_Device::DrawLine(int x1,int y1,int x2,int y2,DWORD dwColor)
|
|
{
|
|
D3DTLVERTEX Vertices[2]; // Vertices for the cube
|
|
|
|
Vertices[0] = D3DTLVERTEX(D3DVECTOR( (float)x1, (float)y1,0.9f),1.0f,dwColor,0, 0.0f, 0.0f );
|
|
Vertices[1] = D3DTLVERTEX(D3DVECTOR( (float)x2, (float)y2,0.9f),1.0f,dwColor,0, 0.0f, 0.0f );
|
|
|
|
pD3DDevice->DrawPrimitive( D3DPT_LINESTRIP , D3DFVF_TLVERTEX , Vertices, 2, NULL );
|
|
}
|
|
|
|
void CHSH_Device::DrawLineStrip(int point_count,POINT* pts,DWORD dwColor)
|
|
{
|
|
D3DTLVERTEX *Vertices=(D3DTLVERTEX*)malloc(point_count*sizeof(D3DTLVERTEX));
|
|
|
|
for(int i=0;i<point_count;i++){
|
|
Vertices[i] =
|
|
D3DTLVERTEX(D3DVECTOR( (float)pts[i].x, (float)pts[i].y,0.9f),1.0f,dwColor,0, 0.0f, 0.0f );
|
|
}
|
|
|
|
pD3DDevice->DrawPrimitive( D3DPT_LINESTRIP , D3DFVF_TLVERTEX , Vertices, point_count, NULL );
|
|
free(Vertices);
|
|
}
|
|
|
|
void CHSH_Device::DrawLineList(int line_count,POINT* pts,DWORD dwColor)
|
|
{
|
|
int point_count=line_count*2;
|
|
D3DTLVERTEX *Vertices=(D3DTLVERTEX*)malloc(point_count*sizeof(D3DTLVERTEX));
|
|
|
|
for(int i=0;i<point_count;i++){
|
|
Vertices[i] =
|
|
D3DTLVERTEX(D3DVECTOR( (float)pts[i].x, (float)pts[i].y,0.9f),1.0f,dwColor,0, 0.0f, 0.0f );
|
|
}
|
|
|
|
pD3DDevice->DrawPrimitive( D3DPT_LINELIST , D3DFVF_TLVERTEX , Vertices, point_count, NULL );
|
|
free(Vertices);
|
|
}
|
|
|
|
void CHSH_Device::DrawFrame(int x1,int y1,int x2,int y2,DWORD dwColor)
|
|
{
|
|
D3DTLVERTEX Vertices[5]; // Vertices for the cube
|
|
|
|
Vertices[0] = D3DTLVERTEX(D3DVECTOR( (float)x1, (float)y1,0.9f),1.0f,dwColor,0, 0.0f, 1.0f );
|
|
Vertices[1] = D3DTLVERTEX(D3DVECTOR( (float)x2, (float)y1,0.9f),1.0f,dwColor,0, 0.0f, 0.0f );
|
|
Vertices[2] = D3DTLVERTEX(D3DVECTOR( (float)x2, (float)y2,0.9f),1.0f,dwColor,0, 1.0f, 1.0f );
|
|
Vertices[3] = D3DTLVERTEX(D3DVECTOR( (float)x1, (float)y2,0.9f),1.0f,dwColor,0, 1.0f, 0.0f );
|
|
Vertices[4] = D3DTLVERTEX(D3DVECTOR( (float)x1, (float)y1,0.9f),1.0f,dwColor,0, 1.0f, 0.0f );
|
|
|
|
pD3DDevice->DrawPrimitive( D3DPT_LINESTRIP, D3DFVF_TLVERTEX , Vertices, 5, NULL );
|
|
}
|
|
|
|
void CHSH_Device::DrawFrameList(int framecount,RECT * prc,DWORD dwColor)
|
|
{
|
|
int point_count=framecount*8;
|
|
D3DTLVERTEX *Vertices=(D3DTLVERTEX*)malloc(point_count*sizeof(D3DTLVERTEX));
|
|
|
|
//0=7 / 1=2 / 3=4 / 5=6
|
|
|
|
D3DTLVERTEX *v=Vertices;
|
|
for(int i=0;i<framecount;i++,prc++,v+=8){
|
|
int x1=prc->left;
|
|
int y1=prc->top;
|
|
int x2=prc->right;
|
|
int y2=prc->bottom;
|
|
v[0]=v[7] = D3DTLVERTEX(D3DVECTOR( (float)x1, (float)y2,0.9f),1.0f,dwColor,0, 0.0f, 1.0f );//0
|
|
v[1]=v[2] = D3DTLVERTEX(D3DVECTOR( (float)x1, (float)y1,0.9f),1.0f,dwColor,0, 0.0f, 0.0f );//1
|
|
v[3]=v[4] = D3DTLVERTEX(D3DVECTOR( (float)x2, (float)y2,0.9f),1.0f,dwColor,0, 1.0f, 1.0f );//2
|
|
v[5]=v[6] = D3DTLVERTEX(D3DVECTOR( (float)x2, (float)y1,0.9f),1.0f,dwColor,0, 1.0f, 0.0f );//3
|
|
}
|
|
|
|
|
|
pD3DDevice->DrawPrimitive( D3DPT_LINELIST, D3DFVF_TLVERTEX , Vertices, point_count, NULL );
|
|
|
|
free(Vertices);
|
|
}
|
|
|
|
void CHSH_Device::DrawThickFrame(int x1,int y1,int x2,int y2,int t,DWORD dwColor)
|
|
{
|
|
if(t>1){
|
|
RECT rc[4]={
|
|
{x1 ,y1 ,x2 ,y1+t},
|
|
{x1 ,y2-t,x2 ,y2 },
|
|
{x1 ,y1 ,x1+t,y2 },
|
|
{x2-t,y1 ,x2 ,y2 }
|
|
};
|
|
DrawQuadList(4,rc,dwColor);
|
|
}
|
|
}
|
|
|
|
void CHSH_Device::DrawThickFrameList(int framecount,RECT* prc,int t,DWORD dwColor)
|
|
{
|
|
if(t>1){
|
|
int quadcount=framecount*4;
|
|
RECT* rc=(RECT*)malloc(sizeof(RECT)*quadcount);
|
|
|
|
for(int i=0;i<framecount;i++,prc++,rc+=4){
|
|
int x1=prc->left;
|
|
int y1=prc->top;
|
|
int x2=prc->right;
|
|
int y2=prc->bottom;
|
|
RECT r[4]={
|
|
{x1 ,y1 ,x2 ,y1+t},
|
|
{x1 ,y2-t,x2 ,y2 },
|
|
{x1 ,y1 ,x1+t,y2 },
|
|
{x2-t,y1 ,x2 ,y2 }
|
|
};
|
|
CopyMemory(rc,r,sizeof(r));
|
|
}
|
|
DrawQuadList(quadcount,rc,dwColor);
|
|
free(rc);
|
|
}
|
|
}
|
|
|
|
|
|
//texture 좌표.. u1,v1,u2,v2
|
|
//texture 회전축 tx,ty
|
|
//screen 회전축 x,y
|
|
//회전각 e
|
|
|
|
void CHSH_Device::DrawTextureRotate(float u1,float v1,float u2,float v2,float tx,float ty,float x,float y,float e)
|
|
{
|
|
float U1=u1-tx;
|
|
float V1=v1-ty;
|
|
float U2=u2-tx;
|
|
float V2=v2-ty;
|
|
|
|
//(U1,V1),(U2,V1),(U1,V2),(U2,V2)네쌍을 회전변환 시킨다.
|
|
//pt[0][0]....
|
|
//거기에.. 각 축에..x,y를 더해준다.
|
|
float cose=cosf(e);
|
|
float cos_u1=cose*U1;
|
|
float cos_u2=cose*U2;
|
|
float cos_v1=cose*V1;
|
|
float cos_v2=cose*V2;
|
|
float sine=sinf(e);
|
|
float sin_u1=sine*U1;
|
|
float sin_u2=sine*U2;
|
|
float sin_v1=sine*V1;
|
|
float sin_v2=sine*V2;
|
|
|
|
float pt[4][2];
|
|
pt[0][0] = cos_u1-sin_v1+x;
|
|
pt[0][1] = sin_u1-cos_v1+y;
|
|
pt[1][0] = cos_u2-sin_v1+x;
|
|
pt[1][1] = sin_u2-cos_v1+y;
|
|
pt[2][0] = cos_u1-sin_v2+x;
|
|
pt[2][1] = sin_u1-cos_v2+y;
|
|
pt[3][0] = cos_u2-sin_v2+x;
|
|
pt[3][1] = sin_u2-cos_v2+y;
|
|
|
|
//HSH_Draw3DTexture2(0,pt,0xFF00FF00,u1, v1/256.0f, u2/256.0f, v2/256.0f);
|
|
//거기에다가 모두 x,y를 다시 이동 시킨다.
|
|
}
|
|
|
|
|
|
|
|
//임의로 스케일된다. x1,y1,x2,y2
|
|
void CHSH_Device::DrawTexture(float x1,float y1,float x2,float y2,DWORD dwColor, float u1,float v1,float u2,float v2)
|
|
{
|
|
|
|
D3DTLVERTEX v[4];
|
|
v[0] = D3DTLVERTEX(D3DVECTOR(x1-0.5f,y2-0.5f,0.9f),1.0f, dwColor,0, u1, v2 );
|
|
v[1] = D3DTLVERTEX(D3DVECTOR(x1-0.5f,y1-0.5f,0.9f),1.0f, dwColor,0, u1, v1 );
|
|
v[2] = D3DTLVERTEX(D3DVECTOR(x2-0.5f,y2-0.5f,0.9f),1.0f, dwColor,0, u2, v2 );
|
|
v[3] = D3DTLVERTEX(D3DVECTOR(x2-0.5f,y1-0.5f,0.9f),1.0f, dwColor,0, u2, v1 );
|
|
|
|
pD3DDevice->DrawPrimitive( D3DPT_TRIANGLESTRIP, D3DFVF_TLVERTEX ,v,6,0 );
|
|
}
|
|
|
|
//임의로 스케일된다. x,y,width,height
|
|
void CHSH_Device::DrawTexture2(float x,float y,float w,float h,DWORD dwColor, float u1,float v1,float u2,float v2)
|
|
{
|
|
|
|
D3DTLVERTEX v[4];
|
|
v[0] = D3DTLVERTEX(D3DVECTOR(x+0-0.5f,y+h-0.5f,0.9f),1.0f, dwColor,0, u1, v2 );
|
|
v[1] = D3DTLVERTEX(D3DVECTOR(x+0-0.5f,y+0-0.5f,0.9f),1.0f, dwColor,0, u1, v1 );
|
|
v[2] = D3DTLVERTEX(D3DVECTOR(x+w-0.5f,y+h-0.5f,0.9f),1.0f, dwColor,0, u2, v2 );
|
|
v[3] = D3DTLVERTEX(D3DVECTOR(x+w-0.5f,y+0-0.5f,0.9f),1.0f, dwColor,0, u2, v1 );
|
|
|
|
pD3DDevice->DrawPrimitive( D3DPT_TRIANGLESTRIP, D3DFVF_TLVERTEX ,v,6,0 );
|
|
}
|
|
|
|
|
|
//스케일 되지 않는....
|
|
void CHSH_Device::DrawTexture(float x,float y,DWORD dwColor, float u1,float v1,float u2,float v2)
|
|
{
|
|
D3DTLVERTEX v[4];
|
|
float w=u2-u1;
|
|
float h=v2-v1;
|
|
v[0] = D3DTLVERTEX(D3DVECTOR(x+0-0.5f,y+h-0.5f,0.9f),1.0f, dwColor,0, u1, v2 );
|
|
v[1] = D3DTLVERTEX(D3DVECTOR(x+0-0.5f,y+0-0.5f,0.9f),1.0f, dwColor,0, u1, v1 );
|
|
v[2] = D3DTLVERTEX(D3DVECTOR(x+w-0.5f,y+h-0.5f,0.9f),1.0f, dwColor,0, u2, v2 );
|
|
v[3] = D3DTLVERTEX(D3DVECTOR(x+w-0.5f,y+0-0.5f,0.9f),1.0f, dwColor,0, u2, v1 );
|
|
|
|
pD3DDevice->DrawPrimitive( D3DPT_TRIANGLESTRIP, D3DFVF_TLVERTEX ,v,6,0 );
|
|
}
|
|
|
|
|
|
void CHSH_Device::DrawTexture(float pt[4][2],DWORD dwColor,float tx1,float tx2,float ty1,float ty2)
|
|
{
|
|
D3DTLVERTEX v[4];
|
|
v[0] = D3DTLVERTEX(D3DVECTOR(pt[2][0]-0.5f, pt[2][1]-0.5f,0.9f),1.0f, dwColor,0, tx1, ty2 );
|
|
v[1] = D3DTLVERTEX(D3DVECTOR(pt[0][0]-0.5f, pt[0][1]-0.5f,0.9f),1.0f, dwColor,0, tx1, ty1 );
|
|
v[2] = D3DTLVERTEX(D3DVECTOR(pt[3][0]-0.5f, pt[3][1]-0.5f,0.9f),1.0f, dwColor,0, tx2, ty2 );
|
|
v[3] = D3DTLVERTEX(D3DVECTOR(pt[1][0]-0.5f, pt[1][1]-0.5f,0.9f),1.0f, dwColor,0, tx2, ty1 );
|
|
|
|
pD3DDevice->DrawPrimitive( D3DPT_TRIANGLESTRIP, D3DFVF_TLVERTEX ,v,6,0 );
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/////////////////////////////////// CRadar_Device ///////////////////////////////////
|
|
|
|
|
|
|
|
|
|
|
|
bool CRadar_Device::Init()
|
|
{
|
|
bool ret;
|
|
ret=CHSH_Device::Init(1,640,480,512,1024,"radar_texture1.bmp");
|
|
|
|
char temppath[MAX_PATH];
|
|
sprintf(temppath,"%s\\hsh\\%s",AssetsDirectory1,"radar_background.bmp");
|
|
pDDSBackground=CreateSurfaceFromFile(pDD,temppath);
|
|
|
|
return ret;
|
|
}
|
|
|
|
|
|
//....
|
|
bool CRadar_Device::BeginScene()
|
|
{
|
|
|
|
//Render Target을 설정한다.
|
|
SetRenderTargetTexture();
|
|
pD3DDevice->BeginScene();
|
|
|
|
//Texture에.. background image를 그린다. 일종의 Clear대신이다..
|
|
RECT rc={0,0,480,640};
|
|
pDDSTarget->BltFast(0,0,pDDSBackground,&rc,0);
|
|
|
|
return true;
|
|
}
|
|
bool CRadar_Device::EndScene()
|
|
{
|
|
pD3DDevice->EndScene();
|
|
SetRenderTargetBackbuffer();
|
|
pD3DDevice->BeginScene();
|
|
|
|
pD3DDevice->SetRenderState(D3DRENDERSTATE_ALPHABLENDENABLE,FALSE);
|
|
pD3DDevice->SetTexture( 0, pDDSTarget );
|
|
|
|
DWORD color=0xFFFFFFFF;
|
|
D3DTLVERTEX Vertices[4]; // Vertices for the cube
|
|
|
|
float w=(float)size_back.cx;
|
|
float h=(float)size_back.cy;
|
|
float w2=(float)size_target.cx;
|
|
float h2=(float)size_target.cy;
|
|
|
|
Vertices[0] = D3DTLVERTEX(D3DVECTOR(w,h,0.9f),1.0f,color,0, 0/w2, w/h2);
|
|
Vertices[1] = D3DTLVERTEX(D3DVECTOR(0,h,0.9f),1.0f,color,0, 0/w2, 0/h2);
|
|
Vertices[2] = D3DTLVERTEX(D3DVECTOR(w,0,0.9f),1.0f,color,0, h/w2, w/h2);
|
|
Vertices[3] = D3DTLVERTEX(D3DVECTOR(0,0,0.9f),1.0f,color,0, h/w2, 0/h2);
|
|
|
|
pD3DDevice->DrawPrimitive( D3DPT_TRIANGLESTRIP, D3DFVF_TLVERTEX , Vertices, 4, NULL );
|
|
|
|
pD3DDevice->EndScene();
|
|
return true;
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/////////////////////////////////// CMFD_Device ///////////////////////////////////
|
|
|
|
|
|
|
|
|
|
static DWORD channel_color[6]={
|
|
0xFFFF0000,
|
|
0xFF00FF00,
|
|
0xFF0000FF,
|
|
0xFFFF0000,
|
|
0xFF00FF00,
|
|
0xFF0000FF,
|
|
};
|
|
|
|
bool CMFD_Device::Init()
|
|
{
|
|
return CHSH_Device::Init(2,1280,480,1024,512,"mfd_texture");
|
|
|
|
pDDSMechTexture=CreatePixelFormatTexture(pDD,256,256,&DDPF_R5G6B5);//3D메크 이미지 저장하기 위한 텍스쳐...
|
|
}
|
|
|
|
|
|
bool CMFD_Device::BeginChannel(DWORD channel)
|
|
{
|
|
ch=channel;
|
|
|
|
//Render Target을 설정한다.
|
|
SetRenderTargetTexture();
|
|
pD3DDevice->BeginScene();
|
|
pD3DDevice->Clear(0,NULL,D3DCLEAR_TARGET ,0,0,0);
|
|
return true;
|
|
}
|
|
|
|
|
|
bool CMFD_Device::EndChannel()
|
|
{
|
|
pD3DDevice->EndScene();
|
|
|
|
SetRenderTargetBackbuffer();
|
|
pD3DDevice->BeginScene();
|
|
|
|
pD3DDevice->SetRenderState(D3DRENDERSTATE_ALPHABLENDENABLE,TRUE);
|
|
pD3DDevice->SetRenderState(D3DRENDERSTATE_SRCBLEND,D3DBLEND_ONE);
|
|
pD3DDevice->SetRenderState(D3DRENDERSTATE_DESTBLEND,D3DBLEND_ONE);
|
|
pD3DDevice->SetTexture( 0, pDDSTarget );
|
|
|
|
DWORD color=channel_color[ch];
|
|
D3DTLVERTEX Vertices[4]; // Vertices for the cube
|
|
|
|
float w=(float)size_back.cx/2;//<==주의: 이점이 radar와 다른점이다.
|
|
float x1=(ch/3)*w;
|
|
float x2=x1+w;
|
|
float h=(float)size_back.cy;
|
|
float w2=(float)size_target.cx;
|
|
float h2=(float)size_target.cy;
|
|
|
|
Vertices[0] = D3DTLVERTEX(D3DVECTOR(x1,h,0.9f),1.0f,color,0, 0/w2, h/h2);
|
|
Vertices[1] = D3DTLVERTEX(D3DVECTOR(x1,0,0.9f),1.0f,color,0, 0/w2, 0/h2);
|
|
Vertices[2] = D3DTLVERTEX(D3DVECTOR(x2,h,0.9f),1.0f,color,0, w/w2, h/h2);
|
|
Vertices[3] = D3DTLVERTEX(D3DVECTOR(x2,0,0.9f),1.0f,color,0, w/w2, 0/h2);
|
|
|
|
pD3DDevice->DrawPrimitive( D3DPT_TRIANGLESTRIP, D3DFVF_TLVERTEX , Vertices, 4, NULL );
|
|
|
|
pD3DDevice->EndScene();
|
|
return true;
|
|
}
|
|
|
|
|
|
bool CMFD_Device::BeginScene()
|
|
{
|
|
SetRenderTargetBackbuffer();
|
|
pD3DDevice->BeginScene();
|
|
pD3DDevice->Clear(0,NULL,D3DCLEAR_TARGET ,0,0,0);
|
|
pD3DDevice->EndScene();
|
|
return true;
|
|
}
|
|
|
|
|
|
bool CMFD_Device::EndScene()
|
|
{
|
|
//do nothing???
|
|
return true;
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//_____________________________________________________________________________________________________
|
|
//
|
|
// Font3D
|
|
//_____________________________________________________________________________________________________
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static DWORD GetFontAreaHeight(DWORD width,HFONT hfont)
|
|
{
|
|
HDC hdc=GetDC(NULL);
|
|
HFONT holdfont=(HFONT)SelectObject(hdc,hfont);
|
|
|
|
char str[4];
|
|
DWORD x=0,y=0;
|
|
SIZE size={0,};
|
|
for( char c=32; c<127; c++ ){
|
|
str[0] = c;
|
|
GetTextExtentPoint32( hdc, str, 1, &size );
|
|
|
|
if( (DWORD)(x+size.cx+1) > width ){
|
|
x = 0;
|
|
y += size.cy+1;
|
|
}
|
|
x += size.cx+1;
|
|
}
|
|
|
|
SelectObject(hdc,holdfont);
|
|
ReleaseDC(NULL,hdc);
|
|
return (y+ size.cy+1);
|
|
}
|
|
|
|
static HFONT CreateFont(DWORD dwHeight, bool fBold,bool fItalic,const char* FaceName)
|
|
{
|
|
DWORD dwBold = fBold ? FW_BOLD : FW_NORMAL;
|
|
DWORD dwItalic = fItalic ? TRUE : FALSE;
|
|
|
|
return CreateFont( dwHeight, 0, 0, 0, dwBold, dwItalic,
|
|
FALSE, FALSE, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS,
|
|
CLIP_DEFAULT_PRECIS, ANTIALIASED_QUALITY,
|
|
VARIABLE_PITCH, FaceName );
|
|
}
|
|
|
|
static int Get2NHeight(int h)
|
|
{
|
|
for(int i=6;i<=10;i++){
|
|
if(h<=(1<<i))return (1<<i);
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
//input:Font Handle,Font Height(One Character)
|
|
//output:expected width and height
|
|
static void GetFontTextureSize(HFONT hFont,DWORD dwHeight,DWORD &w,DWORD& h)
|
|
{
|
|
//Width
|
|
w=(dwHeight>=50)?512:256;
|
|
//Height
|
|
DWORD height=GetFontAreaHeight(w,hFont);
|
|
h=Get2NHeight(height);
|
|
}
|
|
|
|
static HBITMAP CreateTopDownDIB32(int Width,int Height,DWORD**ppBitmapBits)
|
|
{
|
|
BITMAPINFO bmi;
|
|
ZeroMemory( &bmi.bmiHeader, sizeof(BITMAPINFOHEADER) );
|
|
bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
|
|
bmi.bmiHeader.biWidth = (int)Width;
|
|
bmi.bmiHeader.biHeight = -(int)Height;
|
|
bmi.bmiHeader.biPlanes = 1;
|
|
bmi.bmiHeader.biCompression = BI_RGB;
|
|
bmi.bmiHeader.biBitCount = 32;
|
|
|
|
return CreateDIBSection( NULL, &bmi, DIB_RGB_COLORS,(VOID**)ppBitmapBits, NULL, 0 );
|
|
}
|
|
|
|
CHSHFont::CHSHFont()
|
|
{
|
|
m_pd3dDevice=0;
|
|
m_pTexture=0;
|
|
|
|
m_dwSavedStateBlock=0;
|
|
m_dwDrawTextStateBlock=0;
|
|
}
|
|
|
|
CHSHFont::~CHSHFont()
|
|
{
|
|
}
|
|
|
|
void CHSHFont::Init(LPDIRECTDRAW7 pDD, LPDIRECT3DDEVICE7 pd3dDevice ,const char* strFontName, DWORD dwHeight, bool fBold,bool fItalic)
|
|
{
|
|
if(pd3dDevice==NULL)return;
|
|
m_pd3dDevice = pd3dDevice;
|
|
m_pd3dDevice->AddRef();
|
|
|
|
HFONT hFont = CreateFont( dwHeight, fBold, fItalic,strFontName);
|
|
|
|
GetFontTextureSize(hFont,dwHeight,m_dwTexWidth,m_dwTexHeight);
|
|
|
|
m_pTexture=CreateRGBATexture(pDD,m_dwTexWidth,m_dwTexHeight,16);
|
|
|
|
// Prepare to create a bitmap
|
|
DWORD * pBitmapBits;
|
|
HBITMAP hbmBitmap;
|
|
hbmBitmap=CreateTopDownDIB32(m_dwTexWidth,m_dwTexHeight,&pBitmapBits);
|
|
|
|
// Create a DC and a bitmap for the font
|
|
HDC hDC = CreateCompatibleDC( NULL );
|
|
SelectObject( hDC, hbmBitmap );
|
|
SelectObject( hDC, hFont );
|
|
|
|
DWORD x = 0;
|
|
DWORD y = 0;
|
|
char str[4] = {0,};//DWORD align시키기 위해서..(원래는 2를 쓰면된다.)
|
|
SIZE size;
|
|
|
|
for( char c=32; c<127; c++ ){
|
|
|
|
str[0] = c;
|
|
GetTextExtentPoint32( hDC, str, 1, &size );
|
|
|
|
if( (DWORD)(x+size.cx+1) > m_dwTexWidth ){
|
|
x = 0;
|
|
y += size.cy+1;
|
|
}
|
|
//j가 i의 영역을 침범한다. 적절한 조치를 취할것...
|
|
ExtTextOut( hDC, x+0, y+0, ETO_OPAQUE, NULL, str, 1, NULL );
|
|
|
|
m_fTexCoords[c-32][0] = ((float)(x+0))/m_dwTexWidth;
|
|
m_fTexCoords[c-32][1] = ((float)(y+0))/m_dwTexHeight;
|
|
m_fTexCoords[c-32][2] = ((float)(x+0+size.cx))/m_dwTexWidth;
|
|
m_fTexCoords[c-32][3] = ((float)(y+0+size.cy))/m_dwTexHeight;
|
|
|
|
x += size.cx+1;
|
|
}
|
|
|
|
WORD* pDst16 = (WORD*)GetSurfacePointer(m_pTexture);
|
|
BYTE bAlpha;
|
|
|
|
for( y=0; y < m_dwTexHeight; y++ ){
|
|
for( x=0; x < m_dwTexWidth; x++ ){
|
|
bAlpha = (BYTE)((pBitmapBits[m_dwTexWidth*y + x] & 0xff) >> 4);
|
|
if (bAlpha > 0)
|
|
*pDst16++ = (WORD)((bAlpha << 12) | 0x0fff);
|
|
else
|
|
*pDst16++ = 0x0000;
|
|
}
|
|
}
|
|
|
|
ReleaseSurfacePointer(m_pTexture);
|
|
|
|
DeleteObject( hbmBitmap );
|
|
DeleteDC( hDC );
|
|
DeleteObject( hFont );
|
|
|
|
//////StateBlock관련..
|
|
for( UINT which=0; which<2; which++ ){
|
|
m_pd3dDevice->BeginStateBlock();
|
|
m_pd3dDevice->SetTexture( 0, m_pTexture );
|
|
m_pd3dDevice->SetRenderState( D3DRENDERSTATE_ALPHABLENDENABLE, TRUE );
|
|
m_pd3dDevice->SetRenderState( D3DRENDERSTATE_SRCBLEND, D3DBLEND_SRCALPHA );
|
|
m_pd3dDevice->SetRenderState( D3DRENDERSTATE_DESTBLEND, D3DBLEND_INVSRCALPHA );
|
|
|
|
LPDWORD blocktosave = (which==0) ? &m_dwSavedStateBlock:&m_dwDrawTextStateBlock;
|
|
|
|
m_pd3dDevice->EndStateBlock(blocktosave);
|
|
}
|
|
}
|
|
|
|
void CHSHFont::Cleanup()
|
|
{
|
|
// Delete the state blocks
|
|
if( m_pd3dDevice ){
|
|
if( m_dwSavedStateBlock ){
|
|
m_pd3dDevice->DeleteStateBlock( m_dwSavedStateBlock );
|
|
m_dwSavedStateBlock = 0L;
|
|
}
|
|
if( m_dwDrawTextStateBlock ){
|
|
m_pd3dDevice->DeleteStateBlock( m_dwDrawTextStateBlock );
|
|
m_dwDrawTextStateBlock = 0L;
|
|
}
|
|
SAFE_RELEASE( m_pTexture );
|
|
SAFE_RELEASE( m_pd3dDevice );
|
|
}//m_pd3dDevice==NULL이면 아무것도 하지 않는다.
|
|
|
|
}
|
|
|
|
|
|
HRESULT CHSHFont::GetTextExtent(const char* strText, SIZE* pSize )
|
|
{
|
|
if( NULL==strText || NULL==pSize )return E_FAIL;
|
|
|
|
float fRowWidth = 0.0f;
|
|
float fRowHeight = (m_fTexCoords[0][3]-m_fTexCoords[0][1])*m_dwTexHeight;
|
|
float fWidth = 0.0f;
|
|
float fHeight = fRowHeight;
|
|
|
|
char c;
|
|
while( (c=*strText++)!=0 ){
|
|
if( c == '\n' ){
|
|
fRowWidth = 0.0f;
|
|
fHeight += fRowHeight;
|
|
}
|
|
|
|
if( c < ' ' )continue;
|
|
|
|
float tx1 = m_fTexCoords[c-32][0];
|
|
float tx2 = m_fTexCoords[c-32][2];
|
|
|
|
fRowWidth += (tx2-tx1)*m_dwTexWidth;
|
|
|
|
if( fRowWidth > fWidth )fWidth = fRowWidth;
|
|
}
|
|
|
|
pSize->cx = (int)fWidth;
|
|
pSize->cy = (int)fHeight;
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
HRESULT CHSHFont::DrawText( float sx, float sy, DWORD dwColor,const char* strText)
|
|
{
|
|
if( m_pd3dDevice == NULL )
|
|
return E_FAIL;
|
|
|
|
// Setup renderstate
|
|
m_pd3dDevice->CaptureStateBlock( m_dwSavedStateBlock );
|
|
m_pd3dDevice->ApplyStateBlock( m_dwDrawTextStateBlock );
|
|
|
|
|
|
// Fill vertex buffer
|
|
DWORD dwNumVtx = 0;
|
|
D3DTLVERTEX * pVertices =m_pVB;
|
|
char c;
|
|
float osx=sx;//원래의 sx;
|
|
float h = (m_fTexCoords[0][3]-m_fTexCoords[0][1]) * m_dwTexHeight ;//한글자의 높이는 모두 동일할 것이다.
|
|
|
|
while( (c = *strText++)!=0 ){
|
|
|
|
if( c < ' ' )continue;
|
|
|
|
if( c == '\n')sy+=h,sx=osx;//여러줄을 표시할때...
|
|
|
|
float *TexCoords=m_fTexCoords[c-32];
|
|
float tx1 = TexCoords[0];
|
|
float ty1 = TexCoords[1];
|
|
float tx2 = TexCoords[2];
|
|
float ty2 = TexCoords[3];
|
|
|
|
float w = (tx2-tx1) * m_dwTexWidth ;
|
|
|
|
*pVertices++ = D3DTLVERTEX(D3DVECTOR(sx+0-0.5f,sy+h-0.5f,0.9f),1.0f, dwColor,0, tx1, ty2 );
|
|
*pVertices++ = D3DTLVERTEX(D3DVECTOR(sx+0-0.5f,sy+0-0.5f,0.9f),1.0f, dwColor,0, tx1, ty1 );
|
|
*pVertices++ = D3DTLVERTEX(D3DVECTOR(sx+w-0.5f,sy+h-0.5f,0.9f),1.0f, dwColor,0, tx2, ty2 );
|
|
*pVertices++ = D3DTLVERTEX(D3DVECTOR(sx+w-0.5f,sy+0-0.5f,0.9f),1.0f, dwColor,0, tx2, ty1 );
|
|
*pVertices++ = D3DTLVERTEX(D3DVECTOR(sx+w-0.5f,sy+h-0.5f,0.9f),1.0f, dwColor,0, tx2, ty2 );
|
|
*pVertices++ = D3DTLVERTEX(D3DVECTOR(sx+0-0.5f,sy+0-0.5f,0.9f),1.0f, dwColor,0, tx1, ty1 );
|
|
dwNumVtx += 6;
|
|
|
|
if( dwNumVtx > (MAX_NUM_VERTICES-6) ){
|
|
m_pd3dDevice->DrawPrimitive( D3DPT_TRIANGLELIST, D3DFVF_TLVERTEX ,m_pVB,dwNumVtx,0 );
|
|
pVertices = m_pVB;
|
|
dwNumVtx = 0L;
|
|
}
|
|
|
|
sx += w;
|
|
}
|
|
|
|
//나머지 것들을 그린다.
|
|
if(dwNumVtx> 0 ){
|
|
m_pd3dDevice->DrawPrimitive( D3DPT_TRIANGLELIST, D3DFVF_TLVERTEX ,m_pVB,dwNumVtx,0 );
|
|
}
|
|
|
|
// Restore the modified renderstates
|
|
m_pd3dDevice->ApplyStateBlock( m_dwSavedStateBlock );
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
#define TEXTALIGN_HORZ 0x0F
|
|
#define TEXTALIGN_LEFT 0x00
|
|
#define TEXTALIGN_RIGHT 0x01
|
|
#define TEXTALIGN_CENTER 0x02
|
|
|
|
#define TEXTALIGN_VERT 0xF0
|
|
#define TEXTALIGN_TOP 0x00
|
|
#define TEXTALIGN_BOTTON 0x10
|
|
#define TEXTALIGN_VCENTER 0x20
|
|
|
|
HRESULT CHSHFont::DrawText( float sx, float sy, DWORD dwColor,const char* strText,DWORD dwFlags)
|
|
{
|
|
SIZE size;
|
|
GetTextExtent(strText, &size );
|
|
|
|
int offsetx=0;
|
|
|
|
switch(dwFlags&TEXTALIGN_HORZ){
|
|
case TEXTALIGN_LEFT:
|
|
offsetx=0;
|
|
break;
|
|
case TEXTALIGN_RIGHT:
|
|
offsetx = -size.cx;
|
|
break;
|
|
case TEXTALIGN_CENTER:
|
|
offsetx = -size.cx/2;
|
|
break;
|
|
}
|
|
|
|
int offsety=0;
|
|
switch(dwFlags&TEXTALIGN_VERT){
|
|
case TEXTALIGN_TOP:
|
|
offsety=0;
|
|
break;
|
|
case TEXTALIGN_BOTTON:
|
|
offsety=-size.cy;
|
|
break;
|
|
case TEXTALIGN_VCENTER:
|
|
offsety=-size.cy/2;
|
|
break;
|
|
}
|
|
|
|
return DrawText(sx+(float)offsetx,sy+(float)offsety,dwColor,strText);
|
|
}
|
|
|
|
|
|
//_____________________________________________________________________________________________________
|
|
//
|
|
// CopyTargetImage
|
|
//_____________________________________________________________________________________________________
|
|
|
|
|
|
|
|
|
|
static LPVOID GetSurfacePointer(LPDIRECTDRAWSURFACE7 psurf,RECT& rc,LONG& lPitch)
|
|
{
|
|
DDSURFACEDESC2 desc={0,};
|
|
desc.dwSize=sizeof(desc);
|
|
|
|
psurf->Lock(&rc,&desc,DDLOCK_WAIT ,NULL);
|
|
lPitch=desc.lPitch;
|
|
return desc.lpSurface;
|
|
}
|
|
|
|
static void ReleaseSurfacePointer(LPDIRECTDRAWSURFACE7 psurf,RECT& rc)
|
|
{
|
|
psurf->Unlock(&rc);
|
|
}
|
|
|
|
LPDIRECTDRAWSURFACE7 BackbufferSurface;
|
|
//stage
|
|
//0:init
|
|
//1:normal function
|
|
//2:cleanup
|
|
int HSH_CopyTargetImage(int stage,LPDIRECTDRAWSURFACE7 tex=NULL)
|
|
{
|
|
static DWORD* mem_org;
|
|
static bool inited=false;
|
|
static LPDIRECTDRAWSURFACE7 texture;
|
|
if(stage==1){
|
|
if(inited){
|
|
//normal function
|
|
//성능상의 이유로.. 맨처음에 두었음..
|
|
RECT rc={0,0,256,256};
|
|
LONG lPitch;
|
|
DWORD* agp;
|
|
DWORD* pci;
|
|
DWORD* mem;
|
|
int x,y;
|
|
|
|
//1. AGP->MEM
|
|
mem=mem_org;
|
|
agp=(DWORD*)GetSurfacePointer(BackbufferSurface,rc,lPitch);
|
|
if(lPitch%4==0){// DWORD align됐을때만 실행한다.
|
|
for(y=0;y<256;y++){
|
|
for(x=0;x<256*2/4;x++){
|
|
*mem++=*agp++;
|
|
}
|
|
agp+=(lPitch-256*2)/4;//padding...
|
|
}
|
|
}
|
|
ReleaseSurfacePointer(BackbufferSurface,rc);
|
|
|
|
//2. MEM Only
|
|
|
|
//3. MEM->PCI
|
|
mem=mem_org;
|
|
pci=(DWORD*)GetSurfacePointer(texture,rc,lPitch);
|
|
if(lPitch%4==0){// DWORD align됐을때만 실행한다.
|
|
for(y=0;y<256;y++){
|
|
for(x=0;x<256*2/4;x++){
|
|
*pci++=*mem++;
|
|
}
|
|
pci+=(lPitch-256*2)/4;//padding...
|
|
}
|
|
}
|
|
ReleaseSurfacePointer(texture,rc);
|
|
}
|
|
}else if(stage==0){
|
|
//init
|
|
if(tex){
|
|
texture=tex;
|
|
texture->AddRef();
|
|
mem_org=(DWORD*)LocalAlloc(LPTR,256*256*2);
|
|
inited=true;
|
|
}
|
|
}else if(stage==2){
|
|
//cleanup
|
|
if(inited){
|
|
texture->Release();
|
|
texture=0;
|
|
LocalFree((HLOCAL)mem_org);
|
|
mem_org=0;
|
|
inited=false;
|
|
}
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
|
|
//_____________________________________________________________________________________________________
|
|
//
|
|
// Full Screen
|
|
//_____________________________________________________________________________________________________
|
|
|
|
//전에 SCREENS와 유사한 역할을 한다
|
|
//command line paramemer에 의해 정해지고 이후에는 변하지 않는다.
|
|
bool use_multimonitor;
|
|
|
|
//보통 true이다.. 그러나 window모드로 들어가면.. false가된다.
|
|
//true이면.. 각종 드로딩 루틴을 그리고 false를 일때는 일체 하지 않는다.
|
|
bool draw_mfd_huds;
|
|
|
|
//window모드가 되었을때 무조건 true가 되도록한다.(현재에는..)
|
|
//멀티모디터 드로잉과는 관계없다.
|
|
bool draw_main_huds;
|
|
CRadar_Device radar_device;
|
|
CMFD_Device mfd_device;
|
|
|
|
bool hsh_initialized=false;
|
|
|
|
void HSH_EnterFullScreen2()
|
|
{
|
|
radar_device.Init();
|
|
mfd_device.Init();
|
|
HSH_CopyTargetImage(1);
|
|
hsh_initialized=true;
|
|
}
|
|
|
|
void HSH_DirectDrawRelease2()
|
|
{
|
|
if(hsh_initialized){
|
|
mfd_device.Release();
|
|
radar_device.Release();
|
|
HSH_CopyTargetImage(2);
|
|
hsh_initialized=false;
|
|
}
|
|
} |