/*----------------------------------------------------------------------------- Name : binkPlay Description : playback a Bink video file Inputs : ... Outputs : Return : TRUE or FALSE (success or failure) ----------------------------------------------------------------------------*/ bool binkPlay(char* filename, binkDisplay_proc displayProc, binkDecodeCallback_proc decodeProc, sdword surfType, bool rev, sdword trackNum) { if (!systemActive) { return FALSE; } g_trackNum = trackNum; if (trackNum != -1) { soundEventUpdate(); speechEventUpdate(); Sleep(150); soundEventUpdate(); speechEventUpdate(); } binkStopNow = FALSE; binkUpdate = FALSE; binkIsPaused = FALSE; binkFrameAdd = 0; if (!binkOpen(filename)) { return FALSE; } binkDecodeFrameCount = 0; binkDisplayFrameCount = 0; binkDisplayFlags = BINKSURFACECOPYALL; binkDonePlaying = FALSE; binkPlaying = TRUE; g_surfType = surfType; if (displayProc == NULL) { g_displayProc = (hwGetDepth() > 16) ? binkDisplay32 : binkDisplay16; } else { g_displayProc = displayProc; } g_decodeProc = decodeProc; binkPlayLoop(); binkPlaying = FALSE; BinkClose(bnk); binkDonePlaying = TRUE; return TRUE; }
/*----------------------------------------------------------------------------- Name : svShipViewRender Description : Callback which draws the main ship view. Inputs : standard FE callback Outputs : .. Return : void ----------------------------------------------------------------------------*/ void svShipViewRender(featom* atom, regionhandle region) { rectangle drawRect; rectangle* rect; rectangle viewRect; fonthandle currentFont; GLint viewPort[4]; GLint box[4]; ShipStaticInfo* info; real32 scale; sdword width, height; sdword x, y; keyindex key; char* keystring; bool resetRender = FALSE; char temp[100]; // facilitates smooth transition between auto/manual rotation of ship static real32 angle_user_rotated_to = 0.0f; static real32 declination_user_rotated_to = 0.0f; static real32 time_user_rotated_view = 0.0f; real32 real_time_angle = 0.0f; static real32 user_real_angle_offset = 0.0f; rect = ®ion->rect; viewRect.x0 = 0; viewRect.y0 = 0; viewRect.x1 = MAIN_WindowWidth - 1; viewRect.y1 = MAIN_WindowHeight - 1; info = NULL; if (svShipType != DefaultShip) { if (universe.curPlayerPtr) { info = GetShipStaticInfoSafe(svShipType, universe.curPlayerPtr->race); } if (info == NULL) { info = GetShipStaticInfoSafe(svShipType, GetValidRaceForShipType(svShipType)); } if (info == NULL) { return; } } svShipViewRegion = region; if (!resetRender) { if (svMouseInside) { ferDrawFocusWindow(region, lw_focus); } else { ferDrawFocusWindow(region, lw_normal); } } soundEventUpdate(); currentFont = fontMakeCurrent(svShipViewFont); if (region->flags == 0 || region->flags == RPE_DrawFunctionAdded) { //if region not processed yet region->flags = RPE_Enter | RPE_Exit | RPE_WheelDown | RPE_WheelUp | RPE_PressLeft | RPE_ReleaseLeft | RPE_PressRight | RPE_ReleaseRight; regFunctionSet(region, (regionfunction) svReadMouseEvent); //set new region handler function } //scale = *svScale[svShipType]; //svCamera.closestZoom = *svMinZoom[svShipType]; //svCamera.farthestZoom = *svMaxZoom[svShipType]; scale = 1.0f; //*svScale[svShipType]; if(svShipType != DefaultShip) { svCamera.closestZoom = info->minimumZoomDistance*svZoomInScalar; svCamera.farthestZoom = (svCamera.closestZoom+info->staticheader.staticCollInfo.approxcollspheresize)*svZoomOutScalar; if(ReZoom) { ReZoom=FALSE; cameraZoom(&svCamera,1.0f,FALSE); } if (svMouseInside && (wheel_down || wheel_up)) { cameraControl(&svCamera, FALSE); } else if (svMouseInside && svMousePressRight) { camMouseX = (svMouseCentreX - mouseCursorX()) * 4; //was 2 camMouseY = (svMouseCentreY - mouseCursorY()) * 4; savecamMouseX = savecamMouseX * SPIN_FEEDBACK + (real32)camMouseX * (1.0f - SPIN_FEEDBACK); cameraControl(&svCamera, FALSE); //update the camera mouseCursorHide(); mousePositionSet(svMouseCentreX, svMouseCentreY); // Reset position so it doesn't walk off region // keep track of where the user left the camera so we can sync auto-rotation with it angle_user_rotated_to = svCamera.angle; declination_user_rotated_to = svCamera.declination; time_user_rotated_view = universe.totaltimeelapsed; } else // auto rotate ship model { // continual 360 degree yaw rotation real_time_angle = DEG_TO_RAD(remainder(universe.totaltimeelapsed, SV_360_ROTATION_SECS) / SV_360_ROTATION_SECS * 360); if (angle_user_rotated_to >= 0.0) { user_real_angle_offset = angle_user_rotated_to - real_time_angle; angle_user_rotated_to = -1.0; } svCamera.angle = real_time_angle + user_real_angle_offset; // collapse pitch to default declination if (time_user_rotated_view > 0.0) { if (universe.totaltimeelapsed > time_user_rotated_view + SV_PITCH_FLATTEN_SECS) { svCamera.declination = DEG_TO_RAD(svDeclination); time_user_rotated_view = 0.0; } else { svCamera.declination = declination_user_rotated_to + (DEG_TO_RAD(svDeclination) - declination_user_rotated_to) * ((universe.totaltimeelapsed - time_user_rotated_view) / SV_PITCH_FLATTEN_SECS); } } if (svMouseInside) mouseCursorShow(); } } //rotation drawRect.x0 = rect->x0 + SV_ViewMargin; drawRect.y0 = rect->y0 + SV_ViewMargin; drawRect.x1 = rect->x1 - SV_ViewMargin; drawRect.y1 = rect->y1 - SV_ViewMargin; width = drawRect.x1 - drawRect.x0; height = drawRect.y1 - drawRect.y0; glGetIntegerv(GL_VIEWPORT, viewPort); glViewport(drawRect.x0, MAIN_WindowHeight - drawRect.y1, width, height); primModeSet2(); if (!resetRender) { primRectSolid2(&viewRect, FEC_Background); } primModeClear2(); glEnable(GL_SCISSOR_TEST); glGetIntegerv(GL_SCISSOR_BOX, box); glScissor(drawRect.x0, MAIN_WindowHeight - drawRect.y1, width, height); glClear(GL_DEPTH_BUFFER_BIT); glDisable(GL_SCISSOR_TEST); rndPerspectiveCorrection(TRUE); //svCamera.lookatpoint.x = -info->staticheader.staticCollInfo.collsphereoffset.z * scale; //svCamera.lookatpoint.y = -info->staticheader.staticCollInfo.collsphereoffset.x * scale; //svCamera.lookatpoint.z = -info->staticheader.staticCollInfo.collsphereoffset.y * scale; if (svShipType == DefaultShip) { svCamera.lookatpoint.x=0.0f; svCamera.lookatpoint.y=0.0f; svCamera.lookatpoint.z=0.0f; } else { svCamera.lookatpoint.x = -info->staticheader.staticCollInfo.collsphereoffset.z; svCamera.lookatpoint.y = -info->staticheader.staticCollInfo.collsphereoffset.x; svCamera.lookatpoint.z = -info->staticheader.staticCollInfo.collsphereoffset.y; } cameraSetEyePosition(&svCamera); rndLightingEnable(TRUE); glMatrixMode(GL_PROJECTION); glLoadIdentity(); rgluPerspective( svCamera.fieldofview, (float)(width) / (float)(height) /*rndAspectRatio*/, //set projection matrix svCamera.clipPlaneNear, svCamera.clipPlaneFar); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); rgluLookAt( svCamera.eyeposition.x, svCamera.eyeposition.y, svCamera.eyeposition.z, svCamera.lookatpoint.x, svCamera.lookatpoint.y, svCamera.lookatpoint.z, svCamera.upvector.x, svCamera.upvector.y, svCamera.upvector.z); glPushMatrix(); glRotatef(-90.0f, 0.0f, 1.0f, 0.0f); glGetFloatv(GL_MODELVIEW_MATRIX, (GLfloat *)(&rndCameraMatrix)); glGetFloatv(GL_PROJECTION_MATRIX, (GLfloat *)(&rndProjectionMatrix)); glEnable(GL_NORMALIZE); glLightfv(GL_LIGHT0, GL_POSITION, lightPosition0); //position light(s) within world glScalef(scale, scale, scale); if (svShipType != DefaultShip) { sdword index; //try player index colours first index = universe.curPlayerIndex; if (info->teamColor[index] == 0) { //colour scheme doesn't exist, search for something valid for (index = 0; index < MAX_MULTIPLAYER_PLAYERS; index++) { if (info->teamColor[index] != 0) { break; } } if (index == MAX_MULTIPLAYER_PLAYERS) { //this ship doesn't have any colour info, //at least avoid a GPF index = universe.curPlayerIndex; } } meshRender((meshdata *)info->staticheader.LOD->level[0].pData, index); } glDisable(GL_NORMALIZE); glPopMatrix(); primModeSet2(); glScissor(box[0], box[1], box[2], box[3]); glViewport(viewPort[0], viewPort[1], viewPort[2], viewPort[3]); rndLightingEnable(FALSE); rndPerspectiveCorrection(FALSE); x = rect->x0 + 2 + SV_ViewMargin; y = rect->y0 + 2 + SV_ViewMargin; if (svShipType != DefaultShip && !resetRender) { fontPrintf( x, y, FEC_ListItemStandard, "%s", ShipTypeToNiceStr(svShipType)); y += fontHeight(" "); sprintf(temp, "%s %d %s",strGetString(strSVCost),info->buildCost, strGetString(strSVRUs)); fontPrintf( x, y, FEC_ListItemStandard, temp); if (cmPrintHotKey) { x = rect->x1 - 2 - SV_ViewMargin; y = rect->y0 + 2 + SV_ViewMargin; key = cmShipTypeToKey(svShipType); keystring = opKeyToNiceString((keyindex)(key & 0x00ff)); if (key & CM_SHIFT) { width = fontWidthf("[SHIFT-%s]",keystring); fontPrintf( x-width, y, FEC_ListItemStandard, "[SHIFT-%s]", keystring); } else if (key) { width = fontWidthf("[%s]",keystring); fontPrintf( x-width, y, FEC_ListItemStandard, "[%s]", keystring); } } } fontMakeCurrent(currentFont); svDirtyShipView(); }
/*----------------------------------------------------------------------------- Name : binkDecodeTimerProc Description : mmtimer callback proc for decoding a frame of Bink video Inputs : [all ignored] Outputs : Return : ----------------------------------------------------------------------------*/ void CALLBACK binkDecodeTimerProc(UINT uid, UINT msg, DWORD dwUser, DWORD dw1, DWORD dw2) { if (!systemActive) { binkUpdate = FALSE; binkStopNow = TRUE; return; } if (inDecode || binkStopNow) { if (binkStopNow) { binkUpdate = FALSE; } return; } inDecode = TRUE; soundEventUpdate(); speechEventUpdate(); if (bnk->FrameNum < 2) { binkTimeReset(); binkDecodeSimply(); inDecode = FALSE; return; } if (systemActive) { sdword diff, i; sdword idealFrame = binkIdealFrame(); (void)BinkWait(bnk); if (idealFrame >= bnk->Frames) { idealFrame = bnk->Frames - 1; binkStopNow = TRUE; inDecode = FALSE; binkUpdate = FALSE; if (binkTimerHandle != 0) { (void)timeKillEvent(binkTimerHandle); binkTimerHandle = 0; } return; } diff = idealFrame - bnk->FrameNum; if (diff < 0) { diff = 0; } binkDisplayFlags = (diff > 1) ? BINKSURFACECOPYALL : 0; for (i = 0; i < diff; i++) { if ((i > 0) && (!(i & 3))) { (void)BinkWait(bnk); } binkDecodeFrameCount++; binkNextFrame(); binkUpdate = TRUE; if (binkStopNow) { break; } } if (g_decodeProc != NULL) { g_decodeProc(binkDecodeFrameCount); } } if (binkStopNow) { binkUpdate = FALSE; } inDecode = FALSE; }