#include "../common.win32/stdafx.h" #include #include #include "activecommon.h" #include "../kegs/src/sim65816.h" #include "../kegs/src/driver.h" #include "../kegs/src/adb.h" #include "../common.win32/activegs.rc.h" extern const char* currentBuild; void x_display_alert(int _abord, const char* _title, const char* _msg) { CString strsys(_msg); CString titlesys(_title); MessageBox(NULL,strsys,titlesys,MB_OK); } CEmulatorWin32::CEmulatorWin32(CEmulator** _parent) : CEmulator(_parent) { m_hWnd = NULL; hThread = NULL; #ifndef UNDER_CE hAlphaCursor = NULL; activeInfo = NULL; wStatus=NULL; wLoading=NULL; theConsole=NULL; hhkLowLevelKybd=NULL; #endif } extern void my_exit(int); CEmulatorWin32::~CEmulatorWin32() { outputInfo("~CEmulatorWin32 (%X)\n",this); destroy(); #ifndef UNDER_CE disableSystemKeys(); #endif } extern void kegsshut(); DWORD WINAPI CEmulatorWin32::myThread(LPVOID lpParameter) { CEmulatorWin32* emu = (CEmulatorWin32*)lpParameter; kegsinit(emu->m_hWnd); emu->theThread(); kegsshut(); CloseHandle(emu->hThread); emu->hThread=NULL; return 0; } int CEmulatorWin32::initWindow(HWND _hWnd, HINSTANCE _hInstance) { m_hWnd = _hWnd; hInst = _hInstance; #ifndef UNDER_CE theConsole=new CConsole(); CWnd *pw =CWnd::FromHandle(m_hWnd); wStatus = new CActiveStatus(pw); wStatus->Create(CActiveStatus::IDD,pw); wLoading = new CActiveStatus(pw); wLoading->Create(IDD_LOADING,pw); wLoadingBitmap[0].LoadBitmap(IDB_DISK51); wLoadingBitmap[1].LoadBitmap(IDB_DISK52); wLoadingBitmap[2].LoadBitmap(IDB_DISK61); wLoadingBitmap[3].LoadBitmap(IDB_DISK62); enableSystemKeys(); #endif resetLocalIMG(); return 1; } void async_snd_shutdown(); void async_sound_init(); void CEmulatorWin32::x_WaitForEndThread() { // enlËve le mode pause //g_pause=0; DWORD r; MSG msg; while ( ::PeekMessage( &msg, NULL, 0, 0, PM_NOREMOVE )||bInThread ) { // Sleep(20); int bStillRunning = hThread && (r=WaitForSingleObject(hThread,0)==WAIT_TIMEOUT); if (!bStillRunning) { outputInfo("exiting thread %X %X\n",hThread,r); break; } } } /* void CEmulatorWin32::activateEmulator() { if (theEmulator != this) return ; launchEmulator( this->hInst,this->m_hWnd ); } */ void CEmulatorWin32::x_LaunchThread( ) { if (theEmulator != this) return ; outputInfo("launching win32 thread\n"); DWORD threadID; #ifndef UNDER_CE theConsole->initConsole(this->hInst,this->m_hWnd); hAlphaCursor = CreateAlphaCursor(hInst); #endif // initialize le son async //async_sound_init(); hThread= CreateThread(NULL,0,myThread,this,0,&threadID ); if (!hThread) outputInfo("thread initialisation failed!\n"); /* else bRun = true; */ } LRESULT CEmulatorWin32::eventHandler(UINT umsg, WPARAM wParam, LPARAM lParam) { return win_event_handler(m_hWnd,umsg,wParam,lParam); } void win_event_key_async(HWND hwnd, UINT raw_vk, BOOL down, int repeat, UINT flags); void CEmulatorWin32::keyHandler(UINT raw_vk,BOOL down, UINT flags) { win_event_key_async(m_hWnd,raw_vk, down, 0/*repeat*/, flags); } int CEmulatorWin32::hasFocus() { HWND h = ::GetFocus(); if (h == m_hWnd) return 1; else return 0; } #ifndef UNDER_CE LRESULT CALLBACK LowLevelKeyboardProc(int nCode, WPARAM wParam, LPARAM lParam) { BOOL fEatKeystroke = FALSE; CEmulatorWin32* emu = (CEmulatorWin32*)CEmulator::theEmulator; // Manage the key only if the emulator has the focus if (emu && emu->hasFocus() && nCode == HC_ACTION) { PKBDLLHOOKSTRUCT p; p = (PKBDLLHOOKSTRUCT) lParam; int down=0; switch (wParam) { case WM_SYSKEYDOWN: case WM_KEYDOWN: down=1; case WM_SYSKEYUP: case WM_KEYUP: int syskeys = ( p->vkCode == VK_TAB && p->flags & LLKHF_ALTDOWN ) || ( p->vkCode == VK_ESCAPE && p->flags & LLKHF_ALTDOWN ) || ( p->vkCode == VK_ESCAPE && (GetKeyState(VK_CONTROL) & 0x8000)) || p->vkCode == VK_LWIN || p->vkCode == VK_RWIN || p->vkCode==VK_CANCEL || p->vkCode==VK_SCROLL || p->vkCode==VK_TAB || p->vkCode==VK_LMENU || p->vkCode == VK_APPS; if (syskeys ) { fEatKeystroke = 1; // outputInfo("LLSYKEY: %X\n",p->vkCode); ASSERT(emu); emu->keyHandler(p->vkCode,down,((p->flags&0x1)<<8)); } else { // outputInfo("LLKEY: %X\n",p->vkCode); } break; } } else { // outputInfo("NO LL: %X %X %X",GetActiveWindow(),::GetFocus(),emu?emu->m_hWnd:0 ); } return(fEatKeystroke ? 1 : CallNextHookEx(NULL, nCode, wParam, lParam)); } void CEmulatorWin32::enableSystemKeys() { hhkLowLevelKybd = SetWindowsHookEx(WH_KEYBOARD_LL, LowLevelKeyboardProc, AfxGetInstanceHandle(), 0); } void CEmulatorWin32::disableSystemKeys() { if (hhkLowLevelKybd) UnhookWindowsHookEx(hhkLowLevelKybd); } #endif extern const char * activegsdownloaddir ; extern int g_config_control_panel; LRESULT CEmulatorWin32::windowProc(UINT message, WPARAM wParam, LPARAM lParam) { { if (message==WM_USER) { if (wParam==LOADING_ON) { showLoading(TRUE,lParam); return TRUE; } else if (wParam==LOADING_OFF) { showLoading(FALSE,lParam); return TRUE; } else if (wParam==REFRESH_STATUS) { refreshStatus(this->statusMsg.c_str()); return TRUE; } else return eventHandler(message,wParam,lParam); } else #ifndef UNDER_CE if (message==WM_SETCURSOR) { if (hasFocus() && !g_config_control_panel) { SetCursor(hAlphaCursor); return TRUE; } else { //outputInfo("nofocus\n"); return FALSE; } } else #endif if (message==WM_RBUTTONDOWN) { ShowActiveInfo(); } else return eventHandler(message,wParam,lParam); } return DefWindowProc(m_hWnd,message, wParam, lParam); } void CEmulatorWin32::destroy() { outputInfo("onDestroy\n"); #ifndef UNDER_CE if (hAlphaCursor) { DestroyIcon(hAlphaCursor); hAlphaCursor = NULL; } if (activeInfo) { activeInfo->DestroyWindow(); delete activeInfo; activeInfo=NULL; } if (wStatus ) { // if (IsWindow(wStatus->m_hWnd)) wStatus->DestroyWindow(); delete wStatus; wStatus = NULL; } if (wLoading ) { // if (IsWindow(wLoading->m_hWnd)) wLoading->DestroyWindow(); delete wLoading; wLoading=NULL; } for(int i=0;i<4;i++) wLoadingBitmap[i].DeleteObject(); if (theConsole) { theConsole->shutConsole(this->m_hWnd); delete theConsole; theConsole=NULL; } #endif } void CEmulatorWin32::ShowActiveInfo() { if(!bInThread) { MessageBox(m_hWnd,_T("Close other instances first & reload page"),_T("ActiveGS"),MB_OK); return ; } #ifndef UNDER_CE if (!activeInfo) { CWnd *pw =CWnd::FromHandle(m_hWnd); activeInfo = new CActiveInfo(pw); // this? activeInfo->Create(CActiveInfo::IDD,pw); // this ? } g_adb.g_warp_pointer=WARP_NONE; g_adb.g_hide_pointer = 0; x_hide_pointer(false); activeInfo->ShowWindow(SW_SHOW); #endif } void CEmulatorWin32::refreshStatus(const char* _msg) { #ifndef UNDER_CE if (wStatus) { RECT my; wStatus->GetWindowRect(&my); wStatus->ScreenToClient(&my); my.left += 8; my.right += 8; my.bottom += 8; my.top +=8; wStatus->MoveWindow(&my); wStatus->SendDlgItemMessage(IDC_STATUS,WM_SETTEXT,0,(LPARAM)(LPCSTR)_msg); wStatus->ShowWindow(SW_SHOWNOACTIVATE); OutputDebugString(_msg); if (wStatus->TimerID) wStatus->KillTimer(wStatus->TimerID); wStatus->TimerID = wStatus->SetTimer(0,2000,NULL); } #endif } void CEmulatorWin32::showLoading( int _loading,int _disk) { #ifndef UNDER_CE if (wLoading) { if (_loading) { RECT my; wLoading->GetWindowRect(&my); wLoading->ScreenToClient(&my); CWnd* w = CWnd::FromHandle(this->m_hWnd); RECT wrect; w->GetClientRect(&wrect); my.left += wrect.right-56; my.right += wrect.right-56; my.bottom += 8; my.top +=8; wLoading->MoveWindow(&my); CWnd * hWndViewer = wLoading->GetDlgItem(IDC_IMAGECTRLDISK); hWndViewer->SendMessage( STM_SETIMAGE, (WPARAM) IMAGE_BITMAP, (LPARAM) wLoadingBitmap[_disk].m_hObject ); wLoading->ShowWindow(SW_SHOWNOACTIVATE); if (wLoading->TimerID) { wLoading->KillTimer(wLoading->TimerID); wLoading->TimerID = NULL; } } else { if (!wLoading->TimerID) wLoading->TimerID = wLoading->SetTimer(2,2000,NULL); } } #endif } #ifndef UNDER_CE void DeleteCursor(HCURSOR theCursor) { DestroyIcon(theCursor); } typedef struct { DWORD bV5Size; LONG bV5Width; LONG bV5Height; WORD bV5Planes; WORD bV5BitCount; DWORD bV5Compression; DWORD bV5SizeImage; LONG bV5XPelsPerMeter; LONG bV5YPelsPerMeter; DWORD bV5ClrUsed; DWORD bV5ClrImportant; DWORD bV5RedMask; DWORD bV5GreenMask; DWORD bV5BlueMask; DWORD bV5AlphaMask; DWORD bV5CSType; CIEXYZTRIPLE bV5Endpoints; DWORD bV5GammaRed; DWORD bV5GammaGreen; DWORD bV5GammaBlue; DWORD bV5Intent; DWORD bV5ProfileData; DWORD bV5ProfileSize; DWORD bV5Reserved; } MYBITMAPV5HEADER; HCURSOR CreateAlphaCursor(HINSTANCE hInst) { HDC hMemDC; DWORD dwWidth, dwHeight; MYBITMAPV5HEADER bi; HBITMAP hBitmap, hOldBitmap; void *lpBits; DWORD x,y; HCURSOR hAlphaCursor = NULL; HDC hdc; HDC src; HBITMAP hMonoBitmap; DWORD *lpdwPixel; ICONINFO ii; HGDIOBJ hOldSrc; HBITMAP hBm = LoadBitmap(hInst,MAKEINTRESOURCE(IDB_ALPHACURSOR)); if (!hBm) { outputInfo("Load AlphaCursor failed (inst:%0X)\n",hInst); return NULL; } BITMAP bm; GetObject(hBm, sizeof(bm), &bm); /* alpha.GetBitmap(&bm); */ dwWidth = bm.bmWidth; // width of cursor dwHeight = bm.bmHeight; // height of cursor ZeroMemory(&bi,sizeof(MYBITMAPV5HEADER)); bi.bV5Size = sizeof(MYBITMAPV5HEADER); bi.bV5Width = dwWidth; bi.bV5Height = dwHeight; bi.bV5Planes = 1; bi.bV5BitCount = 32; bi.bV5Compression = BI_BITFIELDS; // The following mask specification specifies a supported 32 BPP // alpha format for Windows XP. bi.bV5RedMask = 0x00FF0000; bi.bV5GreenMask = 0x0000FF00; bi.bV5BlueMask = 0x000000FF; bi.bV5AlphaMask = 0xFF000000; hdc = GetDC(NULL); // Create the DIB section with an alpha channel. hBitmap = CreateDIBSection(hdc, (BITMAPINFO *)&bi, DIB_RGB_COLORS, (void **)&lpBits, NULL, (DWORD)0); hMemDC = CreateCompatibleDC(hdc); src = CreateCompatibleDC(hdc); ReleaseDC(NULL,hdc); hOldBitmap = (HBITMAP)SelectObject(hMemDC, hBitmap); hOldSrc = SelectObject( src, hBm ); BitBlt(hMemDC,0,0,dwWidth,dwHeight,src,0,0,SRCCOPY); SelectObject(src,hOldSrc); DeleteDC(src); SelectObject(hMemDC,hOldBitmap); DeleteDC(hMemDC); // Create an empty mask bitmap hMonoBitmap = CreateBitmap(dwWidth,dwHeight,1,1,NULL); lpdwPixel = (DWORD *)lpBits; for (x=0;xdisableConsole(); #endif } int CEmulatorWin32::activeRead(char *buf) { #ifndef UNDER_CE CConsole* c = theConsole; if (c) return c->read(buf); #endif buf[0]=0; return 0; } void CEmulatorWin32::getEngineString(MyString& _engine) { _engine ="WIN32"; #ifdef USE_RASTER _engine+="(vbl)"; #endif }; void x_refresh_panel(int _enum) { #ifndef UNDER_CE CEmulatorWin32* p = (CEmulatorWin32*)CEmulator::theEmulator; if (!p) return; if (!p->activeInfo) return ; if (_enum & PANEL_PARAMS) p->activeInfo->updateParams(); if (_enum & (PANEL_DISK | PANEL_RUNTIME)) p->activeInfo->refresh(); #endif } const int soundWin32Ressources[]= { NULL, IDR_SPINUPSEARCH1, IDR_SPINUPSEARCH2 }; void x_play_sound(enum_sound hSound) { HINSTANCE h = ((CEmulatorWin32*)CEmulator::theEmulator)->hInst; BOOL err = PlaySound(MAKEINTRESOURCE(soundWin32Ressources[hSound]), h, SND_RESOURCE | SND_ASYNC); } int x_is_sound_playing(enum_sound _hSound) { return 0; };