GameState * EndOfRound::Update() { int backgroundColor = 122; // clear the drawing surface DDraw_Fill_Surface(lpddsback,backgroundColor ); Draw_Blocks(); Draw_Players(); // flip the surfaces DDraw_Flip(); countDownTimer--; if(countDownTimer < 1) { Player * survivor = Universe::GetSurvivingPlayer(); if(survivor) { int numberOfSurvivorWins = survivor->GetNumberOfWins(); numberOfSurvivorWins++; survivor->SetNumberofWins(numberOfSurvivorWins); } return new EndOfRoundReport(); } return this; }
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 // check of user is trying to exit if (KEY_DOWN(VK_ESCAPE)) { PostMessage(main_window_handle, WM_DESTROY,0,0); // stop all sounds DSound_Stop_All_Sounds(); } // end if // start the timing clock Start_Clock(); // clear the drawing surface DDraw_Fill_Surface(lpddsback, 0); // lock back buffer and copy background into it DDraw_Lock_Back_Surface(); // draw background Draw_Bitmap16(&background_bmp, back_buffer, back_lpitch,0); // unlock back surface DDraw_Unlock_Back_Surface(); // process the fly ai, move them buzz around dead bodies Flys_AI(); // draw the flys for (index=0; index < MAX_FLYS; index++) Draw_BOB16(&flys[index], lpddsback); // flip the surfaces DDraw_Flip(); // sync to 30ish fps Wait_Clock(30); // return success return(1); } // end Game_Main
int Game_Main(void *parms, int num_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, index_x, index_y; // looping vars // 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(); // clear the drawing surface DDraw_Fill_Surface(lpddsback, 0); // move the aliens for (index = 0; index<NUM_ALIENS; index++) Move_BOB(&aliens[index]); // draw the aliens for (index = 0; index<NUM_ALIENS; index++) Draw_BOB(&aliens[index], lpddsback); #ifndef USE_MULTITHREADING // animate the aliens -- color animation Rotate_Colors(249, 253); #endif // draw some info Draw_Text_GDI("<ESC> to Exit.",8,8,RGB(0,255,0),lpddsback); // flip the surfaces DDraw_Flip(); // sync to 30 fps Wait_Clock(30); // return success return(1); } // end Game_Main
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 // start the timing clock Start_Clock(); // clear the drawing surface DDraw_Fill_Surface(lpddsback, 0); // read keyboard and other devices here DInput_Read_Keyboard(); // game logic here... // flip the surfaces DDraw_Flip(); // sync to 30ish fps Wait_Clock(30); // check of user is trying to exit if (KEY_DOWN(VK_ESCAPE) || keyboard_state[DIK_ESCAPE]) { PostMessage(main_window_handle, WM_DESTROY,0,0); } // end if // return success return(1); } // end Game_Main
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! char work_string[256]; // temp string int index; // looping var // start the timing clock Start_Clock(); // clear the drawing surface //DDraw_Fill_Surface(lpddsback, 0); //Draw_Rectangle(0,WINDOW_HEIGHT/2-1, WINDOW_WIDTH, WINDOW_HEIGHT, RGB16Bit(20,12,0), lpddsback); // read keyboard and other devices here DInput_Read_Keyboard(); // game logic here... // lock the back buffer DDraw_Lock_Back_Surface(); // draw a randomly positioned gouraud triangle with 3 random vertex colors POLYF4DV2 face; // set the vertices face.tvlist[0].x = (int)RAND_RANGE(0, screen_width - 1); face.tvlist[0].y = (int)RAND_RANGE(0, screen_height - 1); face.lit_color[0] = RGB16Bit(RAND_RANGE(0,255), RAND_RANGE(0,255), RAND_RANGE(0,255)); face.tvlist[1].x = (int)RAND_RANGE(0, screen_width - 1); face.tvlist[1].y = (int)RAND_RANGE(0, screen_height - 1); face.lit_color[1] = RGB16Bit(RAND_RANGE(0,255), RAND_RANGE(0,255), RAND_RANGE(0,255)); face.tvlist[2].x = (int)(int)RAND_RANGE(0, screen_width - 1); face.tvlist[2].y = (int)(int)RAND_RANGE(0, screen_height - 1); face.lit_color[2] = RGB16Bit(RAND_RANGE(0,255), RAND_RANGE(0,255), RAND_RANGE(0,255)); // draw the gouraud shaded triangle Draw_Gouraud_Triangle16(&face, back_buffer, back_lpitch); // unlock the back buffer DDraw_Unlock_Back_Surface(); // draw instructions Draw_Text_GDI("Press ESC to exit.", 0, 0, RGB(0,255,0), lpddsback); // flip the surfaces DDraw_Flip(); // wait a sec to see pretty triangle Wait_Clock(100); // check of user is trying to exit if (KEY_DOWN(VK_ESCAPE) || keyboard_state[DIK_ESCAPE]) { PostMessage(main_window_handle, WM_DESTROY,0,0); } // end if // return success return(1); } // end Game_Main
int Game_Main(void *parms, int num_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, index_x, index_y; // looping vars int start_map_x,start_map_y, // map positions end_map_x,end_map_y; int offset_x, offset_y; // pixel offsets within cell // 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(); // clear the drawing surface DDraw_Fill_Surface(lpddsback, 0); // check for movement (scrolling) if (KEY_DOWN(VK_RIGHT)) { if ((world_x+=4) >= 1280) world_x = 1279; } // end if else if (KEY_DOWN(VK_LEFT)) { if ((world_x-=4) < 0) world_x = 0; } // end if if (KEY_DOWN(VK_UP)) { if ((world_y-=4) < 0) world_y = 0; } // end if else if (KEY_DOWN(VK_DOWN)) { if ((world_y+=4) >= 896) world_y = 895; } // end if // compute starting map indices by dividing position by size of cell start_map_x = world_x/64; // use >> 6 for speed, but this is clearer start_map_y = world_y/64; // compute end of map rectangle for best cast i.e. aligned on 64x64 boundary end_map_x = start_map_x + 10 - 1; end_map_y = start_map_y + 7 - 1; // now compute number of pixels in x,y we are within the tile, i.e // how much is scrolled off the edge? offset_x = -(world_x % 64); offset_y = -(world_y % 64); // adjust end_map_x,y for offsets if (offset_x) end_map_x++; if (offset_y) end_map_y++; // set starting position of first upper lh texture int texture_x = offset_x; int texture_y = offset_y; // draw the current window for (index_y = start_map_y; index_y <= end_map_y; index_y++) { for (index_x = start_map_x; index_x <= end_map_x; index_x++) { // set position to blit textures.x = texture_x; textures.y = texture_y; // set frame textures.curr_frame = world[index_y][index_x] - '0'; // draw the texture Draw_BOB(&textures,lpddsback); // update texture position texture_x+=64; } // end for map_x // reset x postion, update y texture_x = offset_x; texture_y += 64; } // end for map_y // draw some info Draw_Text_GDI("USE ARROW KEYS TO MOVE, <ESC> to Exit.",8,8,RGB(255,255,255),lpddsback); sprintf(buffer,"World Position = [%d, %d] ", world_x, world_y); Draw_Text_GDI(buffer,8,screen_height - 32 - 24,RGB(0,255,0),lpddsback); // flip the surfaces DDraw_Flip(); // sync to 30 fps Wait_Clock(30); // return success return(1); } // end Game_Main
int Game_Main(void *parms, int num_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(); // clear the drawing surface DDraw_Fill_Surface(lpddsback, 0); // get joystick data lpdijoy->Poll(); // this is needed for joysticks only lpdijoy->GetDeviceState(sizeof(DIJOYSTATE2), (LPVOID)&joy_state); // lock the back buffer DDraw_Lock_Back_Surface(); // draw the background reactor image Draw_Bitmap16(&playfield, back_buffer, back_lpitch, 0); // unlock the back buffer DDraw_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_BOB(&blaster,0); // draw blaster Animate_BOB(&blaster); Draw_BOB16(&blaster,lpddsback); // draw some text Draw_Text_GDI("(16-Bit Version) Let's Rock!!!",0,0,RGB(255,255,255),lpddsback); // display joystick and buttons 0-7 sprintf(buffer,"Joystick Stats: X-Axis=%d, Y-Axis=%d, buttons(%d,%d,%d,%d,%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], joy_state.rgbButtons[4], joy_state.rgbButtons[5], joy_state.rgbButtons[6], joy_state.rgbButtons[7]); Draw_Text_GDI(buffer,0,SCREEN_HEIGHT-20,RGB(255,255,50),lpddsback); // print out name of joystick sprintf(buffer, "Joystick Name & Vendor: %s",joyname); Draw_Text_GDI(buffer,0,SCREEN_HEIGHT-40,RGB(255,255,50),lpddsback); // flip the surfaces DDraw_Flip(); // sync to 30 fps Wait_Clock(30); // return success return(1); } // end Game_Main
GameState * GameStart::Update() { if(!setupCalled) { Setup(); setupCalled = 1; } bool skip = false; if(skip) { delete this; return new Playing(); } DWORD backgroundColor = _RGB32BIT(0,36,146,255); // clear the drawing surface DDraw_Fill_Surface(lpddsback,backgroundColor ); if(gameStartFlashTimer > 0) { gameStartFlashTimer--; } else { if(isDrawingGameStart) { isDrawingGameStart = false; } else { isDrawingGameStart = true; } gameStartFlashTimer = gameStartFlashTimeInitValue; } if(isDrawingGameStart) { gameStartGameObject->GetBlitterObject()->Draw(lpddsback); } winMatchGameObject->GetBlitterObject()->Draw(lpddsback); switch(numberOfRounds) { case 1: _1GameObject->GetBlitterObject()->Draw(lpddsback); break; case 2: _2GameObject->GetBlitterObject()->Draw(lpddsback); break; case 3: _3GameObject->GetBlitterObject()->Draw(lpddsback); break; case 4: _4GameObject->GetBlitterObject()->Draw(lpddsback); break; case 5: _5GameObject->GetBlitterObject()->Draw(lpddsback); break; } switch(numberOfPlayers) { case 1: whitePad1GameObject->GetBlitterObject()->Draw(lpddsback); break; case 2: whitePad1GameObject->GetBlitterObject()->Draw(lpddsback); blackPad2GameObject->GetBlitterObject()->Draw(lpddsback); break; case 3: whitePad1GameObject->GetBlitterObject()->Draw(lpddsback); blackPad2GameObject->GetBlitterObject()->Draw(lpddsback); redPad3GameObject->GetBlitterObject()->Draw(lpddsback); break; case 4: whitePad1GameObject->GetBlitterObject()->Draw(lpddsback); blackPad2GameObject->GetBlitterObject()->Draw(lpddsback); redPad3GameObject->GetBlitterObject()->Draw(lpddsback); bluePad4GameObject->GetBlitterObject()->Draw(lpddsback); break; } countdownTimer--; if(countdownTimer <= 0) { delete this; return new Playing(); } DDraw_Flip(); return this; }
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 static int player_moving = 0; // tracks player motion static PALETTEENTRY glow = {0,0,0,PC_NOCOLLAPSE}; // used to animation red border static int glow_count = 0, glow_dx = 5; // start the timing clock Start_Clock(); // clear the drawing surface DDraw_Fill_Surface(lpddsback, 0); // lock the back buffer DDraw_Lock_Back_Surface(); // draw the background reactor image Draw_Bitmap(&reactor, back_buffer, back_lpitch, 0); // unlock the back buffer DDraw_Unlock_Back_Surface(); // read keyboard and other devices here DInput_Read_Keyboard(); // reset motion flag player_moving = 0; // test direction of motion, this is a good example of testing the keyboard // although the code could be optimized this is more educational if (keyboard_state[DIK_RIGHT] && keyboard_state[DIK_UP]) { // move skelaton skelaton.x+=2; skelaton.y-=2; dx=2; dy=-2; // set motion flag player_moving = 1; // check animation needs to change if (skelaton.curr_animation != SKELATON_NEAST) Set_Animation_BOB(&skelaton,SKELATON_NEAST); } // end if else if (keyboard_state[DIK_LEFT] && keyboard_state[DIK_UP]) { // move skelaton skelaton.x-=2; skelaton.y-=2; dx=-2; dy=-2; // set motion flag player_moving = 1; // check animation needs to change if (skelaton.curr_animation != SKELATON_NWEST) Set_Animation_BOB(&skelaton,SKELATON_NWEST); } // end if else if (keyboard_state[DIK_LEFT] && keyboard_state[DIK_DOWN]) { // move skelaton skelaton.x-=2; skelaton.y+=2; dx=-2; dy=2; // set motion flag player_moving = 1; // check animation needs to change if (skelaton.curr_animation != SKELATON_SWEST) Set_Animation_BOB(&skelaton,SKELATON_SWEST); } // end if else if (keyboard_state[DIK_RIGHT] && keyboard_state[DIK_DOWN]) { // move skelaton skelaton.x+=2; skelaton.y+=2; dx=2; dy=2; // set motion flag player_moving = 1; // check animation needs to change if (skelaton.curr_animation != SKELATON_SEAST) Set_Animation_BOB(&skelaton,SKELATON_SEAST); } // end if else if (keyboard_state[DIK_RIGHT]) { // move skelaton skelaton.x+=2; dx=2; dy=0; // set motion flag player_moving = 1; // check animation needs to change if (skelaton.curr_animation != SKELATON_EAST) Set_Animation_BOB(&skelaton,SKELATON_EAST); } // end if else if (keyboard_state[DIK_LEFT]) { // move skelaton skelaton.x-=2; dx=-2; dy=0; // set motion flag player_moving = 1; // check animation needs to change if (skelaton.curr_animation != SKELATON_WEST) Set_Animation_BOB(&skelaton,SKELATON_WEST); } // end if else if (keyboard_state[DIK_UP]) { // move skelaton skelaton.y-=2; dx=0; dy=-2; // set motion flag player_moving = 1; // check animation needs to change if (skelaton.curr_animation != SKELATON_NORTH) Set_Animation_BOB(&skelaton,SKELATON_NORTH); } // end if else if (keyboard_state[DIK_DOWN]) { // move skelaton skelaton.y+=2; dx=0; dy=+2; // set motion flag player_moving = 1; // check animation needs to change if (skelaton.curr_animation != SKELATON_SOUTH) Set_Animation_BOB(&skelaton,SKELATON_SOUTH); } // end if // only animate if player is moving if (player_moving) { // animate skelaton Animate_BOB(&skelaton); // see if skelaton hit a wall // lock surface, so we can scan it DDraw_Lock_Back_Surface(); // call the color scanner with WALL_ANIMATION_COLOR, the color of the glowing wall // try to center the scan in the center of the object to make it // more realistic if (Color_Scan(skelaton.x+16, skelaton.y+16, skelaton.x+skelaton.width-16, skelaton.y+skelaton.height-16, WALL_ANIMATION_COLOR, WALL_ANIMATION_COLOR, back_buffer,back_lpitch)) { // back the skelaton up along its last trajectory skelaton.x-=dx; skelaton.y-=dy; } // end if // done, so unlock DDraw_Unlock_Back_Surface(); // check if skelaton is off screen if (skelaton.x < 0 || skelaton.x > (screen_width - skelaton.width)) skelaton.x-=dx; if (skelaton.y < 0 || skelaton.y > (screen_height - skelaton.height)) skelaton.y-=dy; } // end if // draw the skelaton Draw_BOB(&skelaton, lpddsback); // animate color glow.peGreen+=glow_dx; // test boundary if (glow.peGreen == 0 || glow.peGreen == 255) glow_dx = -glow_dx; Set_Palette_Entry(WALL_ANIMATION_COLOR, &glow); // draw some text Draw_Text_GDI("I STILL HAVE A BONE TO PICK!",0,screen_height - 32,WALL_ANIMATION_COLOR,lpddsback); Draw_Text_GDI("USE ARROW KEYS TO MOVE, <ESC> TO EXIT.",0,0,RGB(32,32,32),lpddsback); // flip the surfaces DDraw_Flip(); // sync to 30ish fps Wait_Clock(30); // check of user is trying to exit if (KEY_DOWN(VK_ESCAPE) || keyboard_state[DIK_ESCAPE]) { PostMessage(main_window_handle, WM_DESTROY,0,0); } // end if // return success return(1); } // end Game_Main
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! static MATRIX4X4 mrot; // general rotation matrix // these are used to create a circling camera static float view_angle = 0; static float camera_distance = 6000; static VECTOR4D pos = {0,0,0,0}; static float tank_speed; static float turning = 0; // state variables for different rendering modes and help static int wireframe_mode = 1; static int backface_mode = 1; static int lighting_mode = 1; static int help_mode = 1; static int zsort_mode = 1; char work_string[256]; // temp string int index; // looping var // start the timing clock Start_Clock(); // clear the drawing surface //DDraw_Fill_Surface(lpddsback, 0); #if 1 // draw the sky //Draw_Rectangle(0,0, WINDOW_WIDTH-1, WINDOW_HEIGHT/2, 166, lpddsback); //Draw_Rectangle(0,WINDOW_HEIGHT/2, WINDOW_WIDTH-1, WINDOW_HEIGHT-1, rgblookup[RGB16Bit565(115,42,16)], lpddsback); //Draw_Rectangle(0,0, WINDOW_WIDTH-1, WINDOW_HEIGHT/2, rgblookup[RGB16Bit565(0,140,192)], lpddsback); //Draw_Rectangle(0,0, WINDOW_WIDTH-1, WINDOW_HEIGHT/2, RGB16Bit(0,140,192), lpddsback); Draw_Rectangle(0,0, WINDOW_WIDTH, WINDOW_HEIGHT/2, RGB16Bit(0,35,50), lpddsback); // draw the ground //Draw_Rectangle(0,WINDOW_HEIGHT/2, WINDOW_WIDTH-1, WINDOW_HEIGHT-1, 28, lpddsback); //Draw_Rectangle(0,WINDOW_HEIGHT/2, WINDOW_WIDTH-1, WINDOW_HEIGHT-1, rgblookup[RGB16Bit565(115,42,16)], lpddsback); //Draw_Rectangle(0,WINDOW_HEIGHT/2, WINDOW_WIDTH-1, WINDOW_HEIGHT-1, RGB16Bit(103,62,3), lpddsback); Draw_Rectangle(0,WINDOW_HEIGHT/2-1, WINDOW_WIDTH, WINDOW_HEIGHT, RGB16Bit(20,12,0), lpddsback); // read keyboard and other devices here DInput_Read_Keyboard(); // game logic here... // reset the render list Reset_RENDERLIST4DV2(&rend_list); // allow user to move camera // turbo if (keyboard_state[DIK_SPACE]) tank_speed = 5*TANK_SPEED; else tank_speed = TANK_SPEED; // forward/backward if (keyboard_state[DIK_UP]) { // move forward cam.pos.x += tank_speed*Fast_Sin(cam.dir.y); cam.pos.z += tank_speed*Fast_Cos(cam.dir.y); } // end if if (keyboard_state[DIK_DOWN]) { // move backward cam.pos.x -= tank_speed*Fast_Sin(cam.dir.y); cam.pos.z -= tank_speed*Fast_Cos(cam.dir.y); } // end if // rotate if (keyboard_state[DIK_RIGHT]) { cam.dir.y+=3; // add a little turn to object if ((turning+=2) > 25) turning=25; } // end if if (keyboard_state[DIK_LEFT]) { cam.dir.y-=3; // add a little turn to object if ((turning-=2) < -25) turning=-25; } // end if else // center heading again { if (turning > 0) turning-=1; else if (turning < 0) turning+=1; } // end else // modes and lights // wireframe mode if (keyboard_state[DIK_W]) { // toggle wireframe mode if (++wireframe_mode > 1) wireframe_mode=0; Wait_Clock(100); // wait, so keyboard doesn't bounce } // end if // backface removal if (keyboard_state[DIK_B]) { // toggle backface removal backface_mode = -backface_mode; Wait_Clock(100); // wait, so keyboard doesn't bounce } // end if // lighting if (keyboard_state[DIK_L]) { // toggle lighting engine completely lighting_mode = -lighting_mode; Wait_Clock(100); // wait, so keyboard doesn't bounce } // end if // toggle ambient light if (keyboard_state[DIK_A]) { // toggle ambient light if (lights[AMBIENT_LIGHT_INDEX].state == LIGHTV1_STATE_ON) lights[AMBIENT_LIGHT_INDEX].state = LIGHTV1_STATE_OFF; else lights[AMBIENT_LIGHT_INDEX].state = LIGHTV1_STATE_ON; Wait_Clock(100); // wait, so keyboard doesn't bounce } // end if // toggle infinite light if (keyboard_state[DIK_I]) { // toggle ambient light if (lights[INFINITE_LIGHT_INDEX].state == LIGHTV1_STATE_ON) lights[INFINITE_LIGHT_INDEX].state = LIGHTV1_STATE_OFF; else lights[INFINITE_LIGHT_INDEX].state = LIGHTV1_STATE_ON; Wait_Clock(100); // wait, so keyboard doesn't bounce } // end if // toggle point light if (keyboard_state[DIK_P]) { // toggle point light if (lights[POINT_LIGHT_INDEX].state == LIGHTV1_STATE_ON) lights[POINT_LIGHT_INDEX].state = LIGHTV1_STATE_OFF; else lights[POINT_LIGHT_INDEX].state = LIGHTV1_STATE_ON; Wait_Clock(100); // wait, so keyboard doesn't bounce } // end if // toggle spot light if (keyboard_state[DIK_S]) { // toggle spot light if (lights[SPOT_LIGHT2_INDEX].state == LIGHTV1_STATE_ON) lights[SPOT_LIGHT2_INDEX].state = LIGHTV1_STATE_OFF; else lights[SPOT_LIGHT2_INDEX].state = LIGHTV1_STATE_ON; Wait_Clock(100); // wait, so keyboard doesn't bounce } // end if // help menu if (keyboard_state[DIK_H]) { // toggle help menu help_mode = -help_mode; Wait_Clock(100); // wait, so keyboard doesn't bounce } // end if // z-sorting if (keyboard_state[DIK_Z]) { // toggle z sorting zsort_mode = -zsort_mode; Wait_Clock(100); // wait, so keyboard doesn't bounce } // end if static float plight_ang = 0, slight_ang = 0; // angles for light motion // move point light source in ellipse around game world lights[POINT_LIGHT_INDEX].pos.x = 4000*Fast_Cos(plight_ang); lights[POINT_LIGHT_INDEX].pos.y = 200; lights[POINT_LIGHT_INDEX].pos.z = 4000*Fast_Sin(plight_ang); if ((plight_ang+=3) > 360) plight_ang = 0; // move spot light source in ellipse around game world lights[SPOT_LIGHT2_INDEX].pos.x = 2000*Fast_Cos(slight_ang); lights[SPOT_LIGHT2_INDEX].pos.y = 200; lights[SPOT_LIGHT2_INDEX].pos.z = 2000*Fast_Sin(slight_ang); if ((slight_ang-=5) < 0) slight_ang = 360; // generate camera matrix Build_CAM4DV1_Matrix_Euler(&cam, CAM_ROT_SEQ_ZYX); // insert the player into the world // reset the object (this only matters for backface and object removal) Reset_OBJECT4DV2(&obj_player); // set position of tank obj_player.world_pos.x = cam.pos.x+300*Fast_Sin(cam.dir.y); obj_player.world_pos.y = cam.pos.y-70; obj_player.world_pos.z = cam.pos.z+300*Fast_Cos(cam.dir.y); // generate rotation matrix around y axis static int turn=0; Build_XYZ_Rotation_MATRIX4X4(1, cam.dir.y+turning, 2, &mrot); // rotate the local coords of the object Transform_OBJECT4DV2(&obj_player, &mrot, TRANSFORM_LOCAL_TO_TRANS,1); // perform world transform Model_To_World_OBJECT4DV2(&obj_player, TRANSFORM_TRANS_ONLY); //Light_OBJECT4DV2_World16(&obj_player, &cam, lights, 4); // insert the object into render list Insert_OBJECT4DV2_RENDERLIST4DV2(&rend_list, &obj_player,0); #if 1 ////////////////////////////////////////////////////////// // insert the tanks in the world for (index = 0; index < NUM_TANKS; index++) { // reset the object (this only matters for backface and object removal) Reset_OBJECT4DV2(&obj_tank); // generate rotation matrix around y axis Build_XYZ_Rotation_MATRIX4X4(0, tanks[index].w, 0, &mrot); // rotate the local coords of the object Transform_OBJECT4DV2(&obj_tank, &mrot, TRANSFORM_LOCAL_TO_TRANS,1); // set position of tank obj_tank.world_pos.x = tanks[index].x; obj_tank.world_pos.y = tanks[index].y; obj_tank.world_pos.z = tanks[index].z; // attempt to cull object if (!Cull_OBJECT4DV2(&obj_tank, &cam, CULL_OBJECT_XYZ_PLANES)) { // if we get here then the object is visible at this world position // so we can insert it into the rendering list // perform local/model to world transform Model_To_World_OBJECT4DV2(&obj_tank, TRANSFORM_TRANS_ONLY); //Light_OBJECT4DV2_World16(&obj_tank, &cam, lights, 4); // insert the object into render list Insert_OBJECT4DV2_RENDERLIST4DV2(&rend_list, &obj_tank,0); } // end if } // end for //////////////////////////////////////////////////////// // insert the towers in the world for (index = 0; index < NUM_TOWERS; index++) { // reset the object (this only matters for backface and object removal) Reset_OBJECT4DV2(&obj_tower); // set position of tower obj_tower.world_pos.x = towers[index].x; obj_tower.world_pos.y = towers[index].y; obj_tower.world_pos.z = towers[index].z; // attempt to cull object if (!Cull_OBJECT4DV2(&obj_tower, &cam, CULL_OBJECT_XYZ_PLANES)) { // if we get here then the object is visible at this world position // so we can insert it into the rendering list // perform local/model to world transform Model_To_World_OBJECT4DV2(&obj_tower); //Light_OBJECT4DV2_World16(&obj_tower, &cam, lights, 4); // insert the object into render list Insert_OBJECT4DV2_RENDERLIST4DV2(&rend_list, &obj_tower,0); } // end if } // end for /////////////////////////////////////////////////////////////// // seed number generator so that modulation of markers is always the same srand(13); static int mcount = 0, mdir = 2; mcount+=mdir; if (mcount > 200 || mcount < -200) { mdir=-mdir; mcount+=mdir; } // insert the ground markers into the world for (int index_x = 0; index_x < NUM_POINTS_X; index_x++) for (int index_z = 0; index_z < NUM_POINTS_Z; index_z++) { // reset the object (this only matters for backface and object removal) Reset_OBJECT4DV2(&obj_marker); // set position of tower obj_marker.world_pos.x = RAND_RANGE(-100,100)-UNIVERSE_RADIUS+index_x*POINT_SIZE; obj_marker.world_pos.y = obj_marker.max_radius[0] + 50*Fast_Sin(index_x*10+Fast_Sin(index_z)+mcount); obj_marker.world_pos.z = RAND_RANGE(-100,100)-UNIVERSE_RADIUS+index_z*POINT_SIZE; // attempt to cull object if (!Cull_OBJECT4DV2(&obj_marker, &cam, CULL_OBJECT_XYZ_PLANES)) { // if we get here then the object is visible at this world position // so we can insert it into the rendering list // perform local/model to world transform Model_To_World_OBJECT4DV2(&obj_marker); //Light_OBJECT4DV2_World16(&obj_marker, &cam, lights, 4); // insert the object into render list Insert_OBJECT4DV2_RENDERLIST4DV2(&rend_list, &obj_marker,0); } // end if } // end for //////////////////////////////////////////////////////////////////////// #endif // remove backfaces if (backface_mode==1) Remove_Backfaces_RENDERLIST4DV2(&rend_list, &cam); // light scene all at once if (lighting_mode==1) Light_RENDERLIST4DV2_World16(&rend_list, &cam, lights, 4); // apply world to camera transform World_To_Camera_RENDERLIST4DV2(&rend_list, &cam); // sort the polygon list (hurry up!) if (zsort_mode == 1) Sort_RENDERLIST4DV2(&rend_list, SORT_POLYLIST_AVGZ); // apply camera to perspective transformation Camera_To_Perspective_RENDERLIST4DV2(&rend_list, &cam); // apply screen transform Perspective_To_Screen_RENDERLIST4DV2(&rend_list, &cam); sprintf(work_string,"pos:[%f, %f, %f] heading:[%f] elev:[%f], polys[%d]", cam.pos.x, cam.pos.y, cam.pos.z, cam.dir.y, cam.dir.x, debug_polys_rendered_per_frame); Draw_Text_GDI(work_string, 0, WINDOW_HEIGHT-20, RGB(0,255,0), lpddsback); sprintf(work_string,"Lighting [%s]: Ambient=%d, Infinite=%d, Point=%d, Spot=%d | Zsort [%s], BckFceRM [%s]", ((lighting_mode == 1) ? "ON" : "OFF"), lights[AMBIENT_LIGHT_INDEX].state, lights[INFINITE_LIGHT_INDEX].state, lights[POINT_LIGHT_INDEX].state, lights[SPOT_LIGHT2_INDEX].state, ((zsort_mode == 1) ? "ON" : "OFF"), ((backface_mode == 1) ? "ON" : "OFF")); Draw_Text_GDI(work_string, 0, WINDOW_HEIGHT-34, RGB(0,255,0), lpddsback); // draw instructions Draw_Text_GDI("Press ESC to exit. Press <H> for Help.", 0, 0, RGB(0,255,0), lpddsback); // should we display help int text_y = 16; if (help_mode==1) { // draw help menu Draw_Text_GDI("<A>..............Toggle ambient light source.", 0, text_y+=12, RGB(255,255,255), lpddsback); Draw_Text_GDI("<I>..............Toggle infinite light source.", 0, text_y+=12, RGB(255,255,255), lpddsback); Draw_Text_GDI("<P>..............Toggle point light source.", 0, text_y+=12, RGB(255,255,255), lpddsback); Draw_Text_GDI("<S>..............Toggle spot light source.", 0, text_y+=12, RGB(255,255,255), lpddsback); Draw_Text_GDI("<W>..............Toggle wire frame/solid mode.", 0, text_y+=12, RGB(255,255,255), lpddsback); Draw_Text_GDI("<B>..............Toggle backface removal.", 0, text_y+=12, RGB(255,255,255), lpddsback); Draw_Text_GDI("<RIGHT ARROW>....Rotate player right.", 0, text_y+=12, RGB(255,255,255), lpddsback); Draw_Text_GDI("<LEFT ARROW>.....Rotate player left.", 0, text_y+=12, RGB(255,255,255), lpddsback); Draw_Text_GDI("<UP ARROW>.......Move player forward.", 0, text_y+=12, RGB(255,255,255), lpddsback); Draw_Text_GDI("<DOWN ARROW>.....Move player backward.", 0, text_y+=12, RGB(255,255,255), lpddsback); Draw_Text_GDI("<SPACE BAR>......Turbo.", 0, text_y+=12, RGB(255,255,255), lpddsback); Draw_Text_GDI("<H>..............Toggle Help.", 0, text_y+=12, RGB(255,255,255), lpddsback); Draw_Text_GDI("<ESC>............Exit demo.", 0, text_y+=12, RGB(255,255,255), lpddsback); } // end help // lock the back buffer DDraw_Lock_Back_Surface(); // reset number of polys rendered debug_polys_rendered_per_frame = 0; // render the object if (wireframe_mode == 0) Draw_RENDERLIST4DV2_Wire16(&rend_list, back_buffer, back_lpitch); else if (wireframe_mode == 1) Draw_RENDERLIST4DV2_Solid16(&rend_list, back_buffer, back_lpitch); #endif // unlock the back buffer DDraw_Unlock_Back_Surface(); // flip the surfaces DDraw_Flip(); // sync to 30ish fps Wait_Clock(30); // check of user is trying to exit if (KEY_DOWN(VK_ESCAPE) || keyboard_state[DIK_ESCAPE]) { PostMessage(main_window_handle, WM_DESTROY,0,0); } // end if // return success return(1); } // end Game_Main
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 static rotate = 0; // start the timing clock Start_Clock(); // lock back buffer and copy background into it DDraw_Lock_Back_Surface(); // draw background Draw_Bitmap16(&background_bmp, back_buffer, back_lpitch,0); // draw shape Draw_Polygon2D16(&shape, back_buffer, back_lpitch); // have a little fun if (++rotate > 10) { Rotate_Polygon2D(&shape,1); rotate=0; } // unlock back surface DDraw_Unlock_Back_Surface(); // read keyboard DInput_Read_Keyboard(); // move the balls and compute collisions Compute_Collisions(); // draw the balls for (index=0; index < NUM_BALLS; index++) { balls[index].x = balls[index].varsF[INDEX_X]+0.5-BALL_RADIUS; balls[index].y = balls[index].varsF[INDEX_Y]+0.5-BALL_RADIUS; Draw_BOB16(&balls[index], lpddsback); } // end for // draw the velocity vectors DDraw_Lock_Back_Surface(); for (index=0; index < NUM_BALLS; index++) { Draw_Clip_Line16(balls[index].varsF[INDEX_X]+0.5, balls[index].varsF[INDEX_Y]+0.5, balls[index].varsF[INDEX_X]+2*balls[index].varsF[INDEX_XV]+0.5, balls[index].varsF[INDEX_Y]+2*balls[index].varsF[INDEX_YV]+0.5, RGB16Bit(255,255,255), back_buffer, back_lpitch); } // end for DDraw_Unlock_Back_Surface(); // draw the title Draw_Text_GDI("(16-Bit Version) Object to Contour Collision DEMO, Press <ESC> to Exit.",10, 10,RGB(255,255,255), lpddsback); // flip the surfaces DDraw_Flip(); // run collision algorithm here Compute_Collisions(); // sync to 30 fps = 1/30sec = 33 ms Wait_Clock(33); // check of user is trying to exit if (KEY_DOWN(VK_ESCAPE) || keyboard_state[DIK_ESCAPE]) { PostMessage(main_window_handle, WM_DESTROY,0,0); // stop all sounds DSound_Stop_All_Sounds(); } // end if // return success return(1); } // end Game_Main
int Game_Main(void *parms, int num_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 // 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(); // clear the drawing surface DDraw_Fill_Surface(lpddsback, 0); // get the input from the mouse lpdimouse->GetDeviceState(sizeof(DIMOUSESTATE), (LPVOID)&mouse_state); // move the mouse cursor mouse_x+=(mouse_state.lX); mouse_y+=(mouse_state.lY); // test bounds // first x boundaries if (mouse_x >= screen_width) mouse_x = screen_width-1; else if (mouse_x < 0) mouse_x = 0; // now the y boundaries if (mouse_y >= screen_height) mouse_y= screen_height-1; else if (mouse_y < 0) mouse_y = 0; // position the pointer bob to the mouse coords pointer.x = mouse_x - 16; pointer.y = mouse_y - 16; // test what the user is doing with the mouse if ((mouse_x > 3) && (mouse_x < 500-3) && (mouse_y > 3) && (mouse_y < SCREEN_HEIGHT-3)) { // mouse is within canvas region // if left button is down then draw if (mouse_state.rgbButtons[0]) { // test drawing mode if (buttons_state[BUTTON_PENCIL]) { // draw a pixel Draw_Pixel(mouse_x, mouse_y, mouse_color, canvas.buffer, canvas.width); Draw_Pixel(mouse_x+1, mouse_y, mouse_color, canvas.buffer, canvas.width); Draw_Pixel(mouse_x, mouse_y+1, mouse_color, canvas.buffer, canvas.width); Draw_Pixel(mouse_x+1, mouse_y+1, mouse_color, canvas.buffer, canvas.width); } else { // draw spray for (index=0; index<10; index++) { // get next particle int sx=mouse_x-8+rand()%16; int sy=mouse_y-8+rand()%16; // make sure particle is in bounds if (sx > 0 && sx < 500 && sy > 0 && sy < screen_height) Draw_Pixel(sx, sy, mouse_color, canvas.buffer, canvas.width); } // end for index } // end else } // end if left button else // right button is eraser if (mouse_state.rgbButtons[1]) { // test drawing mode if (buttons_state[BUTTON_PENCIL]) { // erase a pixel Draw_Pixel(mouse_x, mouse_y, 0, canvas.buffer, canvas.width); Draw_Pixel(mouse_x+1, mouse_y, 0, canvas.buffer, canvas.width); Draw_Pixel(mouse_x, mouse_y+1, 0, canvas.buffer, canvas.width); Draw_Pixel(mouse_x+1, mouse_y+1, 0, canvas.buffer, canvas.width); } // end if else { // erase spray for (index=0; index<20; index++) { // get next particle int sx=mouse_x-8+rand()%16; int sy=mouse_y-8+rand()%16; // make sure particle is in bounds if (sx > 0 && sx < 500 && sy > 0 && sy < screen_height) Draw_Pixel(sx, sy, 0, canvas.buffer, canvas.width); } // end for index } // end else } // end if left button } // end if else if ( (mouse_x > 500+16) && (mouse_x < 500+16+8*9) && (mouse_y > 8) && (mouse_y < 8+32*9)) { // within palette // test if button left button is down if (mouse_state.rgbButtons[0]) { // see what color cell user is pointing to int cell_x = (mouse_x - (500+16))/9; int cell_y = (mouse_y - (8))/9; // change color mouse_color = cell_x + cell_y*8; } // end if } // end if else if ((mouse_x > 500) && (mouse_x < (500+100)) && (mouse_y > 344) && (mouse_y < (383+34)) ) { // within button area // test for each button for (index=0; index<4; index++) { if ((mouse_x > buttons_x[index]) && (mouse_x < (buttons_x[index]+32)) && (mouse_y > buttons_y[index]) && (mouse_y < (buttons_y[index]+34)) ) break; } // end for // at this point we know where the user is, now determine what he // is doing with the buttons switch(index) { case BUTTON_SPRAY: { // if left button is down simply activate spray mode if (mouse_state.rgbButtons[0]) { // depress button buttons_state[index] = 1; // de-activate pencil mode buttons_state[BUTTON_PENCIL] = 0; } // end if else { // make sure button is up // buttons_state[index] = 0; } // end else } break; case BUTTON_PENCIL: { // if left button is down activate spray mode if (mouse_state.rgbButtons[0]) { // depress button buttons_state[index] = 1; // de-activate spray mode buttons_state[BUTTON_SPRAY] = 0; } // end if else { // make sure button is up // buttons_state[index] = 0; } // end else } break; case BUTTON_ERASE: { // test if left button is down, if so clear screen if (mouse_state.rgbButtons[0]) { // clear memory memset(canvas.buffer,0,canvas.width*canvas.height); // depress button buttons_state[index] = 1; } // end if else { // make sure button is up buttons_state[index] = 0; } // end else } break; case BUTTON_EXIT: { // test if left button down, if so bail if (mouse_state.rgbButtons[0]) PostMessage(main_window_handle, WM_DESTROY,0,0); } break; } // end switch } // end if else { // no mans land } // end else // lock back buffer DDraw_Lock_Back_Surface(); // draw the canvas Draw_Bitmap(&canvas, back_buffer, back_lpitch,0); // draw control panel Draw_Bitmap(&cpanel,back_buffer,back_lpitch,0); // unlock back buffer DDraw_Unlock_Back_Surface(); // draw the color palette for (int col=0; col < 256; col++) { Draw_Rectangle(500+16+(col%8)*9, 8+(col/8)*9, 500+16+(col%8)*9+8, 8+(col/8)*9+8, col,lpddsback); } // end for col // draw the current color selected Draw_Rectangle(533,306,533+34,306+34,mouse_color,lpddsback); // draw the buttons for (index=0; index<4; index++) { // set position of button bob buttons.x = buttons_x[index]; buttons.y = buttons_y[index]; // now select the on/off frame based on if the // button is off if (buttons_state[index]==0) buttons.curr_frame = index; else // button is on buttons.curr_frame = index+4; // draw the button Draw_BOB(&buttons, lpddsback); } // end for index static int green = 0; // display coords sprintf(buffer,"Pointer (%d,%d)",mouse_x,mouse_y); Draw_Text_GDI(buffer, 8,screen_height - 16,RGB(0,255,0),lpddsback); Draw_Text_GDI("T3D Paint Version 2.0 - Press <ESC> to Exit.",0,0,RGB(0,(green & 255),0),lpddsback); // a little animation ++green; // draw the cursor last Draw_BOB(&pointer,lpddsback); // flip the surfaces DDraw_Flip(); // sync to 30 fps Wait_Clock(30); // return success return(1); } // end Game_Main
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 static int curr_angle = 0; // current angle of elevation from horizon static float curr_vel = 10; // current velocity of projectile // start the timing clock Start_Clock(); // clear the drawing surface //DDraw_Fill_Surface(lpddsback, 0); // lock back buffer and copy background into it DDraw_Lock_Back_Surface(); // draw background Draw_Bitmap(&background_bmp, back_buffer, back_lpitch,0); // do the graphics Draw_Polygon2D(&cannon, back_buffer, back_lpitch); // unlock back surface DDraw_Unlock_Back_Surface(); // read keyboard DInput_Read_Keyboard(); // test for rotate if ((curr_angle < 90) && keyboard_state[DIK_UP]) // rotate left { Rotate_Polygon2D_Mat(&cannon, -5); curr_angle+=5; } // end if else if ((curr_angle > 0) &&keyboard_state[DIK_DOWN]) // rotate right { Rotate_Polygon2D_Mat(&cannon, 5); curr_angle-=5; } // end if // test for projectile velocity if (keyboard_state[DIK_RIGHT]) { if (curr_vel < 30) curr_vel+=0.1; } // end if else if (keyboard_state[DIK_LEFT]) { if (curr_vel > 0) curr_vel-=0.1; } // end if // test for wind force if (keyboard_state[DIK_W]) { if (wind_force < 2) wind_force+=0.01; } // end if else if (keyboard_state[DIK_E]) { if (wind_force > -2) wind_force-=0.01; } // end if // test for gravity force if (keyboard_state[DIK_G]) { if (gravity_force < 15) gravity_force+=0.1; } // end if else if (keyboard_state[DIK_B]) { if (gravity_force > -15) gravity_force-=0.1; } // end if // test for fire! if (keyboard_state[DIK_LCONTROL]) { Fire_Projectile(curr_angle, curr_vel); } // end fire // move all the projectiles Move_Projectiles(); // draw the projectiles Draw_Projectiles(); // draw the title Draw_Text_GDI("Trajectory DEMO, Press <ESC> to Exit.",10, 10,RGB(255,255,255), lpddsback); Draw_Text_GDI("<RIGHT>, <LEFT> to adjust velocity, <UP>, <DOWN> to adjust angle",10, 25, RGB(255,255,255), lpddsback); Draw_Text_GDI("<G>, <B> to adjust gravity, <W>, <E> to adjust wind, <CTRL> to fire.",10, 40, RGB(255,255,255), lpddsback); sprintf(buffer, "Ang=%d, Vel=%f", curr_angle, curr_vel); Draw_Text_GDI(buffer,10, 60, RGB(255,255,255), lpddsback); sprintf(buffer, "Wind force=%f, Gravity Force=%f", wind_force, gravity_force); Draw_Text_GDI(buffer,10, 75, RGB(255,255,255), lpddsback); // flip the surfaces DDraw_Flip(); // sync to 30 fps = 1/30sec = 33 ms Wait_Clock(33); // check of user is trying to exit if (KEY_DOWN(VK_ESCAPE) || keyboard_state[DIK_ESCAPE]) { PostMessage(main_window_handle, WM_DESTROY,0,0); // stop all sounds DSound_Stop_All_Sounds(); // do a screen transition Screen_Transitions(SCREEN_DARKNESS,NULL,0); } // end if // return success return(1); } // end Game_Main
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 // start the timing clock Start_Clock(); // clear the drawing surface DDraw_Fill_Surface(lpddsback, 0); // lock back buffer and copy background into it DDraw_Lock_Back_Surface(); // draw background Draw_Bitmap(&background_bmp, back_buffer, back_lpitch,0); // unlock back surface DDraw_Unlock_Back_Surface(); // read keyboard DInput_Read_Keyboard(); // check the player controls // is the player turning right or left? if (keyboard_state[DIK_RIGHT]) { // there are 16 possible positions for the ship to point in if (++ship.varsI[0] >= 16) ship.varsI[0] = 0; } // end if else if (keyboard_state[DIK_LEFT]) { // there are 16 possible positions for the ship to point in if (--ship.varsI[0] < 0) ship.varsI[0] = 15; } // end if // now test for forward thrust if (keyboard_state[DIK_UP]) { // thrust ship in current direction float rad_angle = (float)ship.varsI[0]*(float)3.14159/(float)8; float xv = cos(rad_angle); float yv = sin(rad_angle); ship.varsF[0]+=xv; ship.varsF[1]+=yv; // animate the ship ship.curr_frame = ship.varsI[0]+16*(rand()%2); } // end if else // show non thrust version ship.curr_frame = ship.varsI[0]; // move ship ship.varsF[2]+=ship.varsF[0]; ship.varsF[3]+=ship.varsF[1]; // always apply friction in direction opposite current trajectory float fx = -ship.varsF[0]; float fy = -ship.varsF[1]; float length_f = sqrt(fx*fx+fy*fy); // normally we would avoid square root at all costs! // compute the frictional resitance if (fabs(length_f) > 0.1) { fx = FRICTION_FACTOR*fx/length_f; fy = FRICTION_FACTOR*fy/length_f; } // end if else fx=fy=0; // now apply friction to forward velocity ship.varsF[0]+=fx; ship.varsF[1]+=fy; //////////////////////////////////////////////////////////////////// // gravity calculation section // step 1: compute vector from black hole to ship, note that the centers // of each object are used float grav_x = (black_hole.x + black_hole.width/2) - (ship.x + ship.width/2); float grav_y = (black_hole.y + black_hole.height/2) - (ship.y + ship.height/2); float radius_squared = grav_x*grav_x + grav_y*grav_y; // equal to radius squared float length_grav = sqrt(radius_squared); // step 2: normalize the length of the vector to 1.0 grav_x = grav_x/length_grav; grav_y = grav_y/length_grav; // step 3: compute the gravity force float grav_force = (VIRTUAL_GRAVITY_CONSTANT) * (SHIP_MASS * BLACK_HOLE_MASS) / radius_squared; // step 4: apply gforce in the direction of grav_x, grav_y with the magnitude of grav_force ship.varsF[0]+=grav_x*grav_force; ship.varsF[1]+=grav_y*grav_force; //////////////////////////////////////////////////////////////////// // test if ship is off screen if (ship.varsF[2] > SCREEN_WIDTH) ship.varsF[2] = -ship.width; else if (ship.varsF[2] < -ship.width) ship.varsF[2] = SCREEN_WIDTH; if (ship.varsF[3] > SCREEN_HEIGHT) ship.varsF[3] = -ship.height; else if (ship.varsF[3] < -ship.height) ship.varsF[3] = SCREEN_HEIGHT; // test if velocity is insane if ( (ship.varsF[0]*ship.varsF[0] + ship.varsF[1]*ship.varsF[1]) > MAX_VEL) { // scale velocity down ship.varsF[0]*=.95; ship.varsF[1]*=.95; } // end if // animate the black hole Animate_BOB(&black_hole); // draw the black hole Draw_BOB(&black_hole, lpddsback); // copy floating point position to bob x,y ship.x = ship.varsF[2]; ship.y = ship.varsF[3]; // draw the ship Draw_BOB(&ship,lpddsback); // draw the title Draw_Text_GDI("GRAVITY MASS DEMO - Use Arrows to Control Ship.",10, 10,RGB(0,255,255), lpddsback); sprintf(buffer,"Friction: X=%f, Y=%f",fx, fy); Draw_Text_GDI(buffer,10,420,RGB(0,255,0), lpddsback); sprintf(buffer,"Velocity: X=%f, Y=%f",ship.varsF[0], ship.varsF[1]); Draw_Text_GDI(buffer,10,440,RGB(0,255,0), lpddsback); sprintf(buffer,"Gravity: X=%f, Y=%f",ship.varsF[2], ship.varsF[3]); Draw_Text_GDI(buffer,10,460,RGB(0,255,0), lpddsback); // flip the surfaces DDraw_Flip(); // sync to 30 fps = 1/30sec = 33 ms Wait_Clock(33); // check of user is trying to exit if (KEY_DOWN(VK_ESCAPE) || keyboard_state[DIK_ESCAPE]) { PostMessage(main_window_handle, WM_DESTROY,0,0); // stop all sounds DSound_Stop_All_Sounds(); // do a screen transition Screen_Transitions(SCREEN_DARKNESS,NULL,0); } // end if // return success return(1); } // end Game_Main
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 static int delay = 30; // initial delay per frame // start the timing clock DWORD start_time = Start_Clock(); // lock back buffer and copy background into it DDraw_Lock_Back_Surface(); // draw background Draw_Bitmap16(&background_bmp, back_buffer, back_lpitch,0); // unlock back surface DDraw_Unlock_Back_Surface(); // read keyboard DInput_Read_Keyboard(); // update delay if (keyboard_state[DIK_RIGHT]) delay+=5; else if (delay > 5 && keyboard_state[DIK_LEFT]) delay-=5; // draw the ship ship.x = ship.varsF[SHIP_X_POS]+0.5; ship.y = ship.varsF[SHIP_Y_POS]+0.5; ship.curr_frame = 0; Draw_BOB(&ship, lpddsback); // draw shadow ship.curr_frame = 1; ship.x-=64; ship.y+=128; Draw_BOB(&ship, lpddsback); // draw the title Draw_Text_GDI("(16-Bit Version) Time Based Kinematic Motion DEMO, Press <ESC> to Exit.",10, 10,RGB(255,255,255), lpddsback); sprintf(buffer, "Frame rate = %f, use <RIGHT>, <LEFT> arrows to change load", 1000*1/(float)delay ); Draw_Text_GDI(buffer,10, 25,RGB(255,255,255), lpddsback); sprintf(buffer,"Ship Velocity is %f pixels/sec",1000*ship.varsF[SHIP_X_VEL]); Draw_Text_GDI(buffer,10, 40,RGB(255,255,255), lpddsback); // this models the load in the game Wait_Clock(delay); // flip the surfaces DDraw_Flip(); // move the ship based on time ////////////////////////////////// // x = x + v*dt // compute dt float dt = Get_Clock() - start_time; // in milliseconds // move based on 30 pixels per seconds or .03 pixels per millisecond ship.varsF[SHIP_X_POS]+=(ship.varsF[SHIP_X_VEL]*dt); // test for off screen if (ship.varsF[SHIP_X_POS] > screen_width+ship.width) ship.varsF[SHIP_X_POS] = -ship.width; ////////////////////////////////////////////////////// // check of user is trying to exit if (KEY_DOWN(VK_ESCAPE) || keyboard_state[DIK_ESCAPE]) { PostMessage(main_window_handle, WM_DESTROY,0,0); // stop all sounds DSound_Stop_All_Sounds(); } // end if // return success return(1); } // end Game_Main
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 // start the timing clock Start_Clock(); // clear the drawing surface //DDraw_Fill_Surface(lpddsback, 0); // lock back buffer and copy background into it DDraw_Lock_Back_Surface(); // draw background Draw_Bitmap16(&background_bmp, back_buffer, back_lpitch,0); // draw table HLine16(TABLE_MIN_X, TABLE_MAX_X, TABLE_MIN_Y, RGB16Bit(0,255,0), back_buffer, back_lpitch); HLine16(TABLE_MIN_X, TABLE_MAX_X, TABLE_MAX_Y, RGB16Bit(0,255,0), back_buffer, back_lpitch); VLine16(TABLE_MIN_Y, TABLE_MAX_Y, TABLE_MIN_X, RGB16Bit(0,255,0), back_buffer, back_lpitch); VLine16(TABLE_MIN_Y, TABLE_MAX_Y, TABLE_MAX_X, RGB16Bit(0,255,0), back_buffer, back_lpitch); // unlock back surface DDraw_Unlock_Back_Surface(); // read keyboard DInput_Read_Keyboard(); // check for change of e if (keyboard_state[DIK_RIGHT]) cof_E+=.01; else if (keyboard_state[DIK_LEFT]) cof_E-=.01; float total_ke_x = 0, total_ke_y = 0; // move all the balls and compute system momentum for (index=0; index < NUM_BALLS; index++) { // move the ball balls[index].varsF[INDEX_X]+=balls[index].varsF[INDEX_XV]; balls[index].varsF[INDEX_Y]+=balls[index].varsF[INDEX_YV]; // add x,y contributions to kinetic energy total_ke_x+=(balls[index].varsF[INDEX_XV]*balls[index].varsF[INDEX_XV]*balls[index].varsF[INDEX_MASS]); total_ke_y+=(balls[index].varsF[INDEX_YV]*balls[index].varsF[INDEX_YV]*balls[index].varsF[INDEX_MASS]); } // end fof // test for boundary collision with virtual table edge, no need for collision // response here, I know what's going to happen :) for (index=0; index < NUM_BALLS; index++) { if ((balls[index].varsF[INDEX_X] >= TABLE_MAX_X-BALL_RADIUS) || (balls[index].varsF[INDEX_X] <= TABLE_MIN_X+BALL_RADIUS)) { // invert velocity balls[index].varsF[INDEX_XV] = -balls[index].varsF[INDEX_XV]; balls[index].varsF[INDEX_X]+=balls[index].varsF[INDEX_XV]; balls[index].varsF[INDEX_Y]+=balls[index].varsF[INDEX_YV]; // start a hit sound Ball_Sound(); } // end if if ((balls[index].varsF[INDEX_Y] >= TABLE_MAX_Y-BALL_RADIUS) || (balls[index].varsF[INDEX_Y] <= TABLE_MIN_Y+BALL_RADIUS)) { // invert velocity balls[index].varsF[INDEX_YV] =-balls[index].varsF[INDEX_YV]; balls[index].varsF[INDEX_X]+=balls[index].varsF[INDEX_XV]; balls[index].varsF[INDEX_Y]+=balls[index].varsF[INDEX_YV]; // play sound Ball_Sound(); } // end if } // end for index // draw the balls for (index=0; index < NUM_BALLS; index++) { balls[index].x = balls[index].varsF[INDEX_X]+0.5-BALL_RADIUS; balls[index].y = balls[index].varsF[INDEX_Y]+0.5-BALL_RADIUS; Draw_BOB16(&balls[index], lpddsback); } // end for // draw the velocity vectors DDraw_Lock_Back_Surface(); for (index=0; index < NUM_BALLS; index++) { Draw_Clip_Line16(balls[index].varsF[INDEX_X]+0.5, balls[index].varsF[INDEX_Y]+0.5, balls[index].varsF[INDEX_X]+2*balls[index].varsF[INDEX_XV]+0.5, balls[index].varsF[INDEX_Y]+2*balls[index].varsF[INDEX_YV]+0.5, RGB16Bit(255,255,255), back_buffer, back_lpitch); } // end for DDraw_Unlock_Back_Surface(); // draw the title Draw_Text_GDI("(16-Bit Version) ELASTIC Object-Object Collision Response DEMO, Press <ESC> to Exit.",10, 10,RGB(255,255,255), lpddsback); // draw the title sprintf(buffer,"Coefficient of Restitution e=%f, use <RIGHT>, <LEFT> arrow to change.", cof_E); Draw_Text_GDI(buffer,10, 30,RGB(255,255,255), lpddsback); sprintf(buffer,"Total System Kinetic Energy Sum(1/2MiVi^2)=%f ",0.5*sqrt(total_ke_x*total_ke_x+total_ke_y*total_ke_y)); Draw_Text_GDI(buffer,10, 465, RGB(255,255,255), lpddsback); // flip the surfaces DDraw_Flip(); // run collision response algorithm here Collision_Response(); // sync to 30 fps = 1/30sec = 33 ms Wait_Clock(33); // check of user is trying to exit if (KEY_DOWN(VK_ESCAPE) || keyboard_state[DIK_ESCAPE]) { PostMessage(main_window_handle, WM_DESTROY,0,0); // stop all sounds DSound_Stop_All_Sounds(); } // end if // return success return(1); } // end Game_Main
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! static MATRIX4X4 mrot; // general rotation matrix static float plight_ang = 0, slight_ang = 0; // angles for light motion // use these to rotate objects static float x_ang = 0, y_ang = 0, z_ang = 0; // state variables for different rendering modes and help static int wireframe_mode = 1; static int backface_mode = 1; static int lighting_mode = 1; static int help_mode = 1; static int zsort_mode = 1; static int x_clip_mode = 1; static int y_clip_mode = 1; static int z_clip_mode = 1; static int perspective_mode = 0; static char *perspective_modes[3] = {"AFFINE", "PERSPECTIVE CORRECT" }; char work_string[256]; // temp string int index; // looping var // start the timing clock Start_Clock(); // clear the drawing surface DDraw_Fill_Surface(lpddsback, 0); // draw the sky Draw_Rectangle(0,0, WINDOW_WIDTH, WINDOW_HEIGHT, RGB16Bit(50,50,255), lpddsback); // draw the ground //Draw_Rectangle(0,WINDOW_HEIGHT*.38, WINDOW_WIDTH, WINDOW_HEIGHT, RGB16Bit(25,50,110), lpddsback); // read keyboard and other devices here DInput_Read_Keyboard(); // game logic here... // reset the render list Reset_RENDERLIST4DV2(&rend_list); // modes and lights // wireframe mode if (keyboard_state[DIK_W]) { // toggle wireframe mode if (++wireframe_mode > 1) wireframe_mode=0; Wait_Clock(100); // wait, so keyboard doesn't bounce } // end if // backface removal if (keyboard_state[DIK_B]) { // toggle backface removal backface_mode = -backface_mode; Wait_Clock(100); // wait, so keyboard doesn't bounce } // end if // lighting if (keyboard_state[DIK_L]) { // toggle lighting engine completely lighting_mode = -lighting_mode; Wait_Clock(100); // wait, so keyboard doesn't bounce } // end if // toggle ambient light if (keyboard_state[DIK_A]) { // toggle ambient light if (lights2[AMBIENT_LIGHT_INDEX].state == LIGHTV2_STATE_ON) lights2[AMBIENT_LIGHT_INDEX].state = LIGHTV2_STATE_OFF; else lights2[AMBIENT_LIGHT_INDEX].state = LIGHTV2_STATE_ON; Wait_Clock(100); // wait, so keyboard doesn't bounce } // end if // toggle infinite light if (keyboard_state[DIK_I]) { // toggle ambient light if (lights2[INFINITE_LIGHT_INDEX].state == LIGHTV2_STATE_ON) lights2[INFINITE_LIGHT_INDEX].state = LIGHTV2_STATE_OFF; else lights2[INFINITE_LIGHT_INDEX].state = LIGHTV2_STATE_ON; Wait_Clock(100); // wait, so keyboard doesn't bounce } // end if // toggle point light if (keyboard_state[DIK_P]) { // toggle point light if (lights2[POINT_LIGHT_INDEX].state == LIGHTV2_STATE_ON) lights2[POINT_LIGHT_INDEX].state = LIGHTV2_STATE_OFF; else lights2[POINT_LIGHT_INDEX].state = LIGHTV2_STATE_ON; // toggle point light if (lights2[POINT_LIGHT2_INDEX].state == LIGHTV2_STATE_ON) lights2[POINT_LIGHT2_INDEX].state = LIGHTV2_STATE_OFF; else lights2[POINT_LIGHT2_INDEX].state = LIGHTV2_STATE_ON; Wait_Clock(100); // wait, so keyboard doesn't bounce } // end if // help menu if (keyboard_state[DIK_H]) { // toggle help menu help_mode = -help_mode; Wait_Clock(100); // wait, so keyboard doesn't bounce } // end if // z-sorting if (keyboard_state[DIK_Z]) { // toggle z sorting zsort_mode = -zsort_mode; Wait_Clock(100); // wait, so keyboard doesn't bounce } // end if // perspective mode if (keyboard_state[DIK_T]) { if (++perspective_mode > 1) perspective_mode=0; Wait_Clock(100); // wait, so keyboard doesn't bounce } // end if // forward/backward if (keyboard_state[DIK_UP]) { // move forward if ( (cam_speed+=1) > MAX_SPEED) cam_speed = MAX_SPEED; } // end if else if (keyboard_state[DIK_DOWN]) { // move backward if ((cam_speed-=1) < -MAX_SPEED) cam_speed = -MAX_SPEED; } // end if // rotate around y axis or yaw if (keyboard_state[DIK_RIGHT]) { cam.dir.y+=5; } // end if if (keyboard_state[DIK_LEFT]) { cam.dir.y-=5; } // end if // motion section ///////////////////////////////////////////////////////// // terrain following, simply find the current cell we are over and then // index into the vertex list and find the 4 vertices that make up the // quad cell we are hovering over and then average the values, and based // on the current height and the height of the terrain push the player upward // the terrain generates and stores some results to help with terrain following //ivar1 = columns; //ivar2 = rows; //fvar1 = col_vstep; //fvar2 = row_vstep; int cell_x = (cam.pos.x + TERRAIN_WIDTH/2) / obj_terrain.fvar1; int cell_y = (cam.pos.z + TERRAIN_HEIGHT/2) / obj_terrain.fvar1; static float terrain_height, delta; // test if we are on terrain if ( (cell_x >=0) && (cell_x < obj_terrain.ivar1) && (cell_y >=0) && (cell_y < obj_terrain.ivar2) ) { // compute vertex indices into vertex list of the current quad int v0 = cell_x + cell_y*obj_terrain.ivar2; int v1 = v0 + 1; int v2 = v1 + obj_terrain.ivar2; int v3 = v0 + obj_terrain.ivar2; // now simply index into table terrain_height = 0.25 * (obj_terrain.vlist_trans[v0].y + obj_terrain.vlist_trans[v1].y + obj_terrain.vlist_trans[v2].y + obj_terrain.vlist_trans[v3].y); // compute height difference delta = terrain_height - (cam.pos.y - gclearance); // test for penetration if (delta > 0) { // apply force immediately to camera (this will give it a springy feel) vel_y+=(delta * (VELOCITY_SCALER)); // test for pentration, if so move up immediately so we don't penetrate geometry cam.pos.y+=(delta*CAM_HEIGHT_SCALER); // now this is more of a hack than the physics model :) let move the front // up and down a bit based on the forward velocity and the gradient of the // hill cam.dir.x -= (delta*PITCH_CHANGE_RATE); } // end if } // end if // decelerate camera if (cam_speed > (CAM_DECEL) ) cam_speed-=CAM_DECEL; else if (cam_speed < (-CAM_DECEL) ) cam_speed+=CAM_DECEL; else cam_speed = 0; // force camera to seek a stable orientation if (cam.dir.x > (neutral_pitch+PITCH_RETURN_RATE)) cam.dir.x -= (PITCH_RETURN_RATE); else if (cam.dir.x < (neutral_pitch-PITCH_RETURN_RATE)) cam.dir.x += (PITCH_RETURN_RATE); else cam.dir.x = neutral_pitch; // apply gravity vel_y+=gravity; // test for absolute sea level and push upward.. if (cam.pos.y < sea_level) { vel_y = 0; cam.pos.y = sea_level; } // end if // move camera cam.pos.x += cam_speed*Fast_Sin(cam.dir.y); cam.pos.z += cam_speed*Fast_Cos(cam.dir.y); cam.pos.y += vel_y; // move point light source in ellipse around game world lights2[POINT_LIGHT_INDEX].pos.x = 1000*Fast_Cos(plight_ang); lights2[POINT_LIGHT_INDEX].pos.y = 100; lights2[POINT_LIGHT_INDEX].pos.z = 1000*Fast_Sin(plight_ang); // move point light source in ellipse around game world lights2[POINT_LIGHT2_INDEX].pos.x = 500*Fast_Cos(-2*plight_ang); lights2[POINT_LIGHT2_INDEX].pos.y = 200; lights2[POINT_LIGHT2_INDEX].pos.z = 1000*Fast_Sin(-2*plight_ang); if ((plight_ang+=3) > 360) plight_ang = 0; // generate camera matrix Build_CAM4DV1_Matrix_Euler(&cam, CAM_ROT_SEQ_ZYX); ////////////////////////////////////////////////////////////////////////// // flat shaded textured cube // reset the object (this only matters for backface and object removal) Reset_OBJECT4DV2(&obj_terrain); // generate rotation matrix around y axis //Build_XYZ_Rotation_MATRIX4X4(x_ang, y_ang, z_ang, &mrot); MAT_IDENTITY_4X4(&mrot); // rotate the local coords of the object Transform_OBJECT4DV2(&obj_terrain, &mrot, TRANSFORM_LOCAL_TO_TRANS,1); // perform world transform Model_To_World_OBJECT4DV2(&obj_terrain, TRANSFORM_TRANS_ONLY); // insert the object into render list Insert_OBJECT4DV2_RENDERLIST4DV2(&rend_list, &obj_terrain,0); // reset number of polys rendered debug_polys_rendered_per_frame = 0; debug_polys_lit_per_frame = 0; // update rotation angles //if ((x_ang+=.2) > 360) x_ang = 0; //if ((y_ang+=.4) > 360) y_ang = 0; //if ((z_ang+=.8) > 360) z_ang = 0; // remove backfaces if (backface_mode==1) Remove_Backfaces_RENDERLIST4DV2(&rend_list, &cam); // apply world to camera transform World_To_Camera_RENDERLIST4DV2(&rend_list, &cam); // clip the polygons themselves now Clip_Polys_RENDERLIST4DV2(&rend_list, &cam, ((x_clip_mode == 1) ? CLIP_POLY_X_PLANE : 0) | ((y_clip_mode == 1) ? CLIP_POLY_Y_PLANE : 0) | ((z_clip_mode == 1) ? CLIP_POLY_Z_PLANE : 0) ); // light scene all at once if (lighting_mode==1) { Transform_LIGHTSV2(lights2, 4, &cam.mcam, TRANSFORM_LOCAL_TO_TRANS); Light_RENDERLIST4DV2_World2_16(&rend_list, &cam, lights2, 4); } // end if // sort the polygon list (hurry up!) if (zsort_mode == 1) Sort_RENDERLIST4DV2(&rend_list, SORT_POLYLIST_AVGZ); // apply camera to perspective transformation Camera_To_Perspective_RENDERLIST4DV2(&rend_list, &cam); // apply screen transform Perspective_To_Screen_RENDERLIST4DV2(&rend_list, &cam); // lock the back buffer DDraw_Lock_Back_Surface(); // reset number of polys rendered debug_polys_rendered_per_frame = 0; // render the object if (wireframe_mode == 0) Draw_RENDERLIST4DV2_Wire16(&rend_list, back_buffer, back_lpitch); else if (wireframe_mode == 1) { // perspective mode affine texturing if (perspective_mode == 0) { // set up rendering context rc.attr = RENDER_ATTR_INVZBUFFER // | RENDER_ATTR_ALPHA // | RENDER_ATTR_MIPMAP // | RENDER_ATTR_BILERP | RENDER_ATTR_TEXTURE_PERSPECTIVE_AFFINE; } // end if else // linear piece wise texturing if (perspective_mode == 1) { // set up rendering context rc.attr = RENDER_ATTR_INVZBUFFER // | RENDER_ATTR_ALPHA // | RENDER_ATTR_MIPMAP // | RENDER_ATTR_BILERP | RENDER_ATTR_TEXTURE_PERSPECTIVE_LINEAR; } // end if else // perspective correct texturing if (perspective_mode == 2) { // set up rendering context rc.attr = RENDER_ATTR_INVZBUFFER // | RENDER_ATTR_ALPHA // | RENDER_ATTR_MIPMAP // | RENDER_ATTR_BILERP | RENDER_ATTR_TEXTURE_PERSPECTIVE_CORRECT; } // end if // initialize zbuffer to 0 fixed point Clear_Zbuffer(&zbuffer, (0 << FIXP16_SHIFT)); // set up remainder of rendering context rc.video_buffer = back_buffer; rc.lpitch = back_lpitch; rc.mip_dist = 4500; rc.zbuffer = (UCHAR *)zbuffer.zbuffer; rc.zpitch = WINDOW_WIDTH*4; rc.rend_list = &rend_list; rc.texture_dist = 0; rc.alpha_override = -1; // render scene Draw_RENDERLIST4DV2_RENDERCONTEXTV1_16(&rc); } // end if // unlock the back buffer DDraw_Unlock_Back_Surface(); // draw cockpit //Draw_BOB16(&cockpit, lpddsback); sprintf(work_string,"Lighting [%s]: Ambient=%d, Infinite=%d, Point=%d, BckFceRM [%s], Texture MODE [%s]", ((lighting_mode == 1) ? "ON" : "OFF"), lights2[AMBIENT_LIGHT_INDEX].state, lights2[INFINITE_LIGHT_INDEX].state, lights2[POINT_LIGHT_INDEX].state, ((backface_mode == 1) ? "ON" : "OFF"), (perspective_modes[perspective_mode])); Draw_Text_GDI(work_string, 0, WINDOW_HEIGHT-34, RGB(0,255,0), lpddsback); // draw instructions Draw_Text_GDI("Press ESC to exit. Press <H> for Help.", 0, 0, RGB(0,255,0), lpddsback); // should we display help int text_y = 16; if (help_mode==1) { // draw help menu Draw_Text_GDI("<A>..............Toggle ambient light source.", 0, text_y+=12, RGB(255,255,255), lpddsback); Draw_Text_GDI("<I>..............Toggle infinite light source.", 0, text_y+=12, RGB(255,255,255), lpddsback); Draw_Text_GDI("<P>..............Toggle point light source.", 0, text_y+=12, RGB(255,255,255), lpddsback); Draw_Text_GDI("<W>..............Toggle wire frame/solid mode.", 0, text_y+=12, RGB(255,255,255), lpddsback); Draw_Text_GDI("<B>..............Toggle backface removal.", 0, text_y+=12, RGB(255,255,255), lpddsback); Draw_Text_GDI("<T>..............Select thru texturing modes.", 0, text_y+=12, RGB(255,255,255), lpddsback); Draw_Text_GDI("<H>..............Toggle Help.", 0, text_y+=12, RGB(255,255,255), lpddsback); Draw_Text_GDI("<ESC>............Exit demo.", 0, text_y+=12, RGB(255,255,255), lpddsback); } // end help sprintf(work_string,"Polys Rendered: %d, Polys lit: %d", debug_polys_rendered_per_frame, debug_polys_lit_per_frame); Draw_Text_GDI(work_string, 0, WINDOW_HEIGHT-34-16-16, RGB(0,255,0), lpddsback); sprintf(work_string,"CAM [%5.2f, %5.2f, %5.2f], CELL [%d, %d]", cam.pos.x, cam.pos.y, cam.pos.z, cell_x, cell_y); Draw_Text_GDI(work_string, 0, WINDOW_HEIGHT-34-16-16-16, RGB(0,255,0), lpddsback); // flip the surfaces DDraw_Flip(); // sync to 30ish fps Wait_Clock(30); // check of user is trying to exit if (KEY_DOWN(VK_ESCAPE) || keyboard_state[DIK_ESCAPE]) { PostMessage(main_window_handle, WM_DESTROY,0,0); } // end if // return success return(1); } // end Game_Main
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! static MATRIX4X4 mrot; // general rotation matrix // these are used to create a circling camera static float view_angle = 0; static float camera_distance = 6000; static VECTOR4D pos = {0,0,0,0}; static float tank_speed; static float turning = 0; // state variables for different rendering modes and help static int wireframe_mode = 1; static int backface_mode = 1; static int lighting_mode = 1; static int help_mode = 1; static int zsort_mode = 1; char work_string[256]; // temp string int index; // looping var // start the timing clock Start_Clock(); // clear the drawing surface DDraw_Fill_Surface(lpddsback, 0); // draw the sky //Draw_Rectangle(0,0, WINDOW_WIDTH, WINDOW_HEIGHT/2, RGB16Bit(0,35,50), lpddsback); // draw the ground //Draw_Rectangle(0,WINDOW_HEIGHT/2-1, WINDOW_WIDTH, WINDOW_HEIGHT, RGB16Bit(20,12,0), lpddsback); // read keyboard and other devices here DInput_Read_Keyboard(); // game logic here... // reset the render list Reset_RENDERLIST4DV2(&rend_list); // modes and lights // wireframe mode if (keyboard_state[DIK_W]) { // toggle wireframe mode if (++wireframe_mode > 1) wireframe_mode=0; Wait_Clock(100); // wait, so keyboard doesn't bounce } // end if // backface removal if (keyboard_state[DIK_B]) { // toggle backface removal backface_mode = -backface_mode; Wait_Clock(100); // wait, so keyboard doesn't bounce } // end if // lighting if (keyboard_state[DIK_L]) { // toggle lighting engine completely lighting_mode = -lighting_mode; Wait_Clock(100); // wait, so keyboard doesn't bounce } // end if // toggle ambient light if (keyboard_state[DIK_A]) { // toggle ambient light if (lights[AMBIENT_LIGHT_INDEX].state == LIGHTV1_STATE_ON) lights[AMBIENT_LIGHT_INDEX].state = LIGHTV1_STATE_OFF; else lights[AMBIENT_LIGHT_INDEX].state = LIGHTV1_STATE_ON; Wait_Clock(100); // wait, so keyboard doesn't bounce } // end if // toggle infinite light if (keyboard_state[DIK_I]) { // toggle ambient light if (lights[INFINITE_LIGHT_INDEX].state == LIGHTV1_STATE_ON) lights[INFINITE_LIGHT_INDEX].state = LIGHTV1_STATE_OFF; else lights[INFINITE_LIGHT_INDEX].state = LIGHTV1_STATE_ON; Wait_Clock(100); // wait, so keyboard doesn't bounce } // end if // toggle point light if (keyboard_state[DIK_P]) { // toggle point light if (lights[POINT_LIGHT_INDEX].state == LIGHTV1_STATE_ON) lights[POINT_LIGHT_INDEX].state = LIGHTV1_STATE_OFF; else lights[POINT_LIGHT_INDEX].state = LIGHTV1_STATE_ON; Wait_Clock(100); // wait, so keyboard doesn't bounce } // end if // toggle spot light if (keyboard_state[DIK_S]) { // toggle spot light if (lights[SPOT_LIGHT2_INDEX].state == LIGHTV1_STATE_ON) lights[SPOT_LIGHT2_INDEX].state = LIGHTV1_STATE_OFF; else lights[SPOT_LIGHT2_INDEX].state = LIGHTV1_STATE_ON; Wait_Clock(100); // wait, so keyboard doesn't bounce } // end if // help menu if (keyboard_state[DIK_H]) { // toggle help menu help_mode = -help_mode; Wait_Clock(100); // wait, so keyboard doesn't bounce } // end if // z-sorting if (keyboard_state[DIK_Z]) { // toggle z sorting zsort_mode = -zsort_mode; Wait_Clock(100); // wait, so keyboard doesn't bounce } // end if static float plight_ang = 0, slight_ang = 0; // angles for light motion // move point light source in ellipse around game world lights[POINT_LIGHT_INDEX].pos.x = 1000*Fast_Cos(plight_ang); lights[POINT_LIGHT_INDEX].pos.y = 100; lights[POINT_LIGHT_INDEX].pos.z = 1000*Fast_Sin(plight_ang); if ((plight_ang+=3) > 360) plight_ang = 0; // move spot light source in ellipse around game world lights[SPOT_LIGHT2_INDEX].pos.x = 1000*Fast_Cos(slight_ang); lights[SPOT_LIGHT2_INDEX].pos.y = 200; lights[SPOT_LIGHT2_INDEX].pos.z = 1000*Fast_Sin(slight_ang); if ((slight_ang-=5) < 0) slight_ang = 360; // generate camera matrix Build_CAM4DV1_Matrix_Euler(&cam, CAM_ROT_SEQ_ZYX); // use these to rotate objects static float x_ang = 0, y_ang = 0, z_ang = 0; ////////////////////////////////////////////////////////////////////////// // constant shaded water // reset the object (this only matters for backface and object removal) Reset_OBJECT4DV2(&obj_constant_water); // set position of constant shaded water obj_constant_water.world_pos.x = -50; obj_constant_water.world_pos.y = 0; obj_constant_water.world_pos.z = 120; // generate rotation matrix around y axis Build_XYZ_Rotation_MATRIX4X4(x_ang, y_ang, z_ang, &mrot); // rotate the local coords of the object Transform_OBJECT4DV2(&obj_constant_water, &mrot, TRANSFORM_LOCAL_TO_TRANS,1); // perform world transform Model_To_World_OBJECT4DV2(&obj_constant_water, TRANSFORM_TRANS_ONLY); // insert the object into render list Insert_OBJECT4DV2_RENDERLIST4DV2(&rend_list, &obj_constant_water,0); ////////////////////////////////////////////////////////////////////////// // flat shaded water // reset the object (this only matters for backface and object removal) Reset_OBJECT4DV2(&obj_flat_water); // set position of constant shaded water obj_flat_water.world_pos.x = 0; obj_flat_water.world_pos.y = 0; obj_flat_water.world_pos.z = 120; // generate rotation matrix around y axis Build_XYZ_Rotation_MATRIX4X4(x_ang, y_ang, z_ang, &mrot); // rotate the local coords of the object Transform_OBJECT4DV2(&obj_flat_water, &mrot, TRANSFORM_LOCAL_TO_TRANS,1); // perform world transform Model_To_World_OBJECT4DV2(&obj_flat_water, TRANSFORM_TRANS_ONLY); // insert the object into render list Insert_OBJECT4DV2_RENDERLIST4DV2(&rend_list, &obj_flat_water,0); ////////////////////////////////////////////////////////////////////////// // gouraud shaded water // reset the object (this only matters for backface and object removal) Reset_OBJECT4DV2(&obj_gouraud_water); // set position of constant shaded water obj_gouraud_water.world_pos.x = 50; obj_gouraud_water.world_pos.y = 0; obj_gouraud_water.world_pos.z = 120; // generate rotation matrix around y axis Build_XYZ_Rotation_MATRIX4X4(x_ang, y_ang, z_ang, &mrot); // rotate the local coords of the object Transform_OBJECT4DV2(&obj_gouraud_water, &mrot, TRANSFORM_LOCAL_TO_TRANS,1); // perform world transform Model_To_World_OBJECT4DV2(&obj_gouraud_water, TRANSFORM_TRANS_ONLY); // insert the object into render list Insert_OBJECT4DV2_RENDERLIST4DV2(&rend_list, &obj_gouraud_water,0); // update rotation angles if ((x_ang+=1) > 360) x_ang = 0; if ((y_ang+=2) > 360) y_ang = 0; if ((z_ang+=3) > 360) z_ang = 0; // remove backfaces if (backface_mode==1) Remove_Backfaces_RENDERLIST4DV2(&rend_list, &cam); // light scene all at once if (lighting_mode==1) Light_RENDERLIST4DV2_World16(&rend_list, &cam, lights, 4); // apply world to camera transform World_To_Camera_RENDERLIST4DV2(&rend_list, &cam); // sort the polygon list (hurry up!) if (zsort_mode == 1) Sort_RENDERLIST4DV2(&rend_list, SORT_POLYLIST_AVGZ); // apply camera to perspective transformation Camera_To_Perspective_RENDERLIST4DV2(&rend_list, &cam); // apply screen transform Perspective_To_Screen_RENDERLIST4DV2(&rend_list, &cam); sprintf(work_string,"Lighting [%s]: Ambient=%d, Infinite=%d, Point=%d, Spot=%d | Zsort [%s], BckFceRM [%s]", ((lighting_mode == 1) ? "ON" : "OFF"), lights[AMBIENT_LIGHT_INDEX].state, lights[INFINITE_LIGHT_INDEX].state, lights[POINT_LIGHT_INDEX].state, lights[SPOT_LIGHT2_INDEX].state, ((zsort_mode == 1) ? "ON" : "OFF"), ((backface_mode == 1) ? "ON" : "OFF")); Draw_Text_GDI(work_string, 0, WINDOW_HEIGHT-34, RGB(0,255,0), lpddsback); // draw instructions Draw_Text_GDI("Press ESC to exit. Press <H> for Help.", 0, 0, RGB(0,255,0), lpddsback); // should we display help int text_y = 16; if (help_mode==1) { // draw help menu Draw_Text_GDI("<A>..............Toggle ambient light source.", 0, text_y+=12, RGB(255,255,255), lpddsback); Draw_Text_GDI("<I>..............Toggle infinite light source.", 0, text_y+=12, RGB(255,255,255), lpddsback); Draw_Text_GDI("<P>..............Toggle point light source.", 0, text_y+=12, RGB(255,255,255), lpddsback); Draw_Text_GDI("<S>..............Toggle spot light source.", 0, text_y+=12, RGB(255,255,255), lpddsback); Draw_Text_GDI("<W>..............Toggle wire frame/solid mode.", 0, text_y+=12, RGB(255,255,255), lpddsback); Draw_Text_GDI("<B>..............Toggle backface removal.", 0, text_y+=12, RGB(255,255,255), lpddsback); Draw_Text_GDI("<H>..............Toggle Help.", 0, text_y+=12, RGB(255,255,255), lpddsback); Draw_Text_GDI("<ESC>............Exit demo.", 0, text_y+=12, RGB(255,255,255), lpddsback); } // end help // lock the back buffer DDraw_Lock_Back_Surface(); // reset number of polys rendered debug_polys_rendered_per_frame = 0; // render the object if (wireframe_mode == 0) Draw_RENDERLIST4DV2_Wire16(&rend_list, back_buffer, back_lpitch); else if (wireframe_mode == 1) Draw_RENDERLIST4DV2_Solid16(&rend_list, back_buffer, back_lpitch); // unlock the back buffer DDraw_Unlock_Back_Surface(); // flip the surfaces DDraw_Flip(); // sync to 30ish fps Wait_Clock(30); // check of user is trying to exit if (KEY_DOWN(VK_ESCAPE) || keyboard_state[DIK_ESCAPE]) { PostMessage(main_window_handle, WM_DESTROY,0,0); } // end if // return success return(1); } // end Game_Main
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! static MATRIX4X4 mrot; // general rotation matrix static float x_ang = 0, y_ang = 2, z_ang = 0; int index; // looping var // start the timing clock Start_Clock(); // clear the drawing surface DDraw_Fill_Surface(lpddsback, 0); // read keyboard and other devices here DInput_Read_Keyboard(); // game logic here... // reset the object (this only matters for backface and object removal) Reset_OBJECT4DV1(&obj); // reset angles x_ang = z_ang = 0; // is user trying to rotate if (KEY_DOWN(VK_DOWN)) x_ang = 1; else if (KEY_DOWN(VK_UP)) x_ang = -1; // generate rotation matrix around y axis Build_XYZ_Rotation_MATRIX4X4(x_ang, y_ang, z_ang, &mrot); // rotate the local coords of single polygon in renderlist Transform_OBJECT4DV1(&obj, &mrot, TRANSFORM_LOCAL_ONLY,1); // perform local/model to world transform Model_To_World_OBJECT4DV1(&obj); // generate camera matrix Build_CAM4DV1_Matrix_Euler(&cam, CAM_ROT_SEQ_ZYX); // remove backfaces Remove_Backfaces_OBJECT4DV1(&obj, &cam); // apply world to camera transform World_To_Camera_OBJECT4DV1(&obj, &cam); // apply camera to perspective transformation Camera_To_Perspective_OBJECT4DV1(&obj, &cam); // apply screen transform Perspective_To_Screen_OBJECT4DV1(&obj, &cam); // draw instructions Draw_Text_GDI("Press ESC to exit. Use UP ARROW and DOWN ARROW to rotate.", 0, 0, RGB(0,255,0), lpddsback); // lock the back buffer DDraw_Lock_Back_Surface(); // render the object Draw_OBJECT4DV1_Wire16(&obj, back_buffer, back_lpitch); // unlock the back buffer DDraw_Unlock_Back_Surface(); // flip the surfaces DDraw_Flip(); // sync to 30ish fps Wait_Clock(30); // check of user is trying to exit if (KEY_DOWN(VK_ESCAPE) || keyboard_state[DIK_ESCAPE]) { PostMessage(main_window_handle, WM_DESTROY,0,0); } // end if // return success return(1); } // end Game_Main
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! static MATRIX4X4 mrot; // general rotation matrix // these are used to create a circling camera static float view_angle = 0; static float camera_distance = 6000; static VECTOR4D pos = {0,0,0,0}; static float tank_speed; static float turning = 0; char work_string[256]; // temp string int index; // looping var // start the timing clock Start_Clock(); // clear the drawing surface DDraw_Fill_Surface(lpddsback, 0); // draw the sky Draw_Rectangle(0,0, WINDOW_WIDTH-1, WINDOW_HEIGHT/2, RGB16Bit(0,140,192), lpddsback); // draw the ground Draw_Rectangle(0,WINDOW_HEIGHT/2, WINDOW_WIDTH-1, WINDOW_HEIGHT-1, RGB16Bit(103,62,3), lpddsback); // read keyboard and other devices here DInput_Read_Keyboard(); // game logic here... // reset the render list Reset_RENDERLIST4DV1(&rend_list); // allow user to move camera // turbo if (keyboard_state[DIK_SPACE]) tank_speed = 5*TANK_SPEED; else tank_speed = TANK_SPEED; // forward/backward if (keyboard_state[DIK_UP]) { // move forward cam.pos.x += tank_speed*Fast_Sin(cam.dir.y); cam.pos.z += tank_speed*Fast_Cos(cam.dir.y); } // end if if (keyboard_state[DIK_DOWN]) { // move backward cam.pos.x -= tank_speed*Fast_Sin(cam.dir.y); cam.pos.z -= tank_speed*Fast_Cos(cam.dir.y); } // end if // rotate if (keyboard_state[DIK_RIGHT]) { cam.dir.y+=3; // add a little turn to object if ((turning+=2) > 15) turning=15; } // end if if (keyboard_state[DIK_LEFT]) { cam.dir.y-=3; // add a little turn to object if ((turning-=2) < -15) turning=-15; } // end if else // center heading again { if (turning > 0) turning-=1; else if (turning < 0) turning+=1; } // end else // generate camera matrix Build_CAM4DV1_Matrix_Euler(&cam, CAM_ROT_SEQ_ZYX); // insert the tanks in the world for (index = 0; index < NUM_TANKS; index++) { // reset the object (this only matters for backface and object removal) Reset_OBJECT4DV1(&obj_tank); // generate rotation matrix around y axis Build_XYZ_Rotation_MATRIX4X4(0, tanks[index].w, 0, &mrot); // rotate the local coords of the object Transform_OBJECT4DV1(&obj_tank, &mrot, TRANSFORM_LOCAL_TO_TRANS,1); // set position of tank obj_tank.world_pos.x = tanks[index].x; obj_tank.world_pos.y = tanks[index].y; obj_tank.world_pos.z = tanks[index].z; // attempt to cull object if (!Cull_OBJECT4DV1(&obj_tank, &cam, CULL_OBJECT_XYZ_PLANES)) { // if we get here then the object is visible at this world position // so we can insert it into the rendering list // perform local/model to world transform Model_To_World_OBJECT4DV1(&obj_tank, TRANSFORM_TRANS_ONLY); // insert the object into render list Insert_OBJECT4DV1_RENDERLIST4DV1(&rend_list, &obj_tank); } // end if } // end for // insert the player into the world // reset the object (this only matters for backface and object removal) Reset_OBJECT4DV1(&obj_player); // set position of tank obj_player.world_pos.x = cam.pos.x+300*Fast_Sin(cam.dir.y); obj_player.world_pos.y = cam.pos.y-70; obj_player.world_pos.z = cam.pos.z+300*Fast_Cos(cam.dir.y); // generate rotation matrix around y axis Build_XYZ_Rotation_MATRIX4X4(0, cam.dir.y+turning, 0, &mrot); // rotate the local coords of the object Transform_OBJECT4DV1(&obj_player, &mrot, TRANSFORM_LOCAL_TO_TRANS,1); // perform world transform Model_To_World_OBJECT4DV1(&obj_player, TRANSFORM_TRANS_ONLY); // insert the object into render list Insert_OBJECT4DV1_RENDERLIST4DV1(&rend_list, &obj_player); // insert the towers in the world for (index = 0; index < NUM_TOWERS; index++) { // reset the object (this only matters for backface and object removal) Reset_OBJECT4DV1(&obj_tower); // set position of tower obj_tower.world_pos.x = towers[index].x; obj_tower.world_pos.y = towers[index].y; obj_tower.world_pos.z = towers[index].z; // attempt to cull object if (!Cull_OBJECT4DV1(&obj_tower, &cam, CULL_OBJECT_XYZ_PLANES)) { // if we get here then the object is visible at this world position // so we can insert it into the rendering list // perform local/model to world transform Model_To_World_OBJECT4DV1(&obj_tower); // insert the object into render list Insert_OBJECT4DV1_RENDERLIST4DV1(&rend_list, &obj_tower); } // end if } // end for // seed number generator so that modulation of markers is always the same srand(13); // insert the ground markers into the world for (int index_x = 0; index_x < NUM_POINTS_X; index_x++) for (int index_z = 0; index_z < NUM_POINTS_Z; index_z++) { // reset the object (this only matters for backface and object removal) Reset_OBJECT4DV1(&obj_marker); // set position of tower obj_marker.world_pos.x = RAND_RANGE(-100,100)-UNIVERSE_RADIUS+index_x*POINT_SIZE; obj_marker.world_pos.y = obj_marker.max_radius; obj_marker.world_pos.z = RAND_RANGE(-100,100)-UNIVERSE_RADIUS+index_z*POINT_SIZE; // attempt to cull object if (!Cull_OBJECT4DV1(&obj_marker, &cam, CULL_OBJECT_XYZ_PLANES)) { // if we get here then the object is visible at this world position // so we can insert it into the rendering list // perform local/model to world transform Model_To_World_OBJECT4DV1(&obj_marker); // insert the object into render list Insert_OBJECT4DV1_RENDERLIST4DV1(&rend_list, &obj_marker); } // end if } // end for // remove backfaces Remove_Backfaces_RENDERLIST4DV1(&rend_list, &cam); // apply world to camera transform World_To_Camera_RENDERLIST4DV1(&rend_list, &cam); // apply camera to perspective transformation Camera_To_Perspective_RENDERLIST4DV1(&rend_list, &cam); // apply screen transform Perspective_To_Screen_RENDERLIST4DV1(&rend_list, &cam); sprintf(work_string,"pos:[%f, %f, %f] heading:[%f] elev:[%f]", cam.pos.x, cam.pos.y, cam.pos.z, cam.dir.y, cam.dir.x); Draw_Text_GDI(work_string, 0, WINDOW_HEIGHT-20, RGB(0,255,0), lpddsback); // draw instructions Draw_Text_GDI("Press ESC to exit. Press Arrow Keys to Move. Space for TURBO.", 0, 0, RGB(0,255,0), lpddsback); // lock the back buffer DDraw_Lock_Back_Surface(); // render the object Draw_RENDERLIST4DV1_Wire16(&rend_list, back_buffer, back_lpitch); // unlock the back buffer DDraw_Unlock_Back_Surface(); // flip the surfaces DDraw_Flip(); // sync to 30ish fps Wait_Clock(30); // check of user is trying to exit if (KEY_DOWN(VK_ESCAPE) || keyboard_state[DIK_ESCAPE]) { PostMessage(main_window_handle, WM_DESTROY,0,0); } // end if // return success return(1); } // end Game_Main
int Game_Main(void *parms, int num_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 static int player_moving = 0; // tracks player motion // 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(); // clear the drawing surface DDraw_Fill_Surface(lpddsback, 0); // lock the back buffer DDraw_Lock_Back_Surface(); // draw the background reactor image Draw_Bitmap16(&reactor, back_buffer, back_lpitch, 0); // unlock the back buffer DDraw_Unlock_Back_Surface(); // get player input // get the keyboard data lpdikey->GetDeviceState(256, (LPVOID)keyboard_state); // reset motion flag player_moving = 0; // test direction of motion, this is a good example of testing the keyboard // although the code could be optimized this is more educational if (keyboard_state[DIK_RIGHT] && keyboard_state[DIK_UP]) { // move skelaton skelaton.x+=2; skelaton.y-=2; dx=2; dy=-2; // set motion flag player_moving = 1; // check animation needs to change if (skelaton.curr_animation != SKELATON_NEAST) Set_Animation_BOB(&skelaton,SKELATON_NEAST); } // end if else if (keyboard_state[DIK_LEFT] && keyboard_state[DIK_UP]) { // move skelaton skelaton.x-=2; skelaton.y-=2; dx=-2; dy=-2; // set motion flag player_moving = 1; // check animation needs to change if (skelaton.curr_animation != SKELATON_NWEST) Set_Animation_BOB(&skelaton,SKELATON_NWEST); } // end if else if (keyboard_state[DIK_LEFT] && keyboard_state[DIK_DOWN]) { // move skelaton skelaton.x-=2; skelaton.y+=2; dx=-2; dy=2; // set motion flag player_moving = 1; // check animation needs to change if (skelaton.curr_animation != SKELATON_SWEST) Set_Animation_BOB(&skelaton,SKELATON_SWEST); } // end if else if (keyboard_state[DIK_RIGHT] && keyboard_state[DIK_DOWN]) { // move skelaton skelaton.x+=2; skelaton.y+=2; dx=2; dy=2; // set motion flag player_moving = 1; // check animation needs to change if (skelaton.curr_animation != SKELATON_SEAST) Set_Animation_BOB(&skelaton,SKELATON_SEAST); } // end if else if (keyboard_state[DIK_RIGHT]) { // move skelaton skelaton.x+=2; dx=2; dy=0; // set motion flag player_moving = 1; // check animation needs to change if (skelaton.curr_animation != SKELATON_EAST) Set_Animation_BOB(&skelaton,SKELATON_EAST); } // end if else if (keyboard_state[DIK_LEFT]) { // move skelaton skelaton.x-=2; dx=-2; dy=0; // set motion flag player_moving = 1; // check animation needs to change if (skelaton.curr_animation != SKELATON_WEST) Set_Animation_BOB(&skelaton,SKELATON_WEST); } // end if else if (keyboard_state[DIK_UP]) { // move skelaton skelaton.y-=2; dx=0; dy=-2; // set motion flag player_moving = 1; // check animation needs to change if (skelaton.curr_animation != SKELATON_NORTH) Set_Animation_BOB(&skelaton,SKELATON_NORTH); } // end if else if (keyboard_state[DIK_DOWN]) { // move skelaton skelaton.y+=2; dx=0; dy=+2; // set motion flag player_moving = 1; // check animation needs to change if (skelaton.curr_animation != SKELATON_SOUTH) Set_Animation_BOB(&skelaton,SKELATON_SOUTH); } // end if // only animate if player is moving if (player_moving) { // animate skelaton Animate_BOB(&skelaton); // see if skelaton hit a wall // lock surface, so we can scan it DDraw_Lock_Back_Surface(); // call the color scanner with WALL_COLOR the color of the walls // try to center the scan on the feet of the player // note since we are uin 16-bit mode, we need to scan the 16 bit value then compare // it against the 16-bit color code for the green pixel which has values RB(41,231,41) // but depending if this is a 5.5.5 or 5.6.5 the 16-bit value will be different, however // during ddraw_init RGB16Bit() was vectored (function pointer) to either 5.5.5 or 5.6.5 // depending on the actual surface mode, so it should all work out :) if (Color_Scan16(skelaton.x+16, skelaton.y+16, skelaton.x+skelaton.width-16, skelaton.y+skelaton.height-16, RGB16Bit(WALL_COLOR_R, WALL_COLOR_G, WALL_COLOR_B), RGB16Bit(WALL_COLOR_R, WALL_COLOR_G, WALL_COLOR_B), back_buffer,back_lpitch)) { // back the skelaton up along its last trajectory skelaton.x-=dx; skelaton.y-=dy; } // end if // done, so unlock DDraw_Unlock_Back_Surface(); // check if skelaton is off screen if (skelaton.x < 0 || skelaton.x > (screen_width - skelaton.width)) skelaton.x-=dx; if (skelaton.y < 0 || skelaton.y > (screen_height - skelaton.height)) skelaton.y-=dy; } // end if // draw the skelaton Draw_BOB16(&skelaton, lpddsback); // draw some text Draw_Text_GDI("I STILL HAVE A BONE TO PICK!",0,screen_height - 32,RGB(32,32,32),lpddsback); Draw_Text_GDI("(16-Bit Version) USE ARROW KEYS TO MOVE, <ESC> TO EXIT.",0,0,RGB(32,32,32),lpddsback); // flip the surfaces DDraw_Flip(); // sync to 30 fps Wait_Clock(30); // return success return(1); } // end Game_Main