28
28
#include <windows.h>
29
30
#ifdef HAVE_COMMCTRL_H
30
31
#include <commctrl.h>
32
34
#include "datasette.h"
36
40
#include "statusbar.h"
39
43
static HWND status_hwnd[2];
40
static int number_of_status_windows=0;
41
static int status_height;
44
static int number_of_status_windows = 0;
45
static int status_height;
47
static unsigned int enabled_drives;
43
48
static ui_drive_enable_t status_enabled;
44
static int status_led[DRIVE_NUM];
45
static int status_map[DRIVE_NUM]; // Translate from window index -> drive index
46
static int status_partindex[DRIVE_NUM]; // Translate from drive index -> window index
47
static double status_track[DRIVE_NUM];
48
static int *drive_active_led;
50
static int tape_enabled = 0;
51
static int tape_motor;
52
static int tape_counter;
53
static int tape_control;
55
static char emu_status_text[1024];
57
static HBRUSH led_red;
58
static HBRUSH led_green;
59
static HBRUSH led_black;
60
static HBRUSH tape_motor_on_brush;
61
static HBRUSH tape_motor_off_brush;
49
static int status_led[DRIVE_NUM];
50
/* Translate from window index -> drive index */
51
static int status_map[DRIVE_NUM];
52
/* Translate from drive index -> window index */
53
static int status_partindex[DRIVE_NUM];
54
static double status_track[DRIVE_NUM];
55
static int *drive_active_led;
57
static int tape_enabled = 0;
58
static int tape_motor;
59
static int tape_counter;
60
static int tape_control;
62
static BYTE joyport[3] = { 0, 0, 0 };
64
static int event_part;
65
static int event_mode;
66
static unsigned int event_time_current, event_time_total;
68
static char emu_status_text[1024];
69
static TCHAR st_emu_status_text[1024];
72
static HBRUSH b_green;
73
static HBRUSH b_black;
74
static HBRUSH b_yellow;
64
78
static void SetStatusWindowParts(HWND hwnd)
87
/* one part for statusinfo, one for joystick and tape */
79
92
for (i = 0; i < DRIVE_NUM; i++) {
80
93
int the_drive = 1 << i;
82
95
if (status_enabled & the_drive) {
83
96
status_map[enabled_drives++] = i;
84
status_partindex[i] = number_of_parts++;
97
if (enabled_drives & 1) {
99
status_map[enabled_drives] = -1;
101
status_partindex[i] = last_part - 1;
87
GetWindowRect(hwnd,&rect);
88
width=rect.right-rect.left;
89
for (i=number_of_parts; i>=0; i--) {
93
SendMessage(hwnd,SB_SETPARTS,number_of_parts+1,(LPARAM)posx);
94
SendMessage(hwnd,SB_SETTEXT,number_of_parts|SBT_OWNERDRAW,0);
104
disk_update_part = last_part - 1;
106
/* the event history part */
107
if (event_mode != EVENT_OFF) {
108
event_part = last_part;
112
posx = lib_malloc(last_part * sizeof(int));
114
GetWindowRect(hwnd, &rect);
115
width = rect.right-rect.left;
117
if (event_mode != EVENT_OFF) {
127
posx[0] = width - 20;
129
SendMessage(hwnd, SB_SETPARTS, last_part, (LPARAM)posx);
130
SendMessage(hwnd, SB_SETTEXT, disk_update_part|SBT_OWNERDRAW,0);
131
SendMessage(hwnd, SB_SETTEXT, 1|SBT_OWNERDRAW, 0);
132
SendMessage(hwnd, SB_SETTEXT, (last_part - 1)|SBT_OWNERDRAW,0);
98
138
void statusbar_create(HWND hwnd)
104
status_hwnd[number_of_status_windows]=CreateStatusWindow(WS_CHILD|WS_VISIBLE,"",hwnd,IDM_STATUS_WINDOW);
105
GetClientRect(status_hwnd[number_of_status_windows],&rect);
106
status_height=rect.bottom-rect.top;
142
status_hwnd[number_of_status_windows] =
143
CreateStatusWindow(WS_CHILD | WS_VISIBLE, TEXT(""), hwnd,
145
SendMessage(status_hwnd[number_of_status_windows], SB_SETMINHEIGHT, 40, (LPARAM)0);
146
SendMessage(status_hwnd[number_of_status_windows], WM_SIZE, 0, (LPARAM)0);
148
GetClientRect(status_hwnd[number_of_status_windows], &rect);
149
status_height = rect.bottom - rect.top;
107
150
SetStatusWindowParts(status_hwnd[number_of_status_windows]);
108
151
number_of_status_windows++;
111
154
void statusbar_destroy(void)
117
for (i=0; i<number_of_status_windows; i++) {
158
for (i = 0; i < number_of_status_windows; i++) {
118
159
DestroyWindow(status_hwnd[i]);
121
number_of_status_windows=0;
162
number_of_status_windows = 0;
124
165
void statusbar_create_brushes(void)
126
led_green=CreateSolidBrush(0xff00);
127
led_red=CreateSolidBrush(0xff);
128
led_black=CreateSolidBrush(0x00);
129
tape_motor_on_brush=CreateSolidBrush(0xffff);
130
tape_motor_off_brush=CreateSolidBrush(0x808080);
167
b_green = CreateSolidBrush(0xff00);
168
b_red = CreateSolidBrush(0xff);
169
b_black = CreateSolidBrush(0x00);
170
b_yellow = CreateSolidBrush(0xffff);
171
b_grey = CreateSolidBrush(0x808080);
133
174
int statusbar_get_status_height(void)
138
179
void statusbar_setstatustext(const char *text)
142
strcpy(emu_status_text,text);
143
for (i=0; i<number_of_status_windows; i++) {
144
SendMessage(status_hwnd[i],SB_SETTEXT,0|SBT_OWNERDRAW,0);
183
strcpy(emu_status_text, text);
184
for (i = 0; i < number_of_status_windows; i++) {
185
SendMessage(status_hwnd[i], SB_SETTEXT, 0 | SBT_OWNERDRAW, 0);
148
void statusbar_enable_drive_status(ui_drive_enable_t enable, int *drive_led_color)
189
void statusbar_enable_drive_status(ui_drive_enable_t enable,
190
int *drive_led_color)
152
194
status_enabled = enable;
153
195
drive_active_led = drive_led_color;
154
for (i=0; i<number_of_status_windows; i++) {
196
for (i = 0; i < number_of_status_windows; i++) {
155
197
SetStatusWindowParts(status_hwnd[i]);
159
void statusbar_display_drive_track(int drivenum, int drive_base, double track_number)
201
void statusbar_display_drive_track(int drivenum, int drive_base,
163
status_track[drivenum]=track_number;
164
for (i=0; i<number_of_status_windows; i++) {
165
SendMessage(status_hwnd[i],SB_SETTEXT,(status_partindex[drivenum]+1)|SBT_OWNERDRAW,0);
206
status_track[drivenum] = track_number;
207
for (i = 0; i < number_of_status_windows; i++) {
208
SendMessage(status_hwnd[i], SB_SETTEXT,
209
(status_partindex[drivenum]) | SBT_OWNERDRAW, 0);
170
214
void statusbar_display_drive_led(int drivenum, int status)
174
status_led[drivenum]=status;
175
for (i=0; i<number_of_status_windows; i++) {
176
SendMessage(status_hwnd[i],SB_SETTEXT,(status_partindex[drivenum]+1)|SBT_OWNERDRAW,0);
218
status_led[drivenum] = status;
219
for (i = 0; i < number_of_status_windows; i++) {
220
SendMessage(status_hwnd[i], SB_SETTEXT,
221
(status_partindex[drivenum]) | SBT_OWNERDRAW, 0);
180
225
void statusbar_set_tape_status(int tape_status)
184
229
tape_enabled = tape_status;
185
for (i=0; i<number_of_status_windows; i++) {
186
SetStatusWindowParts(status_hwnd[i]);
230
for (i = 0; i < number_of_status_windows; i++) {
231
SendMessage(status_hwnd[i], SB_SETTEXT, 1 | SBT_OWNERDRAW, 0);
190
235
void statusbar_display_tape_motor_status(int motor)
194
239
tape_motor = motor;
195
for (i=0; i<number_of_status_windows; i++) {
196
SendMessage(status_hwnd[i],SB_SETTEXT,1|SBT_OWNERDRAW,0);
240
for (i = 0; i < number_of_status_windows; i++) {
241
SendMessage(status_hwnd[i], SB_SETTEXT, 1 | SBT_OWNERDRAW, 0);
200
245
void statusbar_display_tape_control_status(int control)
204
249
tape_control = control;
205
for (i=0; i<number_of_status_windows; i++) {
206
SendMessage(status_hwnd[i],SB_SETTEXT,1|SBT_OWNERDRAW,0);
250
for (i = 0; i < number_of_status_windows; i++) {
251
SendMessage(status_hwnd[i], SB_SETTEXT, 1 | SBT_OWNERDRAW, 0);
210
255
void statusbar_display_tape_counter(int counter)
214
if (counter!=tape_counter) {
259
if (counter != tape_counter) {
215
260
tape_counter = counter;
216
for (i=0; i<number_of_status_windows; i++) {
217
SendMessage(status_hwnd[i],SB_SETTEXT,1|SBT_OWNERDRAW,0);
261
for (i = 0; i < number_of_status_windows; i++) {
262
SendMessage(status_hwnd[i], SB_SETTEXT, 1 | SBT_OWNERDRAW, 0);
222
void statusbar_handle_WMSIZE(UINT msg, WPARAM wparam, LPARAM lparam, int window_index)
224
SendMessage(status_hwnd[window_index],msg,wparam,lparam);
267
void statusbar_display_joyport(BYTE *joystick_status)
271
joyport[1] = joystick_status[1];
272
joyport[2] = joystick_status[2];
273
for (i = 0; i < number_of_status_windows; i++)
274
SendMessage(status_hwnd[i], SB_SETTEXT, 1 | SBT_OWNERDRAW, 0);
277
void statusbar_event_status(int mode)
281
event_time_current = 0;
282
event_time_total = 0;
284
for (i = 0; i < number_of_status_windows; i++) {
285
SetStatusWindowParts(status_hwnd[i]);
289
void statusbar_event_time(unsigned int current, unsigned int total)
293
event_time_current = current;
294
event_time_total = total;
295
for (i = 0; i < number_of_status_windows; i++)
296
SendMessage(status_hwnd[i], SB_SETTEXT, event_part | SBT_OWNERDRAW, 0);
299
void statusbar_handle_WMSIZE(UINT msg, WPARAM wparam, LPARAM lparam,
302
SendMessage(status_hwnd[window_index], msg, wparam, lparam);
225
303
SetStatusWindowParts(status_hwnd[window_index]);
228
306
void statusbar_handle_WMDRAWITEM(WPARAM wparam, LPARAM lparam)
233
if (wparam==IDM_STATUS_WINDOW) {
234
if (((DRAWITEMSTRUCT*)lparam)->itemID==0) {
311
if (wparam == IDM_STATUS_WINDOW) {
312
int part_top = ((DRAWITEMSTRUCT*)lparam)->rcItem.top;
313
int part_left = ((DRAWITEMSTRUCT*)lparam)->rcItem.left;
314
HDC hDC = ((DRAWITEMSTRUCT*)lparam)->hDC;
315
UINT itemID = ((DRAWITEMSTRUCT*)lparam)->itemID;
317
SetBkColor(hDC, (COLORREF)GetSysColor(COLOR_3DFACE));
318
SetTextColor(hDC, (COLORREF)GetSysColor(COLOR_MENUTEXT));
235
321
/* it's the status info */
236
led=((DRAWITEMSTRUCT*)lparam)->rcItem;
322
led = ((DRAWITEMSTRUCT*)lparam)->rcItem;
241
SetBkColor(((DRAWITEMSTRUCT*)lparam)->hDC,(COLORREF)GetSysColor(COLOR_3DFACE));
242
SetTextColor(((DRAWITEMSTRUCT*)lparam)->hDC,(COLORREF)GetSysColor(COLOR_MENUTEXT));
243
DrawText(((DRAWITEMSTRUCT*)lparam)->hDC,emu_status_text,-1,&led,0);
327
system_mbstowcs(st_emu_status_text, emu_status_text, 1024);
328
DrawText(hDC, st_emu_status_text, -1, &led, DT_WORDBREAK);
245
if ((((DRAWITEMSTRUCT*)lparam)->itemID==1) && tape_enabled) {
246
/* it's the tape status */
247
POINT tape_control_sign[3];
249
/* the leading "Tape:" */
250
led.top=((DRAWITEMSTRUCT*)lparam)->rcItem.top+2;
251
led.bottom=((DRAWITEMSTRUCT*)lparam)->rcItem.top+18;
252
led.left=((DRAWITEMSTRUCT*)lparam)->rcItem.left+2;
253
led.right=((DRAWITEMSTRUCT*)lparam)->rcItem.left+34;
254
SetBkColor(((DRAWITEMSTRUCT*)lparam)->hDC,(COLORREF)GetSysColor(COLOR_3DFACE));
255
SetTextColor(((DRAWITEMSTRUCT*)lparam)->hDC,(COLORREF)GetSysColor(COLOR_MENUTEXT));
256
DrawText(((DRAWITEMSTRUCT*)lparam)->hDC,"Tape:",-1,&led,0);
259
led.top=((DRAWITEMSTRUCT*)lparam)->rcItem.top+1;
260
led.bottom=((DRAWITEMSTRUCT*)lparam)->rcItem.top+15;
261
led.left=((DRAWITEMSTRUCT*)lparam)->rcItem.left+36;
262
led.right=((DRAWITEMSTRUCT*)lparam)->rcItem.left+50;
263
FillRect(((DRAWITEMSTRUCT*)lparam)->hDC,&led,tape_motor?tape_motor_on_brush:tape_motor_off_brush);
265
/* the tape-control */
270
tape_control_sign[0].x = led.left;
271
tape_control_sign[1].x = led.left+4;
272
tape_control_sign[2].x = led.left;
273
tape_control_sign[0].y = led.top;
274
tape_control_sign[1].y = led.top+4;
275
tape_control_sign[2].y = led.top+8;
276
switch (tape_control) {
332
const int offset_x[] = { 5, 0, -5, 10, -5 };
333
const int offset_y[] = { 0, 10, -5, 0, 0 };
334
int dir_index, joynum;
338
POINT tape_control_sign[3];
340
/* the leading "Tape:" */
341
led.top = part_top + 2;
342
led.bottom = part_top + 18;
343
led.left = part_left + 2;
344
led.right = part_left + 34;
345
DrawText(hDC, TEXT("Tape:"), -1, &led, 0);
348
led.top = part_top + 1;
349
led.bottom = part_top + 15;
350
led.left = part_left + 36;
351
led.right = part_left + 50;
352
FillRect(hDC, &led, tape_motor ? b_yellow : b_grey);
354
/* the tape-control */
359
tape_control_sign[0].x = led.left;
360
tape_control_sign[1].x = led.left+4;
361
tape_control_sign[2].x = led.left;
362
tape_control_sign[0].y = led.top;
363
tape_control_sign[1].y = led.top+4;
364
tape_control_sign[2].y = led.top+8;
365
switch (tape_control) {
277
366
case DATASETTE_CONTROL_STOP:
278
FillRect(((DRAWITEMSTRUCT*)lparam)->hDC,&led,led_black);
367
FillRect(hDC, &led, b_black);
280
369
case DATASETTE_CONTROL_START:
281
370
case DATASETTE_CONTROL_RECORD:
282
SelectObject(((DRAWITEMSTRUCT*)lparam)->hDC,led_black);
283
Polygon(((DRAWITEMSTRUCT*)lparam)->hDC,tape_control_sign,3);
284
if (tape_control==DATASETTE_CONTROL_RECORD) {
285
SelectObject(((DRAWITEMSTRUCT*)lparam)->hDC,led_red);
286
Ellipse(((DRAWITEMSTRUCT*)lparam)->hDC,
371
SelectObject(hDC, b_black);
372
Polygon(hDC, tape_control_sign, 3);
373
if (tape_control == DATASETTE_CONTROL_RECORD) {
374
SelectObject(hDC, b_red);
375
Ellipse(hDC, led.left + 16, led.top + 1,
376
led.left + 23, led.top + 8);
293
379
case DATASETTE_CONTROL_REWIND:
295
381
tape_control_sign[1].x -= 4;
296
382
tape_control_sign[2].x += 4;
297
383
case DATASETTE_CONTROL_FORWARD:
298
Polyline(((DRAWITEMSTRUCT*)lparam)->hDC,tape_control_sign,3);
384
Polyline(hDC, tape_control_sign, 3);
299
385
tape_control_sign[0].x += 4;
300
386
tape_control_sign[1].x += 4;
301
387
tape_control_sign[2].x += 4;
302
Polyline(((DRAWITEMSTRUCT*)lparam)->hDC,tape_control_sign,3);
305
/* the tape-counter */
306
led.top=((DRAWITEMSTRUCT*)lparam)->rcItem.top+2;
307
led.bottom=((DRAWITEMSTRUCT*)lparam)->rcItem.top+18;
308
led.left=((DRAWITEMSTRUCT*)lparam)->rcItem.left+75;
309
led.right=((DRAWITEMSTRUCT*)lparam)->rcItem.left+110;
310
sprintf(text,"%03i",tape_counter);
311
DrawText(((DRAWITEMSTRUCT*)lparam)->hDC,text,-1,&led,0);
314
if ((int)((DRAWITEMSTRUCT*)lparam)->itemID>(tape_enabled?1:0)) {
315
int index=((DRAWITEMSTRUCT*)lparam)->itemID-(tape_enabled?2:1);
317
led.top=((DRAWITEMSTRUCT*)lparam)->rcItem.top+2;
318
led.bottom=((DRAWITEMSTRUCT*)lparam)->rcItem.top+18;
319
led.left=((DRAWITEMSTRUCT*)lparam)->rcItem.left+2;
320
led.right=((DRAWITEMSTRUCT*)lparam)->rcItem.left+84;
321
sprintf(text,"%d: Track: %.1f",status_map[index]+8,status_track[status_map[index]]);
322
SetBkColor(((DRAWITEMSTRUCT*)lparam)->hDC,(COLORREF)GetSysColor(COLOR_3DFACE));
323
SetTextColor(((DRAWITEMSTRUCT*)lparam)->hDC,(COLORREF)GetSysColor(COLOR_MENUTEXT));
324
DrawText(((DRAWITEMSTRUCT*)lparam)->hDC,text,-1,&led,0);
326
led.top=((DRAWITEMSTRUCT*)lparam)->rcItem.top+2;
327
led.bottom=((DRAWITEMSTRUCT*)lparam)->rcItem.top+2+12;
328
led.left=((DRAWITEMSTRUCT*)lparam)->rcItem.left+86;
329
led.right=((DRAWITEMSTRUCT*)lparam)->rcItem.left+86+16;
330
FillRect(((DRAWITEMSTRUCT*)lparam)->hDC,&led,status_led[status_map[index]] ? (drive_active_led[status_map[index]] ? led_green : led_red ) : led_black);
388
Polyline(hDC, tape_control_sign, 3);
391
/* the tape-counter */
392
led.top = part_top + 2;
393
led.bottom = part_top + 18;
394
led.left = part_left + 65;
395
led.right = part_left + 100;
396
_stprintf(text, TEXT("%03i"), tape_counter);
397
DrawText(hDC, text, -1, &led, 0);
401
led.left = part_left + 2;
402
led.right = part_left + 48;
403
led.top = part_top + 22;
404
led.bottom = part_top + 38;
406
DrawText(hDC, TEXT("Joystick:"), -1, &led, 0);
408
for (joynum = 1; joynum <= 2; joynum ++) {
410
led.top = part_top + 22;
411
led.left = part_left + (joynum - 1) * 18 + 52;
412
led.bottom = led.top + 3;
413
led.right = led.left + 3;
415
for (dir_index = 0; dir_index < 5; dir_index++) {
418
if (joyport[joynum] & (1 << dir_index))
419
brush = (dir_index < 4 ? b_green : b_red);
423
OffsetRect(&led, offset_x[dir_index], offset_y[dir_index]);
425
FillRect(hDC, &led, brush);
431
if (itemID > 1 && itemID <= ((enabled_drives + 3) >> 1)) {
432
/* it's a disk part*/
434
int index = ((itemID - 2) << 1);
435
for (y = 0; y < 2 && status_map[index] >= 0; y++, index++) {
436
led.top = part_top + 20 * y + 2 ;
437
led.bottom = led.top + 16;
438
led.left = part_left + 2;
439
led.right = part_left + 45;
440
_stprintf(text, TEXT("%2d: %.1f"), status_map[index] + 8,
441
status_track[status_map[index]]);
442
DrawText(hDC, text, -1, &led, 0);
444
led.bottom = led.top + 12;
445
led.left = part_left + 47;
446
led.right = part_left + 47 + 16;
447
FillRect(hDC, &led, status_led[status_map[index]] ?
448
(drive_active_led[status_map[index]] ?
449
b_green : b_red ) : b_black);
453
if (itemID > ((enabled_drives + 3) >> 1)) {
454
/* it's the event history part */
455
switch (event_mode) {
456
case EVENT_RECORDING:
457
_stprintf(text, TEXT("Recording\n%02d:%02d"),
458
event_time_current / 60,
459
event_time_current % 60);
462
_stprintf(text, TEXT("Playback\n%02d:%02d (%02d:%02d)"),
463
event_time_current / 60,
464
event_time_current % 60,
465
event_time_total / 60,
466
event_time_total % 60);
469
_stprintf(text, TEXT("Unknown"));
471
led = ((DRAWITEMSTRUCT*)lparam)->rcItem;
476
DrawText(hDC, text, -1, &led, DT_WORDBREAK);