📄 ui_os2vio.c
字号:
/* * XaoS, a fast portable realtime fractal zoomer * Copyright (C) 1996,1997 by * * Jan Hubicka (hubicka@paru.cas.cz) * Thomas Marsh (tmarsh@austin.ibm.com) * * OS/2 VIO driver by * Thomas A. K. Kjaer (takjaer@imv.aau.dk) * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */#include "aconfig.h"#ifdef OS2VIO_DRIVER#define INCL_VIO#define INCL_KBD#define INCL_MOU#include <os2.h>#include <sys/hw.h>#include <stdio.h>#include <stdlib.h>#include <unistd.h>#include <string.h>#include "ui.h"#include "ui_os2viofont.h"struct ui_driver os2vio_driver;static int currentbuff = 0;static int width = 320, height = 200;static int page_size = 64000;static int buttons = 0, keys = 0;static char *buffers[2] = { NULL, NULL };static PVIOPHYSBUF phys_buf;static VIOMODEINFO orig_mode, vio_mode;static PCH ScrPtr;static HMOU hMou;static USHORT mouwait = MOU_NOWAIT;static USHORT oldDeviceStatus;static int mousetype = NORMALMOUSE;static char screen[8 * 8];static voidvio_mousetype (int m){ mousetype = m;}static intvio_init (){ USHORT mask = 0x7F; USHORT status; PTRLOC ptrLoc = { 0, 0 }; if (MouOpen (NULL, &hMou) && MouOpen ("POINTER$", &hMou)) hMou = 0; MouFlushQue (hMou); MouSetEventMask (&mask, hMou); MouGetDevStatus (&oldDeviceStatus, hMou); /* Turn off mouse pointer drawing, BEFORE switching to graphics mode! */ status = 0x100; MouSetDevStatus (&status, hMou); orig_mode.cb = sizeof (VIOMODEINFO); VioGetMode ((PVIOMODEINFO) & orig_mode, (HVIO) 0); MouSetPtrPos (&ptrLoc, hMou); memcpy ((void *) &vio_mode, (const void *) &orig_mode, sizeof (VIOMODEINFO)); vio_mode.fbType = 3; vio_mode.color = 8; vio_mode.col = 40; vio_mode.row = 25; vio_mode.hres = width; vio_mode.vres = height; vio_mode.fmt_ID = 0; vio_mode.attrib = 0; if (VioSetMode (&vio_mode, (HVIO) 0)) { printf ("VioSetMode error\n"); return 0; } phys_buf = malloc (sizeof (VIOPHYSBUF)); phys_buf->pBuf = (unsigned char *) 0xA0000; phys_buf->cb = page_size; if (VioGetPhysBuf (phys_buf, 0)) { printf ("VioGetPhysBuf error\n"); return 0; } ScrPtr = MAKEP (phys_buf->asel[0], 0); memset (ScrPtr, 0, page_size); return 1;}static voidvio_get_size (int *wi, int *he){ *wi = width; *he = height;}#define ABS(a) (((a)<0) ? -(a) : (a))static intvga_drawline (int x1, int y1, int x2, int y2, int c){ int dx = x2 - x1; int dy = y2 - y1; int ax = ABS (dx) << 1; int ay = ABS (dy) << 1; int sx = (dx >= 0) ? 1 : -1; int sy = (dy >= 0) ? 1 : -1; int x = x1; int y = y1; if (ax > ay) { int d = ay - (ax >> 1); while (x != x2) { ScrPtr[y * width + x] = c; if (d > 0 || (d == 0 && sx == 1)) { y += sy; d -= ax; } x += sx; d += ay; } } else { int d = ax - (ay >> 1); while (y != y2) { ScrPtr[y * width + x] = c; if (d > 0 || (d == 0 && sy == 1)) { x += sx; d -= ay; } y += sy; d += ax; } } ScrPtr[y * width + x] = c; return 0;}static voiddraw_mouse (int x, int y, int clear){ static int oldx = 3, oldy = 3; int buffstart, i; char status; if (mousetype != REPLAYMOUSE) { VioScrLock (1, &status, (HVIO) 0); if (x < 3) x = 3; if (y < 3) y = 3; if (x > width - 5) x = width - 5; if (y > height - 4) y = height - 4; if ((oldx != x || oldy != y) && clear) { /* copy rectangle over mouse pointer */ buffstart = (oldy - 3) * width + (oldx - 3); for (i = 0; i < 8; i++) { memcpy ((PCH) (ScrPtr + buffstart), (char *) (buffstart + buffers[currentbuff]), 8); buffstart += width; } } vga_drawline (x - 3, y - 3, x + 3, y + 3, 255); vga_drawline (x - 3, y + 3, x + 3, y - 3, 255); vga_drawline (x + 1 - 3, y - 3, x + 1 + 3, y + 3, 253); vga_drawline (x + 1 - 3, y + 3, x + 1 + 3, y - 3, 253); oldx = x; oldy = y; VioScrUnLock ((HVIO) 0); }}/* check for keys * * returns ascii-code */static intcheck_keys (KBDKEYINFO k){ if (!(k.fbStatus & 0x02)) { /* ASCII code */ if (k.chChar == 27) return 'q'; return k.chChar; } return 0; /* not handled */}static intcheck_ckeys (KBDKEYINFO k){ int c; if (k.fbStatus & 0x02) { /* SCAN code */ c = k.chScan; if (c == 75) { /* left */ keys |= 1; } else { keys &= ~1; } if (c == 77) { /* right */ keys |= 2; } else { keys &= ~2; } if (c == 72) { /* up */ keys |= 4; } else { keys &= ~4; } if (c == 80) { /* down */ keys |= 8; } else { keys &= ~8; } } return keys;}static voidvio_processevents (int wait, int *x, int *y, int *b, int *k){ KBDKEYINFO kbdkeyinfo; MOUEVENTINFO mouEvent; *k = 0; *b = buttons; if (wait) { while (1) { KbdCharIn (&kbdkeyinfo, IO_NOWAIT, 0); if (kbdkeyinfo.fbStatus != 0) { if (check_keys (kbdkeyinfo)) ui_key (kbdkeyinfo.chChar); *k = check_ckeys (kbdkeyinfo); return; } MouReadEventQue (&mouEvent, &mouwait, hMou); if (! ((mouEvent.fs == 0) && (mouEvent.col == 0) && (mouEvent.row == 0))) { if (mouEvent.fs & 0x60) buttons |= BUTTON2; else buttons &= ~BUTTON2; if ((mouEvent.fs & 0x18) || (mouEvent.fs & 0x60 && mouEvent.fs & 0x06)) buttons |= BUTTON3; else buttons &= ~BUTTON3; if (mouEvent.fs & 0x06) buttons |= BUTTON1; else buttons &= ~BUTTON1; if (mouEvent.fs & 0x01) buttons = 0; *x = mouEvent.col; *y = mouEvent.row; *b = buttons; draw_mouse (*x, *y, 1); return; } DosSleep (0); } } else { KbdCharIn (&kbdkeyinfo, IO_NOWAIT, 0); if (kbdkeyinfo.fbStatus != 0) { if (check_keys (kbdkeyinfo)) ui_key (kbdkeyinfo.chChar); *k = check_ckeys (kbdkeyinfo); } os2vio_driver.getmouse (x, y, b); } return;}static voidvio_getmouse (int *x, int *y, int *b){ PTRLOC ptrLoc; MOUEVENTINFO mouEvent; MouGetPtrPos (&ptrLoc, hMou); MouReadEventQue (&mouEvent, &mouwait, hMou); *x = ptrLoc.col; *y = ptrLoc.row; if ((mouEvent.fs == 0) && (mouEvent.col == 0) && (mouEvent.row == 0)) { /* no event */ *b = buttons; draw_mouse (ptrLoc.col, ptrLoc.row, 1); return; } if (mouEvent.fs & 0x60) buttons |= BUTTON2; else buttons &= ~BUTTON2; if ((mouEvent.fs & 0x18) || (mouEvent.fs & 0x60 && mouEvent.fs & 0x06)) buttons |= BUTTON3; else buttons &= ~BUTTON3; if (mouEvent.fs & 0x06) buttons |= BUTTON1; else buttons &= ~BUTTON1; if (mouEvent.fs & 0x01) buttons = 0; *b = buttons; draw_mouse (ptrLoc.col, ptrLoc.row, 1);}static voidvio_uninitialise (){ MouSetDevStatus (&oldDeviceStatus, hMou); MouClose (hMou); VioSetMode (&orig_mode, (HVIO) 0);}static voidvio_setpalette (ui_palette pal, int start, int end){ int i; _portaccess (0x03c8, 0x03c9); for (i = 0; i <= end - start; i++) { _outp8 (0x03c8, i); _outp8 (0x03c9, pal[i][0] / 4); _outp8 (0x03c9, pal[i][1] / 4); _outp8 (0x03c9, pal[i][2] / 4); } _outp8 (0x03c8, 253); _outp8 (0x03c9, 0); _outp8 (0x03c9, 0); _outp8 (0x03c9, 0); _outp8 (0x03c8, 254); _outp8 (0x03c9, 0); _outp8 (0x03c9, 0); _outp8 (0x03c9, 40); _outp8 (0x03c8, 255); _outp8 (0x03c9, 255); _outp8 (0x03c9, 255); _outp8 (0x03c9, 255);}static voidvio_print (int x, int y, CONST char *text){ char c, t, status; int i, idx, cx, cy; fprintf (stderr, "x=%d, y=%d\n", x, y); if (y > height - os2vio_driver.textheight) return; VioScrLock (1, &status, (HVIO) 0); while ((c = *text++) != '\0') { cy = y; if (cy >= 200) { VioScrUnLock ((HVIO) 0); return; } for (i = 0; i < os2vio_driver.textheight; i++) { cx = x; if (cx >= 320) { VioScrUnLock ((HVIO) 0); return; } t = font8[c * 8 + i]; for (idx = 0; idx < 8; idx++) { if (t & 0x80) ScrPtr[cy * width + cx++] = 255; else ScrPtr[cy * width + cx++] = 254; t = t << 1; } cy++; } x += os2vio_driver.textwidth; } VioScrUnLock ((HVIO) 0);}static voidvio_display (){ PTRLOC ptrLoc; char status; /* lock screen, if possible */ VioScrLock (1, &status, (HVIO) 0); MouGetPtrPos (&ptrLoc, hMou); memcpy (ScrPtr, buffers[currentbuff], page_size); draw_mouse (ptrLoc.col, ptrLoc.row, 0); VioScrUnLock ((HVIO) 0);}static intvio_alloc (char **b1, char **b2){ *b1 = buffers[0] = (char *) malloc (width * height); *b2 = buffers[1] = (char *) malloc (width * height); currentbuff = 0; return (width);}voidvio_free (char *b1, char *b2){ free (buffers[0]); free (buffers[1]);}static voidvio_flip_buffers (){ currentbuff ^= 1;}static voidvio_clear (void){ memset (ScrPtr, 0, page_size);}static char *helptext[] = { "OS/2 VIO DRIVER VERSION 1.1 ", "========================= ", " I really like this driver, because ", " I much prefer full screen zooming ", " instead of small 320x200 window on ", " the OS/2 Desktop. ", " This XaoS driver is for OS/2 VIO mode ", " and is fully featured. ", " The following problems can ocour: ", " o It doesn't start ", " Thats can not be true. You can see ", " this text! ", " ", " As can be seen, I managed to get the ", " MouAPI working in VIO fullscreen... ", " What a fight is was.. ", " ", " OS/2 VIO driver was done by ", " Thomas A. K. Kjaer (C) 1996/97 ", " takjaer@imv.aau.dk "};#define UGLYTEXTSIZE (sizeof(helptext)/sizeof(char *))static struct params params[] = { {NULL, 0, NULL, NULL}};struct ui_driver os2vio_driver = { "OS2VIO", vio_init, vio_get_size, vio_processevents, vio_getmouse, vio_uninitialise, NULL, vio_setpalette, vio_print, vio_display, vio_alloc, vio_free, vio_flip_buffers, vio_clear, vio_mousetype, NULL, NULL, 8, 8, helptext, UGLYTEXTSIZE, params, FULLSCREEN | UPDATE_AFTER_RESIZE | PALETTE_ROTATION | ROTATE_INSIDE_CALCULATION, 0.0, 0.0, 0, 0, UI_C256, 0, 252, 253};#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -