Skip to main content
gamedev.net
🔒 Locked

double buffer in 16bit?

Started by edwinnie Apr 11, 2002 at 1:10 AM 5 replies 250+ views
Original Post
edwinnie
edwinnie
i am using the WGPFD book. i noe the code provided for its double buffer is in 8bit mode. so i tried to modify it to become a 16bit one. i tried 1) changing all the UCHAR to USHORT 2) adding #define _RGB16BIT(r,g,b) ((b%32)+((g%32)<<5)+((r%32)<<10)) 3) changing SCREEN_BPP to 16 4) modifying the game logic to this> // draw the next frame into the double buffer // plot 5000 random pixels for (int index=0; index<5000; index++) { int x = rand()%SCREEN_WIDTH; int y = rand()%SCREEN_HEIGHT; USHORT r = rand()%256; USHORT g = rand()%256; USHORT b = rand()%256; double_buffer[x+(y*ddsd.lPitch >> 1)] = _RGB16BIT(r,g,b); } // end for index But i jus couldnt get the thing work
MOooOM
MOooOM
Your videocard may have 565 16bpp so your macros would be

#define RGB16BIT(r,g,b) ((b%32)+((G%64)<<6)+((r%32)<<11))

I think its something like that
edwinnie
edwinnie
huh?
i dun get it

how do those values come about?
aniwae, i am using an ELSA GeForce2 card

i tried again and it still din work

HELP!!
edwinnie
edwinnie
is there any diff with the macros below?
#define _RGB16BIT565(r,g,b) ((b%32)+((g%64)<<6)+((r%32)<<11)) 

and
#define _RGB16BIT565(r,g,b) ((b>>3) | ((g>>2) << 6) | ((r>>3) <<11)) 


aniwae how does one put his code appear in this msg screen
with a white background and with scrollable bars?



[edited by - edwinnie on April 11, 2002 3:04:34 AM]

[edited by - edwinnie on April 11, 2002 3:05:14 AM]

[edited by - edwinnie on April 11, 2002 3:06:02 AM]

[edited by - edwinnie on April 11, 2002 3:18:28 AM]

[edited by - edwinnie on April 11, 2002 3:19:25 AM]

[edited by - edwinnie on April 11, 2002 3:20:08 AM]
remi
remi
check the Faq
hope it helps
"...and we all know what "undefined" means: it means it works during development, it works during testing, and it blows up in your most important customers' faces."----------Scott Meyers, "Effective C++"
edwinnie
edwinnie
ok heres my code> wats wrong wif the 16bit modifications?

       

// INCLUDES


#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <windowsx.h>
#include <mmsystem.h>
#include <iostream.h>
#include <conio.h>
#include <stdlib.h>
#include <malloc.h>
#include <memory.h>
#include <string.h>
#include <stdarg.h>
#include <stdio.h>
#include <math.h>
#include <io.h>
#include <fcntl.h>

#include <ddraw.h>


// DEFINES


#define WINDOW_CLASS_NAME "WINCLASS1"

#define WINDOW_WIDTH 640
#define WINDOW_HEIGHT 480
#define SCREEN_WIDTH 640
#define SCREEN_HEIGHT 480
#define SCREEN_BPP 16


// MACROS

// these read the keyboard asynchronously


#define KEY_DOWN(vk_code) ((GetAsyncKeyState(vk_code) & 0x8000) ? 1 : 0)
#define KEY_UP(vk_code) ((GetAsyncKeyState(vk_code) & 0x8000) ? 0 : 1)

// builds up a 16 bit color


#define _RGB16BIT565(r,g,b) ((b%32)+((g%64)<<6)+((r%32)<<11))



// TYPES //////////////////////////////////////////////////

typedef unsigned short USHORT;
typedef unsigned short WORD;
typedef unsigned char UCHAR;
typedef unsigned char BYTE;
///////////////////////////////////////////////////////////



// PROTOTYPES /////////////////////////////////////////////

int Game_Init(void *parms=NULL);
int Game_Shutdown(void *parms=NULL);
int Game_Main(void *parms=NULL);
///////////////////////////////////////////////////////////



// GLOBALS ///////////////////////////////////////////////////////////////

HWND main_window_handle = NULL; // save the window handle

HINSTANCE main_instance = NULL; // save the instance

char buffer[80]; // used to print text


LPDIRECTDRAW lpdd = NULL; // pointer to direct draw object

LPDIRECTDRAWSURFACE lpddsprimary = NULL; // pointer to primary surface

LPDIRECTDRAWSURFACE lpddsback = NULL; // pointer to back surface

LPDIRECTDRAWPALETTE lpddpal = NULL; // pointer to the created dd palette

DDSURFACEDESC ddsd; // a direct draw surface description struct

DDSCAPS ddscaps; // a direct draw surface capabilities struct

HRESULT ddrval; // result back from dd calls


USHORT *double_buffer = NULL; // the double buffer

//////////////////////////////////////////////////////////////////////////



// FUNCTIONS /////////////////////////////////////////////////////////////

LRESULT CALLBACK WindowProc(HWND hwnd, //the window

UINT msg, //the message itself

WPARAM wparam, //more info on message

LPARAM lparam) //more info on message

{
// this is the main message handler of the system

PAINTSTRUCT ps; //used in WM_PAINT

HDC hdc; //handle to a device context


// what is the message

switch(msg)
{
case WM_CREATE:
{
// do initialization stuff here

return(0); //return to event loop

} break;

case WM_PAINT:
{
//start painting & get graphics device context

hdc = BeginPaint(hwnd,&ps);

// release graphics device context

EndPaint(hwnd,&ps);
return(0);
} break;

case WM_DESTROY:
{
// post a quit message to event queue, which sends a WM_QUIT to message queue

PostQuitMessage(0);
return(0);
} break;

default:break;
} // end switch


// let windows handle anything i didn't

return (DefWindowProc(hwnd, msg, wparam, lparam));

} // end WindowProc

//////////////////////////////////////////////////////////////////////////



// WINMAIN ///////////////////////////////////////////////////////////////

int WINAPI WinMain( HINSTANCE hinstance, //handle of app.instance

HINSTANCE hprevinstance,
LPSTR lpcmdline, //pointer->cmdline parameters

int ncmdshow) //directs how init.window is to be shown

{
WNDCLASS winclass; // a declaration of a window class

HWND hwnd; // generic window handle

MSG msg; // generic message

HDC hdc; // generic dc

PAINTSTRUCT ps; // generic paintstruct


// first fill in the window class stucture

winclass.style = CS_DBLCLKS | CS_OWNDC | //style field

CS_HREDRAW | CS_VREDRAW;
winclass.lpfnWndProc = WindowProc; //function ptr that points to event handler function

winclass.cbClsExtra = 0;
winclass.cbWndExtra = 0;
winclass.hInstance = hinstance; //store instance of app.

winclass.hIcon = LoadIcon(NULL, IDI_APPLICATION); //@handle of icon to display

winclass.hCursor = LoadCursor(NULL, IDC_ARROW); //@handle to cursor

winclass.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH); //handle to backgrd brush

winclass.lpszMenuName = NULL; //name of resource for the menu attached to window

winclass.lpszClassName = WINDOW_CLASS_NAME; //name i wish to refer to my new window class


// register the window class

if (!RegisterClass(&winclass))
return(0);

// create the window

if (!(hwnd = CreateWindow(WINDOW_CLASS_NAME, //@preregistered clas

"Crystal Breakers", //@title of window

WS_POPUP | WS_VISIBLE, //@window creation style flags

0,0, //x,y positions to open window at

WINDOW_WIDTH, //width of SCREEN

WINDOW_HEIGHT, //height of SCREEN

NULL, //handle to parent

NULL, //handle to menu

hinstance, //instance from WinMain

NULL))) //creation parms

return(0);

// save the window handle in a global

main_window_handle = hwnd;
main_instance = hinstance;


// perform all game console specific initialization

Game_Init();

// enter main event loop, loop until there is a WM_QUIT message

while(1)
{
if (PeekMessage(&msg,NULL,0,0,PM_REMOVE)) //pointed msg structure

{
// test if this is a quit

if (msg.message == WM_QUIT)
break;

// translate any accelerator keys

TranslateMessage(&msg);

// send the message to the window proc

DispatchMessage(&msg);
} // end if


// main game processing goes here

Game_Main();


} // end while


// shutdown game and release all resources

Game_Shutdown();

// return to Windows like this

return(msg.wParam);

} // end WinMain

/////////////////////////////////////////////////////////////////



//////////////////////////////////////////////////////////////////////////

// WINX GAME PROGRAMMING CONSOLE FUNCTIONS //

////////////////////////////////////////////////////////////////////////////

int Game_Init(void *parms)

{
// this function is where you do all the initialization for your game


//--------------------------------------------------------------------------

// create object and test for error

if (DirectDrawCreate(NULL,&lpdd,NULL)!=DD_OK)
return(0);

// set cooperation level to windowed mode normal

if ((lpdd->SetCooperativeLevel(main_window_handle,
DDSCL_ALLOWMODEX | DDSCL_FULLSCREEN |
DDSCL_EXCLUSIVE | DDSCL_ALLOWREBOOT))!=DD_OK)
return(0);

// set the display mode

if ((lpdd->SetDisplayMode(SCREEN_WIDTH,SCREEN_HEIGHT,SCREEN_BPP))!=DD_OK)
return(0);
//--------------------------------------------------------------------------


//--------------------------------------------------------------------------

// Create the primary surface

memset(&ddsd,0,sizeof(ddsd));
ddsd.dwSize = sizeof(ddsd);

/*indicate the flags i wan in a primary drawing surface*/
ddsd.dwFlags = DDSD_CAPS;

/*set capabilities for primary surface*/

ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;

if (lpdd->CreateSurface(&ddsd,&lpddsprimary,NULL)!=DD_OK)
return(0);
//--------------------------------------------------------------------------


//--------------------------------------------------------------------------

// allocate memory for the double buffer

if ((double_buffer = (USHORT *)malloc(SCREEN_WIDTH*SCREEN_HEIGHT))==NULL)
return(0); //

//--------------------------------------------------------------------------


// return success

return(1);
} // end Game_Init

////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////

int Game_Shutdown(void *parms)
{
// this function is where you shutdown your game and

// release all resources that you allocated


// first release the primary surface

if (lpddsprimary!=NULL)
lpddsprimary->Release();

// release the directdraw object

if (lpdd!=NULL)
lpdd->Release();

// free double buffer

if (double_buffer!=NULL)
free(double_buffer);

// return success

return(1);
} // end Game_Shutdown

////////////////////////////////////////////////////////////////////////////


int Game_Main(void *parms)
{
// this is the workhorse of your game it will be called

// continuously in real-time this is like main() in C

// all the calls for you game go here!


//--------------------------------------------------------------------------

//use this to access surface memory

USHORT *primary_buffer = NULL, // used to draw

*dest_ptr = NULL, // used in line by line copy //

*src_ptr = NULL; // " "


// this will hold the number of 16 bit words per video line

//int words_per_line = 0;


//MACROS //

// trying to escape

if (KEY_DOWN(VK_ESCAPE))
{ //@other details?

PostMessage(main_window_handle,WM_DESTROY,0,0);
} // end if


// compute words per line

//words_per_line = (ddsd.lPitch >> 1);

//--------------------------------------------------------------------------


//--------------------------------------------------------------------------

// erase double buffer

memset(double_buffer,0, SCREEN_WIDTH*SCREEN_HEIGHT);
//--------------------------------------------------------------------------



// perform game logic...


// draw the next frame into the double buffer

// plot 5000 random pixels

for (int index=0; index<5000; index++)
{
int x = rand()%SCREEN_WIDTH;
int y = rand()%SCREEN_HEIGHT;

// get random color

UCHAR r = rand()%256;
UCHAR g = rand()%256;
UCHAR b = rand()%256;

double_buffer[x + (y*ddsd.lPitch >> 1)] = (USHORT)_RGB16BIT565(r,g,b);
} // end for index


//--------------------------------------------------------------------------

// set up surface description to lock the surface

// zero out data structure and set its size

memset(&ddsd,0,sizeof(ddsd));
ddsd.dwSize = sizeof(ddsd);

// lock the primary surface, note in a real game you would

// do this once per frame

lpddsprimary->Lock(NULL,&ddsd,
DDLOCK_SURFACEMEMORYPTR | DDLOCK_WAIT,NULL);

// get video pointer

primary_buffer = (USHORT *)ddsd.lpSurface;
//--------------------------------------------------------------------------


//--------------------------------------------------------------------------

// test if memory is linear

if (ddsd.lPitch == SCREEN_WIDTH)
{
// copy memory from double buffer to primary buffer

memcpy(primary_buffer, double_buffer, SCREEN_WIDTH*SCREEN_HEIGHT);
} // end if

else
{ // non-linear

// make copy of source and destination addresses

dest_ptr = primary_buffer;
src_ptr = double_buffer;

// memory is non-linear, copy line by line

for (int y=0; y<SCREEN_HEIGHT; y++)
{
// copy line

memcpy(dest_ptr, src_ptr, SCREEN_WIDTH);

// advance pointers to next line

dest_ptr+=ddsd.lPitch;
src_ptr+=SCREEN_WIDTH;

// note: the above code code be replaced with the simpler

// memcpy(&primary_buffer[y*ddsd.lPitch], double_buffer[y*SCREEN_WIDTH], SCREEN_WIDTH);

// but it is much slower due to the recalculation and multiplication each cycle


} // end for


} // end else

//--------------------------------------------------------------------------


//--------------------------------------------------------------------------

// unlock the surface, very important!

lpddsprimary->Unlock(primary_buffer);
//--------------------------------------------------------------------------


// synchronize video to some constant rate

Sleep(5);

// return success

return(1);
} // end Game_Main








[edited by - edwinnie on April 11, 2002 3:46:19 AM]

[edited by - edwinnie on April 11, 2002 3:48:15 AM]

[edited by - edwinnie on April 11, 2002 3:49:45 AM]
siaspete
siaspete
Firstly, you''re not allocating enough memory for your double buffer. Secondly why are you doing this yourself and not using a DirectDraw surface?

I''m pretty sure the DirectDraw docs tell you how to set this up.


Helpful links:
How To Ask Questions The Smart Way | Google can help with your question | Search MSDN for help with standard C or Windows functions

Topic Locked

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

Sign in to reply to this topic.