diff options
Diffstat (limited to 'uisimulator/sdl/uisw32.c')
-rw-r--r-- | uisimulator/sdl/uisw32.c | 344 |
1 files changed, 344 insertions, 0 deletions
diff --git a/uisimulator/sdl/uisw32.c b/uisimulator/sdl/uisw32.c new file mode 100644 index 0000000000..1b4dbbd410 --- /dev/null +++ b/uisimulator/sdl/uisw32.c | |||
@@ -0,0 +1,344 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * $Id$ | ||
9 | * | ||
10 | * Copyright (C) 2002 by Felix Arends | ||
11 | * | ||
12 | * All files in this archive are subject to the GNU General Public License. | ||
13 | * See the file COPYING in the source tree root for full license agreement. | ||
14 | * | ||
15 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY | ||
16 | * KIND, either express or implied. | ||
17 | * | ||
18 | ****************************************************************************/ | ||
19 | |||
20 | #include <windows.h> | ||
21 | #include <process.h> | ||
22 | #include <stdlib.h> | ||
23 | #include <fcntl.h> | ||
24 | #include "autoconf.h" | ||
25 | #include "uisw32.h" | ||
26 | #include "resource.h" | ||
27 | #include "button.h" | ||
28 | #include "thread.h" | ||
29 | #include "thread-win32.h" | ||
30 | #include "kernel.h" | ||
31 | #include "sound.h" | ||
32 | |||
33 | #ifndef LR_VGACOLOR /* Should be under MINGW32 builds? */ | ||
34 | #define LR_VGACOLOR LR_COLOR | ||
35 | #endif | ||
36 | |||
37 | // extern functions | ||
38 | extern void app_main (void *); // mod entry point | ||
39 | extern void new_key(int key); | ||
40 | extern void sim_tick_tasks(void); | ||
41 | |||
42 | void button_event(int key, bool pressed); | ||
43 | |||
44 | // variables | ||
45 | HWND hGUIWnd; // the GUI window handle | ||
46 | unsigned int uThreadID; // id of mod thread | ||
47 | PBYTE lpKeys; | ||
48 | bool bActive; // window active? | ||
49 | HANDLE hGUIThread; // thread for GUI | ||
50 | #ifdef ROCKBOX_HAS_SIMSOUND | ||
51 | HANDLE hSoundThread; // thread for sound | ||
52 | #endif | ||
53 | bool bIsWinNT; // Windows NT derivate? | ||
54 | |||
55 | bool lcd_display_redraw=true; // Used for player simulator | ||
56 | char having_new_lcd=true; // Used for player simulator | ||
57 | |||
58 | // GUIWndProc | ||
59 | // window proc for GUI simulator | ||
60 | LRESULT CALLBACK GUIWndProc ( | ||
61 | HWND hWnd, | ||
62 | UINT uMsg, | ||
63 | WPARAM wParam, | ||
64 | LPARAM lParam | ||
65 | ) | ||
66 | { | ||
67 | static HBITMAP hBkgnd; | ||
68 | static HDC hMemDc; | ||
69 | |||
70 | static LARGE_INTEGER persec, tick1, ticknow; | ||
71 | long new_tick; | ||
72 | |||
73 | switch (uMsg) | ||
74 | { | ||
75 | case WM_TIMER: | ||
76 | QueryPerformanceCounter(&ticknow); | ||
77 | new_tick = ((ticknow.QuadPart-tick1.QuadPart)*HZ)/persec.QuadPart; | ||
78 | if (new_tick != current_tick) | ||
79 | { | ||
80 | long i; | ||
81 | for (i = new_tick - current_tick; i > 0; i--) | ||
82 | sim_tick_tasks(); | ||
83 | current_tick = new_tick; | ||
84 | } | ||
85 | return TRUE; | ||
86 | case WM_ACTIVATE: | ||
87 | if (LOWORD(wParam) == WA_ACTIVE || LOWORD(wParam) == WA_CLICKACTIVE) | ||
88 | bActive = true; | ||
89 | else | ||
90 | bActive = false; | ||
91 | return TRUE; | ||
92 | case WM_CREATE: | ||
93 | QueryPerformanceFrequency(&persec); | ||
94 | QueryPerformanceCounter(&tick1); | ||
95 | SetTimer (hWnd, TIMER_EVENT, 1, NULL); | ||
96 | |||
97 | // load background image | ||
98 | hBkgnd = (HBITMAP)LoadImage (GetModuleHandle (NULL), | ||
99 | MAKEINTRESOURCE(IDB_UI), IMAGE_BITMAP, 0, 0, LR_VGACOLOR); | ||
100 | hMemDc = CreateCompatibleDC (GetDC (hWnd)); | ||
101 | SelectObject (hMemDc, hBkgnd); | ||
102 | return TRUE; | ||
103 | case WM_SIZING: | ||
104 | { | ||
105 | LPRECT r = (LPRECT)lParam; | ||
106 | char s[256]; | ||
107 | int v; | ||
108 | int h_add = GetSystemMetrics (SM_CXSIZEFRAME) * 2 + 4; | ||
109 | int v_add = GetSystemMetrics (SM_CYSIZEFRAME) * 2 | ||
110 | + GetSystemMetrics (SM_CYCAPTION) + 4; | ||
111 | |||
112 | switch (wParam) | ||
113 | { | ||
114 | case WMSZ_BOTTOM: | ||
115 | v = (r->bottom - r->top) / (UI_HEIGHT / 5); | ||
116 | r->bottom = r->top + v * UI_HEIGHT / 5 + v_add; | ||
117 | r->right = r->left + v * UI_WIDTH / 5 + h_add; | ||
118 | break; | ||
119 | case WMSZ_RIGHT: | ||
120 | v = (r->right - r->left) / (UI_WIDTH / 5); | ||
121 | r->bottom = r->top + v * UI_HEIGHT / 5 + v_add; | ||
122 | r->right = r->left + v * UI_WIDTH / 5 + h_add; | ||
123 | break; | ||
124 | case WMSZ_TOP: | ||
125 | v = (r->bottom - r->top) / (UI_HEIGHT / 5); | ||
126 | r->top = r->bottom - v * UI_HEIGHT / 5 - v_add; | ||
127 | r->right = r->left + v * UI_WIDTH / 5 + h_add; | ||
128 | break; | ||
129 | case WMSZ_LEFT: | ||
130 | v = (r->right - r->left) / (UI_WIDTH / 5); | ||
131 | r->bottom = r->top + v * UI_HEIGHT / 5 + v_add; | ||
132 | r->left = r->right - v * UI_WIDTH / 5 - h_add; | ||
133 | break; | ||
134 | case WMSZ_BOTTOMRIGHT: | ||
135 | v = ((r->right - r->left) * UI_HEIGHT | ||
136 | +(r->bottom - r->top) * UI_WIDTH) | ||
137 | / (2 * UI_WIDTH * UI_HEIGHT / 5); | ||
138 | r->bottom = r->top + v * UI_HEIGHT / 5 + v_add; | ||
139 | r->right = r->left + v * UI_WIDTH / 5 + h_add; | ||
140 | break; | ||
141 | case WMSZ_BOTTOMLEFT: | ||
142 | v = ((r->right - r->left) * UI_HEIGHT | ||
143 | +(r->bottom - r->top) * UI_WIDTH) | ||
144 | / (2 * UI_WIDTH * UI_HEIGHT / 5); | ||
145 | r->bottom = r->top + v * UI_HEIGHT / 5 + v_add; | ||
146 | r->left = r->right - v * UI_WIDTH / 5 - h_add; | ||
147 | break; | ||
148 | case WMSZ_TOPRIGHT: | ||
149 | v = ((r->right - r->left) * UI_HEIGHT | ||
150 | +(r->bottom - r->top) * UI_WIDTH) | ||
151 | / (2 * UI_WIDTH * UI_HEIGHT / 5); | ||
152 | r->top = r->bottom - v * UI_HEIGHT / 5 - v_add; | ||
153 | r->right = r->left + v * UI_WIDTH / 5 + h_add; | ||
154 | break; | ||
155 | case WMSZ_TOPLEFT: | ||
156 | v = ((r->right - r->left) * UI_HEIGHT | ||
157 | +(r->bottom - r->top) * UI_WIDTH) | ||
158 | / (2 * UI_WIDTH * UI_HEIGHT / 5); | ||
159 | r->top = r->bottom - v * UI_HEIGHT / 5 - v_add; | ||
160 | r->left = r->right - v * UI_WIDTH / 5 - h_add; | ||
161 | break; | ||
162 | } | ||
163 | |||
164 | wsprintf (s, UI_TITLE " @%d%%", | ||
165 | (r->right - r->left - h_add + 1) * 100 / UI_WIDTH); | ||
166 | SetWindowText (hWnd, s); | ||
167 | |||
168 | return TRUE; | ||
169 | } | ||
170 | case WM_ERASEBKGND: | ||
171 | { | ||
172 | HDC hDc = (HDC) wParam; | ||
173 | RECT r; | ||
174 | |||
175 | GetClientRect (hWnd, &r); | ||
176 | // blit background image to screen | ||
177 | SetStretchBltMode(hDc, bIsWinNT ? HALFTONE : COLORONCOLOR); | ||
178 | StretchBlt (hDc, 0, 0, r.right, r.bottom, | ||
179 | hMemDc, 0, 0, UI_WIDTH, UI_HEIGHT, SRCCOPY); | ||
180 | return TRUE; | ||
181 | } | ||
182 | case WM_PAINT: | ||
183 | { | ||
184 | PAINTSTRUCT ps; | ||
185 | RECT r; | ||
186 | HDC hDc = BeginPaint (hWnd, &ps); | ||
187 | |||
188 | GetClientRect (hWnd, &r); | ||
189 | // draw lcd screen | ||
190 | SetStretchBltMode(hDc, bIsWinNT ? HALFTONE : COLORONCOLOR); | ||
191 | StretchDIBits (hDc, | ||
192 | UI_LCD_POSX * r.right / UI_WIDTH, | ||
193 | UI_LCD_POSY * r.bottom / UI_HEIGHT, | ||
194 | UI_LCD_WIDTH * r.right / UI_WIDTH, | ||
195 | UI_LCD_HEIGHT * r.bottom / UI_HEIGHT, | ||
196 | 0, 0, LCD_WIDTH, LCD_HEIGHT, | ||
197 | bitmap, (BITMAPINFO *) &bmi, DIB_RGB_COLORS, | ||
198 | SRCCOPY); | ||
199 | #ifdef HAVE_REMOTE_LCD | ||
200 | StretchDIBits (hDc, | ||
201 | UI_REMOTE_POSX * r.right / UI_WIDTH, | ||
202 | UI_REMOTE_POSY * r.bottom / UI_HEIGHT, | ||
203 | UI_REMOTE_WIDTH * r.right / UI_WIDTH, | ||
204 | UI_REMOTE_HEIGHT * r.bottom / UI_HEIGHT, | ||
205 | 0, 0, LCD_REMOTE_WIDTH, LCD_REMOTE_HEIGHT, | ||
206 | remote_bitmap, (BITMAPINFO *) &remote_bmi, | ||
207 | DIB_RGB_COLORS, SRCCOPY); | ||
208 | #endif | ||
209 | EndPaint (hWnd, &ps); | ||
210 | return TRUE; | ||
211 | } | ||
212 | case WM_CLOSE: | ||
213 | // close simulator | ||
214 | KillTimer (hWnd, TIMER_EVENT); | ||
215 | hGUIWnd = NULL; | ||
216 | PostQuitMessage (0); | ||
217 | break; | ||
218 | case WM_DESTROY: | ||
219 | // close simulator | ||
220 | hGUIWnd = NULL; | ||
221 | PostQuitMessage (0); | ||
222 | break; | ||
223 | case WM_KEYDOWN: | ||
224 | button_event(wParam, true); | ||
225 | break; | ||
226 | case WM_KEYUP: | ||
227 | button_event(wParam, false); | ||
228 | break; | ||
229 | } | ||
230 | |||
231 | return DefWindowProc (hWnd, uMsg, wParam, lParam); | ||
232 | } | ||
233 | |||
234 | // GUIStartup | ||
235 | // register window class, show window, init GUI | ||
236 | BOOL GUIStartup () | ||
237 | { | ||
238 | WNDCLASS wc; | ||
239 | |||
240 | // create window class | ||
241 | ZeroMemory (&wc, sizeof(wc)); | ||
242 | wc.hbrBackground = GetSysColorBrush (COLOR_WINDOW); | ||
243 | wc.hCursor = LoadCursor (NULL, IDC_ARROW); | ||
244 | wc.hInstance = GetModuleHandle (NULL); | ||
245 | wc.lpfnWndProc = GUIWndProc; | ||
246 | wc.lpszClassName = "RockBoxUISimulator"; | ||
247 | wc.style = CS_HREDRAW | CS_VREDRAW; | ||
248 | |||
249 | if (RegisterClass (&wc) == 0) | ||
250 | return FALSE; | ||
251 | |||
252 | // create window | ||
253 | hGUIWnd = CreateWindowEx ( | ||
254 | WS_EX_OVERLAPPEDWINDOW, | ||
255 | "RockBoxUISimulator", UI_TITLE, | ||
256 | WS_VISIBLE | WS_SYSMENU | WS_OVERLAPPEDWINDOW, | ||
257 | CW_USEDEFAULT, CW_USEDEFAULT, | ||
258 | UI_WIDTH + GetSystemMetrics (SM_CXSIZEFRAME) * 2 +4, | ||
259 | UI_HEIGHT + GetSystemMetrics (SM_CYSIZEFRAME) * 2 + | ||
260 | GetSystemMetrics (SM_CYCAPTION) +4, | ||
261 | NULL, NULL, GetModuleHandle (NULL), NULL); | ||
262 | |||
263 | if (hGUIWnd == NULL) | ||
264 | return FALSE; | ||
265 | |||
266 | simlcdinit(); | ||
267 | |||
268 | return TRUE; | ||
269 | } | ||
270 | |||
271 | // GUIDown | ||
272 | // destroy window, unregister window class | ||
273 | int GUIDown () | ||
274 | { | ||
275 | int i; | ||
276 | |||
277 | DestroyWindow (hGUIWnd); | ||
278 | CloseHandle (hGUIThread); | ||
279 | #ifdef ROCKBOX_HAS_SIMSOUND | ||
280 | CloseHandle (hSoundThread); | ||
281 | #endif | ||
282 | |||
283 | for (i = 0; i < nThreads; i++) | ||
284 | { | ||
285 | CloseHandle (lpThreads[i]); | ||
286 | } | ||
287 | return 0; | ||
288 | } | ||
289 | |||
290 | // GUIMessageLoop | ||
291 | // standard message loop for GUI window | ||
292 | void GUIMessageLoop () | ||
293 | { | ||
294 | MSG msg; | ||
295 | while (GetMessage (&msg, NULL, 0, 0)) | ||
296 | { | ||
297 | TranslateMessage (&msg); | ||
298 | DispatchMessage (&msg); | ||
299 | } | ||
300 | } | ||
301 | |||
302 | |||
303 | // WinMain | ||
304 | // program entry point | ||
305 | int WINAPI WinMain ( | ||
306 | HINSTANCE hInstance, // current instance | ||
307 | HINSTANCE hPrevInstance, // previous instance | ||
308 | LPSTR lpCmd, // command line | ||
309 | int nShowCmd // show command | ||
310 | ) | ||
311 | { | ||
312 | DWORD dwThreadID; | ||
313 | |||
314 | (void)hInstance; | ||
315 | (void)hPrevInstance; | ||
316 | (void)lpCmd; | ||
317 | (void)nShowCmd; | ||
318 | |||
319 | /* default file mode should be O_BINARY to be consistent with rockbox */ | ||
320 | _fmode = _O_BINARY; | ||
321 | |||
322 | bIsWinNT = ((GetVersion() & 0x80000000) == 0); | ||
323 | |||
324 | if (!GUIStartup ()) | ||
325 | return 0; | ||
326 | |||
327 | hGUIThread = CreateThread (NULL, 0, (LPTHREAD_START_ROUTINE)app_main, | ||
328 | NULL, 0, &dwThreadID); | ||
329 | |||
330 | if (hGUIThread == NULL) | ||
331 | return MessageBox (NULL, "Error creating gui thread!", "Error", MB_OK); | ||
332 | |||
333 | #ifdef ROCKBOX_HAS_SIMSOUND | ||
334 | hSoundThread = CreateThread (NULL, 0, (LPTHREAD_START_ROUTINE) | ||
335 | sound_playback_thread, NULL, 0, &dwThreadID); | ||
336 | |||
337 | if (hSoundThread == NULL) | ||
338 | MessageBox (NULL, "Error creating sound thread!", "Warning", MB_OK); | ||
339 | #endif | ||
340 | |||
341 | GUIMessageLoop (); | ||
342 | |||
343 | return GUIDown (); | ||
344 | } | ||