Tässä pieni esimerkki DirectDrawin käytöstä. Esimerkissä käytetään DirectDrawin 4:ttä versiota, joka on ollut muistaakseni 4. versio DirectX:n 6. versiosta lähtien. Anyway muista lisätä projektiin ddraw.lib ja dxguid.lib, jotta ohjelma suostuu kääntymään. Koodi kääntyy ainakin VC++ 6.0:lla, mutta voi kääntyä Borlandilla, tai jopa Dev-C++:ssa. Joo, mutta tässäpä pitemmittä löpinöittää koodi. Olen kommentoinut liki jokaisen rivin, mikä vain on selittämisen arvoinen.
/* Pieni DirectDraw esimerkki by HtH
* Pieni esimerkki, kuinka käytetään DirectDraw4
* Resoluution voit helposti vaihtaa muuttamalla alempana olevia vakioita.
* Muista sisällyttää projektiin ddraw.lib ja dxguid.lib, muuten koodi ei käänny!
*/
#define WIN32_LEAN_AND_MEAN // Ei MFC:tä
#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> // DirectDraw mukaan
//Makro, joka ei ole omatekemäni; katsoo näppäimenpainallukset
#define KEYDOWN(vk_code) ((GetAsyncKeyState(vk_code) & 0x8000) ? 1 : 0)
#define resox 640 //Näitä vakioita muuttamalla saat vaihdettua resoluutiota
#define resoy 480
//Tapahtuma käsittelijä; hoitaa windowsin lähettämät viestit
LRESULT CALLBACK WindowProc(HWND hwnd,
UINT msg,
WPARAM wparam,
LPARAM lparam) {
switch(msg) {
case WM_DESTROY: { // Kun ikkunaa ollaan tuhoamassa...
PostQuitMessage(0); // Lähetetään WM_QUIT viesti
return(0); //Palautetaan operaation onnistuminen Windowsille
} break;
default:break;
}
//Annetaan Windowsin hoitaa tehtävät, joista emme huolehtineet
return(DefWindowProc(hwnd, msg, wparam, lparam));
} //Tapahtumien käsittelijäin loppu
// DirectDraw rajapinta; vanha versio mukana että saamme käyttöön DirectDrawin uudemman version
LPDIRECTDRAW lpdd = NULL;
// DirectDraw rajapinta versio 4
LPDIRECTDRAW4 lpdd4 = NULL;
// Pinta, jolla piiretään
LPDIRECTDRAWSURFACE4 lpddsprimary = NULL;
DDSURFACEDESC2 ddsd;
// Paletin kuvaus
LPDIRECTDRAWPALETTE lpddpal = NULL;
// Paletin arvot
PALETTEENTRY palette[256];
int Game_Init(HWND hwnd) { // Aliohjelma, joka hoitaa alustuksen.
// Luodaan aluksi Direct Draw rajapinta
DirectDrawCreate(NULL, &lpdd, NULL);
// Vaihdetaan uudempaan versioon
lpdd->QueryInterface(IID_IDirectDraw4, (LPVOID *)&lpdd4);
// Luovutaan vanhasta
lpdd->Release();
lpdd=NULL;
// Asetetaan yhteistyötaso Windowsin kanssa
lpdd4->SetCooperativeLevel(hwnd, DDSCL_FULLSCREEN | DDSCL_ALLOWMODEX | DDSCL_EXCLUSIVE | DDSCL_ALLOWREBOOT);
// Vaihdetaan näyttötila
lpdd4->SetDisplayMode(resox, resoy, 8, 0, 0);
// Tyhjennetään ddsd
memset(&ddsd, 0, sizeof(lpdd));
// Ilmoitetaan ddsd:lle oma kokonsa
ddsd.dwSize = sizeof(ddsd);
// Kerromme ddsd:lle, että dwCaps on käytössä
ddsd.dwFlags = DDSD_CAPS;
// Asetetaan opioita
ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
// Luodaan pinta
lpdd4->CreateSurface(&ddsd, &lpddsprimary, NULL);
// Tehdään paletti
unsigned char r=0, g=0, b=0;
int jutska= 0;
for(int i = 0; i < 256; i++) {
jutska++;
r++;
if(jutska>=2) {g++; jutska=0;}
b++;
palette[i].peRed = r;
palette[i].peGreen = g;
palette[i].peBlue = b;
palette[i].peFlags = PC_NOCOLLAPSE;
}
palette[0].peRed = 0;
palette[0].peGreen = 0;
palette[0].peBlue = 0;
palette[0].peFlags = PC_NOCOLLAPSE;
// Luodaan palettirajapintaan tiedot paletista.
lpdd4->CreatePalette(DDPCAPS_8BIT | DDPCAPS_ALLOW256 | DDPCAPS_INITIALIZE,
palette, &lpddpal, NULL);
// Asetetaan paletti käyttöön pintaan.
lpddsprimary->SetPalette(lpddpal);
return(0);
}
int Game_Main(HWND hwnd) { // Tässä aliohjelmassa tapahtuu kaikki ohjelman päätapahtumat
// Escistä poistutaan ohjelmasta...
if (KEYDOWN(VK_ESCAPE))
SendMessage(hwnd,WM_CLOSE,0,0);
// Tyhjennetään ddsd
memset(&ddsd, 0, sizeof(ddsd));
// Ilmoitetaan koko
ddsd.dwSize = sizeof(ddsd);
// Lukitaan pinta, jotta voimme piirtää siihen
lpddsprimary->Lock(NULL, &ddsd, DDLOCK_SURFACEMEMORYPTR | DDLOCK_WAIT, NULL);
// Tehdään asiat vähän helpommaksi, ettemme tarvitse käyttää tyyppimuunnoksia alempana
int pitch = (int)ddsd.lPitch;
unsigned char *buffer = (unsigned char*)ddsd.lpSurface;
//Piirretään tuhat pikseliä näytölle sattumanvaraisiin kohtiin.
for(int i = 0; i < 1000; i++) {
int x = rand()%resox;
int y = rand()%resoy;
if(buffer) buffer[x+y*pitch] = rand()%256;
}
// Avataan pinta.
lpddsprimary->Unlock(NULL);
return(0);
}
int Game_Exit(HWND hwnd) { // Tätä kutsutaan poistuttaessa.
// Siivotaan vain käytetyt rajapinnat.
if(lpddpal) {lpddpal->Release();
lpddpal = NULL;}
if(lpddsprimary){lpddsprimary->Release();
lpddsprimary = NULL;}
if(lpdd4){lpdd4->Release();
lpdd4 = NULL;}
return(0);
}
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPSTR lpCmdLine, int nShowCmd) {
//Luodaan luokka
WNDCLASSEX winclass;
winclass.cbSize = sizeof(WNDCLASSEX);
winclass.style = CS_DBLCLKS | CS_OWNDC | CS_HREDRAW | CS_VREDRAW;
winclass.lpfnWndProc = WindowProc;
winclass.cbClsExtra = 0;
winclass.cbWndExtra = 0;
winclass.hInstance = hInstance;
winclass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
winclass.hCursor = LoadCursor(NULL, IDC_CROSS);
winclass.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);
winclass.lpszMenuName = "MainMenu";
winclass.lpszClassName = "WINCLASS1";
winclass.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
// Kerrotaan siitä Windowsille
RegisterClassEx(&winclass);
HWND hwnd;
MSG msg;
int t=0;
// Luodaan ikkuna
if(!(hwnd = CreateWindowEx(NULL,
"WINCLASS1",
"Ikkuna",
WS_POPUP | WS_VISIBLE,
0, 0, resox, resoy,
NULL,
LoadMenu(hInstance, "MainMenu"),
hInstance, NULL))) return(0);
// Kutsutaan alustusfunktiota
Game_Init(hwnd);
// Pääluuppi
while(TRUE) {
if(!PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) {
if(msg.message == WM_QUIT) {break;} // Jos löytyy WM_QUIT viesti, rikotaan looppi
}
// Hoidetaan viestit
TranslateMessage(&msg);
// Kutsutaan Game_Main funktiota, joka hoitaa päätapahtumat.
Game_Main(hwnd);
DispatchMessage(&msg);
}
// Siivotaan jäljet
Game_Exit(hwnd);
// Kerrotaan Windowsille onnistuminen
return(msg.wParam);
}Jeps, taas unohtu ilmoittaa, että valmiiksi käännetty versio löytyypi osoitteesta http://koti.mbnet.fi/~haraa/files/ddraw.exe
HtH pyysit IRCissä kommentoimaan tätä.
Ainaski EXEks käännetty on hieno!
Kiitti Kiitti Kiitti tosi tarpeeseen
Todella loistava esimerkki!!
Ei mitenkään erikoinen, melkein suora kopio LaMothen kirjasta "Inside Peliohjelmointi"
Aihe on jo aika vanha, joten et voi enää vastata siihen.