vmgremx.c
来自「国外网站上的一些精典的C程序」· C语言 代码 · 共 745 行 · 第 1/2 页
C
745 行
/* * VMGREMX.C; VidMgr module for the EMX GNU C/C++ compiler. Release 1.2. * * This module written in April 1996 by Andrew Clarke and released to the * public domain. Last modified in June 1996. */#include <stdlib.h>#include <string.h>#include <dos.h>#include <sys/video.h>#define INCL_KBD#define INCL_VIO#define INCL_DOSPROCESS#include <os2.h>#include "vidmgr.h"#include "opsys.h"static int vm_iscolorcard(void);static void vm_setcursorsize(char start, char end);static void vm_getcursorsize(char *start, char *end);static void vm_getkey(unsigned char *chScan, unsigned char *chChar);static int video_init = 0;#define vi_init() { if (!video_init) video_init = v_init(); }#define vi_done() { video_init = 0; }void vm_init(void){ vi_init(); vm_getinfo(&vm_startup); vm_setattr(vm_startup.attr); if (_osmode == DOS_MODE) { opsysDetect(); }}void vm_done(void){ vm_setcursorsize(vm_startup.cur_start, vm_startup.cur_end); vi_done();}void vm_getinfo(struct vm_info *v){ v->ypos = vm_wherey(); v->xpos = vm_wherex(); v->attr = vm_getattrxy(v->xpos, v->ypos); v->height = vm_getscreenheight(); v->width = vm_getscreenwidth(); vm_getcursorsize(&v->cur_start, &v->cur_end);}char vm_getscreenwidth(void){ if (_osmode == DOS_MODE) { int width, height; vi_init(); v_dimen(&width, &height); return (char)width; } else { VIOMODEINFO vi; vi.cb = sizeof(VIOMODEINFO); VioGetMode(&vi, 0); return vi.col; }}char vm_getscreenheight(void){ if (_osmode == DOS_MODE) { int width, height; vi_init(); v_dimen(&width, &height); return (char)height; } else { VIOMODEINFO vi; vi.cb = sizeof(VIOMODEINFO); VioGetMode(&vi, 0); return vi.row; }}short vm_getscreensize(void){ return (short)(vm_getscreenwidth() * vm_getscreenheight() * 2);}char vm_wherex(void){ if (_osmode == DOS_MODE) { int row, col; vi_init(); v_getxy(&col, &row); return (char)(col + 1); } else { USHORT row, col; VioGetCurPos(&row, &col, 0); return (char)(col + 1); }}char vm_wherey(void){ if (_osmode == DOS_MODE) { int row, col; vi_init(); v_getxy(&col, &row); return (char)(row + 1); } else { USHORT row, col; VioGetCurPos(&row, &col, 0); return (char)(row + 1); }}static int vm_iscolorcard(void){ int hw = v_hardware(); return hw == V_COLOR_8 || hw == V_COLOR_12 ? 1 : 0;}void vm_gotoxy(char x, char y){ if (_osmode == DOS_MODE) { vi_init(); v_gotoxy((int)(x - 1), (int)(y - 1)); } else { VioSetCurPos((USHORT) (y - 1), (USHORT) (x - 1), 0); }}static void vm_setcursorsize(char start, char end){ if (_osmode == DOS_MODE) { vi_init(); v_ctype(start, end); } else { VIOCURSORINFO vi; vi.yStart = start; vi.cEnd = end; vi.cx = 0; vi.attr = 0; VioSetCurType(&vi, 0); }}static void vm_getcursorsize(char *start, char *end){ if (_osmode == DOS_MODE) { int cstart, cend; vi_init(); v_getctype(&cstart, &cend); *start = (char)cstart; *end = (char)cend; } else { VIOCURSORINFO vi; VioGetCurType(&vi, 0); *start = vi.yStart; *end = vi.cEnd; }}static void vm_getkey(unsigned char *chScan, unsigned char *chChar){ union REGS regs; regs.h.ah = 0x00; _int86(0x16, ®s, ®s); *chScan = regs.h.ah; *chChar = regs.h.al;}int vm_kbhit(void){ if (_osmode == DOS_MODE) { union REGS regs; static unsigned short counter = 0; if (counter % 10 == 0) { opsysTimeSlice(); } counter++; regs.h.ah = 0x01; _int86(0x16, ®s, ®s); return !(regs.x.flags & 0x40); } else { KBDKEYINFO ki; ki.fbStatus = 0; KbdPeek(&ki, 0); return ki.fbStatus & KBDTRF_FINAL_CHAR_IN; }}int vm_getch(void){ if (_osmode == DOS_MODE) { unsigned char chChar, chScan; while (!vm_kbhit()) { /* nada */ } vm_getkey(&chScan, &chChar); if (chChar == 0xe0) { if (chScan) { chChar = 0; /* force scan return */ } else { /* get next block */ chChar = 0; vm_getkey(&chScan, &chChar); if (!chScan) { /* still no scan? */ chScan = chChar; /* move new char over */ chChar = 0; /* force its return */ } else { chChar = 0; /* force new scan */ } } } if (chScan == 0xe0) { if (!chChar) { chScan = 0; vm_getkey(&chScan, &chChar); if (!chScan) { /* still no scan? */ chScan = chChar; /* move new char over */ chChar = 0; /* force its return */ } else { chChar = 0; /* force new scan */ } } else { chScan = 0; /* handle 0xe00d case */ } } if (chChar) { chScan = 0; } return (int)((chScan << 8) + (chChar)); } else { KBDKEYINFO ki; ki.chChar = 0; ki.chScan = 0; KbdCharIn(&ki, IO_WAIT, 0); if (ki.chChar == 0xe0) { if (ki.chScan) { ki.chChar = 0; /* force scan return */ } else { /* get next block */ ki.chChar = 0; KbdCharIn(&ki, IO_WAIT, 0); if (!ki.chScan) { /* still no scan? */ ki.chScan = ki.chChar; /* move new char over */ ki.chChar = 0; /* force its return */ } else { ki.chChar = 0; /* force new scan */ } } } if (ki.chScan == 0xe0) { if (!ki.chChar) { ki.chScan = 0; KbdCharIn(&ki, IO_WAIT, 0); if (!ki.chScan) { /* still no scan? */ ki.chScan = ki.chChar; /* move new char over */ ki.chChar = 0; /* force its return */ } else { ki.chChar = 0; /* force new scan */ } } else { ki.chScan = 0; /* handle 0xe00d case */ } } if (ki.chChar) { ki.chScan = 0; } return (int)((ki.chScan << 8) + (ki.chChar)); }}char vm_getchxy(char x, char y){ if (_osmode == DOS_MODE) { char cell[2]; vi_init(); v_getline(cell, (int)(x - 1), (int)(y - 1), 1); return *cell; } else { char cell[2]; USHORT len = sizeof cell; VioReadCharStr(cell, &len, (USHORT) (y - 1), (USHORT) (x - 1), 0); return *cell; }}char vm_getattrxy(char x, char y){ if (_osmode == DOS_MODE) { char cell[2]; vi_init(); v_getline(cell, (int)(x - 1), (int)(y - 1), 1); return *(cell + 1); } else {
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?