mirror of
https://github.com/dgis/emu48android
synced 2025-01-17 18:11:37 +01:00
This commit is contained in:
parent
807502a10c
commit
000de917f0
9 changed files with 364 additions and 209 deletions
|
@ -60,76 +60,6 @@ add_library( # Sets the name of the library.
|
|||
src/main/cpp/emu48-jni.c
|
||||
)
|
||||
|
||||
#_makepath OK
|
||||
#bActFollowsMouse
|
||||
#bAlwaysDisplayLog
|
||||
#bAlwaysOnTop
|
||||
#bAutoSave
|
||||
#bAutoSaveOnExit
|
||||
#bClientWinMove
|
||||
#bGrayscale
|
||||
#bLoadObjectWarning
|
||||
#bMacroRealSpeed
|
||||
#bSaveDefConfirm
|
||||
#bShowMenu
|
||||
#bShowTitle
|
||||
#bSingleInstance
|
||||
#bStartupBackup
|
||||
#CheckBreakpoint
|
||||
#CreateBackupBreakpointList
|
||||
#csDbgLock
|
||||
#csIOLock
|
||||
#csKeyLock
|
||||
#csSlowLock
|
||||
#csT1Lock
|
||||
#csT2Lock
|
||||
#DisableDebugger
|
||||
#disassemble
|
||||
#disassembler_mode
|
||||
#disassembler_symb
|
||||
#DisplayChooseKml
|
||||
#dwMacroMinDelay
|
||||
#dwTColor
|
||||
#dwWakeupDelay
|
||||
#ExtCreateRegion
|
||||
#GetLineCounter
|
||||
#hEventShutdn
|
||||
#hOldPalette
|
||||
#hPalette
|
||||
#hThread
|
||||
#hWindowDC
|
||||
#InitKML
|
||||
#KeyMacroRecord
|
||||
#KillKML
|
||||
#lAppStart
|
||||
#lFreq
|
||||
#LoadBreakpointList
|
||||
#nArgc
|
||||
#nMacroTimeout
|
||||
#NotifyDebugger
|
||||
#OnToolMacroStop
|
||||
#ppArgv
|
||||
#RefreshDisp0
|
||||
#ReloadButtons
|
||||
#RestoreBackupBreakpointList
|
||||
#RGB
|
||||
#SaveBreakpointList
|
||||
#SetWindowPlacement
|
||||
#SetWindowTitle
|
||||
#StartDisplay
|
||||
#StopDisplay
|
||||
#szUdpServer
|
||||
#UpdateAnnunciators
|
||||
#UpdateContrast
|
||||
#UpdateDbgCycleCounter
|
||||
#UpdateDisplayPointers
|
||||
#UpdateMainDisplay
|
||||
#UpdateMenuDisplay
|
||||
#uWaveDevId
|
||||
#WriteToMainDisplay
|
||||
#WriteToMenuDisplay
|
||||
#wUdpPort
|
||||
|
||||
# Searches for a specified prebuilt library and stores the path as a
|
||||
# variable. Because CMake includes system libraries in the search path by
|
||||
# default, you only need to specify the name of the public NDK library
|
||||
|
|
|
@ -2,6 +2,8 @@
|
|||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="com.regis.cosnier.emu48">
|
||||
|
||||
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
|
||||
|
||||
<application
|
||||
android:allowBackup="true"
|
||||
android:icon="@mipmap/ic_launcher"
|
||||
|
|
|
@ -2025,7 +2025,7 @@ BOOL emu48Start()
|
|||
// ATOM classAtom;
|
||||
// RECT rectWindow;
|
||||
// HACCEL hAccel;
|
||||
// DWORD dwThreadId;
|
||||
DWORD dwThreadId;
|
||||
// LPFN_STIP fnSetThreadIdealProcessor;
|
||||
// DWORD dwProcessor;
|
||||
// HSZ hszService, hszTopic; // variables for DDE server
|
||||
|
@ -2288,3 +2288,10 @@ BOOL emu48Start()
|
|||
UNREFERENCED_PARAMETER(lpCmdLine);
|
||||
UNREFERENCED_PARAMETER(hPrevInst);
|
||||
}
|
||||
|
||||
|
||||
|
||||
//BOOL DisplayChooseKmlEx(CHAR cType) {
|
||||
// lstrcpy(szCurrentKml, "hello.kml");
|
||||
// return TRUE;
|
||||
//}
|
||||
|
|
|
@ -68,7 +68,7 @@ VOID SoundBeep(DWORD dwFrequency, DWORD dwDuration) {
|
|||
//HPALETTE hOldPalette = NULL; // old palette of hWindowDC
|
||||
//DWORD dwTColor = (DWORD) -1; // transparency color
|
||||
//DWORD dwTColorTol = 0; // transparency color tolerance
|
||||
HRGN hRgn = NULL;
|
||||
//HRGN hRgn = NULL;
|
||||
//HCURSOR hCursorArrow = NULL;
|
||||
//HCURSOR hCursorHand = NULL;
|
||||
//UINT uWaveDevId = WAVE_MAPPER; // default audio device
|
||||
|
@ -88,6 +88,9 @@ HRGN hRgn = NULL;
|
|||
|
||||
// udp.c
|
||||
|
||||
TCHAR szUdpServer[1024] = _T("localhost");
|
||||
WORD wUdpPort = 5025; // scpi-raw
|
||||
|
||||
VOID ResetUdp(VOID) {
|
||||
return;
|
||||
}
|
||||
|
@ -97,6 +100,52 @@ BOOL SendByteUdp(BYTE byData) {
|
|||
}
|
||||
|
||||
// debugger.c
|
||||
LRESULT OnToolDebug(VOID) {
|
||||
return NULL;
|
||||
VOID UpdateDbgCycleCounter(VOID) {
|
||||
return;
|
||||
}
|
||||
BOOL CheckBreakpoint(DWORD dwAddr, DWORD wRange, UINT nType) {
|
||||
return 0;
|
||||
}
|
||||
VOID NotifyDebugger(INT nType) {
|
||||
return;
|
||||
}
|
||||
VOID DisableDebugger(VOID) {
|
||||
return;
|
||||
}
|
||||
LRESULT OnToolDebug(VOID) {
|
||||
return 0;
|
||||
}
|
||||
VOID LoadBreakpointList(HANDLE hFile) {
|
||||
return;
|
||||
}
|
||||
VOID SaveBreakpointList(HANDLE hFile) {
|
||||
return;
|
||||
}
|
||||
VOID CreateBackupBreakpointList(VOID) {
|
||||
return;
|
||||
}
|
||||
VOID RestoreBackupBreakpointList(VOID) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Disasm.c
|
||||
BOOL disassembler_mode = HP_MNEMONICS;
|
||||
BOOL disassembler_symb = FALSE;
|
||||
DWORD disassemble(DWORD addr, LPTSTR out) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Keymacro.c
|
||||
//INT nMacroState;
|
||||
INT nMacroTimeout;
|
||||
BOOL bMacroRealSpeed;
|
||||
DWORD dwMacroMinDelay;
|
||||
VOID KeyMacroRecord(BOOL bPress, UINT out, UINT in) {
|
||||
return;
|
||||
}
|
||||
//LRESULT OnToolMacroNew(VOID);
|
||||
//LRESULT OnToolMacroPlay(VOID);
|
||||
LRESULT OnToolMacroStop(VOID) {
|
||||
return 0;
|
||||
}
|
||||
//LRESULT OnToolMacroSettings(VOID);
|
|
@ -14,7 +14,10 @@ Java_com_regis_cosnier_emu48_MainActivity_stringFromJNI(
|
|||
}
|
||||
|
||||
extern void emu48Start();
|
||||
#include <asset_manager.h>
|
||||
#include <asset_manager_jni.h>
|
||||
|
||||
JNIEXPORT void JNICALL Java_com_regis_cosnier_emu48_MainActivity_emu48Start(JNIEnv *env, jobject thisz) {
|
||||
JNIEXPORT void JNICALL Java_com_regis_cosnier_emu48_MainActivity_emu48Start(JNIEnv *env, jobject thisz, jobject assetManager) {
|
||||
AAssetManager * mgr = (AAssetManager *)assetManager;
|
||||
emu48Start();
|
||||
}
|
||||
|
|
|
@ -57,7 +57,7 @@
|
|||
#define GetWindowLongPtr GetWindowLong
|
||||
#define SetClassLongPtr SetClassLong
|
||||
#define GetClassLongPtr GetClassLong
|
||||
typedef SIZE_T DWORD_PTR, *PDWORD_PTR;
|
||||
//typedef SIZE_T DWORD_PTR, *PDWORD_PTR;
|
||||
typedef ULONG ULONG_PTR, *PULONG_PTR;
|
||||
typedef LONG LONG_PTR, *PLONG_PTR;
|
||||
#endif
|
||||
|
@ -93,3 +93,7 @@ typedef LONG LONG_PTR, *PLONG_PTR;
|
|||
language='*'\"")
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
//#define DisplayChooseKml DisplayChooseKmlEx
|
||||
//extern BOOL DisplayChooseKmlEx(CHAR cType);
|
||||
|
|
|
@ -1,15 +1,14 @@
|
|||
#include "pch.h"
|
||||
//#include <mach/mach_time.h>
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
#include <sys/mman.h>
|
||||
#include <pthread.h>
|
||||
|
||||
HANDLE hWnd;
|
||||
LPTSTR szTitle;
|
||||
|
||||
//static NSMutableDictionary *gEventLockDict;
|
||||
static HANDLE gEventId;
|
||||
//static HANDLE gEventId;
|
||||
|
||||
|
||||
DWORD GetCurrentDirectory(DWORD nBufferLength, LPTSTR lpBuffer) {
|
||||
|
@ -27,8 +26,32 @@ BOOL SetCurrentDirectory(LPCTSTR path)
|
|||
return chdir(path);
|
||||
}
|
||||
|
||||
#include <jni.h>
|
||||
#include <asset_manager.h>
|
||||
#include <asset_manager_jni.h>
|
||||
HANDLE CreateFile(LPCTSTR lpFileName, DWORD dwDesiredAccess, DWORD dwShareMode, LPVOID lpSecurityAttributes, DWORD dwCreationDisposition, DWORD dwFlagsAndAttributes, LPVOID hTemplateFile)
|
||||
{
|
||||
if(strncmp(lpFileName, "assets/", 7) == 0) {
|
||||
AAssetDir* assetDir = AAssetManager_openDir(mgr, "");
|
||||
const char* filename = (const char*)NULL;
|
||||
while ((filename = AAssetDir_getNextFileName(assetDir)) != NULL) {
|
||||
AAsset* asset = AAssetManager_open(mgr, filename, AASSET_MODE_STREAMING);
|
||||
char buf[BUFSIZ];
|
||||
int nb_read = 0;
|
||||
FILE* out = fopen(filename, "w");
|
||||
while ((nb_read = AAsset_read(asset, buf, BUFSIZ)) > 0)
|
||||
fwrite(buf, nb_read, 1, out);
|
||||
fclose(out);
|
||||
AAsset_close(asset);
|
||||
}
|
||||
AAssetDir_close(assetDir);
|
||||
HANDLE handle = malloc(sizeof(_HANDLE));
|
||||
handle->handleType = HANDLE_TYPE_FILE;
|
||||
handle->fileDescriptor = fd;
|
||||
handle->fileIsAsset = TRUE;
|
||||
return handle;
|
||||
} else {
|
||||
|
||||
int flags = O_RDWR;
|
||||
int fd = -1;
|
||||
struct flock lock;
|
||||
|
@ -36,11 +59,10 @@ HANDLE CreateFile(LPCTSTR lpFileName, DWORD dwDesiredAccess, DWORD dwShareMode,
|
|||
|
||||
if (GENERIC_READ == dwDesiredAccess)
|
||||
flags = O_RDONLY;
|
||||
else
|
||||
{
|
||||
else {
|
||||
if (GENERIC_WRITE == dwDesiredAccess)
|
||||
flags = O_WRONLY;
|
||||
else if (0 != ((GENERIC_READ|GENERIC_WRITE) & dwDesiredAccess))
|
||||
else if (0 != ((GENERIC_READ | GENERIC_WRITE) & dwDesiredAccess))
|
||||
flags = O_RDWR;
|
||||
|
||||
if (CREATE_ALWAYS == dwCreationDisposition)
|
||||
|
@ -48,8 +70,7 @@ HANDLE CreateFile(LPCTSTR lpFileName, DWORD dwDesiredAccess, DWORD dwShareMode,
|
|||
}
|
||||
|
||||
fd = open(lpFileName, flags, perm);
|
||||
if (-1 != fd && 0 != dwShareMode)
|
||||
{
|
||||
if (-1 != fd && 0 != dwShareMode) {
|
||||
// Not specifiying shared write means non-shared (exclusive) write
|
||||
if (0 == (dwShareMode & FILE_SHARE_WRITE))
|
||||
lock.l_type = F_WRLCK;
|
||||
|
@ -60,17 +81,20 @@ HANDLE CreateFile(LPCTSTR lpFileName, DWORD dwDesiredAccess, DWORD dwShareMode,
|
|||
lock.l_len = lock.l_start = 0;
|
||||
lock.l_whence = SEEK_SET;
|
||||
|
||||
if (-1 == fcntl(fd, F_SETLK, &lock) && (EACCES == errno || EAGAIN == errno))
|
||||
{
|
||||
if (-1 == fcntl(fd, F_SETLK, &lock) && (EACCES == errno || EAGAIN == errno)) {
|
||||
close(fd);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
HANDLE result = malloc(sizeof(_HANDLE));
|
||||
result->handleType = HANDLE_TYPE_FILE;
|
||||
result->fileDescriptor = fd;
|
||||
return result;
|
||||
if (fd != -1) {
|
||||
HANDLE handle = malloc(sizeof(_HANDLE));
|
||||
handle->handleType = HANDLE_TYPE_FILE;
|
||||
handle->fileDescriptor = fd;
|
||||
handle->fileIsAsset = FALSE;
|
||||
return handle;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
BOOL ReadFile(HANDLE hFile, LPVOID lpBuffer, DWORD nNumberOfBytesToRead, LPDWORD lpNumberOfBytesRead, LPOVERLAPPED lpOverlapped) {
|
||||
|
@ -116,12 +140,12 @@ DWORD GetFileSize(HANDLE hFile, LPDWORD lpFileSizeHigh) {
|
|||
//https://www.ibm.com/developerworks/systems/library/es-win32linux.html
|
||||
//https://www.ibm.com/developerworks/systems/library/es-win32linux-sem.html
|
||||
HANDLE CreateFileMapping(HANDLE hFile, LPSECURITY_ATTRIBUTES lpFileMappingAttributes, DWORD flProtect, DWORD dwMaximumSizeHigh, DWORD dwMaximumSizeLow, LPCSTR lpName) {
|
||||
HANDLE result = malloc(sizeof(_HANDLE));
|
||||
result->handleType = HANDLE_TYPE_FILE_MAPPING;
|
||||
result->fileDescriptor = hFile->fileDescriptor;
|
||||
result->fileMappingSize = (dwMaximumSizeHigh << 32) & dwMaximumSizeLow;
|
||||
result->fileMappingAddress = NULL;
|
||||
return result;
|
||||
HANDLE handle = malloc(sizeof(_HANDLE));
|
||||
handle->handleType = HANDLE_TYPE_FILE_MAPPING;
|
||||
handle->fileDescriptor = hFile->fileDescriptor;
|
||||
handle->fileMappingSize = (dwMaximumSizeHigh << 32) & dwMaximumSizeLow;
|
||||
handle->fileMappingAddress = NULL;
|
||||
return handle;
|
||||
}
|
||||
|
||||
//https://msdn.microsoft.com/en-us/library/Aa366761(v=VS.85).aspx
|
||||
|
@ -142,92 +166,131 @@ BOOL UnmapViewOfFile(LPCVOID lpBaseAddress) {
|
|||
return result == 0;
|
||||
}
|
||||
|
||||
// https://github.com/NeoSmart/PEvents
|
||||
HANDLE CreateEvent(WORD attr, BOOL is_manual_reset, BOOL is_signaled, WORD name)
|
||||
//https://github.com/neosmart/pevents/blob/master/src/pevents.cpp
|
||||
HANDLE CreateEvent(LPVOID lpEventAttributes, BOOL bManualReset, BOOL bInitialState, LPCTSTR name)
|
||||
{
|
||||
// if (nil == gEventLockDict)
|
||||
// {
|
||||
// gEventLockDict = [[NSMutableDictionary alloc] init];
|
||||
// }
|
||||
// ++gEventId;
|
||||
// NSNumber *key = [[NSNumber alloc] initWithInt: gEventId];
|
||||
// NSConditionLock *lock = [[NSConditionLock alloc] initWithCondition: 0];
|
||||
// [gEventLockDict setObject:lock forKey:key];
|
||||
// [lock release];
|
||||
// [key release];
|
||||
//// if (NULL == gEventLock)
|
||||
//// {
|
||||
//// gEventLock = [[NSConditionLock alloc] initWithCondition: 0];
|
||||
//// }
|
||||
HANDLE handle = malloc(sizeof(_HANDLE));
|
||||
handle->handleType = HANDLE_TYPE_EVENT;
|
||||
|
||||
return gEventId;
|
||||
int result = pthread_cond_init(&(handle->eventCVariable), 0);
|
||||
_ASSERT(result == 0);
|
||||
|
||||
result = pthread_mutex_init(&(handle->eventMutex), 0);
|
||||
_ASSERT(result == 0);
|
||||
|
||||
handle->eventState = FALSE;
|
||||
handle->eventAutoReset = bManualReset ? FALSE : TRUE;
|
||||
|
||||
if (bInitialState)
|
||||
{
|
||||
result = SetEvent(handle);
|
||||
_ASSERT(result == 0);
|
||||
}
|
||||
|
||||
return handle;
|
||||
}
|
||||
|
||||
void SetEvent(HANDLE eventId)
|
||||
{
|
||||
// NSNumber *key = [[NSNumber alloc] initWithInt: eventId];
|
||||
// NSConditionLock *lock = [gEventLockDict objectForKey: key];
|
||||
// [key release];
|
||||
// if (lock)
|
||||
// {
|
||||
// [lock lock];
|
||||
// [lock unlockWithCondition: eventId];
|
||||
// }
|
||||
BOOL SetEvent(HANDLE hEvent) {
|
||||
int result = pthread_mutex_lock(&hEvent->eventMutex);
|
||||
_ASSERT(result == 0);
|
||||
|
||||
hEvent->eventState = TRUE;
|
||||
|
||||
//Depending on the event type, we either trigger everyone or only one
|
||||
if (hEvent->eventAutoReset)
|
||||
{
|
||||
//hEvent->eventState can be false if compiled with WFMO support
|
||||
if (hEvent->eventState)
|
||||
{
|
||||
result = pthread_mutex_unlock(&hEvent->eventMutex);
|
||||
_ASSERT(result == 0);
|
||||
result = pthread_cond_signal(&hEvent->eventCVariable);
|
||||
_ASSERT(result == 0);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
result = pthread_mutex_unlock(&hEvent->eventMutex);
|
||||
_ASSERT(result == 0);
|
||||
result = pthread_cond_broadcast(&hEvent->eventCVariable);
|
||||
_ASSERT(result == 0);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
BOOL ResetEvent(HANDLE eventId)
|
||||
BOOL ResetEvent(HANDLE hEvent)
|
||||
{
|
||||
// NSNumber *key = [[NSNumber alloc] initWithInt: eventId];
|
||||
// NSConditionLock *lock = [gEventLockDict objectForKey: key];
|
||||
// [key release];
|
||||
// if (lock)
|
||||
// {
|
||||
// [lock lock];
|
||||
// [lock unlockWithCondition: 0];
|
||||
// return TRUE;
|
||||
// }
|
||||
return FALSE;
|
||||
int result = pthread_mutex_lock(&hEvent->eventMutex);
|
||||
_ASSERT(result == 0);
|
||||
|
||||
hEvent->eventState = FALSE;
|
||||
|
||||
result = pthread_mutex_unlock(&hEvent->eventMutex);
|
||||
_ASSERT(result == 0);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void DestroyEvent(HANDLE eventId)
|
||||
int UnlockedWaitForEvent(HANDLE hHandle, uint64_t milliseconds)
|
||||
{
|
||||
// NSNumber *key = [[NSNumber alloc] initWithInt: eventId];
|
||||
// NSConditionLock *lock = [gEventLockDict objectForKey: key];
|
||||
// if (lock)
|
||||
// {
|
||||
// [gEventLockDict removeObjectForKey: key];
|
||||
// }
|
||||
// [key release];
|
||||
}
|
||||
int result = 0;
|
||||
if (!hHandle->eventState)
|
||||
{
|
||||
//Zero-timeout event state check optimization
|
||||
if (milliseconds == 0)
|
||||
{
|
||||
return WAIT_TIMEOUT;
|
||||
}
|
||||
|
||||
struct timespec ts;
|
||||
if (milliseconds != (uint64_t) -1)
|
||||
{
|
||||
struct timeval tv;
|
||||
gettimeofday(&tv, NULL);
|
||||
|
||||
uint64_t nanoseconds = ((uint64_t) tv.tv_sec) * 1000 * 1000 * 1000 + milliseconds * 1000 * 1000 + ((uint64_t) tv.tv_usec) * 1000;
|
||||
|
||||
ts.tv_sec = nanoseconds / 1000 / 1000 / 1000;
|
||||
ts.tv_nsec = (nanoseconds - ((uint64_t) ts.tv_sec) * 1000 * 1000 * 1000);
|
||||
}
|
||||
|
||||
do
|
||||
{
|
||||
//Regardless of whether it's an auto-reset or manual-reset event:
|
||||
//wait to obtain the event, then lock anyone else out
|
||||
if (milliseconds != (uint64_t) -1)
|
||||
{
|
||||
result = pthread_cond_timedwait(&hHandle->eventCVariable, &hHandle->eventMutex, &ts);
|
||||
}
|
||||
else
|
||||
{
|
||||
result = pthread_cond_wait(&hHandle->eventCVariable, &hHandle->eventMutex);
|
||||
}
|
||||
} while (result == 0 && !hHandle->eventState);
|
||||
|
||||
if (result == 0 && hHandle->eventAutoReset)
|
||||
{
|
||||
//We've only accquired the event if the wait succeeded
|
||||
hHandle->eventState = FALSE;
|
||||
}
|
||||
}
|
||||
else if (hHandle->eventAutoReset)
|
||||
{
|
||||
//It's an auto-reset event that's currently available;
|
||||
//we need to stop anyone else from using it
|
||||
result = 0;
|
||||
hHandle->eventState = FALSE;
|
||||
}
|
||||
//Else we're trying to obtain a manual reset event with a signaled state;
|
||||
//don't do anything
|
||||
|
||||
DWORD WaitForSingleObject(HANDLE eventId, int timeout)
|
||||
{
|
||||
DWORD result = WAIT_OBJECT_0;
|
||||
// NSNumber *key = [[NSNumber alloc] initWithInt: eventId];
|
||||
// NSConditionLock *lock = [gEventLockDict objectForKey: key];
|
||||
// [key release];
|
||||
//
|
||||
// if (nil == lock)
|
||||
// return WAIT_FAILED;
|
||||
//
|
||||
// if (timeout > 0)
|
||||
// {
|
||||
// NSDate *timeoutDate = [[NSDate alloc] initWithTimeIntervalSinceNow: (timeout/1000.0)];
|
||||
// if (![lock lockWhenCondition:eventId beforeDate:timeoutDate])
|
||||
// result = WAIT_TIMEOUT;
|
||||
// [timeoutDate release];
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// [lock lockWhenCondition: eventId];
|
||||
// [lock unlockWithCondition: 0];
|
||||
// }
|
||||
return result;
|
||||
}
|
||||
|
||||
#include <pthread.h>
|
||||
HANDLE WINAPI CreateThread(LPSECURITY_ATTRIBUTES lpThreadAttributes, SIZE_T dwStackSize, LPTHREAD_START_ROUTINE lpStartAddress, LPVOID lpParameter, DWORD dwCreationFlags, LPDWORD lpThreadId) {
|
||||
pthread_t *threadId;
|
||||
HANDLE CreateThread(LPSECURITY_ATTRIBUTES lpThreadAttributes, SIZE_T dwStackSize, LPTHREAD_START_ROUTINE lpStartAddress, LPVOID lpParameter, DWORD dwCreationFlags, LPDWORD lpThreadId) {
|
||||
pthread_t threadId;
|
||||
pthread_attr_t attr;
|
||||
pthread_attr_init(&attr);
|
||||
if(dwStackSize)
|
||||
|
@ -236,11 +299,11 @@ HANDLE WINAPI CreateThread(LPSECURITY_ATTRIBUTES lpThreadAttributes, SIZE_T dwSt
|
|||
//https://stackoverflow.com/questions/3140867/suspend-pthreads-without-using-condition
|
||||
//https://stackoverflow.com/questions/7953917/create-thread-in-suspended-mode-using-pthreads
|
||||
//http://man7.org/linux/man-pages/man3/pthread_create.3.html
|
||||
int pthreadResult = pthread_create(threadId, &attr, /*(void*(*)(void*))*/lpStartAddress, lpParameter);
|
||||
int pthreadResult = pthread_create(&threadId, &attr, /*(void*(*)(void*))*/lpStartAddress, lpParameter);
|
||||
if(pthreadResult == 0) {
|
||||
HANDLE result = malloc(sizeof(_HANDLE));
|
||||
result->handleType = HANDLE_TYPE_THREAD;
|
||||
result->threadId = *threadId;
|
||||
result->threadId = threadId;
|
||||
return result;
|
||||
}
|
||||
return NULL;
|
||||
|
@ -251,6 +314,46 @@ DWORD ResumeThread(HANDLE hThread) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
//https://docs.microsoft.com/en-us/windows/desktop/api/synchapi/nf-synchapi-waitforsingleobject
|
||||
DWORD WaitForSingleObject(HANDLE hHandle, DWORD dwMilliseconds)
|
||||
{
|
||||
if(hHandle->handleType == HANDLE_TYPE_THREAD) {
|
||||
_ASSERT(dwMilliseconds == INFINITE)
|
||||
if(dwMilliseconds == INFINITE) {
|
||||
pthread_join(hHandle->threadId, NULL);
|
||||
}
|
||||
//TODO for dwMilliseconds != INFINITE
|
||||
//https://stackoverflow.com/questions/2719580/waitforsingleobject-and-waitformultipleobjects-equivalent-in-linux
|
||||
} else if(hHandle->handleType == HANDLE_TYPE_EVENT) {
|
||||
|
||||
int tempResult;
|
||||
if (dwMilliseconds == 0)
|
||||
{
|
||||
tempResult = pthread_mutex_trylock(&hHandle->eventMutex);
|
||||
if (tempResult == EBUSY)
|
||||
{
|
||||
return WAIT_TIMEOUT;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
tempResult = pthread_mutex_lock(&hHandle->eventMutex);
|
||||
}
|
||||
|
||||
_ASSERT(tempResult == 0);
|
||||
|
||||
int result = UnlockedWaitForEvent(hHandle, dwMilliseconds);
|
||||
|
||||
tempResult = pthread_mutex_unlock(&hHandle->eventMutex);
|
||||
_ASSERT(tempResult == 0);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
DWORD result = WAIT_OBJECT_0;
|
||||
return result;
|
||||
}
|
||||
|
||||
BOOL WINAPI CloseHandle(HANDLE hObject) {
|
||||
//https://msdn.microsoft.com/en-us/9b84891d-62ca-4ddc-97b7-c4c79482abd9
|
||||
// Can be a thread/event/file handle!
|
||||
|
@ -275,9 +378,17 @@ BOOL WINAPI CloseHandle(HANDLE hObject) {
|
|||
}
|
||||
break;
|
||||
}
|
||||
case HANDLE_TYPE_EVENT:
|
||||
//free(hObject);
|
||||
case HANDLE_TYPE_EVENT: {
|
||||
int result = 0;
|
||||
result = pthread_cond_destroy(&hObject->eventCVariable);
|
||||
_ASSERT(result == 0);
|
||||
result = pthread_mutex_destroy(&hObject->eventMutex);
|
||||
_ASSERT(result == 0);
|
||||
hObject->eventAutoReset = FALSE;
|
||||
hObject->eventState = FALSE;
|
||||
free(hObject);
|
||||
return TRUE;
|
||||
}
|
||||
case HANDLE_TYPE_THREAD:
|
||||
hObject->threadId = 0;
|
||||
free(hObject);
|
||||
|
@ -310,8 +421,8 @@ BOOL QueryPerformanceCounter(PLARGE_INTEGER l)
|
|||
time_t tv_sec; /* seconds */
|
||||
long tv_nsec; /* nanoseconds */
|
||||
} time;
|
||||
int clock_gettime(CLOCK_MONOTONIC, &time);
|
||||
l->QuadPart = time.tv_nsec;
|
||||
int result = clock_gettime(CLOCK_MONOTONIC, &time);
|
||||
l->QuadPart = 1e9 * time.tv_sec + time.tv_nsec;
|
||||
return TRUE;
|
||||
}
|
||||
void EnterCriticalSection(CRITICAL_SECTION *lock)
|
||||
|
@ -394,6 +505,10 @@ LRESULT SendMessage(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam) {
|
|||
//TODO
|
||||
return NULL;
|
||||
}
|
||||
BOOL PostMessage(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam) {
|
||||
//TODO
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
int MessageBox(HANDLE h, LPCTSTR szMessage, LPCTSTR title, int flags)
|
||||
|
@ -458,6 +573,12 @@ BOOL DestroyWindow(HWND hWnd) {
|
|||
BOOL GetWindowPlacement(HWND hWnd, WINDOWPLACEMENT *lpwndpl) { return 0; }
|
||||
BOOL SetWindowPlacement(HWND hWnd, CONST WINDOWPLACEMENT *lpwndpl) { return 0; }
|
||||
BOOL InvalidateRect(HWND hWnd, CONST RECT *lpRect, BOOL bErase) { return 0; }
|
||||
BOOL AdjustWindowRect(LPRECT lpRect, DWORD dwStyle, BOOL bMenu) { return 0; }
|
||||
LONG GetWindowLong(HWND hWnd, int nIndex) { return 0; }
|
||||
HMENU GetMenu(HWND hWnd) { return NULL; }
|
||||
BOOL SetWindowPos(HWND hWnd, HWND hWndInsertAfter, int X, int Y, int cx, int cy, UINT uFlags) { return 0; }
|
||||
BOOL IsRectEmpty(CONST RECT *lprc) { return 0; }
|
||||
BOOL WINAPI SetWindowOrgEx(HDC hdc, int x, int y, LPPOINT lppt) { return 0; }
|
||||
|
||||
int GetObject(HANDLE h, int c, LPVOID pv) {
|
||||
//TODO
|
||||
|
@ -519,6 +640,10 @@ BOOL BitBlt(HDC hdc, int x, int y, int cx, int cy, HDC hdcSrc, int x1, int y1, D
|
|||
//TODO
|
||||
return 0;
|
||||
}
|
||||
UINT SetDIBColorTable(HDC hdc, UINT iStart, UINT cEntries, CONST RGBQUAD *prgbq) {
|
||||
//TODO
|
||||
return 0;
|
||||
}
|
||||
/* constants for CreateDIBitmap */
|
||||
#define CBM_INIT 0x04L /* initialize bitmap */
|
||||
/* DIB color table identifiers */
|
||||
|
@ -672,9 +797,18 @@ HRESULT SHGetMalloc(IMalloc **ppMalloc) {
|
|||
//TODO
|
||||
return 0;
|
||||
}
|
||||
|
||||
PIDLIST_ABSOLUTE SHBrowseForFolderA(LPBROWSEINFOA lpbi) {
|
||||
//TODO
|
||||
return NULL;
|
||||
}
|
||||
//extern INT_PTR CALLBACK ChooseKMLProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam);
|
||||
#include "resource.h"
|
||||
extern TCHAR szCurrentKml[MAX_PATH];
|
||||
INT_PTR DialogBoxParamA(HINSTANCE hInstance, LPCSTR lpTemplateName, HWND hWndParent, DLGPROC lpDialogFunc, LPARAM dwInitParam) {
|
||||
//TODO
|
||||
if(lpTemplateName == MAKEINTRESOURCE(IDD_CHOOSEKML)) {
|
||||
lstrcpy(szCurrentKml, "hello.kml");
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
HCURSOR SetCursor(HCURSOR hCursor) {
|
||||
|
|
|
@ -10,7 +10,7 @@ typedef signed char BOOL; // deliberately same type as defined in objc
|
|||
#define TRUE 1
|
||||
#define FALSE 0
|
||||
#define MAX_PATH PATH_MAX
|
||||
#define INFINITE 0
|
||||
#define INFINITE 0xFFFFFFFF //0
|
||||
#define FAR
|
||||
#define NEAR
|
||||
|
||||
|
@ -58,10 +58,19 @@ enum HANDLE_TYPE {
|
|||
};
|
||||
typedef struct {
|
||||
int handleType;
|
||||
|
||||
int fileDescriptor;
|
||||
BOOL fileIsAsset;
|
||||
|
||||
size_t fileMappingSize;
|
||||
void* fileMappingAddress;
|
||||
|
||||
pthread_t threadId;
|
||||
|
||||
pthread_cond_t eventCVariable;
|
||||
pthread_mutex_t eventMutex;
|
||||
BOOL eventAutoReset;
|
||||
BOOL eventState;
|
||||
} _HANDLE;
|
||||
typedef _HANDLE * HANDLE;
|
||||
typedef HANDLE HPALETTE;
|
||||
|
@ -463,16 +472,15 @@ extern BOOL QueryPerformanceCounter(PLARGE_INTEGER l);
|
|||
extern DWORD timeGetTime(void);
|
||||
extern void EnterCriticalSection(CRITICAL_SECTION *);
|
||||
extern void LeaveCriticalSection(CRITICAL_SECTION *);
|
||||
extern HANDLE CreateEvent(WORD, BOOL, BOOL, WORD);
|
||||
extern void SetEvent(HANDLE);
|
||||
extern void DestroyEvent(HANDLE);
|
||||
extern BOOL ResetEvent(HANDLE);
|
||||
//#define CloseEvent(h);
|
||||
extern HANDLE CreateEvent(LPVOID lpEventAttributes, BOOL bManualReset, BOOL bInitialState, LPCTSTR name);
|
||||
extern BOOL SetEvent(HANDLE hEvent);
|
||||
extern BOOL ResetEvent(HANDLE hEvent);
|
||||
|
||||
#define WAIT_OBJECT_0 0
|
||||
#define WAIT_TIMEOUT 0x00000102
|
||||
#define WAIT_FAILED 0xFFFFFFFF
|
||||
extern DWORD WaitForSingleObject(HANDLE, int);
|
||||
extern DWORD WaitForSingleObject(HANDLE hHandle, DWORD dwMilliseconds);
|
||||
|
||||
extern void Sleep(int);
|
||||
#define UNREFERENCED_PARAMETER(a)
|
||||
|
||||
|
@ -483,6 +491,7 @@ typedef DWORD (*PTHREAD_START_ROUTINE)(
|
|||
LPVOID lpThreadParameter
|
||||
);
|
||||
typedef PTHREAD_START_ROUTINE LPTHREAD_START_ROUTINE;
|
||||
#define CREATE_SUSPENDED 0x00000004
|
||||
extern HANDLE CreateThread(LPSECURITY_ATTRIBUTES lpThreadAttributes, SIZE_T dwStackSize, LPTHREAD_START_ROUTINE lpStartAddress, LPVOID lpParameter, DWORD dwCreationFlags, LPDWORD lpThreadId);
|
||||
extern DWORD ResumeThread(HANDLE hThread);
|
||||
extern BOOL CloseHandle(HANDLE hObject);
|
||||
|
@ -566,6 +575,7 @@ extern HGDIOBJ GetStockObject(int i);
|
|||
#define BLACKNESS (DWORD)0x00000042 /* dest = BLACK */
|
||||
extern BOOL PatBlt(HDC hdc, int x, int y, int w, int h, DWORD rop);
|
||||
extern BOOL BitBlt(HDC hdc, int x, int y, int cx, int cy, HDC hdcSrc, int x1, int y1, DWORD rop);
|
||||
extern UINT SetDIBColorTable(HDC hdc, UINT iStart, UINT cEntries, CONST RGBQUAD *prgbq);
|
||||
/* constants for CreateDIBitmap */
|
||||
#define CBM_INIT 0x04L /* initialize bitmap */
|
||||
/* DIB color table identifiers */
|
||||
|
@ -647,6 +657,20 @@ extern BOOL DestroyWindow(HWND hWnd);
|
|||
extern BOOL GetWindowPlacement(HWND hWnd, WINDOWPLACEMENT *lpwndpl);
|
||||
extern BOOL SetWindowPlacement(HWND hWnd, CONST WINDOWPLACEMENT *lpwndpl);
|
||||
extern BOOL InvalidateRect(HWND hWnd, CONST RECT *lpRect, BOOL bErase);
|
||||
#define GWL_STYLE (-16)
|
||||
extern BOOL AdjustWindowRect(LPRECT lpRect, DWORD dwStyle, BOOL bMenu);
|
||||
extern LONG GetWindowLong(HWND hWnd, int nIndex);
|
||||
extern HMENU GetMenu(HWND hWnd);
|
||||
#define HWND_TOP ((HWND)0)
|
||||
#define HWND_BOTTOM ((HWND)1)
|
||||
#define HWND_TOPMOST ((HWND)-1)
|
||||
#define HWND_NOTOPMOST ((HWND)-2)
|
||||
#define SWP_NOSIZE 0x0001
|
||||
#define SWP_NOMOVE 0x0002
|
||||
#define SWP_NOZORDER 0x0004
|
||||
extern BOOL SetWindowPos(HWND hWnd, HWND hWndInsertAfter, int X, int Y, int cx, int cy, UINT uFlags);
|
||||
extern BOOL IsRectEmpty(CONST RECT *lprc);
|
||||
extern BOOL WINAPI SetWindowOrgEx(HDC hdc, int x, int y, LPPOINT lppt);
|
||||
|
||||
#define _MAX_PATH 260 // max. length of full pathname
|
||||
#define _MAX_DRIVE 3 // max. length of drive component
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
package com.regis.cosnier.emu48;
|
||||
|
||||
import android.content.res.AssetManager;
|
||||
import android.os.Bundle;
|
||||
import android.widget.TextView;
|
||||
import android.support.design.widget.FloatingActionButton;
|
||||
|
@ -37,7 +38,8 @@ public class MainActivity extends AppCompatActivity {
|
|||
TextView tv = (TextView) findViewById(R.id.sample_text);
|
||||
tv.setText(stringFromJNI());
|
||||
|
||||
emu48Start();
|
||||
AssetManager mgr = getResources().getAssets();
|
||||
emu48Start(mgr);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -68,5 +70,5 @@ public class MainActivity extends AppCompatActivity {
|
|||
*/
|
||||
public native String stringFromJNI();
|
||||
|
||||
public native void emu48Start();
|
||||
public native void emu48Start(AssetManager mgr);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue