📄 bdxdisp.cpp
字号:
#include <stdio.h>
#include <windows.h>
#include "dxdisp.h"
static IDirectDraw *dd=NULL;
// Dave's DirectDraw routines (previously dd.cpp)
static IDirectDrawClipper *attach_clipper
(IDirectDraw *lpdd,HWND hWnd,IDirectDrawSurface *lpprim)
{
IDirectDrawClipper *clipper=NULL; int ret=0;
ret=lpdd->CreateClipper(0,&clipper,NULL);
if (ret!=DD_OK)
{
dprintf ("createclipper failed: Ret was %x (%+-d)\n",
ret,ret-MAKE_DDHRESULT(0));
}
else
{
ret=clipper->SetHWnd(0,hWnd);
if (ret!=DD_OK)
{
dprintf ("SethWnd failed: Ret was %x (%+-d)\n",
ret,ret-MAKE_DDHRESULT(0));
}
else
{
ret=lpprim->SetClipper(clipper);
if (ret!=DD_OK)
{
dprintf ("SetClipper failed: Ret was %x (%+-d)\n",
ret,ret-MAKE_DDHRESULT(0));
}
}
}
return 0;
}
static IDirectDrawSurface *create_surface (IDirectDraw *lpdd,int width,int height)
{
IDirectDrawSurface *lpsurf=NULL; int ret=0;
// Seems to default to Window's bpp anyway!
DDSURFACEDESC ddsd;
//Clear all fields in structure
memset( &ddsd, 0, sizeof(ddsd) );
//Set flags in structure
ddsd.dwSize = sizeof( ddsd );
ddsd.dwFlags = DDSD_CAPS|DDSD_WIDTH|DDSD_HEIGHT;
ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_SYSTEMMEMORY;
ddsd.dwWidth = width;
ddsd.dwHeight = height;
ret=lpdd->CreateSurface(&ddsd,&lpsurf,NULL);
if (ret!=DD_OK)
{
dprintf (
"Error creating buffer Surface: Return value was %x (%+-d)\n",
ret,ret-MAKE_DDHRESULT(0));
return NULL;
}
return lpsurf;
}
static IDirectDrawSurface *create_primary_surface(IDirectDraw *lpdd)
{
int ret=0; IDirectDrawSurface *lpsurf=NULL;
if (lpdd==NULL) return 0;
// (Creating Primary Surface)
DDSURFACEDESC ddsd;
//Clear all fields in structure
memset( &ddsd, 0, sizeof(ddsd) );
//Set flags in structure
ddsd.dwSize = sizeof( ddsd );
ddsd.dwFlags = DDSD_CAPS;
ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
//Create Surface
ret = lpdd->CreateSurface(&ddsd, &lpsurf, NULL );
if (ret!=DD_OK)
{
dprintf (
"Error creating primary Surface: Return value was %x (%+-d)\n",
ret,ret-MAKE_DDHRESULT(0));
return NULL;
}
return lpsurf;
}
// Remember, after you are done using the DirectDrawSurface,
// you must do this:
// bufsurf->Unlock(bm.data); bm.data=NULL;
static int lock_surface_to_bm(struct bmap *sbm,IDirectDrawSurface *lpsurf)
{
// Turn the buf surface into something we can write into
DDSURFACEDESC sd; int ret=0;
memset(&sd,0,sizeof( sd ));
sd.dwSize = sizeof( sd );
ret=lpsurf->GetSurfaceDesc(&sd);
if (ret!=DD_OK)
{
dprintf ("GetSurfaceDesc returned %x (%+-d)\n"
,ret,ret-MAKE_DDHRESULT(0));
return 1;
}
sbm->w=sd.dwWidth;
sbm->h=sd.dwHeight;
DDPIXELFORMAT pf;
memset(&pf,0,sizeof(pf));
pf.dwSize = sizeof(pf);
ret=lpsurf->GetPixelFormat(&pf);
if (ret!=DD_OK)
{
dprintf ("ret is %x (%+-d)\n",ret,ret-MAKE_DDHRESULT(0));
return 1;
}
sbm->bpp=pf.dwRGBBitCount;
if (sbm->bpp==16)
if (pf.dwGBitMask==0x03e0) sbm->bpp=15;
ret=lpsurf->Lock(NULL,&sd,DDLOCK_SURFACEMEMORYPTR,NULL);
if (ret!=DD_OK)
{
dprintf ("lpsurf->Lock returned %.8x (%.8x) sd is %p\n",
ret,MAKE_DDHRESULT(0),sd.lpSurface);
return 1;
}
sbm->pitch=sd.lPitch;
sbm->data=(unsigned char *)sd.lpSurface;
return 0;
}
// MD DirectX Display stuff
dxdisp::dxdisp(HWND iwnd,int ifullscreen)
{
dprintf ("DXDISP construct %p\n",this);
dd=NULL; prim=buf=NULL; clipper=NULL;
wnd=iwnd; bm.data=NULL; fullscreen=ifullscreen;
ready=0;
are_we_ready();
}
// return value 1 means READY and 0 not ready (just like the variable)
int dxdisp::are_we_ready()
{
if (ready==2) return 1; // we are shutting down!
if (ready==1) return 1;
directdraw_init();
if (ready==1) return 1;
directdraw_exit(); // maybe have another go later when problem has cleared
return 0;
}
dxdisp::~dxdisp()
{
directdraw_exit();
wnd=0; bm.data=NULL;
dprintf ("DXDISP destroy %p\n",this);
}
// Main MD Screen Window
// This gets called until DirectDraw calls are completed
// clipper isn't vital
int dxdisp::directdraw_init()
{
int ret=0;
dprintf ("%p directdraw_init()\n",this);
if (ready) { dprintf ("WARNING - already ready\n"); return 1; }
if (fullscreen) ShowCursor(FALSE);
if (dd==NULL)
{
ret = DirectDrawCreate( NULL, &dd, NULL );
if (ret!=DD_OK)
{
dprintf ("DirectDrawCreate returned %x\n",ret);
return 1;
}
}
if (dd!=NULL)
{
if (fullscreen)
{
ret=dd->SetCooperativeLevel(wnd, DDSCL_ALLOWREBOOT | DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN | DDSCL_ALLOWMODEX);
if (ret!=DD_OK)
{
dprintf ("SetCooperativeLevel(EXCLUSIVE) returned %x (%d)\n",ret,ret-MAKE_DDHRESULT(0));
fullscreen=0; // We will get stuck if we don't change to windowed mode
return 1;
}
}
if (!fullscreen)
{
ret=dd->SetCooperativeLevel(wnd, DDSCL_NORMAL);
if (ret!=DD_OK)
{
dprintf ("SetCooperativeLevel returned %x (%d)\n",ret,ret-MAKE_DDHRESULT(0));
return 1;
}
}
if (fullscreen)
{
ret = dd->SetDisplayMode(320,240,16);
if (ret!=DD_OK)
{
dprintf ("SetDisplayMode() returned %x (%d)\n",ret,ret-MAKE_DDHRESULT(0));
return 1;
}
}
if (prim==NULL) prim=create_primary_surface(dd);
if (prim==NULL) return 1;
if (buf==NULL) buf=create_surface(dd,320+16,224+16);
if (buf==NULL) return 1;
if (!fullscreen)
if (prim!=NULL)
if (clipper==NULL) clipper=attach_clipper(dd,wnd,prim);
}
ready=1;
return 0;
}
int dxdisp::directdraw_exit()
{
ready=2; // shutting down
// Release DirectDraw when we are destroyed
if (clipper !=NULL) clipper->Release(); clipper=NULL;
if (buf !=NULL) buf ->Release(); buf =NULL;
if (prim !=NULL) prim ->Release(); prim =NULL;
dprintf ("%p directdraw_exit() MID3\n",this);
if (dd !=NULL) dd ->Release(); dd =NULL;
dprintf ("%p directdraw_exit() MID4\n",this);
if (fullscreen) ShowCursor(TRUE);
return 0;
}
int dxdisp::cls()
{
if (!are_we_ready()) return 1;
if (fullscreen)
{
DDBLTFX bltfx;
RECT destrect={0,0,320,240};
// clear screen
memset(&bltfx, 0,sizeof(bltfx)); // Sets dwFillColor to 0 as well
bltfx.dwSize = sizeof(bltfx);
prim->Blt(&destrect,NULL,NULL,DDBLT_WAIT|DDBLT_COLORFILL,&bltfx);
}
return 0;
}
int dxdisp::update(int any_size)
{
RECT src,dest; int ret=0;
if (!are_we_ready()) return 1;
src.left=8; src.top=8;
src.right=8+320; src.bottom=8+224;
if (fullscreen)
{
int s;
src.left=8; src.top=8;
src.right=8+320; src.bottom=8+224;
ret=prim->BltFast(0,8,buf,&src,0);
}
else
{
GetWindowRect(wnd,&dest);
dest.top+=42;
dest.bottom-=4;
dest.left+=4;
dest.right-=4;
if (!any_size)
{
int wid,hei;
wid=dest.right-dest.left;
hei=dest.bottom-dest.top;
if (wid<320) ;
else if (wid<320*2) wid=320;
else if (wid<320*3) wid=320*2;
else if (wid<320*4) wid=320*3;
if (hei<224) ;
else if (hei<224*2) hei=224;
else if (hei<224*3) hei=224*2;
else if (hei<224*4) hei=224*3;
dest.left=(dest.right+dest.left)/2;
dest.left-=wid/2;
dest.right=dest.left+wid;
dest.top=(dest.top+dest.bottom)/2;
dest.top-=hei/2;
dest.bottom=dest.top+hei;
}
ret=prim->Blt(&dest,buf,&src,DDBLT_WAIT,NULL);
if (ret!=DD_OK)
dprintf ("prim->Blt returned %x (%d)\n",ret,ret-MAKE_DDHRESULT(0));
if (ret==DDERR_SURFACELOST)
{
ret=prim->Restore();
dprintf ("Restore returned %.8x (%d)\n",ret,ret-MAKE_DDHRESULT(0));
if (ret!=DD_OK)
{ directdraw_exit(); return 1; }// Changed screen mode?
}
}
return 0;
}
struct bmap dxdisp::lock()
{
if (!are_we_ready()) { bm.data=NULL; return bm; }
if (lock_surface_to_bm(&bm,buf)!=0) { bm.data=NULL; return bm; }
return bm;
}
int dxdisp::unlock()
{
if (!are_we_ready()) return 1;
if (bm.data!=NULL) buf->Unlock(bm.data); bm.data=NULL;
return 0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -