Sorry about the resend, but I used an old copy of the source
inadvertently.

I'm new to wine and relatively new to windows programming being mostly
a unix hack.  Just for yucks I thought I'd get a relatively simple app
emu48 to work.  Turns out emu48 is not so simple (multi-threaded,
etc.).  First task towards functionality is to get the boot up display
to look right and a BitBlt didn't seem to be functioning correctly.

Much investigation later it turns out that in the file dib.c:

   /* if the source bitmap is 8bpp or less, we're supposed to use the
    * DC's palette for color conversion (not the DIB color table) */

is NOT true at least not for my case where the DC containing the
bitmap has one palette and the colormap for the bitmap is not the
same.  If I disable the hPalette tests as I did below and always use
the DIB colormap it boots up with the correct display
otherwise the color mapping  doesn't match the DIB bits and I get
garbage.


   if (dib.dsBm.bmBitsPixel <= 8) {
     HPALETTE hPalette = GetCurrentObject( physDevSrc->hdc, OBJ_PAL
);
     if (/*!hPalette || (hPalette ==
GetStockObject(DEFAULT_PALETTE))*/1) {
   /* HACK: no palette has been set in the source DC,
    * use the DIB colormap instead - this is necessary in some
    * cases since we need to do depth conversion in some places
    * where real Windows can just copy data straight over */
   colorMap = physBitmap->colorMap;
   nColorMap = physBitmap->nColorMap;

     } else {
   colorMap = X11DRV_DIB_BuildColorMap( physDevSrc, (WORD)-1,
                        dib.dsBm.bmBitsPixel,
                        (BITMAPINFO*)&dib.dsBmih,
                        &nColorMap );
   if (colorMap) aColorMap = TRUE;
     }
   }

Not knowing the full ramifications of this code I thought I'd pass
this along so that someone more familiar with it can reassess
it.

The DC and bitmap are created thusly (nLcdDoubled == 2):

#define B 0x00000000
#define W 0x00FFFFFF
#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
        }
};
VOID CreateLcdBitmap(VOID)
{
        // create LCD bitmap
        _ASSERT(nLcdDoubled == 1 || nLcdDoubled == 2 || nLcdDoubled == 4);
        bmiLcd.Lcd_bmih.biWidth = LCD1_ROW * nLcdDoubled;
        bmiLcd.Lcd_bmih.biHeight = -64 * nLcdDoubled;
        hLcdDC = CreateCompatibleDC(hWindowDC);
        _ASSERT(hLcdDC != NULL);
hLcdBitmap = CreateDIBSection(hLcdDC, (BITMAPINFO*)&bmiLcd,DIB_RGB_COLORS, (LPVOID*)&pbyLcd, NULL, 0);
        _ASSERT(hLcdBitmap != NULL);
        hOldLcdBitmap = SelectObject(hLcdDC, hLcdBitmap);
        _ASSERT(hPalette != NULL);
        SelectPalette(hLcdDC, hPalette, FALSE); // set palette for LCD DC
        RealizePalette(hLcdDC);                                 // realize 
palette
        UpdateContrast(Chipset.contrast);
}
In the new source update contrast doesn't do a SetDIBColorTable
it just plays with the pattern used to write to the dib.
static DWORD Pattern[16];

VOID UpdateContrast(BYTE byContrast)
{
        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);
                        }
                }
                return;
        }

        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;
                return;
        }

        c = (c<<16) | c;
        b = (b<<16) | b;

        if (nLcdDoubled == 4)
        {
                Pattern[0] = b;
                Pattern[1] = c;
        }
        return;
}
The BitBlt:
static BYTE Buf[36];

VOID UpdateMainDisplay(VOID)
{
        UINT  x, y, nLines;
        DWORD d = Chipset.start1;
        BYTE *p = pbyLcd;

        #if defined DEBUG_DISPLAY
        {
                TCHAR buffer[256];
                wsprintf(buffer,_T("%.5lx: Update Main Display\n"),Chipset.pc);
                OutputDebugString(buffer);
        }
        #endif

        _ASSERT(nLcdDoubled == 1 || nLcdDoubled == 2 || nLcdDoubled == 4);
        if (!Chipset.dispon)
        {
                nLines = 64;
                ZeroMemory(pbyLcd, LCD1_ROW * nLcdDoubled * nLines * 
nLcdDoubled);
        }
        else
        {
                nLines = LINES(Chipset.lcounter);       // main display lines
                if (nLcdDoubled == 4)
                {
                        for (y = 0; y < nLines; ++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;
                        }
                }
                if (nLcdDoubled == 2)
                {
                        for (y = 0; y < nLines; ++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)
                {
                        for (y = 0; y < nLines; ++y)
                        {
                                Npeek(Buf,d,36);
                                for (x=0; x<36; x++) 
*(((DWORD*)p)++)=Pattern[Buf[x]];
                                d+=Chipset.width;
                        }
                }
        }
        EnterCriticalSection(&csGDILock);           // solving NT GDI problems
        {
                BitBlt(hWindowDC, nLcdX, nLcdY, 131*nLcdDoubled, 
nLines*nLcdDoubled,
                           hLcdDC, Chipset.boffset*nLcdDoubled, 0, SRCCOPY);
                GdiFlush();
        }
        LeaveCriticalSection(&csGDILock);
        return;
}

As emu48 still doesn't work I'll probably have more things I find in
likely much different areas later.

Dave


Reply via email to