123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966 |
- #include "main.h"
- #include "IVideoD3DOSD.h"
- #include "resource.h"
- extern wchar_t FileTitle[];
- static HMODULE d3dx_lib = 0;
- // For non-debug builds, comment out DXTraceW debug statements to
- // remove them completely
- //#ifndef _DEBUG
- #define DXTraceW //
- //#endif
- typedef HRESULT (WINAPI *D3DXCREATESPRITE)(LPDIRECT3DDEVICE9, LPD3DXSPRITE *);
- typedef HRESULT (WINAPI *D3DXCREATEFONTW)(LPDIRECT3DDEVICE9, INT, UINT, UINT, UINT, BOOL, DWORD, DWORD, DWORD, DWORD, LPCWSTR, LPD3DXFONT *);
- typedef HRESULT (WINAPI *D3DXCREATETEXTUREFROMRESOURCEEXW)(LPDIRECT3DDEVICE9, HMODULE, LPCWSTR, UINT, UINT, UINT, DWORD, D3DFORMAT, D3DPOOL, DWORD, DWORD, D3DCOLOR, D3DXIMAGE_INFO *, PALETTEENTRY *, LPDIRECT3DTEXTURE9 *);
- D3DXCREATESPRITE pCreateSprite = NULL;
- D3DXCREATEFONTW pCreateFontW = NULL;
- D3DXCREATETEXTUREFROMRESOURCEEXW pCreateTextureFromResourceExW = NULL;
- HMODULE FindD3DX9()
- {
- if (d3dx_lib)
- return d3dx_lib;
- HMODULE d3dx9 = NULL;
- HANDLE hFind;
- WIN32_FIND_DATAW pfiledata;
- wchar_t systemDir[MAX_PATH] = {0};
- wchar_t libPath[MAX_PATH] = {0};
- GetSystemDirectoryW(systemDir, MAX_PATH);
- StringCchCatW(systemDir, MAX_PATH,L"\\d3dx9_");
- StringCchCopyW(libPath, MAX_PATH, systemDir);
- StringCchCatW(systemDir, MAX_PATH,L"*.dll");
- hFind = FindFirstFileW(systemDir,&pfiledata);
- if (hFind != INVALID_HANDLE_VALUE)
- {
- BOOL more = true;
- int iHighVersion = 0;
- while (more)
- {
- wchar_t *start = wcsrchr(pfiledata.cFileName,L'_') + 1;
- int version = _wtoi(start);
- if (version <= 42 && version > iHighVersion)
- iHighVersion = version;
- more = FindNextFileW(hFind,&pfiledata);
- }
- FindClose(hFind);
- if (iHighVersion >= 24)
- {
- wchar_t finalD3DX9LibPath[MAX_PATH] = {0};
- StringCchPrintfW(finalD3DX9LibPath,MAX_PATH,L"%s%d%s",libPath,iHighVersion,L".dll");
- d3dx9 = LoadLibraryW(finalD3DX9LibPath);
- }
- }
- return d3dx9;
- }
- IVideoD3DOSD::IVideoD3DOSD(void)
- {
- osdSprite = NULL;
- osdAtlasTexture = NULL;
- osdTimeFont = NULL;
- osdTitleFont = NULL;
- streaming = 0;
- titleFits = false;
- // Texture Src Coordinates for sprite images
- // Right and Bottom (last two) excluded from image
- SetRect(&osdBkgrndTextSrcCoords, 38, 534, 647, 635);
- SetRect(&osdPrevButtonNormalSrcCoords, 41, 17, 63, 31);
- SetRect(&osdPlayButtonNormalSrcCoords, 145, 14, 161, 35);
- SetRect(&osdPauseButtonNormalSrcCoords, 95, 16, 110, 33);
- SetRect(&osdStopButtonNormalSrcCoords, 195, 16, 210, 33);
- SetRect(&osdNextButtonNormalSrcCoords, 242, 17, 264, 31);
- SetRect(&osdProgressFrameNormalSrcCoords, 41, 226, 606, 235);
- SetRect(&osdVolumeFrameNormalSrcCoords, 41, 294, 111, 302);
- SetRect(&osdEndFSButtonNormalSrcCoords, 41, 140, 59, 158);
- SetRect(&osdMuteButtonNormalSrcCoords, 41, 416, 51, 428);
- SetRect(&osdProgressSliderNormalSrcCoords, 41, 343, 57, 361);
- SetRect(&osdVolumeSliderNormalSrcCoords, 41, 343, 57, 361);
- SetRect(&osdProgressProgressSrcCoords, 41, 274, 606, 282); //hilited progress indicator
- SetRect(&osdVolumeProgressSrcCoords, 41, 314, 111, 322); //hilited volume indicator
- SetRect(&osdPrevButtonClickSrcCoords, 41, 76, 63, 90);
- SetRect(&osdPlayButtonClickSrcCoords, 145, 73, 161, 94);
- SetRect(&osdPauseButtonClickSrcCoords, 95, 75, 110, 92);
- SetRect(&osdStopButtonClickSrcCoords, 195, 75, 210, 92);
- SetRect(&osdNextButtonClickSrcCoords, 242, 76, 264, 90);
- SetRect(&osdEndFSButtonClickSrcCoords, 41, 192, 59, 210);
- SetRect(&osdProgressSliderClickSrcCoords, 41, 385, 57, 403);
- SetRect(&osdVolumeSliderClickSrcCoords, 41, 385, 57, 403);
- SetRect(&osdPrevButtonDisabledSrcCoords, 41, 106, 63, 120);
- SetRect(&osdNextButtonDisabledSrcCoords, 242, 106, 264, 120);
- SetRect(&osdPrevButtonHiliteSrcCoords, 41, 46, 63, 60);
- SetRect(&osdPlayButtonHiliteSrcCoords, 145, 43, 161, 64);
- SetRect(&osdPauseButtonHiliteSrcCoords, 95, 45, 110, 62);
- SetRect(&osdStopButtonHiliteSrcCoords, 195, 45, 210, 62);
- SetRect(&osdNextButtonHiliteSrcCoords, 242, 46, 264, 60);
- SetRect(&osdEndFSButtonHiliteSrcCoords, 41, 166, 59, 184);
- SetRect(&osdProgressSliderHiliteSrcCoords, 41, 363, 57, 381);
- SetRect(&osdVolumeSliderHiliteSrcCoords, 41, 363, 57, 381);
- xScalingFactor = 1.0f;
- yScalingFactor = 1.0f;
- for (int i = 0; i < 12; i++)
- {
- bState[i] = NORMAL;
- }
- mouseOver = NO_BUTTON;
- mouseLastOver = NO_BUTTON;
- mousePressed = NO_BUTTON;
- mouseLastPressed = NO_BUTTON;
- mouseDragging = false;
- displayTitle = NULL;
- marqueeTitleSrc = NULL;
- titleRestart = 0;
- dtFormat = 0;
- isInited = false;
- isReadyToDraw = false;
- }
- RECT IVideoD3DOSD::BuildHitRect(D3DXVECTOR3 position, RECT size)
- {
- RECT hitRect;
- // casting float to long since I know the position vector will not be too big.
- hitRect.left = (long)position.x;
- hitRect.top = (long)position.y;
- hitRect.right = (long)position.x + size.right - size.left;
- hitRect.bottom = (long)position.y + size.bottom - size.top;
- return hitRect;
- }
- IVideoD3DOSD::~IVideoD3DOSD(void)
- {
- if (osdSprite)
- {
- osdSprite->Release();
- osdSprite = NULL;
- }
- if (osdAtlasTexture)
- {
- osdAtlasTexture->Release();
- osdAtlasTexture = NULL;
- }
- if (marqueeTitleSrc)
- {
- delete [] marqueeTitleSrc;
- marqueeTitleSrc = NULL;
- }
- if (displayTitle)
- {
- delete [] displayTitle;
- displayTitle = NULL;
- }
- //if (d3dx_lib)
- //{
- // FreeLibrary(d3dx_lib);
- // d3dx_lib = NULL;
- //}
- }
- void IVideoD3DOSD::SetScalingFactor(float fx, float fy)
- {
- xScalingFactor = fx;
- yScalingFactor = fy;
- }
- void IVideoD3DOSD::CreateOSD(IDirect3DDevice9 * device)
- {
- HRESULT hr;
- d3dx_lib = FindD3DX9();
- if (!d3dx_lib)
- return;
- pCreateFontW = (D3DXCREATEFONTW) GetProcAddress(d3dx_lib,"D3DXCreateFontW");
- pCreateSprite = (D3DXCREATESPRITE) GetProcAddress(d3dx_lib,"D3DXCreateSprite");
- pCreateTextureFromResourceExW = (D3DXCREATETEXTUREFROMRESOURCEEXW) GetProcAddress(d3dx_lib,"D3DXCreateTextureFromResourceExW");
- if (!pCreateFontW || !pCreateSprite || !pCreateTextureFromResourceExW)
- return;
- hr = pCreateSprite(device,&osdSprite);
- if (FAILED(hr))
- {
- DXTraceW(__FILE__, __LINE__, hr, L"CreateSprite Error", TRUE);
- return;
- }
- int font_size = -12 ;
- hr = pCreateFontW(
- device,
- font_size,
- 0,
- FW_NORMAL,
- 1,
- 0,
- DEFAULT_CHARSET,
- OUT_DEFAULT_PRECIS,
- ANTIALIASED_QUALITY, //DEFAULT_QUALITY,
- DEFAULT_PITCH,
- L"Arial",
- &osdTimeFont);
- if (FAILED(hr))
- {
- DXTraceW(__FILE__, __LINE__, hr, L"CreateFont (Time) Error", TRUE);
- return;
- }
- font_size = -16 ;
- hr = pCreateFontW(
- device,
- font_size,
- 0,
- FW_NORMAL,
- 1,
- 0,
- DEFAULT_CHARSET,
- OUT_DEFAULT_PRECIS,
- ANTIALIASED_QUALITY,//DEFAULT_QUALITY,
- DEFAULT_PITCH,
- L"Trebuchet MS",
- &osdTitleFont);
- if (FAILED(hr))
- {
- DXTraceW(__FILE__, __LINE__, hr, L"CreateFont (Title) Error", TRUE);
- return;
- }
- ResetOSD(device);
- isInited = true;
- }
- void IVideoD3DOSD::UpdateOSD(HWND hWnd, VideoOutput *adjuster)
- {
- // Position of sprites in screen coordinates
- // Center of sprite (where the position is mapped) is left to default to upper left corner
- // Note the Bkgrnd is positioned and then all other sprites are relative to that
- RECT clientRect;
- GetClientRect(hWnd,&clientRect);
- // Need to adjust the client rect to match the video aspect ration to fit the osd on the video.
- // adjuster->adjustAspect(clientRect);
- // width of the client area - width of the bkgrnd / 2 gives the space on each side
- // add that space to the offset of the left side of the client area.
- float xPosBkg = clientRect.left +
- (((clientRect.right - clientRect.left) - (osdBkgrndTextSrcCoords.right - osdBkgrndTextSrcCoords.left))/2.0f);
- // width of the client area * .95 give the location of the bottom of the osd (i.e. 5% from bottom)
- // that minus the height of the bkgrnd gives the location of the upper left of background
- // add that space to the offset of the top of the client area.
- float yPosBkg = clientRect.top +
- (((clientRect.bottom - clientRect.top) * 1.0f) - (osdBkgrndTextSrcCoords.bottom - osdBkgrndTextSrcCoords.top));
- osdBkgrndPosition = D3DXVECTOR3(floor(xPosBkg), floor(yPosBkg), 0.0f);
- osdPrevButtonPosition = osdBkgrndPosition + D3DXVECTOR3(191.0f, 75.0f, 0.0f);
- osdPlayButtonPosition = osdBkgrndPosition + D3DXVECTOR3(246.0f, 72.0f, 0.0f);
- osdPauseButtonPosition = osdBkgrndPosition + D3DXVECTOR3(296.0f, 74.0f, 0.0f);
- osdStopButtonPosition = osdBkgrndPosition + D3DXVECTOR3(345.5f, 74.0f, 0.0f);
- osdNextButtonPosition = osdBkgrndPosition + D3DXVECTOR3(392.5f, 75.0f, 0.0f);
- osdProgressFramePosition = osdBkgrndPosition + D3DXVECTOR3(22.0f, 49.0f, 0.0f);
- osdVolumeFramePosition = osdBkgrndPosition + D3DXVECTOR3(518.0f, 76.0f, 0.0f);
- osdEndFSButtonPosition = osdBkgrndPosition + D3DXVECTOR3(583.0f, 19.0f, 0.0f);
- osdMuteButtonPosition = osdVolumeFramePosition + D3DXVECTOR3(-15.0f, -1.0f, 0.0f);
- osdProgressSliderPosition = osdProgressFramePosition + D3DXVECTOR3(0.0f, 0.0f, 0.0f);
- osdVolumeSliderPosition = osdVolumeFramePosition + D3DXVECTOR3(0.0f, 0.0f, 0.0f);
- SetRect(&osdTimeRect,
- (long)osdBkgrndPosition.x + 26,
- (long)osdBkgrndPosition.y + 76,
- (long)osdBkgrndPosition.x + 98,
- (long)osdBkgrndPosition.y + 85);
- SetRect(&osdTitleRect,
- (long)osdBkgrndPosition.x + 26,
- (long)osdBkgrndPosition.y + 17,
- (long)osdBkgrndPosition.x + 503,
- (long)osdBkgrndPosition.y + 37);
- // Create Hit Test Rects for ui elements that don't move
- osdPrevButtonHit = BuildHitRect(osdPrevButtonPosition, osdPrevButtonNormalSrcCoords );
- osdPlayButtonHit = BuildHitRect(osdPlayButtonPosition, osdPlayButtonNormalSrcCoords );
- osdPauseButtonHit = BuildHitRect(osdPauseButtonPosition, osdPauseButtonNormalSrcCoords );
- osdStopButtonHit = BuildHitRect(osdStopButtonPosition, osdStopButtonNormalSrcCoords );
- osdNextButtonHit = BuildHitRect(osdNextButtonPosition, osdNextButtonNormalSrcCoords );
- osdEndFSButtonHit = BuildHitRect(osdEndFSButtonPosition, osdEndFSButtonNormalSrcCoords);
- osdProgressFrameHit = BuildHitRect(osdProgressFramePosition, osdProgressFrameNormalSrcCoords);
- osdVolumeFrameHit = BuildHitRect(osdVolumeFramePosition, osdVolumeFrameNormalSrcCoords);
- streaming = (in_getlength() < 0) || !in_mod || !in_mod->is_seekable;
- if (streaming)
- {
- bState[PREV_BUTTON] = DISABLED;
- bState[NEXT_BUTTON] = DISABLED;
- bState[PROGRESS_FRAME] = DISABLED;
- bState[PROGRESS_SLIDER] = DISABLED;
- }
- // Find out if the title will fit in the UI space for it
- RECT tempTitleRect = osdTitleRect;
- osdTitleFont->DrawTextW(NULL, FileTitle, -1, &tempTitleRect, DT_CENTER | DT_VCENTER | DT_SINGLELINE | DT_NOCLIP | DT_CALCRECT, D3DCOLOR_XRGB(255,255,255));
- if (tempTitleRect.right <= osdTitleRect.right)
- {
- // The title fits, just use it
- titleFits = true;
- displayTitle = FileTitle;
- dtFormat = DT_LEFT | DT_VCENTER | DT_SINGLELINE | DT_NOCLIP;
- } else
- {
- // title will not fit, we need to set up a marquee.
- //
- // a string with two copies of the title makes it easier to process
- // sizeNeeded, in chars, includes one space, five dots,
- // one space and 1 extra for null.
- size_t sizeNeeded = (lstrlenW(FileTitle)*2) + 8;
- marqueeTitleSrc = new wchar_t[sizeNeeded];
- displayTitle = new wchar_t[sizeNeeded];
- titleRestart = lstrlenW(FileTitle);
- StringCchPrintfW(marqueeTitleSrc, sizeNeeded, L"%s ..... %s", FileTitle, FileTitle);
- titleFits = false;
- dtFormat = DT_RIGHT | DT_TOP | DT_SINGLELINE;
- }
- isReadyToDraw = true;
- }
- #ifdef _DEBUG
- #define DRAW_OSD_SET_ERROR(x) draw_osd_error=x
- #else
- #define DRAW_OSD_SET_ERROR(x)
- #endif
- void IVideoD3DOSD::DrawOSD(IDirect3DDevice9 * device)
- {
- HRESULT hr;
- D3DXVECTOR3 sliderCenter(8.0f, 8.0f, 0.0f);
- const wchar_t *draw_osd_error;
- hr = osdSprite->Begin(D3DXSPRITE_ALPHABLEND);
- if (FAILED(hr))
- {
- DXTraceW(__FILE__, __LINE__, hr, L"Sprite Begin Error", TRUE);
- return ;
- }
- // Doing Scaling of sprites here
- // If we do translations and/or rotations we'll have to do a more
- // robust hit test (picking) since the current one assumes a rectangular
- // shape based on screen coordinates. Only scaling is currently handled
- // in the hit test.
- //D3DXMATRIX scalingMatrix;
- //osdSprite->SetTransform(D3DXMatrixScaling(&scalingMatrix, 1.0f /*xScalingFactor*/, 1.0f /*yScalingFactor*/, 0.0f));
- hr = osdSprite->Draw(osdAtlasTexture, &osdBkgrndTextSrcCoords, NULL, &osdBkgrndPosition, D3DCOLOR_XRGB(255,255,255));
- if (FAILED(hr))
- {
- DRAW_OSD_SET_ERROR(L"Background Sprite Draw Error");
- goto DrawOSD_Error;
- }
- hr = osdSprite->Draw(osdAtlasTexture, GetTextCoords(PREV_BUTTON), NULL, &osdPrevButtonPosition, D3DCOLOR_XRGB(255,255,255));
- if (FAILED(hr))
- {
- DRAW_OSD_SET_ERROR(L"Prev Button Sprite Draw Error");
- goto DrawOSD_Error;
- }
- hr = osdSprite->Draw(osdAtlasTexture, GetTextCoords(PLAY_BUTTON), NULL, &osdPlayButtonPosition, D3DCOLOR_XRGB(255,255,255));
- if (FAILED(hr))
- {
- DRAW_OSD_SET_ERROR(L"Play Button Sprite Draw Error");
- goto DrawOSD_Error;
- }
- hr = osdSprite->Draw(osdAtlasTexture, GetTextCoords(PAUSE_BUTTON), NULL, &osdPauseButtonPosition, D3DCOLOR_XRGB(255,255,255));
- if (FAILED(hr))
- {
- DRAW_OSD_SET_ERROR(L"Pause Button Sprite Draw Error");
- goto DrawOSD_Error;
- }
- hr = osdSprite->Draw(osdAtlasTexture, GetTextCoords(STOP_BUTTON), NULL, &osdStopButtonPosition, D3DCOLOR_XRGB(255,255,255));
- if (FAILED(hr))
- {
- DRAW_OSD_SET_ERROR(L"Stop Button Sprite Draw Error");
- goto DrawOSD_Error;
- }
- hr = osdSprite->Draw(osdAtlasTexture, GetTextCoords(NEXT_BUTTON), NULL, &osdNextButtonPosition, D3DCOLOR_XRGB(255,255,255));
- if (FAILED(hr))
- {
- DRAW_OSD_SET_ERROR(L"Next Button Sprite Draw Error");
- goto DrawOSD_Error;
- }
- hr = osdSprite->Draw(osdAtlasTexture, GetTextCoords(PROGRESS_FRAME), NULL, &osdProgressFramePosition, D3DCOLOR_XRGB(255,255,255));
- if (FAILED(hr))
- {
- DRAW_OSD_SET_ERROR(L"Progress Frame Sprite Draw Error");
- goto DrawOSD_Error;
- }
- hr = osdSprite->Draw(osdAtlasTexture, GetTextCoords(VOLUME_FRAME), NULL, &osdVolumeFramePosition, D3DCOLOR_XRGB(255,255,255));
- if (FAILED(hr))
- {
- DRAW_OSD_SET_ERROR(L"Volume Frame Sprite Draw Error");
- goto DrawOSD_Error;
- }
- hr = osdSprite->Draw(osdAtlasTexture, GetTextCoords(ENDFS_BUTTON), NULL, &osdEndFSButtonPosition, D3DCOLOR_XRGB(255,255,255));
- if (FAILED(hr))
- {
- DRAW_OSD_SET_ERROR(L"EndFS Button Sprite Draw Error");
- goto DrawOSD_Error;
- }
- hr = osdSprite->Draw(osdAtlasTexture, GetTextCoords(MUTE_BUTTON), NULL, &osdMuteButtonPosition, D3DCOLOR_XRGB(255,255,255));
- if (FAILED(hr))
- {
- DRAW_OSD_SET_ERROR(L"Mute Button Sprite Draw Error");
- goto DrawOSD_Error;
- }
- if (playing && !streaming && !mouseDragging) // if mouseDragging we may be repositioning the slider, don't set it back till Lmouseup
- {
- // calculate the relative position of the slider
- float ppercent = (in_getouttime() / 1000.0f) / in_getlength();
- float sizeOfProgFrame = (float)osdProgressFrameHit.right - osdProgressFrameHit.left - 0;
- // position the progress slider
- osdProgressSliderPosition.x = osdProgressFramePosition.x + (sizeOfProgFrame * ppercent);
- // Now build the hit rect based on the new position.
- osdProgressSliderHit = BuildHitRect(osdProgressSliderPosition + D3DXVECTOR3(0.0f,0.0f,0.0f), osdProgressSliderNormalSrcCoords);
- }
- hr = osdSprite->Draw(osdAtlasTexture, GetTextCoords(PROGRESS_SLIDER), &sliderCenter, &osdProgressSliderPosition, D3DCOLOR_XRGB(255,255,255));
- if (FAILED(hr))
- {
- DRAW_OSD_SET_ERROR(L"Progress Slider Sprite Draw Error");
- goto DrawOSD_Error;
- }
- // Build the progress hilite line by drawing only a certain amount (width) of the texture.
- RECT seekProgress;
- // The progress hilite line goes on top of progress frame
- seekProgress = osdProgressProgressSrcCoords;
- // The width of the progress hilite line is determined by the location of the slider
- seekProgress.right = seekProgress.left + (osdProgressSliderHit.left - osdProgressFrameHit.left + 0);
- hr = osdSprite->Draw(osdAtlasTexture,
- &seekProgress,
- NULL,
- &osdProgressFramePosition,
- D3DCOLOR_XRGB(255,255,255));
- if (FAILED(hr))
- {
- DRAW_OSD_SET_ERROR(L"Seek Progress Sprite Draw Error");
- goto DrawOSD_Error;
- }
- if (!mouseDragging) // if mouseDragging we may be repositioning the slider, don't set it back till Lmouseup
- {
- // calculate the relative position of the slider
- float vpercent = config_volume / 255.0f;
- float sizeOfVolFrame = (float)osdVolumeFrameHit.right - osdVolumeFrameHit.left - 0;
- // position the volume slider
- osdVolumeSliderPosition.x = (osdVolumeFramePosition.x) + (sizeOfVolFrame * vpercent);
- // Now build the hit rect based on the new position.
- osdVolumeSliderHit = BuildHitRect(osdVolumeSliderPosition + D3DXVECTOR3(0.0f,0.0f,0.0f), osdVolumeSliderNormalSrcCoords);
- }
- hr = osdSprite->Draw(osdAtlasTexture, GetTextCoords(VOLUME_SLIDER), &sliderCenter, &osdVolumeSliderPosition, D3DCOLOR_XRGB(255,255,255));
- if (FAILED(hr))
- {
- DRAW_OSD_SET_ERROR(L"Volume SLider Sprite Draw Error");
- goto DrawOSD_Error;
- }
- // Build the volume hilite line by drawing only a certain amount (width) of the texture.
- RECT volProgress;
- // The volume hilite line goes on top of volume frame
- volProgress = osdVolumeProgressSrcCoords;
- // The width of the volume hilite line is determined by the location of the slider
- volProgress.right = volProgress.left + (osdVolumeSliderHit.left - osdVolumeFrameHit.left + 0);
- hr = osdSprite->Draw(osdAtlasTexture,
- &volProgress,
- NULL,
- &osdVolumeFramePosition,
- D3DCOLOR_XRGB(255,255,255));
- if (FAILED(hr))
- {
- DRAW_OSD_SET_ERROR(L"Volume Progress Sprite Draw Error");
- goto DrawOSD_Error;
- }
- if (osdTimeFont)
- {
- int seconds_in = in_getouttime() / 1000;
- int time_to_go = in_getlength();
- wchar_t timerText[256] = {0};
- if (streaming)
- StringCbPrintfW(timerText,sizeof(timerText),L"%.2u:%.2u",seconds_in /60,seconds_in % 60);
- else
- StringCbPrintfW(timerText,sizeof(timerText),L"%.2u:%.2u / %.2u:%.2u",seconds_in /60,seconds_in % 60,time_to_go / 60, time_to_go % 60);
- osdTimeFont->DrawTextW(osdSprite, timerText, -1, &osdTimeRect, DT_LEFT | DT_VCENTER | DT_SINGLELINE | DT_NOCLIP, D3DCOLOR_XRGB(163,164,167)); // #A3A4A7
- }
- if (osdTitleFont)
- {
- // found possibility that user can pause in full screen and remove items from playlist
- // This prevents a crash by not trying to display a title.
- if (lstrlenW(FileTitle) > 0)
- {
- if (!titleFits)
- {
- // title does not fit, build marquee
- DWORD now = GetTickCount();
- static DWORD then;
- if (now - then > 250) // slow it down so people can read it.
- {
- static int charCount = 2; // start with the first char + 1 for null
- lstrcpynW(displayTitle,marqueeTitleSrc,charCount);
- charCount++;
- if (charCount > lstrlenW(marqueeTitleSrc))
- charCount = lstrlenW(FileTitle);
- then = now;
- }
- }
- osdTitleFont->DrawTextW(osdSprite, displayTitle, -1, &osdTitleRect, dtFormat, D3DCOLOR_XRGB(204,204,204)); // #cccccc
- }
- }
- hr = osdSprite->End();
- if (FAILED(hr))
- {
- DXTraceW(__FILE__, __LINE__, hr, L"Sprite End Error", TRUE);
- return;
- }
- return;
- DrawOSD_Error:
- DXTraceW(__FILE__, __LINE__, hr, draw_osd_error, TRUE);
- osdSprite->End();
- }
- RECT *IVideoD3DOSD::GetTextCoords(UI_ELEM item)
- {
- switch (item)
- {
- case PREV_BUTTON :
- switch (bState[item])
- {
- case NORMAL :
- return &osdPrevButtonNormalSrcCoords;
- break;
- case CLICKED :
- return &osdPrevButtonClickSrcCoords;
- break;
- case HILITE :
- return &osdPrevButtonHiliteSrcCoords;
- break;
- case DISABLED :
- return &osdPrevButtonDisabledSrcCoords;
- break;
- }
- break;
- case PLAY_BUTTON :
- switch (bState[item])
- {
- case NORMAL :
- case DISABLED :
- return &osdPlayButtonNormalSrcCoords;
- break;
- case CLICKED :
- return &osdPlayButtonClickSrcCoords;
- break;
- case HILITE :
- return &osdPlayButtonHiliteSrcCoords;
- break;
- }
- break;
- case PAUSE_BUTTON :
- switch (bState[item])
- {
- case NORMAL :
- case DISABLED :
- return &osdPauseButtonNormalSrcCoords;
- break;
- case CLICKED :
- return &osdPauseButtonClickSrcCoords;
- break;
- case HILITE :
- return &osdPauseButtonHiliteSrcCoords;
- break;
- }
- break;
- case STOP_BUTTON :
- switch (bState[item])
- {
- case NORMAL :
- case DISABLED :
- return &osdStopButtonNormalSrcCoords;
- break;
- case CLICKED :
- return &osdStopButtonClickSrcCoords;
- break;
- case HILITE :
- return &osdStopButtonHiliteSrcCoords;
- break;
- }
- break;
- case NEXT_BUTTON :
- switch (bState[item])
- {
- case NORMAL :
- return &osdNextButtonNormalSrcCoords;
- break;
- case CLICKED :
- return &osdNextButtonClickSrcCoords;
- break;
- case HILITE :
- return &osdNextButtonHiliteSrcCoords;
- break;
- case DISABLED :
- return &osdNextButtonDisabledSrcCoords;
- break;
- }
- break;
- case ENDFS_BUTTON :
- switch (bState[item])
- {
- case NORMAL :
- case DISABLED :
- return &osdEndFSButtonNormalSrcCoords;
- break;
- case CLICKED :
- return &osdEndFSButtonClickSrcCoords;
- break;
- case HILITE :
- return &osdEndFSButtonHiliteSrcCoords;
- break;
- }
- break;
- case MUTE_BUTTON :
- return &osdMuteButtonNormalSrcCoords;
- //switch (bState[item])
- //{
- //case NORMAL :
- //case DISABLED :
- // return &osdMuteButtonNormalSrcCoords;
- // break;
- //case CLICKED :
- // return &osdMuteButtonClickSrcCoords;
- // break;
- //case HILITE :
- // return &osdMuteButtonHiliteSrcCoords;
- // break;
- //}
- break;
- case PROGRESS_FRAME :
- return &osdProgressFrameNormalSrcCoords;
- break;
- case VOLUME_FRAME :
- return &osdVolumeFrameNormalSrcCoords;
- break;
- case PROGRESS_SLIDER :
- switch (bState[item])
- {
- case NORMAL :
- case DISABLED :
- return &osdProgressSliderNormalSrcCoords;
- break;
- case CLICKED :
- return &osdProgressSliderClickSrcCoords;
- break;
- case HILITE :
- return &osdProgressSliderHiliteSrcCoords;
- break;
- }
- break;
- case VOLUME_SLIDER :
- switch (bState[item])
- {
- case NORMAL :
- case DISABLED :
- return &osdVolumeSliderNormalSrcCoords;
- break;
- case CLICKED :
- return &osdVolumeSliderClickSrcCoords;
- break;
- case HILITE :
- return &osdVolumeSliderHiliteSrcCoords;
- break;
- }
- break;
- }
- return NULL;
- }
- void IVideoD3DOSD::LostOSD()
- {
- if (osdSprite)
- osdSprite->OnLostDevice();
- if (osdTimeFont)
- osdTimeFont->OnLostDevice();
- if (osdTitleFont)
- osdTitleFont->OnLostDevice();
- if (osdAtlasTexture)
- {
- osdAtlasTexture->Release();
- osdAtlasTexture = 0;
- }
- }
- void IVideoD3DOSD::ResetOSD(IDirect3DDevice9 * device)
- {
- if (osdSprite)
- osdSprite->OnResetDevice();
- if (osdTimeFont)
- osdTimeFont->OnResetDevice();
- if (osdTitleFont)
- osdTitleFont->OnResetDevice();
- if (device)
- {
- HRESULT hr;
- hr = pCreateTextureFromResourceExW(
- device,
- NULL, // HMODULE
- MAKEINTRESOURCEW(IDB_OSD), // Our texture image atlas
- D3DX_DEFAULT, // width
- D3DX_DEFAULT, // height
- 1, // MIP levels
- 0, // usage
- D3DFMT_UNKNOWN, // get format from file
- D3DPOOL_DEFAULT, // mem pool
- D3DX_DEFAULT, // filter
- D3DX_DEFAULT, // MIP filter
- 0, // transparent color key
- NULL, // image info struct
- NULL, // palette
- &osdAtlasTexture); // the returned texture, if success
- if (FAILED(hr))
- {
- DXTraceW(__FILE__, __LINE__, hr, L"CreateTextureFromFileEx Error", TRUE);
- return;
- }
- }
- }
- bool IVideoD3DOSD::MouseDown(int xpt, int ypt, WPARAM wParam)
- {
- Show();
- // mouseLastPressed is used during mouse up to verify that the up is on the
- // same UI element as the mouse down.
- mouseLastPressed = HitTest((float)xpt, (float)ypt);
- bState[mouseLastPressed] = CLICKED;
- return false;
- }
- bool IVideoD3DOSD::MouseMove(int ixpt, int iypt, WPARAM wParam)
- {
- static int saved_ixpt;
- static int saved_iypt;
- // Need to check whether the mouse cursor is still in the same place.
- // Evidently, WM_MOUSEMOVE can get triggered for other reasons than
- // actually moving the mouse, per Microsoft blogs
- // This code was triggering with IM and EMAIL notifications without
- // moving the mouse.
- if (ixpt == saved_ixpt && iypt == saved_iypt)
- return false;
- saved_ixpt = ixpt;
- saved_iypt = iypt;
- Show();
- // Change input ints to floats so later calculations are more precise.
- float xpt = (float)ixpt;
- float ypt = (float)iypt;
- mouseOver = HitTest((float)xpt, (float)ypt);
- if (wParam & MK_LBUTTON) //dragging
- {
- mouseDragging = true;
- if (mouseLastPressed == VOLUME_SLIDER)
- {
- if (xpt < (osdVolumeFrameHit.left)) xpt = (float) osdVolumeFrameHit.left;
- else if (xpt > (osdVolumeFrameHit.right) - 0) xpt = (float) osdVolumeFrameHit.right - 0;
- //move the volume slider
- osdVolumeSliderPosition.x = xpt;
- // slider uses center as center
- osdVolumeSliderHit = BuildHitRect(osdVolumeSliderPosition + D3DXVECTOR3(0.0f,0.0f,0.0f),osdVolumeSliderNormalSrcCoords);
- }
- else if (mouseLastPressed == PROGRESS_SLIDER)
- {
- if (xpt < osdProgressFrameHit.left) xpt = (float)osdProgressFrameHit.left;
- else if (xpt > (osdProgressFrameHit.right)) xpt = (float)osdProgressFrameHit.right;
- //move the progress slider
- osdProgressSliderPosition.x = xpt;
- osdProgressSliderHit = BuildHitRect(osdProgressSliderPosition + D3DXVECTOR3(0.0f,0.0f,0.0f),osdProgressSliderNormalSrcCoords);
- }
- } else // no click, just mousemove
- {
- mouseDragging = false;
- if (mouseLastOver != mouseOver)
- {
- if (bState[mouseLastOver] == HILITE)
- bState[mouseLastOver] = NORMAL;
- if (bState[mouseOver] == NORMAL)
- bState[mouseOver] = HILITE;
- mouseLastOver = mouseOver;
- }
- }
- return false;
- }
- bool IVideoD3DOSD::MouseUp(int xpt, int ypt, WPARAM wParam)
- {
- mousePressed = HitTest((float)xpt, (float)ypt);
- bState[mouseLastPressed] = NORMAL;
- if (bState[mousePressed] == HILITE)
- bState[mousePressed] = NORMAL;
- mouseDragging = false;
- switch (mousePressed)
- {
- case ENDFS_BUTTON :
- if (mouseLastPressed == ENDFS_BUTTON)
- return true; // end full screen
- break;
- case PREV_BUTTON :
- if (mouseLastPressed == PREV_BUTTON)
- PostMessageW(hMainWindow, WM_COMMAND, WINAMP_BUTTON1, 0);
- break;
- case PLAY_BUTTON :
- if (mouseLastPressed == PLAY_BUTTON)
- PostMessageW(hMainWindow, WM_COMMAND, WINAMP_BUTTON2, 0);
- break;
- case PAUSE_BUTTON :
- if (mouseLastPressed == PAUSE_BUTTON)
- PostMessageW(hMainWindow, WM_COMMAND, WINAMP_BUTTON3, 0);
- break;
- case STOP_BUTTON :
- if (mouseLastPressed == STOP_BUTTON)
- PostMessageW(hMainWindow, WM_COMMAND, WINAMP_BUTTON4, 0);
- break;
- case NEXT_BUTTON :
- if (mouseLastPressed == NEXT_BUTTON)
- PostMessageW(hMainWindow, WM_COMMAND, WINAMP_BUTTON5, 0);
- break;
- default :
- {
- // If not a button, check the sliders
- // The successful use of the sliders should not depend on
- // releasing the mouse inside the frame, which may be very small.
- switch (mouseLastPressed)
- {
- case PROGRESS_SLIDER :
- case PROGRESS_FRAME :
- {
- float xIntoFrame = (float)xpt - osdProgressFrameHit.left;
- // -8 is half the width of the slider
- float rightMaxOfFrame = (float)osdProgressFrameHit.right - 0;
- float leftMinOfFrame = (float)osdProgressFrameHit.left;
- float sizeOfFrame = rightMaxOfFrame - leftMinOfFrame;
- float t = xIntoFrame / sizeOfFrame;
- if (t < 0)
- t = 0;
- if (t > 1)
- t = 1;
- int len = in_getlength();
- in_seek((int)(t*len*1000));
- }
- break;
- case VOLUME_SLIDER :
- case VOLUME_FRAME :
- {
- float xIntoFrame = (float)xpt - (osdVolumeFrameHit.left);
- // -8 is half the width of the slider
- float rightMaxOfFrame = (float)osdVolumeFrameHit.right - 0;
- float leftMinOfFrame = (float)osdVolumeFrameHit.left;
- float sizeOfFrame = rightMaxOfFrame - leftMinOfFrame;
- float t = xIntoFrame / sizeOfFrame;
- if (t < 0)
- t = 0;
- if (t > 1)
- t = 1;
- unsigned char v = (unsigned char)(t * 255);
- config_volume = v;
- in_setvol(v);
- }
- break;
- }
- }
- break;
- }
- mouseLastPressed = NO_BUTTON;
- return false;
- }
- IVideoD3DOSD::UI_ELEM IVideoD3DOSD::HitTest(float xpt, float ypt)
- {
- if (PointInRect(xpt, ypt, osdPrevButtonHit))
- return PREV_BUTTON;
- else if (PointInRect(xpt, ypt, osdPlayButtonHit))
- return PLAY_BUTTON;
- else if (PointInRect(xpt, ypt, osdPauseButtonHit))
- return PAUSE_BUTTON;
- else if (PointInRect(xpt, ypt, osdStopButtonHit))
- return STOP_BUTTON;
- else if (PointInRect(xpt, ypt, osdNextButtonHit))
- return NEXT_BUTTON;
- else if (PointInRect(xpt, ypt, osdEndFSButtonHit))
- return ENDFS_BUTTON;
- else if (PointInRect(xpt, ypt, osdVolumeSliderHit))
- return VOLUME_SLIDER;
- else if (PointInRect(xpt, ypt, osdProgressSliderHit))
- return PROGRESS_SLIDER;
- else if (PointInRect(xpt, ypt, osdProgressFrameHit))
- return PROGRESS_FRAME;
- else if (PointInRect(xpt, ypt, osdVolumeFrameHit))
- return VOLUME_FRAME;
- else
- return NO_BUTTON;
- }
- bool IVideoD3DOSD::PointInRect(float x, float y, RECT testRect)
- {
- if ((x >= testRect.left) && (x <= testRect.right) &&
- (y >= testRect.top) && (y <= testRect.bottom))
- return true;
- else
- return false;
- }
|