LPSHOT Video_FindSubShot( LPVIDEO lpVideo, SHOTID lShot, long lCount, long lFrame ) /***********************************************************************/ { if ( !lpVideo ) return( NULL ); if ( !lFrame ) if ( !(lFrame = MCIGetPosition( lpVideo->hDevice )) ) return( NULL ); long lStartFrame, lEndFrame; if ( !lCount ) lCount = 1; for ( int i=0; i<lCount; i++ ) { LPSHOT lpShot; if ( !(lpShot = Video_GetShotPtr( lpVideo, lShot+i )) ) continue; lStartFrame = lpShot->lStartFrame; lEndFrame = lpShot->lEndFrame; if ( bShortenHotspots && (lpShot->lFlags & A_SPECIAL) ) { long l = (lEndFrame - lStartFrame) / 4; lStartFrame += l; lEndFrame -= l; } if ( lFrame < lStartFrame || lFrame > lEndFrame ) continue; // The current frame is in this shot's range return( Video_GetShot( lpVideo, lShot+i ) ); } return( NULL ); }
//************************************************************************ LOCAL void Story_OnTimer(HWND hWindow, UINT id) //************************************************************************ { PSTORY pStory = GetStory(hWindow); if (!pStory) return; DWORD dwPos = MCIGetPosition(pStory->m_hMCIfile); for (int i = 0; i < pStory->m_nRects; ++i) { if (dwPos >= pStory->m_lpWordData[i].dwFrom && dwPos <= pStory->m_lpWordData[i].dwTo) { if ((pStory->m_iHighlight-1) != i) { HDC hDC = GetDC(hWindow); if (pStory->m_iHighlight) Story_OnDraw(hWindow, hDC, &pStory->m_lpWordData[pStory->m_iHighlight-1].rArea, FALSE); Story_OnDraw(hWindow, hDC, &pStory->m_lpWordData[i].rArea, TRUE); pStory->m_iHighlight = i+1; ReleaseDC(hWindow, hDC); } break; } } }
static int PtInHotspot( LPVIDEO lpVideo, int x, int y, BOOL bDisable ) /***********************************************************************/ { if ( !lpVideo ) return( NULL ); LPSHOT lpShotOrig; if ( !(lpShotOrig = Video_GetShotPtr( lpVideo, lpVideo->lCurrentShot )) ) return( NULL ); POINT pt; pt.x = x; pt.y = y; LPSHOT lpShot; long lFrame = 0; //TryLeft: // Try the left event lpShot = lpShotOrig; if ( lpShot->bLeftIsSubShot ) { if ( !lFrame ) // We need it now... if ( !(lFrame = MCIGetPosition( lpVideo->hDevice )) ) goto TryRight; if ( !(lpShot = Video_FindSubShot( lpVideo, lpShot->lLeftShot, lpShot->lLeftCount, lFrame )) ) goto TryRight; } if ( !(lpShot->fHotspotDisabled & 1) && PtInEventHotspot( lpShot->lLeftHotspot, pt ) ) { if ( bDisable && (lpShot->lFlags & A_SPECIAL) ) lpShot->fHotspotDisabled |= 1; return( EVENT_LEFT ); } TryRight: // Try the right event lpShot = lpShotOrig; if ( lpShot->bRightIsSubShot ) { if ( !lFrame ) // We need it now... if ( !(lFrame = MCIGetPosition( lpVideo->hDevice )) ) goto TryUp; if ( !(lpShot = Video_FindSubShot( lpVideo, lpShot->lRightShot, lpShot->lRightCount, lFrame )) ) goto TryUp; } if ( !(lpShot->fHotspotDisabled & 2) && PtInEventHotspot( lpShot->lRightHotspot, pt ) ) { if ( bDisable && (lpShot->lFlags & A_SPECIAL) ) lpShot->fHotspotDisabled |= 2; return( EVENT_RIGHT ); } TryUp: // Try the up event lpShot = lpShotOrig; if ( lpShot->bUpIsSubShot ) { if ( !lFrame ) // We need it now... if ( !(lFrame = MCIGetPosition( lpVideo->hDevice )) ) goto TryDown; if ( !(lpShot = Video_FindSubShot( lpVideo, lpShot->lUpShot, lpShot->lUpCount, lFrame )) ) goto TryDown; } if ( !(lpShot->fHotspotDisabled & 4) && PtInEventHotspot( lpShot->lUpHotspot, pt ) ) { if ( bDisable && (lpShot->lFlags & A_SPECIAL) ) lpShot->fHotspotDisabled |= 4; return( EVENT_UP ); } TryDown: // Try the down event lpShot = lpShotOrig; if ( lpShot->bDownIsSubShot ) { if ( !lFrame ) // We need it now... if ( !(lFrame = MCIGetPosition( lpVideo->hDevice )) ) goto TryHome; if ( !(lpShot = Video_FindSubShot( lpVideo, lpShot->lDownShot, lpShot->lDownCount, lFrame )) ) goto TryHome; } if ( !(lpShot->fHotspotDisabled & 8) && PtInEventHotspot( lpShot->lDownHotspot, pt ) ) { if ( bDisable && (lpShot->lFlags & A_SPECIAL) ) lpShot->fHotspotDisabled |= 8; return( EVENT_DOWN ); } TryHome: // Try the home event lpShot = lpShotOrig; if ( lpShot->bHomeIsSubShot ) { if ( !lFrame ) // We need it now... if ( !(lFrame = MCIGetPosition( lpVideo->hDevice )) ) goto TryDone; if ( !(lpShot = Video_FindSubShot( lpVideo, lpShot->lHomeShot, lpShot->lHomeCount, lFrame )) ) goto TryDone; } if ( !(lpShot->fHotspotDisabled & 16) && PtInEventHotspot( lpShot->lHomeHotspot, pt ) ) { if ( bDisable && (lpShot->lFlags & A_SPECIAL) ) lpShot->fHotspotDisabled |= 16; return( EVENT_HOME ); } TryDone: return( NULL ); }
void Video_GotoShot( HWND hWindow, LPVIDEO lpVideo, SHOTID lShot, long lCount, int iFrames, int iEventCode ) /***********************************************************************/ { LPSHOT lpShot; if ( !(lpShot = Video_GetShot( lpVideo, lShot, lCount )) ) { MCIStop( lpVideo->hDevice, YES/*bWait*/ ); MCIPlay( lpVideo->hDevice, hWindow/*Notify Myself*/ ); return; } if ( lpShot->wDisk != lpVideo->wDisk ) if ( !Video_Open( hWindow, lpVideo, lpShot->wDisk, lpShot->lStartFrame ) ) return; if ( lpShot->lShotID != lpVideo->lCurrentShot || !iEventCode ) { // if the shot is changing, or a NULL event code... // Send the notification message if the shot is changing lpShot->iLastEvent = iEventCode; LPPSHOT lppShot = &lpShot; FORWARD_WM_COMMAND( GetParent(hWindow), GET_WINDOW_ID(hWindow), LOWORD(lppShot), HIWORD(lppShot), SendMessage ); if ( !(*lppShot) ) // if the application rejects this shot... return; // get out, and whatever is playing keeps playing // Set the previous shot variables, unless we could cause an infinite loop if ( lpShot->bGoesPrev ) { LPSHOT lpCurrentShot = Video_GetShotPtr( lpVideo, lpVideo->lCurrentShot ); if ( lpCurrentShot && !lpCurrentShot->bGoesPrev ) { lpVideo->lPrevFrame = MCIGetPosition( lpVideo->hDevice ); lpVideo->lPrevShot = lpVideo->lCurrentShot; } } lpVideo->lCurrentShot = lpShot->lShotID; } // Calculate the lFrom and lTo frames long lTo = lpShot->lEndFrame; long lFrom = lpShot->lStartFrame; if ( iFrames > 0 ) lFrom = max( lTo - iFrames, lFrom ); if ( lpShot->lIndentFrames ) { // If indention is being used... lFrom += lpShot->lIndentFrames; lpShot->lIndentFrames = 0; if ( lFrom > lTo ) lFrom = lTo; } else // Clear any disabled hotspot flags Video_ShotEnableHotspots( lpVideo, lpShot ); MCIStop( lpVideo->hDevice, YES/*bWait*/ ); MCIPlay( lpVideo->hDevice, hWindow/*Notify Myself*/, lFrom, lTo ); lpVideo->lLastShotToPlay = lpVideo->lCurrentShot; }
static void Video_OnKey(HWND hWindow, UINT vk, BOOL fDown, int cRepeat, UINT flags) /***********************************************************************/ { BOOL bReturn; LPVIDEO lpVideo; static int iSpeed; if ( StyleOn( hWindow, WS_NOTENABLED ) ) return; #ifndef _DEBUG if ( flags & KF_REPEAT ) return; #endif if ( !(lpVideo = (LPVIDEO)GetWindowLong( hWindow, GWL_DATAPTR )) ) return; switch ( vk ) { case 'P': { // Play Video_GotoShot( hWindow, lpVideo, lpVideo->lCurrentShot, 1/*lCount*/, 0/*iFrames*/, 0/*iEventCode*/ ); break; } case 'S': { // Stop if (lpVideo->idLoopTimer) { KillTimer (hWindow, lpVideo->idLoopTimer); lpVideo->idLoopTimer = NULL; } bReturn = MCIStop( lpVideo->hDevice, YES/*bWait*/ ); break; } case VK_PAUSE: { DWORD dwMode = MCIGetMode( lpVideo->hDevice ); if ( dwMode == MCI_MODE_PAUSE ) bReturn = MCIResume( lpVideo->hDevice ); else if ( dwMode == MCI_MODE_PLAY ) bReturn = MCIPause( lpVideo->hDevice ); break; } case VK_SPACE: { // Process the END event to skip the current shot Video_ProcessEvent( hWindow, lpVideo, EVENT_END ); break; } case VK_LEFT: { // Process the LEFT event Video_ProcessEvent( hWindow, lpVideo, EVENT_LEFT ); break; } case VK_UP: { // Process the UP event Video_ProcessEvent( hWindow, lpVideo, EVENT_UP ); break; } case VK_RIGHT: { // Process the RIGHT event Video_ProcessEvent( hWindow, lpVideo, EVENT_RIGHT ); break; } case VK_DOWN: { // Process the DOWN event Video_ProcessEvent( hWindow, lpVideo, EVENT_DOWN ); break; } case VK_HOME: { // Process the DOWN event Video_ProcessEvent( hWindow, lpVideo, EVENT_HOME ); break; } #ifdef _DEBUG case '1': { bReturn = MCISetAudioOnOff( lpVideo->hDevice, OFF ); break; } case '2': { bReturn = MCISetAudioOnOff( lpVideo->hDevice, ON ); break; } case '3': { bReturn = MCISetVideoOnOff( lpVideo->hDevice, OFF ); break; } case '4': { bReturn = MCISetVideoOnOff( lpVideo->hDevice, ON ); break; } case 'G': // Turn grid draw proc on { Video_DrawProcInstall( hWindow, VDP_GridSet, VDP_GridDraw, 33 ); break; } case 'H': // Turn hotspot draw proc on { Video_DrawProcInstall( hWindow, VDP_HotspotSet, VDP_HotspotDraw, 33 ); break; } case 'N': // Turn draw proc off { Video_DrawProcInstall( hWindow, NULL, NULL, 33 ); break; } // case VK_HOME: // { // bReturn = MCISeekHome( lpVideo->hDevice ); // break; // } case VK_END: { LPSHOT lpShot = Video_GetShotPtr( lpVideo, lpVideo->lCurrentShot ); if ( lpShot ) bReturn = MCISeek( lpVideo->hDevice, lpShot->lEndFrame ); else bReturn = MCISeekEnd( lpVideo->hDevice ); break; } case VK_NEXT: { bReturn = MCIStepForward( lpVideo->hDevice, 1 ); break; } case VK_PRIOR: { bReturn = MCIStepReverse( lpVideo->hDevice ); break; } case VK_MULTIPLY: { iSpeed = 0; bReturn = MCISetVideoSpeed( lpVideo->hDevice, 1000L + iSpeed ); break; } case VK_ADD: { if ( iSpeed >= 1000 ) break; iSpeed += 100; bReturn = MCISetVideoSpeed( lpVideo->hDevice, 1000L + iSpeed ); break; } case VK_SUBTRACT: { if ( iSpeed <= -1000 ) break; iSpeed -= 100; bReturn = MCISetVideoSpeed( lpVideo->hDevice, 1000L + iSpeed ); break; } #endif default: break; } #ifdef _DEBUG // For putting the current frame number into a text box STRING szString; wsprintf( szString, "%ld", MCIGetPosition( lpVideo->hDevice ) ); SetDlgItemText( GetParent(hWindow), 120/*IDC_VIDEO_SHOTFRAME*/, szString ); #endif }