📄 demoii10_2_8b.cpp
字号:
// shut everything down
// release all your resources created for the game here....
// now directsound
DSound_Stop_All_Sounds();
DSound_Delete_All_Sounds();
DSound_Shutdown();
// directmusic
DMusic_Delete_All_MIDI();
DMusic_Shutdown();
// shut down directinput
DInput_Release_Keyboard();
// shutdown directinput
DInput_Shutdown();
// shutdown directdraw last
DDraw_Shutdown();
Close_Error_File();
// 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!
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;
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*.38, rgblookup[RGB16Bit565(38,168,252)], lpddsback);
// draw the ground
Draw_Rectangle(0,WINDOW_HEIGHT*.38, WINDOW_WIDTH, WINDOW_HEIGHT, rgblookup[RGB16Bit565(85,85,255)], 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;
Wait_Clock(100); // wait, so keyboard doesn't bounce
} // end if
// toggle spot light
if (keyboard_state[DIK_S])
{
// toggle spot light
if (lights2[SPOT_LIGHT2_INDEX].state == LIGHTV2_STATE_ON)
lights2[SPOT_LIGHT2_INDEX].state = LIGHTV2_STATE_OFF;
else
lights2[SPOT_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
// clipping
if (keyboard_state[DIK_X])
{
// toggle x clipping
x_clip_mode = -x_clip_mode;
Wait_Clock(100); // wait, so keyboard doesn't bounce
} // end if
if (keyboard_state[DIK_Y])
{
// toggle y clipping
y_clip_mode = -y_clip_mode;
Wait_Clock(100); // wait, so keyboard doesn't bounce
} // end if
if (keyboard_state[DIK_Z])
{
// toggle z clipping
z_clip_mode = -z_clip_mode;
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;
// make engine sound
DSound_Set_Freq(car_sound_id,8000+fabs(cam_speed)*250);
// 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);
if ((plight_ang+=3) > 360)
plight_ang = 0;
// move spot light source in ellipse around game world
lights2[SPOT_LIGHT2_INDEX].pos.x = 1000*Fast_Cos(slight_ang);
lights2[SPOT_LIGHT2_INDEX].pos.y = 200;
lights2[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);
//////////////////////////////////////////////////////////////////////////
// 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(&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_Wire(&rend_list, back_buffer, back_lpitch);
else
if (wireframe_mode == 1)
Draw_RENDERLIST4DV2_Solid(&rend_list, back_buffer, back_lpitch);
// unlock the back buffer
DDraw_Unlock_Back_Surface();
// draw cockpit
Draw_BOB(&cockpit, lpddsback);
sprintf(work_string,"Lighting [%s]: Ambient=%d, Infinite=%d, Point=%d, Spot=%d, BckFceRM [%s]",
((lighting_mode == 1) ? "ON" : "OFF"),
lights2[AMBIENT_LIGHT_INDEX].state,
lights2[INFINITE_LIGHT_INDEX].state,
lights2[POINT_LIGHT_INDEX].state,
lights2[SPOT_LIGHT2_INDEX].state,
((backface_mode == 1) ? "ON" : "OFF"));
Draw_Text_GDI(work_string, 0, WINDOW_HEIGHT-34, RGB(0,255,0), lpddsback);
sprintf(work_string,"X Clipping [%s], Y Clipping [%s], Z Clipping [%s], ",((x_clip_mode == 1) ? "ON" : "OFF") ,
((y_clip_mode == 1) ? "ON" : "OFF") ,
((z_clip_mode == 1) ? "ON" : "OFF") );
Draw_Text_GDI(work_string, 0, WINDOW_HEIGHT-34-16, 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("<X>..............Toggle X axis clipping.", 0, text_y+=12, RGB(255,255,255), lpddsback);
Draw_Text_GDI("<Y>..............Toggle Y axis clipping.", 0, text_y+=12, RGB(255,255,255), lpddsback);
Draw_Text_GDI("<Z>..............Toggle Z axis clipping.", 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
//////////////////////////////////////////////////////////
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -