From c9307edf0cdc150910b653ad2f68d0ddfa0866f8 Mon Sep 17 00:00:00 2001 From: Ove Kaaven Date: Thu, 3 Feb 2000 00:46:29 +0000 Subject: [PATCH] Added alphanumeric mode to the VGA emulation. Use service thread for the periodic refresh. --- graphics/vga.c | 153 ++++++++++++++++++++++++++++++++++++++----------- include/vga.h | 13 ++++- 2 files changed, 130 insertions(+), 36 deletions(-) diff --git a/graphics/vga.c b/graphics/vga.c index 31e0f31eed3..1d5889c574f 100644 --- a/graphics/vga.c +++ b/graphics/vga.c @@ -7,11 +7,11 @@ #include #include "winbase.h" -#include "winuser.h" -#include "wine/winuser16.h" +#include "wincon.h" #include "miscemu.h" #include "vga.h" #include "ddraw.h" +#include "services.h" #include "debugtools.h" DEFAULT_DEBUG_CHANNEL(ddraw) @@ -20,9 +20,32 @@ static IDirectDraw *lpddraw = NULL; static IDirectDrawSurface *lpddsurf; static IDirectDrawPalette *lpddpal; static DDSURFACEDESC sdesc; -static WORD poll_timer; -static CRITICAL_SECTION vga_crit; -static int vga_polling,vga_refresh; +static LONG vga_polling,vga_refresh; +static HANDLE poll_timer; + +static void VGA_DeinstallTimer(void) +{ + if (poll_timer) { + SERVICE_Delete( poll_timer ); + poll_timer = 0; + } +} + +static void VGA_InstallTimer(unsigned Rate) +{ + VGA_DeinstallTimer(); + if (!poll_timer) + poll_timer = SERVICE_AddTimer( Rate, VGA_Poll, 0 ); +} + +HANDLE VGA_AlphaConsole(void) +{ + /* this assumes that no Win32 redirection has taken place, but then again, + * only 16-bit apps are likely to use this part of Wine... */ + return GetStdHandle(STD_OUTPUT_HANDLE); +} + +/*** GRAPHICS MODE ***/ int VGA_SetMode(unsigned Xres,unsigned Yres,unsigned Depth) { @@ -51,10 +74,8 @@ int VGA_SetMode(unsigned Xres,unsigned Yres,unsigned Depth) return 1; } vga_refresh=0; - InitializeCriticalSection(&vga_crit); - MakeCriticalSectionGlobal(&vga_crit); /* poll every 20ms (50fps should provide adequate responsiveness) */ - poll_timer = CreateSystemTimer( 20, VGA_Poll ); + VGA_InstallTimer(20000); } return 0; } @@ -72,8 +93,7 @@ int VGA_GetMode(unsigned*Height,unsigned*Width,unsigned*Depth) void VGA_Exit(void) { if (lpddraw) { - SYSTEM_KillSystemTimer(poll_timer); - DeleteCriticalSection(&vga_crit); + VGA_DeinstallTimer(); IDirectDrawSurface_Release(lpddsurf); lpddsurf=NULL; IDirectDraw_Release(lpddraw); @@ -124,37 +144,96 @@ void VGA_Unlock(void) IDirectDrawSurface_Unlock(lpddsurf,sdesc.u1.lpSurface); } -/* We are called from SIGALRM, aren't we? We should _NOT_ do synchronization - * stuff! - */ -void VGA_Poll( WORD timer ) +/*** TEXT MODE ***/ + +int VGA_SetAlphaMode(unsigned Xres,unsigned Yres) +{ + COORD siz; + + if (lpddraw) VGA_Exit(); + + /* the xterm is slow, so refresh only every 200ms (5fps) */ + VGA_InstallTimer(200000); + + siz.x = Xres; + siz.y = Yres; + SetConsoleScreenBufferSize(VGA_AlphaConsole(),siz); + return 0; +} + +void VGA_GetAlphaMode(unsigned*Xres,unsigned*Yres) +{ + CONSOLE_SCREEN_BUFFER_INFO info; + GetConsoleScreenBufferInfo(VGA_AlphaConsole(),&info); + if (Xres) *Xres=info.dwSize.x; + if (Yres) *Yres=info.dwSize.y; +} + +void VGA_SetCursorPos(unsigned X,unsigned Y) +{ + COORD pos; + + pos.x = X; + pos.y = Y; + SetConsoleCursorPosition(VGA_AlphaConsole(),pos); +} + +void VGA_GetCursorPos(unsigned*X,unsigned*Y) +{ + CONSOLE_SCREEN_BUFFER_INFO info; + GetConsoleScreenBufferInfo(VGA_AlphaConsole(),&info); + if (X) *X=info.dwCursorPosition.x; + if (Y) *Y=info.dwCursorPosition.y; +} + +/*** CONTROL ***/ + +void CALLBACK VGA_Poll( ULONG_PTR arg ) { char *dat; unsigned Pitch,Height,Width; char *surf; - int Y; - /* int X; */ + int Y,X; - EnterCriticalSection(&vga_crit); - if (!vga_polling) { - vga_polling++; - LeaveCriticalSection(&vga_crit); + if (!InterlockedExchangeAdd(&vga_polling, 1)) { /* FIXME: optimize by doing this only if the data has actually changed * (in a way similar to DIBSection, perhaps) */ - surf = VGA_Lock(&Pitch,&Height,&Width,NULL); - if (!surf) return; - dat = DOSMEM_MapDosToLinear(0xa0000); - /* copy from virtual VGA frame buffer to DirectDraw surface */ - for (Y=0; Y