2019-03-11: Updated to version 60
Signed-off-by: Gwenhael Le Moine <gwenhael.le.moine@gmail.com>
This commit is contained in:
parent
311f1aa6b5
commit
9ed4c0cec5
15 changed files with 1031 additions and 206 deletions
BIN
Emu48.dll
BIN
Emu48.dll
Binary file not shown.
BIN
Emu48.exe
BIN
Emu48.exe
Binary file not shown.
|
@ -1,9 +1,3 @@
|
|||
Additional known bugs and restrictions of Emu48 V1.59+
|
||||
------------------------------------------------------
|
||||
|
||||
- some display issues, such as when scrolling up, that were fixed in
|
||||
regular Emu48 haven't yet been merged into Emu48+
|
||||
|
||||
Known bugs and restrictions of Emu48 V1.61
|
||||
------------------------------------------
|
||||
|
||||
|
|
|
@ -467,8 +467,9 @@ VOID WriteToMainDisplay(LPBYTE a, DWORD d, UINT s)
|
|||
if (MAINSCREENHEIGHT == 0) return; // menu disabled
|
||||
|
||||
d -= Chipset.start1; // nibble offset to DISPADDR (start of display)
|
||||
y0 = y = (d / lWidth) + Chipset.d0size; // bitmap row
|
||||
x0 = x = d % lWidth; // bitmap coloumn
|
||||
d += SCREENHEIGHTREAL * lWidth; // make positive offset
|
||||
y0 = y = abs((INT)d / lWidth - SCREENHEIGHTREAL); // bitmap row
|
||||
x0 = x = (INT)d % lWidth; // bitmap column
|
||||
p = (DWORD*)(pbyLcd + y0*LCD_ROW + x0*sizeof(*p));
|
||||
|
||||
// outside main display area
|
||||
|
@ -485,21 +486,46 @@ VOID WriteToMainDisplay(LPBYTE a, DWORD d, UINT s)
|
|||
++x; // next x position
|
||||
if (((INT) x==lWidth)&&s) // end of display line
|
||||
{
|
||||
// end of main display area
|
||||
if (y == (INT)MAINSCREENHEIGHT + Chipset.d0size - 1) break;
|
||||
x = 0; // first coloumn
|
||||
++y; // next row
|
||||
if (y == (INT) MAINSCREENHEIGHT+Chipset.d0size) break;
|
||||
|
||||
// recalculate bitmap memory position of new line
|
||||
p = (DWORD*) (pbyLcd+y*LCD_ROW); // CdB for HP: add 64/80 line display for apples
|
||||
}
|
||||
else
|
||||
p++;
|
||||
}
|
||||
if (y==y0) y++;
|
||||
|
||||
// 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
|
||||
}
|
||||
|
||||
EnterCriticalSection(&csGDILock); // solving NT GDI problems
|
||||
{
|
||||
StretchBlt(hWindowDC, nLcdX, nLcdY+y0*nLcdZoom*nGdiYZoom,
|
||||
131*nLcdZoom*nGdiXZoom, (y-y0)*nLcdZoom*nGdiYZoom,
|
||||
hLcdDC, Chipset.boffset, y0, 131, y-y0, SRCCOPY); // CdB for HP: add 64/80 line display for apples
|
||||
StretchBlt(hWindowDC, nLcdX + x0*nLcdZoom*nGdiXZoom, nLcdY+y0*nLcdZoom*nGdiYZoom,
|
||||
x*nLcdZoom*nGdiXZoom, (y-y0)*nLcdZoom*nGdiYZoom,
|
||||
hLcdDC, x0 + Chipset.boffset, y0, x, y-y0, SRCCOPY); // CdB for HP: add 64/80 line display for apples
|
||||
GdiFlush();
|
||||
}
|
||||
LeaveCriticalSection(&csGDILock);
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
#include "kml.h"
|
||||
#include "debugger.h"
|
||||
|
||||
#define VERSION "1.59+"
|
||||
#define VERSION "1.60+"
|
||||
|
||||
#ifdef _DEBUG
|
||||
LPCTSTR szNoTitle = _T("Emu48 ")_T(VERSION)_T(" Debug");
|
||||
|
|
|
@ -28,9 +28,6 @@
|
|||
|
||||
#define CF_HPOBJ "CF_HPOBJ" // clipboard format for DDE
|
||||
|
||||
// CPU cycles in 16384 Hz time frame
|
||||
#define T2CYCLES ((cCurrentRomType=='S')?dwSXCycles:(cCurrentRomType=='G')?dwGXCycles:(cCurrentRomType=='P')?dwGPCycles:(cCurrentRomType=='Q')?dwGPCycles:dwG2Cycles) // CdB for HP: add apples
|
||||
|
||||
#define SM_RUN 0 // states of cpu emulation thread
|
||||
#define SM_INVALID 1
|
||||
#define SM_RETURN 2
|
||||
|
@ -205,6 +202,7 @@ extern DWORD dwSXCycles;
|
|||
extern DWORD dwGXCycles;
|
||||
extern DWORD dwGPCycles; // CdB for HP: add apples speed
|
||||
extern DWORD dwG2Cycles; // CdB for HP: add apples speed
|
||||
extern DWORD dwT2Cycles;
|
||||
extern HANDLE hEventDebug;
|
||||
extern BOOL bDbgAutoStateCtrl;
|
||||
extern INT nDbgState;
|
||||
|
@ -266,6 +264,7 @@ extern BOOL bBackup;
|
|||
extern VOID SetWindowLocation(HWND hWnd,INT nPosX,INT nPosY);
|
||||
extern DWORD GetCutPathName(LPCTSTR szFileName,LPTSTR szBuffer,DWORD dwBufferLength,INT nCutLength);
|
||||
extern VOID SetWindowPathTitle(LPCTSTR szFileName);
|
||||
extern BOOL CheckForBeepPatch(VOID);
|
||||
extern VOID UpdatePatches(BOOL bPatch);
|
||||
extern BOOL PatchRom(LPCTSTR szFilename);
|
||||
extern BOOL CrcRom(WORD *pwChk);
|
||||
|
|
|
@ -295,7 +295,7 @@ FONT 8, "MS Sans Serif"
|
|||
BEGIN
|
||||
ICON IDI_EMU48,IDC_STATIC,7,6,20,20,SS_REALSIZEIMAGE
|
||||
LTEXT "",IDC_VERSION,29,6,151,8,NOT WS_GROUP
|
||||
LTEXT "Copyright © 2018 Christoph Gießelink && Sébastien Carlier",
|
||||
LTEXT "Copyright © 2019 Christoph Gießelink && Sébastien Carlier",
|
||||
IDC_STATIC,29,18,181,8
|
||||
DEFPUSHBUTTON "OK",IDOK,215,12,39,14
|
||||
EDITTEXT IDC_LICENSE,7,33,247,112,ES_MULTILINE | ES_AUTOHSCROLL |
|
||||
|
@ -691,8 +691,8 @@ END
|
|||
//
|
||||
|
||||
VS_VERSION_INFO VERSIONINFO
|
||||
FILEVERSION 1,5,9,0
|
||||
PRODUCTVERSION 1,5,9,0
|
||||
FILEVERSION 1,6,0,0
|
||||
PRODUCTVERSION 1,6,0,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/50 Emulator\0"
|
||||
VALUE "FileVersion", "1, 5, 9, 0\0"
|
||||
VALUE "FileVersion", "1, 6, 0, 0\0"
|
||||
VALUE "InternalName", "Emu48\0"
|
||||
VALUE "LegalCopyright", "Copyright © 2018\0"
|
||||
VALUE "LegalCopyright", "Copyright © 2019\0"
|
||||
VALUE "OriginalFilename", "Emu48.exe\0"
|
||||
VALUE "ProductName", "Emu48\0"
|
||||
VALUE "ProductVersion", "1, 5, 9, 0\0"
|
||||
VALUE "ProductVersion", "1, 6, 0, 0\0"
|
||||
END
|
||||
END
|
||||
BLOCK "VarFileInfo"
|
||||
|
|
|
@ -34,6 +34,8 @@ DWORD dwGXCycles = 123; // GX cpu cycles in interval
|
|||
DWORD dwGPCycles = 123*3; // g+ cpu cycles in interval // CdB for HP: add apples display management
|
||||
DWORD dwG2Cycles = 123*2; // gII cpu cycles in interval // CdB for HP: add apples display management
|
||||
|
||||
DWORD dwT2Cycles = 0xFFFFFFFF; // CPU cycles in 16384 Hz time frame
|
||||
|
||||
// variables for debugger engine
|
||||
HANDLE hEventDebug; // event handle to stop cpu thread
|
||||
|
||||
|
@ -201,11 +203,11 @@ static __inline VOID Debugger(VOID) // debugger part
|
|||
{
|
||||
// cpu cycles for one timer2 tick elapsed
|
||||
if ((DWORD) (Chipset.cycles & 0xFFFFFFFF) - dwEDbgCycles
|
||||
>= (SAMPLE / 8192) * (DWORD) T2CYCLES)
|
||||
>= (SAMPLE / 8192) * dwT2Cycles)
|
||||
{
|
||||
--Chipset.t2;
|
||||
// adjust cycles reference
|
||||
dwEDbgCycles += (SAMPLE / 8192) * T2CYCLES;
|
||||
dwEDbgCycles += (SAMPLE / 8192) * dwT2Cycles;
|
||||
}
|
||||
}
|
||||
else // new timer2 value
|
||||
|
@ -293,7 +295,7 @@ static __inline VOID AdjustSpeed(VOID) // adjust emulation speed
|
|||
EnterCriticalSection(&csSlowLock);
|
||||
{
|
||||
// cycles elapsed for next check
|
||||
if ((dwCycles = (DWORD) (Chipset.cycles & 0xFFFFFFFF)-dwOldCyc) >= (DWORD) T2CYCLES)
|
||||
if ((dwCycles = (DWORD) (Chipset.cycles & 0xFFFFFFFF)-dwOldCyc) >= dwT2Cycles)
|
||||
{
|
||||
LARGE_INTEGER lAct;
|
||||
do
|
||||
|
@ -306,7 +308,7 @@ static __inline VOID AdjustSpeed(VOID) // adjust emulation speed
|
|||
// ticks elapsed or negative number (workaround for QueryPerformanceCounter() in Win2k)
|
||||
while (dwTicks <= dwTickRef || (dwTicks & 0x80000000) != 0);
|
||||
|
||||
dwOldCyc += T2CYCLES; // adjust cycles reference
|
||||
dwOldCyc += dwT2Cycles; // adjust cycles reference
|
||||
dwSpeedRef += dwTickRef; // adjust reference time
|
||||
}
|
||||
|
||||
|
@ -317,6 +319,32 @@ static __inline VOID AdjustSpeed(VOID) // adjust emulation speed
|
|||
return;
|
||||
}
|
||||
|
||||
static __inline VOID SetT2Cycles(VOID) // set device specific cpu cycles in interval
|
||||
{
|
||||
switch (cCurrentRomType)
|
||||
{
|
||||
case 'S': // HP48SX
|
||||
dwT2Cycles = dwSXCycles;
|
||||
break;
|
||||
case '6': // HP38G with 64KB RAM
|
||||
case 'A': // HP38G
|
||||
case 'E': // HP39/40G
|
||||
case 'G': // HP48GX
|
||||
case 'X': // HP49G
|
||||
default:
|
||||
dwT2Cycles = dwGXCycles;
|
||||
break;
|
||||
case 'P': // HP39G+
|
||||
case 'Q': // HP49G+
|
||||
dwT2Cycles = dwGPCycles;
|
||||
break;
|
||||
case '2': // HP48GII
|
||||
dwT2Cycles = dwG2Cycles;
|
||||
break;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
VOID CheckSerial(VOID)
|
||||
{
|
||||
// COM port closed and serial on
|
||||
|
@ -387,7 +415,7 @@ VOID UpdateKdnBit(VOID) // update KDN bit
|
|||
{
|
||||
if ( Chipset.intk
|
||||
&& (Chipset.IORam[TIMER2_CTRL]&RUN) != 0
|
||||
&& (DWORD) (Chipset.cycles & 0xFFFFFFFF) - Chipset.dwKdnCycles > (DWORD) T2CYCLES * 16)
|
||||
&& (DWORD) (Chipset.cycles & 0xFFFFFFFF) - Chipset.dwKdnCycles > dwT2Cycles * 16)
|
||||
IOBit(SRQ2,KDN,Chipset.in != 0);
|
||||
return;
|
||||
}
|
||||
|
@ -570,6 +598,7 @@ loop:
|
|||
dwOldCyc = (DWORD) (Chipset.cycles & 0xFFFFFFFF);
|
||||
QueryPerformanceCounter(&lDummyInt);
|
||||
dwSpeedRef = lDummyInt.LowPart;
|
||||
SetT2Cycles(); // set device specific cpu cycles in interval
|
||||
SetHP48Time(); // update HP48 time & date
|
||||
// start display counter/update engine
|
||||
StartDisplay((BYTE)(((Chipset.IORam[LINECOUNT+1]<<4)|Chipset.IORam[LINECOUNT])&0x3F));
|
||||
|
|
|
@ -194,6 +194,71 @@ VOID SetWindowPathTitle(LPCTSTR szFileName)
|
|||
|
||||
|
||||
|
||||
//################
|
||||
//#
|
||||
//# BEEP Patch check
|
||||
//#
|
||||
//################
|
||||
|
||||
BOOL CheckForBeepPatch(VOID)
|
||||
{
|
||||
typedef struct beeppatch
|
||||
{
|
||||
const DWORD dwAddress; // patch address
|
||||
const BYTE byPattern[4]; // patch pattern
|
||||
} BEEPPATCH, *PBEEPPATCH;
|
||||
|
||||
// known beep patches
|
||||
const BEEPPATCH s38[] = { { 0x017D0, { 0x8, 0x1, 0xB, 0x1 } } };
|
||||
const BEEPPATCH s39[] = { { 0x017BC, { 0x8, 0x1, 0xB, 0x1 } } };
|
||||
const BEEPPATCH s48[] = { { 0x017A6, { 0x8, 0x1, 0xB, 0x1 } } };
|
||||
const BEEPPATCH s49[] = { { 0x4157A, { 0x8, 0x1, 0xB, 0x1 } }, // 1.18/1.19-5/1.19-6
|
||||
{ 0x41609, { 0x8, 0x1, 0xB, 0x1 } } }; // 1.24/2.01/2.09
|
||||
|
||||
const BEEPPATCH *psData;
|
||||
UINT nDataItems;
|
||||
BOOL bMatch;
|
||||
|
||||
switch (cCurrentRomType)
|
||||
{
|
||||
case '6':
|
||||
case 'A': // HP38G
|
||||
psData = s38;
|
||||
nDataItems = ARRAYSIZEOF(s38);
|
||||
break;
|
||||
case 'E': // HP39/40G
|
||||
psData = s39;
|
||||
nDataItems = ARRAYSIZEOF(s39);
|
||||
break;
|
||||
case 'S': // HP48SX
|
||||
case 'G': // HP48GX
|
||||
psData = s48;
|
||||
nDataItems = ARRAYSIZEOF(s48);
|
||||
break;
|
||||
case 'X': // HP49G
|
||||
psData = s49;
|
||||
nDataItems = ARRAYSIZEOF(s49);
|
||||
break;
|
||||
default:
|
||||
psData = NULL;
|
||||
nDataItems = 0;
|
||||
}
|
||||
|
||||
// check if one data set match
|
||||
for (bMatch = FALSE; !bMatch && nDataItems > 0; --nDataItems)
|
||||
{
|
||||
_ASSERT(pbyRom != NULL && psData != NULL);
|
||||
|
||||
// pattern matching?
|
||||
bMatch = (psData->dwAddress + ARRAYSIZEOF(psData->byPattern) < dwRomSize)
|
||||
&& (memcmp(&pbyRom[psData->dwAddress],psData->byPattern,ARRAYSIZEOF(psData->byPattern))) == 0;
|
||||
++psData; // next data set
|
||||
}
|
||||
return bMatch;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//################
|
||||
//#
|
||||
//# Patch
|
||||
|
|
|
@ -2614,9 +2614,14 @@ BOOL InitKML(LPCTSTR szFilename, BOOL bNoLog)
|
|||
if (!CrcRom(&wRomCrc)) // build patched ROM fingerprint and check for unpacked data
|
||||
{
|
||||
AddToLog(_T("Error, packed ROM image detected."));
|
||||
UnmapRom(); // free memory
|
||||
goto quit;
|
||||
}
|
||||
if (CheckForBeepPatch()) // check if ROM contain beep patches
|
||||
{
|
||||
AddToLog(_T("Warning, ROM beep patch detected. Remove beep patches please."));
|
||||
bNoLog = FALSE;
|
||||
bAlwaysDisplayLog = TRUE;
|
||||
}
|
||||
|
||||
ResizeMainBitmap(nScaleMul,nScaleDiv); // resize main picture
|
||||
CreateLcdBitmap();
|
||||
|
|
843
source/LODEPNG.C
843
source/LODEPNG.C
File diff suppressed because it is too large
Load diff
212
source/LODEPNG.H
212
source/LODEPNG.H
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
LodePNG version 20180611
|
||||
LodePNG version 20180910
|
||||
|
||||
Copyright (c) 2005-2018 Lode Vandevenne
|
||||
|
||||
|
@ -255,7 +255,7 @@ const char* lodepng_error_text(unsigned code);
|
|||
typedef struct LodePNGDecompressSettings LodePNGDecompressSettings;
|
||||
struct LodePNGDecompressSettings
|
||||
{
|
||||
/* Check LodePNGDecoderSettings for more ignorable errors */
|
||||
/* Check LodePNGDecoderSettings for more ignorable errors such as ignore_crc */
|
||||
unsigned ignore_adler32; /*if 1, continue and don't give an error message if the Adler32 checksum is corrupted*/
|
||||
|
||||
/*use custom zlib decoder instead of built in one (default: null)*/
|
||||
|
@ -360,6 +360,8 @@ void lodepng_color_mode_init(LodePNGColorMode* info);
|
|||
void lodepng_color_mode_cleanup(LodePNGColorMode* info);
|
||||
/*return value is error code (0 means no error)*/
|
||||
unsigned lodepng_color_mode_copy(LodePNGColorMode* dest, const LodePNGColorMode* source);
|
||||
/* Makes a temporary LodePNGColorMode that does not need cleanup (no palette) */
|
||||
LodePNGColorMode lodepng_color_mode_make(LodePNGColorType colortype, unsigned bitdepth);
|
||||
|
||||
void lodepng_palette_clear(LodePNGColorMode* info);
|
||||
/*add 1 color to the palette*/
|
||||
|
@ -415,18 +417,30 @@ typedef struct LodePNGInfo
|
|||
|
||||
#ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS
|
||||
/*
|
||||
suggested background color chunk (bKGD)
|
||||
This color uses the same color mode as the PNG (except alpha channel), which can be 1-bit to 16-bit.
|
||||
Suggested background color chunk (bKGD)
|
||||
|
||||
For greyscale PNGs, r, g and b will all 3 be set to the same. When encoding
|
||||
the encoder writes the red one. For palette PNGs: When decoding, the RGB value
|
||||
will be stored, not a palette index. But when encoding, specify the index of
|
||||
the palette in background_r, the other two are then ignored.
|
||||
This uses the same color mode and bit depth as the PNG (except no alpha channel),
|
||||
with values truncated to the bit depth in the unsigned integer.
|
||||
|
||||
The decoder does not use this background color to edit the color of pixels.
|
||||
For greyscale and palette PNGs, the value is stored in background_r. The values
|
||||
in background_g and background_b are then unused.
|
||||
|
||||
So when decoding, you may get these in a different color mode than the one you requested
|
||||
for the raw pixels.
|
||||
|
||||
When encoding with auto_convert, you must use the color model defined in info_png.color for
|
||||
these values. The encoder normally ignores info_png.color when auto_convert is on, but will
|
||||
use it to interpret these values (and convert copies of them to its chosen color model).
|
||||
|
||||
When encoding, avoid setting this to an expensive color, such as a non-grey value
|
||||
when the image is grey, or the compression will be worse since it will be forced to
|
||||
write the PNG with a more expensive color mode (when auto_convert is on).
|
||||
|
||||
The decoder does not use this background color to edit the color of pixels. This is a
|
||||
completely optional metadata feature.
|
||||
*/
|
||||
unsigned background_defined; /*is a suggested background color given?*/
|
||||
unsigned background_r; /*red component of suggested background color*/
|
||||
unsigned background_r; /*red/grey/palette component of suggested background color*/
|
||||
unsigned background_g; /*green component of suggested background color*/
|
||||
unsigned background_b; /*blue component of suggested background color*/
|
||||
|
||||
|
@ -437,6 +451,10 @@ typedef struct LodePNGInfo
|
|||
text_strings, while text_keys are keywords that give a short description what
|
||||
the actual text represents, e.g. Title, Author, Description, or anything else.
|
||||
|
||||
All the string fields below including keys, names and language tags are null terminated.
|
||||
The PNG specification uses null characters for the keys, names and tags, and forbids null
|
||||
characters to appear in the main text which is why we can use null termination everywhere here.
|
||||
|
||||
A keyword is minimum 1 character and maximum 79 characters long. It's
|
||||
discouraged to use a single line length longer than 79 characters for texts.
|
||||
|
||||
|
@ -469,11 +487,86 @@ typedef struct LodePNGInfo
|
|||
unsigned phys_unit; /*may be 0 (unknown unit) or 1 (metre)*/
|
||||
|
||||
/*
|
||||
unknown chunks
|
||||
There are 3 buffers, one for each position in the PNG where unknown chunks can appear
|
||||
each buffer contains all unknown chunks for that position consecutively
|
||||
The 3 buffers are the unknown chunks between certain critical chunks:
|
||||
0: IHDR-PLTE, 1: PLTE-IDAT, 2: IDAT-IEND
|
||||
Color profile related chunks: gAMA, cHRM, sRGB, iCPP
|
||||
|
||||
LodePNG does not apply any color conversions on pixels in the encoder or decoder and does not interpret these color
|
||||
profile values. It merely passes on the information. If you wish to use color profiles and convert colors, please
|
||||
use these values with a color management library.
|
||||
|
||||
See the PNG, ICC and sRGB specifications for more information about the meaning of these values.
|
||||
*/
|
||||
|
||||
/* gAMA chunk: optional, overridden by sRGB or iCCP if those are present. */
|
||||
unsigned gama_defined; /* Whether a gAMA chunk is present (0 = not present, 1 = present). */
|
||||
unsigned gama_gamma; /* Gamma exponent times 100000 */
|
||||
|
||||
/* cHRM chunk: optional, overridden by sRGB or iCCP if those are present. */
|
||||
unsigned chrm_defined; /* Whether a cHRM chunk is present (0 = not present, 1 = present). */
|
||||
unsigned chrm_white_x; /* White Point x times 100000 */
|
||||
unsigned chrm_white_y; /* White Point y times 100000 */
|
||||
unsigned chrm_red_x; /* Red x times 100000 */
|
||||
unsigned chrm_red_y; /* Red y times 100000 */
|
||||
unsigned chrm_green_x; /* Green x times 100000 */
|
||||
unsigned chrm_green_y; /* Green y times 100000 */
|
||||
unsigned chrm_blue_x; /* Blue x times 100000 */
|
||||
unsigned chrm_blue_y; /* Blue y times 100000 */
|
||||
|
||||
/*
|
||||
sRGB chunk: optional. May not appear at the same time as iCCP.
|
||||
If gAMA is also present gAMA must contain value 45455.
|
||||
If cHRM is also present cHRM must contain respectively 31270,32900,64000,33000,30000,60000,15000,6000.
|
||||
*/
|
||||
unsigned srgb_defined; /* Whether an sRGB chunk is present (0 = not present, 1 = present). */
|
||||
unsigned srgb_intent; /* Rendering intent: 0=perceptual, 1=rel. colorimetric, 2=saturation, 3=abs. colorimetric */
|
||||
|
||||
/*
|
||||
iCCP chunk: optional. May not appear at the same time as sRGB.
|
||||
|
||||
LodePNG does not parse or use the ICC profile (except its color space header field for an edge case), a
|
||||
separate library to handle the ICC data (not included in LodePNG) format is needed to use it for color
|
||||
management and conversions.
|
||||
|
||||
For encoding, if iCCP is present, gAMA and cHRM are recommended to be added as well with values that match the ICC
|
||||
profile as closely as possible, if you wish to do this you should provide the correct values for gAMA and cHRM and
|
||||
enable their '_defined' flags since LodePNG will not automatically compute them from the ICC profile.
|
||||
|
||||
For encoding, the ICC profile is required by the PNG specification to be an "RGB" profile for non-grey
|
||||
PNG color types and a "GRAY" profile for grey PNG color types. If you disable auto_convert, you must ensure
|
||||
the ICC profile type matches your requested color type, else the encoder gives an error. If auto_convert is
|
||||
enabled (the default), and the ICC profile is not a good match for the pixel data, this will result in an encoder
|
||||
error if the pixel data has non-grey pixels for a GRAY profile, or a silent less-optimal compression of the pixel
|
||||
data if the pixels could be encoded as greyscale but the ICC profile is RGB.
|
||||
|
||||
To avoid this do not set an ICC profile in the image unless there is a good reason for it, and when doing so
|
||||
make sure you compute it carefully to avoid the above problems.
|
||||
*/
|
||||
unsigned iccp_defined; /* Whether an iCCP chunk is present (0 = not present, 1 = present). */
|
||||
char* iccp_name; /* Null terminated string with profile name, 1-79 bytes */
|
||||
/*
|
||||
The ICC profile in iccp_profile_size bytes.
|
||||
Don't allocate this buffer yourself. Use the init/cleanup functions
|
||||
correctly and use lodepng_set_icc and lodepng_clear_icc.
|
||||
*/
|
||||
unsigned char* iccp_profile;
|
||||
unsigned iccp_profile_size; /* The size of iccp_profile in bytes */
|
||||
|
||||
/* End of color profile related chunks */
|
||||
|
||||
|
||||
/*
|
||||
unknown chunks: chunks not known by LodePNG, passed on byte for byte.
|
||||
|
||||
There are 3 buffers, one for each position in the PNG where unknown chunks can appear.
|
||||
Each buffer contains all unknown chunks for that position consecutively.
|
||||
The 3 positions are:
|
||||
0: between IHDR and PLTE, 1: between PLTE and IDAT, 2: between IDAT and IEND.
|
||||
|
||||
For encoding, do not store critical chunks or known chunks that are enabled with a "_defined" flag
|
||||
above in here, since the encoder will blindly follow this and could then encode an invalid PNG file
|
||||
(such as one with two IHDR chunks or the disallowed combination of sRGB with iCCP). But do use
|
||||
this if you wish to store an ancillary chunk that is not supported by LodePNG (such as sPLT or hIST),
|
||||
or any non-standard PNG chunk.
|
||||
|
||||
Do not allocate or traverse this data yourself. Use the chunk traversing functions declared
|
||||
later, such as lodepng_chunk_next and lodepng_chunk_append, to read/write this struct.
|
||||
*/
|
||||
|
@ -489,12 +582,16 @@ void lodepng_info_cleanup(LodePNGInfo* info);
|
|||
unsigned lodepng_info_copy(LodePNGInfo* dest, const LodePNGInfo* source);
|
||||
|
||||
#ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS
|
||||
void lodepng_clear_text(LodePNGInfo* info); /*use this to clear the texts again after you filled them in*/
|
||||
unsigned lodepng_add_text(LodePNGInfo* info, const char* key, const char* str); /*push back both texts at once*/
|
||||
void lodepng_clear_text(LodePNGInfo* info); /*use this to clear the texts again after you filled them in*/
|
||||
|
||||
void lodepng_clear_itext(LodePNGInfo* info); /*use this to clear the itexts again after you filled them in*/
|
||||
unsigned lodepng_add_itext(LodePNGInfo* info, const char* key, const char* langtag,
|
||||
const char* transkey, const char* str); /*push back the 4 texts of 1 chunk at once*/
|
||||
void lodepng_clear_itext(LodePNGInfo* info); /*use this to clear the itexts again after you filled them in*/
|
||||
|
||||
/*replaces if exists*/
|
||||
unsigned lodepng_set_icc(LodePNGInfo* info, const char* name, const unsigned char* profile, unsigned profile_size);
|
||||
void lodepng_clear_icc(LodePNGInfo* info); /*use this to clear the texts again after you filled them in*/
|
||||
#endif /*LODEPNG_COMPILE_ANCILLARY_CHUNKS*/
|
||||
|
||||
/*
|
||||
|
@ -521,10 +618,14 @@ typedef struct LodePNGDecoderSettings
|
|||
{
|
||||
LodePNGDecompressSettings zlibsettings; /*in here is the setting to ignore Adler32 checksums*/
|
||||
|
||||
/* Check LodePNGDecompressSettings for more ignorable errors */
|
||||
/* Check LodePNGDecompressSettings for more ignorable errors such as ignore_adler32 */
|
||||
unsigned ignore_crc; /*ignore CRC checksums*/
|
||||
unsigned ignore_critical; /*ignore unknown critical chunks*/
|
||||
unsigned ignore_end; /*ignore issues at end of file if possible (missing IEND chunk, too large chunk, ...)*/
|
||||
/* TODO: make a system involving warnings with levels and a strict mode instead. Other potentially recoverable
|
||||
errors: srgb rendering intent value, size of content of ancillary chunks, more than 79 characters for some
|
||||
strings, placement/combination rules for ancillary chunks, crc of unknown chunks, allowed characters
|
||||
in string keys, etc... */
|
||||
|
||||
unsigned color_convert; /*whether to convert the PNG to the color type you want. Default: yes*/
|
||||
|
||||
|
@ -558,8 +659,11 @@ typedef enum LodePNGFilterStrategy
|
|||
LFS_PREDEFINED
|
||||
} LodePNGFilterStrategy;
|
||||
|
||||
/*Gives characteristics about the colors of the image, which helps decide which color model to use for encoding.
|
||||
Used internally by default if "auto_convert" is enabled. Public because it's useful for custom algorithms.*/
|
||||
/*Gives characteristics about the integer RGBA colors of the image (count, alpha channel usage, bit depth, ...),
|
||||
which helps decide which color model to use for encoding.
|
||||
Used internally by default if "auto_convert" is enabled. Public because it's useful for custom algorithms.
|
||||
NOTE: This is not related to the ICC color profile, search "iccp_profile" instead to find the ICC/chromacity/...
|
||||
fields in this header file.*/
|
||||
typedef struct LodePNGColorProfile
|
||||
{
|
||||
unsigned colored; /*not greyscale*/
|
||||
|
@ -571,11 +675,14 @@ typedef struct LodePNGColorProfile
|
|||
unsigned numcolors; /*amount of colors, up to 257. Not valid if bits == 16.*/
|
||||
unsigned char palette[1024]; /*Remembers up to the first 256 RGBA colors, in no particular order*/
|
||||
unsigned bits; /*bits per channel (not for palette). 1,2 or 4 for greyscale only. 16 if 16-bit per channel required.*/
|
||||
size_t numpixels;
|
||||
} LodePNGColorProfile;
|
||||
|
||||
void lodepng_color_profile_init(LodePNGColorProfile* profile);
|
||||
|
||||
/*Get a LodePNGColorProfile of the image.*/
|
||||
/*Get a LodePNGColorProfile of the image. The profile must already have been inited.
|
||||
NOTE: This is not related to the ICC color profile, search "iccp_profile" instead to find the ICC/chromacity/...
|
||||
fields in this header file.*/
|
||||
unsigned lodepng_get_color_profile(LodePNGColorProfile* profile,
|
||||
const unsigned char* image, unsigned w, unsigned h,
|
||||
const LodePNGColorMode* mode_in);
|
||||
|
@ -657,7 +764,7 @@ unsigned lodepng_decode(unsigned char** out, unsigned* w, unsigned* h,
|
|||
|
||||
/*
|
||||
Read the PNG header, but not the actual data. This returns only the information
|
||||
that is in the header chunk of the PNG, such as width, height and color type. The
|
||||
that is in the IHDR chunk of the PNG, such as width, height and color type. The
|
||||
information is placed in the info_png field of the LodePNGState.
|
||||
*/
|
||||
unsigned lodepng_inspect(unsigned* w, unsigned* h,
|
||||
|
@ -665,6 +772,20 @@ unsigned lodepng_inspect(unsigned* w, unsigned* h,
|
|||
const unsigned char* in, size_t insize);
|
||||
#endif /*LODEPNG_COMPILE_DECODER*/
|
||||
|
||||
/*
|
||||
Reads one metadata chunk (other than IHDR) of the PNG file and outputs what it
|
||||
read in the state. Returns error code on failure.
|
||||
Use lodepng_inspect first with a new state, then e.g. lodepng_chunk_find_const
|
||||
to find the desired chunk type, and if non null use lodepng_inspect_chunk (with
|
||||
chunk_pointer - start_of_file as pos).
|
||||
Supports most metadata chunks from the PNG standard (gAMA, bKGD, tEXt, ...).
|
||||
Ignores unsupported, unknown, non-metadata or IHDR chunks (without error).
|
||||
Requirements: &in[pos] must point to start of a chunk, must use regular
|
||||
lodepng_inspect first since format of most other chunks depends on IHDR, and if
|
||||
there is a PLTE chunk, that one must be inspected before tRNS or bKGD.
|
||||
*/
|
||||
unsigned lodepng_inspect_chunk(LodePNGState* state, size_t pos,
|
||||
const unsigned char* in, size_t insize);
|
||||
|
||||
#ifdef LODEPNG_COMPILE_ENCODER
|
||||
/*This function allocates the out buffer with standard malloc and stores the size in *outsize.*/
|
||||
|
@ -678,11 +799,23 @@ The lodepng_chunk functions are normally not needed, except to traverse the
|
|||
unknown chunks stored in the LodePNGInfo struct, or add new ones to it.
|
||||
It also allows traversing the chunks of an encoded PNG file yourself.
|
||||
|
||||
PNG standard chunk naming conventions:
|
||||
First byte: uppercase = critical, lowercase = ancillary
|
||||
Second byte: uppercase = public, lowercase = private
|
||||
Third byte: must be uppercase
|
||||
Fourth byte: uppercase = unsafe to copy, lowercase = safe to copy
|
||||
The chunk pointer always points to the beginning of the chunk itself, that is
|
||||
the first byte of the 4 length bytes.
|
||||
|
||||
In the PNG file format, chunks have the following format:
|
||||
-4 bytes length: length of the data of the chunk in bytes (chunk itself is 12 bytes longer)
|
||||
-4 bytes chunk type (ASCII a-z,A-Z only, see below)
|
||||
-length bytes of data (may be 0 bytes if length was 0)
|
||||
-4 bytes of CRC, computed on chunk name + data
|
||||
|
||||
The first chunk starts at the 8th byte of the PNG file, the entire rest of the file
|
||||
exists out of concatenated chunks with the above format.
|
||||
|
||||
PNG standard chunk ASCII naming conventions:
|
||||
-First byte: uppercase = critical, lowercase = ancillary
|
||||
-Second byte: uppercase = public, lowercase = private
|
||||
-Third byte: must be uppercase
|
||||
-Fourth byte: uppercase = unsafe to copy, lowercase = safe to copy
|
||||
*/
|
||||
|
||||
/*
|
||||
|
@ -717,10 +850,24 @@ unsigned lodepng_chunk_check_crc(const unsigned char* chunk);
|
|||
/*generates the correct CRC from the data and puts it in the last 4 bytes of the chunk*/
|
||||
void lodepng_chunk_generate_crc(unsigned char* chunk);
|
||||
|
||||
/*iterate to next chunks. don't use on IEND chunk, as there is no next chunk then*/
|
||||
/*
|
||||
Iterate to next chunks, allows iterating through all chunks of the PNG file.
|
||||
Input must be at the beginning of a chunk (result of a previous lodepng_chunk_next call,
|
||||
or the 8th byte of a PNG file which always has the first chunk), or alternatively may
|
||||
point to the first byte of the PNG file (which is not a chunk but the magic header, the
|
||||
function will then skip over it and return the first real chunk).
|
||||
Expects at least 8 readable bytes of memory in the input pointer.
|
||||
Will output pointer to the start of the next chunk or the end of the file if there
|
||||
is no more chunk after this. Start this process at the 8th byte of the PNG file.
|
||||
In a non-corrupt PNG file, the last chunk should have name "IEND".
|
||||
*/
|
||||
unsigned char* lodepng_chunk_next(unsigned char* chunk);
|
||||
const unsigned char* lodepng_chunk_next_const(const unsigned char* chunk);
|
||||
|
||||
/*Finds the first chunk with the given type in the range [chunk, end), or returns NULL if not found.*/
|
||||
unsigned char* lodepng_chunk_find(unsigned char* chunk, const unsigned char* end, const char type[5]);
|
||||
const unsigned char* lodepng_chunk_find_const(const unsigned char* chunk, const unsigned char* end, const char type[5]);
|
||||
|
||||
/*
|
||||
Appends chunk to the data in out. The given chunk should already have its chunk header.
|
||||
The out variable and outlength are updated to reflect the new reallocated buffer.
|
||||
|
@ -894,13 +1041,15 @@ TODO:
|
|||
[.] test if there are no memory leaks or security exploits - done a lot but needs to be checked often
|
||||
[.] check compatibility with various compilers - done but needs to be redone for every newer version
|
||||
[X] converting color to 16-bit per channel types
|
||||
[ ] read all public PNG chunk types (but never let the color profile and gamma ones touch RGB values)
|
||||
[X] support color profile chunk types (but never let them touch RGB values by default)
|
||||
[ ] support all public PNG chunk types
|
||||
[ ] make sure encoder generates no chunks with size > (2^31)-1
|
||||
[ ] partial decoding (stream processing)
|
||||
[X] let the "isFullyOpaque" function check color keys and transparent palettes too
|
||||
[X] better name for the variables "codes", "codesD", "codelengthcodes", "clcl" and "lldl"
|
||||
[ ] don't stop decoding on errors like 69, 57, 58 (make warnings)
|
||||
[ ] make warnings like: oob palette, checksum fail, data after iend, wrong/unknown crit chunk, no null terminator in text, ...
|
||||
[ ] errors with line numbers (and version)
|
||||
[ ] let the C++ wrapper catch exceptions coming from the standard library and return LodePNG error codes
|
||||
[ ] allow user to provide custom color conversion functions, e.g. for premultiplied alpha, padding bits or not, ...
|
||||
[ ] allow user to give data (void*) to custom allocator
|
||||
|
@ -1614,6 +1763,11 @@ yyyymmdd.
|
|||
Some changes aren't backwards compatible. Those are indicated with a (!)
|
||||
symbol.
|
||||
|
||||
*) 10 sep 2018: added way to inspect metadata chunks without full decoding.
|
||||
*) 19 aug 2018 (!): fixed color mode bKGD is encoded with and made it use
|
||||
palette index in case of palette.
|
||||
*) 10 aug 2018 (!): added support for gAMA, cHRM, sRGB and iCCP chunks. This
|
||||
change is backwards compatible unless you relied on unknown_chunks for those.
|
||||
*) 11 jun 2018: less restrictive check for pixel size integer overflow
|
||||
*) 14 jan 2018: allow optionally ignoring a few more recoverable errors
|
||||
*) 17 sep 2017: fix memory leak for some encoder input error cases
|
||||
|
|
|
@ -1086,7 +1086,7 @@ VOID o80810(LPBYTE I) // RSI
|
|||
ScanKeyboard(TRUE,TRUE); // one input bit high (direct)?
|
||||
|
||||
// enable KDN update
|
||||
w.dwKdnCycles = (DWORD) (w.cycles & 0xFFFFFFFF) - (DWORD) T2CYCLES * 16;
|
||||
w.dwKdnCycles = (DWORD) (w.cycles & 0xFFFFFFFF) - dwT2Cycles * 16;
|
||||
|
||||
if (w.in && w.inte == FALSE) // key interrupt pending
|
||||
w.intd = TRUE; // keyboard interrupt pending
|
||||
|
|
|
@ -448,7 +448,7 @@ VOID SoundOut(CHIPSET* w, WORD wOut)
|
|||
dwDiffSatCycles = dwCycles - dwLastCyc; // time difference from syncpoint in original Saturn cycles
|
||||
|
||||
// theoretical CPU frequency from given T2CYCLES
|
||||
dwCpuFreq = T2CYCLES * 16384;
|
||||
dwCpuFreq = dwT2Cycles * 16384;
|
||||
|
||||
if (dwDiffSatCycles > dwCpuFreq / 2) // frequency < 1 Hz
|
||||
{
|
||||
|
|
|
@ -50,7 +50,7 @@ static DWORD CalcT2(VOID) // calculate timer2 value
|
|||
DWORD dwT2Dif;
|
||||
|
||||
// timer should run a little bit faster (10%) than maschine in authentic speed mode
|
||||
DWORD dwCycPerTick = (9 * T2CYCLES) / 5;
|
||||
DWORD dwCycPerTick = (9 * dwT2Cycles) / 5;
|
||||
|
||||
QueryPerformanceCounter(&lT2Act); // actual time
|
||||
// calculate realtime timer2 ticks since reference point
|
||||
|
|
Loading…
Reference in a new issue