⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 bdxdisp.cpp

📁 DGen源码最后版本
💻 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 + -