This commit is contained in:
dgis 2018-12-21 23:09:28 +00:00
parent 0f4dce6e10
commit ec570921f4
3 changed files with 167 additions and 29 deletions

View file

@ -11,6 +11,7 @@
#include "core/Emu48.h" #include "core/Emu48.h"
#include "core/io.h" #include "core/io.h"
#include "core/kml.h" #include "core/kml.h"
#include "win32-layer.h"
extern void emu48Start(); extern void emu48Start();
extern AAssetManager * assetManager; extern AAssetManager * assetManager;
@ -636,6 +637,21 @@ JNIEXPORT void JNICALL Java_com_regis_cosnier_emu48_NativeLib_onViewCopy(JNIEnv
dwLen += (DWORD) (1 << wBits) * sizeof(RGBQUAD); dwLen += (DWORD) (1 << wBits) * sizeof(RGBQUAD);
} }
size_t strideSource = (size_t)(4 * ((hBmp->bitmapInfoHeader->biWidth * hBmp->bitmapInfoHeader->biBitCount + 31) / 32));
size_t strideDestination = (size_t)(4 * hBmp->bitmapInfoHeader->biWidth * hBmp->bitmapInfoHeader->biBitCount);
VOID * bitmapBitsSource = (VOID *)hBmp->bitmapBits;
VOID * bitmapBitsDestination = pixelsDestination;
for(int y = 0; y < hBmp->bitmapInfoHeader->biHeight; y++) {
memcpy(bitmapBitsDestination, bitmapBitsSource, strideSource);
bitmapBitsSource += strideSource;
bitmapBitsDestination += strideDestination;
}
// // memory allocation for clipboard data // // memory allocation for clipboard data
// if ((hClipObj = GlobalAlloc(GMEM_MOVEABLE, dwLen)) != NULL) // if ((hClipObj = GlobalAlloc(GMEM_MOVEABLE, dwLen)) != NULL)
// { // {

View file

@ -736,8 +736,34 @@ HGDIOBJ SelectObject(HDC hdc, HGDIOBJ h) {
return NULL; return NULL;
} }
int GetObject(HANDLE h, int c, LPVOID pv) { int GetObject(HANDLE h, int c, LPVOID pv) {
//TODO if(h) {
return 0; switch (h->handleType) {
case HGDIOBJ_TYPE_PEN:
break;
case HGDIOBJ_TYPE_BRUSH:
break;
case HGDIOBJ_TYPE_FONT:
break;
case HGDIOBJ_TYPE_BITMAP:
if(h && c == sizeof(BITMAP) && pv) {
BITMAP * pBITMAP = (BITMAP *)pv;
HBITMAP hBITMAP = (HBITMAP)h;
pBITMAP->bmType = 0;
pBITMAP->bmWidth = hBITMAP->bitmapInfoHeader->biWidth;
pBITMAP->bmHeight = hBITMAP->bitmapInfoHeader->biWidth;
pBITMAP->bmWidthBytes = (4 * ((hBITMAP->bitmapInfoHeader->biWidth * hBITMAP->bitmapInfoHeader->biBitCount + 31) / 32));
pBITMAP->bmPlanes = hBITMAP->bitmapInfoHeader->biPlanes;
pBITMAP->bmBitsPixel = hBITMAP->bitmapInfoHeader->biBitCount;
pBITMAP->bmBits = (LPVOID)hBITMAP->bitmapBits;
return sizeof(BITMAP);
}
break;
case HGDIOBJ_TYPE_REGION:
break;
case HGDIOBJ_TYPE_PALETTE:
break;
}
} return 0;
} }
HGDIOBJ GetCurrentObject(HDC hdc, UINT type) { HGDIOBJ GetCurrentObject(HDC hdc, UINT type) {
//TODO //TODO
@ -849,12 +875,12 @@ BOOL StretchBlt(HDC hdcDest, int xDest, int yDest, int wDest, int hDest, HDC hdc
LOGE("AndroidBitmap_lockPixels() failed ! error=%d", ret); LOGE("AndroidBitmap_lockPixels() failed ! error=%d", ret);
} }
HBITMAP hBitmap = hdcSrc->selectedBitmap; HBITMAP hBitmapSource = hdcSrc->selectedBitmap;
void * pixelsSource = hBitmap->bitmapBits; void * pixelsSource = hBitmapSource->bitmapBits;
int sourceWidth = hBitmap->bitmapInfoHeader->biWidth; int sourceWidth = hBitmapSource->bitmapInfoHeader->biWidth;
int sourceHeight = abs(hBitmap->bitmapInfoHeader->biHeight); int sourceHeight = abs(hBitmapSource->bitmapInfoHeader->biHeight);
int destinationWidth = androidBitmapInfo.width; int destinationWidth = androidBitmapInfo.width;
int destinationHeight = androidBitmapInfo.height; int destinationHeight = androidBitmapInfo.height;
@ -867,9 +893,9 @@ BOOL StretchBlt(HDC hdcDest, int xDest, int yDest, int wDest, int hDest, HDC hdc
float dst_maxy = yDest + hDest; float dst_maxy = yDest + hDest;
float src_cury = ySrc; float src_cury = ySrc;
int sourceBytes = (hBitmap->bitmapInfoHeader->biBitCount >> 3); int sourceBytes = (hBitmapSource->bitmapInfoHeader->biBitCount >> 3);
float sourceStride = sourceWidth * sourceBytes; float sourceStride = sourceWidth * sourceBytes;
sourceStride = (float)(4 * ((sourceWidth * hBitmap->bitmapInfoHeader->biBitCount + 31) / 32)); sourceStride = (float)(4 * ((sourceWidth * hBitmapSource->bitmapInfoHeader->biBitCount + 31) / 32));
float destinationStride = androidBitmapInfo.stride; // Destination always 4 bytes RGBA float destinationStride = androidBitmapInfo.stride; // Destination always 4 bytes RGBA
//LOGD("StretchBlt(%08x, x:%d, y:%d, w:%d, h:%d, %08x, x:%d, y:%d, w:%d, h:%d) -> sourceBytes: %d", hdcDest->hdcCompatible, xDest, yDest, wDest, hDest, hdcSrc, xSrc, ySrc, wSrc, hSrc, sourceBytes); //LOGD("StretchBlt(%08x, x:%d, y:%d, w:%d, h:%d, %08x, x:%d, y:%d, w:%d, h:%d) -> sourceBytes: %d", hdcDest->hdcCompatible, xDest, yDest, wDest, hDest, hdcSrc, xSrc, ySrc, wSrc, hSrc, sourceBytes);
@ -910,7 +936,7 @@ BOOL StretchBlt(HDC hdcDest, int xDest, int yDest, int wDest, int hDest, HDC hdc
destinationPixel[3] = 255; destinationPixel[3] = 255;
break; break;
case 4: case 4:
memcpy(destinationPixel, sourcePixel, sourceBytes); memcpy(destinationPixel, sourcePixel, (size_t) sourceBytes);
break; break;
default: default:
break; break;
@ -929,6 +955,84 @@ BOOL StretchBlt(HDC hdcDest, int xDest, int yDest, int wDest, int hDest, HDC hdc
//mainViewUpdateCallback(); //mainViewUpdateCallback();
return TRUE; return TRUE;
} else if(hdcDest->selectedBitmap && hdcSrc->selectedBitmap && hDest && hSrc) {
// We update the main window
HBITMAP hBitmapSource = hdcSrc->selectedBitmap;
void * pixelsSource = (void *) hBitmapSource->bitmapBits;
HBITMAP hBitmapDestination = hdcDest->selectedBitmap;
void * pixelsDestination = (void *) hBitmapDestination->bitmapBits;
int sourceWidth = hBitmapSource->bitmapInfoHeader->biWidth;
int sourceHeight = abs(hBitmapSource->bitmapInfoHeader->biHeight);
int destinationWidth = hBitmapDestination->bitmapInfoHeader->biWidth;
int destinationHeight = abs(hBitmapDestination->bitmapInfoHeader->biHeight);
//https://softwareengineering.stackexchange.com/questions/148123/what-is-the-algorithm-to-copy-a-region-of-one-bitmap-into-a-region-in-another
float src_dx = (float)wSrc / (float)wDest;
float src_dy = (float)hSrc / (float)hDest;
float src_maxx = xSrc + wSrc;
float src_maxy = ySrc + hSrc;
float dst_maxx = xDest + wDest;
float dst_maxy = yDest + hDest;
float src_cury = ySrc;
int sourceBytes = (hBitmapSource->bitmapInfoHeader->biBitCount >> 3);
float sourceStride = (float)(4 * ((sourceWidth * sourceBytes * hBitmapSource->bitmapInfoHeader->biBitCount + 31) / 32));
int destinationBytes = (hBitmapDestination->bitmapInfoHeader->biBitCount >> 3);
float destinationStride = (float)(4 * ((destinationWidth * destinationBytes * hBitmapDestination->bitmapInfoHeader->biBitCount + 31) / 32));
//LOGD("StretchBlt(%08x, x:%d, y:%d, w:%d, h:%d, %08x, x:%d, y:%d, w:%d, h:%d) -> sourceBytes: %d", hdcDest->hdcCompatible, xDest, yDest, wDest, hDest, hdcSrc, xSrc, ySrc, wSrc, hSrc, sourceBytes);
PALETTEENTRY * palPalEntry = hdcSrc->selectedPalette && hdcSrc->selectedPalette->paletteLog && hdcSrc->selectedPalette->paletteLog->palPalEntry ?
hdcSrc->selectedPalette->paletteLog->palPalEntry : NULL;
for (float y = yDest; y < dst_maxy; y++)
{
float src_curx = xSrc;
for (float x = xDest; x < dst_maxx; x++)
{
// Point sampling - you can also impl as bilinear or other
//dst.bmp[x,y] = src.bmp[src_curx, src_cury];
BYTE * destinationPixel = pixelsDestination + (int)(4.0 * x + destinationStride * y);
BYTE * sourcePixel = pixelsSource + (int)(sourceBytes * (int)src_curx) + (int)(sourceStride * (int)src_cury);
// -> ARGB_8888
switch (sourceBytes) {
case 1:
if(palPalEntry) {
BYTE colorIndex = sourcePixel[0];
destinationPixel[0] = palPalEntry[colorIndex].peBlue;
destinationPixel[1] = palPalEntry[colorIndex].peGreen;
destinationPixel[2] = palPalEntry[colorIndex].peRed;
destinationPixel[3] = 255;
} else {
destinationPixel[0] = sourcePixel[0];
destinationPixel[1] = sourcePixel[0];
destinationPixel[2] = sourcePixel[0];
destinationPixel[3] = 255;
}
break;
case 3:
destinationPixel[0] = sourcePixel[2];
destinationPixel[1] = sourcePixel[1];
destinationPixel[2] = sourcePixel[0];
destinationPixel[3] = 255;
break;
case 4:
memcpy(destinationPixel, sourcePixel, (size_t) sourceBytes);
break;
default:
break;
}
src_curx += src_dx;
}
src_cury += src_dy;
}
return TRUE;
} }
return FALSE; return FALSE;
} }
@ -947,13 +1051,13 @@ UINT SetDIBColorTable(HDC hdc, UINT iStart, UINT cEntries, CONST RGBQUAD *prgbq
return 0; return 0;
} }
HBITMAP CreateDIBitmap( HDC hdc, CONST BITMAPINFOHEADER *pbmih, DWORD flInit, CONST VOID *pjBits, CONST BITMAPINFO *pbmi, UINT iUsage) { HBITMAP CreateDIBitmap( HDC hdc, CONST BITMAPINFOHEADER *pbmih, DWORD flInit, CONST VOID *pjBits, CONST BITMAPINFO *pbmi, UINT iUsage) {
HGDIOBJ newHDC = (HGDIOBJ)malloc(sizeof(_HGDIOBJ)); HGDIOBJ newHBITMAP = (HGDIOBJ)malloc(sizeof(_HGDIOBJ));
memset(newHDC, 0, sizeof(_HGDIOBJ)); memset(newHBITMAP, 0, sizeof(_HGDIOBJ));
newHDC->handleType = HGDIOBJ_TYPE_BITMAP; newHBITMAP->handleType = HGDIOBJ_TYPE_BITMAP;
BITMAPINFO * newBitmapInfo = malloc(sizeof(BITMAPINFO)); BITMAPINFO * newBitmapInfo = malloc(sizeof(BITMAPINFO));
memcpy(newBitmapInfo, pbmi, sizeof(BITMAPINFO)); memcpy(newBitmapInfo, pbmi, sizeof(BITMAPINFO));
newHDC->bitmapInfo = newBitmapInfo; newHBITMAP->bitmapInfo = newBitmapInfo;
newHDC->bitmapInfoHeader = (BITMAPINFOHEADER *)newBitmapInfo; newHBITMAP->bitmapInfoHeader = (BITMAPINFOHEADER *)newBitmapInfo;
//size_t stride = (size_t)(newBitmapInfo->bmiHeader.biWidth * (newBitmapInfo->bmiHeader.biBitCount >> 3)); //size_t stride = (size_t)(newBitmapInfo->bmiHeader.biWidth * (newBitmapInfo->bmiHeader.biBitCount >> 3));
size_t stride = (size_t)(4 * ((newBitmapInfo->bmiHeader.biWidth * newBitmapInfo->bmiHeader.biBitCount + 31) / 32)); size_t stride = (size_t)(4 * ((newBitmapInfo->bmiHeader.biWidth * newBitmapInfo->bmiHeader.biBitCount + 31) / 32));
size_t size = newBitmapInfo->bmiHeader.biSizeImage ? size_t size = newBitmapInfo->bmiHeader.biSizeImage ?
@ -969,25 +1073,43 @@ HBITMAP CreateDIBitmap( HDC hdc, CONST BITMAPINFOHEADER *pbmih, DWORD flInit, CO
bitmapBitsSource += stride; bitmapBitsSource += stride;
bitmapBitsDestination -= stride; bitmapBitsDestination -= stride;
} }
newHDC->bitmapBits = bitmapBits; newHBITMAP->bitmapBits = bitmapBits;
return newHDC; return newHBITMAP;
} }
HBITMAP CreateDIBSection(HDC hdc, CONST BITMAPINFO *pbmi, UINT usage, VOID **ppvBits, HANDLE hSection, DWORD offset) { HBITMAP CreateDIBSection(HDC hdc, CONST BITMAPINFO *pbmi, UINT usage, VOID **ppvBits, HANDLE hSection, DWORD offset) {
HGDIOBJ newHDC = (HGDIOBJ)malloc(sizeof(_HGDIOBJ)); HGDIOBJ newHBITMAP = (HGDIOBJ)malloc(sizeof(_HGDIOBJ));
memset(newHDC, 0, sizeof(_HGDIOBJ)); memset(newHBITMAP, 0, sizeof(_HGDIOBJ));
newHDC->handleType = HGDIOBJ_TYPE_BITMAP; newHBITMAP->handleType = HGDIOBJ_TYPE_BITMAP;
newHDC->bitmapInfo = pbmi; newHBITMAP->bitmapInfo = pbmi;
newHDC->bitmapInfoHeader = pbmi; newHBITMAP->bitmapInfoHeader = (const BITMAPINFOHEADER *) pbmi;
// For DIB_RGB_COLORS only // For DIB_RGB_COLORS only
int size = pbmi->bmiHeader.biWidth * abs(pbmi->bmiHeader.biHeight) * 4; //(pbmi->bmiHeader.biBitCount >> 3); size_t size = (size_t) (pbmi->bmiHeader.biWidth * abs(pbmi->bmiHeader.biHeight) * 4);
newHDC->bitmapBits = malloc(size); //pbmi->bmiHeader.biSizeImage); newHBITMAP->bitmapBits = malloc(size);
memset(newHDC->bitmapBits, 0, size); memset((void *) newHBITMAP->bitmapBits, 0, size);
*ppvBits = newHDC->bitmapBits; *ppvBits = (void *) newHBITMAP->bitmapBits;
return newHDC; return newHBITMAP;
} }
HBITMAP CreateCompatibleBitmap( HDC hdc, int cx, int cy) { HBITMAP CreateCompatibleBitmap( HDC hdc, int cx, int cy) {
//TODO HGDIOBJ newHBITMAP = (HGDIOBJ)malloc(sizeof(_HGDIOBJ));
return NULL; memset(newHBITMAP, 0, sizeof(_HGDIOBJ));
newHBITMAP->handleType = HGDIOBJ_TYPE_BITMAP;
BITMAPINFO * newBitmapInfo = malloc(sizeof(BITMAPINFO));
memset(newBitmapInfo, 0, sizeof(BITMAPINFO));
newHBITMAP->bitmapInfo = newBitmapInfo;
newHBITMAP->bitmapInfoHeader = (BITMAPINFOHEADER *)newBitmapInfo;
newBitmapInfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
newBitmapInfo->bmiHeader.biWidth = cx;
newBitmapInfo->bmiHeader.biHeight = cy;
newBitmapInfo->bmiHeader.biBitCount = 24;
size_t stride = (size_t)(4 * ((newBitmapInfo->bmiHeader.biWidth * newBitmapInfo->bmiHeader.biBitCount + 31) / 32));
size_t size = newBitmapInfo->bmiHeader.biHeight * stride;
newBitmapInfo->bmiHeader.biSizeImage = (DWORD) size;
newHBITMAP->bitmapBits = malloc(size);
memset((void *) newHBITMAP->bitmapBits, 0, size);
return newHBITMAP;
} }
int GetDIBits(HDC hdc, HBITMAP hbm, UINT start, UINT cLines, LPVOID lpvBits, LPBITMAPINFO lpbmi, UINT usage) { int GetDIBits(HDC hdc, HBITMAP hbm, UINT start, UINT cLines, LPVOID lpvBits, LPBITMAPINFO lpbmi, UINT usage) {
//TODO //TODO

View file

@ -587,7 +587,7 @@ public class MainActivity extends AppCompatActivity
Bitmap bitmapScreen = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888); Bitmap bitmapScreen = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
bitmapScreen.eraseColor(Color.BLACK); bitmapScreen.eraseColor(Color.BLACK);
//TODO NativeLib.onViewCopy(bitmapScreen); NativeLib.onViewCopy(bitmapScreen);
String imageFilename = "Emu48-" + new SimpleDateFormat("yyyy-MM-dd_HH-mm-ss", Locale.US).format(new Date()); String imageFilename = "Emu48-" + new SimpleDateFormat("yyyy-MM-dd_HH-mm-ss", Locale.US).format(new Date());
try { try {