home *** CD-ROM | disk | FTP | other *** search
- // PROG14_3_16b.CPP - DirectInput joystick demo
- // move the bug blaster around, notice it moves more or
- // less depending on how much the stick is moves, hence
- // the analog nature of joysticks
-
-
- // INCLUDES ///////////////////////////////////////////////
-
- #define WIN32_LEAN_AND_MEAN
- #define INITGUID
-
- #include <windows.h> // include important windows stuff
- #include <windowsx.h>
- #include <mmsystem.h>
- #include <objbase.h>
- #include <iostream.h> // include important C/C++ stuff
- #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> // directX includes
- #include <dinput.h>
- #include "gpdumb1.h"
-
- // DEFINES ////////////////////////////////////////////////
-
- // defines for windows
- #define WINDOW_CLASS_NAME "WINXCLASS" // class name
-
- #define WINDOW_WIDTH 64 // size of window
- #define WINDOW_HEIGHT 48
-
-
- // PROTOTYPES /////////////////////////////////////////////
-
- // game console
- 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
-
- // directinput globals
- LPDIRECTINPUT8 lpdi = NULL; // dinput object
- LPDIRECTINPUTDEVICE8 lpdikey = NULL; // dinput keyboard
- LPDIRECTINPUTDEVICE8 lpdimouse = NULL; // dinput mouse
- LPDIRECTINPUTDEVICE8 lpdijoy = NULL; // dinput joystick
- GUID joystickGUID; // guid for main joystick
- char joyname[80]; // name of joystick
-
- // these contain the target records for all di input packets
- UCHAR keyboard_state[256]; // contains keyboard state table
- DIMOUSESTATE mouse_state; // contains state of mouse
- DIJOYSTATE joy_state; // contains state of joystick
-
- BITMAP_IMAGE playfield; // used to hold playfield
- BITMAP_IMAGE mushrooms[4]; // holds mushrooms
- BOB blaster; // holds bug blaster
-
- int blaster_anim[5] = {0,1,2,1,0}; // blinking animation
-
- // lets use a line segment for the missle
- int missile_x, // position of missle
- missile_y,
- missile_state; // state of missle 0 off, 1 on
-
- // PROTOTYPES //////////////////////////////////////////////
-
- int Color_Scan(int x1, int y1, int x2, int y2,
- USHORT scan_start, USHORT scan_end,
- UCHAR *scan_buffer, int scan_lpitch);
-
- int Start_Missile(void);
- int Move_Missile(void);
- int Draw_Missile(void);
-
- // FUNCTIONS //////////////////////////////////////////////
-
- LRESULT CALLBACK WindowProc(HWND hwnd,
- UINT msg,
- WPARAM wparam,
- LPARAM lparam)
- {
- // 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);
- } break;
-
- case WM_PAINT:
- {
- // start painting
- hdc = BeginPaint(hwnd,&ps);
-
- // end painting
- EndPaint(hwnd,&ps);
- return(0);
- } break;
-
- case WM_DESTROY:
- {
- // kill the application
- PostQuitMessage(0);
- return(0);
- } break;
-
- default:break;
-
- } // end switch
-
- // process any messages that we didn't take care of
- return (DefWindowProc(hwnd, msg, wparam, lparam));
-
- } // end WinProc
-
- // WINMAIN ////////////////////////////////////////////////
-
- int WINAPI WinMain( HINSTANCE hinstance,
- HINSTANCE hprevinstance,
- LPSTR lpcmdline,
- int ncmdshow)
- {
- // this is the winmain function
-
- WNDCLASS winclass; // this will hold the class we create
- 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 |
- 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_ARROW);
- winclass.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);
- winclass.lpszMenuName = NULL;
- winclass.lpszClassName = WINDOW_CLASS_NAME;
-
- // register the window class
- if (!RegisterClass(&winclass))
- return(0);
-
- // create the window, note the use of WS_POPUP
- if (!(hwnd = CreateWindow(WINDOW_CLASS_NAME, // class
- "WinX Game Console", // title
- WS_POPUP | WS_VISIBLE,
- 0,0, // x,y
- WINDOW_WIDTH, // width
- WINDOW_HEIGHT, // height
- NULL, // handle to parent
- NULL, // handle to menu
- hinstance,// instance
- NULL))) // creation parms
- return(0);
-
- // save the window handle and instance in a global
- main_window_handle = hwnd;
- main_instance = hinstance;
-
- // perform all game console specific initialization
- Game_Init();
-
- // enter main event loop
- while(1)
- {
- if (PeekMessage(&msg,NULL,0,0,PM_REMOVE))
- {
- // 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
-
- ///////////////////////////////////////////////////////////
-
- int Color_Scan(int x1, int y1, int x2, int y2,
- USHORT scan_start, USHORT scan_end,
- UCHAR *scan_buffer, int scan_lpitch)
- {
- // this function implements a crude collision technique
- // based on scanning for a range of colors within a rectangle
-
- // clip rectangle
-
- USHORT *scan_buffer2 = (USHORT *)scan_buffer;
-
- // x coords first
- if (x1 >= screen_width)
- x1=screen_width-1;
- else
- if (x1 < 0)
- x1=0;
-
- if (x2 >= screen_width)
- x2=screen_width-1;
- else
- if (x2 < 0)
- x2=0;
-
- // now y-coords
- if (y1 >= screen_height)
- y1=screen_height-1;
- else
- if (y1 < 0)
- y1=0;
-
- if (y2 >= screen_height)
- y2=screen_height-1;
- else
- if (y2 < 0)
- y2=0;
-
- // scan the region
- scan_buffer2 +=y1*(scan_lpitch >> 1);
-
- for (int scan_y=y1; scan_y<=y2; scan_y++)
- {
- for (int scan_x=x1; scan_x<=x2; scan_x++)
- {
- if (scan_buffer2[scan_x] >= scan_start && scan_buffer2[scan_x] <= scan_end )
- return(1);
- } // end for x
-
- // move down a line
- scan_buffer2+=(scan_lpitch >> 1);
-
- } // end for y
-
- // return failure
- return(0);
-
- } // end Color_Scan
-
- // WINX GAME PROGRAMMING CONSOLE FUNCTIONS ////////////////
-
- BOOL CALLBACK DI_Enum_Joysticks(LPCDIDEVICEINSTANCE lpddi,
- LPVOID guid_ptr)
- {
- // this function enumerates the joysticks, but
- // stops at the first one and returns the
- // instance guid of it, so we can create it
-
- *(GUID*)guid_ptr = lpddi->guidInstance;
-
- // copy name into global
- strcpy(joyname, (char *)lpddi->tszProductName);
-
- // stop enumeration after one iteration
- return(DIENUM_STOP);
-
- } // end DI_Enum_Joysticks
-
- ///////////////////////////////////////////////////////////
-
- int Start_Missile(void)
- {
- // this function starts the missle, if it is currently off
-
- if (missile_state==0)
- {
- // enable missile
- missile_state = 1;
-
- // computer position of missile
- missile_x = blaster.x + 16;
- missile_y = blaster.y-4;
-
- // return success
- return(1);
- } // end if
-
- // couldn't start missile
- return(0);
-
- } // end Start_Missile
-
- ///////////////////////////////////////////////////////////
-
- int Move_Missile(void)
- {
- // this function moves the missle
-
- // test if missile is alive
- if (missile_state==1)
- {
- // move the missile upward
- if ((missile_y-=10) < 0)
- {
- missile_state = 0;
- return(1);
- } // end if
-
- // lock secondary buffer
- DD_Lock_Back_Surface();
-
- // test if missile has hit anything
- if (Color_Scan(missile_x-1, missile_y+4,
- missile_x+1, missile_y+12,
- 1,65535, back_buffer,back_lpitch))
- {
- // kill missile
- missile_state = 0;
-
- // cause some damage
- for (int index=0; index<25; index++)
- {
- Draw_Pixel16(missile_x-4+rand()%8,missile_y-2+rand()%12,_RGB16BIT565(0,0,0),
- playfield.buffer, playfield.width*2);
-
- } // end for index
-
- } // end if
-
- // unlock surface
- DD_Unlock_Back_Surface();
-
- // return success
- return(1);
-
- } // end if
-
- // return failure
- return(0);
-
- } // end Move_Missle
-
- ///////////////////////////////////////////////////////////
-
- int Draw_Missile(void)
- {
- // this function draws the missile
-
- // test if missile is alive
- if (missile_state==1)
- {
- // lock secondary buffer
- DD_Lock_Back_Surface();
-
- // draw the missile in green
- Draw_Clip_Line16(missile_x, missile_y,
- missile_x, missile_y+6,
- _RGB16BIT565(0,63,0) ,back_buffer, back_lpitch);
-
- // unlock surface
- DD_Unlock_Back_Surface();
-
- // return success
- return(1);
-
- } // end if
-
- // return failure
- return(0);
-
- } // end Draw_Missle
-
- ///////////////////////////////////////////////////////////
-
- int Game_Init(void *parms)
- {
- // this function is where you do all the initialization
- // for your game
-
- int index; // looping var
- char filename[80]; // used to build up files names
-
- // set up screen dimensions
- screen_width = 640;
- screen_height = 480;
- screen_bpp = 16;
-
- // initialize directdraw
- DD_Init(screen_width, screen_height, screen_bpp);
-
- // joystick creation section ////////////////////////////////
-
- // first create the direct input object
- if (DirectInput8Create(main_instance, DIRECTINPUT_VERSION, IID_IDirectInput8, (void **)&lpdi,NULL)!=DI_OK)
- return(0);
-
- // first find the fucking GUID of your particular joystick
- lpdi->EnumDevices(DI8DEVCLASS_GAMECTRL,
- DI_Enum_Joysticks,
- &joystickGUID,
- DIEDFL_ATTACHEDONLY);
-
- if (lpdi->CreateDevice(joystickGUID, &lpdijoy, NULL)!=DI_OK)
- return(0);
-
- // set cooperation level
- if (lpdijoy->SetCooperativeLevel(main_window_handle,
- DISCL_NONEXCLUSIVE | DISCL_BACKGROUND)!=DI_OK)
- return(0);
-
- // set data format
- if (lpdijoy->SetDataFormat(&c_dfDIJoystick)!=DI_OK)
- return(0);
-
- // set the range of the joystick
- DIPROPRANGE joy_axis_range;
-
- // first x axis
- joy_axis_range.lMin = -24;
- joy_axis_range.lMax = 24;
-
- joy_axis_range.diph.dwSize = sizeof(DIPROPRANGE);
- joy_axis_range.diph.dwHeaderSize = sizeof(DIPROPHEADER);
- joy_axis_range.diph.dwObj = DIJOFS_X;
- joy_axis_range.diph.dwHow = DIPH_BYOFFSET;
-
- lpdijoy->SetProperty(DIPROP_RANGE,&joy_axis_range.diph);
-
- // now y-axis
- joy_axis_range.lMin = -24;
- joy_axis_range.lMax = 24;
-
- joy_axis_range.diph.dwSize = sizeof(DIPROPRANGE);
- joy_axis_range.diph.dwHeaderSize = sizeof(DIPROPHEADER);
- joy_axis_range.diph.dwObj = DIJOFS_Y;
- joy_axis_range.diph.dwHow = DIPH_BYOFFSET;
-
- lpdijoy->SetProperty(DIPROP_RANGE,&joy_axis_range.diph);
-
- // acquire the joystick
- if (lpdijoy->Acquire()!=DI_OK)
- return(0);
-
- ///////////////////////////////////////////////////////////
-
- // load the background
- Load_Bitmap_File(&bitmap8bit, "MUSH16.BMP");
-
-
- // load in the four frames of the mushroom
- for (index=0; index<4; index++)
- {
- // create mushroom bitmaps
- Create_Bitmap16(&mushrooms[index],0,0,32,32);
- Load_Image_Bitmap16(&mushrooms[index],&bitmap8bit,index,0,BITMAP_EXTRACT_MODE_CELL);
- } // end for index
-
- // now create the bug blaster bob
- Create_BOB16(&blaster,0,0,32,32,3,
- BOB_ATTR_VISIBLE | BOB_ATTR_MULTI_ANIM | BOB_ATTR_ANIM_ONE_SHOT,
- DDSCAPS_SYSTEMMEMORY);
-
- // load in the four frames of the mushroom
- for (index=0; index<3; index++)
- Load_Frame_BOB16(&blaster,&bitmap8bit,index,index,1,BITMAP_EXTRACT_MODE_CELL);
-
- // unload the bitmap file
- Unload_Bitmap_File(&bitmap8bit);
-
- // set the animation sequences for bug blaster
- Load_Animation_BOB16(&blaster,0,5,blaster_anim);
-
- // set up stating state of bug blaster
- Set_Pos_BOB16(&blaster,320, 400);
- Set_Anim_Speed_BOB16(&blaster,3);
-
- // set clipping rectangle to screen extents so objects dont
- // mess up at edges
- RECT screen_rect = {0,0,screen_width,screen_height};
- lpddclipper = DD_Attach_Clipper(lpddsback,1,&screen_rect);
-
- // seed random number generator
- srand(Start_Clock());
-
- // create mushroom playfield bitmap
- Create_Bitmap16(&playfield,0,0,screen_width,screen_height);
- playfield.attr |= BITMAP_ATTR_LOADED;
-
- // clear it out
- memset(playfield.buffer,0,playfield.width*playfield.height*2);
-
- // create the random mushroom patch
- for (index=0; index<50; index++)
- {
- // select a mushroom
- int mush = rand()%4;
-
- // set mushroom to random position
- mushrooms[mush].x = rand()%(screen_width-32);
- mushrooms[mush].y = rand()%(screen_height-128);
-
- // now draw the mushroom into playfield
- Draw_Bitmap16(&mushrooms[mush], playfield.buffer, playfield.width*2,1);
-
- } // end for
-
- // hide the mouse
- ShowCursor(FALSE);
-
- // 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
-
- // kill the bug blaster
- Destroy_BOB16(&blaster);
-
- // kill the mushroom maker
- for (int index=0; index<4; index++)
- Destroy_Bitmap16(&mushrooms[index]);
-
- // kill the playfield bitmap
- Destroy_Bitmap16(&playfield);
-
- // release joystick
- lpdijoy->Unacquire();
- lpdijoy->Release();
- lpdi->Release();
-
- // shutdonw directdraw
- DD_Shutdown();
-
- // 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!
-
- int index; // looping var
- int dx,dy; // general deltas used in collision detection
-
- // check of user is trying to exit
- if (KEY_DOWN(VK_ESCAPE) || KEY_DOWN(VK_SPACE))
- PostMessage(main_window_handle, WM_DESTROY,0,0);
-
- // start the timing clock
- Start_Clock();
-
- // get joystick data
- lpdijoy->Poll(); // this is needed for joysticks only
- lpdijoy->GetDeviceState(sizeof(DIJOYSTATE), (LPVOID)&joy_state);
-
- // clear the drawing surface
- DD_Fill_Surface(lpddsback, 0);
-
- // lock the back buffer
- DD_Lock_Back_Surface();
-
- // draw the background reactor image
- Draw_Bitmap16(&playfield, back_buffer, back_lpitch, 0);
-
- // unlock the back buffer
- DD_Unlock_Back_Surface();
-
- // is the player moving?
- blaster.x+=joy_state.lX;
- blaster.y+=joy_state.lY;
-
- // test bounds
- if (blaster.x > screen_width-32)
- blaster.x = screen_width-32;
- else
- if (blaster.x < 0)
- blaster.x = 0;
-
- if (blaster.y > screen_height-32)
- blaster.y = screen_height-32;
- else
- if (blaster.y < screen_height-128)
- blaster.y = screen_height-128;
-
- // is player firing?
- if (joy_state.rgbButtons[0])
- Start_Missile();
-
- // move and draw missle
- Move_Missile();
- Draw_Missile();
-
- // is it time to blink eyes
- if ((rand()%100)==50)
- Set_Animation_BOB16(&blaster,0);
-
- // draw blaster
- Animate_BOB16(&blaster);
- Draw_BOB16(&blaster,lpddsback);
-
- // draw some text
- Draw_Text_GDI("Blast Those Mushrooms!",0,0,RGB(0,0,255),lpddsback);
-
- // display joystick
- sprintf(buffer,"Joystick: X-Axis=%d, Y-Axis=%d, buttons(%d,%d,%d,%d)",joy_state.lX,joy_state.lY,
- joy_state.rgbButtons[0],
- joy_state.rgbButtons[1],
- joy_state.rgbButtons[2],
- joy_state.rgbButtons[3]);
-
- Draw_Text_GDI(buffer,0,screen_height-20,RGB(255,0,0),lpddsback);
-
- // print out name of joystick
- Draw_Text_GDI(joyname,0,screen_height-40,RGB(255,255,50),lpddsback);
-
- // flip the surfaces
- DD_Flip();
-
- // sync to 40ish fps
- Wait_Clock(20);
-
- // return success
- return(1);
-
- } // end Game_Main
-
- //////////////////////////////////////////////////////////