2 #include <conio.h> /* this is where Open Watcom hides the outp() etc. functions */
13 #include <hw/cpu/cpu.h>
14 #include <hw/dos/dos.h>
15 #include <hw/vga/vga.h>
16 #include <hw/vga/vgatty.h>
17 #include <hw/vga/vgagui.h>
20 # include <hw/dos/winfcon.h>
21 # include <windows/apihelp.h>
22 # include <windows/dispdib/dispdib.h>
23 # include <windows/win16eb/win16eb.h>
26 struct vga_menu_bar_state vga_menu_bar = {NULL,-1,0};
27 void (*vga_menu_idle)() = NULL;
29 int vga_menu_item_nonselectable(const struct vga_menu_item *m) {
30 if (m->text == (char*)1) return 1;
34 void vga_menu_bar_draw() {
35 VGA_ALPHA_PTR vga = vga_alpha_ram + (80*vga_menu_bar.row);
36 const struct vga_menu_bar_item *m = vga_menu_bar.bar;
37 unsigned int x,i,color,colorh,ti;
45 while (x < 80 && m->name != NULL) {
48 hi = (i == vga_menu_bar.sel);
49 color = hi ? 0x1F00 : 0x7000;
50 colorh = hi ? 0x1E00 : 0x7100;
51 if (m->x >= 80) break;
52 while (x < m->x) vga[x++] = color | 0x20;
53 while (x < (m->x+m->w) && *msg != 0) {
54 if (ti && *msg == m->shortcut_key) {
55 vga[x++] = colorh | (*msg++);
59 vga[x++] = color | (*msg++);
62 while (x < (m->x+m->w)) vga[x++] = color | 0x20;
69 while (x < 80) vga[x++] = 0x7020;
72 void vga_menu_draw_item(VGA_ALPHA_PTR screen,const struct vga_menu_item **scan,unsigned int i,unsigned int w,unsigned int color,unsigned int tcolor) {
73 const struct vga_menu_item *sci = scan[i];
74 const char *txt = sci->text;
77 screen += (i * vga_width) + 1;
78 if (txt == (char*)1) {
79 screen[-1] = 204 | color;
80 for (x=0;x < w;x++) screen[x] = 205 | color;
81 screen[w] = 185 | color;
84 for (x=0;x < w && txt[x] != 0;x++) {
85 if (ti && tolower(txt[x]) == tolower(sci->shortcut_key)) {
86 screen[x] = txt[x] | tcolor;
90 screen[x] = txt[x] | color;
93 for (;x < w;x++) screen[x] = 0x20 | color;
97 const struct vga_menu_item *vga_menu_bar_menuitem(const struct vga_menu_bar_item *menu,unsigned char row,unsigned int *spec) {
98 const struct vga_menu_item *ret = NULL,**scan,*sci;
99 unsigned int w,h,i,l,x,y,o,ks,nks,items,sel,c,altup=0;
100 static const unsigned int hicolor = 0x7000;
101 static const unsigned int hitcolor = 0x7100;
102 static const unsigned int color = 0x1700;
103 static const unsigned int tcolor = 0x1E00;
104 VGA_ALPHA_PTR screen,buf;
105 unsigned char loop = 1;
107 /* FIX: If re-inited because of arrow keys, then one more alt-up should trigger release */
108 if (*spec == 0x4B00 || *spec == 0x4D00)
115 ks = (read_bios_keystate() & BIOS_KS_ALT);
117 for (i=0;(sci=scan[i]) != NULL;i++) {
118 if (sci->text == (char*)1) l = 1;
119 else l = (unsigned int)strlen(sci->text);
121 if (w < (l+2)) w = (l+2);
122 if (h < (i+2) && (h+2+row) <= 25) h = i+2;
126 #if TARGET_MSDOS == 32
127 buf = malloc(w * h * 2);
129 buf = _fmalloc(w * h * 2);
131 screen = vga_alpha_ram + (row * vga_width) + menu->x;
133 /* copy off the screen contents */
134 for (y=0;y < h;y++) {
137 for (x=0;x < w;x++,o++,i++) buf[o] = screen[i];
141 for (y=0;y < (h-1);y++) {
143 screen[o+0] = 186 | color;
144 screen[o+w-1] = 186 | color;
146 o = vga_width * (h-1);
147 screen[o+0] = 200 | color;
148 for (x=1;x < (w-1);x++) screen[o+x] = 205 | color;
149 screen[o+w-1] = 188 | color;
152 for (i=0;i < items;i++)
153 vga_menu_draw_item(screen,scan,i,w-2,i == sel ? hicolor : color,i == sel ? hitcolor : tcolor);
156 nks = (read_bios_keystate() & BIOS_KS_ALT);
160 if (++altup >= 2) break;
166 if (c == 0) c = getch() << 8;
174 else if (c == 0x4800) {
175 vga_menu_draw_item(screen,scan,sel,w-2,color,tcolor);
177 if (sel == 0) sel = items-1;
179 } while (vga_menu_item_nonselectable(scan[sel]));
180 vga_menu_draw_item(screen,scan,sel,w-2,hicolor,hitcolor);
182 else if (c == 0x5000) {
183 vga_menu_draw_item(screen,scan,sel,w-2,color,tcolor);
185 if (++sel >= items) sel = 0;
186 } while (vga_menu_item_nonselectable(scan[sel]));
187 vga_menu_draw_item(screen,scan,sel,w-2,hicolor,hitcolor);
189 else if (c == 0x4B00 || c == 0x4D00) {
194 else if (c > 32 && c < 127) {
195 int patience = items;
197 vga_menu_draw_item(screen,scan,sel,w-2,color,tcolor);
198 /* look for the first menu item with that shortcut key */
199 if (++sel >= items) sel = 0;
200 while (tolower(scan[sel]->shortcut_key) != tolower(c)) {
201 if (--patience == 0) {
206 if (++sel >= items) sel = 0;
208 vga_menu_draw_item(screen,scan,sel,w-2,hicolor,hitcolor);
217 /* copy screen contents back */
218 for (y=0;y < h;y++) {
221 for (x=0;x < w;x++,o++,i++) screen[o] = buf[i];
224 #if TARGET_MSDOS == 32
235 const struct vga_menu_item *vga_menu_bar_keymon() {
236 const struct vga_menu_bar_item *m = NULL;
237 const struct vga_menu_item *ret = NULL;
241 if (vga_menu_bar.bar == NULL)
244 if (read_bios_keystate() & BIOS_KS_ALT) {
245 vga_menu_bar.sel = 0;
256 if (c == 0x9B) { /* ALT-left */
257 if (--vga_menu_bar.sel < 0) {
258 vga_menu_bar.sel = 0;
259 while (vga_menu_bar.bar[vga_menu_bar.sel].name != NULL) vga_menu_bar.sel++;
262 m = &vga_menu_bar.bar[vga_menu_bar.sel];
265 else if (c == 0x9D) { /* ALT-right */
266 if (vga_menu_bar.bar[++vga_menu_bar.sel].name == NULL) vga_menu_bar.sel = 0;
267 m = &vga_menu_bar.bar[vga_menu_bar.sel];
271 int oi = vga_menu_bar.sel;
273 for (m=vga_menu_bar.bar;m->name != NULL;m++,i++) {
274 if (c == m->shortcut_scan)
277 if (m->name == NULL) {
279 vga_menu_bar.sel = -1;
282 vga_menu_bar.sel = i;
285 if (oi != vga_menu_bar.sel)
293 } while (read_bios_keystate() & BIOS_KS_ALT);
295 if (!(read_bios_keystate() & BIOS_KS_ALT)) {
296 while (kbhit()) getch();
300 ret = vga_menu_bar_menuitem(m,vga_menu_bar.row+1,&spec);
302 if (spec == 0x4B00) {
303 if (--vga_menu_bar.sel < 0) {
304 vga_menu_bar.sel = 0;
305 while (vga_menu_bar.bar[vga_menu_bar.sel].name != NULL) vga_menu_bar.sel++;
308 m = &vga_menu_bar.bar[vga_menu_bar.sel];
312 else if (spec == 0x4D00) {
313 if (vga_menu_bar.bar[++vga_menu_bar.sel].name == NULL) vga_menu_bar.sel = 0;
314 m = &vga_menu_bar.bar[vga_menu_bar.sel];
321 while (read_bios_keystate() & BIOS_KS_ALT);
322 vga_menu_bar.sel = -1;
329 int vga_msg_box_create(struct vga_msg_box *b,const char *msg,unsigned int extra_y,unsigned int min_x) {
330 unsigned int w=min_x,h=max(1,extra_y),x=0,y,px,py,i,o;
331 static const unsigned int color = 0x1E00;
340 else if ((unsigned char)(*scan) >= 32) {
346 w += 4; if (w > 80) w = 80;
347 h += 2; if (h > 25) h = 25;
348 px = (vga_width - w) / 2;
349 py = (vga_height - h) / 2;
350 b->screen = vga_alpha_ram + (py * vga_width) + px;
356 #if TARGET_MSDOS == 32
357 b->buf = malloc(w * h * 2);
359 b->buf = _fmalloc(w * h * 2);
361 if (b->buf != NULL) {
362 /* copy the screen to buffer */
363 for (y=0;y < h;y++) {
366 for (x=0;x < w;x++,i++,o++) b->buf[o] = b->screen[i];
371 for (y=1;y < (h-1);y++) {
373 b->screen[o+0] = 186 | color;
374 b->screen[o+1] = 32 | color;
375 b->screen[o+w-2] = 32 | color;
376 b->screen[o+w-1] = 186 | color;
379 for (x=1;x < (w-1);x++) {
380 b->screen[x] = 205 | color;
381 b->screen[x+o] = 205 | color;
383 b->screen[0] = 201 | color;
384 b->screen[w-1] = 187 | color;
385 b->screen[o] = 200 | color;
386 b->screen[o+w-1] = 188 | color;
395 b->screen[o+x] = 32 | color;
398 if (++y >= (h-2)) break;
402 else if ((unsigned char)(*scan) >= 32) {
403 if (x < (w-4)) b->screen[o+x] = *scan | color;
410 b->screen[o+x] = 32 | color;
423 void vga_msg_box_destroy(struct vga_msg_box *b) {
424 unsigned int x,y,i,o;
428 /* copy screen back */
429 for (y=0;y < b->h;y++) {
432 for (x=0;x < b->w;x++,i++,o++) b->screen[o] = b->buf[i];
435 #if TARGET_MSDOS == 32
446 int confirm_yes_no_dialog(const char *message) {
447 struct vga_msg_box box = {NULL,NULL,0,0};
452 if (vga_msg_box_create(&box,message,2,(bw*2)+2)) {
453 x = ((box.w+2-(bw*2))/2)+box.x;
454 vga_write_color(0x70);
455 vga_moveto(x,box.y+box.h-2);
457 vga_write_color(0x71);
459 vga_write_color(0x70);
461 vga_moveto(x+bw,box.y+box.h-2);
463 vga_write_color(0x71);
465 vga_write_color(0x70);
472 if (c == 0) c = getch() << 8;
474 if (c == 'Y' || c == 'y') {
478 else if (c == 'N' || c == 'n') {
489 vga_msg_box_destroy(&box);