void Game::Step() { // 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 int id = -1; static mat4 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 z_buffer_mode = -1; static int display_mode = 1; static int bsp_backface_mode = 1; char work_string[256]; // temp string int index; // looping var bspeditor::Context* context = bspeditor::Context::Instance(); Graphics& graphics = Modules::GetGraphics(); DIMOUSESTATE& mouse_state = t3d::Modules::GetInput().MouseState(); // is user in editor mode or viewing mode? switch(context->editor_state) { case EDITOR_STATE_INIT: ///////////////////////////////////////////////// { // now transition to edit mode context->editor_state = EDITOR_STATE_EDIT; } break; case EDITOR_STATE_EDIT: ///////////////////////////////////////////////// { // start the timing clock Modules::GetTimer().Start_Clock(); // clear the drawing surface //DDraw_Fill_Surface(graphics.GetBackSurface(), 0); graphics.GetBackSurface()->Blt(NULL, gadgets->background->GetImage(), NULL, DDBLT_WAIT, NULL); // read keyboard and other devices here Modules::GetInput().ReadKeyboard(); //DInput_Read_Mouse(); // game logic here... // find nearest line context->nearest_line = task->DeleteLine(mouse_state.lX, mouse_state.lY,0); // is user trying to press left button? if (mouse_state.rgbButtons[0] || mouse_state.rgbButtons[2])// && mouse_debounce[0] == 0) { // determine area click is occuring in if (mouse_state.lX > INTERFACE_MIN_X && mouse_state.lX < INTERFACE_MAX_X && mouse_state.lY > INTERFACE_MIN_Y && mouse_state.lY < INTERFACE_MAX_Y) { // check for gadget if ((id = gadgets->Process(mouse_state.lX, mouse_state.lY, mouse_state.rgbButtons)) >= 0) { // play a sound first //DSound_Play(beep0_sound_id); // process clicks switch(id) { case GADGET_ID_SEGMENT_MODE_ID: { task->action = ACTION_STARTING_LINE; } break; case GADGET_ID_POLYLINE_MODE_ID: { task->action = ACTION_STARTING_POLYLINE; } break; case GADGET_ID_DELETE_MODE_ID: { task->action = ACTION_DELETE_LINE; } break; case GADGET_ID_CLEAR_ALL_ID: { // reset everything context->Reset(); } break; case GADGET_ID_FLOOR_MODE_ID: { task->action = ACTION_FLOOR_MODE; } break; case GADGET_ID_WALL_TEXTURE_DEC: { if (--context->texture_index_wall < -1) context->texture_index_wall = -1; } break; case GADGET_ID_WALL_TEXTURE_INC: { if (++context->texture_index_wall >= NUM_TEXTURES) context->texture_index_wall = NUM_TEXTURES-1; } break; case GADGET_ID_WALL_HEIGHT_DEC: { if ((context->wall_height-=8) < 0) context->wall_height = 0; } break; case GADGET_ID_WALL_HEIGHT_INC: { context->wall_height+=8; } break; case GADGET_ID_FLOOR_TEXTURE_DEC: { if (--context->texture_index_floor < -1) context->texture_index_floor = -1; } break; case GADGET_ID_FLOOR_TEXTURE_INC: { if (++context->texture_index_floor >= NUM_TEXTURES) context->texture_index_floor = NUM_TEXTURES-1; } break; default: break; } // end switch } // end if else { } // end else } // end if interface // test for bsp area if (mouse_state.lX > BSP_MIN_X && mouse_state.lX < BSP_MAX_X && mouse_state.lY > BSP_MIN_Y && mouse_state.lY < BSP_MAX_Y) { // process bsp editor area click // test if this is starting point or endpoint if (task->action == ACTION_STARTING_LINE) { // set starting field, note the offsets to center the // starting point in middle of cross hairs if (!context->snap_to_grid) { context->lines[context->total_lines].p0.x = mouse_state.lX; context->lines[context->total_lines].p0.y = mouse_state.lY; } // end if else { context->lines[context->total_lines].p0.x = BSP_GRID_SIZE * (int)(0.5+(float)mouse_state.lX / (float)BSP_GRID_SIZE); context->lines[context->total_lines].p0.y = BSP_GRID_SIZE * (int)(0.5+(float)mouse_state.lY / (float)BSP_GRID_SIZE); } // end if // remember starting line to close contour context->starting_line = context->total_lines; // set point type to ending point task->action = ACTION_ENDING_LINE; // wait for mouse button release // Wait_For_Mouse_Up(); } // end if start of wall else if (task->action == ACTION_ENDING_LINE) { // check for normal left mouse click if (mouse_state.rgbButtons[0]) { // must be the end of a wall or ending point if (!context->snap_to_grid) { context->lines[context->total_lines].p1.x = mouse_state.lX; context->lines[context->total_lines].p1.y = mouse_state.lY; } // end if else { context->lines[context->total_lines].p1.x = BSP_GRID_SIZE * (int)(0.5+(float)mouse_state.lX / (float)BSP_GRID_SIZE); context->lines[context->total_lines].p1.y = BSP_GRID_SIZE * (int)(0.5+(float)mouse_state.lY / (float)BSP_GRID_SIZE); } // end if // set texture id context->lines[context->total_lines].texture_id = context->texture_index_wall; // set height context->lines[context->total_lines].height = context->wall_height; // set attributes context->lines[context->total_lines].attr = context->poly_attr; // set color context->lines[context->total_lines].color = context->poly_color; // set task->action back to starting point task->action = ACTION_STARTING_LINE; // advance number of context->lines if (++context->total_lines >= MAX_LINES) context->total_lines = MAX_LINES - 1; // wait for mouse button release // Wait_For_Mouse_Up(); } // end if else // check for right mouse click trying to close contour if (mouse_state.rgbButtons[2]) { // reset, user wants to restart segment task->action = ACTION_STARTING_LINE; } // end if } // end else if else // test if this is starting point or endpoint if (task->action == ACTION_STARTING_POLYLINE) { // set starting field, note the offsets to center the // starting point in middle of cross hairs if (!context->snap_to_grid) { context->lines[context->total_lines].p0.x = mouse_state.lX; context->lines[context->total_lines].p0.y = mouse_state.lY; } // end if else { context->lines[context->total_lines].p0.x = BSP_GRID_SIZE * (int)(0.5+(float)mouse_state.lX / (float)BSP_GRID_SIZE); context->lines[context->total_lines].p0.y = BSP_GRID_SIZE * (int)(0.5+(float)mouse_state.lY / (float)BSP_GRID_SIZE); } // end if // remember starting line to close contour context->starting_line = context->total_lines; // set point type to ending point task->action = ACTION_ADDING_POLYLINE; // wait for mouse button release // Wait_For_Mouse_Up(); } // end if start of wall else if (task->action == ACTION_ADDING_POLYLINE) { // check for normal left mouse click if (mouse_state.rgbButtons[0]) { // must be the end of a wall or ending point if (!context->snap_to_grid) { context->lines[context->total_lines].p1.x = mouse_state.lX; context->lines[context->total_lines].p1.y = mouse_state.lY; } // end if else { context->lines[context->total_lines].p1.x = BSP_GRID_SIZE * (int)(0.5+(float)mouse_state.lX / (float)BSP_GRID_SIZE); context->lines[context->total_lines].p1.y = BSP_GRID_SIZE * (int)(0.5+(float)mouse_state.lY / (float)BSP_GRID_SIZE); } // end if // set texture id context->lines[context->total_lines].texture_id = context->texture_index_wall; // set height context->lines[context->total_lines].height = context->wall_height; // set attributes context->lines[context->total_lines].attr = context->poly_attr; // set color context->lines[context->total_lines].color = context->poly_color; // set task->action back to starting point task->action = ACTION_ADDING_POLYLINE; // advance number of context->lines if (++context->total_lines >= MAX_LINES) context->total_lines = MAX_LINES - 1; // set start point as last endpoint context->lines[context->total_lines].p0.x = context->lines[context->total_lines-1].p1.x; context->lines[context->total_lines].p0.y = context->lines[context->total_lines-1].p1.y; // wait for mouse button release // Wait_For_Mouse_Up(); } // end if else // check for right mouse click trying to close contour if (mouse_state.rgbButtons[2]) { // end the polyline task->action = ACTION_STARTING_POLYLINE; // Wait_For_Mouse_Up(); } // end if } // end else if else if (task->action==ACTION_DELETE_LINE) { // try and delete the line nearest selected point task->DeleteLine(mouse_state.lX, mouse_state.lY,1); // wait for mouse release // Wait_For_Mouse_Up(); } // end if else if (task->action==ACTION_FLOOR_MODE) { // compute cell that mouse is on int cell_x = (mouse_state.lX - BSP_MIN_X) / BSP_GRID_SIZE; int cell_y = (mouse_state.lY - BSP_MIN_Y) / BSP_GRID_SIZE; // drawing or erasing if (mouse_state.rgbButtons[0]) { // set texture id context->floors[cell_y][cell_x] = context->texture_index_floor; } // end if else if (mouse_state.rgbButtons[2]) { // set texture id context->floors[cell_y][cell_x] = -1; } // end if } // end if } // end if in bsp area // force button debounce if (mouse_state.rgbButtons[0]) mouse_state.rgbButtons[0] = 0; if (mouse_state.rgbButtons[2]) mouse_state.rgbButtons[2] = 0; //mouse_debounce[0] = 1; } // end if // debounce mouse //if (!mouse_state.rgbButtons[0] && mouse_debounce[0] == 1) // mouse_debounce[0] = 0; // draw the floors if (context->view_floors == 1) task->DrawFloors(graphics.GetBackSurface()); // lock the back buffer graphics.LockBackSurface(); // draw the context->lines if (context->view_walls == 1) task->DrawLines(graphics.GetBackBuffer(), graphics.GetBackLinePitch()); // draw the grid if (context->view_grid==1) task->DrawGrid(graphics.GetBackBuffer(), graphics.GetBackLinePitch(), _RGB32BIT(255,255,255,255), BSP_MIN_X, BSP_MIN_Y, BSP_GRID_SIZE, BSP_GRID_SIZE, BSP_CELLS_X,BSP_CELLS_Y); // unlock the back buffer graphics.UnlockBackSurface(); // draw all the buttons gadgets->Draw(graphics.GetBackSurface()); // draw the textures previews if (context->texture_index_wall >= 0) { // selected texture context->textures->SetPosition(665, 302-55); context->textures->SetCurrFrame(context->texture_index_wall); context->textures->DrawScaled(64,64,graphics.GetBackSurface()); // get the line that mouse is closest to context->nearest_line = task->DeleteLine(mouse_state.lX, mouse_state.lY,0); // draw texture that is applied to line in secondary preview window if (context->nearest_line >= 0) { context->textures->SetPosition(736, 247); context->textures->SetCurrFrame(context->lines[context->nearest_line].texture_id); context->textures->DrawScaled(32,32,graphics.GetBackSurface()); // now draw height of line sprintf(buffer,"%d",context->lines[context->nearest_line].height); graphics.DrawTextGDI(buffer, 750,188,RGB(0,255,0),graphics.GetBackSurface()); } // end if } // end if // draw the floor texture preview if (context->texture_index_floor >= 0) { context->textures->SetPosition(665, 453); context->textures->SetCurrFrame(context->texture_index_floor); context->textures->DrawScaled(64,64,graphics.GetBackSurface()); } // end if // draw the wall index if (context->texture_index_wall >= 0) { sprintf(buffer,"%d",context->texture_index_wall); graphics.DrawTextGDI(buffer, 738,336-56,RGB(0,255,0),graphics.GetBackSurface()); } // end if else { graphics.DrawTextGDI("None", 738,336,RGB(0,255,0),graphics.GetBackSurface()); } // end // wall height sprintf(buffer,"%d",context->wall_height); graphics.DrawTextGDI(buffer, 688, 188,RGB(0,255,0),graphics.GetBackSurface()); // texture index for floors if (context->texture_index_floor >= 0) { sprintf(buffer,"%d",context->texture_index_floor); graphics.DrawTextGDI(buffer, 738,488,RGB(0,255,0),graphics.GetBackSurface()); } // end if else { graphics.DrawTextGDI("None", 738,488,RGB(0,255,0),graphics.GetBackSurface()); } // end // display stats sprintf(buffer,"WorldPos=(%d,%d). Num Walls=%d. Num Floor Tiles=%d. Total Polys=%d.", mouse_state.lX, mouse_state.lY, context->total_lines+1, context->num_floor_tiles, 2*(context->total_lines+1+context->num_floor_tiles)); graphics.DrawTextGDI(buffer, 8,WINDOW_HEIGHT - 18,RGB(0,255,0),graphics.GetBackSurface()); // flip the surfaces graphics.Flip(main_window_handle); // sync to 30ish fps Sleep(10); #if 0 // check of user is trying to exit if (KEY_DOWN(VK_ESCAPE) || Modules::GetInput().KeyboardState()[DIK_ESCAPE]) { PostMessage(main_window_handle, WM_DESTROY,0,0); } // end if #endif } break; case EDITOR_STATE_VIEW: /////////////////////////////////////////////// { // start the timing clock Modules::GetTimer().Start_Clock(); // clear the drawing surface graphics.FillSurface(graphics.GetBackSurface(), 0); // read keyboard and other devices here Modules::GetInput().ReadKeyboard(); // game logic here... // modes and lights // wireframe mode if (Modules::GetInput().KeyboardState()[DIK_W]) { // toggle wireframe mode if (++wireframe_mode > 1) wireframe_mode=0; Modules::GetTimer().Wait_Clock(100); // wait, so keyboard doesn't bounce } // end if // backface removal if (Modules::GetInput().KeyboardState()[DIK_B]) { // toggle backface removal backface_mode = -backface_mode; Modules::GetTimer().Wait_Clock(100); // wait, so keyboard doesn't bounce } // end if // lighting if (Modules::GetInput().KeyboardState()[DIK_L]) { // toggle lighting engine completely lighting_mode = -lighting_mode; Modules::GetTimer().Wait_Clock(100); // wait, so keyboard doesn't bounce } // end if LightsMgr& lights = Modules::GetGraphics().GetLights(); // toggle ambient light if (Modules::GetInput().KeyboardState()[DIK_A]) { // toggle ambient light if (lights[AMBIENT_LIGHT_INDEX].state == LIGHT_STATE_ON) lights[AMBIENT_LIGHT_INDEX].state = LIGHT_STATE_OFF; else lights[AMBIENT_LIGHT_INDEX].state = LIGHT_STATE_ON; Modules::GetTimer().Wait_Clock(100); // wait, so keyboard doesn't bounce } // end if // toggle point light if (Modules::GetInput().KeyboardState()[DIK_P]) { // toggle point light if (lights[POINT_LIGHT_INDEX].state == LIGHT_STATE_ON) lights[POINT_LIGHT_INDEX].state = LIGHT_STATE_OFF; else lights[POINT_LIGHT_INDEX].state = LIGHT_STATE_ON; // toggle point light if (lights[POINT_LIGHT2_INDEX].state == LIGHT_STATE_ON) lights[POINT_LIGHT2_INDEX].state = LIGHT_STATE_OFF; else lights[POINT_LIGHT2_INDEX].state = LIGHT_STATE_ON; Modules::GetTimer().Wait_Clock(100); // wait, so keyboard doesn't bounce } // end if // toggle infinite light if (Modules::GetInput().KeyboardState()[DIK_I]) { // toggle ambient light if (lights[INFINITE_LIGHT_INDEX].state == LIGHT_STATE_ON) lights[INFINITE_LIGHT_INDEX].state = LIGHT_STATE_OFF; else lights[INFINITE_LIGHT_INDEX].state = LIGHT_STATE_ON; Modules::GetTimer().Wait_Clock(100); // wait, so keyboard doesn't bounce } // end if // help menu if (Modules::GetInput().KeyboardState()[DIK_H]) { // toggle help menu help_mode = -help_mode; Modules::GetTimer().Wait_Clock(100); // wait, so keyboard doesn't bounce } // end if // z-sorting if (Modules::GetInput().KeyboardState()[DIK_S]) { // toggle z sorting zsort_mode = -zsort_mode; Modules::GetTimer().Wait_Clock(100); // wait, so keyboard doesn't bounce } // end if // z buffer if (Modules::GetInput().KeyboardState()[DIK_Z]) { // toggle z buffer z_buffer_mode = -z_buffer_mode; Modules::GetTimer().Wait_Clock(100); // wait, so keyboard doesn't bounce } // end if // forward/backward if (Modules::GetInput().KeyboardState()[DIK_UP]) { // move forward if ( (context->cam_speed+=2) > MAX_SPEED) context->cam_speed = MAX_SPEED; } // end if else if (Modules::GetInput().KeyboardState()[DIK_DOWN]) { // move backward if ((context->cam_speed-=2) < -MAX_SPEED) context->cam_speed = -MAX_SPEED; } // end if // rotate around y axis or yaw if (Modules::GetInput().KeyboardState()[DIK_RIGHT]) { context->cam->DirRef().y+=10; // scroll the background background_bmp->Scroll(-10); } // end if if (Modules::GetInput().KeyboardState()[DIK_LEFT]) { context->cam->DirRef().y-=10; // scroll the background background_bmp->Scroll(10); } // end if // ambient scrolling static int scroll_counter = 0; if (++scroll_counter > 5) { // scroll the background background_bmp->Scroll(1); // reset scroll counter scroll_counter = 0; } // end if // move point light source in ellipse around game world lights[POINT_LIGHT_INDEX].pos.x = 1000*cos(DEG_TO_RAD(plight_ang)); lights[POINT_LIGHT_INDEX].pos.y = 100; lights[POINT_LIGHT_INDEX].pos.z = 1000*sin(DEG_TO_RAD(plight_ang)); // move point light source in ellipse around game world lights[POINT_LIGHT2_INDEX].pos.x = 500*cos(DEG_TO_RAD(-2*plight_ang)); lights[POINT_LIGHT2_INDEX].pos.y = 200; lights[POINT_LIGHT2_INDEX].pos.z = 1000*sin(DEG_TO_RAD(-2*plight_ang)); if ((plight_ang+=3) > 360) plight_ang = 0; // decelerate camera if (context->cam_speed > (CAM_DECEL) ) context->cam_speed-=CAM_DECEL; else if (context->cam_speed < (-CAM_DECEL) ) context->cam_speed+=CAM_DECEL; else context->cam_speed = 0; // move camera context->cam->PosRef().x += context->cam_speed*sin(DEG_TO_RAD(context->cam->Dir().y)); context->cam->PosRef().z += context->cam_speed*cos(DEG_TO_RAD(context->cam->Dir().y)); // generate camera matrix context->cam->BuildMatrixEuler(CAM_ROT_SEQ_ZYX); // build the camera vector rotation matrix //////////////////////////////// mrot = mat4::RotateX(context->cam->Dir().x) * mat4::RotateX(context->cam->Dir().y) * mat4::RotateX(context->cam->Dir().z); // transform the (0,0,1) vector and store it in the cam.n vector, this is now the // view direction vector context->cam->_n = mrot * vec4(0,0,1,1); // normalize the viewing vector context->cam->_n.Normalize(); // reset the render list list->Reset(); // render the floors into polylist first // reset the object (this only matters for backface and object removal) RenderObject* obj_scene = bspeditor::Context::Instance()->obj_scene; obj_scene->Reset(); // set position of floor obj_scene->SetWorldPos(0, 0, 0); // attempt to cull object if (!obj_scene->Cull(*context->cam, CULL_OBJECT_XYZ_PLANES)) { // create an identity to work with mrot = mat4::Identity(); // rotate the local coords of the object obj_scene->Transform(mrot, TRANSFORM_LOCAL_TO_TRANS,1); // perform world transform obj_scene->ModelToWorld(TRANSFORM_TRANS_ONLY); // insert the object into render list list->Insert(*obj_scene,0); } // end if // reset the object (this only matters for backface and object removal) obj_scene->Reset(); // set position of ceiling obj_scene->SetWorldPos(0, context->ceiling_height, 0); // attempt to cull object if (!obj_scene->Cull(*context->cam, CULL_OBJECT_XYZ_PLANES)) { // create an identity to work with mrot = mat4::Identity(); // rotate the local coords of the object obj_scene->Transform(mrot, TRANSFORM_LOCAL_TO_TRANS,1); // perform world transform obj_scene->ModelToWorld(TRANSFORM_TRANS_ONLY); // insert the object into render list list->Insert(*obj_scene,0); } // end if int polycount = list->GetNumPolys(); // insert the bsp into rendering list without culling context->bspfile->bsp_root->InsertionTraversal(*list, *context->cam, 1); // compute total number of polys inserted into list polycount = list->GetNumPolys() - polycount; // reset number of polys rendered debug_polys_rendered_per_frame = 0; debug_polys_lit_per_frame = 0; // remove backfaces if (backface_mode==1) list->RemoveBackfaces(*context->cam); // apply world to camera transform list->WorldToCamera(*context->cam); // clip the polygons themselves now list->ClipPolys(*context->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) { lights.Transform(context->cam->CameraMat(), TRANSFORM_LOCAL_TO_TRANS); list->LightWorld32(*context->cam); } // end if // sort the polygon list (hurry up!) if (zsort_mode == 1) list->Sort(SORT_POLYLIST_AVGZ); // apply camera to perspective transformation list->CameraToPerspective(*context->cam); // apply screen transform list->PerspectiveToScreen(*context->cam); // lock the back buffer graphics.LockBackSurface(); // draw background background_bmp->Draw32(graphics.GetBackBuffer(), graphics.GetBackLinePitch(), 0); // reset number of polys rendered debug_polys_rendered_per_frame = 0; // render the renderinglist if (wireframe_mode == 0) list->DrawWire32(graphics.GetBackBuffer(), graphics.GetBackLinePitch()); else if (wireframe_mode == 1) { RenderContext rc; // is z buffering enabled if (z_buffer_mode == 1) { // set up rendering context for 1/z buffer rc.attr = RENDER_ATTR_NOBUFFER //| RENDER_ATTR_ALPHA //| RENDER_ATTR_MIPMAP //| RENDER_ATTR_BILERP | RENDER_ATTR_TEXTURE_PERSPECTIVE_AFFINE; } // end if else { // set up rendering context for no zbuffer rc.attr = RENDER_ATTR_NOBUFFER //| RENDER_ATTR_ALPHA //| RENDER_ATTR_MIPMAP // | RENDER_ATTR_BILERP | RENDER_ATTR_TEXTURE_PERSPECTIVE_AFFINE; } // end else // if z abuffer or 1/z buffer is being used then clear z buffer if (rc.attr & RENDER_ATTR_ZBUFFER || rc.attr & RENDER_ATTR_WRITETHRUZBUFFER) { // clear the z buffer zbuffer->Clear(32000 << FIXP16_SHIFT); } // end if else if (rc.attr & RENDER_ATTR_INVZBUFFER) { // clear the 1/z buffer zbuffer->Clear(0 << FIXP16_SHIFT); } // end if rc.video_buffer = graphics.GetBackBuffer(); rc.lpitch = graphics.GetBackLinePitch(); rc.mip_dist = 3500; rc.zbuffer = (unsigned char*)zbuffer->Buffer(); rc.zpitch = WINDOW_WIDTH*4; rc.texture_dist = 0; rc.alpha_override = -1; // render scene list->DrawContext(rc); } // end if // unlock the back buffer graphics.UnlockBackSurface(); sprintf(work_string,"Lighting [%s]: Ambient=%d, Infinite=%d, BckFceRM [%s], Zsort [%s], Zbuffer [%s] vdir=[%3.2f,%3.2f,%3.2f]", ((lighting_mode == 1) ? "ON" : "OFF"), lights[AMBIENT_LIGHT_INDEX].state, lights[INFINITE_LIGHT_INDEX].state, ((backface_mode == 1) ? "ON" : "OFF"), ((zsort_mode == 1) ? "ON" : "OFF"), ((z_buffer_mode == 1) ? "ON" : "OFF"), context->cam->Normal().x, context->cam->Normal().y, context->cam->Normal().z); graphics.DrawTextGDI(work_string, 0, WINDOW_HEIGHT-34-16, RGB(0,255,0), graphics.GetBackSurface()); // draw instructions graphics.DrawTextGDI("Press ESC to return to editor mode. Press <H> for Help.", 0, 0, RGB(0,255,0), graphics.GetBackSurface()); // should we display help int text_y = 16; if (help_mode==1) { // draw help menu graphics.DrawTextGDI("<A>..............Toggle ambient light source.", 0, text_y+=12, RGB(255,255,255), graphics.GetBackSurface()); graphics.DrawTextGDI("<I>..............Toggle infinite light source.", 0, text_y+=12, RGB(255,255,255), graphics.GetBackSurface()); graphics.DrawTextGDI("<P>..............Toggle point lights.", 0, text_y+=12, RGB(255,255,255), graphics.GetBackSurface()); graphics.DrawTextGDI("<B>..............Toggle backface removal.", 0, text_y+=12, RGB(255,255,255), graphics.GetBackSurface()); graphics.DrawTextGDI("<S>..............Toggle Z sorting.", 0, text_y+=12, RGB(255,255,255), graphics.GetBackSurface()); graphics.DrawTextGDI("<Z>..............Toggle Z buffering.", 0, text_y+=12, RGB(255,255,255), graphics.GetBackSurface()); graphics.DrawTextGDI("<Z>..............Toggle Wireframe mode.", 0, text_y+=12, RGB(255,255,255), graphics.GetBackSurface()); graphics.DrawTextGDI("<H>..............Toggle Help.", 0, text_y+=12, RGB(255,255,255), graphics.GetBackSurface()); graphics.DrawTextGDI("<ESC>............Exit demo.", 0, text_y+=12, RGB(255,255,255), graphics.GetBackSurface()); } // end help sprintf(work_string,"Polys Rendered: %d, Polys lit: %d, Polys Inserted from BSP: %d", debug_polys_rendered_per_frame, debug_polys_lit_per_frame, polycount); graphics.DrawTextGDI(work_string, 0, WINDOW_HEIGHT-34-16-16, RGB(0,255,0), graphics.GetBackSurface()); sprintf(work_string,"CAM [%5.2f, %5.2f, %5.2f]", context->cam->Pos().x, context->cam->Pos().y, context->cam->Pos().z); graphics.DrawTextGDI(work_string, 0, WINDOW_HEIGHT-34-16-16-16, RGB(0,255,0), graphics.GetBackSurface()); // flip the surfaces graphics.Flip(main_window_handle); // sync to 30ish fps Modules::GetTimer().Wait_Clock(30); // check of user is trying to exit if (KEY_DOWN(VK_ESCAPE) || Modules::GetInput().KeyboardState()[DIK_ESCAPE]) { // switch game state back to editor more context->editor_state = EDITOR_STATE_EDIT; } // end if } break; default: break; } // end switch }
int WINAPI WinMain( HINSTANCE hinstance, HINSTANCE hprevinstance, LPSTR lpcmdline, int ncmdshow) { WNDCLASS winclass; // this will hold the class created HWND hwnd; // generic window handle MSG msg; // generic message HDC hdc; // generic dc RECT rect; float velocity[15]; int ball_y[15], ball_x[15], iEndPos[15], index=0; LARGE_INTEGER a; __int64 b=0,c=0, diffrenceC_B=0; //fill in the window class stucture winclass.style = CS_DBLCLKS | CS_OWNDC | CS_HREDRAW | CS_VREDRAW; winclass.lpfnWndProc = WindowProc; winclass.cbClsExtra = 0; winclass.cbWndExtra = 0; winclass.hInstance = hinstance; winclass.hIcon = LoadIcon(NULL, IDI_APPLICATION); winclass.hCursor = LoadCursor(NULL, IDC_ARROW); winclass.hbrBackground = (HBRUSH) GetStockObject(BLACK_BRUSH); winclass.lpszMenuName = NULL; //MAKEINTRESOURCE(IDR_MENU1); winclass.lpszClassName = WINDOW_CLASS_NAME; // register the window class if (!RegisterClass(&winclass)) return(0); // create the window if (!(hwnd = CreateWindow(WINDOW_CLASS_NAME, // class "Bouncing on the desktop", // title WS_OVERLAPPEDWINDOW | WS_VISIBLE, 0,600, // x,y WINDOW_WIDTH, // width WINDOW_HEIGHT, // height NULL, // handle to parent NULL, // handle to menu hinstance,// instance NULL))) // creation parms { MessageBox(hwnd, "Window Could not be Created", NULL, MB_OK); //NULL is default for Error return(0); } // save the window handle and instance in a global main_window_handle = hwnd; main_instance = hinstance; for(index=0; index<=14; index++) //start balls at random positions, set velocity = 0 { ball_y[index]= -10; ball_x[index]= rand()%1000; iEndPos[index]= rand()%900; velocity[index]= 0; } index=0; //reset index // enter main event loop while(1) { //check messages if (PeekMessage(&msg,NULL,0,0,PM_REMOVE)) { // test if this is a quit message if (msg.message == WM_QUIT) break; // translate any accelerator keys TranslateMessage(&msg); // send the message to the window proc DispatchMessage(&msg); } // end if if(KEY_DOWN(VK_ESCAPE)) //if hit the Esc key quit the program PostQuitMessage(0); if(!QueryPerformanceCounter(&a)) { MessageBox(hwnd, "Error on QueryPerformanceCounter()", NULL, MB_OK); //NULL is default for Error return(0); } else { b = c = a.QuadPart; } hdc= GetDC(hwnd); //--------Begin Text Info--------------------- SetBkMode(hdc, TRANSPARENT); //set background color //first create the eraser string for variable text SetTextColor(hdc,RGB(0,255,0)); //set text color black TextOut(hdc, 30, 60, buffer, strlen(buffer)); //print text TextOut(hdc, 30, 75, buffer2, strlen(buffer2)); //print text //unvarieing text SetTextColor(hdc,RGB(0,255,0)); //set text color black TextOut(hdc, 30, 15,"Keys 0-6 set the delay time", strlen("Keys 0-6 set the delay time")); //print text TextOut(hdc, 30, 30,"Left and right arrows change gravity", strlen("Left and right arrows change gravity")); //print text TextOut(hdc, 30, 45,"Up and down arrows change friction", strlen("Up and down arrows change friction")); //print text TextOut(hdc, 30, 90,"S key starts over", strlen("S key starts over")); //print text //variable text sprintf(buffer,"Friction= ", friction); sprintf(buffer2,"Gravity= ", gravity); TextOut(hdc, 30, 60, buffer, strlen(buffer)); //print text TextOut(hdc, 30, 75, buffer2, strlen(buffer2)); //print text //--------End Text Info------------------------- ReleaseDC(hwnd, hdc); hdc= GetWindowDC(GetDesktopWindow()); //-------------Erasing ball---------------- //fill in rect struct for erasing ball rect.left = ball_x[index] - BALL_RADIUS5; rect.right = ball_x[index] + BALL_RADIUS5; rect.top = ball_y[index] - BALL_RADIUS5; rect.bottom = ball_y[index] + BALL_RADIUS5; //Draw erasing ball in the old position SelectObject(hdc, red_pen5); SelectObject(hdc, red_brush5); Ellipse(hdc,rect.left, rect.top, rect.right, rect.bottom); //------------End Erasing ball---------------- //-------------Test to see whats going on----------- //if the ball hits the ground, bounce back. The reason its here is because the erasing ball //needs the old position to erase the drawing ball. if(ball_y[index] >= iEndPos[index]) { //velocity[index] = -velocity[index]; ball_y[index] = iEndPos[index]; //need to rest the y position because of >=, the y could be > 370 } //allows user to restart balls in a new possition if they want to //the reason its put here is so that if the user decides to restart, the erasing ball //will erase the drawing ball, and won't leave ball marks all over. if(startOver) { for(index=0; index<=14; index++) //start balls at random positions, set velocity = 0 { ball_y[index]= -10; ball_x[index]= rand()%2000; iEndPos[index]= rand()%900; velocity[index]= 0; }//end for loop on index startOver= false; //reset startOver back to false }//end if on startOver //--------------End Test to see whats going on //-------------- Move the ball-------------- velocity[index]+= gravity* ( (diffrenceC_B*0.0009)*0.02); velocity[index]*= friction; ball_y[index]+= (int) velocity[index]; //-------------End Move the ball------------ //---------------Draw the Ball------------------ //Redraw the ball in its new position //fill in rect struct for drawing ball //ball 5 rect.left = ball_x[index] - BALL_RADIUS5; rect.right = ball_x[index] + BALL_RADIUS5; rect.top = ball_y [index] - BALL_RADIUS5; rect.bottom = ball_y[index] + BALL_RADIUS5; //Draw the ball in its new spot SelectObject(hdc, red_pen5); SelectObject(hdc, red_brush5); Ellipse(hdc,rect.left, rect.top, rect.right, rect.bottom); //end ball 5 //ball 4 rect.left = ball_x[index] - BALL_RADIUS4; rect.right = ball_x[index] + BALL_RADIUS4; rect.top = ball_y [index] - BALL_RADIUS4; rect.bottom = ball_y[index] + BALL_RADIUS4; //Draw the ball in its new spot SelectObject(hdc, red_pen4); SelectObject(hdc, red_brush4); Ellipse(hdc,rect.left, rect.top, rect.right, rect.bottom); //end ball 4 //ball 3 rect.left = ball_x[index] - BALL_RADIUS3; rect.right = ball_x[index] + BALL_RADIUS3; rect.top = ball_y [index] - BALL_RADIUS3; rect.bottom = ball_y[index] + BALL_RADIUS3; //Draw the ball in its new spot SelectObject(hdc, red_pen3); SelectObject(hdc, red_brush3); Ellipse(hdc,rect.left, rect.top, rect.right, rect.bottom); //end ball 3 //ball 2 rect.left = ball_x[index] - BALL_RADIUS2; rect.right = ball_x[index] + BALL_RADIUS2; rect.top = ball_y [index] - BALL_RADIUS2; rect.bottom = ball_y[index] + BALL_RADIUS2; //Draw the ball in its new spot SelectObject(hdc, red_pen2); SelectObject(hdc, red_brush2); Ellipse(hdc,rect.left, rect.top, rect.right, rect.bottom); //end ball 2 //ball 1 rect.left = ball_x[index] - BALL_RADIUS1; rect.right = ball_x[index] + BALL_RADIUS1; rect.top = ball_y [index] - BALL_RADIUS1; rect.bottom = ball_y[index] + BALL_RADIUS1; //Draw the ball in its new spot SelectObject(hdc, red_pen1); SelectObject(hdc, red_brush1); Ellipse(hdc,rect.left, rect.top, rect.right, rect.bottom); //end ball 1 //----------------End draw the ball---------------s //if index increments to 14 (or last ball) start drawing from the //begining again over again (meaning draw ball b0, b1,...b14 start back at b1) index++; if(index >=14) index=0; if(!QueryPerformanceCounter(&a)) { MessageBox(hwnd, "Error on QueryPerformanceCounter()", NULL, MB_OK); //NULL is default for Error return(0); } else { c = a.QuadPart; diffrenceC_B= c-b; } //slow things down a bit //Sleep(delay); //Release device context ReleaseDC(GetDesktopWindow(), hdc); } // end while // return to Windows like this return(msg.wParam); } // end WinMain
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 float hl = 300, // artificial light height ks = 1.25; // generic scaling factor to make things look good 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-1, RGB16Bit(50,50,200), 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 // next animation if (keyboard_state[DIK_2]) { if (++obj_md2.anim_state >= NUM_MD2_ANIMATIONS) obj_md2.anim_state = 0; Set_Animation_MD2(&obj_md2, obj_md2.anim_state, MD2_ANIM_SINGLE_SHOT); Wait_Clock(100); // wait, so keyboard doesn't bounce } // end if // previous animation if (keyboard_state[DIK_1]) { if (--obj_md2.anim_state < 0) obj_md2.anim_state = NUM_MD2_ANIMATIONS-1; Set_Animation_MD2(&obj_md2, obj_md2.anim_state, MD2_ANIM_SINGLE_SHOT); Wait_Clock(100); // wait, so keyboard doesn't bounce } // end if // replay animation if (keyboard_state[DIK_3]) { Set_Animation_MD2(&obj_md2, obj_md2.anim_state, MD2_ANIM_SINGLE_SHOT); Wait_Clock(100); // wait, so keyboard doesn't bounce } // end if // replay animation if (keyboard_state[DIK_4]) { Set_Animation_MD2(&obj_md2, obj_md2.anim_state, MD2_ANIM_LOOP); 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; // scroll the background Scroll_Bitmap(&background_bmp, -10); } // end if if (keyboard_state[DIK_LEFT]) { cam.dir.y-=5; // scroll the background Scroll_Bitmap(&background_bmp, 10); } // end if // scroll sky slowly Scroll_Bitmap(&background_bmp, -1); // 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 = 500*Fast_Cos(plight_ang); //lights2[POINT_LIGHT_INDEX].pos.y = 200; lights2[POINT_LIGHT_INDEX].pos.z = 500*Fast_Sin(plight_ang); // move point light source in ellipse around game world lights2[POINT_LIGHT2_INDEX].pos.x = 200*Fast_Cos(-2*plight_ang); //lights2[POINT_LIGHT2_INDEX].pos.y = 400; lights2[POINT_LIGHT2_INDEX].pos.z = 200*Fast_Sin(-2*plight_ang); if ((plight_ang+=1) > 360) plight_ang = 0; // generate camera matrix Build_CAM4DV1_Matrix_Euler(&cam, CAM_ROT_SEQ_ZYX); ////////////////////////////////////////////////////////////////////////// // the terrain // 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); ////////////////////////////////////////////////////////////////////////// int v0, v1, v2, v3; // used to track vertices VECTOR4D pl, // position of the light po, // position of the occluder object/vertex vlo, // vector from light to object ps; // position of the shadow float rs, // radius of shadow t; // parameter t ////////////////////////////////////////////////////////////////////////// // render model, this next section draws each copy of the mech model ////////////////////////////////////////////////////////////////////////// // animate the model Animate_MD2(&obj_md2); // extract the frame of animation from vertex banks Extract_MD2_Frame(&obj_model, // pointer to destination object &obj_md2); // md2 object to extract frame from // set position of object obj_model.world_pos.x = 0; obj_model.world_pos.y = 100; obj_model.world_pos.z = 0; // reset the object (this only matters for backface and object removal) Reset_OBJECT4DV2(&obj_model); // create identity matrix MAT_IDENTITY_4X4(&mrot); // transform the local coords of the object Transform_OBJECT4DV2(&obj_model, &mrot, TRANSFORM_LOCAL_TO_TRANS,1); // perform world transform Model_To_World_OBJECT4DV2(&obj_model, TRANSFORM_TRANS_ONLY); // insert the object into render list Insert_OBJECT4DV2_RENDERLIST4DV2(&rend_list, &obj_model,0); // set position of object obj_model.world_pos.x = 0; obj_model.world_pos.y = 100; obj_model.world_pos.z = 200; // reset the object (this only matters for backface and object removal) Reset_OBJECT4DV2(&obj_model); // create identity matrix MAT_IDENTITY_4X4(&mrot); // transform the local coords of the object Transform_OBJECT4DV2(&obj_model, &mrot, TRANSFORM_LOCAL_TO_TRANS,1); // perform world transform Model_To_World_OBJECT4DV2(&obj_model, TRANSFORM_TRANS_ONLY); // insert the object into render list Insert_OBJECT4DV2_RENDERLIST4DV2(&rend_list, &obj_model,0); ////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////// // draw all the light objects to represent the position of light sources // reset the object (this only matters for backface and object removal) Reset_OBJECT4DV2(&obj_light_array[INDEX_RED_LIGHT_INDEX]); // set position of object to light obj_light_array[INDEX_RED_LIGHT_INDEX].world_pos = lights2[POINT_LIGHT_INDEX].pos; // create identity matrix MAT_IDENTITY_4X4(&mrot); // transform the local coords of the object Transform_OBJECT4DV2(&obj_light_array[INDEX_RED_LIGHT_INDEX], &mrot, TRANSFORM_LOCAL_TO_TRANS,1); // perform world transform Model_To_World_OBJECT4DV2(&obj_light_array[INDEX_RED_LIGHT_INDEX], TRANSFORM_TRANS_ONLY); // insert the object into render list Insert_OBJECT4DV2_RENDERLIST4DV2(&rend_list, &obj_light_array[INDEX_RED_LIGHT_INDEX],0); // reset the object (this only matters for backface and object removal) Reset_OBJECT4DV2(&obj_light_array[INDEX_YELLOW_LIGHT_INDEX]); // set position of object to light obj_light_array[INDEX_YELLOW_LIGHT_INDEX].world_pos = lights2[POINT_LIGHT2_INDEX].pos; // create identity matrix MAT_IDENTITY_4X4(&mrot); // transform the local coords of the object Transform_OBJECT4DV2(&obj_light_array[INDEX_YELLOW_LIGHT_INDEX], &mrot, TRANSFORM_LOCAL_TO_TRANS,1); // perform world transform Model_To_World_OBJECT4DV2(&obj_light_array[INDEX_YELLOW_LIGHT_INDEX], TRANSFORM_TRANS_ONLY); // insert the object into render list Insert_OBJECT4DV2_RENDERLIST4DV2(&rend_list, &obj_light_array[INDEX_YELLOW_LIGHT_INDEX],0); //////////////////////////////////////////////////////////////////////////////////// // reset number of polys rendered debug_polys_rendered_per_frame = 0; debug_polys_lit_per_frame = 0; // perform rendering pass one // 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, CLIP_POLY_X_PLANE | CLIP_POLY_Y_PLANE | CLIP_POLY_Z_PLANE ); // 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(); // draw background Draw_Bitmap16(&background_bmp, back_buffer, back_lpitch,0); // 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 // set up rendering context rc.attr = RENDER_ATTR_ZBUFFER // | RENDER_ATTR_ALPHA // | RENDER_ATTR_MIPMAP // | RENDER_ATTR_BILERP | RENDER_ATTR_TEXTURE_PERSPECTIVE_AFFINE; // initialize zbuffer to 0 fixed point Clear_Zbuffer(&zbuffer, (16000 << FIXP16_SHIFT)); // set up remainder of rendering context rc.video_buffer = back_buffer; rc.lpitch = back_lpitch; rc.mip_dist = 0; 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_2(&rc); } // end if // now make second rendering pass and draw shadow // reset the render list Reset_RENDERLIST4DV2(&rend_list); ////////////////////////////////////////////////////////////////////////// // project shaded object into shadow by projecting it's vertices onto // the ground plane // reset the object (this only matters for backface and object removal) Reset_OBJECT4DV2(&obj_model); // save the shading attributes/color of each polygon, and override them with // attributes of a shadow then restore them int pcolor[OBJECT4DV2_MAX_POLYS], // used to store color pattr[OBJECT4DV2_MAX_POLYS]; // used to store attribute // save all the color and attributes for each polygon for (int pindex = 0; pindex < obj_model.num_polys; pindex++) { // save attribute and color pattr[pindex] = obj_model.plist[pindex].attr; pcolor[pindex] = obj_model.plist[pindex].color; // set attributes for shadow rendering obj_model.plist[pindex].attr = POLY4DV2_ATTR_RGB16 | POLY4DV2_ATTR_SHADE_MODE_CONSTANT | POLY4DV2_ATTR_TRANSPARENT; obj_model.plist[pindex].color = RGB16Bit(50,50,50) + (7 << 24); } // end for pindex // create identity matrix MAT_IDENTITY_4X4(&mrot); // solve for t when the projected vertex intersects ground plane pl = lights2[POINT_LIGHT_INDEX].pos; // transform each local/model vertex of the object mesh and store result // in "transformed" vertex list, note for (int vertex=0; vertex < obj_model.num_vertices; vertex++) { POINT4D presult; // hold result of each transformation // compute parameter t0 when projected ray pierces y=0 plane VECTOR4D vi; // set position of object obj_model.world_pos.x = 0; obj_model.world_pos.y = 100; obj_model.world_pos.z = 0; // transform coordinates to worldspace right now... VECTOR4D_Add(&obj_model.vlist_local[vertex].v, &obj_model.world_pos, &vi); float t0 = -pl.y / (vi.y - pl.y); // transform point obj_model.vlist_trans[vertex].v.x = pl.x + t0*(vi.x - pl.x); obj_model.vlist_trans[vertex].v.y = 10.0; // pl.y + t0*(vi.y - pl.y); obj_model.vlist_trans[vertex].v.z = pl.z + t0*(vi.z - pl.z); obj_model.vlist_trans[vertex].v.w = 1.0; } // end for index // insert the object into render list Insert_OBJECT4DV2_RENDERLIST4DV2(&rend_list, &obj_model,0); // and now second shadow object from second light source... // solve for t when the projected vertex intersects pl = lights2[POINT_LIGHT_INDEX].pos; // transform each local/model vertex of the object mesh and store result // in "transformed" vertex list for (vertex=0; vertex < obj_model.num_vertices; vertex++) { POINT4D presult; // hold result of each transformation // compute parameter t0 when projected ray pierces y=0 plane VECTOR4D vi; // set position of object obj_model.world_pos.x = 0; obj_model.world_pos.y = 100; obj_model.world_pos.z = 200; // transform coordinates to worldspace right now... VECTOR4D_Add(&obj_model.vlist_local[vertex].v, &obj_model.world_pos, &vi); float t0 = -pl.y / (vi.y - pl.y); // transform point obj_model.vlist_trans[vertex].v.x = pl.x + t0*(vi.x - pl.x); obj_model.vlist_trans[vertex].v.y = 10.0; // pl.y + t0*(vi.y - pl.y); obj_model.vlist_trans[vertex].v.z = pl.z + t0*(vi.z - pl.z); obj_model.vlist_trans[vertex].v.w = 1.0; } // end for index // insert the object into render list Insert_OBJECT4DV2_RENDERLIST4DV2(&rend_list, &obj_model,0); // restore attributes and color for (pindex = 0; pindex < obj_model.num_polys; pindex++) { // save attribute and color obj_model.plist[pindex].attr = pattr[pindex]; obj_model.plist[pindex].color = pcolor[pindex]; } // end for pindex ////////////////////////////////////////////////////////////////////////// // 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, CLIP_POLY_X_PLANE | CLIP_POLY_Y_PLANE | CLIP_POLY_Z_PLANE ); // 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); // 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 // set up rendering context rc.attr = RENDER_ATTR_ZBUFFER | RENDER_ATTR_ALPHA // | RENDER_ATTR_MIPMAP // | RENDER_ATTR_BILERP | RENDER_ATTR_TEXTURE_PERSPECTIVE_AFFINE; // initialize zbuffer to 0 fixed point //Clear_Zbuffer(&zbuffer, (16000 << FIXP16_SHIFT)); // set up remainder of rendering context rc.video_buffer = back_buffer; rc.lpitch = back_lpitch; rc.mip_dist = 0; 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_3(&rc); } // end if // unlock the back buffer DDraw_Unlock_Back_Surface(); // draw cockpit //Draw_BOB16(&cockpit, lpddsback); // draw instructions Draw_Text_GDI("Press ESC to exit. Press <H> for Help.", 0, 0, RGB(255,255,255), 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("<Z>..............Toggle Z-sorting.", 0, text_y+=12, RGB(255,255,255), lpddsback); Draw_Text_GDI("<1>,<2>..........Previous/Next Animation.", 0, text_y+=12, RGB(255,255,255), lpddsback); Draw_Text_GDI("<3>,<4>..........Play Animation Single Shot/Looped.", 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,"Lighting [%s]: Ambient=%d, Infinite=%d, Point=%d, BckFceRM [%s], Zsort[%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"), ((zsort_mode == 1) ? "ON" : "OFF") ); Draw_Text_GDI(work_string, 0+1, WINDOW_HEIGHT-34+1, RGB(0,0,0), lpddsback); Draw_Text_GDI(work_string, 0, WINDOW_HEIGHT-34, RGB(255,255,255), lpddsback); sprintf(work_string,"Polys Rendered: %d, Polys lit: %d Anim[%d]=%s Frm=%d", debug_polys_rendered_per_frame, debug_polys_lit_per_frame, obj_md2.anim_state,md2_anim_strings[obj_md2.anim_state], obj_md2.curr_frame ); Draw_Text_GDI(work_string, 0+1, WINDOW_HEIGHT-34-2*16+1, RGB(0,0,0), lpddsback); Draw_Text_GDI(work_string, 0, WINDOW_HEIGHT-34-2*16, RGB(255,255,255), 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+1, WINDOW_HEIGHT-34-3*16+1, RGB(0,0,0), lpddsback); Draw_Text_GDI(work_string, 0, WINDOW_HEIGHT-34-3*16, RGB(255,255,255), lpddsback); // flip the surfaces DDraw_Flip2(); // 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
// -------------------------------------------------------------------------- // main(Number of arguments, Argument values) // Description : This is the entry point of the program. // Return value : SUCCESS:0 ERROR:-1 // -------------------------------------------------------------------------- int main(int argc, char **argv) { // AR.Drone class ARDrone ardrone; // Initialize if (!ardrone.open()) { printf("Failed to initialize.\n"); return -1; } // Battery int battery = ardrone.getBatteryPercentage(); printf("ardrone.battery = %d [%%]\n", battery); // Instructions printf("***************************************\n"); printf("* CV Drone sample program *\n"); printf("* - Haw To Play - *\n"); printf("***************************************\n"); printf("* *\n"); printf("* - Controls - *\n"); printf("* 'Space' -- Takeoff/Landing *\n"); printf("* 'Up' -- Move forward *\n"); printf("* 'Down' -- Move backward *\n"); printf("* 'Left' -- Turn left *\n"); printf("* 'Right' -- Turn right *\n"); printf("* 'Shift+Up' -- Move upward *\n"); printf("* 'Shift+Down' -- Move downward *\n"); printf("* 'Shift+Left' -- Move left *\n"); printf("* 'Shift+Right' -- Move right *\n"); printf("* *\n"); printf("* - Others - *\n"); printf("* 'C' -- Change camera *\n"); printf("* 'Esc' -- Exit *\n"); printf("* *\n"); printf("***************************************\n\n"); // Main loop while (!GetAsyncKeyState(VK_ESCAPE)) { // Update if (!ardrone.update()) break; // Get an image IplImage *image = ardrone.getImage(); // Take off / Landing if (KEY_PUSH(VK_SPACE)) { if (ardrone.onGround()) ardrone.takeoff(); else ardrone.landing(); } // Move double vx = 0.0, vy = 0.0, vz = 0.0, vr = 0.0; if (KEY_DOWN(VK_SHIFT)) { if (KEY_DOWN(VK_UP)) vz = 1.0; if (KEY_DOWN(VK_DOWN)) vz = -1.0; if (KEY_DOWN(VK_LEFT)) vy = 1.0; if (KEY_DOWN(VK_RIGHT)) vy = -1.0; } else { if (KEY_DOWN(VK_UP)) vx = 1.0; if (KEY_DOWN(VK_DOWN)) vx = -1.0; if (KEY_DOWN(VK_LEFT)) vr = 1.0; if (KEY_DOWN(VK_RIGHT)) vr = -1.0; } ardrone.move3D(vx, vy, vz, vr); // Change camera static int mode = 0; if (KEY_PUSH('C')) ardrone.setCamera(++mode%4); // Display the image cvShowImage("camera", image); cvWaitKey(1); } // See you ardrone.close(); return 0; }
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 static PALETTEENTRY glow = {0,0,0,PC_NOCOLLAPSE}; // used to animation red border static int glow_count = 0, glow_dx = 5; // 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_Bitmap(&reactor, back_buffer, back_lpitch, 0); // unlock the back buffer DDraw_Unlock_Back_Surface(); // get player input // get the keyboard data 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 30 fps Wait_Clock(30); // return success return(1); } // end Game_Main
void Game::Step() { static mat4 mrot; // general rotation matrix static float x_ang = 0, // these track the rotation y_ang = 2, // of the object z_ang = 0; Graphics& graphics = Modules::GetGraphics(); int index; // looping var // start the timing clock Modules::GetTimer().Start_Clock(); // clear the drawing surface graphics.FillSurface(graphics.GetBackSurface(), 0); // read keyboard and other devices here Modules::GetInput().ReadKeyboard(); // game logic here... // initialize the renderlist _obj.Reset(); // 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; mrot = mat4::RotateX(x_ang) * mat4::RotateY(y_ang) * mat4::RotateZ(z_ang); // rotate the local coords of single polygon in renderlist _obj.Transform(mrot, TRANSFORM_LOCAL_ONLY, 1); // perform local/model to world transform _obj.ModelToWorld(); // generate camera matrix _cam->BuildMatrixEuler(CAM_ROT_SEQ_ZYX); // remove backfaces _obj.RemoveBackfaces(*_cam); // apply world to camera transform _obj.WorldToCamera(*_cam); // apply camera to perspective transformation _obj.CameraToPerspective(*_cam); // apply screen transform _obj.PerspectiveToScreen(*_cam); // draw instructions graphics.DrawTextGDI("Press ESC to exit. Use UP ARROW and DOWN ARROW to rotate.", 0, 0, RGB(0,255,0), graphics.GetBackSurface()); // lock the back buffer graphics.LockBackSurface(); // render the polygon list _obj.DrawWire32(graphics.GetBackBuffer(), graphics.GetBackLinePitch()); // unlock the back buffer graphics.UnlockBackSurface(); // flip the surfaces graphics.Flip(main_window_handle); // sync to 30ish fps Modules::GetTimer().Wait_Clock(30); // check of user is trying to exit if (KEY_DOWN(VK_ESCAPE) || Modules::GetInput().KeyboardState()[DIK_ESCAPE]) { PostMessage(main_window_handle, WM_DESTROY,0,0); } }
void cheat_handle_stick ( struct vehicle_info *vehicle_info, struct actor_info *actor_info, float time_diff ) { traceLastFunc( "cheat_handle_stick()" ); struct object_base *base_stick, *base_self; struct actor_info *actor_stick; struct vehicle_info *vehicle_stick; float *speed_stick, *speed_self; float *spin_stick, *spin_self; static int id = -1; int i; if ( KEY_PRESSED(set.key_stick) ) { if ( vehicle_info != NULL ) cheat_state->vehicle.stick ^= 1; else cheat_state->actor.stick ^= 1; id = actor_find( id - 1, 1, ACTOR_ALIVE | ACTOR_NOT_SAME_VEHICLE ); } if ( KEY_PRESSED(set.key_stick_nearest) ) { if ( vehicle_info != NULL ) cheat_state->vehicle.stick ^= 1; else cheat_state->actor.stick ^= 1; id = actor_find_nearest( ACTOR_ALIVE | ACTOR_NOT_SAME_VEHICLE ); } if ( (vehicle_info != NULL && cheat_state->vehicle.stick) || (actor_info != NULL && cheat_state->actor.stick) ) { // remove any bad vehicle or actor stuffs if ( isBadPtr_GTA_pVehicle(vehicle_info) ) vehicle_info = NULL; if ( isBadPtr_GTA_pPed(actor_info) ) actor_info = NULL; /* check if actor has disappeared.. and if it has, switch to teh nearest */ if ( id != -1 && actor_info_get(id, ACTOR_ALIVE) == NULL ) id = actor_find_nearest( ACTOR_ALIVE | ACTOR_NOT_SAME_VEHICLE ); if ( KEY_PRESSED(set.key_stick_prev) ) id = actor_find( id, -1, ACTOR_ALIVE | ACTOR_NOT_SAME_VEHICLE ); if ( KEY_PRESSED(set.key_stick_next) ) id = actor_find( id, 1, ACTOR_ALIVE | ACTOR_NOT_SAME_VEHICLE ); /* no actors to stick to */ if ( id == -1 ) { cheat_state_text( "No players found; stick disabled." ); cheat_state->vehicle.stick = 0; cheat_state->actor.stick = 0; return; } /* get actor struct for the actor we're sticking to */ actor_stick = actor_info_get( id, ACTOR_ALIVE | ACTOR_NOT_SAME_VEHICLE ); if ( actor_stick == NULL ) return; /* is this actor in a vehicle? */ vehicle_stick = actor_vehicle_get( actor_stick ); base_stick = vehicle_stick ? &vehicle_stick->base : &actor_stick->base; base_self = vehicle_info ? &vehicle_info->base : &actor_info->base; speed_stick = vehicle_stick ? vehicle_stick->speed : actor_stick->speed; speed_self = vehicle_info ? vehicle_info->speed : actor_info->speed; spin_stick = vehicle_stick ? vehicle_stick->spin : actor_stick->spin; spin_self = vehicle_info ? vehicle_info->spin : actor_info->spin; /* allow warping to work + always warp towards whatever we're sticking to... but only when we're in a vehicle */ if ( KEY_PRESSED(set.key_warp_mod) && vehicle_info != NULL ) { float out[4]; /* multiply the matrix of whatever we're sticking to with the user supplied vector */ matrix_vect4_mult( base_stick->matrix, set.stick_vect, out ); /* multiply the result with the negative warp-speed value, and put it in the speed vector (negative because we want to warp towards teh target, not away from it */ vect3_mult( out, -set.warp_speed, speed_self ); } if ( !KEY_DOWN(set.key_warp_mod) ) { float d[4] = { 0.0f, 0.0f, 0.0f, 0.0f }; float accel_mult = 1.0f; float out[4]; /* handle stick movement keys */ if ( KEY_DOWN(set.key_stick_forward) ) d[1] += 1.0f; if ( KEY_DOWN(set.key_stick_backward) ) d[1] -= 1.0f; if ( KEY_DOWN(set.key_stick_left) ) d[0] -= 1.0f; if ( KEY_DOWN(set.key_stick_right) ) d[0] += 1.0f; if ( KEY_DOWN(set.key_stick_up) ) d[2] += 1.0f; if ( KEY_DOWN(set.key_stick_down) ) d[2] -= 1.0f; if ( KEY_DOWN(set.key_stick_in) ) d[3] -= 1.0f; if ( KEY_DOWN(set.key_stick_out) ) d[3] += 1.0f; if ( !near_zero(set.stick_accel_time) ) { static uint32_t time_start; if ( !vect4_near_zero(d) ) time_start = ( time_start == 0 ) ? time_get() : time_start; else time_start = 0; /* no keys pressed */ /* acceleration */ if ( time_start != 0 ) { float t = TIME_TO_FLOAT( time_get() - time_start ); if ( t < set.stick_accel_time ) accel_mult *= t / set.stick_accel_time; } } /* calculate new vector + dist */ if ( !vect3_near_zero(d) && !vect3_near_zero(set.stick_vect) ) { for ( i = 0; i < 3; i++ ) { d[i] = set.stick_vect[i] * set.stick_vect_dist + d[i] * time_diff * 8.0f * accel_mult; } set.stick_vect_dist = vect3_length( d ); vect3_normalize( d, set.stick_vect ); } /* move towards/away from the center */ if ( !near_zero(d[3]) ) set.stick_vect_dist += d[3] * time_diff * 40.0f * accel_mult; /* Teleport vehicle detachables */ if ( vehicle_info != NULL ) vehicle_detachables_teleport( vehicle_info, &base_self->matrix[4 * 3], &base_stick->matrix[4 * 3] ); matrix_copy( base_stick->matrix, base_self->matrix ); vect3_copy( speed_stick, speed_self ); vect3_copy( spin_stick, spin_self ); /*base_self->interior_id = base_stick->interior_id; gta_interior_id_set(base_stick->interior_id);*/ /* multiply the matrix of the target with the user supplied vector */ matrix_vect4_mult( base_stick->matrix, set.stick_vect, out ); /* multiply the result with the user supplied vector distance */ vect3_mult( out, set.stick_vect_dist, out ); /* and add it to our position */ vect3_vect3_add( &base_self->matrix[4 * 3], out, &base_self->matrix[4 * 3] ); if ( vehicle_info != NULL ) { /* Teleport detachables again :p */ vehicle_detachables_teleport( vehicle_info, &base_stick->matrix[4 * 3], &base_self->matrix[4 * 3] ); vehicle_prevent_below_height( vehicle_info, set.stick_min_height ); } else if ( actor_info != NULL ) { // new pedFlags actor_info->pedFlags.bIsStanding = true; actor_info->pedFlags.bWasStanding = true; actor_info->pedFlags.bStayInSamePlace = true; } } } }
bool CKeyDown::Right() { return KEY_DOWN(VK_RIGHT); }
void Game::Step() { Modules::GetTimer().Step(); // todo zz int debug_polys_rendered_per_frame = 0; int debug_polys_lit_per_frame = 0; static mat4 mrot; // general rotation matrix // state variables for different rendering modes and help static bool wireframe_mode = false; static bool backface_mode = true; static bool lighting_mode = true; static bool help_mode = true; static bool zsort_mode = true; static bool x_clip_mode = true; static bool y_clip_mode = true; static bool z_clip_mode = true; static bool z_buffer_mode = true; static bool display_mode = true; static float turning = 0; char work_string[256]; // temp string Graphics& graphics = Modules::GetGraphics(); // start the timing clock Modules::GetTimer().Start_Clock(); // clear the drawing surface graphics.FillSurface(graphics.GetBackSurface(), 0); // draw the sky // DrawRectangle(0,0, WINDOW_WIDTH, WINDOW_HEIGHT*.5, graphics.GetColor(180,180,220), graphics.GetBackSurface()); graphics.GetBackSurface()->Blt(NULL, background->GetImage(), NULL, DDBLT_WAIT, NULL); // read keyboard and other devices here Modules::GetInput().ReadKeyboard(); // game logic here... // reset the render list _list->Reset(); // modes and lights // wireframe mode if (Modules::GetInput().KeyboardState()[DIK_W]) { // toggle wireframe mode wireframe_mode = !wireframe_mode; Modules::GetTimer().Wait_Clock(100); // wait, so keyboard doesn't bounce } // end if // backface removal if (Modules::GetInput().KeyboardState()[DIK_B]) { // toggle backface removal backface_mode = !backface_mode; Modules::GetTimer().Wait_Clock(100); // wait, so keyboard doesn't bounce } // end if // lighting if (Modules::GetInput().KeyboardState()[DIK_L]) { // toggle lighting engine completely lighting_mode = !lighting_mode; Modules::GetTimer().Wait_Clock(100); // wait, so keyboard doesn't bounce } // end if LightsMgr& lights = Modules::GetGraphics().GetLights(); // toggle ambient light if (Modules::GetInput().KeyboardState()[DIK_A]) { // toggle ambient light if (lights[AMBIENT_LIGHT_INDEX].state == LIGHT_STATE_ON) lights[AMBIENT_LIGHT_INDEX].state = LIGHT_STATE_OFF; else lights[AMBIENT_LIGHT_INDEX].state = LIGHT_STATE_ON; Modules::GetTimer().Wait_Clock(100); // wait, so keyboard doesn't bounce } // end if // toggle infinite light if (Modules::GetInput().KeyboardState()[DIK_I]) { // toggle ambient light if (lights[INFINITE_LIGHT_INDEX].state == LIGHT_STATE_ON) lights[INFINITE_LIGHT_INDEX].state = LIGHT_STATE_OFF; else lights[INFINITE_LIGHT_INDEX].state = LIGHT_STATE_ON; Modules::GetTimer().Wait_Clock(100); // wait, so keyboard doesn't bounce } // end if // toggle point light if (Modules::GetInput().KeyboardState()[DIK_P]) { // toggle point light if (lights[POINT_LIGHT_INDEX].state == LIGHT_STATE_ON) lights[POINT_LIGHT_INDEX].state = LIGHT_STATE_OFF; else lights[POINT_LIGHT_INDEX].state = LIGHT_STATE_ON; Modules::GetTimer().Wait_Clock(100); // wait, so keyboard doesn't bounce } // end if // toggle spot light if (Modules::GetInput().KeyboardState()[DIK_S]) { // toggle spot light if (lights[SPOT_LIGHT2_INDEX].state == LIGHT_STATE_ON) lights[SPOT_LIGHT2_INDEX].state = LIGHT_STATE_OFF; else lights[SPOT_LIGHT2_INDEX].state = LIGHT_STATE_ON; Modules::GetTimer().Wait_Clock(100); // wait, so keyboard doesn't bounce } // end if // help menu if (Modules::GetInput().KeyboardState()[DIK_H]) { // toggle help menu help_mode = !help_mode; Modules::GetTimer().Wait_Clock(100); // wait, so keyboard doesn't bounce } // end if // z-sorting if (Modules::GetInput().KeyboardState()[DIK_S]) { // toggle z sorting zsort_mode = !zsort_mode; Modules::GetTimer().Wait_Clock(100); // wait, so keyboard doesn't bounce } // end if // z buffer if (Modules::GetInput().KeyboardState()[DIK_Z]) { // toggle z buffer z_buffer_mode = !z_buffer_mode; Modules::GetTimer().Wait_Clock(100); // wait, so keyboard doesn't bounce } // end if // object and camera movement // rotate around y axis or yaw if (Modules::GetInput().KeyboardState()[DIK_RIGHT]) { _cam->DirRef().y+=3; // add a little turn to object if ((turning+=2) > 25) turning=25; } // end if else if (Modules::GetInput().KeyboardState()[DIK_LEFT]) { _cam->DirRef().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 if (Modules::GetInput().KeyboardState()[DIK_UP]) { // move forward if ( (cam_speed+=1) > MAX_SPEED) cam_speed = MAX_SPEED; } // end if if (Modules::GetInput().KeyboardState()[DIK_DOWN]) { // move backward if ((cam_speed-=1) < -MAX_SPEED) cam_speed = -MAX_SPEED; } // end if // move to next object if (Modules::GetInput().KeyboardState()[DIK_N]) { if (++curr_object >= NUM_OBJECTS) curr_object = 0; // update pointer obj_work = obj_array[curr_object]; Modules::GetTimer().Wait_Clock(100); // wait, so keyboard doesn't bounce } // 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; // move camera _cam->PosRef().x += cam_speed*sin(DEG_TO_RAD(_cam->Dir().y)); _cam->PosRef().z += cam_speed*cos(DEG_TO_RAD(_cam->Dir().y)); 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*cos(DEG_TO_RAD(plight_ang)); lights[POINT_LIGHT_INDEX].pos.y = 100; lights[POINT_LIGHT_INDEX].pos.z = 1000*sin(DEG_TO_RAD(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*cos(DEG_TO_RAD(slight_ang)); lights[SPOT_LIGHT2_INDEX].pos.y = 200; lights[SPOT_LIGHT2_INDEX].pos.z = 1000*sin(DEG_TO_RAD(slight_ang)); if ((slight_ang-=5) < 0) slight_ang = 360; obj_work->SetWorldPos(_cam->Pos().x + 75*sin(DEG_TO_RAD(_cam->Dir().y)), _cam->Pos().y - 20, _cam->Pos().z + 75*cos(DEG_TO_RAD(_cam->Dir().y))); // generate camera matrix _cam->BuildMatrixEuler(CAM_ROT_SEQ_ZYX); //////////////////////////////////////////////////////// // insert the scenery into universe for (int index = 0; index < NUM_SCENE_OBJECTS; index++) { // reset the object (this only matters for backface and object removal) obj_scene->Reset(); // set position of tower obj_scene->SetWorldPos(scene_objects[index].x, scene_objects[index].y, scene_objects[index].z); // move objects scene_objects[index].x+=scene_objects_vel[index].x; scene_objects[index].y+=scene_objects_vel[index].y; scene_objects[index].z+=scene_objects_vel[index].z; // test for out of bounds if (scene_objects[index].x >= UNIVERSE_RADIUS || scene_objects[index].x <= -UNIVERSE_RADIUS) { scene_objects_vel[index].x=-scene_objects_vel[index].x; scene_objects[index].x+=scene_objects_vel[index].x; } // end if if (scene_objects[index].y >= (UNIVERSE_RADIUS/2) || scene_objects[index].y <= -(UNIVERSE_RADIUS/2)) { scene_objects_vel[index].y=-scene_objects_vel[index].y; scene_objects[index].y+=scene_objects_vel[index].y; } // end if if (scene_objects[index].z >= UNIVERSE_RADIUS || scene_objects[index].z <= -UNIVERSE_RADIUS) { scene_objects_vel[index].z=-scene_objects_vel[index].z; scene_objects[index].z+=scene_objects_vel[index].z; } // end if // attempt to cull object if (!obj_scene->Cull(*_cam, CULL_OBJECT_XYZ_PLANES)) { mrot = mrot.Identity(); // rotate the local coords of the object obj_scene->Transform(mrot, TRANSFORM_LOCAL_TO_TRANS,1); // perform world transform obj_scene->ModelToWorld(TRANSFORM_TRANS_ONLY); // insert the object into render list _list->Insert(*obj_scene, false); } // end if } // end for ////////////////////////////////////////////////////////////////////////// // constant shaded water // reset the object (this only matters for backface and object removal) obj_work->Reset(); // generate rotation matrix around y axis mrot = mat4::RotateX(-15) * mat4::RotateY(_cam->Dir().y + turning); // rotate the local coords of the object obj_work->Transform(mrot, TRANSFORM_LOCAL_TO_TRANS,true); // perform world transform obj_work->ModelToWorld(TRANSFORM_TRANS_ONLY); // insert the object into render list _list->Insert(*obj_work, false); // reset number of polys rendered debug_polys_rendered_per_frame = 0; debug_polys_lit_per_frame = 0; // use these to rotate objects static float x_ang = 0, y_ang = 0, z_ang = 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; // update the alpha level alpha_override+=alpha_inc; if (alpha_override > 255 || alpha_override < 0) { alpha_inc=-alpha_inc; alpha_override+=alpha_inc; } // end if // remove backfaces if (backface_mode) _list->RemoveBackfaces(*_cam); // apply world to camera transform _list->WorldToCamera(*_cam); // clip the polygons themselves now _list->ClipPolys(*_cam, (x_clip_mode ? CLIP_POLY_X_PLANE : 0) | (y_clip_mode ? CLIP_POLY_Y_PLANE : 0) | (z_clip_mode ? CLIP_POLY_Z_PLANE : 0) ); // light scene all at once if (lighting_mode) { lights.Transform(_cam->CameraMat(), TRANSFORM_LOCAL_TO_TRANS); _list->LightWorld32(*_cam); } // sort the polygon list (hurry up!) if (zsort_mode) _list->Sort(SORT_POLYLIST_AVGZ); // apply camera to perspective transformation _list->CameraToPerspective(*_cam); // apply screen transform _list->PerspectiveToScreen(*_cam); // lock the back buffer graphics.LockBackSurface(); // reset number of polys rendered debug_polys_rendered_per_frame = 0; if (wireframe_mode) { _list->DrawWire32(graphics.GetBackBuffer(), graphics.GetBackLinePitch()); } else { // set up rendering context RenderContext rc; rc.attr = RENDER_ATTR_NOBUFFER | RENDER_ATTR_ALPHA | RENDER_ATTR_MIPMAP | RENDER_ATTR_BILERP | RENDER_ATTR_TEXTURE_PERSPECTIVE_AFFINE; rc.video_buffer = graphics.GetBackBuffer(); rc.lpitch = graphics.GetBackLinePitch(); rc.mip_dist = 3500; rc.zbuffer = (unsigned char*)zbuffer->Buffer(); rc.zpitch = WINDOW_WIDTH*4; rc.texture_dist = 0; rc.alpha_override = alpha_override; // render scene _list->DrawContext(rc); } // unlock the back buffer graphics.UnlockBackSurface(); sprintf(work_string,"Lighting [%s]: Ambient=%d, Infinite=%d, Point=%d, Spot=%d | Zsort [%s], BckFceRM [%s]", (lighting_mode ? "ON" : "OFF"), lights[AMBIENT_LIGHT_INDEX].state, lights[INFINITE_LIGHT_INDEX].state, lights[POINT_LIGHT_INDEX].state, lights[SPOT_LIGHT2_INDEX].state, (zsort_mode ? "ON" : "OFF"), (backface_mode ? "ON" : "OFF"), (z_buffer_mode ? "ON" : "OFF")); graphics.DrawTextGDI(work_string, 0, WINDOW_HEIGHT-34, RGB(0,255,0), graphics.GetBackSurface()); // draw instructions graphics.DrawTextGDI("Press ESC to exit. Press <H> for Help.", 0, 0, RGB(0,255,0), graphics.GetBackSurface()); // should we display help int text_y = 16; if (help_mode) { // draw help menu graphics.DrawTextGDI("<A>..............Toggle ambient light source.", 0, text_y+=12, RGB(255,255,255), graphics.GetBackSurface()); graphics.DrawTextGDI("<I>..............Toggle infinite light source.", 0, text_y+=12, RGB(255,255,255), graphics.GetBackSurface()); graphics.DrawTextGDI("<P>..............Toggle point light source.", 0, text_y+=12, RGB(255,255,255), graphics.GetBackSurface()); graphics.DrawTextGDI("<S>..............Toggle spot light source.", 0, text_y+=12, RGB(255,255,255), graphics.GetBackSurface()); graphics.DrawTextGDI("<N>..............Next object.", 0, text_y+=12, RGB(255,255,255), graphics.GetBackSurface()); graphics.DrawTextGDI("<W>..............Toggle wire frame/solid mode.", 0, text_y+=12, RGB(255,255,255), graphics.GetBackSurface()); graphics.DrawTextGDI("<B>..............Toggle backface removal.", 0, text_y+=12, RGB(255,255,255), graphics.GetBackSurface()); graphics.DrawTextGDI("<S>..............Toggle Z sorting.", 0, text_y+=12, RGB(255,255,255), graphics.GetBackSurface()); graphics.DrawTextGDI("<Z>..............Toggle Z buffering.", 0, text_y+=12, RGB(255,255,255), graphics.GetBackSurface()); graphics.DrawTextGDI("<D>..............Toggle Normal 3D display / Z buffer visualization mode.", 0, text_y+=12, RGB(255,255,255), graphics.GetBackSurface()); graphics.DrawTextGDI("<H>..............Toggle Help.", 0, text_y+=12, RGB(255,255,255), graphics.GetBackSurface()); graphics.DrawTextGDI("<ESC>............Exit demo.", 0, text_y+=12, RGB(255,255,255), graphics.GetBackSurface()); } // end help sprintf(work_string,"Polys Rendered: %d, Polys lit: %d", debug_polys_rendered_per_frame, debug_polys_lit_per_frame); graphics.DrawTextGDI(work_string, 0, WINDOW_HEIGHT-34-16-16, RGB(0,255,0), graphics.GetBackSurface()); sprintf(work_string,"CAM [%5.2f, %5.2f, %5.2f]", _cam->Pos().x, _cam->Pos().y, _cam->Pos().z); graphics.DrawTextGDI(work_string, 0, WINDOW_HEIGHT-34-16-16-16, RGB(0,255,0), graphics.GetBackSurface()); sprintf(work_string,"FPS: %d", Modules::GetTimer().FPS()); graphics.DrawTextGDI(work_string, 0, WINDOW_HEIGHT-34-16-16-16-16, RGB(0,255,0), graphics.GetBackSurface()); // flip the surfaces graphics.Flip(main_window_handle); // sync to 30ish fps Modules::GetTimer().Wait_Clock(30); // check of user is trying to exit if (KEY_DOWN(VK_ESCAPE) || Modules::GetInput().KeyboardState()[DIK_ESCAPE]) { PostMessage(main_window_handle, WM_DESTROY,0,0); } // end if }
void cheat_handle_debug ( HWND wnd ) { static const int data_size[4] = { 1, 2, 4, 4 }; struct debug_info *debug = &cheat_state->debug; int move = 0, hist_chng = 0; if ( !cheat_state->debug_enabled ) return; /* go to pointer */ if ( KEY_PRESSED(VK_NUMPAD1) ) { setDebugPointer( *(void **)debug->cursor_data ); hist_chng = 1; } /* go back */ if ( KEY_PRESSED(VK_NUMPAD7) ) { if ( debug->hist_pos > 0 ) { debug->hist_pos--; hist_chng = 1; } else if ( debug->hist_pos == 0 ) setDebugPointer( (void *)NULL ); } /* change data type */ if ( KEY_PRESSED(VK_DIVIDE) ) debug->data_type = ( debug->data_type + 1 ) % 4; /* inc/dec value */ if ( KEY_DOWN(VK_ADD) || KEY_DOWN(VK_SUBTRACT) ) { const int value = KEY_DOWN( VK_ADD ) ? 1 : -1; uint8_t data[4] = { 0, 0, 0, 0 }; if ( memcpy_safe(data, debug->ptr[debug->hist_pos] + debug->offset[debug->hist_pos], data_size[debug->data_type]) ) { switch ( debug->data_type ) { #pragma warning( disable : 4244 ) case 0: ( *(uint8_t *)data ) += ( uint8_t ) value; break; case 1: ( *(uint16_t *)data ) += ( uint16_t ) value; break; case 2: ( *(uint32_t *)data ) += ( uint32_t ) value; break; case 3: ( *(float *)data ) += (float)value / 10.0f; break; } memcpy_safe( debug->ptr[debug->hist_pos] + debug->offset[debug->hist_pos], data, data_size[debug->data_type] ); } } /* copy info to clipboard */ if ( KEY_PRESSED(VK_MULTIPLY) ) { if ( OpenClipboard(wnd) ) { HGLOBAL mem = GlobalAlloc( GMEM_MOVEABLE, sizeof(debug->ptr_hist_str) ); if ( mem != NULL ) { char *str = (char *)GlobalLock( mem ); strlcpy( str, debug->ptr_hist_str, sizeof(debug->ptr_hist_str) ); Log( "%s", str ); GlobalUnlock( str ); EmptyClipboard(); if ( !SetClipboardData(CF_TEXT, mem) ) Log( "SetClipboardData() %d", GetLastError() ); /*SetClipboardData(CF_TEXT, mem);*/ } CloseClipboard(); } else { Log( "OpenClipboard() %d", GetLastError() ); } } if ( KEY_PRESSED(VK_NUMPAD4) ) move -= data_size[debug->data_type]; if ( KEY_PRESSED(VK_NUMPAD6) ) move += data_size[debug->data_type]; if ( KEY_PRESSED(VK_NUMPAD8) ) move += -16; if ( KEY_PRESSED(VK_NUMPAD2) ) move += 16; if ( KEY_PRESSED(VK_NUMPAD9) ) move += -160; if ( KEY_PRESSED(VK_NUMPAD3) ) move += 160; debug->offset[debug->hist_pos] += move; if ( move != 0 || hist_chng ) { memset( debug->modify_time, 0, DEBUG_DATA_SIZE * sizeof(uint32_t) ); debug->data_prev_clear = 1; } for ( int i = 0; i < 9; i++ ) KEY_CONSUME( VK_NUMPAD1 + i ); KEY_CONSUME( VK_MULTIPLY ); KEY_CONSUME( VK_DIVIDE ); KEY_CONSUME( VK_ADD ); KEY_CONSUME( VK_SUBTRACT ); }
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 static float alpha_override = 0, alpha_inc = .25; // 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 z_buffer_mode = 1; static int display_mode = 1; static float turning = 0; static int pass_mode = 2; 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(0,0,0), lpddsback); lpddsback->Blt(NULL, background.images[0], NULL, DDBLT_WAIT, NULL); // draw the ground //Draw_Rectangle(0,WINDOW_HEIGHT*.5, WINDOW_WIDTH, WINDOW_HEIGHT, RGB16Bit(190,190,230), lpddsback); // read keyboard and other devices here DInput_Read_Keyboard(); // game logic here... // 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 // reflection pass mode if (keyboard_state[DIK_N]) { // toggle help menu if (++pass_mode > 2) pass_mode = 0; Wait_Clock(100); // wait, so keyboard doesn't bounce } // end if // z-sorting if (keyboard_state[DIK_S]) { // toggle z sorting zsort_mode = -zsort_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 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 // 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; // move camera cam.pos.x += cam_speed*Fast_Sin(cam.dir.y); cam.pos.y = 200; cam.pos.z += cam_speed*Fast_Cos(cam.dir.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; // 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; // generate camera matrix Build_CAM4DV1_Matrix_Euler(&cam, CAM_ROT_SEQ_ZYX); // lock the back buffer DDraw_Lock_Back_Surface(); // render the terrain first ///////////////////////////////// if (pass_mode >= 0) { // reset the render list Reset_RENDERLIST4DV2(&rend_list); // rotate the local coords of the object MAT_IDENTITY_4X4(&mrot); 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); // 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); // // get an identity matrix // MAT_IDENTITY_4X4(&mrot); // mrot.M11 = -1; // transform the rendering list by x-z plane reflection matrix Transform_RENDERLIST4DV2(&rend_list, &mrot, TRANSFORM_TRANS_ONLY); // apply camera to perspective transformation Camera_To_Perspective_RENDERLIST4DV2(&rend_list, &cam); // apply screen transform Perspective_To_Screen_RENDERLIST4DV2(&rend_list, &cam); // reset number of polys rendered debug_polys_rendered_per_frame = 0; // render the renderinglist if (wireframe_mode == 0) Draw_RENDERLIST4DV2_Wire16(&rend_list, back_buffer, back_lpitch); else if (wireframe_mode == 1) { // initialize zbuffer to 16000 fixed point Clear_Zbuffer(&zbuffer, (16000 << FIXP16_SHIFT)); // set up rendering context rc.attr = RENDER_ATTR_ZBUFFER | RENDER_ATTR_ALPHA //| RENDER_ATTR_MIPMAP //| RENDER_ATTR_BILERP | RENDER_ATTR_TEXTURE_PERSPECTIVE_AFFINE; rc.video_buffer = back_buffer; rc.lpitch = back_lpitch; rc.mip_dist = 3500; 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 } // end if ////////////////////////////////////////////////////////// if (pass_mode >= 1) { // render the reflection of the objects // reset the render list Reset_RENDERLIST4DV2(&rend_list); // insert the scenery into universe for (index = 0; index < NUM_SCENE_OBJECTS; index++) { // select proper object first obj_work = &obj_array[(int)scene_objects[index].w]; // reset the object (this only matters for backface and object removal) Reset_OBJECT4DV2(obj_work); // set position of tower obj_work->world_pos.x = scene_objects[index].x; obj_work->world_pos.y = scene_objects[index].y; obj_work->world_pos.z = scene_objects[index].z; // move objects scene_objects[index].x+=scene_objects_vel[index].x; scene_objects[index].y+=scene_objects_vel[index].y; scene_objects[index].z+=scene_objects_vel[index].z; // test for out of bounds if (scene_objects[index].x >= UNIVERSE_RADIUS || scene_objects[index].x <= -UNIVERSE_RADIUS) { scene_objects_vel[index].x=-scene_objects_vel[index].x; scene_objects[index].x+=scene_objects_vel[index].x; } // end if if (scene_objects[index].y >= (UNIVERSE_RADIUS/2) || scene_objects[index].y <= -(UNIVERSE_RADIUS/2)) { scene_objects_vel[index].y=-scene_objects_vel[index].y; scene_objects[index].y+=scene_objects_vel[index].y; } // end if if (scene_objects[index].z >= UNIVERSE_RADIUS || scene_objects[index].z <= -UNIVERSE_RADIUS) { scene_objects_vel[index].z=-scene_objects_vel[index].z; scene_objects[index].z+=scene_objects_vel[index].z; } // end if // attempt to cull object if (!Cull_OBJECT4DV2(obj_work, &cam, CULL_OBJECT_XYZ_PLANES)) { MAT_IDENTITY_4X4(&mrot); // rotate the local coords of the object Transform_OBJECT4DV2(obj_work, &mrot, TRANSFORM_LOCAL_TO_TRANS,1); // perform world transform Model_To_World_OBJECT4DV2(obj_work, TRANSFORM_TRANS_ONLY); // insert the object into render list Insert_OBJECT4DV2_RENDERLIST4DV2(&rend_list, obj_work,0); } // end if } // end for // 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); // get an identity matrix MAT_IDENTITY_4X4(&mrot); mrot.M11 = -1; mrot.M31 = -450; // transform the rendering list by x-z plane reflection matrix Transform_RENDERLIST4DV2(&rend_list, &mrot, TRANSFORM_TRANS_ONLY); // apply camera to perspective transformation Camera_To_Perspective_RENDERLIST4DV2(&rend_list, &cam); // apply screen transform Perspective_To_Screen_RENDERLIST4DV2(&rend_list, &cam); // reset number of polys rendered debug_polys_rendered_per_frame = 0; // render the renderinglist if (wireframe_mode == 0) Draw_RENDERLIST4DV2_Wire16(&rend_list, back_buffer, back_lpitch); else if (wireframe_mode == 1) { // set up rendering context rc.attr = RENDER_ATTR_NOBUFFER | RENDER_ATTR_ALPHA //| RENDER_ATTR_MIPMAP //| RENDER_ATTR_BILERP | RENDER_ATTR_TEXTURE_PERSPECTIVE_AFFINE; rc.video_buffer = back_buffer; rc.lpitch = back_lpitch; rc.mip_dist = 3500; 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 } // end if ////////////////////////////////////////////////////////// if (pass_mode >= 2) { // render the objects now // reset the render list Reset_RENDERLIST4DV2(&rend_list); // insert the scenery into universe for (index = 0; index < NUM_SCENE_OBJECTS; index++) { // select proper object first obj_work = &obj_array[(int)scene_objects[index].w]; // reset the object (this only matters for backface and object removal) Reset_OBJECT4DV2(obj_work); // set position of tower obj_work->world_pos.x = scene_objects[index].x; obj_work->world_pos.y = scene_objects[index].y; obj_work->world_pos.z = scene_objects[index].z; // move objects scene_objects[index].x+=scene_objects_vel[index].x; scene_objects[index].y+=scene_objects_vel[index].y; scene_objects[index].z+=scene_objects_vel[index].z; // test for out of bounds if (scene_objects[index].x >= UNIVERSE_RADIUS || scene_objects[index].x <= -UNIVERSE_RADIUS) { scene_objects_vel[index].x=-scene_objects_vel[index].x; scene_objects[index].x+=scene_objects_vel[index].x; } // end if if (scene_objects[index].y >= (UNIVERSE_RADIUS/2) || scene_objects[index].y <= -(UNIVERSE_RADIUS/2)) { scene_objects_vel[index].y=-scene_objects_vel[index].y; scene_objects[index].y+=scene_objects_vel[index].y; } // end if if (scene_objects[index].z >= UNIVERSE_RADIUS || scene_objects[index].z <= -UNIVERSE_RADIUS) { scene_objects_vel[index].z=-scene_objects_vel[index].z; scene_objects[index].z+=scene_objects_vel[index].z; } // end if // attempt to cull object if (!Cull_OBJECT4DV2(obj_work, &cam, CULL_OBJECT_XYZ_PLANES)) { MAT_IDENTITY_4X4(&mrot); // rotate the local coords of the object Transform_OBJECT4DV2(obj_work, &mrot, TRANSFORM_LOCAL_TO_TRANS,1); // perform world transform Model_To_World_OBJECT4DV2(obj_work, TRANSFORM_TRANS_ONLY); // insert the object into render list Insert_OBJECT4DV2_RENDERLIST4DV2(&rend_list, obj_work,0); } // end if } // end for // 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); // get an identity matrix //MAT_IDENTITY_4X4(&mrot); //mrot.M11 = -1; mrot.M31 = -400; // transform the rendering list by x-z plane reflection matrix Transform_RENDERLIST4DV2(&rend_list, &mrot, TRANSFORM_TRANS_ONLY); // apply camera to perspective transformation Camera_To_Perspective_RENDERLIST4DV2(&rend_list, &cam); // apply screen transform Perspective_To_Screen_RENDERLIST4DV2(&rend_list, &cam); // reset number of polys rendered debug_polys_rendered_per_frame = 0; // render the renderinglist if (wireframe_mode == 0) Draw_RENDERLIST4DV2_Wire16(&rend_list, back_buffer, back_lpitch); else if (wireframe_mode == 1) { // set up rendering context rc.attr = RENDER_ATTR_ZBUFFER | RENDER_ATTR_ALPHA //| RENDER_ATTR_MIPMAP //| RENDER_ATTR_BILERP | RENDER_ATTR_TEXTURE_PERSPECTIVE_AFFINE; rc.video_buffer = back_buffer; rc.lpitch = back_lpitch; rc.mip_dist = 3500; 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 } // end if // unlock the back buffer DDraw_Unlock_Back_Surface(); sprintf(work_string,"Lighting [%s]: Ambient=%d, Infinite=%d, Point=%d, Spot=%d, BckFceRM [%s], Zsort [%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, ((backface_mode == 1) ? "ON" : "OFF"), ((zsort_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("<N>..............Enable next rendering pass.", 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("<S>..............Toggle Z sorting.", 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]", cam.pos.x, cam.pos.y, cam.pos.z); Draw_Text_GDI(work_string, 0, WINDOW_HEIGHT-34-16-16-16, RGB(0,255,0), lpddsback); // flip the surfaces DDraw_Flip2(); // 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 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, RGB16Bit(255,120,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 // move to next object if (keyboard_state[DIK_O]) { VECTOR4D old_pos; old_pos = obj_work->world_pos; if (++curr_object >= NUM_OBJECTS) curr_object = 0; // update pointer obj_work = &obj_array[curr_object]; obj_work->world_pos = old_pos; 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 = 200; 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 = 400; 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); ////////////////////////////////////////////////////////////////////////// // the terrain // 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); ////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////// // render the shaded object that projects the shadow // reset the object (this only matters for backface and object removal) Reset_OBJECT4DV2(obj_work); // update rotation angle of object obj_work->ivar1+=3.0; if (obj_work->ivar1 >= 360) obj_work->ivar1 = 0; // set position of object obj_work->world_pos.x = 200*Fast_Cos(obj_work->ivar1); obj_work->world_pos.y = 200+50*Fast_Sin(3*obj_work->ivar1); obj_work->world_pos.z = 200*Fast_Sin(obj_work->ivar1); // 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_work, &mrot, TRANSFORM_LOCAL_TO_TRANS,1); // perform world transform Model_To_World_OBJECT4DV2(obj_work, TRANSFORM_TRANS_ONLY); // insert the object into render list Insert_OBJECT4DV2_RENDERLIST4DV2(&rend_list, obj_work,0); ////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////// // draw all the light objects to represent the position of light sources // reset the object (this only matters for backface and object removal) Reset_OBJECT4DV2(&obj_light_array[INDEX_GREEN_LIGHT_INDEX]); // set position of object to light obj_light_array[INDEX_GREEN_LIGHT_INDEX].world_pos = lights2[POINT_LIGHT_INDEX].pos; // create identity matrix MAT_IDENTITY_4X4(&mrot); // rotate the local coords of the object Transform_OBJECT4DV2(&obj_light_array[INDEX_GREEN_LIGHT_INDEX], &mrot, TRANSFORM_LOCAL_TO_TRANS,1); // perform world transform Model_To_World_OBJECT4DV2(&obj_light_array[INDEX_GREEN_LIGHT_INDEX], TRANSFORM_TRANS_ONLY); // insert the object into render list Insert_OBJECT4DV2_RENDERLIST4DV2(&rend_list, &obj_light_array[INDEX_GREEN_LIGHT_INDEX],0); // reset the object (this only matters for backface and object removal) Reset_OBJECT4DV2(&obj_light_array[INDEX_WHITE_LIGHT_INDEX]); // set position of object to light obj_light_array[INDEX_WHITE_LIGHT_INDEX].world_pos = lights2[POINT_LIGHT2_INDEX].pos; // create identity matrix MAT_IDENTITY_4X4(&mrot); // rotate the local coords of the object Transform_OBJECT4DV2(&obj_light_array[INDEX_WHITE_LIGHT_INDEX], &mrot, TRANSFORM_LOCAL_TO_TRANS,1); // perform world transform Model_To_World_OBJECT4DV2(&obj_light_array[INDEX_WHITE_LIGHT_INDEX], TRANSFORM_TRANS_ONLY); // insert the object into render list Insert_OBJECT4DV2_RENDERLIST4DV2(&rend_list, &obj_light_array[INDEX_WHITE_LIGHT_INDEX],0); //////////////////////////////////////////////////////////////////////////////////// // reset number of polys rendered debug_polys_rendered_per_frame = 0; debug_polys_lit_per_frame = 0; // prepare to make first pass at rendering target, so we can alpha blend in the shadows // on the next pass // 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, CLIP_POLY_X_PLANE | CLIP_POLY_Y_PLANE | CLIP_POLY_Z_PLANE ); // 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 // set up rendering context rc.attr = RENDER_ATTR_ZBUFFER // | RENDER_ATTR_ALPHA // | RENDER_ATTR_MIPMAP // | RENDER_ATTR_BILERP | RENDER_ATTR_TEXTURE_PERSPECTIVE_AFFINE; // initialize zbuffer to 0 fixed point Clear_Zbuffer(&zbuffer, (16000 << FIXP16_SHIFT)); // set up remainder of rendering context rc.video_buffer = back_buffer; rc.lpitch = back_lpitch; rc.mip_dist = 0; 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_2(&rc); } // end if // now make second rendering pass and draw shadow(s) // reset the render list Reset_RENDERLIST4DV2(&rend_list); ////////////////////////////////////////////////////////////////////////// // shadow object // reset the object (this only matters for backface and object removal) Reset_OBJECT4DV2(&shadow_obj); // compute terrain cell shadow is over cell_x = (obj_work->world_pos.x + TERRAIN_WIDTH/2) / obj_terrain.fvar1; cell_y = (obj_work->world_pos.z + TERRAIN_HEIGHT/2) / obj_terrain.fvar1; // 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 = MAX( MAX(obj_terrain.vlist_trans[v0].y, obj_terrain.vlist_trans[v1].y), MAX(obj_terrain.vlist_trans[v2].y, obj_terrain.vlist_trans[v3].y) ); // update position shadow_obj.world_pos = obj_work->world_pos; shadow_obj.world_pos.y = terrain_height+10; // create identity matrix MAT_IDENTITY_4X4(&mrot); // transform the local coords of the object Transform_OBJECT4DV2(&shadow_obj, &mrot, TRANSFORM_LOCAL_TO_TRANS,1); // perform world transform Model_To_World_OBJECT4DV2(&shadow_obj, TRANSFORM_TRANS_ONLY); // insert the object into render list Insert_OBJECT4DV2_RENDERLIST4DV2(&rend_list, &shadow_obj,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, CLIP_POLY_X_PLANE | CLIP_POLY_Y_PLANE | CLIP_POLY_Z_PLANE ); // 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); // 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 // set up rendering context rc.attr = RENDER_ATTR_ZBUFFER | RENDER_ATTR_ALPHA // | RENDER_ATTR_MIPMAP // | RENDER_ATTR_BILERP | RENDER_ATTR_TEXTURE_PERSPECTIVE_AFFINE; // initialize zbuffer to 0 fixed point //Clear_Zbuffer(&zbuffer, (16000 << FIXP16_SHIFT)); // set up remainder of rendering context rc.video_buffer = back_buffer; rc.lpitch = back_lpitch; rc.mip_dist = 0; 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_3(&rc); } // end if // unlock the back buffer DDraw_Unlock_Back_Surface(); // draw cockpit //Draw_BOB16(&cockpit, lpddsback); #if 1 sprintf(work_string,"Lighting [%s]: Ambient=%d, Infinite=%d, Point=%d, BckFceRM [%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")); 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("<O>..............Select different objects.", 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); #endif // flip the surfaces DDraw_Flip2(); // 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
void GameController::Run() { Player* me = new Player(0,0,1); sObjMgr->CreateWorld(); sObjMgr->Update(); DWORD realCurrTime = 0; DWORD realPrevTime = GetMSTime(); DWORD diff; /* Example for using the sScreenLog class */ sScreenLog->AddTrack(&diff,ScreenLog::Track::UINT,20,30,0xFFFF0000); // sScreenLog->AddTrack(&me->X,ScreenLog::Track::INT,20,50,0xFFFF0000); // sScreenLog->AddTrack(&me->Y,ScreenLog::Track::INT,20,70,0xFFFF0000); while(true) { realCurrTime = GetMSTime(); diff = GetMSTimeDiff(realPrevTime,realCurrTime); Player* me = sObjMgr->Me(); ReadKeyboard(); if(KEY_PRESSED(DIK_F)) me->Fire(); if(KEY_DOWN(DIK_ESCAPE)) break; if(KEY_DOWN(DIK_W)) me->SetYVelocity(-3); if(KEY_DOWN(DIK_S)) me->SetYVelocity(3); if(KEY_DOWN(DIK_A)) { me->SetXVelocity(-3); if(KEY_DOWN(DIK_D)) { new Explosion(me,me->GetX()+4,me->GetY()+(me->GetHeight()/2),19,0,false); } } if(KEY_DOWN(DIK_D)) { me->SetXVelocity(3); if(KEY_DOWN(DIK_A)) { new Explosion(me,me->GetX()+me->GetWidth()-4,me->GetY()+(me->GetHeight()/2),19,0,false); } } /* Oops :< */ //if(KEY_UP(DIK_W) && KEY_UP(DIK_A) && KEY_UP(DIK_S) && KEY_UP(DIK_D)) // { // me->SetXVelocity(0); // me->SetYVelocity(0); // } if(KEY_DOWN(DIK_R)) me->SetPos(30,70); if(KEY_DOWN(DIK_Q)) me->SetAngle(me->GetAngle()+0.1f); if(KEY_DOWN(DIK_E)) me->SetAngle(me->GetAngle()-0.1f); if(KEY_DOWN(DIK_M)) sWorld->PrintMap(); if(KEY_DOWN(DIK_SPACE)) { me->SetXVelocity(0); me->SetYVelocity(0); } sObjMgr->Update(/* diff */); FollowUnit(me); Render(); realPrevTime = realCurrTime; } }
// point must be in logical void CDrawObject::MoveHandleTo(int nHandle, CPoint point) { FTLASSERT(this); if(KEY_DOWN(VK_SHIFT)) { if(dotLine == m_objType || dotLineArrow == m_objType) { return MoveLineHandleToWithShift(nHandle, point); } else { return MoveHandleToWithShift(nHandle, point); } } CRect position = m_position; switch (nHandle) { case 1: { position.left = point.x; position.top = point.y; } break; case 2: position.top = point.y; break; case 3: position.right = point.x; position.top = point.y; break; case 4: position.right = point.x; break; case 5: { position.right = point.x; position.bottom = point.y; } break; case 6: position.bottom = point.y; break; case 7: position.left = point.x; position.bottom = point.y; break; case 8: position.left = point.x; break; default: FTLASSERT(FALSE); break; } MoveTo(position); }
bool CKeyDown::Left() { return KEY_DOWN(VK_LEFT); }
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 bilinear_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, RGB16Bit(250,190,80), lpddsback); lpddsback->Blt(NULL, background.images[0], NULL, DDBLT_WAIT, NULL); // draw the ground //Draw_Rectangle(0,WINDOW_HEIGHT*.5, WINDOW_WIDTH, WINDOW_HEIGHT, RGB16Bit(190,190,230), 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 // 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_S]) { // toggle z sorting zsort_mode = -zsort_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 // move to next object if (keyboard_state[DIK_N]) { if (++curr_object >= NUM_OBJECTS) curr_object = 0; // update pointer obj_work = &obj_array[curr_object]; Wait_Clock(100); // wait, so keyboard doesn't bounce } // end if // toggle bilinear mode if (keyboard_state[DIK_B]) { bilinear_mode = -bilinear_mode; Wait_Clock(100); // wait, so keyboard doesn't bounce } // 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; // move camera cam.pos.x += cam_speed*Fast_Sin(cam.dir.y); cam.pos.z += cam_speed*Fast_Cos(cam.dir.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); // reset BHV for culling BHV_Reset_Tree(&bhv_tree); // now cull the BHV ... die polygons die! bhv_nodes_visited = 0; BHV_FrustrumCull(&bhv_tree, // the root of the BHV &cam, // camera to cull relative to CULL_OBJECT_XYZ_PLANES); // clipping planes to consider // statistic tracking int objects_processed = 0; //////////////////////////////////////////////////////// // insert the scenery into universe for (index = 0; index < NUM_SCENE_OBJECTS; index++) { // test if container has been culled already by BHV if (scene_objects[index].state & OBJECT4DV2_STATE_CULLED) continue; // reset the object (this only matters for backface and object removal) Reset_OBJECT4DV2(obj_work); objects_processed++; // set position of object obj_work->world_pos.x = scene_objects[index].pos.x; obj_work->world_pos.y = scene_objects[index].pos.y; obj_work->world_pos.z = scene_objects[index].pos.z; // rotate object if ((scene_objects[index].rot.y+=scene_objects[index].auxi[0]) >= 360) scene_objects[index].rot.y = 0; // attempt to cull object if (!Cull_OBJECT4DV2(obj_work, &cam, CULL_OBJECT_XYZ_PLANES)) { MAT_IDENTITY_4X4(&mrot); // generate rotation matrix around y axis Build_XYZ_Rotation_MATRIX4X4(0, scene_objects[index].rot.y, 0, &mrot); // rotate the local coords of the object Transform_OBJECT4DV2(obj_work, &mrot, TRANSFORM_LOCAL_TO_TRANS,1); // perform world transform Model_To_World_OBJECT4DV2(obj_work, TRANSFORM_TRANS_ONLY); // insert the object into render list Insert_OBJECT4DV2_RENDERLIST4DV2(&rend_list,obj_work,0); } // end if } // end for // reset number of polys rendered debug_polys_rendered_per_frame = 0; debug_polys_lit_per_frame = 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 renderinglist if (wireframe_mode == 0) Draw_RENDERLIST4DV2_Wire16(&rend_list, back_buffer, back_lpitch); else if (wireframe_mode == 1) { // initialize zbuffer to 16000 fixed point Clear_Zbuffer(&zbuffer, (000 << FIXP16_SHIFT)); // set up rendering context rc.attr = RENDER_ATTR_INVZBUFFER // | RENDER_ATTR_ALPHA // | RENDER_ATTR_MIPMAP | (bilinear_mode==1 ? RENDER_ATTR_BILERP : 0) | RENDER_ATTR_TEXTURE_PERSPECTIVE_AFFINE; rc.video_buffer = back_buffer; rc.lpitch = back_lpitch; rc.mip_dist = 3500; rc.zbuffer = (UCHAR *)zbuffer.zbuffer; rc.zpitch = WINDOW_WIDTH*4; rc.rend_list = &rend_list; rc.texture_dist = 0; rc.alpha_override = 5; // render scene Draw_RENDERLIST4DV2_RENDERCONTEXTV1_16(&rc); } // end if // unlock the back buffer DDraw_Unlock_Back_Surface(); sprintf(work_string,"Lighting [%s]: Ambient=%d, Infinite=%d, Point=%d, Spot=%d, Zsort [%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")); 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("<N>..............Next object.", 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("<S>..............Toggle Z sorting.", 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, Object Pre-Culled by BHV: %d, Nodes visited in BHV Tree: %d", debug_polys_rendered_per_frame, debug_polys_lit_per_frame, NUM_SCENE_OBJECTS - objects_processed, bhv_nodes_visited); 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]", cam.pos.x, cam.pos.y, cam.pos.z); Draw_Text_GDI(work_string, 0, WINDOW_HEIGHT-34-16-16-16, RGB(0,255,0), lpddsback); // flip the surfaces DDraw_Flip2(); // 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
bool CKeyDown::X() { return KEY_DOWN(0x58); }
// an Update() helper that handles the input void GameWindow::HandleInput(){ //check for escape key (to exit program) if (KEY_DOWN(VK_ESCAPE)) PostMessage(m_Window, WM_DESTROY, 0, 0); //start game if(!m_bInGame){ if(KEY_DOWN(VK_SPACE) || KEY_DOWN(VK_RETURN)){ m_bInGame = true; m_pSelect->Play(); } } else{ //A or LeftArrow move left if (KEY_DOWN(VK_LEFT) || KEY_DOWN(0x41)){ m_wPlayer.m_xVelocity = -6; } //D or RightArrow move right if (KEY_DOWN(VK_RIGHT) || KEY_DOWN(0x44)){ m_wPlayer.m_xVelocity = 6; } //W or UpArrow to jump if(KEY_DOWN(VK_UP) || KEY_DOWN(0x57)){ if(m_wPlayer.m_bGrounded){ m_wPlayer.m_bGrounded = false; m_wPlayer.m_yVelocity = -18; //play sound m_pJump->Play(); } } //space to cast spell if(KEY_DOWN(VK_SPACE)){ //for making sure fire spell shoots in correct directions int vel = 1; //cast fire if(m_wPlayer.m_Spell == "Fire"){ //(for making sure fire spell goes in correct direction if(m_wPlayer.m_Image == L"images\\wiz.l.png"){ vel = -1; } //make a new projectile and shoot it Projectile newProj = m_wPlayer.Shoot(vel); if(newProj.m_bOnScreen){ for(int i = 0; i < 10; i++){ if(m_pProjectileList[i].m_bOnScreen == false){ m_pProjectileList[i] = newProj; m_pProjectileList[i].m_bOnScreen = true; //play sound m_pShoot->Play(); break; } } } } //cast dark or lightning else if(m_wPlayer.m_Spell == "Lightning" || (m_wPlayer.m_Spell == "Dark" && m_wPlayer.m_bGrounded)){ Projectile newProj = m_wPlayer.Shoot(vel); if(newProj.m_bOnScreen){ for(int i = 0; i < 10; i++){ if(m_pProjectileList[i].m_bOnScreen == false){ m_pProjectileList[i] = newProj; m_pProjectileList[i].m_bOnScreen = true; if(m_wPlayer.m_Spell == "Dark"){ //play sound m_pShoot->Play(); } else{ m_pKill->Play(); } break; } } } } } } }
bool CKeyDown::Z() { return KEY_DOWN(0x5A); }
void S9xProcessEvents (bool8 block) { static char prev_keystate[128]; extern volatile char key[128]; #ifdef GRIP_SUPPORT ReadGrip (); #endif #ifdef SIDEWINDER_SUPPORT if (num_sidewinders) ReadSidewinders (); #endif char key1[128]; char *keystate = (char *) key1; int fn = 0; memcpy (key1, (char *) key, sizeof (key1)); #undef KEY_DOWN #define KEY_DOWN(a) (keystate[a]) #undef KEY_PRESS #define KEY_PRESS(a) (keystate[a] && !prev_keystate[a]) #undef KEY_WASPRESSED #define KEY_WASPRESSED(a) (prev_keystate[a] && !keystate[a]) #undef PROCESS_KEY #define PROCESS_KEY(k, b, v)\ if (KEY_PRESS(k)) b |= v;\ if (KEY_WASPRESSED(k)) b &= ~v; if (KEY_PRESS (SCANCODE_ESCAPE)) S9xExit (); // Joypad 1: PROCESS_KEY(SCANCODE_K, joypads [0], SNES_RIGHT_MASK) PROCESS_KEY(SCANCODE_CURSORRIGHT, joypads [0], SNES_RIGHT_MASK) PROCESS_KEY(SCANCODE_H, joypads [0], SNES_LEFT_MASK) PROCESS_KEY(SCANCODE_CURSORLEFT, joypads [0], SNES_LEFT_MASK) PROCESS_KEY(SCANCODE_N, joypads [0], SNES_DOWN_MASK) PROCESS_KEY(SCANCODE_J, joypads [0], SNES_DOWN_MASK) PROCESS_KEY(SCANCODE_CURSORDOWN, joypads [0], SNES_DOWN_MASK) PROCESS_KEY(SCANCODE_U, joypads [0], SNES_UP_MASK) PROCESS_KEY(SCANCODE_CURSORUP, joypads [0], SNES_UP_MASK) PROCESS_KEY(SCANCODE_ENTER, joypads [0], SNES_START_MASK) PROCESS_KEY(SCANCODE_SPACE, joypads [0], SNES_SELECT_MASK) PROCESS_KEY(SCANCODE_A, joypads [0], SNES_TL_MASK) PROCESS_KEY(SCANCODE_V, joypads [0], SNES_TL_MASK) PROCESS_KEY(SCANCODE_Q, joypads [0], SNES_TL_MASK) PROCESS_KEY(SCANCODE_Z, joypads [0], SNES_TR_MASK) PROCESS_KEY(SCANCODE_B, joypads [0], SNES_TR_MASK) PROCESS_KEY(SCANCODE_W, joypads [0], SNES_TR_MASK) PROCESS_KEY(SCANCODE_S, joypads [0], SNES_X_MASK) PROCESS_KEY(SCANCODE_M, joypads [0], SNES_X_MASK) PROCESS_KEY(SCANCODE_E, joypads [0], SNES_X_MASK) PROCESS_KEY(SCANCODE_X, joypads [0], SNES_Y_MASK) PROCESS_KEY(SCANCODE_COMMA, joypads [0], SNES_Y_MASK) PROCESS_KEY(SCANCODE_R, joypads [0], SNES_Y_MASK) PROCESS_KEY(SCANCODE_D, joypads [0], SNES_A_MASK) PROCESS_KEY(SCANCODE_PERIOD, joypads [0], SNES_A_MASK) PROCESS_KEY(SCANCODE_T, joypads [0], SNES_A_MASK) PROCESS_KEY(SCANCODE_C, joypads [0], SNES_B_MASK) PROCESS_KEY(SCANCODE_SLASH, joypads [0], SNES_B_MASK) PROCESS_KEY(SCANCODE_Y, joypads [0], SNES_B_MASK) // Joypad 2: // PROCESS_KEY(SCANCODE_CURSORRIGHT, joypads [1], SNES_RIGHT_MASK) // PROCESS_KEY(SCANCODE_CURSORLEFT, joypads [1], SNES_LEFT_MASK) // PROCESS_KEY(SCANCODE_CURSORDOWN, joypads [1], SNES_DOWN_MASK) // PROCESS_KEY(SCANCODE_CURSORUP, joypads [1], SNES_UP_MASK) PROCESS_KEY(SCANCODE_KEYPADENTER, joypads [0], SNES_START_MASK) PROCESS_KEY(SCANCODE_KEYPADPLUS, joypads [0], SNES_SELECT_MASK) PROCESS_KEY(SCANCODE_INSERT, joypads [0], SNES_X_MASK) PROCESS_KEY(SCANCODE_REMOVE, joypads [0], SNES_Y_MASK) PROCESS_KEY(SCANCODE_HOME, joypads [0], SNES_A_MASK) PROCESS_KEY(SCANCODE_END, joypads [0], SNES_B_MASK) PROCESS_KEY(SCANCODE_PAGEUP, joypads [0], SNES_TL_MASK) PROCESS_KEY(SCANCODE_PAGEDOWN, joypads [0], SNES_TR_MASK) if (KEY_PRESS (SCANCODE_0)) Settings.DisableHDMA = !Settings.DisableHDMA; if (KEY_PRESS (SCANCODE_1)) PPU.BG_Forced ^= 1; if (KEY_PRESS (SCANCODE_2)) PPU.BG_Forced ^= 2; if (KEY_PRESS (SCANCODE_3)) PPU.BG_Forced ^= 4; if (KEY_PRESS (SCANCODE_4)) PPU.BG_Forced ^= 8; if (KEY_PRESS (SCANCODE_5)) PPU.BG_Forced ^= 16; if (KEY_PRESS (SCANCODE_6)) Settings.SwapJoypads = !Settings.SwapJoypads; if (KEY_PRESS (SCANCODE_7)) { if (IPPU.Controller == SNES_SUPERSCOPE) show_mouse (NULL); S9xNextController (); if (IPPU.Controller == SNES_SUPERSCOPE) show_mouse (screen); } if (KEY_PRESS (SCANCODE_8)) Settings.BGLayering = !Settings.BGLayering; if (KEY_PRESS (SCANCODE_9)) if (Settings.SixteenBit) Settings.Transparency = !Settings.Transparency; if (KEY_PRESS(SCANCODE_TAB)) superscope_turbo = !superscope_turbo; PROCESS_KEY(SCANCODE_GRAVE, superscope_pause, 1); if (KEY_PRESS(SCANCODE_F1)) fn = 1; if (KEY_PRESS(SCANCODE_F2)) fn = 2; if (KEY_PRESS(SCANCODE_F3)) fn = 3; if (KEY_PRESS(SCANCODE_F4)) fn = 4; if (KEY_PRESS(SCANCODE_F5)) fn = 5; if (KEY_PRESS(SCANCODE_F6)) fn = 6; if (KEY_PRESS(SCANCODE_F7)) fn = 7; if (KEY_PRESS(SCANCODE_F8)) fn = 8; if (KEY_PRESS(SCANCODE_F9)) fn = 9; if (KEY_PRESS(SCANCODE_F10)) fn = 10; if (KEY_PRESS(SCANCODE_F11)) fn = 11; if (KEY_PRESS(SCANCODE_F12)) fn = 12; if (fn > 0) { if (!KEY_DOWN(SCANCODE_LEFTALT) && !KEY_DOWN(SCANCODE_LEFTSHIFT)) { if (fn == 11) { S9xLoadSnapshot (S9xChooseFilename (TRUE)); } else if (fn == 12) { Snapshot (S9xChooseFilename (FALSE)); } else { char def [PATH_MAX]; char filename [PATH_MAX]; char drive [_MAX_DRIVE]; char dir [_MAX_DIR]; char ext [_MAX_EXT]; _splitpath (Memory.ROMFilename, drive, dir, def, ext); sprintf (filename, "%s%s%s.%03d", S9xGetSnapshotDirectory (), SLASH_STR, def, fn - 1); S9xLoadSnapshot (filename); } } else if (KEY_DOWN(SCANCODE_LEFTALT)) { if (fn >= 4) S9xToggleSoundChannel (fn - 4); #ifdef DEBUGGER else if (fn == 1) CPU.Flags |= DEBUG_MODE_FLAG; #endif else if (fn == 2) S9xLoadSnapshot (S9xChooseFilename (TRUE)); else if (fn == 3) Snapshot (S9xChooseFilename (FALSE)); } else { char def [PATH_MAX]; char filename [PATH_MAX]; char drive [_MAX_DRIVE]; char dir [_MAX_DIR]; char ext [_MAX_EXT]; _splitpath (Memory.ROMFilename, drive, dir, def, ext); sprintf (filename, "%s%s%s.%03d", S9xGetSnapshotDirectory (), SLASH_STR, def, fn - 1); Snapshot (filename); } } if (KEY_PRESS (SCANCODE_BREAK) || KEY_PRESS (SCANCODE_BREAK_ALTERNATIVE) || KEY_PRESS (SCANCODE_SCROLLLOCK)) Settings.Paused ^= 1; if (KEY_PRESS (SCANCODE_PRINTSCREEN)) SaveScreenshot (); if (KEY_PRESS (SCANCODE_MINUS)) { if (Settings.SkipFrames <= 1) Settings.SkipFrames = AUTO_FRAMERATE; else if (Settings.SkipFrames != AUTO_FRAMERATE) Settings.SkipFrames--; } if (KEY_PRESS (SCANCODE_EQUAL)) { if (Settings.SkipFrames == AUTO_FRAMERATE) Settings.SkipFrames = 1; else if (Settings.SkipFrames < 10) Settings.SkipFrames++; } memcpy (prev_keystate, keystate, sizeof (prev_keystate)); if (block) __dpmi_yield (); }
bool CKeyDown::Space() { return KEY_DOWN(VK_SPACE); }
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
bool CKeyDown::Esc() { return KEY_DOWN(VK_ESCAPE); }
//28. // the entry point for any Windows program //29. int WINAPI WinMain(HINSTANCE hInstance, //30. HINSTANCE hPrevInstance, //31. LPSTR lpCmdLine, //32. int nCmdShow) //33. { //34. HWND hWnd; //35. WNDCLASSEX wc; //36. //37. ZeroMemory(&wc, sizeof(WNDCLASSEX)); //38. //39. wc.cbSize = sizeof(WNDCLASSEX); //40. wc.style = CS_HREDRAW | CS_VREDRAW; //41. wc.lpfnWndProc = WindowProc; //42. wc.hInstance = hInstance; //43. wc.hCursor = LoadCursor(NULL, IDC_ARROW); //44. // wc.hbrBackground = (HBRUSH)COLOR_WINDOW; // not needed any more //45. wc.lpszClassName = "WindowClass"; //46. //47. RegisterClassEx(&wc); //48. //49. hWnd = CreateWindowEx(NULL, //50. "WindowClass", //51. "Our Direct3D Program", //52. WS_EX_TOPMOST | WS_POPUP, // fullscreen values //53. 0, 0, // the starting x and y positions should be 0 //54. SCREEN_WIDTH, SCREEN_HEIGHT, // set the window to 640 x 480 //55. NULL, //56. NULL, //57. hInstance, //58. NULL); //59. //60. ShowWindow(hWnd, nCmdShow); //61. //62. // set up and initialize Direct3D //63. initD3D(hWnd); //64. //65. // enter the main loop: //66. //67. MSG msg; //68. //69. while(TRUE) //70. { //71. while(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) //72. { //73. TranslateMessage(&msg); //74. DispatchMessage(&msg); //75. } //76. //77. if(msg.message == WM_QUIT) //78. break; //79. //80. render_frame(); //81. //82. // check the 'escape' key //83. if(KEY_DOWN(VK_ESCAPE)) //84. PostMessage(hWnd, WM_DESTROY, 0, 0); //85. } //86. //87. // clean up DirectX and COM //88. cleanD3D(); //89. //90. return msg.wParam; //91. }
bool CKeyDown::Up() { return KEY_DOWN(VK_UP); }
// -------------------------------------------------------------------------- // main(Number of arguments, Value of arguments) // This is the main function. // Return value Success:0 Error:-1 // -------------------------------------------------------------------------- int main(int argc, char **argv) { // AR.Drone class ARDrone ardrone; // Initialize if (!ardrone.open()) { printf("Failed to initialize.\n"); return -1; } // Main loop while (!GetAsyncKeyState(VK_ESCAPE)) { // Update your AR.Drone if (!ardrone.update()) break; // Get an image IplImage *image = ardrone.getImage(); // Battery printf("ardrone.battery = %d [��] (�c���%d��)\n", battery, 12*battery/100); // Take off / Landing if (KEY_PUSH(VK_SPACE)) { if (ardrone.onGround()) ardrone.takeoff(); else ardrone.landing(); } // Emergency stop if (KEY_PUSH(VK_RETURN)) ardrone.emergency(); // AR.Drone is flying if (!ardrone.onGround()) { double x = 0.0, y = 0.0, z = 0.0, r = 0.0; // Keyboard if (KEY_DOWN(VK_UP)) x = 0.5; if (KEY_DOWN(VK_DOWN)) x = -0.5; if (KEY_DOWN(VK_LEFT)) r = 0.5; if (KEY_DOWN(VK_RIGHT)) r = -0.5; if (KEY_DOWN('Q')) z = 0.5; if (KEY_DOWN('A')) z = -0.5; // Joypad JOYINFOEX JoyInfoEx; JoyInfoEx.dwSize = sizeof(JOYINFOEX); JoyInfoEx.dwFlags = JOY_RETURNALL; // Get joypad infomations if (joyGetPosEx(0, &JoyInfoEx) == JOYERR_NOERROR) { int y_pad = -((int)JoyInfoEx.dwXpos - 0x7FFF) / 32512.0*100.0; int x_pad = -((int)JoyInfoEx.dwYpos - 0x7FFF) / 32512.0*100.0; int r_pad = -((int)JoyInfoEx.dwZpos - 0x7FFF) / 32512.0*100.0; int z_pad = ((int)JoyInfoEx.dwRpos - 0x7FFF) / 32512.0*100.0; printf("X = %d ", x_pad); printf("Y = %d ", y_pad); printf("Z = %d ", z_pad); printf("R = %d\n", r_pad); x = 0.5 * x_pad / 100; y = 0.5 * y_pad / 100; z = 0.5 * z_pad / 100; r = 0.5 * r_pad / 100; if (JoyInfoEx.dwButtons & JOY_BUTTON1) ardrone.takeoff(); if (JoyInfoEx.dwButtons & JOY_BUTTON2) ardrone.landing(); } // Move ardrone.move3D(x, y, z, r); } // Display the image cvShowImage("camera", image); cvWaitKey(1); } // See you ardrone.close(); return 0; }
bool CKeyDown::Down() { return KEY_DOWN(VK_DOWN); }
void Render() { Matrix mat,mat1,mat2; Bulid_XYZ_RotationMatrix(mat1,0.0,0.0,g_roty); BuildTranslateMatrix(mat2,0.0,0.0,g_tranz); static bool bDrawNonTextureCube=false; if(KEY_DOWN(VK_F1)) { //Draw the color cube. don't use texture bDrawNonTextureCube = !bDrawNonTextureCube; } int icount = g_RenderManager.RenderObjectSize(); for(int i = 0; i < icount;++i) { CRenderObject *pobj = g_RenderManager[i]; POLYGONLIST &polygonlist = pobj->m_PolyGonList; int polygonsize = polygonlist.size(); for( int j = 0; j < polygonsize;++j) { POLYGON &polygon = polygonlist[j]; if(bDrawNonTextureCube) polygon.state &= ~OBJECT_HAS_TEXTURE; else polygon.state |= OBJECT_HAS_TEXTURE; } pobj->Transform(mat1);//transform local pobj->world_pos *= mat2; } //local->world,world->camera,camera->screen static bool bEnableLighting = false; static bool bEableBackfaceRemove =false; static bool bEnableInvZBuffer = false; if(KEY_DOWN(VK_HOME)) { //user press p for(int i=0; i< g_lights.GetLightsCount();++i) { CLight* pLight = g_lights.GetLight(i); pLight->EnableLight(); /* if(pLight->GetLightType() == CLight::kAmbientLight) { pLight->EnableLight(); break; }*/ } bEnableLighting = true; } else if(KEY_DOWN(VK_END)) { bEnableLighting = false; } else if(KEY_DOWN(VK_F2)) { bEableBackfaceRemove = true; } else if(KEY_DOWN(VK_F3)) { bEableBackfaceRemove = false; } else if(KEY_DOWN(VK_F4)) { bEnableInvZBuffer = true; } else if(KEY_DOWN(VK_F5)) { bEnableInvZBuffer = false; } if(bEnableInvZBuffer) ZBuffer::GetInstance()->Clear(0); else ZBuffer::GetInstance()->Clear((1<<30)-1); g_RenderManager.Render(bEnableLighting,bEableBackfaceRemove,!bEnableInvZBuffer); g_fps++; }
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