2018-08-18: Updated to version 1.61
Signed-off-by: Gwenhael Le Moine <gwenhael.le.moine@gmail.com>
This commit is contained in:
parent
7d4ddc1f37
commit
d67939112f
15 changed files with 8378 additions and 83 deletions
BIN
Emu48.exe
BIN
Emu48.exe
Binary file not shown.
|
@ -95,9 +95,9 @@ h3 { color:red; font-size:1.1em; }
|
|||
Emu48 v1.0 under the GPL. Without this decision newer versions of the
|
||||
emulator wouldn't have been possible or ports to other similar
|
||||
calculators wouldn't have been made. Also a big thank to Jean-Yves
|
||||
Avenard for his technical assistance in the beginning. And finally I
|
||||
want to thank all the unnamed authors for publishing material about
|
||||
these calculators.</p>
|
||||
Avenard for his technical assistance in the beginning. Lode Vandevenne
|
||||
spend the PNG image decoder and finally I want to thank all the
|
||||
unnamed authors for publishing material about these calculators.</p>
|
||||
<h1><a name=s3>3. ROM Images</a></h1>
|
||||
<p>Emu48 needs an image of a calculator ROM to be able to run. ROM
|
||||
images are valid in a packed (even address lower nibble, odd address
|
||||
|
@ -591,7 +591,7 @@ h3 { color:red; font-size:1.1em; }
|
|||
</table>
|
||||
<h1><a name=s14>14. License</a></h1>
|
||||
<p>Emu48 - A HP38G/39G/40G/48SX/48GX/49G Emulator<br>
|
||||
Copyright (C) 2017 Christoph Gießelink</p>
|
||||
Copyright (C) 2018 Christoph Gießelink</p>
|
||||
<p>This program is free software; you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License as published by the Free
|
||||
Software Foundation; either version 2 of the License, or (at your option)
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
Known bugs and restrictions of Emu48 V1.60
|
||||
Known bugs and restrictions of Emu48 V1.61
|
||||
------------------------------------------
|
||||
|
||||
- the following I/O bits aren't emulated (incomplete)
|
||||
|
@ -47,4 +47,4 @@ Known bugs and restrictions of Emu48 V1.60
|
|||
- quitting the emulator while programming the flash isn't allowed,
|
||||
because the content of flash state machine isn't saved so far
|
||||
|
||||
01/23/18 (c) by Christoph Gießelink, c dot giesselink at gmx dot de
|
||||
08/14/18 (c) by Christoph Gießelink, c dot giesselink at gmx dot de
|
||||
|
|
|
@ -1,3 +1,46 @@
|
|||
Service Pack 61 for Emu48 Version 1.0
|
||||
|
||||
EMU48.DSP
|
||||
- added lodepng.h and lodepng.c sources
|
||||
|
||||
EMU48.RC
|
||||
- changed version
|
||||
|
||||
FILES.C
|
||||
- added function DecodePng() as wrapper for decoding PNG image files
|
||||
- changed function LoadBitmapFile(), added PNG image file support
|
||||
- added function EncodeColorBits() returning bitfield position
|
||||
encoded color bits
|
||||
- bugfix in function CreateRgnFromBitmap(), removed GetObject() call
|
||||
for getting the image properties, they are get over a GetDIBits()
|
||||
query now, removed creating a memory DC because it's unused and
|
||||
added bitfield decoding which is important for the 16 bit (5:6:5)
|
||||
color setting
|
||||
|
||||
KML.C
|
||||
- changed function AdjustPixel(), changed function prototype using
|
||||
a buffer position instead of device context pixel coordinate to
|
||||
locate the adjustable pixel
|
||||
- changed function TransparentCircle(), complete new implementation
|
||||
with changed function prototype; the prior implementation used the
|
||||
GetPixel()/SetPixel() method to adjust the pixel color of a single
|
||||
pixel, this method was extremely slow on some PC configurations,
|
||||
the current method is creating a byte copy of the complete target
|
||||
area, does the pixel adjustments on byte level and finally copy
|
||||
the result back to the target device context
|
||||
- changed function DrawButton(), adjusted implementation to new
|
||||
prototype of function TransparentCircle()
|
||||
|
||||
LODEPNG.C
|
||||
- new module for decoding PNG files LodePNG version 20180611 with
|
||||
unmarked typecast patches for x64 compatibility, Copyright (c)
|
||||
2005-2018 Lode Vandevenne
|
||||
|
||||
LODEPNG.H
|
||||
- header file for decoding PNG files LodePNG version 20180611,
|
||||
Copyright (c) 2005-2018 Lode Vandevenne
|
||||
|
||||
|
||||
Service Pack 60 for Emu48 Version 1.0
|
||||
|
||||
DISRPL.C
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
#include "kml.h"
|
||||
#include "debugger.h"
|
||||
|
||||
#define VERSION "1.60"
|
||||
#define VERSION "1.61"
|
||||
|
||||
#ifdef _DEBUG
|
||||
LPCTSTR szNoTitle = _T("Emu48 ")_T(VERSION)_T(" Debug");
|
||||
|
|
|
@ -7,21 +7,21 @@
|
|||
CFG=Emu48 - Win32 Release
|
||||
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
|
||||
!MESSAGE use the Export Makefile command and run
|
||||
!MESSAGE
|
||||
!MESSAGE
|
||||
!MESSAGE NMAKE /f "Emu48.mak".
|
||||
!MESSAGE
|
||||
!MESSAGE
|
||||
!MESSAGE You can specify a configuration when running NMAKE
|
||||
!MESSAGE by defining the macro CFG on the command line. For example:
|
||||
!MESSAGE
|
||||
!MESSAGE
|
||||
!MESSAGE NMAKE /f "Emu48.mak" CFG="Emu48 - Win32 Release"
|
||||
!MESSAGE
|
||||
!MESSAGE
|
||||
!MESSAGE Possible choices for configuration are:
|
||||
!MESSAGE
|
||||
!MESSAGE
|
||||
!MESSAGE "Emu48 - Win32 Release" (based on "Win32 (x86) Application")
|
||||
!MESSAGE "Emu48 - Win32 Debug" (based on "Win32 (x86) Application")
|
||||
!MESSAGE "Emu48 - Win32 Release Unicode" (based on "Win32 (x86) Application")
|
||||
!MESSAGE "Emu48 - Win32 Debug Unicode" (based on "Win32 (x86) Application")
|
||||
!MESSAGE
|
||||
!MESSAGE
|
||||
|
||||
# Begin Project
|
||||
# PROP AllowPerConfigDependencies 0
|
||||
|
@ -138,7 +138,7 @@ LINK32=link.exe
|
|||
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib comdlg32.lib shell32.lib winmm.lib comctl32.lib advapi32.lib /nologo /subsystem:windows /debug /machine:I386
|
||||
# ADD LINK32 kernel32.lib user32.lib gdi32.lib comdlg32.lib shell32.lib winmm.lib comctl32.lib advapi32.lib ws2_32.lib /nologo /subsystem:windows /debug /machine:I386
|
||||
|
||||
!ENDIF
|
||||
!ENDIF
|
||||
|
||||
# Begin Target
|
||||
|
||||
|
@ -219,6 +219,12 @@ SOURCE=.\kml.c
|
|||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\lodepng.c
|
||||
# ADD CPP /D "LODEPNG_NO_COMPILE_ENCODER" /D "LODEPNG_NO_COMPILE_DISK" /D "LODEPNG_NO_COMPILE_ERROR_TEXT" /D "LODEPNG_NO_COMPILE_CPP"
|
||||
# SUBTRACT CPP /YX /Yc /Yu
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\lowbat.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
@ -312,6 +318,10 @@ SOURCE=.\kml.h
|
|||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\lodepng.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\opcodes.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
|
|
@ -691,8 +691,8 @@ END
|
|||
//
|
||||
|
||||
VS_VERSION_INFO VERSIONINFO
|
||||
FILEVERSION 1,6,0,0
|
||||
PRODUCTVERSION 1,6,0,0
|
||||
FILEVERSION 1,6,1,0
|
||||
PRODUCTVERSION 1,6,1,0
|
||||
FILEFLAGSMASK 0x3fL
|
||||
#ifdef _DEBUG
|
||||
FILEFLAGS 0x1L
|
||||
|
@ -709,12 +709,12 @@ BEGIN
|
|||
BEGIN
|
||||
VALUE "CompanyName", "Christoph Gießelink & Sebastien Carlier\0"
|
||||
VALUE "FileDescription", "HP38/39/40/48/49 Emulator\0"
|
||||
VALUE "FileVersion", "1, 6, 0, 0\0"
|
||||
VALUE "FileVersion", "1, 6, 1, 0\0"
|
||||
VALUE "InternalName", "Emu48\0"
|
||||
VALUE "LegalCopyright", "Copyright © 2018\0"
|
||||
VALUE "OriginalFilename", "Emu48.exe\0"
|
||||
VALUE "ProductName", "Emu48\0"
|
||||
VALUE "ProductVersion", "1, 6, 0, 0\0"
|
||||
VALUE "ProductVersion", "1, 6, 1, 0\0"
|
||||
END
|
||||
END
|
||||
BLOCK "VarFileInfo"
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
#include "kml.h"
|
||||
#include "i28f160.h" // flash support
|
||||
#include "debugger.h"
|
||||
#include "lodepng.h"
|
||||
|
||||
#pragma intrinsic(abs,labs)
|
||||
|
||||
|
@ -1474,8 +1475,8 @@ BOOL GetSaveObjectFilename(LPCTSTR lpstrFilter,LPCTSTR lpstrDefExt)
|
|||
|
||||
WORD WriteStack(UINT nStkLevel,LPBYTE lpBuf,DWORD dwSize) // separated from LoadObject()
|
||||
{
|
||||
BOOL bBinary;
|
||||
DWORD dwAddress, i;
|
||||
BOOL bBinary;
|
||||
DWORD dwAddress, i;
|
||||
|
||||
bBinary = ((lpBuf[dwSize+0]=='H')
|
||||
&& (lpBuf[dwSize+1]=='P')
|
||||
|
@ -1562,11 +1563,11 @@ BOOL LoadObject(LPCTSTR szFilename) // separated stack writing part
|
|||
|
||||
BOOL SaveObject(LPCTSTR szFilename) // separated stack reading part
|
||||
{
|
||||
HANDLE hFile;
|
||||
LPBYTE pbyHeader;
|
||||
DWORD lBytesWritten;
|
||||
DWORD dwAddress;
|
||||
DWORD dwLength;
|
||||
HANDLE hFile;
|
||||
LPBYTE pbyHeader;
|
||||
DWORD lBytesWritten;
|
||||
DWORD dwAddress;
|
||||
DWORD dwLength;
|
||||
|
||||
dwAddress = RPL_Pick(1);
|
||||
if (dwAddress == 0)
|
||||
|
@ -1926,7 +1927,7 @@ static HBITMAP DecodeGif(LPBMPFILE pBmp,DWORD *pdwTransparentColor)
|
|||
|
||||
// allocate buffer for pixels
|
||||
VERIFY(hBitmap = CreateDIBSection(hWindowDC,
|
||||
(LPBITMAPINFO)&bmi,
|
||||
&bmi,
|
||||
DIB_RGB_COLORS,
|
||||
(VOID **)&pbyPixels,
|
||||
NULL,
|
||||
|
@ -2322,6 +2323,91 @@ quit:
|
|||
return hBitmap;
|
||||
}
|
||||
|
||||
static HBITMAP DecodePng(LPBMPFILE pBmp)
|
||||
{
|
||||
// this implementation use the PNG image file decoder
|
||||
// engine of Copyright (c) 2005-2018 Lode Vandevenne
|
||||
|
||||
HBITMAP hBitmap;
|
||||
|
||||
UINT uError,uWidth,uHeight;
|
||||
INT nWidth,nHeight;
|
||||
LONG lBytesPerLine;
|
||||
|
||||
LPBYTE pbyImage; // PNG RGB image data
|
||||
LPBYTE pbySrc; // source buffer pointer
|
||||
LPBYTE pbyPixels; // BMP buffer
|
||||
|
||||
BITMAPINFO bmi;
|
||||
|
||||
hBitmap = NULL;
|
||||
pbyImage = NULL;
|
||||
|
||||
// decode PNG image
|
||||
uError = lodepng_decode_memory(&pbyImage,&uWidth,&uHeight,pBmp->pbyFile,pBmp->dwFileSize,LCT_RGB,8);
|
||||
if (uError) goto quit;
|
||||
|
||||
ZeroMemory(&bmi,sizeof(bmi)); // init bitmap info
|
||||
bmi.bmiHeader.biSize = sizeof(bmi.bmiHeader);
|
||||
bmi.bmiHeader.biWidth = (LONG) uWidth;
|
||||
bmi.bmiHeader.biHeight = (LONG) uHeight;
|
||||
bmi.bmiHeader.biPlanes = 1;
|
||||
bmi.bmiHeader.biBitCount = 24; // create a true color DIB
|
||||
bmi.bmiHeader.biCompression = BI_RGB;
|
||||
|
||||
// bitmap dimensions
|
||||
lBytesPerLine = WIDTHBYTES(bmi.bmiHeader.biWidth * bmi.bmiHeader.biBitCount);
|
||||
bmi.bmiHeader.biSizeImage = lBytesPerLine * bmi.bmiHeader.biHeight;
|
||||
|
||||
// allocate buffer for pixels
|
||||
VERIFY(hBitmap = CreateDIBSection(hWindowDC,
|
||||
&bmi,
|
||||
DIB_RGB_COLORS,
|
||||
(VOID **)&pbyPixels,
|
||||
NULL,
|
||||
0));
|
||||
if (hBitmap == NULL) goto quit;
|
||||
|
||||
pbySrc = pbyImage; // init source loop pointer
|
||||
|
||||
// fill bottom up DIB pixel buffer with color information
|
||||
for (nHeight = bmi.bmiHeader.biHeight - 1; nHeight >= 0; --nHeight)
|
||||
{
|
||||
LPBYTE pbyLine = pbyPixels + nHeight * lBytesPerLine;
|
||||
|
||||
for (nWidth = 0; nWidth < bmi.bmiHeader.biWidth; ++nWidth)
|
||||
{
|
||||
*pbyLine++ = pbySrc[2]; // blue
|
||||
*pbyLine++ = pbySrc[1]; // green
|
||||
*pbyLine++ = pbySrc[0]; // red
|
||||
pbySrc += 3;
|
||||
}
|
||||
|
||||
_ASSERT((DWORD) (pbyLine - pbyPixels) <= bmi.bmiHeader.biSizeImage);
|
||||
}
|
||||
|
||||
if (hPalette == NULL)
|
||||
{
|
||||
hPalette = CreateBIPalette((PBITMAPINFOHEADER) &bmi);
|
||||
// save old palette
|
||||
hOldPalette = SelectPalette(hWindowDC, hPalette, FALSE);
|
||||
RealizePalette(hWindowDC);
|
||||
}
|
||||
|
||||
quit:
|
||||
if (pbyImage != NULL) // buffer for PNG image allocated
|
||||
{
|
||||
free(pbyImage); // free PNG image data
|
||||
}
|
||||
|
||||
if (hBitmap != NULL && uError != 0) // creation failed
|
||||
{
|
||||
DeleteObject(hBitmap); // delete bitmap
|
||||
hBitmap = NULL;
|
||||
}
|
||||
return hBitmap;
|
||||
}
|
||||
|
||||
HBITMAP LoadBitmapFile(LPCTSTR szFilename)
|
||||
{
|
||||
HANDLE hFile;
|
||||
|
@ -2365,6 +2451,13 @@ HBITMAP LoadBitmapFile(LPCTSTR szFilename)
|
|||
break;
|
||||
}
|
||||
|
||||
// check for PNG file header
|
||||
if (Bmp.dwFileSize >= 8 && memcmp(Bmp.pbyFile,"\x89PNG\r\n\x1a\n",8) == 0)
|
||||
{
|
||||
hBitmap = DecodePng(&Bmp);
|
||||
break;
|
||||
}
|
||||
|
||||
// unknown file type
|
||||
hBitmap = NULL;
|
||||
}
|
||||
|
@ -2411,15 +2504,41 @@ static BOOL LabColorCmp(DWORD dwColor1,DWORD dwColor2,DWORD dwTol)
|
|||
return dwDiff > dwTol; // FALSE = colors match
|
||||
}
|
||||
|
||||
static DWORD EncodeColorBits(DWORD dwColorVal,DWORD dwMask)
|
||||
{
|
||||
#define MAXBIT 32
|
||||
UINT uLshift = MAXBIT;
|
||||
UINT uRshift = 8;
|
||||
DWORD dwBitMask = dwMask;
|
||||
|
||||
dwColorVal &= 0xFF; // the color component using the lowest 8 bit
|
||||
|
||||
// position of highest bit
|
||||
while ((dwBitMask & (1<<(MAXBIT-1))) == 0 && uLshift > 0)
|
||||
{
|
||||
dwBitMask <<= 1; // next bit
|
||||
--uLshift; // next position
|
||||
}
|
||||
|
||||
if (uLshift > 24) // avoid overflow on 32bit mask
|
||||
{
|
||||
uLshift -= uRshift; // normalize left shift
|
||||
uRshift = 0;
|
||||
}
|
||||
|
||||
return ((dwColorVal << uLshift) >> uRshift) & dwMask;
|
||||
#undef MAXBIT
|
||||
}
|
||||
|
||||
HRGN CreateRgnFromBitmap(HBITMAP hBmp,COLORREF color,DWORD dwTol)
|
||||
{
|
||||
#define ADD_RECTS_COUNT 256
|
||||
|
||||
BOOL (*fnColorCmp)(DWORD dwColor1,DWORD dwColor2,DWORD dwTol);
|
||||
|
||||
DWORD dwRed,dwGreen,dwBlue;
|
||||
HRGN hRgn;
|
||||
LPRGNDATA pRgnData;
|
||||
BITMAP bm;
|
||||
LPBITMAPINFO bi;
|
||||
LPBYTE pbyBits;
|
||||
LPBYTE pbyColor;
|
||||
|
@ -2429,7 +2548,6 @@ HRGN CreateRgnFromBitmap(HBITMAP hBmp,COLORREF color,DWORD dwTol)
|
|||
LONG x,y,xleft;
|
||||
BOOL bFoundLeft;
|
||||
BOOL bIsMask;
|
||||
HDC hDC;
|
||||
|
||||
if (dwTol >= 1000) // use CIE L*a*b compare
|
||||
{
|
||||
|
@ -2441,16 +2559,13 @@ HRGN CreateRgnFromBitmap(HBITMAP hBmp,COLORREF color,DWORD dwTol)
|
|||
fnColorCmp = AbsColorCmp;
|
||||
}
|
||||
|
||||
// get image properties
|
||||
GetObject(hBmp,sizeof(bm),&bm);
|
||||
|
||||
// allocate memory for extended image information incl. RGBQUAD color table
|
||||
bi = (LPBITMAPINFO) calloc(1,sizeof(BITMAPINFOHEADER) + 256 * sizeof(RGBQUAD));
|
||||
bi->bmiHeader.biSize = sizeof(bi->bmiHeader);
|
||||
_ASSERT(bi->bmiHeader.biBitCount == 0); // for query without color table
|
||||
|
||||
// get information about image
|
||||
hDC = CreateCompatibleDC(hWindowDC);
|
||||
GetDIBits(hDC,hBmp,0,bm.bmHeight,NULL,bi,DIB_RGB_COLORS);
|
||||
GetDIBits(hWindowDC,hBmp,0,0,NULL,bi,DIB_RGB_COLORS);
|
||||
|
||||
// DWORD aligned bitmap width in BYTES
|
||||
dwAlignedWidthBytes = WIDTHBYTES( bi->bmiHeader.biWidth
|
||||
|
@ -2467,24 +2582,36 @@ HRGN CreateRgnFromBitmap(HBITMAP hBmp,COLORREF color,DWORD dwTol)
|
|||
pbyBits = (LPBYTE) malloc(bi->bmiHeader.biSizeImage);
|
||||
|
||||
// fill bits buffer
|
||||
GetDIBits(hDC,hBmp,0,bi->bmiHeader.biHeight,pbyBits,bi,DIB_RGB_COLORS);
|
||||
DeleteDC(hDC);
|
||||
GetDIBits(hWindowDC,hBmp,0,bi->bmiHeader.biHeight,pbyBits,bi,DIB_RGB_COLORS);
|
||||
|
||||
// convert color if current DC is 16-bit RGB coded
|
||||
if (bi->bmiHeader.biBitCount == 16)
|
||||
// convert color if current DC is 16-bit/32-bit bitfield coded
|
||||
if (bi->bmiHeader.biCompression == BI_BITFIELDS)
|
||||
{
|
||||
// for 15 bit (5:5:5)
|
||||
color = ((color & 0xF80000) >> 19)
|
||||
| ((color & 0x00F800) >> 6)
|
||||
| ((color & 0x0000F8) << 7);
|
||||
dwRed = *(LPDWORD) &bi->bmiColors[0];
|
||||
dwGreen = *(LPDWORD) &bi->bmiColors[1];
|
||||
dwBlue = *(LPDWORD) &bi->bmiColors[2];
|
||||
}
|
||||
else
|
||||
else // RGB coded
|
||||
{
|
||||
// convert COLORREF to RGBQUAD color
|
||||
color = ((color & 0xFF0000) >> 16)
|
||||
| ((color & 0x00FF00) >> 0)
|
||||
| ((color & 0x0000FF) << 16);
|
||||
// convert color if current DC is 16-bit RGB coded
|
||||
if (bi->bmiHeader.biBitCount == 16)
|
||||
{
|
||||
// for 15 bit (5:5:5)
|
||||
dwRed = 0x00007C00;
|
||||
dwGreen = 0x000003E0;
|
||||
dwBlue = 0x0000001F;
|
||||
}
|
||||
else
|
||||
{
|
||||
// convert COLORREF to RGBQUAD color
|
||||
dwRed = 0x00FF0000;
|
||||
dwGreen = 0x0000FF00;
|
||||
dwBlue = 0x000000FF;
|
||||
}
|
||||
}
|
||||
color = EncodeColorBits((color >> 16), dwBlue)
|
||||
| EncodeColorBits((color >> 8), dwGreen)
|
||||
| EncodeColorBits((color >> 0), dwRed);
|
||||
|
||||
dwBpp = bi->bmiHeader.biBitCount >> 3; // bytes per pixel
|
||||
|
||||
|
@ -2528,7 +2655,7 @@ HRGN CreateRgnFromBitmap(HBITMAP hBmp,COLORREF color,DWORD dwTol)
|
|||
}
|
||||
pbyColor += dwBpp; // shift pointer to next color
|
||||
|
||||
if (!bFoundLeft && bIsMask) // non transparent color found
|
||||
if (!bFoundLeft && bIsMask) // non transparent color found
|
||||
{
|
||||
xleft = x;
|
||||
bFoundLeft = TRUE;
|
||||
|
|
|
@ -1813,39 +1813,59 @@ static UINT iSqrt(UINT nNumber) // integer y=sqrt(x) function
|
|||
return b;
|
||||
}
|
||||
|
||||
static VOID AdjustPixel(UINT x, UINT y, BYTE byOffset)
|
||||
static VOID AdjustPixel(LPBYTE pbyPixel, BYTE byOffset)
|
||||
{
|
||||
COLORREF rgb;
|
||||
WORD wB, wG, wR;
|
||||
INT i = 3; // BGR colors
|
||||
|
||||
rgb = GetPixel(hWindowDC, x, y);
|
||||
|
||||
// adjust color red
|
||||
wR = (((WORD) rgb) & 0x00FF) + byOffset;
|
||||
if (wR > 0xFF) wR = 0xFF;
|
||||
rgb >>= 8;
|
||||
// adjust color green
|
||||
wG = (((WORD) rgb) & 0x00FF) + byOffset;
|
||||
if (wG > 0xFF) wG = 0xFF;
|
||||
rgb >>= 8;
|
||||
// adjust color blue
|
||||
wB = (((WORD) rgb) & 0x00FF) + byOffset;
|
||||
if (wB > 0xFF) wB = 0xFF;
|
||||
|
||||
SetPixel(hWindowDC, x, y, RGB(wR,wG,wB));
|
||||
while (--i >= 0)
|
||||
{
|
||||
WORD wColor = (WORD) *pbyPixel + byOffset;
|
||||
// jumpless saturation to 0xFF
|
||||
wColor = -(wColor >> 8) | (BYTE) wColor;
|
||||
*pbyPixel++ = (BYTE) wColor;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// draw transparent circle with center coordinates and radius in pixel
|
||||
static __inline VOID TransparentCircle(UINT cx, UINT cy, UINT r)
|
||||
// draw transparent circle button type
|
||||
static __inline VOID TransparentCircle(UINT nOx, UINT nOy, UINT nCx, UINT nCy)
|
||||
{
|
||||
#define HIGHADJ 0x80 // color incr. at center
|
||||
#define LOWADJ 0x10 // color incr. at border
|
||||
|
||||
UINT x, y, rr, rrc;
|
||||
BITMAPINFO bmi;
|
||||
HDC hMemDC;
|
||||
HBITMAP hMemBitMap;
|
||||
LPBYTE pbyPixels; // BMP data
|
||||
|
||||
UINT x, y, cx, cy, r, rr, rrc;
|
||||
|
||||
r = min(nCx,nCy) / 2; // radius
|
||||
if (r < 2) return; // radius 2 pixel minimum
|
||||
|
||||
// create memory copy of button rectangle
|
||||
ZeroMemory(&bmi,sizeof(bmi));
|
||||
bmi.bmiHeader.biSize = sizeof(bmi.bmiHeader);
|
||||
bmi.bmiHeader.biWidth = (LONG) nCx;
|
||||
bmi.bmiHeader.biHeight = (LONG) nCy;
|
||||
bmi.bmiHeader.biPlanes = 1;
|
||||
bmi.bmiHeader.biBitCount = 32; // use 32 bit bitmap for easier buffer calculation
|
||||
bmi.bmiHeader.biCompression = BI_RGB;
|
||||
VERIFY(hMemBitMap = CreateDIBSection(hWindowDC,
|
||||
&bmi,
|
||||
DIB_RGB_COLORS,
|
||||
(VOID **)&pbyPixels,
|
||||
NULL,
|
||||
0));
|
||||
if (hMemBitMap == NULL) return;
|
||||
|
||||
hMemDC = CreateCompatibleDC(hWindowDC);
|
||||
hMemBitMap = (HBITMAP) SelectObject(hMemDC,hMemBitMap);
|
||||
BitBlt(hMemDC, 0, 0, nCx, nCy, hWindowDC, nOx, nOy, SRCCOPY);
|
||||
|
||||
cx = nCx / 2; // x-center coordinate
|
||||
cy = nCy / 2; // y-center coordinate
|
||||
|
||||
rr = r * r; // calculate r^2
|
||||
rrc = (r-1) * (r-1); // calculate (r-1)^2 for color steps
|
||||
|
||||
|
@ -1862,12 +1882,31 @@ static __inline VOID TransparentCircle(UINT cx, UINT cy, UINT r)
|
|||
// color offset, sqrt(x*x+y*y) < r !!!
|
||||
BYTE byOff = HIGHADJ - (BYTE) (iSqrt((x*x+yy) * (HIGHADJ-LOWADJ)*(HIGHADJ-LOWADJ) / rrc));
|
||||
|
||||
AdjustPixel(cx+x, cy+y, byOff);
|
||||
if (x != 0) AdjustPixel(cx-x, cy+y, byOff);
|
||||
if (y != 0) AdjustPixel(cx+x, cy-y, byOff);
|
||||
if (x != 0 && y != 0) AdjustPixel(cx-x, cy-y, byOff);
|
||||
AdjustPixel(pbyPixels + (((cy+y) * bmi.bmiHeader.biWidth + (cx+x)) << 2), byOff);
|
||||
|
||||
if (x != 0)
|
||||
{
|
||||
AdjustPixel(pbyPixels + (((cy+y) * bmi.bmiHeader.biWidth + (cx-x)) << 2), byOff);
|
||||
}
|
||||
|
||||
if (y != 0)
|
||||
{
|
||||
AdjustPixel(pbyPixels + (((cy-y) * bmi.bmiHeader.biWidth + (cx+x)) << 2), byOff);
|
||||
}
|
||||
|
||||
if (x != 0 && y != 0)
|
||||
{
|
||||
AdjustPixel(pbyPixels + (((cy-y) * bmi.bmiHeader.biWidth + (cx-x)) << 2), byOff);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// update button area with modified data
|
||||
BitBlt(hWindowDC, nOx, nOy, nCx, nCy, hMemDC, 0, 0, SRCCOPY);
|
||||
|
||||
// delete memory bitmap
|
||||
VERIFY(DeleteObject(SelectObject(hMemDC,hMemBitMap)));
|
||||
DeleteDC(hMemDC);
|
||||
return;
|
||||
|
||||
#undef HIGHADJ
|
||||
|
@ -1948,9 +1987,7 @@ static VOID DrawButton(UINT nId)
|
|||
case 5: // transparent circle
|
||||
if (pButton[nId].bDown)
|
||||
{
|
||||
TransparentCircle(x0 + pButton[nId].nCx / 2, // x-center coordinate
|
||||
y0 + pButton[nId].nCy / 2, // y-center coordinate
|
||||
min(pButton[nId].nCx,pButton[nId].nCy) / 2); // radius
|
||||
TransparentCircle(x0, y0, pButton[nId].nCx, pButton[nId].nCy);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
6300
Sources/Emu48/LODEPNG.C
Normal file
6300
Sources/Emu48/LODEPNG.C
Normal file
File diff suppressed because it is too large
Load diff
1770
Sources/Emu48/LODEPNG.H
Normal file
1770
Sources/Emu48/LODEPNG.H
Normal file
File diff suppressed because it is too large
Load diff
|
@ -720,8 +720,8 @@ END
|
|||
//
|
||||
|
||||
VS_VERSION_INFO VERSIONINFO
|
||||
FILEVERSION 1,6,0,0
|
||||
PRODUCTVERSION 1,6,0,0
|
||||
FILEVERSION 1,6,1,0
|
||||
PRODUCTVERSION 1,6,1,0
|
||||
FILEFLAGSMASK 0x3fL
|
||||
#ifdef _DEBUG
|
||||
FILEFLAGS 0x1L
|
||||
|
@ -738,12 +738,12 @@ BEGIN
|
|||
BEGIN
|
||||
VALUE "CompanyName", "Christoph Gießelink & Sebastien Carlier\0"
|
||||
VALUE "FileDescription", "HP38/39/40/48/49 Emulator\0"
|
||||
VALUE "FileVersion", "1, 6, 0, 0\0"
|
||||
VALUE "FileVersion", "1, 6, 1, 0\0"
|
||||
VALUE "InternalName", "Emu48\0"
|
||||
VALUE "LegalCopyright", "Copyright © 2018\0"
|
||||
VALUE "OriginalFilename", "Emu48.exe\0"
|
||||
VALUE "ProductName", "Emu48\0"
|
||||
VALUE "ProductVersion", "1, 6, 0, 0\0"
|
||||
VALUE "ProductVersion", "1, 6, 1, 0\0"
|
||||
END
|
||||
END
|
||||
BLOCK "VarFileInfo"
|
||||
|
|
|
@ -11,6 +11,11 @@ CFLAGS= -x c -O3 -Wall -Wno-missing-braces -Wno-format -Wno-uninitialized \
|
|||
DEFINES= -DIDC_STATIC=-1 \
|
||||
-DREGISTRY
|
||||
|
||||
LODEPNGDEFINES= -DLODEPNG_NO_COMPILE_ENCODER \
|
||||
-DLODEPNG_NO_COMPILE_DISK \
|
||||
-DLODEPNG_NO_COMPILE_ERROR_TEXT \
|
||||
-DLODEPNG_NO_COMPILE_CPP
|
||||
|
||||
LDFLAGS= -s -mwindows
|
||||
|
||||
TARGET=$(PRJ).exe
|
||||
|
@ -24,9 +29,9 @@ RSRCOBJ=$(PRJ).o
|
|||
|
||||
OBJS=cursor.o ddeserv.o debugger.o disasm.o dismem.o display.o disrpl.o \
|
||||
emu48.o engine.o external.o fetch.o files.o i28f160.o keyboard.o \
|
||||
keymacro.o kml.o lowbat.o mru.o mops.o opcodes.o redeye.o rpl.o \
|
||||
serial.o settings.o sndenum.o sound.o stack.o symbfile.o timer.o \
|
||||
udp.o \
|
||||
keymacro.o kml.o lodepng.o lowbat.o mru.o mops.o opcodes.o \
|
||||
redeye.o rpl.o serial.o settings.o sndenum.o sound.o stack.o \
|
||||
symbfile.o timer.o udp.o \
|
||||
$(RSRCOBJ)
|
||||
|
||||
LIBS=-lwinmm -lcomctl32 -lws2_32 -luuid
|
||||
|
@ -99,6 +104,9 @@ keymacro.o: keymacro.c pch.h resource.h Emu48.h types.h kml.h
|
|||
kml.o: kml.c pch.h resource.h emu48.h types.h kml.h
|
||||
$(CC) $(CFLAGS) $(DEFINES) -c -o kml.o kml.c
|
||||
|
||||
lodepng.o: lodepng.c lodepng.h
|
||||
$(CC) $(CFLAGS) $(DEFINES) $(LODEPNGDEFINES) -c -o lodepng.o lodepng.c
|
||||
|
||||
lowbat.o: lowbat.c pch.h emu48.h types.h io.h
|
||||
$(CC) $(CFLAGS) $(DEFINES) -c -o lowbat.o lowbat.c
|
||||
|
||||
|
|
|
@ -67,4 +67,4 @@ Many thanks to Pedro A. Arranda Guti
|
|||
compatible.
|
||||
|
||||
|
||||
01/23/18 (c) by Christoph Gießelink
|
||||
02/21/18 (c) by Christoph Gießelink
|
||||
|
|
BIN
uninst.exe
BIN
uninst.exe
Binary file not shown.
Loading…
Reference in a new issue