359 lines
11 KiB
Plaintext
359 lines
11 KiB
Plaintext
----------------------------------------------------------------------
|
|
Patch name: win32-console.patch
|
|
Author: Hartmut Birr <hartmut.birr@tesionmail.de>
|
|
Date:
|
|
|
|
Detailed description:
|
|
Add support for text modes with 8x8 characters on win32 gui.
|
|
This is usefull for ROS (50 lines console).
|
|
|
|
Apply patch to:
|
|
cvs checked out on DATE
|
|
Instructions:
|
|
To patch, go to main bochs directory.
|
|
Type "patch -p1 < THIS_PATCH_FILE".
|
|
----------------------------------------------------------------------
|
|
--- gui/win32.cc Fri Mar 15 17:45:10 2002
|
|
+++ gui/win32.cc Fri Mar 15 19:21:51 2002
|
|
@@ -119,6 +119,9 @@
|
|
static unsigned prev_block_cursor_y = 0;
|
|
static HBITMAP vgafont[256];
|
|
static unsigned x_edge=0, y_edge=0, y_caption=0;
|
|
+static int yChar = 16;
|
|
+static HFONT hFont[3];
|
|
+static int FontId = 2;
|
|
|
|
static char szAppName[] = "Bochs for Windows";
|
|
static char szWindowName[] = "Bochs for Windows - Display";
|
|
@@ -143,8 +146,11 @@
|
|
void create_vga_font(void);
|
|
static unsigned char reverse_bitorder(unsigned char);
|
|
void DrawBitmap (HDC, HBITMAP, int, int, DWORD, unsigned char cColor);
|
|
+void DrawChar (HDC, unsigned char, int, int, unsigned char cColor);
|
|
void updateUpdated(int,int,int,int);
|
|
static void headerbar_click(int x);
|
|
+void InitFont(void);
|
|
+void DestroyFont(void);
|
|
|
|
|
|
/* Macro to convert WM_ button state to BX button state */
|
|
@@ -303,7 +309,7 @@
|
|
|
|
bx_headerbar_y = headerbar_y;
|
|
dimension_x = 640;
|
|
- dimension_y = 480 + bx_headerbar_y;
|
|
+ dimension_y = 800 + bx_headerbar_y;
|
|
stretched_x = dimension_x;
|
|
stretched_y = dimension_y;
|
|
stretch_factor = 1;
|
|
@@ -391,8 +397,8 @@
|
|
WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX,
|
|
CW_USEDEFAULT,
|
|
CW_USEDEFAULT,
|
|
- stretched_x + x_edge * 2,
|
|
- stretched_y + y_edge * 2 + y_caption,
|
|
+ /*stretched_x*/dimension_x + x_edge * 2,
|
|
+ /*stretched_y*/dimension_y + y_edge * 2 + y_caption,
|
|
NULL,
|
|
NULL,
|
|
stInfo.hInstance,
|
|
@@ -400,6 +406,8 @@
|
|
|
|
if (stInfo.hwnd) {
|
|
ShowWindow (stInfo.hwnd, SW_SHOW);
|
|
+ SetWindowPos (stInfo.hwnd, NULL, 0, 0, stretched_x + x_edge * 2,
|
|
+ 480 + y_edge * 2 + y_caption, SWP_NOMOVE|SWP_NOZORDER);
|
|
UpdateWindow (stInfo.hwnd);
|
|
|
|
ShowCursor(!mouseCaptureMode);
|
|
@@ -432,6 +440,7 @@
|
|
|
|
switch (iMsg) {
|
|
case WM_CREATE:
|
|
+ InitFont();
|
|
SetTimer (hwnd, 1, 330, NULL);
|
|
bx_options.Omouse_enabled->set (mouseCaptureMode);
|
|
if (mouseCaptureMode)
|
|
@@ -450,7 +459,7 @@
|
|
cursorWarped();
|
|
}
|
|
bx_options.Omouse_enabled->set (mouseCaptureMode);
|
|
-
|
|
+
|
|
return 0;
|
|
|
|
case WM_PAINT:
|
|
@@ -501,6 +510,7 @@
|
|
case WM_DESTROY:
|
|
KillTimer (hwnd, 1);
|
|
stInfo.UIinited = FALSE;
|
|
+ DestroyFont();
|
|
|
|
PostQuitMessage (0);
|
|
return 0;
|
|
@@ -545,7 +555,7 @@
|
|
}
|
|
|
|
|
|
-void enq_key_event(Bit32u key, Bit32u press_release) {
|
|
+void enq_key_event(Bit32u key, Bit32u press_release) {
|
|
if (((tail+1) % SCANCODE_BUFSIZE) == head) {
|
|
BX_ERROR(( "enq_scancode: buffer full"));
|
|
return;
|
|
@@ -729,9 +739,15 @@
|
|
|
|
if ( (prev_block_cursor_y*80 + prev_block_cursor_x) < nchars) {
|
|
cChar = new_text[(prev_block_cursor_y*80 + prev_block_cursor_x)*2];
|
|
- DrawBitmap(hdc, vgafont[cChar], prev_block_cursor_x*8,
|
|
- prev_block_cursor_y*16 + bx_headerbar_y, SRCCOPY,
|
|
+ if (yChar >= 16) {
|
|
+ DrawBitmap(hdc, vgafont[cChar], prev_block_cursor_x*8,
|
|
+ prev_block_cursor_y*16 + bx_headerbar_y, SRCCOPY,
|
|
new_text[((prev_block_cursor_y*80 + prev_block_cursor_x)*2)+1]);
|
|
+ } else {
|
|
+ DrawChar(hdc, cChar, prev_block_cursor_x*8,
|
|
+ prev_block_cursor_y*yChar + bx_headerbar_y,
|
|
+ new_text[((prev_block_cursor_y*80 + prev_block_cursor_x)*2)+1]);
|
|
+ }
|
|
}
|
|
|
|
for (i=0; i<nchars*2; i+=2) {
|
|
@@ -742,8 +758,11 @@
|
|
|
|
x = (i/2) % 80;
|
|
y = (i/2) / 80;
|
|
-
|
|
- DrawBitmap(hdc, vgafont[cChar], x*8, y*16 + bx_headerbar_y, SRCCOPY, new_text[i+1]);
|
|
+ if(yChar>=16) {
|
|
+ DrawBitmap(hdc, vgafont[cChar], x*8, y*16 + bx_headerbar_y, SRCCOPY, new_text[i+1]);
|
|
+ } else {
|
|
+ DrawChar(hdc, cChar, x*8, y*yChar + bx_headerbar_y, new_text[i+1]);
|
|
+ }
|
|
}
|
|
}
|
|
|
|
@@ -753,15 +772,22 @@
|
|
// now draw character at new block cursor location in reverse
|
|
if (((cursor_y*80 + cursor_x) < nchars ) && (cs_start <= cs_end)) {
|
|
cChar = new_text[(cursor_y*80 + cursor_x)*2];
|
|
- memset(data, 0, sizeof(data));
|
|
- for (unsigned i=0; i<16; i++) {
|
|
- data[i*2] = reverse_bitorder(bx_vgafont[cChar].data[i]);
|
|
- if ((i >= cs_start) && (i <= cs_end))
|
|
- data[i*2] = 255 - data[i*2];
|
|
- }
|
|
- SetBitmapBits(cursorBmp, 32, data);
|
|
- DrawBitmap(hdc, cursorBmp, cursor_x*8, cursor_y*16 + bx_headerbar_y,
|
|
+ if (yChar>=16)
|
|
+ {
|
|
+ memset(data, 0, sizeof(data));
|
|
+ for (unsigned i=0; i<16; i++) {
|
|
+ data[i*2] = reverse_bitorder(bx_vgafont[cChar].data[i]);
|
|
+ if ((i >= cs_start) && (i <= cs_end))
|
|
+ data[i*2] = 255 - data[i*2];
|
|
+ }
|
|
+ SetBitmapBits(cursorBmp, 32, data);
|
|
+ DrawBitmap(hdc, cursorBmp, cursor_x*8, cursor_y*16 + bx_headerbar_y,
|
|
SRCCOPY, new_text[((cursor_y*80 + cursor_x)*2)+1]);
|
|
+ } else {
|
|
+ char cAttr = new_text[((cursor_y*80 + cursor_x)*2)+1];
|
|
+ cAttr = ((cAttr>>4)&0x0f) | ((cAttr&0x0f)<<4);
|
|
+ DrawChar(hdc, cChar, cursor_x*8, cursor_y*yChar + bx_headerbar_y, cAttr);
|
|
+ }
|
|
}
|
|
|
|
ReleaseDC(stInfo.hwnd, hdc);
|
|
@@ -862,7 +888,22 @@
|
|
stretched_y *= 2;
|
|
stretch_factor *= 2;
|
|
}
|
|
-
|
|
+
|
|
+ FontId = 2;
|
|
+ yChar = 16;
|
|
+ if(y>600)
|
|
+ {
|
|
+ FontId = 0;
|
|
+ yChar = 12;
|
|
+ dimension_y = y * yChar / 16 + bx_headerbar_y;
|
|
+ stretched_y = dimension_y * stretch_factor;
|
|
+ } else if (y>480) {
|
|
+ FontId = 1;
|
|
+ yChar = 14;
|
|
+ dimension_y = y * yChar / 16 + bx_headerbar_y;
|
|
+ stretched_y = dimension_y * stretch_factor;
|
|
+ }
|
|
+
|
|
CreateMainBitmap(stInfo.hwnd, stretched_x, stretched_y);
|
|
SetWindowPos(stInfo.hwnd, HWND_TOP, 0, 0, stretched_x + x_edge * 2,
|
|
stretched_y+ y_edge * 2 + y_caption,
|
|
@@ -964,12 +1005,12 @@
|
|
HGDIOBJ oldObj;
|
|
|
|
if (!headerbar_changed || !stInfo.UIinited) return;
|
|
-
|
|
+
|
|
EnterCriticalSection(&stInfo.drawCS);
|
|
-
|
|
+
|
|
oldObj = SelectObject(MemoryDC, MemoryBitmap);
|
|
PatBlt (MemoryDC, 0, 0, dimension_x, bx_headerbar_y, BLACKNESS);
|
|
-
|
|
+
|
|
for (unsigned i=0; i<bx_headerbar_entries; i++) {
|
|
if (bx_headerbar_entry[i].alignment == BX_GRAVITY_LEFT)
|
|
xorigin = bx_headerbar_entry[i].xorigin;
|
|
@@ -1083,29 +1124,29 @@
|
|
// BitBlt(MemoryDC, xStart, yStart, ptSize.x, ptSize.y, hdcMem, ptOrg.x,
|
|
// ptOrg.y, dwRop);
|
|
//Colors taken from Ralf Browns interrupt list.
|
|
-//(0=black, 1=blue, 2=red, 3=purple, 4=green, 5=cyan, 6=yellow, 7=white)
|
|
+//(0=black, 1=blue, 2=red, 3=purple, 4=green, 5=cyan, 6=yellow, 7=white)
|
|
//The highest background bit usually means blinking characters. No idea
|
|
//how to implement that so for now it's just implemented as color.
|
|
//Note: it is also possible to program the VGA controller to have the
|
|
//high bit for the foreground color enable blinking characters.
|
|
|
|
const COLORREF crPal[16] = {
|
|
- RGB(0 ,0 ,0 ), //0 black
|
|
- RGB(0 ,0 ,0xA8 ), //1 dark blue
|
|
- RGB(0 ,0xA8 ,0 ), //2 dark green
|
|
- RGB(0 ,0xA8 ,0xA8 ), //3 dark cyan
|
|
- RGB(0xA8 ,0 ,0 ), //4 dark red
|
|
- RGB(0xA8 ,0 ,0xA8 ), //5 dark magenta
|
|
- RGB(0xA8 ,0x54 ,0 ), //6 brown
|
|
- RGB(0xA8 ,0xA8 ,0xA8 ), //7 light gray
|
|
- RGB(0x54 ,0x54 ,0x54 ), //8 dark gray
|
|
- RGB(0x54 ,0x54 ,0xFC ), //9 light blue
|
|
- RGB(0x54 ,0xFC ,0x54 ), //10 green
|
|
- RGB(0x54 ,0xFC ,0xFC ), //11 cyan
|
|
- RGB(0xFC ,0x54 ,0x54 ), //12 light red
|
|
- RGB(0xFC ,0x54 ,0xFC ), //13 magenta
|
|
- RGB(0xFC ,0xFC ,0x54 ), //14 yellow
|
|
- RGB(0xFC ,0xFC ,0xFC ) //15 white
|
|
+ RGB(0 ,0 ,0 ), //0 black
|
|
+ RGB(0 ,0 ,0xA8 ), //1 dark blue
|
|
+ RGB(0 ,0xA8 ,0 ), //2 dark green
|
|
+ RGB(0 ,0xA8 ,0xA8 ), //3 dark cyan
|
|
+ RGB(0xA8 ,0 ,0 ), //4 dark red
|
|
+ RGB(0xA8 ,0 ,0xA8 ), //5 dark magenta
|
|
+ RGB(0xA8 ,0x54 ,0 ), //6 brown
|
|
+ RGB(0xA8 ,0xA8 ,0xA8 ), //7 light gray
|
|
+ RGB(0x54 ,0x54 ,0x54 ), //8 dark gray
|
|
+ RGB(0x54 ,0x54 ,0xFC ), //9 light blue
|
|
+ RGB(0x54 ,0xFC ,0x54 ), //10 green
|
|
+ RGB(0x54 ,0xFC ,0xFC ), //11 cyan
|
|
+ RGB(0xFC ,0x54 ,0x54 ), //12 light red
|
|
+ RGB(0xFC ,0x54 ,0xFC ), //13 magenta
|
|
+ RGB(0xFC ,0xFC ,0x54 ), //14 yellow
|
|
+ RGB(0xFC ,0xFC ,0xFC ) //15 white
|
|
};
|
|
|
|
COLORREF crFore = SetTextColor(MemoryDC, crPal[(cColor>>4)&0xf]);
|
|
@@ -1177,4 +1218,105 @@
|
|
void
|
|
bx_gui_c::mouse_enabled_changed_specific (Boolean val)
|
|
{
|
|
+}
|
|
+
|
|
+void DrawChar (HDC hdc, unsigned char c, int xStart, int yStart,
|
|
+ unsigned char cColor) {
|
|
+ HDC hdcMem;
|
|
+ POINT ptSize, ptOrg;
|
|
+ HGDIOBJ oldObj;
|
|
+ char str[2];
|
|
+ HFONT hFontOld;
|
|
+
|
|
+ hdcMem = CreateCompatibleDC (hdc);
|
|
+ SetMapMode (hdcMem, GetMapMode (hdc));
|
|
+
|
|
+ ptSize.x = 8;
|
|
+ ptSize.y = yChar;
|
|
+
|
|
+ DPtoLP (hdc, &ptSize, 1);
|
|
+
|
|
+ ptOrg.x = 0;
|
|
+ ptOrg.y = 0;
|
|
+
|
|
+ DPtoLP (hdcMem, &ptOrg, 1);
|
|
+
|
|
+ oldObj = SelectObject(MemoryDC, MemoryBitmap);
|
|
+ hFontOld=(HFONT)SelectObject(MemoryDC, hFont[FontId]);
|
|
+
|
|
+//Colors taken from Ralf Browns interrupt list.
|
|
+//(0=black, 1=blue, 2=red, 3=purple, 4=green, 5=cyan, 6=yellow, 7=white)
|
|
+//The highest background bit usually means blinking characters. No idea
|
|
+//how to implement that so for now it's just implemented as color.
|
|
+//Note: it is also possible to program the VGA controller to have the
|
|
+//high bit for the foreground color enable blinking characters.
|
|
+
|
|
+ const COLORREF crPal[16] = {
|
|
+ RGB(0 ,0 ,0 ), //0 black
|
|
+ RGB(0 ,0 ,0x80 ), //1 dark blue
|
|
+ RGB(0 ,0x80 ,0 ), //2 dark green
|
|
+ RGB(0 ,0x80 ,0x80 ), //3 dark cyan
|
|
+ RGB(0x80 ,0 ,0 ), //4 dark red
|
|
+ RGB(0x80 ,0 ,0x80 ), //5 dark magenta
|
|
+ RGB(0x80 ,0x80 ,0 ), //6 brown
|
|
+ RGB(0xc0 ,0xc0 ,0xc0 ), //7 light gray
|
|
+ RGB(0x80 ,0x80 ,0x80 ), //8 dark gray
|
|
+ RGB(0x00 ,0x00 ,0xff ), //9 light blue
|
|
+ RGB(0x00 ,0xff ,0x00 ), //10 green
|
|
+ RGB(0x00 ,0xff ,0xff ), //11 cyan
|
|
+ RGB(0xff ,0x00 ,0x00 ), //12 light red
|
|
+ RGB(0xff ,0x00 ,0xff ), //13 magenta
|
|
+ RGB(0xff ,0xff ,0x00 ), //14 yellow
|
|
+ RGB(0xff ,0xff ,0xff ) //15 white
|
|
+ };
|
|
+
|
|
+ COLORREF crFore = SetTextColor(MemoryDC, crPal[cColor&0xf]);
|
|
+ COLORREF crBack = SetBkColor(MemoryDC, crPal[(cColor>>4)&0xf]);
|
|
+ str[0]=c;
|
|
+ str[1]=0;
|
|
+ TextOut(MemoryDC, xStart, yStart, str, 1);
|
|
+ SetBkColor(MemoryDC, crBack);
|
|
+ SetTextColor(MemoryDC, crFore);
|
|
+
|
|
+ SelectObject(MemoryDC, hFontOld);
|
|
+ SelectObject(MemoryDC, oldObj);
|
|
+
|
|
+ updateUpdated(xStart, yStart, ptSize.x + xStart - 1, ptSize.y + yStart - 1);
|
|
+
|
|
+ DeleteDC (hdcMem);
|
|
+}
|
|
+
|
|
+void InitFont(void)
|
|
+{
|
|
+ LOGFONT lf;
|
|
+ int i;
|
|
+
|
|
+ lf.lfWidth = 8;
|
|
+ lf.lfEscapement = 0;
|
|
+ lf.lfOrientation = 0;
|
|
+ lf.lfWeight = FW_MEDIUM;
|
|
+ lf.lfItalic = FALSE;
|
|
+ lf.lfUnderline=FALSE;
|
|
+ lf.lfStrikeOut=FALSE;
|
|
+ lf.lfCharSet=OEM_CHARSET;
|
|
+ lf.lfOutPrecision=OUT_DEFAULT_PRECIS;
|
|
+ lf.lfClipPrecision=CLIP_DEFAULT_PRECIS;
|
|
+ lf.lfQuality=DEFAULT_QUALITY;
|
|
+ lf.lfPitchAndFamily=FIXED_PITCH | FF_DONTCARE;
|
|
+ wsprintf(lf.lfFaceName, "Lucida Console");
|
|
+
|
|
+ for (i=0; i < 3; i++)
|
|
+ {
|
|
+ lf.lfHeight = 12 + i * 2;
|
|
+ hFont[i]=CreateFontIndirect(&lf);
|
|
+ }
|
|
+}
|
|
+
|
|
+void DestroyFont(void)
|
|
+{
|
|
+ int i;
|
|
+ for(i = 0; i < 3; i++)
|
|
+ {
|
|
+ DeleteObject(hFont[i]);
|
|
+ }
|
|
}
|