int Bmp2Surface(LPDIRECTDRAWSURFACE7 lpdds, int SurfaceWidth, int SurfaceHeight) { // copy the bitmap image to the lpddsback buffer line by line // notice the 24 to 32 bit conversion pixel by pixel // 一个像素一个像素的逐粒拷贝至表面 // lock the lpddsback surface lpdds->Lock(NULL,&ddsd, DDLOCK_SURFACEMEMORYPTR | DDLOCK_WAIT,NULL); // get video pointer to primary surfce DWORD *back_buffer = (DWORD *)ddsd.lpSurface; // process each line and copy it into the lpddsback buffer if (ddsd.lPitch == SurfaceWidth) { // copy memory from double buffer to lpddsback buffer memcpy((void *)back_buffer, (void *)bitmap.buffer, SurfaceWidth*SurfaceHeight); } else { for (int index_y = 0; index_y < SurfaceHeight; index_y++) { for (int index_x = 0; index_x < SurfaceWidth; index_x++) { // get BGR values UCHAR blue = (bitmap.buffer[index_y*SurfaceWidth*3 + index_x*3 + 0]), green = (bitmap.buffer[index_y*SurfaceWidth*3 + index_x*3 + 1]), red = (bitmap.buffer[index_y*SurfaceWidth*3 + index_x*3 + 2]); // this builds a 32 bit color value in A.8.8.8 format (8-bit alpha mode) DWORD pixel = _RGB32BIT(0,red,green,blue); // write the pixel back_buffer[index_x + (index_y*ddsd.lPitch >> 2)] = pixel; } // end for index_x } // end for index_y } // now unlock the lpddsback surface if (FAILED(lpdds->Unlock(NULL))) return(0); } // end Bmp2Surface
GameStart::GameStart() { numberOfPlayers = (int)Universe::GetPlayers().size(); numberOfRounds = Universe::GetNumberOfRoundsInGame(); countdownTimer = 250; gameStartFlashTimeInitValue = 15; gameStartFlashTimer = gameStartFlashTimeInitValue; isDrawingGameStart = true;; setupCalled = 0; DWORD mask = _RGB32BIT(0,36,146,255); gameStartGameObject = new SimpleGameObject(150,350,332,60,"bitmaps/GameStart/GameStart.bmp",mask); winMatchGameObject = new SimpleGameObject(200,75,238,30,"bitmaps/GameStart/WinMatch.bmp",mask); _1GameObject = new SimpleGameObject(140,75,16,30,"bitmaps/GameStart/1.bmp", mask); _2GameObject = new SimpleGameObject(140,75,24,30,"bitmaps/GameStart/2.bmp", mask); _3GameObject = new SimpleGameObject(140,75,24,30,"bitmaps/GameStart/3.bmp", mask); _4GameObject = new SimpleGameObject(140,75,24,30,"bitmaps/GameStart/4.bmp", mask); _5GameObject = new SimpleGameObject(140,75,22,30,"bitmaps/GameStart/5.bmp", mask); int padWidth = 84; int padHeight = 74; int padLeftX = 140; int padRightX = 380; int padUpperY = 125; int padLowerY = 255; whitePad1GameObject = new SimpleGameObject(padLeftX,padUpperY,padWidth,padHeight,"bitmaps/GameStart/WhitePad1.bmp", mask ); blackPad2GameObject = new SimpleGameObject(padRightX,padLowerY,padWidth,padHeight,"bitmaps/GameStart/BlackPad2.bmp", mask ); redPad3GameObject = new SimpleGameObject(padRightX,padUpperY,padWidth,padHeight,"bitmaps/GameStart/RedPad3.bmp", mask ); bluePad4GameObject = new SimpleGameObject(padLeftX,padLowerY,padWidth,padHeight,"bitmaps/GameStart/BluePad4.bmp", mask ); Sound::PlaySound(Sound::gameStart, .5f); }
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 }
void Game::Init() { Modules::Init(); Modules::GetLog().Init(); Modules::GetGraphics().Init(main_window_handle, WINDOW_WIDTH, WINDOW_HEIGHT, WINDOW_BPP, WINDOWED_APP); Modules::GetInput().Init(main_instance); Modules::GetInput().InitKeyboard(main_window_handle); Modules::GetSound().Init(main_window_handle); // Modules::GetMusic().Init(main_window_handle); // hide the mouse if (!WINDOWED_APP) ShowCursor(FALSE); // seed random number generator srand(Modules::GetTimer().Start_Clock()); // // initialize math engine // Build_Sin_Cos_Tables(); // initialize the camera with 90 FOV, normalized coordinates _cam = new Camera(CAM_MODEL_EULER, // the euler model vec4(0,500,-200,1), // initial camera position vec4(0,0,0,1), // initial camera angles vec4(0,0,0,1), // no target 10.0, // near and far clipping planes 12000.0, 90.0, // field of view in degrees WINDOW_WIDTH, // size of final screen viewport WINDOW_HEIGHT); vec4 terrain_pos(0,0,0,0); obj_terrain->GenerateTerrain(TERRAIN_WIDTH, // width in world coords on x-axis TERRAIN_HEIGHT, // height (length) in world coords on z-axis TERRAIN_SCALE, // vertical scale of terrain "../../assets/chap11/water_track_height_04.bmp", // filename of height bitmap encoded in 256 colors "../../assets/chap11/water_track_color_03.bmp", // filename of texture map _RGB32BIT(255,255,255,255), // color of terrain if no texture &terrain_pos, // initial position NULL, // initial rotations POLY_ATTR_RGB16 | POLY_ATTR_SHADE_MODE_FLAT | /* POLY4DV2_ATTR_SHADE_MODE_GOURAUD */ POLY_ATTR_SHADE_MODE_TEXTURE); // we are getting divide by zero errors due to degenerate triangles // after projection, this is a problem with the rasterizer that we will // fix later, but if we add a random bias to all y components of each vertice // is fixes the problem, its a hack, but hey no one is perfect :) for (int v = 0; v < obj_terrain->VerticesNum(); v++) obj_terrain->GetTransVertexRef(v).y += ((float)RAND_RANGE(-5,5))/10; // load the jetski model for player obj_player->LoadCOB("../../assets/chap11/jetski05.cob", &vec4(17.5,17.50,17.50, 1), &vec4(0,0,150,1), &vec4(0,0,0,1), VERTEX_FLAGS_SWAP_YZ | VERTEX_FLAGS_TRANSFORM_LOCAL | VERTEX_FLAGS_INVERT_TEXTURE_V /* VERTEX_FLAGS_TRANSFORM_LOCAL_WORLD*/ ); // set up lights LightsMgr& lights = Modules::GetGraphics().GetLights(); lights.Reset(); // create some working colors Color white(255,255,255,0), gray(100,100,100,0), black(0,0,0,0), red(255,0,0,0), green(0,255,0,0), blue(0,0,255,0); // ambient light lights.Init(AMBIENT_LIGHT_INDEX, LIGHT_STATE_ON, // turn the light on LIGHT_ATTR_AMBIENT, // ambient light type gray, black, black, // color for ambient term only NULL, NULL, // no need for pos or dir 0,0,0, // no need for attenuation 0,0,0); // spotlight info NA vec4 dlight_dir(-1,1,0,1); // directional light lights.Init(INFINITE_LIGHT_INDEX, LIGHT_STATE_ON, // turn the light on LIGHT_ATTR_INFINITE, // infinite light type black, gray, black, // color for diffuse term only NULL, &dlight_dir, // need direction only 0,0,0, // no need for attenuation 0,0,0); // spotlight info NA vec4 plight_pos(0,200,0,1); // point light lights.Init(POINT_LIGHT_INDEX, LIGHT_STATE_ON, // turn the light on LIGHT_ATTR_POINT, // pointlight type black, green, black, // color for diffuse term only &plight_pos, NULL, // need pos only 0,.002,0, // linear attenuation only 0,0,1); // spotlight info NA // // create lookup for lighting engine // RGB_16_8_IndexedRGB_Table_Builder(DD_PIXEL_FORMAT565, // format we want to build table for // palette, // source palette // rgblookup); // lookup table // load background sounds Sound& sound = Modules::GetSound(); wind_sound_id = sound.LoadWAV("../../assets/chap11/WIND.WAV"); water_light_sound_id = sound.LoadWAV("../../assets/chap11/WATERLIGHT01.WAV"); water_heavy_sound_id = sound.LoadWAV("../../assets/chap11/WATERHEAVY01.WAV"); water_splash_sound_id = sound.LoadWAV("../../assets/chap11/SPLASH01.WAV"); zbuffer_intro_sound_id = sound.LoadWAV("../../assets/chap11/ZBUFFER02.WAV"); zbuffer_instr_sound_id = sound.LoadWAV("../../assets/chap11/ZINSTRUCTIONS02.WAV"); jetski_start_sound_id = sound.LoadWAV("../../assets/chap11/jetskistart04.WAV"); jetski_idle_sound_id = sound.LoadWAV("../../assets/chap11/jetskiidle01.WAV"); jetski_fast_sound_id = sound.LoadWAV("../../assets/chap11/jetskifast01.WAV"); jetski_accel_sound_id = sound.LoadWAV("../../assets/chap11/jetskiaccel01.WAV"); jetski_splash_sound_id = sound.LoadWAV("../../assets/chap11/splash01.WAV"); // load background image BmpFile* bitmap = new BmpFile("../../assets/chap11/cloud03.BMP"); background_bmp = new BmpImg(0,0,800,600,32); background_bmp->LoadImage32(*bitmap,0,0,BITMAP_EXTRACT_MODE_ABS); delete bitmap; // load in all the text images // intro bitmap = new BmpFile("../../assets/chap11/zbufferwr_intro01.BMP"); intro_image->Create(WINDOW_WIDTH/2 - 560/2,40,560,160,1, BOB_ATTR_VISIBLE | BOB_ATTR_SINGLE_FRAME, DDSCAPS_SYSTEMMEMORY, 0, 32); intro_image->LoadFrame(bitmap, 0,0,0,BITMAP_EXTRACT_MODE_ABS); delete bitmap; // get ready bitmap = new BmpFile("../../assets/chap11/zbufferwr_ready01.BMP"); ready_image->Create(WINDOW_WIDTH/2 - 596/2,40,596,244,1, BOB_ATTR_VISIBLE | BOB_ATTR_SINGLE_FRAME, DDSCAPS_SYSTEMMEMORY, 0, 32); ready_image->LoadFrame(bitmap, 0,0,0,BITMAP_EXTRACT_MODE_ABS); delete bitmap; // nice one bitmap = new BmpFile("../../assets/chap11/zbufferwr_nice01.BMP"); nice_one_image->Create(WINDOW_WIDTH/2 - 588/2,40,588,92,1, BOB_ATTR_VISIBLE | BOB_ATTR_SINGLE_FRAME, DDSCAPS_SYSTEMMEMORY, 0, 32); nice_one_image->LoadFrame(bitmap, 0,0,0,BITMAP_EXTRACT_MODE_ABS); delete bitmap; // allocate memory for zbuffer zbuffer->Create(WINDOW_WIDTH, WINDOW_HEIGHT, ZBUFFER_ATTR_32BIT); }
int Game_Init(HWND hWnd,IDirect3DDevice9** pD3D9Device, void *parms = NULL, int num_parms = 0) { int iRetCode = 0; IDirect3D9* pD3d9 = NULL; pD3d9 = Direct3DCreate9(D3D_SDK_VERSION); if( pD3d9 == NULL ){ iRetCode = -1; CWOOD_LOG_ERR(iRetCode,"Direct3DCreate9 Failed pD3d9:%d D3D_SDK_VERSION:%d",pD3d9,D3D_SDK_VERSION); return iRetCode; } D3DDEVTYPE enDevType = D3DDEVTYPE_HAL; D3DCAPS9 stD3DCaps; pD3d9->GetDeviceCaps(D3DADAPTER_DEFAULT, enDevType, &stD3DCaps); int vp = 0; if( stD3DCaps.DevCaps & D3DDEVCAPS_HWTRANSFORMANDLIGHT ){ vp = D3DCREATE_HARDWARE_VERTEXPROCESSING; } else{ vp = D3DCREATE_SOFTWARE_VERTEXPROCESSING; } D3DPRESENT_PARAMETERS d3dpp; d3dpp.BackBufferWidth = W_WINDOW_WIDTH; d3dpp.BackBufferHeight = W_WINDOW_HEIGHT; d3dpp.BackBufferFormat = D3DFMT_A8R8G8B8; d3dpp.BackBufferCount = 1; d3dpp.MultiSampleType = D3DMULTISAMPLE_NONE; d3dpp.MultiSampleQuality = 0; d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD; d3dpp.hDeviceWindow = hWnd; d3dpp.Windowed = true; d3dpp.EnableAutoDepthStencil = true; d3dpp.AutoDepthStencilFormat = D3DFMT_D24S8; d3dpp.Flags = D3DPRESENTFLAG_LOCKABLE_BACKBUFFER; d3dpp.FullScreen_RefreshRateInHz = D3DPRESENT_RATE_DEFAULT; d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE; HRESULT hrRetCode = 0; hrRetCode = pD3d9->CreateDevice( D3DADAPTER_DEFAULT, // primary adapter enDevType, // device type hWnd, // window associated with device vp, // vertex processing &d3dpp, // present parameters pD3D9Device); // return created device if( FAILED(hrRetCode) ){ CWOOD_LOG_ERR(hrRetCode,"CreateDevice Failed pD3d9:%d ColorDepth 32",pD3d9); // try again using a 16-bit depth buffer d3dpp.AutoDepthStencilFormat = D3DFMT_D16; hrRetCode = pD3d9->CreateDevice(D3DADAPTER_DEFAULT,enDevType,hWnd,vp,&d3dpp,pD3D9Device); if( FAILED(hrRetCode) ){ CWOOD_LOG_ERR(hrRetCode,"CreateDevice Failed pD3d9:%d ColorDepth 16",pD3d9); pD3d9->Release(); // done with d3d9 object return hrRetCode; } } pD3d9->Release(); // done with d3d9 object CWOOD_LOG_DEBUG("GameInit Finished, DeviceP:%d",pD3D9Device); // initialize a single polygon g_stPloy4Rend.iState = CW_POLY4DV1_STATE_ACTIVE; g_stPloy4Rend.iAttr = 0; g_stPloy4Rend.iColor = _RGB32BIT(255,0,255,255); g_stPloy4Rend.vlist[0].x = 0; g_stPloy4Rend.vlist[0].y = 30; g_stPloy4Rend.vlist[0].z = 0; g_stPloy4Rend.vlist[0].w = 1; g_stPloy4Rend.vlist[1].x = 30; g_stPloy4Rend.vlist[1].y = -30; g_stPloy4Rend.vlist[1].z = 0; g_stPloy4Rend.vlist[1].w = 1; g_stPloy4Rend.vlist[2].x = -30; g_stPloy4Rend.vlist[2].y = -30; g_stPloy4Rend.vlist[2].z = 0; g_stPloy4Rend.vlist[2].w = 1; g_stPloy4Rend.pNext = NULL; g_stPloy4Rend.pPrev = NULL; POINT4D stPointCamPosition = {0,0,-100,1}; VECTOR4D stVecCamDirection = {0,0,0,1}; g_oWCamera.Init(CW_CAM_MODEL_EULER,&stPointCamPosition,&stVecCamDirection, NULL,50.0,500.0,90.0,W_WINDOW_WIDTH,W_WINDOW_HEIGHT); // all your initialization code goes here... VECTOR4D vscale={5.0,5.0,5.0,1}, vpos = {0,0,0,1}, vrot = {0,0,0,1}; g_oWObjectMyCube.InitFromFile("./wood_cube.plg", &vscale, &vpos, &vrot); return 0; } // end Game_Init
int Game_Main(HWND hWnd,IDirect3DDevice9* pD3D9Device,void *parms = NULL, int num_parms = 0){ LONG lRetCode = 0; if(pD3D9Device == NULL){ lRetCode =-99; CWOOD_LOG_ERR_L(lRetCode,"Dying Alert!! pD3D9Device is NULL, pD3D9Device:%d",pD3D9Device); return 0; } // generate rotation matrix around y axis static MATRIX4X4 stMatrixRotaion; // general rotation matrix CWMath::Build_XYZ_Rotation_MATRIX4X4(g_iIndex, 0, 0, &stMatrixRotaion); static MATRIX4X4 stMatrixMove; // general move matrix CWMath::Build_XYZ_Move_MATRIX4X4(10, 0, 0, &stMatrixMove); g_oWRender.Reset(); g_oWRender.AddPoly4Rend(g_stPloy4Rend); //g_oWObjectMyCube.TransForm(&stMatrixMove,CW_TRANSFORM_TRANS_ONLY); g_oWObjectMyCube.TransForm(&stMatrixRotaion,CW_TRANSFORM_TRANS_ONLY); g_oWRender.AddObject(g_oWObjectMyCube,0); //g_oWRender.Transform(&stMatrixRotaion,CW_TRANSFORM_LOCAL_ONLY); g_oWRender.ModelToWorld(&g_poly_pos,CW_TRANSFORM_LOCAL_TO_TRANS); g_oWCamera.MakeMatrixEuler(CW_CAM_ROT_SEQ_ZYX); g_oWRender.WorldToCamera(&g_oWCamera); g_oWRender.CameraToPerspective(&g_oWCamera); g_oWRender.PerspectiveToScreen(&g_oWCamera); /* IDirect3DSurface9* pD9Surface = NULL; iRetCode = pD3D9Device->CreateOffscreenPlainSurface( W_WINDOW_WIDTH, W_WINDOW_HEIGHT, D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &pD9Surface, NULL); if(iRetCode != D3D_OK){ CWOOD_LOG_ERR(iRetCode,"CreateOffscreenPlainSurface Failed, pD9Surface:%d",pD9Surface); return iRetCode; } */ pD3D9Device->Clear(0, 0, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, _RGB32BIT(255,99,99,99), 1.0f, 0); pD3D9Device->BeginScene(); IDirect3DSurface9* pBackSurface = NULL; lRetCode = pD3D9Device->GetBackBuffer( 0,0,D3DBACKBUFFER_TYPE_MONO,&pBackSurface ); if(lRetCode != D3D_OK){ CWOOD_LOG_ERR_L(lRetCode,"pD3D9Device->GetBackBuffer Failed, pBackSurface:%d",pBackSurface); return lRetCode; } g_iIndex ++; if(g_iIndex>=360000){ g_iIndex = 0; } CWDraw oWDraw(pBackSurface); g_oWRender.RendItOut(oWDraw); oWDraw.Release(); pBackSurface->Release(); pD3D9Device->EndScene(); CWOOD_LOG_DEBUG("GOOD==============================="); // Swap the back and front buffers. pD3D9Device->Present(0, 0, 0, 0); return 0; }
int Game_Init(void *parms = NULL, int num_parms = 0) { // this is called once after the initial window is created and // before the main event loop is entered, do all your initialization // here // create IDirectDraw interface 7.0 object and test for error if (FAILED(DirectDrawCreateEx(NULL, (void **)&lpdd, IID_IDirectDraw7, NULL))) return(0); // set cooperation to full screen if (FAILED(lpdd->SetCooperativeLevel(main_window_handle, DDSCL_FULLSCREEN | DDSCL_ALLOWMODEX | DDSCL_EXCLUSIVE | DDSCL_ALLOWREBOOT))) return(0); // set display mode to 640x480x24 if (FAILED(lpdd->SetDisplayMode(SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_BPP,0,0))) return(0); // clear ddsd and set size DDRAW_INIT_STRUCT(ddsd); // enable valid fields ddsd.dwFlags = DDSD_CAPS | DDSD_BACKBUFFERCOUNT; ddsd.dwBackBufferCount = 1; // // request primary surface ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE | DDSCAPS_COMPLEX | DDSCAPS_FLIP; // create the primary surface if (FAILED(lpdd->CreateSurface(&ddsd, &lpddsprimary, NULL))) return(0); ddsd.ddsCaps.dwCaps = DDSCAPS_BACKBUFFER; if(FAILED(lpddsprimary->GetAttachedSurface(&ddsd.ddsCaps, &lpddsback))) return 0; // 把主屏和缓冲屏都填充为黑色初始化 DDraw_Fill_Surface(lpddsprimary, _RGB32BIT(0, 0,0,0)); DDraw_Fill_Surface(lpddsback, _RGB32BIT(0, 0,0,0)); // load the 24-bit image char* bmp_wc = "WarCraft24.bmp"; char* bmp_b8 = "bitmap8b.bmp"; char* bmp_b24 = "bitmap24.bmp"; char* bmp_b24e = "bitmap24_edit.bmp"; char* bmp_mo24 = "mosaic-600x.bmp"; char* bmp_ni24 = "nightelf-640x.bmp"; char* bmp_alley24 = "alley8_24bit.bmp"; // 载入背景图片 if (!Load_Bitmap_File(&bitmap, bmp_ni24)) return(0); // 创建背景表面、但实际上不是直接用背景表面来显示的、而是拷贝去缓冲表面和人物动作混合 // 后才一次性打到显示表面 // 这里头两个参数是指在屏幕的高和宽、第二个是指表面建立的地点、0指在显存建立、其它表示在 // 系统内存建立、当然速度自然是在显存建立快了、最后一个参数是是否设置为色彩键、这里设定为-1 // 也就是不设定任何色彩过滤、因为这个是背景表面、所以不需要任何透明的色彩键 lpddsbackground = DDraw_Create_Surface(640,480,0,-1); // 把bmp的内容拷贝至缓冲表面中 Bmp2Surface(lpddsbackground, SCREEN_WIDTH, SCREEN_HEIGHT); // 从现在开始创建人物动作了 if (!Load_Bitmap_File(&bitmap, "Dedsp0_24bit.bmp")) return(0); // seed random number generator // GetTickCount是一个系统启动至今的毫秒数、 // 配合srandg来产生一个随机数 srand(GetTickCount()); // initialize all the aliens // alien on level 1 of complex // //系统在调用rand()之前都会自动调用srand(),如果用户在rand()之前曾调用过srand()给参数seed指定了一个值, //那么rand()就会将seed的值作为产生伪随机数的初始值; //而如果用户在rand()前没有调用过srand(),那么rand()就会自动调用srand(1),即系统默认将1作为伪随机数的初始值。 //所以前面要调用一次srand来确保以下调用rand()的值会产生不同 // aliens[0].x = rand()%SCREEN_WIDTH; aliens[0].y = 116 - 72; aliens[0].velocity = 2+rand()%4; aliens[0].current_frame = 0; aliens[0].counter = 0; // alien on level 2 of complex aliens[1].x = rand()%SCREEN_WIDTH; aliens[1].y = 246 - 72; aliens[1].velocity = 2+rand()%4; aliens[1].current_frame = 0; aliens[1].counter = 0; // alien on level 3 of complex aliens[2].x = rand()%SCREEN_WIDTH; aliens[2].y = 382 - 72; aliens[2].velocity = 2+rand()%4; aliens[2].current_frame = 0; aliens[2].counter = 0; // now load the bitmap containing the alien imagery // then scan the images out into the surfaces of alien[0] // and copy then into the other two, be careful of reference counts! // 现在开始载入人物的动画帧图片了 if (!Load_Bitmap_File(&bitmap,"Dedsp0_24bit.bmp")) return(0); // create each surface and load bits // 初始化异形0号的三个动作帧表面、 // 其实、所有的异形动作帧表面都一样的、所以没有必要为每个异形都创建相应的动作帧、 // 所以其它异形的动作帧都指向这个异形0号的动作帧就可以了 for (int index = 0; index < 3; index++) { // create surface to hold image aliens[0].frames[index] = DDraw_Create_Surface(72,80,0); // now load bits... Scan_Image_Bitmap(&bitmap, // bitmap file to scan image data from aliens[0].frames[index], // surface to hold data index, 0); // cell to scan image from } // end for index // unload the bitmap file, we no longer need it Unload_Bitmap_File(&bitmap); // now for the tricky part. There is no need to create more surfaces with the same // data, so I'm going to copy the surface pointers member for member to each alien // however, be careful, since the reference counts do NOT go up, you still only need // to release() each surface once! for (index = 0; index < 3; index++) aliens[1].frames[index] = aliens[2].frames[index] = aliens[0].frames[index]; // return success or failure or your own return code here return(1); } // end Game_Init
GameState * GameStart::Update() { if(!setupCalled) { Setup(); setupCalled = 1; } bool skip = false; if(skip) { delete this; return new Playing(); } DWORD backgroundColor = _RGB32BIT(0,36,146,255); // clear the drawing surface DDraw_Fill_Surface(lpddsback,backgroundColor ); if(gameStartFlashTimer > 0) { gameStartFlashTimer--; } else { if(isDrawingGameStart) { isDrawingGameStart = false; } else { isDrawingGameStart = true; } gameStartFlashTimer = gameStartFlashTimeInitValue; } if(isDrawingGameStart) { gameStartGameObject->GetBlitterObject()->Draw(lpddsback); } winMatchGameObject->GetBlitterObject()->Draw(lpddsback); switch(numberOfRounds) { case 1: _1GameObject->GetBlitterObject()->Draw(lpddsback); break; case 2: _2GameObject->GetBlitterObject()->Draw(lpddsback); break; case 3: _3GameObject->GetBlitterObject()->Draw(lpddsback); break; case 4: _4GameObject->GetBlitterObject()->Draw(lpddsback); break; case 5: _5GameObject->GetBlitterObject()->Draw(lpddsback); break; } switch(numberOfPlayers) { case 1: whitePad1GameObject->GetBlitterObject()->Draw(lpddsback); break; case 2: whitePad1GameObject->GetBlitterObject()->Draw(lpddsback); blackPad2GameObject->GetBlitterObject()->Draw(lpddsback); break; case 3: whitePad1GameObject->GetBlitterObject()->Draw(lpddsback); blackPad2GameObject->GetBlitterObject()->Draw(lpddsback); redPad3GameObject->GetBlitterObject()->Draw(lpddsback); break; case 4: whitePad1GameObject->GetBlitterObject()->Draw(lpddsback); blackPad2GameObject->GetBlitterObject()->Draw(lpddsback); redPad3GameObject->GetBlitterObject()->Draw(lpddsback); bluePad4GameObject->GetBlitterObject()->Draw(lpddsback); break; } countdownTimer--; if(countdownTimer <= 0) { delete this; return new Playing(); } DDraw_Flip(); return this; }