DanieleC88
02-09-2003, 18:05
Usando Dev-C++ 4, sto cercando di creare un gioco 2D stile Raptor, ma purtroppo non riesco a disegnare le bitmap. Il codice che sto usando e' solo un test, ma non capisco dove io sbagli (non vi ho incluso i file resource.rc e resource.h perche' li potreste facilmente riscrivare anche voi.)
Questo e' il mio codice:
//General including section
#include <windows.h>
//Custom including section
#include "resource.h"
/* Constants declarations */
#define FAIL -1
/* Types declarations */
typedef struct SCREEN {
int width, height, bpp;
};
/* General declarations */
HINSTANCE hinst; //instance handle
SCREEN screen; //screen params
HWND hwnd; //window handle
HDC hdc; //device context
int rc; //return code
/* Bitmaps declarations */
HBITMAP hback; /* handle */
BITMAP sback; /* size */
/* Declare Windows procedure */
LRESULT CALLBACK WindowProcedure (HWND, UINT, WPARAM, LPARAM);
/* Make the class name into a global variable */
char *szClassName = "GDI";
char *lpAppName = "Raptor";
void GetScreenMode (SCREEN *scr)
{
HDC sdc; //screen device context
sdc = CreateDC ("DISPLAY", NULL, NULL, NULL);
/* Get screen params */
scr->width = GetDeviceCaps (hdc, HORZRES);
scr->height = GetDeviceCaps (hdc, VERTRES);
scr->bpp = GetDeviceCaps (hdc, BITSPIXEL);
DeleteDC (sdc);
}
void ResizeWindow (HWND hwin, int w, int h)
{
RECT wrec;
GetWindowRect (hwin, &wrec);
MoveWindow (hwnd, wrec.left, wrec.top, w, h, TRUE);
}
/* ------------------------------------------------------------------------- */
/* MAIN PROCEDURE */
/* ------------------------------------------------------------------------- */
int WINAPI WinMain (HINSTANCE hThisInstance,
HINSTANCE hPrevInstance,
LPSTR lpszArgument,
int nFunsterStil)
{
HDC bdc; /* Bitmap device context */
HPEN hpen; /* Custom color pen */
POINT mpos; /* Mouse position */
MSG messages; /* Here messages to the application are saved */
BOOL ldFailed; /* To check if the loading is failed */
DEVMODE cdsdm; /* ChangeDisplaySettings Device Mode */
WNDCLASSEX wincl; /* Data structure for the windowclass */
//General assignements that don't deserve to load nothing
ldFailed = FALSE;
/* First of all, we must load the GDI bitmaps. */
/* Bitmaps are the heart of a 2D game, and if */
/* they're not loaded, there is no reason to */
/* continue with creating classes or windows. */
//Setting the hinst variable
hinst = hThisInstance;
// Default is the BITMAPS directory
// We declared bitmap files in our RESOURCE
// ----------------------------------------
// Background bitmap
hback = LoadBitmap (hinst, MAKEINTRESOURCE (BMPBACKGROUND));
if (hback == NULL || !hback) ldFailed = TRUE;
if (ldFailed) {
MessageBox (0, "Cannot load game bitmaps.\n\n"
"Please, make sure that the folder \"bitmaps\" "
"is in the main game folder and that it contains "
"valid 24-bit bitmaps.", lpAppName, MB_ICONERROR);
//return FAIL;
}
/* The Window structure */
wincl.hInstance = hThisInstance;
wincl.lpszClassName = szClassName;
wincl.lpfnWndProc = WindowProcedure; /* This function is called by Windows */
wincl.style = CS_DBLCLKS; /* Catch double-clicks */
wincl.cbSize = sizeof (WNDCLASSEX);
/* Use default icon and mouse-pointer */
wincl.hIcon = LoadIcon (NULL, IDI_APPLICATION);
wincl.hIconSm = LoadIcon (NULL, IDI_APPLICATION);
wincl.hCursor = LoadCursor (NULL, IDC_ARROW);
wincl.lpszMenuName = NULL; /* No menu */
wincl.cbClsExtra = 0; /* No extra bytes after the window class */
wincl.cbWndExtra = 0; /* structure or the window instance */
/* Use Windows's default color as the background of the window */
wincl.hbrBackground = (HBRUSH) NULL;
/* Register the window class, and if it fails quit the program */
if (!RegisterClassEx (&wincl))
return FAIL;
/* The class is registered, let's create the window */
hwnd = CreateWindowEx (
0, /* Extended possibilites for variation */
szClassName, /* Classname */
"GDI Game", /* Title Text */
WS_POPUPWINDOW, /* default window */
CW_USEDEFAULT, /* Windows decides the position */
CW_USEDEFAULT, /* where the window ends up on the screen */
0, /* The programs width */
0, /* and height in pixels */
HWND_DESKTOP, /* The window is a child-window to desktop */
NULL, /* No menu */
hThisInstance, /* Program Instance handler */
NULL /* No Window Creation data */
);
hdc = GetDC(hwnd);
/* Get screen settings */
GetScreenMode (&screen);
/* Set screen mode */
ZeroMemory (&cdsdm, sizeof (cdsdm));
cdsdm.dmBitsPerPel = 24; //color depth
cdsdm.dmPelsWidth = 640; //x-resolution
cdsdm.dmPelsHeight = 480; //y-resolution
cdsdm.dmFields = (DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT);
if (!(screen.bpp >= 24) || (screen.height != 480) || (screen.width != 640)) {
rc = ChangeDisplaySettings (&cdsdm, CDS_FULLSCREEN);
} else
rc = DISP_CHANGE_SUCCESSFUL;
if (rc != DISP_CHANGE_SUCCESSFUL) {
MessageBox (hwnd, "Cannot change display mode.\n\n"
"Maybe your color depth is too low. Try to change it to "
"24-bit and restart Windows if asked. After restarting "
"Windows, start again the game. If you see this message "
"again, then you'd better check up your monitor and video "
"card capabilities.", lpAppName, MB_ICONERROR);
//DestroyWindow (hwnd);
//return FAIL;
}
/* Refresh screen settings */
GetScreenMode (&screen);
/* Resize the window */
ResizeWindow (hwnd, screen.width, screen.height);
/* Make the window visible on the screen */
ShowWindow (hwnd, nFunsterStil);
hpen = CreatePen (PS_SOLID, 0x0, 0xCCCCCC);
SelectObject (hdc, hpen);
GetCursorPos (&mpos);
MoveToEx (hdc, mpos.x, mpos.y, NULL);
/* Run the message loop. It will run until GetMessage() returns 0 */
while (GetMessage (&messages, NULL, 0, 0))
{
/* Translate virtual-key messages into character messages */
TranslateMessage(&messages);
/* Send message to WindowProcedure */
DispatchMessage(&messages);
/* The main game loop. We must do all here. */
GetCursorPos (&mpos);
LineTo (hdc, mpos.x, mpos.y);
bdc = CreateCompatibleDC (hdc); /* create a bitmap DC */
GetObject (hback, sizeof(sback), &sback); /* get bitmap size */
SelectObject (bdc, hback); /* select bitmap */
BitBlt (hdc, mpos.x, mpos.y, /* draw bitmap */
(mpos.x + sback.bmWidth), (mpos.y + sback.bmHeight),
bdc, sback.bmWidth, sback.bmHeight, SRCCOPY);
DeleteDC (bdc); /* delete bitmap DC */
}
/* We must destroy our HGDIOBJ */
DeleteObject (hpen);
DeleteObject (hback);
/* Restore screen mode */
cdsdm.dmBitsPerPel = screen.bpp;
cdsdm.dmPelsWidth = screen.width;
cdsdm.dmPelsHeight = screen.height;
cdsdm.dmFields = (DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT);
rc = ChangeDisplaySettings (&cdsdm, 0);
if (rc != DISP_CHANGE_SUCCESSFUL) {
MessageBox (hwnd, "Cannot restore display mode.\n\n"
"You can manually restore it by right-clicking the "
"desktop, selecting \"Properties\", switching to tab "
"\"Settings\" and changing the resolution with the "
"slider and the color depth with the combo box.",
lpAppName, MB_ICONERROR);
return FAIL;
}
/* The program return-value is 0 - The value that PostQuitMessage() gave */
return messages.wParam;
}
/* This function is called by the Windows function DispatchMessage() */
LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message) /* handle the messages */
{
case WM_KEYDOWN:
int keycode;
keycode = (int)wParam;
if (keycode == VK_ESCAPE) DestroyWindow(hwnd);
break;
case WM_ERASEBKGND: /* VERY COOOOL without it ! */
HBRUSH hodb; HPEN hopn; // old brush - old pen
HBRUSH htbr; HPEN hnwp; // new brush - new pen
RECT winr; // window rect
GetWindowRect (hwnd, &winr);
htbr = CreateSolidBrush (0x000000); hnwp = CreatePen(PS_SOLID, 0x0, 0x0);
hodb = (HBRUSH) SelectObject (hdc, htbr);
hopn = (HPEN) SelectObject (hdc, hnwp);
Rectangle (hdc, winr.left, winr.top, winr.right, winr.bottom);
SelectObject (hdc, hopn); SelectObject (hdc, hodb);
DeleteObject (htbr); DeleteObject (hnwp);
break;
case WM_DESTROY:
PostQuitMessage (0); /* send a WM_QUIT to the message queue */
break;
default: /* for messages that we don't deal with */
return DefWindowProc (hwnd, message, wParam, lParam);
}
return 0;
}
continuo a non capire dove sia l'errore.
Questo e' il mio codice:
//General including section
#include <windows.h>
//Custom including section
#include "resource.h"
/* Constants declarations */
#define FAIL -1
/* Types declarations */
typedef struct SCREEN {
int width, height, bpp;
};
/* General declarations */
HINSTANCE hinst; //instance handle
SCREEN screen; //screen params
HWND hwnd; //window handle
HDC hdc; //device context
int rc; //return code
/* Bitmaps declarations */
HBITMAP hback; /* handle */
BITMAP sback; /* size */
/* Declare Windows procedure */
LRESULT CALLBACK WindowProcedure (HWND, UINT, WPARAM, LPARAM);
/* Make the class name into a global variable */
char *szClassName = "GDI";
char *lpAppName = "Raptor";
void GetScreenMode (SCREEN *scr)
{
HDC sdc; //screen device context
sdc = CreateDC ("DISPLAY", NULL, NULL, NULL);
/* Get screen params */
scr->width = GetDeviceCaps (hdc, HORZRES);
scr->height = GetDeviceCaps (hdc, VERTRES);
scr->bpp = GetDeviceCaps (hdc, BITSPIXEL);
DeleteDC (sdc);
}
void ResizeWindow (HWND hwin, int w, int h)
{
RECT wrec;
GetWindowRect (hwin, &wrec);
MoveWindow (hwnd, wrec.left, wrec.top, w, h, TRUE);
}
/* ------------------------------------------------------------------------- */
/* MAIN PROCEDURE */
/* ------------------------------------------------------------------------- */
int WINAPI WinMain (HINSTANCE hThisInstance,
HINSTANCE hPrevInstance,
LPSTR lpszArgument,
int nFunsterStil)
{
HDC bdc; /* Bitmap device context */
HPEN hpen; /* Custom color pen */
POINT mpos; /* Mouse position */
MSG messages; /* Here messages to the application are saved */
BOOL ldFailed; /* To check if the loading is failed */
DEVMODE cdsdm; /* ChangeDisplaySettings Device Mode */
WNDCLASSEX wincl; /* Data structure for the windowclass */
//General assignements that don't deserve to load nothing
ldFailed = FALSE;
/* First of all, we must load the GDI bitmaps. */
/* Bitmaps are the heart of a 2D game, and if */
/* they're not loaded, there is no reason to */
/* continue with creating classes or windows. */
//Setting the hinst variable
hinst = hThisInstance;
// Default is the BITMAPS directory
// We declared bitmap files in our RESOURCE
// ----------------------------------------
// Background bitmap
hback = LoadBitmap (hinst, MAKEINTRESOURCE (BMPBACKGROUND));
if (hback == NULL || !hback) ldFailed = TRUE;
if (ldFailed) {
MessageBox (0, "Cannot load game bitmaps.\n\n"
"Please, make sure that the folder \"bitmaps\" "
"is in the main game folder and that it contains "
"valid 24-bit bitmaps.", lpAppName, MB_ICONERROR);
//return FAIL;
}
/* The Window structure */
wincl.hInstance = hThisInstance;
wincl.lpszClassName = szClassName;
wincl.lpfnWndProc = WindowProcedure; /* This function is called by Windows */
wincl.style = CS_DBLCLKS; /* Catch double-clicks */
wincl.cbSize = sizeof (WNDCLASSEX);
/* Use default icon and mouse-pointer */
wincl.hIcon = LoadIcon (NULL, IDI_APPLICATION);
wincl.hIconSm = LoadIcon (NULL, IDI_APPLICATION);
wincl.hCursor = LoadCursor (NULL, IDC_ARROW);
wincl.lpszMenuName = NULL; /* No menu */
wincl.cbClsExtra = 0; /* No extra bytes after the window class */
wincl.cbWndExtra = 0; /* structure or the window instance */
/* Use Windows's default color as the background of the window */
wincl.hbrBackground = (HBRUSH) NULL;
/* Register the window class, and if it fails quit the program */
if (!RegisterClassEx (&wincl))
return FAIL;
/* The class is registered, let's create the window */
hwnd = CreateWindowEx (
0, /* Extended possibilites for variation */
szClassName, /* Classname */
"GDI Game", /* Title Text */
WS_POPUPWINDOW, /* default window */
CW_USEDEFAULT, /* Windows decides the position */
CW_USEDEFAULT, /* where the window ends up on the screen */
0, /* The programs width */
0, /* and height in pixels */
HWND_DESKTOP, /* The window is a child-window to desktop */
NULL, /* No menu */
hThisInstance, /* Program Instance handler */
NULL /* No Window Creation data */
);
hdc = GetDC(hwnd);
/* Get screen settings */
GetScreenMode (&screen);
/* Set screen mode */
ZeroMemory (&cdsdm, sizeof (cdsdm));
cdsdm.dmBitsPerPel = 24; //color depth
cdsdm.dmPelsWidth = 640; //x-resolution
cdsdm.dmPelsHeight = 480; //y-resolution
cdsdm.dmFields = (DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT);
if (!(screen.bpp >= 24) || (screen.height != 480) || (screen.width != 640)) {
rc = ChangeDisplaySettings (&cdsdm, CDS_FULLSCREEN);
} else
rc = DISP_CHANGE_SUCCESSFUL;
if (rc != DISP_CHANGE_SUCCESSFUL) {
MessageBox (hwnd, "Cannot change display mode.\n\n"
"Maybe your color depth is too low. Try to change it to "
"24-bit and restart Windows if asked. After restarting "
"Windows, start again the game. If you see this message "
"again, then you'd better check up your monitor and video "
"card capabilities.", lpAppName, MB_ICONERROR);
//DestroyWindow (hwnd);
//return FAIL;
}
/* Refresh screen settings */
GetScreenMode (&screen);
/* Resize the window */
ResizeWindow (hwnd, screen.width, screen.height);
/* Make the window visible on the screen */
ShowWindow (hwnd, nFunsterStil);
hpen = CreatePen (PS_SOLID, 0x0, 0xCCCCCC);
SelectObject (hdc, hpen);
GetCursorPos (&mpos);
MoveToEx (hdc, mpos.x, mpos.y, NULL);
/* Run the message loop. It will run until GetMessage() returns 0 */
while (GetMessage (&messages, NULL, 0, 0))
{
/* Translate virtual-key messages into character messages */
TranslateMessage(&messages);
/* Send message to WindowProcedure */
DispatchMessage(&messages);
/* The main game loop. We must do all here. */
GetCursorPos (&mpos);
LineTo (hdc, mpos.x, mpos.y);
bdc = CreateCompatibleDC (hdc); /* create a bitmap DC */
GetObject (hback, sizeof(sback), &sback); /* get bitmap size */
SelectObject (bdc, hback); /* select bitmap */
BitBlt (hdc, mpos.x, mpos.y, /* draw bitmap */
(mpos.x + sback.bmWidth), (mpos.y + sback.bmHeight),
bdc, sback.bmWidth, sback.bmHeight, SRCCOPY);
DeleteDC (bdc); /* delete bitmap DC */
}
/* We must destroy our HGDIOBJ */
DeleteObject (hpen);
DeleteObject (hback);
/* Restore screen mode */
cdsdm.dmBitsPerPel = screen.bpp;
cdsdm.dmPelsWidth = screen.width;
cdsdm.dmPelsHeight = screen.height;
cdsdm.dmFields = (DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT);
rc = ChangeDisplaySettings (&cdsdm, 0);
if (rc != DISP_CHANGE_SUCCESSFUL) {
MessageBox (hwnd, "Cannot restore display mode.\n\n"
"You can manually restore it by right-clicking the "
"desktop, selecting \"Properties\", switching to tab "
"\"Settings\" and changing the resolution with the "
"slider and the color depth with the combo box.",
lpAppName, MB_ICONERROR);
return FAIL;
}
/* The program return-value is 0 - The value that PostQuitMessage() gave */
return messages.wParam;
}
/* This function is called by the Windows function DispatchMessage() */
LRESULT CALLBACK WindowProcedure (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message) /* handle the messages */
{
case WM_KEYDOWN:
int keycode;
keycode = (int)wParam;
if (keycode == VK_ESCAPE) DestroyWindow(hwnd);
break;
case WM_ERASEBKGND: /* VERY COOOOL without it ! */
HBRUSH hodb; HPEN hopn; // old brush - old pen
HBRUSH htbr; HPEN hnwp; // new brush - new pen
RECT winr; // window rect
GetWindowRect (hwnd, &winr);
htbr = CreateSolidBrush (0x000000); hnwp = CreatePen(PS_SOLID, 0x0, 0x0);
hodb = (HBRUSH) SelectObject (hdc, htbr);
hopn = (HPEN) SelectObject (hdc, hnwp);
Rectangle (hdc, winr.left, winr.top, winr.right, winr.bottom);
SelectObject (hdc, hopn); SelectObject (hdc, hodb);
DeleteObject (htbr); DeleteObject (hnwp);
break;
case WM_DESTROY:
PostQuitMessage (0); /* send a WM_QUIT to the message queue */
break;
default: /* for messages that we don't deal with */
return DefWindowProc (hwnd, message, wParam, lParam);
}
return 0;
}
continuo a non capire dove sia l'errore.