Skip to main content
GameDev.net gamedev.net
🔒 Locked

Strange screen offset (directdraw)

Started by KabukiWarrior Apr 6, 2005 at 6:17 PM 3 replies 1.1k views
Original Post
KabukiWarrior
KabukiWarrior
I have this directdraw program and it runs... kind of :\ it's totaly shambles I know but it's mainly just cause its only purpose right now is to put a pixl on the screen, clean up latter. The problem is that for some reason the pixel seems rather far to the right (like a the 1/5 mark) but a screen shot using print screen shows it in the correct position... I'll take both answers to the question and tips on how to improve the quality of the program :D, besides this the only other thing I've used DD for was reading the screen, luckly for me that actualy works and looks better :)

#include <windows.h>
#include <ddraw.h>

#define WIN32_LEAN_AND_MEAN
HINSTANCE ghinst = 0;
HWND mainwindow = 0;
static DDSCAPS ddscaps;
static LPDIRECTDRAW lpDD = 0;
static LPDIRECTDRAWSURFACE lpDDSPrimary; 
static LPDIRECTDRAWSURFACE lpDDSBack; 
static DDSURFACEDESC ddsd;
static PAINTSTRUCT ps; 
static HDC whdc;

bool CreatePrimarySurface();
bool DirectDrawInit();
void __forceinline updateFrame( void );
void suicide ();

long FAR PASCAL WndProc (HWND myhwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
 switch (message)
 {
  case WM_CHAR:
   if (wParam == 27)
	  PostQuitMessage(0);
   break;
  case WM_DESTROY: 
   PostQuitMessage(0);
   break;
 }
 return(DefWindowProc(myhwnd,message,wParam,lParam));
}
int FAR PASCAL WinMain (HINSTANCE hInst, HINSTANCE hPrevInst, LPSTR lpCmdLine, int nCmdShow)
 {
 WINDOWPLACEMENT status;
 WNDCLASS wc;
 HWND myhwnd=0;
 HDC hdc;
 MSG msg;
 RECT r;
 ghinst = hInst;
 wc.style = CS_HREDRAW|CS_VREDRAW;
 wc.lpfnWndProc = WndProc;
 wc.hInstance = ghinst;
 wc.cbClsExtra = 0;
 wc.cbWndExtra = 0;
 wc.hIcon = 0;
 wc.lpszMenuName = 0;
 wc.hCursor = LoadCursor(0,IDC_ARROW);
 wc.hbrBackground = (HBRUSH__ *)GetStockObject(BLACK_BRUSH);
 wc.lpszClassName = "DDClass";
 if (!RegisterClass(&wc)) return(1);

 bool mainloop = 1;
 if (!DirectDrawInit())
 {
  suicide();
  exit(0); 
 }
 CreatePrimarySurface();
 long* colour = 0;
 BYTE setpixel = 1;
 while (mainloop)
 {
 while (PeekMessage(&msg,0,0,0,PM_REMOVE))
 {
  if (msg.message == WM_QUIT)
  {mainloop = 0;}
  TranslateMessage(&msg); 
  DispatchMessage(&msg);
 }
 if(setpixel)
  {
   DDSURFACEDESC DDSurfDesc;

   ZeroMemory( &DDSurfDesc, sizeof( DDSurfDesc ));
   DDSurfDesc.dwSize = sizeof( DDSurfDesc );

   lpDDSBack->Lock( 0, &DDSurfDesc, DDLOCK_WAIT, 0 );

   colour =reinterpret_cast<long*>(DDSurfDesc.lpSurface) + 1;
  *colour = 0xFF;

   lpDDSBack->Unlock( colour );
   lpDDSPrimary->Flip( NULL, DDFLIP_WAIT );
   UpdateWindow(mainwindow);
   //lpDDSPrimary->Lock(0,&ddsd,DDLOCK_SURFACEMEMORYPTR,0);
  // colour =reinterpret_cast<long*>(ddsd.lpSurface) + 1;
  //*colour = 0x00FFFFFF;
  //lpDDSPrimary->Unlock(ddsd.lpSurface);
  }
 }
 suicide();
 return(1);
}
void suicide ()
{
 if (lpDD)
 {
  if (lpDDSPrimary)
  {
   lpDDSPrimary->Release();
   lpDDSPrimary = 0;
  }
  lpDD->Release(); lpDD = 0;
 }
 if (mainwindow)
 {
  DestroyWindow(mainwindow);
  mainwindow = 0;
 }
}


bool DirectDrawInit()
{
    HDC hdc = GetDC(0);
    mainwindow = CreateWindow("DDClass","Menu",WS_VISIBLE | WS_POPUP,0,0,GetDeviceCaps(hdc,HORZRES),GetDeviceCaps(hdc,VERTRES),0,0,ghinst,0);
    ReleaseDC(0,hdc);
    ShowCursor(0);
    HRESULT ddrval;

    ddrval = DirectDrawCreate( NULL, &lpDD, NULL );
    if( ddrval != DD_OK )
    {
        return(false);
    }

    ddrval = lpDD->SetCooperativeLevel( mainwindow, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN );
    if( ddrval != DD_OK )
    {
        lpDD->Release();
        return(false);
    }
    ddrval = lpDD->SetDisplayMode( 800, 600, 32);
    if( ddrval != DD_OK )
    {
        lpDD->Release();
        return(false);
    }

    return(true);
}
bool CreatePrimarySurface()
{
    HRESULT ddrval;
    ZeroMemory(&ddsd,sizeof(ddsd));
    ddsd.dwSize = sizeof(ddsd);

    ddsd.dwFlags = DDSD_CAPS | DDSD_BACKBUFFERCOUNT;
    ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE | DDSCAPS_FLIP | DDSCAPS_COMPLEX;
    ddsd.dwBackBufferCount = 1;

    ddrval = lpDD->CreateSurface( &ddsd, &lpDDSPrimary, NULL );
    if( ddrval != DD_OK )
    {
        lpDD->Release();
        return(false);
    }
    ddscaps.dwCaps = DDSCAPS_BACKBUFFER;
    ddrval = lpDDSPrimary->GetAttachedSurface(&ddscaps, &lpDDSBack);
    if( ddrval != DD_OK )
    {
        lpDDSPrimary->Release();
        lpDD->Release();
        return(false);
    }

    return true;
}

void __forceinline updateFrame( void )
{
    lpDDSPrimary->Flip( NULL, DDFLIP_WAIT );
} /* updateFrame */

Aldenar
Aldenar
The code looks fine ( for what it's supposed to do anyway ;) ). Are you sure that the problem is not the screen settings in 800x600 because DD will pick a default|random refresh rate for which your monitor settings may not be properly set. One way to find out is to clear the entire surface to some color and see if it covers the entire display area.

A few tips:

1. Define WIN32_LEAN_AND_MEAN before including windows.h since it's that file that uses the define :)

2. Avoid using constants such as 27 in the code, use VK_ESCAPE instead. It is easier to understand and you'll have more chances of remembering what it is supposed to do when looking at your code in the future.

3. Always check for return values of the DD calls, especially for important functions such as Lock(). It is very useful for tracing bugs.
KabukiWarrior
KabukiWarrior
oh I filled the scree and it seems the entire square is like 50 pixels to the right and 50 pixels up from the bottom.

also when it made the flip command the screen flashed black then blue a few times before it remained solid, I though flipping prevented that...

how do I fix this?

also I can't take screen shots of it any more, and I don't remember what I removed -_-' what do I need to add to take a screen shot?

[Edited by - KabukiWarrior on April 6, 2005 11:48:38 PM]
DBX
DBX
If you are going fullscreen in a mode you don't normally run in, your monitor may not be setup correctly so you'll have to manually adjust it.
KabukiWarrior
KabukiWarrior
oh and if I set the resolution to my current res (the one in use by the desktop) nothing gets displayed at all :( I'd like to figure out whats happening!

also I've added a small asm func that does all this much faster (the memory part) and it functions the exact same as the forloop so I know it's correct except for one thing: when I use inc edi it only increments the edi address 1 byte forward when it should increment it 4 bytes should it not?
(this is from my memory so the code that loops it may be incorect)
void __fastcall fastpixel(long* surface)
{
int iCount = w * h;

// we assume all data in the register is not used by others
__asm
{
// Assign pointers to register
push eax
push edi
push ecx
mov edi, [d] ; put dest addr to edi reg
mov ecx, [iCount] ; put count to ecx reg

codeloop:
mov eax, [edi]
xor eax, 0x00FFFFFF
mov [edi], eax
inc edi
dec ecx ; decrement count by 1
jnz codeloop ; jump to codeloop if not 0
pop eax
pop edi
pop ecx
}

return 1;
}

inc edi should move the address by 4 bytes shouldn't it?

also when I changed the middle where it xor's eax to this (removing the mov commands)

xor [edi] , 0x00FFFFFF

this dosn't work correctly, the entire screen is blue instead of white -_-' your help is greatly appreciated (I'm just starting ASM so this register stuff is hard to grasp :) )

[Edited by - KabukiWarrior on April 7, 2005 12:02:35 PM]

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.