Rev 883 | Details | Compare with Previous | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
716 | lvd | 1 | #include "std.h" |
2 | |||
3 | #include "emul.h" |
||
4 | #include "vars.h" |
||
5 | #include "dx.h" |
||
6 | #include "dxovr.h" |
||
7 | #include "dxerr.h" |
||
8 | #include "init.h" |
||
9 | |||
784 | DimkaM | 10 | static DWORD colorkey=-1U; |
716 | lvd | 11 | |
12 | void update_overlay() |
||
13 | { |
||
14 | |||
15 | RECT rc_src, rc_dst; |
||
16 | |||
17 | GetClientRect(wnd, &rc_dst); |
||
18 | ClientToScreen(wnd, (POINT*)&rc_dst.left); |
||
19 | ClientToScreen(wnd, (POINT*)&rc_dst.right); |
||
20 | |||
21 | if (rc_dst.left == rc_dst.right || rc_dst.top == rc_dst.bottom) return; |
||
22 | |||
23 | rc_src.left = rc_src.top = 0; |
||
784 | DimkaM | 24 | rc_src.right = LONG(temp.ox); |
25 | rc_src.bottom = LONG(temp.oy); |
||
716 | lvd | 26 | |
27 | if (wnd == GetForegroundWindow() && rc_dst.left >= 0 && rc_dst.top >= 0) |
||
28 | { |
||
29 | DDSURFACEDESC desc; desc.dwSize = sizeof desc; |
||
30 | if (sprim->IsLost() == DDERR_SURFACELOST) |
||
31 | sprim->Restore(); |
||
784 | DimkaM | 32 | HRESULT r = sprim->Lock(nullptr, &desc, DDLOCK_SURFACEMEMORYPTR | DDLOCK_WAIT | DDLOCK_READONLY, nullptr); |
716 | lvd | 33 | if (r != DD_OK) { printrdd("IDirectDrawSurface2::Lock() [test]", r); exit(); } |
784 | DimkaM | 34 | char *ptr = (char*)desc.lpSurface + rc_dst.top*desc.lPitch + rc_dst.left*LONG(desc.ddpfPixelFormat.dwRGBBitCount)/8; |
716 | lvd | 35 | colorkey = *(unsigned*)ptr; |
784 | DimkaM | 36 | sprim->Unlock(nullptr); |
716 | lvd | 37 | if (desc.ddpfPixelFormat.dwRGBBitCount < 32) |
38 | colorkey &= (1<<desc.ddpfPixelFormat.dwRGBBitCount)-1; |
||
39 | } |
||
40 | |||
41 | // use min and max stretch |
||
784 | DimkaM | 42 | DDCAPS caps; |
43 | caps.dwSize = sizeof caps; |
||
44 | dd->GetCaps(&caps,nullptr); |
||
45 | if ((rc_dst.right - rc_dst.left)*1000/int(temp.ox) > (int)caps.dwMaxOverlayStretch) |
||
46 | rc_dst.right = rc_dst.left + LONG(temp.ox*caps.dwMaxOverlayStretch/1000); |
||
47 | if ((rc_dst.bottom - rc_dst.top)*1000/int(temp.oy) > (int)caps.dwMaxOverlayStretch) |
||
48 | rc_dst.bottom = rc_dst.top + LONG(temp.oy*caps.dwMaxOverlayStretch/1000); |
||
49 | if ((rc_dst.right - rc_dst.left)*1000/int(temp.ox) < (int)caps.dwMinOverlayStretch) |
||
50 | rc_dst.right = rc_dst.left + LONG(temp.ox*caps.dwMinOverlayStretch/1000); |
||
51 | if ((rc_dst.bottom - rc_dst.top)*1000/int(temp.oy) < (int)caps.dwMinOverlayStretch) |
||
52 | rc_dst.bottom = rc_dst.top + LONG(temp.oy*caps.dwMinOverlayStretch/1000); |
||
716 | lvd | 53 | |
54 | // setup boundaries for non-clipping overlay |
||
55 | int mx = GetSystemMetrics(SM_CXSCREEN), my = GetSystemMetrics(SM_CYSCREEN); |
||
784 | DimkaM | 56 | if(rc_dst.left < 0) |
57 | { |
||
58 | rc_src.left = -rc_dst.left * (rc_src.right - rc_src.left) / (rc_dst.right - rc_dst.left); |
||
59 | rc_dst.left = 0; |
||
60 | } |
||
61 | if(rc_dst.top < 0) |
||
62 | { |
||
63 | rc_src.top = -rc_dst.top * (rc_src.bottom - rc_src.top) / (rc_dst.bottom - rc_dst.top); |
||
64 | rc_dst.top = 0; |
||
65 | } |
||
66 | if(rc_dst.right > mx) |
||
67 | { |
||
68 | rc_src.right = rc_src.left + (mx - rc_dst.left) * (rc_src.right - rc_src.left) / (rc_dst.right - rc_dst.left); |
||
69 | rc_dst.right = mx; |
||
70 | } |
||
71 | if(rc_dst.bottom > my) |
||
72 | { |
||
73 | rc_src.bottom = (my - rc_dst.top) * (rc_src.bottom - rc_src.top) / (rc_dst.bottom - rc_dst.top); |
||
74 | rc_dst.bottom = my; |
||
75 | } |
||
716 | lvd | 76 | |
784 | DimkaM | 77 | if (colorkey==-1U) return; |
716 | lvd | 78 | if (rc_dst.left >= rc_dst.right || rc_dst.top >= rc_dst.bottom) return; |
79 | if (rc_src.left >= rc_src.right || rc_src.top >= rc_src.bottom) return; |
||
80 | |||
81 | DDOVERLAYFX fx = { sizeof fx }; |
||
82 | fx.dckDestColorkey.dwColorSpaceLowValue = fx.dckDestColorkey.dwColorSpaceHighValue = colorkey; |
||
83 | |||
84 | for (;;) { |
||
85 | HRESULT r = surf0->UpdateOverlay(&rc_src, sprim, &rc_dst, DDOVER_SHOW | DDOVER_DDFX | DDOVER_KEYDESTOVERRIDE, &fx); |
||
86 | if (r == DD_OK) break; |
||
87 | if (r == DDERR_SURFACELOST) { |
||
88 | if (surf0->Restore() != DD_OK) set_vidmode(); // recreate overlay |
||
89 | break; // another update_overlay in set_vidmode() -> UpdateWindow() |
||
90 | } |
||
91 | printrdd("IDirectDrawSurface2::UpdateOverlay()", r); exit(); |
||
92 | } |
||
93 | } |