emu48-mirror/sources/Emu48/DISPLAY.C
2024-03-19 22:24:30 +01:00

753 lines
No EOL
19 KiB
C

/*
* display.c
*
* This file is part of Emu48
*
* Copyright (C) 1995 Sebastien Carlier
*
*/
#include "pch.h"
#include "resource.h"
#include "Emu48.h"
#include "kml.h"
#define LCD1_ROW 144
#define LCD2_ROW 288
#define LCD3_ROW 576 // 24.08.98 cg, new, X4 display
UINT nBackgroundX = 0;
UINT nBackgroundY = 0;
UINT nBackgroundW = 0;
UINT nBackgroundH = 0;
UINT nLcdX = 0;
UINT nLcdY = 0;
UINT nLcdDoubled = 1; // 24.08.98 cg, changed to integer var
LPBYTE pbyLcd;
HDC hLcdDC = NULL; // 22.01.98 cg, new, for security only
HDC hMainDC = NULL; // 22.01.98 cg, new, for security only
static HBITMAP hLcdBitmap;
static HBITMAP hMainBitmap;
static HBITMAP hOldLcdBitmap;
static HBITMAP hOldMainBitmap;
#define B 0x00FFFFFF
#define W 0x00000000
#define I 0xFFFFFFFF
static struct
{
BITMAPINFOHEADER Lcd_bmih;
DWORD dwColor[64];
} bmiLcd =
{
{0x28,0/*x*/,0/*y*/,1,8,BI_RGB,0,0,0,64,0},
{
W,B,B,B,B,B,B,B,B,B,B,B,B,B,B,B,
B,B,B,B,B,B,B,B,B,B,B,B,B,B,B,B,
I,I,I,I,I,I,I,I,I,I,I,I,I,I,I,I,
I,I,I,I,I,I,I,I,I,I,I,I,I,I,I,I
}
};
#undef B
#undef W
#undef I
static DWORD Pattern[16]; // 29.01.99 cg, new, use only one pattern
// static DWORD Pattern4[16];
// static DWORD Pattern2[4];
// static DWORD Pattern1[2]; // 24.08.98 cg, new, pattern for X4
VOID UpdateContrast(BYTE byContrast) // 23.02.99 cg, changed, new implementation
{
DWORD c = byContrast;
DWORD b = byContrast + 0x20;
if (bmiLcd.dwColor[b] == 0xFFFFFFFF) b = 0;
_ASSERT(nLcdDoubled == 1 || nLcdDoubled == 2 || nLcdDoubled == 4);
if (nLcdDoubled == 1)
{
WORD i,j;
for (i=0; i<16; ++i)
{
Pattern[i] = 0;
for (j=8; j>0; j>>=1)
{
Pattern[i] = (Pattern[i] << 8) | ((i&j) ? c : b);
}
}
}
c = (c<<8) | c;
b = (b<<8) | b;
if (nLcdDoubled == 2)
{
Pattern[0] = (b<<16)|b;
Pattern[1] = (b<<16)|c;
Pattern[2] = (c<<16)|b;
Pattern[3] = (c<<16)|c;
}
c = (c<<16) | c;
b = (b<<16) | b;
if (nLcdDoubled == 4)
{
Pattern[0] = b;
Pattern[1] = c;
}
return;
}
VOID SetLcdColor(UINT nId, UINT nRed, UINT nGreen, UINT nBlue)
{
// 25.01.08 cg, bugfix, wrong bit position of red and blue
// 23.02.99 cg, changed, allow 64 colors now
bmiLcd.dwColor[nId&0x3F] = ((nRed&0xFF)<<16)|((nGreen&0xFF)<<8)|(nBlue&0xFF);
return;
}
VOID CreateLcdBitmap()
{
// create LCD bitmap
// 24.08.98 cg, changed implementation
_ASSERT(nLcdDoubled == 1 || nLcdDoubled == 2 || nLcdDoubled == 4);
bmiLcd.Lcd_bmih.biWidth = LCD1_ROW * nLcdDoubled;
bmiLcd.Lcd_bmih.biHeight = -64 * nLcdDoubled;
// 24.08.98 cg, end of changed implementation
hLcdDC = CreateCompatibleDC(hWindowDC);
hLcdBitmap = CreateDIBSection(hLcdDC, (BITMAPINFO*)&bmiLcd,DIB_RGB_COLORS, (LPVOID*)&pbyLcd, NULL, 0);
hOldLcdBitmap = SelectObject(hLcdDC, hLcdBitmap);
UpdateContrast(Chipset.contrast); // 23.01.98 cg, bugfix, use saved contrast
}
VOID DestroyLcdBitmap()
{
WORD i;
// 23.02.99 cg, new, clear background colors
for (i=32; i< 64; ++i) bmiLcd.dwColor[i] = 0xFFFFFFFF;
if (hLcdDC != NULL)
{
// destroy LCD bitmap
SelectObject(hLcdDC, hOldLcdBitmap);
DeleteObject(hLcdBitmap);
DeleteDC(hLcdDC);
hLcdDC = NULL;
hLcdBitmap = NULL;
hOldLcdBitmap = NULL;
}
return;
}
BOOL CreateMainBitmap(LPSTR szFilename)
{
hMainDC = CreateCompatibleDC(hWindowDC);
hMainBitmap = LoadBitmapFile(szFilename);
if (hMainBitmap == NULL)
{
DeleteDC(hMainDC);
return FALSE;
}
hOldMainBitmap = SelectObject(hMainDC, hMainBitmap);
SelectPalette(hMainDC, hPalette, FALSE);
return TRUE;
}
VOID DestroyMainBitmap()
{
if (hMainDC != NULL)
{
// destroy Main bitmap
SelectObject(hMainDC, hOldMainBitmap);
DeleteObject(hMainBitmap);
DeleteDC(hMainDC);
hMainDC = NULL;
hMainBitmap = NULL;
hOldMainBitmap = NULL;
}
return;
}
//****************
//*
//* LCD functions
//*
//****************
VOID UpdateDisplayPointers()
{
// 09.09.98 cg, bugfix, calculate display width
Chipset.width = (34 + Chipset.loffset + (Chipset.boffset / 4) * 2) & 0xFFFFFFFE;
Chipset.end1 = Chipset.start1 + (Chipset.lcounter + 1) * Chipset.width;
if (Chipset.end1 < Chipset.start1)
{
// 09.09.98 cg, bugfix, calculate first address of main display
Chipset.start12 = Chipset.end1 - Chipset.width;
// 09.09.98 cg, bugfix, calculate last address of main display
Chipset.end1 = Chipset.start1 - Chipset.width;
}
else
{
Chipset.start12 = Chipset.start1;
}
Chipset.end2 = Chipset.start2 + (63 - Chipset.lcounter) * 34;
}
static BYTE Buf[36];
static BOOL bScreenIsClean = FALSE;
VOID UpdateMainDisplay() // 29.04.98 cg, bugfix, update display even if it's off
{
UINT x, y;
INT nLines;
DWORD d = Chipset.start1;
BYTE *p = pbyLcd;
if (!Chipset.dispon)
{
nLines = 64;
if (!bScreenIsClean)
{
bScreenIsClean = TRUE;
// 24.08.98 cg, changed parameter
// 05.01.99 cg, bugfix, with Zoom > 1 only a part of the display was cleared
FillMemory(pbyLcd, LCD1_ROW * nLcdDoubled * nLines * nLcdDoubled, 0);
}
}
else
{
nLines = Chipset.lcounter + 1;
bScreenIsClean = FALSE;
// 24.08.98 cg, new, new part for X4
_ASSERT(nLcdDoubled == 1 || nLcdDoubled == 2 || nLcdDoubled == 4);
if (nLcdDoubled == 4)
{
for (y=0; y<=Chipset.lcounter; y++)
{
Npeek(Buf,d,36);
for (x=0; x<36; x++)
{
*(((DWORD*)p)++)=Pattern[Buf[x]&1];
*(((DWORD*)p)++)=Pattern[(Buf[x]>>1) & 1];
*(((DWORD*)p)++)=Pattern[(Buf[x]>>2) & 1];
*(((DWORD*)p)++)=Pattern[(Buf[x]>>3) & 1];
}
CopyMemory(p, p-LCD3_ROW, LCD3_ROW);
p+=LCD3_ROW;
CopyMemory(p, p-LCD3_ROW*2, LCD3_ROW*2);
p+=LCD3_ROW*2;
d+=Chipset.width;
}
}
// 24.08.98 cg, end of new part
if (nLcdDoubled == 2) // 24.08.98 cg, new var type
{
for (y=0; y<=Chipset.lcounter; y++)
{
Npeek(Buf,d,36);
for (x=0; x<36; x++)
{
*(((DWORD*)p)++)=Pattern[Buf[x]&3];
*(((DWORD*)p)++)=Pattern[Buf[x]>>2];
}
CopyMemory(p, p-LCD2_ROW, LCD2_ROW);
p+=LCD2_ROW;
d+=Chipset.width;
}
}
if (nLcdDoubled == 1) // 24.08.98 cg, new var type
{
for (y=0; y<=Chipset.lcounter; y++)
{
Npeek(Buf,d,36);
for (x=0; x<36; x++) *(((DWORD*)p)++)=Pattern[Buf[x]];
d+=Chipset.width;
}
}
}
EnterCriticalSection(&csGDILock); // 22.01.98 cg, bugfix, solving NT GDI problems
{
// 24.08.98 cg, use of new var type
BitBlt(hWindowDC, nLcdX, nLcdY, 131*nLcdDoubled, nLines*nLcdDoubled, hLcdDC, Chipset.boffset*nLcdDoubled, 0, SRCCOPY);
GdiFlush(); // 22.01.98 cg
}
LeaveCriticalSection(&csGDILock); // 22.01.98 cg
return;
}
VOID UpdateMenuDisplay()
{
UINT x, y;
BYTE *p;
DWORD d = Chipset.start2;
if (!Chipset.dispon) return;
if (Chipset.lcounter==0x3F) return; // menu disabled
// 24.08.98 cg, new, new part for X4
_ASSERT(nLcdDoubled == 1 || nLcdDoubled == 2 || nLcdDoubled == 4);
// 18.01.99 cg, calculate offset once
p = pbyLcd + ((Chipset.lcounter+1)*nLcdDoubled*LCD1_ROW*nLcdDoubled);
if (nLcdDoubled == 4)
{
for (y=Chipset.lcounter+1; y<64; y++)
{
Npeek(Buf,d,34); // 01.02.99 cg, only 34 nibbles are viewed
for (x=0; x<36; x++)
{
*(((DWORD*)p)++)=Pattern[Buf[x]&1];
*(((DWORD*)p)++)=Pattern[(Buf[x]>>1) & 1];
*(((DWORD*)p)++)=Pattern[(Buf[x]>>2) & 1];
*(((DWORD*)p)++)=Pattern[(Buf[x]>>3) & 1];
}
CopyMemory(p, p-LCD3_ROW, LCD3_ROW);
p+=LCD3_ROW;
CopyMemory(p, p-LCD3_ROW*2, LCD3_ROW*2);
p+=LCD3_ROW*2;
d+=34;
}
}
// 24.08.98 cg, end of new part
if (nLcdDoubled == 2) // 24.08.98 cg, new var type
{
for (y=Chipset.lcounter+1; y<64; y++)
{
Npeek(Buf,d,34); // 01.02.99 cg, only 34 nibbles are viewed
for (x=0; x<36; x++)
{
*(((DWORD*)p)++)=Pattern[Buf[x]&3];
*(((DWORD*)p)++)=Pattern[Buf[x]>>2];
}
CopyMemory(p, p-LCD2_ROW, LCD2_ROW);
p+=LCD2_ROW;
d+=34;
}
}
if (nLcdDoubled == 1) // 24.08.98 cg, new var type
{
for (y=Chipset.lcounter+1; y<64; y++)
{
Npeek(Buf,d,34); // 01.02.99 cg, only 34 nibbles are viewed
for (x=0; x<36; x++) *(((DWORD*)p)++)=Pattern[Buf[x]];
d+=34;
}
}
EnterCriticalSection(&csGDILock); // 22.01.98 cg, bugfix, solving NT GDI problems
{
// 18.01.99 cg, use common output
BitBlt(hWindowDC, nLcdX, nLcdY+(Chipset.lcounter+1)*nLcdDoubled,
131*nLcdDoubled, (63-Chipset.lcounter)*nLcdDoubled,
hLcdDC, 0, (Chipset.lcounter+1)*nLcdDoubled, SRCCOPY);
GdiFlush(); // 22.01.98 cg
}
LeaveCriticalSection(&csGDILock); // 22.01.98 cg
return;
}
VOID WriteToMainDisplay(LPBYTE a, DWORD d, UINT s)
{
// 09.09.98 cg, new bugfixed implementation
// 09.03.99 cg, removed calculated corresponding source memory address
INT x0, x;
INT y0, y;
DWORD *p;
INT lWidth = abs(Chipset.width); // display width
d -= Chipset.start1; // nibble offset to DISPADDR (start of display)
d += 64 * lWidth; // make positive offset
y0 = abs((INT) d / lWidth - 64); // bitmap row
x0 = (INT) d % lWidth; // bitmap coloumn
y = y0; x = x0; // load loop variables
// outside main display area
_ASSERT(y0 >= 0 && y0 <= (INT) Chipset.lcounter);
// illegal zoom factor
_ASSERT(nLcdDoubled == 1 || nLcdDoubled == 2 || nLcdDoubled == 4);
// calculate memory position in LCD bitmap
p = (DWORD*) (pbyLcd + y0*LCD1_ROW*nLcdDoubled*nLcdDoubled
+ x0*sizeof(bmiLcd.dwColor[0])*nLcdDoubled);
while (s--) // loop for nibbles to write
{
if (x<36) // only fill visible area
{
if (nLcdDoubled == 4)
{
p[432] = p[288] = p[144] = p[0] = Pattern[(*a)&1];
p[433] = p[289] = p[145] = p[1] = Pattern[((*a)>>1) &1];
p[434] = p[290] = p[146] = p[2] = Pattern[((*a)>>2) &1];
p[435] = p[291] = p[147] = p[3] = Pattern[((*a)>>3) &1];
}
if (nLcdDoubled == 2)
{
p[72] = p[0] = Pattern[(*a)&3];
p[73] = p[1] = Pattern[(*a)>>2];
}
if (nLcdDoubled == 1)
{
*p = Pattern[*a];
}
}
++a; // next value to write
++x; // next x position
if ((x==lWidth)&&s) // end of display line
{
// end of main display area
if (y == (INT) Chipset.lcounter) break;
x = 0; // first coloumn
++y; // next row
// recalculate bitmap memory position of new line
p = (DWORD*) (pbyLcd+y*LCD1_ROW*nLcdDoubled*nLcdDoubled);
}
else
p += nLcdDoubled; // next x position in bitmap
}
// update window region
if (y0 != y) // changed more than one line
{
x0 = 0; // no x-position offset
x = 131; // redraw complete lines
++y; // redraw this line as well
}
else
{
x0 <<= 2; x <<= 2; // x-position in pixel
_ASSERT(x >= x0); // can't draw negative number of pixel
x -= x0; // number of pixels to update
x0 -= Chipset.boffset; // adjust x-position with left margin
if (x0 < 0) x0 = 0;
if (x0 > 131) x0 = 131; // cut right borders
if (x+x0 > 131) x = 131 - x0;
y = y0 + 1; // draw one line
}
x0 <<= nLcdDoubled / 2; // adjust dimensions to pixel size
x <<= nLcdDoubled / 2;
y0 <<= nLcdDoubled / 2;
y <<= nLcdDoubled / 2;
EnterCriticalSection(&csGDILock);
{
BitBlt(hWindowDC, nLcdX+x0, nLcdY+y0, x, y-y0, hLcdDC, x0+Chipset.boffset*nLcdDoubled, y0, SRCCOPY);
GdiFlush();
}
LeaveCriticalSection(&csGDILock);
#if 0
// 09.09.98 cg, removed
UINT x0, x;
UINT y0, y;
DWORD *p;
if (Chipset.width<0) return;
d -= Chipset.start1;
y0 = y = d / Chipset.width;
x0 = x = d % Chipset.width;
// 05.03.98 cg, bugfix, cut right border later
// if ((x0*4+Chipset.boffset)>=131) return;
// 24.08.98 cg, new, new part for X4
_ASSERT(nLcdDoubled == 1 || nLcdDoubled == 2 || nLcdDoubled == 4);
if (nLcdDoubled == 4)
{
p = (DWORD*)(pbyLcd + y0*LCD3_ROW*4 + x0*16);
while (s--)
{
if (x<36)
{
p[432] = p[288] = p[144] = p[0] = Pattern1[(*a)&1];
p[433] = p[289] = p[145] = p[1] = Pattern1[((*a)>>1) &1];
p[434] = p[290] = p[146] = p[2] = Pattern1[((*a)>>2) &1];
p[435] = p[291] = p[147] = p[3] = Pattern1[((*a)>>3) &1];
}
a++;
x++;
if ((x==(UINT)Chipset.width)&&s)
{
x=0;
y++;
if (y==(Chipset.lcounter+1)) break;
p=(DWORD*)(pbyLcd+y*LCD3_ROW*4);
} else p+=4;
}
EnterCriticalSection(&csGDILock); // 22.01.98 cg, bugfix, solving NT GDI problems
{
if (y0!=y)
{
y+=3;
y0<<=2; y<<=2;
BitBlt(hWindowDC, nLcdX, nLcdY+y0, 524, y-y0, hLcdDC, Chipset.boffset*4, y0, SRCCOPY);
}
else
{
if (x0>0) --x0; // 09.03.98 cg, bugfix, draw left nibble
x0<<=4; x<<=4;
if (x0>524) x0=524; // 05.03.98 cg, bugfix, cut right border
if (x >524) x =524;
y0<<=2; // y<<=1; // 09.03.98 cg, removed
BitBlt(hWindowDC, nLcdX+x0, nLcdY+y0, x-x0, 4, hLcdDC, x0+Chipset.boffset*4, y0, SRCCOPY);
}
GdiFlush(); // 22.01.98 cg
}
LeaveCriticalSection(&csGDILock); // 22.01.98 cg
}
// 24.08.98 cg, end of new part
if (nLcdDoubled == 2) // 24.08.98 cg, new var type
{
p = (DWORD*)(pbyLcd + y0*LCD2_ROW*2 + x0*8);
while (s--)
{
if (x<36)
{
p[72] = p[0] = Pattern2[(*a)&3];
p[73] = p[1] = Pattern2[(*a)>>2];
}
a++;
x++;
if ((x==(UINT)Chipset.width)&&s)
{
x=0;
y++;
if (y==(Chipset.lcounter+1)) break;
p=(DWORD*)(pbyLcd+y*LCD2_ROW*2);
} else p+=2;
}
EnterCriticalSection(&csGDILock); // 22.01.98 cg, bugfix, solving NT GDI problems
{
if (y0!=y)
{
y++;
y0<<=1; y<<=1;
BitBlt(hWindowDC, nLcdX, nLcdY+y0, 262, y-y0, hLcdDC, Chipset.boffset*2, y0, SRCCOPY);
}
else
{
if (x0>0) --x0; // 09.03.98 cg, bugfix, draw left nibble
x0<<=3; x<<=3;
if (x0>262) x0=262; // 05.03.98 cg, bugfix, cut right border
if (x >262) x =262;
y0<<=1; // y<<=1; // 09.03.98 cg, removed
BitBlt(hWindowDC, nLcdX+x0, nLcdY+y0, x-x0, 2, hLcdDC, x0+Chipset.boffset*2, y0, SRCCOPY);
}
GdiFlush(); // 22.01.98 cg
}
LeaveCriticalSection(&csGDILock); // 22.01.98 cg
}
if (nLcdDoubled == 1) // 24.08.98 cg, new var type
{
p = (DWORD*)(pbyLcd + y0*LCD1_ROW + x0*4);
while (s--)
{
if (x<36) *p = Pattern4[*a];
a++;
x++;
if ((x==(UINT)Chipset.width)&&s)
{
x=0;
y++;
if (y==(Chipset.lcounter+1)) break;
p=(DWORD*)(pbyLcd+y*LCD1_ROW);
} else p++;
}
EnterCriticalSection(&csGDILock); // 22.01.98 cg, bugfix, solving NT GDI problems
{
if (y0!=y)
{
BitBlt(hWindowDC, nLcdX, nLcdY+y0, 131, y-y0+1, hLcdDC, Chipset.boffset, y0, SRCCOPY);
}
else
{
if (x0>0) --x0; // 09.03.98 cg, bugfix, draw left nibble
x0<<=2; x<<=2;
if (x0>131) x0=131; // 05.03.98 cg, bugfix, cut right border
if (x >131) x=131;
BitBlt(hWindowDC, nLcdX+x0, nLcdY+y0, x-x0, 1, hLcdDC, x0+Chipset.boffset, y0, SRCCOPY);
}
GdiFlush(); // 22.01.98 cg
}
LeaveCriticalSection(&csGDILock); // 22.01.98 cg
}
#endif
return;
}
VOID WriteToMenuDisplay(LPBYTE a, DWORD d, UINT s)
{
UINT x0, x;
UINT y0, y;
DWORD *p;
// if (Chipset.width<0) return; // 09.09.98 cg, bugfix, allow menu update
if (Chipset.lcounter==0x3F) return; // menu disabled
d -= Chipset.start2;
y0 = y = (d / 34) + (Chipset.lcounter+1);
x0 = x = d % 34;
if (x0 > 32) return; // 01.02.99 cg, changed, position out of viewed area
// 24.08.98 cg, new, new part for X4
_ASSERT(nLcdDoubled == 1 || nLcdDoubled == 2 || nLcdDoubled == 4);
if (nLcdDoubled == 4)
{
p = (DWORD*)(pbyLcd + y0*LCD3_ROW*4 + x0*16);
while (s--)
{
if (x<34)
{
p[432] = p[288] = p[144] = p[0] = Pattern[(*a)&1];
p[433] = p[289] = p[145] = p[1] = Pattern[((*a)>>1) &1];
p[434] = p[290] = p[146] = p[2] = Pattern[((*a)>>2) &1];
p[435] = p[291] = p[147] = p[3] = Pattern[((*a)>>3) &1];
}
a++;
x++;
if ((x==34)&&s)
{
x=0;
y++;
if (y==64) break;
p=(DWORD*)(pbyLcd+y*LCD3_ROW*4);
} else p+=4;
}
EnterCriticalSection(&csGDILock); // 22.01.98 cg, bugfix, solving NT GDI problems
{
if (y0!=y)
{
y0<<=2; y<<=2;
BitBlt(hWindowDC, nLcdX, nLcdY+y0, 524, y-y0+4, hLcdDC, 0, y0, SRCCOPY);
}
else
{
x0<<=4; x<<=4;
y0<<=2; y<<=2;
if (x>524) x=524;
BitBlt(hWindowDC, nLcdX+x0, nLcdY+y0, x-x0, y-y0+4, hLcdDC, x0, y0, SRCCOPY);
}
GdiFlush(); // 22.01.98 cg
}
LeaveCriticalSection(&csGDILock); // 22.01.98 cg
}
// 24.08.98 cg, new, new part for X4
if (nLcdDoubled == 2) // 24.08.98 cg, new var type
{
p = (DWORD*)(pbyLcd + y0*LCD2_ROW*2 + x0*8);
while (s--)
{
if (x<34)
{
p[72] = p[0] = Pattern[(*a)&3];
p[73] = p[1] = Pattern[(*a)>>2];
}
a++;
x++;
if ((x==34)&&s)
{
x=0;
y++;
if (y==64) break;
p=(DWORD*)(pbyLcd+y*LCD2_ROW*2);
} else p+=2;
}
EnterCriticalSection(&csGDILock); // 22.01.98 cg, bugfix, solving NT GDI problems
{
if (y0!=y)
{
y0<<=1; y<<=1;
BitBlt(hWindowDC, nLcdX, nLcdY+y0, 262, y-y0+2, hLcdDC, 0, y0, SRCCOPY);
}
else
{
x0<<=3; x<<=3;
y0<<=1; y<<=1;
if (x>262) x=262;
BitBlt(hWindowDC, nLcdX+x0, nLcdY+y0, x-x0, y-y0+2, hLcdDC, x0, y0, SRCCOPY);
}
GdiFlush(); // 22.01.98 cg
}
LeaveCriticalSection(&csGDILock); // 22.01.98 cg
}
if (nLcdDoubled == 1) // 24.08.98 cg, new var type
{
p = (DWORD*)(pbyLcd + y0*LCD1_ROW + x0*4);
while (s--)
{
if (x<34) *p = Pattern[*a];
a++;
x++;
if ((x==34)&&s)
{
x=0;
y++;
if (y==64) break;
p=(DWORD*)(pbyLcd+y*LCD1_ROW);
} else p++;
}
EnterCriticalSection(&csGDILock); // 22.01.98 cg, bugfix, solving NT GDI problems
{
if (y0!=y)
{
BitBlt(hWindowDC, nLcdX, nLcdY+y0, 131, y-y0+1, hLcdDC, 0, y0, SRCCOPY);
}
else
{
x0<<=2; x<<=2;
if (x>131) x=131;
BitBlt(hWindowDC, nLcdX+x0, nLcdY+y0, x-x0, y-y0+1, hLcdDC, x0, y0, SRCCOPY);
}
GdiFlush(); // 22.01.98 cg
}
LeaveCriticalSection(&csGDILock); // 22.01.98 cg
}
return;
}
VOID UpdateAnnunciators()
{
BYTE c;
c = (BYTE)(Chipset.IORam[0xB] | (Chipset.IORam[0xC]<<4));
if (!(c&0x80)) c=0;
DrawAnnunciator(1,c&0x01);
DrawAnnunciator(2,c&0x02);
DrawAnnunciator(3,c&0x04);
DrawAnnunciator(4,c&0x08);
DrawAnnunciator(5,c&0x10);
DrawAnnunciator(6,c&0x20);
return;
}
VOID ResizeWindow()
{
RECT rectWindow;
RECT rectClient;
if (hWnd == NULL) return; // 30.01.98 cg, bugfix, return if window closed
rectWindow.left = 0;
rectWindow.top = 0;
rectWindow.right = nBackgroundW;
rectWindow.bottom = nBackgroundH;
AdjustWindowRect(&rectWindow, WS_CAPTION|WS_SYSMENU|WS_MINIMIZEBOX|WS_OVERLAPPED, TRUE);
SetWindowPos (hWnd, (HWND)NULL, 0, 0,
rectWindow.right - rectWindow.left,
rectWindow.bottom - rectWindow.top,
SWP_NOMOVE | SWP_NOZORDER);
GetClientRect(hWnd, &rectClient);
AdjustWindowRect(&rectClient, WS_CAPTION|WS_SYSMENU|WS_MINIMIZEBOX|WS_OVERLAPPED, TRUE);
if (rectClient.bottom < rectWindow.bottom)
{
rectWindow.bottom += (rectWindow.bottom - rectClient.bottom);
SetWindowPos (hWnd, (HWND)NULL, 0, 0,
rectWindow.right - rectWindow.left,
rectWindow.bottom - rectWindow.top,
SWP_NOMOVE | SWP_NOZORDER);
}
InvalidateRect(hWnd,NULL,TRUE);
return;
}