📄 main.cpp
字号:
}
// Obtain an interface to the system keyboard device
if( FAILED( hReturn = pDI->CreateDevice(
GUID_SysKeyboard,
&pKeyboard,
NULL ) ) ) {
return( INPUTERROR_NOKEYBOARD );
}
// Create buffer to hold keyboard data
ZeroMemory( &dipdw, sizeof( DIPROPDWORD ) );
dipdw.diph.dwSize = sizeof( DIPROPDWORD );
dipdw.diph.dwHeaderSize = sizeof( DIPROPHEADER );
dipdw.diph.dwObj = 0;
dipdw.diph.dwHow = DIPH_DEVICE;
dipdw.dwData = KEYBOARD_BUFFERSIZE;
// Set the size of the buffer
if( FAILED( hReturn = pKeyboard->SetProperty(
DIPROP_BUFFERSIZE,
&dipdw.diph ) ) ) {
return( INPUTERROR_NOKEYBOARD );
}
// Set the format of the keyboard
if( FAILED( hReturn = pKeyboard->SetDataFormat(
&c_dfDIKeyboard ) ) ) {
return( INPUTERROR_NOKEYBOARD );
}
// Set the co-operative level to exclusive access
if( FAILED( hReturn = pKeyboard->SetCooperativeLevel(
hWnd,
DISCL_NONEXCLUSIVE | DISCL_FOREGROUND
) ) ) {
return( INPUTERROR_NOKEYBOARD );
}
// Acquire the keyboard device
pKeyboard->Acquire();
// Get the keyboard layout, this is required
// for converting scan codes to ascii codes.
g_Layout = GetKeyboardLayout( 0 );
return( INPUTERROR_SUCCESS );
}
//-----------------------------------------------------------------------------
//
// Reads the keyboard data buffer for input actions
//
//-----------------------------------------------------------------------------
int iReadKeyboard( void )
{
HRESULT hr;
DWORD dwCurBuffer;
DIDEVICEOBJECTDATA didKeyboardBuffer[KEYBOARD_BUFFERSIZE];
DWORD dwItems = KEYBOARD_BUFFERSIZE;
BYTE byteASCII;
// Dont try to read the keyboard if the interface or device is invalid
if( !pKeyboard || !pDI ) {
return( INPUTERROR_NOKEYBOARD );
}
// Read the buffered data
hr = pKeyboard->GetDeviceData(
sizeof( DIDEVICEOBJECTDATA ),
didKeyboardBuffer,
&dwItems,
0 );
// Keyboard may have been lost, reacquire it
if( FAILED( hr ) ) {
pKeyboard->Acquire();
return( INPUTERROR_SUCCESS );
}
// Process data if there is data to read
if ( dwItems ) {
// Process the data
for( dwCurBuffer = 0; dwCurBuffer < dwItems; dwCurBuffer++ ) {
// Default all keys to being "up"
for( int j = 0; j < 256; j++ ) {
ascKeys[ j ][ dwCurBuffer ] = 0;
diks[ j ][ dwCurBuffer ] = 0;
}
// Map scan-code to ascii code
byteASCII = Scan2Ascii( didKeyboardBuffer[dwCurBuffer].dwOfs );
// Set key to be down (depressed)
if( didKeyboardBuffer[ dwCurBuffer ].dwData & 0x80 ) {
ascKeys[ byteASCII ][ dwCurBuffer ] = 1;
diks[ didKeyboardBuffer[ dwCurBuffer ].dwOfs ]
[ dwCurBuffer ] = 1;
// Check if SHIFT key changed
if( didKeyboardBuffer[ dwCurBuffer ].dwOfs == DIK_LSHIFT ||
didKeyboardBuffer[ dwCurBuffer ].dwOfs == DIK_RSHIFT ) {
g_bShift = 1;
}
}
// Set key to be up
else {
ascKeys[ byteASCII ][ dwCurBuffer ] = 0;
diks[ didKeyboardBuffer[ dwCurBuffer ].dwOfs ]
[ dwCurBuffer ] = 0;
// Check if SHIFT key changed
if( didKeyboardBuffer[ dwCurBuffer ].dwOfs == DIK_LSHIFT ||
didKeyboardBuffer[ dwCurBuffer ].dwOfs == DIK_RSHIFT ) {
g_bShift = 0;
}
}
}
}
// Return # of items read
return ( dwItems );
}
//-----------------------------------------------------------------------------
//
// Converts scan codes to ASCII codes
//
//-----------------------------------------------------------------------------
BYTE Scan2Ascii( DWORD scancode )
{
UINT vk;
// Map the scancode to an ascii code
vk = MapVirtualKeyEx( scancode, 1, g_Layout);
// Map to lower-case
vk = tolower( vk );
// Return the ascii code
return( vk );
}
void vCheckInput( void )
{
//
// KEYBOARD INPUT
//
// Read from the keyboard buffer
int iResult = iReadKeyboard();
// Check how many key presses were returned
if( iResult ) {
// Loop through result data
for( int i = 0; i < iResult; i++ ) {
// Exit the program if the ESC key is hit
if( diks[ DIK_ESCAPE ][ i ] ) {
PostQuitMessage( 0 );
}
//
// SCROLL AROUND THE MAP
//
// Up
if( diks[ DIK_UP ][ i ] ) {
g_iYPos--;
}
// Down
if( diks[ DIK_DOWN ][ i ] ) {
g_iYPos++;
}
// Left
if( diks[ DIK_LEFT ][ i ] ) {
g_iXPos--;
}
// Right
if( diks[ DIK_RIGHT ][ i ] ) {
g_iXPos++;
}
// Make sure in bounds
if( g_iYPos < 0 )
g_iYPos = 0;
else if ( g_iYPos >= (g_iMapHeight-g_iTilesHigh) )
g_iYPos = (g_iMapHeight-g_iTilesHigh);
if( g_iXPos < 0 )
g_iXPos = 0;
else if ( g_iXPos >= (g_iMapWidth-g_iTilesWide) )
g_iXPos = (g_iMapWidth-g_iTilesWide);
}
}
}
void vCreateToolbar(HWND hwnd, HINSTANCE hinst)
{
WNDCLASSEX wcToolBar;
// Set up and register toolbar window class
wcToolBar.cbSize = sizeof(wcToolBar);
wcToolBar.style = CS_HREDRAW | CS_VREDRAW;
wcToolBar.lpfnWndProc = fnMessageProcessor;
wcToolBar.cbClsExtra = 0;
wcToolBar.cbWndExtra = 0;
wcToolBar.hInstance = hinst;
wcToolBar.hIcon = LoadIcon( NULL, IDI_APPLICATION );
wcToolBar.hCursor = LoadCursor( NULL, IDC_ARROW );
wcToolBar.hbrBackground = (HBRUSH) GetStockObject (COLOR_BACKGROUND);
wcToolBar.lpszMenuName = NULL;
wcToolBar.lpszClassName = "ToolBar"; // Registered Class Name
wcToolBar.hIconSm = LoadIcon( NULL, IDI_APPLICATION );
RegisterClassEx(&wcToolBar);
// Create toolbar window
hWndToolBar = CreateWindowEx (
WS_EX_LEFT|WS_EX_TOPMOST|WS_EX_TOOLWINDOW,
"ToolBar", "ToolBar",
WS_BORDER | WS_VISIBLE | WS_CAPTION | WS_MINIMIZEBOX,
g_iWindowWidth-100, g_iYOffset, 100, g_iWindowHeight-20, hwnd, NULL, hinst, NULL);
// Previous Tile Button
hBUTTON_PREVTILE = CreateWindow(
"BUTTON", "<",
WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON,
10, 405, 20, 20, hWndToolBar, (HMENU)ID_BUTTON_PREVTILE, hinst, NULL);
// Next Tile Button
hBUTTON_NEXTTILE = CreateWindow(
"BUTTON", ">",
WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON,
65, 405, 20, 20, hWndToolBar, (HMENU)ID_BUTTON_NEXTTILE, hinst, NULL);
// Save Button
hBUTTON_SAVE = CreateWindow(
"BUTTON", "Save",
WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON,
5, 365, 85, 20, hWndToolBar, (HMENU)ID_BUTTON_SAVE, hinst, NULL);
// Load Button
hBUTTON_LOAD = CreateWindow(
"BUTTON", "Load",
WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON,
5, 325, 85, 20, hWndToolBar, (HMENU)ID_BUTTON_LOAD, hinst, NULL);
// Activate edit area
SetActiveWindow( g_hWnd );
// Render toolbar tileset
vRenderTileSet();
}
void vPreviousTile( void )
{
if( g_iCurTileSet > 0 )
g_iCurTileSet--;
vRenderTileSet();
SetActiveWindow( g_hWnd );
}
void vNextTile( void )
{
if( g_iCurTileSet < g_iMaxTileSet )
g_iCurTileSet++;
vRenderTileSet();
SetActiveWindow( g_hWnd );
}
void vRenderTileSet(void)
{
RECT rectDest;
RECT rectSrc;
int iX;
int iY;
int iTile;
// Turn on ambient lighting
g_pd3dDevice->SetRenderState( D3DRS_AMBIENT, 0x00606060 );
// Clear the backbuffer and the zbuffer
g_pd3dDevice->Clear( 0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0,0,0), 1.0f, 0 );
// Begin Rendering
g_pd3dDevice->BeginScene();
// Set alpha blending states
// This is used to provide transparency/translucency
g_pd3dDevice->SetRenderState( D3DRS_ALPHABLENDENABLE, TRUE );
g_pd3dDevice->SetRenderState( D3DRS_SRCBLEND, D3DBLEND_SRCALPHA );
g_pd3dDevice->SetRenderState( D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA );
// Display active tiles
for( iY = 0; iY < 7; iY++ ) {
for( iX = 0; iX < 3; iX++ ) {
// Calculate tile to render
iTile = (g_iCurTileSet*21)+(iX+(iY*3));
// Render if valid tile
if( iTile < g_iTotalTiles ) {
vDrawInterfaceObject(
iX*g_iTileSize,
iY*g_iTileSize,
(float)g_iTileSize,
(float)g_iTileSize,
iTile );
}
// Draw overlay to show which
// tile is selected
if( iTile == g_iCurTile ) {
vDrawInterfaceObject(
iX*g_iTileSize,
iY*g_iTileSize,
(float)g_iTileSize,
(float)g_iTileSize,
18 );
}
}
}
// Display a red box around the
// current tile selected
vDrawInterfaceObject(
32,
32*7,
(float)g_iTileSize,
(float)g_iTileSize,
g_iCurTile );
// Stop Rendering
g_pd3dDevice->EndScene();
//
// Output the scene
//
// Source rectangle
rectSrc.top = 0;
rectSrc.bottom = g_iTileSize*8;
rectSrc.left = 0;
rectSrc.right = g_iTileSize*3;
// Destination rectangle
rectDest.top = 0;
rectDest.bottom = (g_iTileSize*8);
rectDest.left = 0;
rectDest.right = (g_iTileSize*3);
// Present the results
g_pd3dDevice->Present( &rectSrc, &rectDest, hWndToolBar, NULL );
}
void vCheckMouse( void )
{
RECT rcWindow;
POINT Point;
int iMouseX;
int iMouseY;
int iTileX;
int iTileY;
// Get mouse coordinates
GetCursorPos( &Point );
iMouseX = Point.x;
iMouseY = Point.y;
// Figure out the toolbar work area
GetWindowRect( hWndToolBar, &rcWindow );
// Check if mouse within tool-bar window
if( iMouseX > rcWindow.left &&
iMouseX < rcWindow.right &&
iMouseY > rcWindow.top &&
iMouseY < rcWindow.bottom )
{
// Adjust mouse coords to be local to toolbar
iMouseX -= rcWindow.right;
iMouseY -= rcWindow.top;
// Figure out tile coordinates
iTileX = iMouseX/g_iTileSize;
iTileY = iMouseY/g_iTileSize;
// Figure out picked tile
g_iCurTile = (g_iCurTileSet*21)+(iTileX+(iTileY*3))-1;
// Make sure tile is valid
if( g_iCurTile < 0 || g_iCurTile >= g_iTotalTiles ) {
g_iCurTile = 0;
}
vRenderTileSet();
}
// Check if mouse within edit window
else {
GetWindowRect( g_hWnd, &rcWindow );
if( iMouseX > rcWindow.left &&
iMouseX < rcWindow.right &&
iMouseY > rcWindow.top &&
iMouseY < rcWindow.bottom )
{
// Adjust mouse coords to be local to edit window
iMouseX -= rcWindow.left+g_iXOffset;
iMouseY -= rcWindow.top+g_iYOffset;
// Figure out tile coordinates
iTileX = iMouseX/g_iTileSize;
iTileY = iMouseY/g_iTileSize;
g_iTileMap[ iTileX+g_iXPos+
( (iTileY + g_iYPos)
* g_iMapWidth ) ] = g_iCurTile;
}
}
}
//-----------------------------------------------------------------------------
//
// Saves the tile map to a binary file.
//
//-----------------------------------------------------------------------------
void vSaveMap( void )
{
FILE *fp;
int iRet;
OPENFILENAME fileStruct;
char szFileName[ 512 ];
char szFilter[ 32 ];
char szExtension[ 32 ];
// Clear buffer to receive file name
memset( szFileName, 0x00, 512 );
// Create file filter
memset( szFilter, 0x00, 32 );
strcpy( szFilter, "*.dat" );
// Create file extension
memset( szExtension, 0x00, 32 );
strcpy( szExtension, "dat" );
//
// Setup the file dialog box
//
// Clear file dialog structure
memset( &fileStruct, 0x00, sizeof( OPENFILENAME ) );
// Initialize structure
fileStruct.hInstance = g_hInstance;
fileStruct.hwndOwner = g_hWnd;
fileStruct.lpstrDefExt = szExtension;
fileStruct.lpstrFileTitle = szFileName;
fileStruct.lpstrFilter = szFilter;
fileStruct.nMaxFileTitle = 512;
fileStruct.lStructSize = sizeof( OPENFILENAME );
// Retrieve the filename
iRet = GetSaveFileName( &fileStruct );
// Exit out on failure
if( !iRet ) {
return;
}
// Open the tile file
fp = fopen( szFileName, "wb" );
// Return if open failed
if( fp == NULL ) {
return;
}
// Save the tile buffer
fwrite( g_iTileMap, 10000, sizeof(int), fp );
// Close the tile file
fclose( fp );
// Play sound to indicate action
PlaySound("bleep.wav",NULL,SND_FILENAME|SND_ASYNC);
}
//-----------------------------------------------------------------------------
//
// Loads the tile map from a binary file.
//
//-----------------------------------------------------------------------------
void vLoadMap( void )
{
FILE *fp;
OPENFILENAME fileStruct;
char szFileName[ 512 ];
char szFilter[ 32 ];
char szExtension[ 32 ];
int iRet;
// Clear buffer to receive file name
memset( szFileName, 0x00, 512 );
// Create file filter
memset( szFilter, 0x00, 32 );
strcpy( szFilter, "*.dat" );
// Create file extension
memset( szExtension, 0x00, 32 );
strcpy( szExtension, "dat" );
//
// Setup the file dialog box
//
// Clear file dialog structure
memset( &fileStruct, 0x00, sizeof( OPENFILENAME ) );
// Initialize structure
fileStruct.hInstance = g_hInstance;
fileStruct.hwndOwner = g_hWnd;
fileStruct.lpstrDefExt = szExtension;
fileStruct.lpstrFileTitle = szFileName;
fileStruct.lpstrFilter = szFilter;
fileStruct.nMaxFileTitle = 512;
fileStruct.lStructSize = sizeof( OPENFILENAME );
// Retrieve the filename
iRet = GetOpenFileName( &fileStruct );
// Exit out on failure
if( !iRet ) {
return;
}
// Open the tile file
fp = fopen( szFileName, "rb" );
// Return if no file to load
if( fp == NULL ) {
return;
}
// Read the tile buffer
fread( g_iTileMap, 10000, sizeof(int), fp );
// Close the tile file
fclose( fp );
// Play sound to indicate action
PlaySound("button.wav",NULL,SND_FILENAME|SND_ASYNC);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -