📄 ddraw_utility.c
字号:
#include <windows.h>
#include <ddraw.h>
#include <dinput.h>
#include <assert.h>
#include <mmsystem.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "ddraw_utility.h"
#include "sgl.h"
#include "sgltype.h"
// Macro to release an object.
#define RELEASE(x) {\
if (x != NULL)\
{\
x->lpVtbl->Release(x);\
x = NULL;\
}\
}
// Macro to display a message box containing the given string.
#define DISPLAYMESSAGE(x) {\
printf("SGL Message:%s\n",x);\
/*MessageBox(NULL, "SGL message", x, MB_OK);*/\
}
#define RESTORE(x) {\
if ( x && x->lpVtbl->IsLost(x)==DDERR_SURFACELOST )\
x->lpVtbl->Restore(x);\
}
extern sglDevice sgl;
CDDraw g_ddraw;
unsigned char *current_pointer;
static HFONT g_font = NULL;
static DDPIXELFORMAT g_pixelformat;
extern void (*DDSetColor)(int r, int g, int b);
extern void (*DDPutPixel)(int x, int y);
extern int SetPixelFunc( void );
PALETTEENTRY g_pe[256];
void DDTextColor(int r, int g, int b)
{
g_ddraw.m_iTextRed = r;
g_ddraw.m_iTextGreen = g;
g_ddraw.m_iTextBlue = b;
}
void DDColor3i(int r, int g, int b)
{
DDTextColor(r,g,b);
DDSetColor(r,g,b);
}
void DDColorKey3i(int r, int g, int b)
{
int backup = g_ddraw.m_Color;
DDSetColor(r,g,b);
g_ddraw.m_ColorKey = g_ddraw.m_Color;
g_ddraw.m_Color = backup;
}
void DDColorKey(int color)
{
g_ddraw.m_ColorKey = color;
}
void DDBGColor3i(int r, int g, int b)
{
int backup = g_ddraw.m_Color;
DDSetColor(r,g,b);
g_ddraw.m_ClearColor = g_ddraw.m_Color;
g_ddraw.m_Color = backup;
}
void DDBGColor(int color)
{
g_ddraw.m_ClearColor = color;
}
void DDShowFPS(int show)
{
g_ddraw.m_bShowFPS = show;
}
void DDUseFont(char *name, int width, int height)
{
int charset = name[0]>0 ? DEFAULT_CHARSET : CHINESEBIG5_CHARSET;
if ( g_font ) DeleteObject(g_font);
g_font = CreateFont(height, width,
0, 0, FW_NORMAL, FALSE, FALSE, FALSE,
charset,
OUT_DEFAULT_PRECIS,
CLIP_DEFAULT_PRECIS,
DEFAULT_QUALITY,
DEFAULT_PITCH,
name);
}
void DDColor(int color)
{
g_ddraw.m_Color = color;
g_ddraw.m_iTextRed = (color & 0xff0000) >> 16;
g_ddraw.m_iTextGreen = (color & 0x00ff00) >> 8;
g_ddraw.m_iTextBlue = (color & 0x0000ff);
}
int DDStartDraw( void )
{
DDSURFACEDESC2 ddsd;
int ddrval;
ZeroMemory(&ddsd,sizeof(ddsd));
ddsd.dwSize = sizeof(ddsd);
ddrval = IDirectDrawSurface7_Lock( g_ddraw.m_pTargetBuffer->surface,
NULL, &ddsd, DDLOCK_WAIT, NULL);
// assert(ddrval==DD_OK);
return (ddrval==DD_OK);
}
int DDEndDraw( void )
{
int ddrval;
ddrval = IDirectDrawSurface7_Unlock( g_ddraw.m_pTargetBuffer->surface, NULL);
// assert(ddrval==DD_OK);
return (ddrval==DD_OK);
}
void DDSetPalette(int index, int r, int g, int b)
{
g_pe[index].peRed = r;
g_pe[index].peGreen = g;
g_pe[index].peBlue = b;
g_pe[index].peFlags = 0;
}
void DDGetPalette(int index, int *r, int *g, int *b)
{
*r = g_pe[index].peRed;
*g = g_pe[index].peGreen;
*b = g_pe[index].peBlue;
}
void DDSelectBuffer(int target)
{
g_ddraw.m_iSelectBuffer = target;
switch( target )
{
case SGL_BACKBUFFER:
g_ddraw.m_pTargetBuffer = &g_ddraw.m_BackBuffer;
break;
case SGL_FRONTBUFFER:
g_ddraw.m_pTargetBuffer = &g_ddraw.m_FrontBuffer;
break;
}
}
BOOL DDReady(void)
{
return g_ddraw.m_bInitized;
}
void DDUpdatePalette(void)
{
LPDIRECTDRAWPALETTE palette = g_ddraw.m_pPalette;
if ( palette==NULL ) return;
IDirectDrawPalette_SetEntries(palette, 0, 0, 256, g_pe);
}
void DDInputRelease(void)
{
if ( g_ddraw.m_pKeyboard ) IDirectInputDevice7_Unacquire(g_ddraw.m_pKeyboard);
RELEASE( g_ddraw.m_pKeyboard);
RELEASE( g_ddraw.m_pDI);
}
BOOL DDInputInit(void)
{
HRESULT hr;
if( g_ddraw.m_hwnd==NULL )
{
DISPLAYMESSAGE("Call sglCreateWindow or sglFullScreen first.");
return FALSE;
}
// Create a DInput object
if( FAILED( hr = DirectInputCreateEx( GetModuleHandle(NULL), DIRECTINPUT_VERSION,
&IID_IDirectInput7, &g_ddraw.m_pDI, NULL ) ) )
{
DISPLAYMESSAGE("Create direct input device fail.");
return FALSE;
}
// Obtain an interface to the system keyboard device.
if( FAILED( hr = IDirectInput7_CreateDeviceEx(
g_ddraw.m_pDI, &GUID_SysKeyboard,
&IID_IDirectInputDevice7, &g_ddraw.m_pKeyboard, NULL ) ) )
{
DISPLAYMESSAGE("Create keyboard device fail.");
return FALSE;
}
if( FAILED( hr = IDirectInputDevice7_SetDataFormat(
g_ddraw.m_pKeyboard, &c_dfDIKeyboard ) ) )
{
DISPLAYMESSAGE("Set data format fail.");
return FALSE;
}
if ( FAILED( hr = IDirectInputDevice7_SetCooperativeLevel(
g_ddraw.m_pKeyboard, g_ddraw.m_hwnd, DISCL_NONEXCLUSIVE|DISCL_FOREGROUND ) ) )
{
DISPLAYMESSAGE("Set directinput cooperativelevel fail.");
RELEASE(g_ddraw.m_pKeyboard);
RELEASE(g_ddraw.m_pDI);
return FALSE;
}
IDirectInputDevice7_Acquire(g_ddraw.m_pKeyboard);
return TRUE;
}
static BYTE keyboardbuffer[256];
BOOL DDReadKeyboard(void)
{
HRESULT hr;
if( g_ddraw.m_pKeyboard == NULL )
return FALSE;
// Get the input's device state, and put the state in dims
ZeroMemory( keyboardbuffer, sizeof(keyboardbuffer) );
hr = IDirectInputDevice7_GetDeviceState(
g_ddraw.m_pKeyboard, sizeof(keyboardbuffer), keyboardbuffer );
if( FAILED(hr) )
{
hr = IDirectInputDevice7_Acquire(g_ddraw.m_pKeyboard);
while( hr == DIERR_INPUTLOST )
hr = IDirectInputDevice7_Acquire(g_ddraw.m_pKeyboard);
return FALSE;
}
return TRUE;
}
BOOL DDKeyPressed(int index)
{
if ( g_ddraw.m_pKeyboard==NULL ) return FALSE;
return (keyboardbuffer[index] & 0x80);
}
BOOL DDFullScreen(HWND hWnd, int width, int height, int bpp, int doublebuffer)
{
HRESULT ddrval;
LPDIRECTDRAW DDraw;
DDSURFACEDESC2 ddsd;
if ( DDReady() )
{
// DDRelease();
DISPLAYMESSAGE("sglFullScreen fail.");
return FALSE;
}
if ( bpp == 0 )
{
HDC hdc = GetDC(hWnd);
bpp = GetDeviceCaps(hdc,BITSPIXEL);
ReleaseDC(hWnd, hdc);
}
ZeroMemory(&g_ddraw, sizeof(g_ddraw) );
g_ddraw.m_Color = 0xffffffff;
sgl.Width = g_ddraw.m_FrontBuffer.width = width;
sgl.Height = g_ddraw.m_FrontBuffer.height = height;
g_ddraw.m_hwnd = hWnd;
sgl.DoubleBuffer = g_ddraw.m_bDoubleBuffer = doublebuffer;
g_ddraw.fpsX = 10;
g_ddraw.fpsY = 5;
g_ddraw.m_FrontBuffer.surface = g_ddraw.m_BackBuffer.surface = NULL;
ddrval = DirectDrawCreate(NULL,&DDraw,NULL);
if( ddrval != DD_OK )
{
DISPLAYMESSAGE("Direct Draw Create Failed");
return FALSE;
}
// Fetch DirectDraw interface
ddrval = IDirectDraw_QueryInterface( DDraw,
&IID_IDirectDraw7, (LPVOID *) &(g_ddraw.m_pDDraw) );
RELEASE(DDraw);
if ( ddrval != DD_OK )
{
DISPLAYMESSAGE("Create DirectDraw 7 fail.");
return FALSE;
}
ddrval = IDirectDraw7_SetCooperativeLevel( g_ddraw.m_pDDraw,
hWnd, DDSCL_EXCLUSIVE|DDSCL_FULLSCREEN);
if( ddrval != DD_OK )
{
RELEASE( g_ddraw.m_pDDraw );
DISPLAYMESSAGE("SetCooperativeLevel Failed");
return FALSE;
}
if( FAILED( IDirectDraw7_SetDisplayMode(
g_ddraw.m_pDDraw, width, height, bpp, 0, 0 ) ) )
{
RELEASE(g_ddraw.m_pDDraw );
DISPLAYMESSAGE("Invalid display mode.");
return FALSE;
}
/* create primary surface */
ZeroMemory(&ddsd,sizeof(ddsd));
ddsd.dwSize = sizeof(ddsd);
ddsd.dwFlags = DDSD_CAPS;
ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE | DDSCAPS_VIDEOMEMORY;
ddrval = IDirectDraw7_CreateSurface( g_ddraw.m_pDDraw,
&ddsd, &g_ddraw.m_FrontBuffer.surface, NULL);
// impossible for primary surface
if (ddrval != DD_OK)
{
DISPLAYMESSAGE("Create Primary Surface Failed.");
RELEASE(g_ddraw.m_pDDraw);
return FALSE;
}
/* get pointer of primary sufrace */
IDirectDrawSurface7_Lock( g_ddraw.m_FrontBuffer.surface,
NULL, &ddsd,
DDLOCK_WAIT | DDLOCK_SURFACEMEMORYPTR, NULL);
g_ddraw.m_FrontBuffer.pointer = (unsigned char *)ddsd.lpSurface;
g_ddraw.m_FrontBuffer.Pitch = ddsd.lPitch;
IDirectDrawSurface7_Unlock( g_ddraw.m_FrontBuffer.surface, NULL );
if ( !SetPixelFunc() )
{
DISPLAYMESSAGE("SGL doesn't support this display mode.");
RELEASE(g_ddraw.m_FrontBuffer.surface);
RELEASE(g_ddraw.m_pDDraw);
return FALSE;
}
ddrval = IDirectDraw7_CreatePalette( g_ddraw.m_pDDraw,
DDPCAPS_8BIT | DDPCAPS_ALLOW256, g_pe, &g_ddraw.m_pPalette, NULL);
ddrval = IDirectDrawSurface7_SetPalette( g_ddraw.m_FrontBuffer.surface, g_ddraw.m_pPalette );
DDUpdatePalette();
if ( doublebuffer )
{
if ( !DDCreateBackSurface( g_ddraw.m_FrontBuffer.width, g_ddraw.m_FrontBuffer.height, &g_ddraw.m_BackBuffer ) )
{
DDRelease();
return FALSE;
}
g_ddraw.m_pTargetBuffer = &g_ddraw.m_BackBuffer;
}
else
{
g_ddraw.m_pTargetBuffer = &g_ddraw.m_FrontBuffer;
}
DDOnMove();
g_ddraw.m_bInitized = TRUE;
return TRUE;
}
BOOL DDWindow( HWND hWnd, int doublebuffer )
{
HRESULT ddrval;
LPDIRECTDRAW DDraw;
DDSURFACEDESC2 ddsd;
RECT rect;
if ( DDReady() )
DDRelease();
GetClientRect(hWnd, &rect);
ZeroMemory(&g_ddraw, sizeof(g_ddraw) );
g_ddraw.m_Color = 0xffffffff;
g_ddraw.m_ColorKey = 0;
sgl.Width = g_ddraw.m_FrontBuffer.width = rect.right-rect.left;
sgl.Height = g_ddraw.m_FrontBuffer.height = rect.bottom-rect.top;
sgl.DoubleBuffer = g_ddraw.m_bDoubleBuffer = doublebuffer;
g_ddraw.m_hwnd=hWnd;
g_ddraw.fpsX = 10;
g_ddraw.fpsY = 5;
g_ddraw.m_FrontBuffer.surface = g_ddraw.m_BackBuffer.surface = NULL;
ddrval = DirectDrawCreate(NULL,&DDraw,NULL);
if( ddrval != DD_OK )
{
DISPLAYMESSAGE("Direct Draw Create Failed");
return FALSE;
}
// Fetch DirectDraw interface
ddrval = IDirectDraw_QueryInterface( DDraw,
&IID_IDirectDraw7, (LPVOID *) &(g_ddraw.m_pDDraw) );
RELEASE(DDraw);
if ( ddrval != DD_OK )
{
DISPLAYMESSAGE("Create DirectDraw 7 fail.");
return FALSE;
}
ddrval = IDirectDraw7_SetCooperativeLevel(g_ddraw.m_pDDraw, hWnd, DDSCL_NORMAL);
if( ddrval != DD_OK )
{
DISPLAYMESSAGE("SetCooperativeLevel Failed.");
RELEASE(g_ddraw.m_pDDraw);
return FALSE;
}
ZeroMemory(&ddsd,sizeof(ddsd));
ddsd.dwSize = sizeof(ddsd);
ddsd.dwFlags = DDSD_CAPS;
ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE | DDSCAPS_VIDEOMEMORY;
ddrval = IDirectDraw7_CreateSurface( g_ddraw.m_pDDraw,
&ddsd, &g_ddraw.m_FrontBuffer.surface, NULL);
// impossible for primary surface
if (ddrval != DD_OK)
{
DISPLAYMESSAGE("Create Primary Surface Failed.");
RELEASE(g_ddraw.m_pDDraw);
return FALSE;
}
/* get pointer of primary surface */
ddrval = IDirectDrawSurface7_Lock( g_ddraw.m_FrontBuffer.surface,
NULL, &ddsd,
DDLOCK_WAIT|DDLOCK_SURFACEMEMORYPTR, NULL);
g_ddraw.m_FrontBuffer.pointer = (unsigned char *)ddsd.lpSurface;
g_ddraw.m_FrontBuffer.Pitch = ddsd.lPitch;
IDirectDrawSurface7_Unlock( g_ddraw.m_FrontBuffer.surface, NULL );
if ( !SetPixelFunc() )
{
DDRelease();
DISPLAYMESSAGE("SGL doesn't support this display mode.");
return FALSE;
}
ddrval = IDirectDraw7_CreateClipper( g_ddraw.m_pDDraw, 0, &g_ddraw.m_pClipper, NULL);
if (ddrval != DD_OK)
{
DDRelease();
DISPLAYMESSAGE("Create Clipper Failed");
return FALSE;
}
ddrval = IDirectDrawClipper_SetHWnd(g_ddraw.m_pClipper, 0, hWnd);
if (ddrval != DD_OK)
{
DDRelease();
DISPLAYMESSAGE("Set HWnd Failed.");
return FALSE;
}
ddrval = IDirectDrawSurface7_SetClipper( g_ddraw.m_FrontBuffer.surface, g_ddraw.m_pClipper );
if (ddrval != DD_OK)
{
DDRelease();
DISPLAYMESSAGE("Set Clipper Failed.");
return FALSE;
}
ddrval = IDirectDraw7_CreatePalette( g_ddraw.m_pDDraw,
DDPCAPS_8BIT | DDPCAPS_ALLOW256, g_pe, &g_ddraw.m_pPalette, NULL);
ddrval = IDirectDrawSurface7_SetPalette( g_ddraw.m_FrontBuffer.surface, g_ddraw.m_pPalette );
DDUpdatePalette();
if ( doublebuffer )
{
if ( !DDCreateBackSurface( g_ddraw.m_FrontBuffer.width, g_ddraw.m_FrontBuffer.height, &g_ddraw.m_BackBuffer ) )
{
DDRelease();
return FALSE;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -