diff --git a/COPYING.TXT b/COPYING.TXT index 60549be..d159169 100644 --- a/COPYING.TXT +++ b/COPYING.TXT @@ -1,12 +1,12 @@ - GNU GENERAL PUBLIC LICENSE - Version 2, June 1991 + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 - Copyright (C) 1989, 1991 Free Software Foundation, Inc. - 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Copyright (C) 1989, 1991 Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. - Preamble + Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public @@ -15,7 +15,7 @@ software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by -the GNU Library General Public License instead.) You can apply it to +the GNU Lesser General Public License instead.) You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not @@ -55,8 +55,8 @@ patent must be licensed for everyone's free use or not licensed at all. The precise terms and conditions for copying, distribution and modification follow. - - GNU GENERAL PUBLIC LICENSE + + GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License applies to any program or other work which contains @@ -110,7 +110,7 @@ above, provided that you also meet all of these conditions: License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.) - + These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in @@ -168,7 +168,7 @@ access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. - + 4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is @@ -225,7 +225,7 @@ impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. - + 8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License @@ -255,7 +255,7 @@ make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. - NO WARRANTY + NO WARRANTY 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN @@ -277,9 +277,9 @@ YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. - END OF TERMS AND CONDITIONS - - How to Apply These Terms to Your New Programs + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it @@ -291,7 +291,7 @@ convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. - Copyright (C) 19yy + Copyright (C) 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 @@ -303,17 +303,16 @@ the "copyright" line and a pointer to where the full notice is found. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. Also add information on how to contact you by electronic and paper mail. If the program is interactive, make it output a short notice like this when it starts in an interactive mode: - Gnomovision version 69, Copyright (C) 19yy name of author + Gnomovision version 69, Copyright (C) year name of author Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. @@ -336,5 +335,5 @@ necessary. Here is a sample; alter the names: This General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the -library. If this is what you want to do, use the GNU Library General +library. If this is what you want to do, use the GNU Lesser General Public License instead of this License. diff --git a/Emu48.exe b/Emu48.exe index d0c3df5..ae817d3 100755 Binary files a/Emu48.exe and b/Emu48.exe differ diff --git a/PROBLEMS.TXT b/PROBLEMS.TXT index ad3178d..edfff3e 100644 --- a/PROBLEMS.TXT +++ b/PROBLEMS.TXT @@ -1,4 +1,4 @@ -Known bugs and restrictions of Emu48 V1.57 +Known bugs and restrictions of Emu48 V1.58 ------------------------------------------ - the following I/O bits aren't emulated (incomplete) @@ -47,4 +47,4 @@ Known bugs and restrictions of Emu48 V1.57 - quitting the emulator while programming the flash isn't allowed, because the content of flash state machine isn't saved so far -07/14/15 (c) by Christoph Gießelink, c dot giesselink at gmx dot de +08/16/16 (c) by Christoph Gießelink, c dot giesselink at gmx dot de diff --git a/Sources/Emu48/CHANGES.TXT b/Sources/Emu48/CHANGES.TXT index 6bf9f48..0b0948e 100644 --- a/Sources/Emu48/CHANGES.TXT +++ b/Sources/Emu48/CHANGES.TXT @@ -1,3 +1,80 @@ +Service Pack 58 for Emu48 Version 1.0 + +DDESERV.C +- bugfix in function DdeCallback(), improved input data checking and + avoided multiple DDE data fetch in XTYP_POKE case + +DEBUGGER.C +- changed function UpdateStackWnd(), OnStackPush() and OnStackPop(), + fixed signed/unsigned mismatch +- bugfix in function OnLButtonUp(), fixed a buffer overflow when + converting a 3 byte hexadecimal string to variable Chipset.out + which overwrite the content of variable Chipset.in, fixed a buffer + overflow when converting a 4 byte hexadecimal string to variable + Chipset.in which overwrite the following two padding bytes and + changed method converting a 2 byte hexadecimal string to variable + Chipset.Bank_FF +- changed function UpdateProfileWnd(), fixed signed/unsigned + mismatch and optimized ENG unit search break +- changed function InfoWoRegister(), changed function prototype to + DLGPROC + +DISPLAY.C +- added variable for additional GDI zoom +- changed function UpdateMainDisplay(), UpdateMenuDisplay(), + WriteToMainDisplay() and WriteToMenuDisplay(), replaced BitBlt by + StretchBlt operation to implement an additional GDI zoom factor + (there is no noticeable speed difference between BitBlt and + StretchBlt with a stretching factor of 1) +- bugfix in function ResizeWindow(), the WM_PAINT message wasn't + generated by the InvalidateRect() call when the title and menu bar + was disabled and the client area was empty, so we got a main + window with zero size which could not be activated any more -> + issue solved by forcing a menu bar when client area is empty + +EMU48.C +- changed szLicence string, updated to the latest revision of the + GPLv2 +- moved function SetSoundDeviceList() to SNDENUM.C +- bugfix in function SettingsGeneralProc(), SettingsMemoryProc() and + SettingsPeripheralProc(), changed function prototype to DLGPROC + for getting a 64 bit lParam pointer when compiling for x64 + architecture +- changed function OnPaint(), replaced BitBlt by StretchBlt + operation at display handling to implement an additional GDI zoom + factor +- changed function OnViewSettings(), removed DLGPROC typecasts + +EMU48.DSP +- added snddef.h and sndenum.c sources + +EMU48.H +- extern declaration of global variable and function + +EMU48.RC +- changed IDD_SET_PERIPHERAL, enlarged width of slider + IDC_SOUND_SLIDER and combo box IDC_SOUND_DEVICE +- changed version and copyright + +KML.C +- changed function InitLcd(), removed Zoom factor 4 limitation +- changed function KillKML(), added reset of variable nGdiZoom +- changed function iSqrt(), changed implementation to Heron's method + for speed optimization + +SNDDEF.H +- include files and interface definitions for SNDENUM.C for + compilers without installed DirectX SDK + +SNDENUM.C +- new module with implementation of function SetSoundDeviceList() + prior located in EMU48.C for sound device enumeration showing the + full device name used since Windows Vista + +STACK.C +- removed include resource.h + + Service Pack 57 for Emu48 Version 1.0 DEBUGGER.C diff --git a/Sources/Emu48/DDESERV.C b/Sources/Emu48/DDESERV.C index 5ebb39b..f8a5c47 100644 --- a/Sources/Emu48/DDESERV.C +++ b/Sources/Emu48/DDESERV.C @@ -46,13 +46,6 @@ HDDEDATA CALLBACK DdeCallback(UINT iType,UINT iFmt,HCONV hConv, if (*psz != 0 || nStkLvl < 1) // invalid number format return (HDDEDATA) DDE_FNOTPROCESSED; - DdeAccessData(hData,&dwSize); // fetch data size - DdeUnaccessData(hData); - - // reserve memory - if ((lpData = (LPBYTE) malloc(dwSize * 2)) == NULL) - return (HDDEDATA) DDE_FNOTPROCESSED; - SuspendDebugger(); // suspend debugger bDbgAutoStateCtrl = FALSE; // disable automatic debugger state control @@ -66,7 +59,6 @@ HDDEDATA CALLBACK DdeCallback(UINT iType,UINT iFmt,HCONV hConv, if (WaitForSleepState()) // wait for cpu SHUTDN then sleep state { - free(lpData); // free memory hReturn = DDE_FNOTPROCESSED; goto cancel; } @@ -74,13 +66,32 @@ HDDEDATA CALLBACK DdeCallback(UINT iType,UINT iFmt,HCONV hConv, while (nState!=nNextState) Sleep(0); _ASSERT(nState==SM_SLEEP); - // fetch data and write to stack - DdeGetData(hData,(LPBYTE) &dwIndex,sizeof(DWORD),0L); - if (dwIndex <= dwSize - sizeof(DWORD)) - dwSize = dwIndex; - dwSize = DdeGetData(hData,lpData+dwSize,dwSize,sizeof(DWORD)); - bSuccess = (WriteStack(nStkLvl,lpData,dwSize) == S_ERR_NO); - free(lpData); // free memory + bSuccess = FALSE; + + // get data and size + lpData = DdeAccessData(hData,&dwSize); + + // has object length header + if (lpData && dwSize >= sizeof(DWORD)) + { + dwIndex = *(LPDWORD) lpData; // object length + + if (dwIndex <= dwSize - sizeof(DWORD)) + { + // reserve unpacked object length memory + LPBYTE pbyMem = (LPBYTE) malloc(dwIndex * 2); + + if (pbyMem != NULL) + { + // copy data and write to stack + CopyMemory(pbyMem+dwIndex,lpData+sizeof(DWORD),dwIndex); + bSuccess = (WriteStack(nStkLvl,pbyMem,dwIndex) == S_ERR_NO); + free(pbyMem); // free memory + } + } + } + + DdeUnaccessData(hData); SwitchToState(SM_RUN); // run state while (nState!=nNextState) Sleep(0); diff --git a/Sources/Emu48/DEBUGGER.C b/Sources/Emu48/DEBUGGER.C index d51a82a..0cab4aa 100644 --- a/Sources/Emu48/DEBUGGER.C +++ b/Sources/Emu48/DEBUGGER.C @@ -713,7 +713,7 @@ static VOID UpdateMemoryWnd(HWND hDlg) // static VOID UpdateStackWnd(HWND hDlg) { - INT i; + UINT i; LONG nPos; TCHAR szBuffer[64]; @@ -1168,15 +1168,15 @@ static BOOL OnStackPush(HWND hDlg) TCHAR szBuffer[] = _T("00000"); DWORD dwAddr; HWND hWnd; - INT i,j; + UINT i,j; if (nDbgState != DBG_STEPINTO) // not in single step mode return TRUE; hWnd = GetDlgItem(hDlg,IDC_DEBUG_STACK); - i = (INT) SendMessage(hWnd,LB_GETCURSEL,0,0); - if (LB_ERR == i) return TRUE; // no selection + i = (UINT) SendMessage(hWnd,LB_GETCURSEL,0,0); + if (LB_ERR == (INT) i) return TRUE; // no selection if (IDOK != OnNewValue(szBuffer)) // canceled function return TRUE; @@ -1200,15 +1200,15 @@ static BOOL OnStackPush(HWND hDlg) static BOOL OnStackPop(HWND hDlg) { HWND hWnd; - INT i,j; + UINT i,j; if (nDbgState != DBG_STEPINTO) // not in single step mode return TRUE; hWnd = GetDlgItem(hDlg,IDC_DEBUG_STACK); - i = (INT) SendMessage(hWnd,LB_GETCURSEL,0,0); - if (LB_ERR == i) return TRUE; // no selection + i = (UINT) SendMessage(hWnd,LB_GETCURSEL,0,0); + if (LB_ERR == (INT) i) return TRUE; // no selection // pop stack element for (j = i + 1; j < ARRAYSIZEOF(Chipset.rstk); ++j) @@ -1324,11 +1324,11 @@ static BOOL OnLButtonUp(HWND hDlg, LPARAM lParam) break; case IDC_REG_OUT: // OUT OnNewValue(&szBuffer[4]); - _stscanf(&szBuffer[4],_T("%3X"),&Chipset.out); + Chipset.out = (WORD) _tcstoul(&szBuffer[4],NULL,16); break; case IDC_REG_IN: // IN OnNewValue(&szBuffer[3]); - _stscanf(&szBuffer[3],_T("%4X"),&Chipset.in); + Chipset.in = (WORD) _tcstoul(&szBuffer[3],NULL,16); break; case IDC_REG_ST: // ST OnNewValue(&szBuffer[3]); @@ -1362,7 +1362,7 @@ static BOOL OnLButtonUp(HWND hDlg, LPARAM lParam) break; case IDC_MISC_BS: // Bank switcher setting OnNewValue(szBuffer); - _stscanf(szBuffer,_T("%2X"),&Chipset.Bank_FF); + Chipset.Bank_FF = _tcstoul(szBuffer,NULL,16); Chipset.Bank_FF &= 0x7F; RomSwitch(Chipset.Bank_FF); // update memory mapping @@ -2355,7 +2355,7 @@ static VOID UpdateProfileWnd(HWND hDlg) QWORD lVar; TCHAR szBuffer[64]; - INT i; + UINT i; DWORD dwFreq, dwEndFreq; if (hDlg == NULL) return; // dialog not open @@ -2373,10 +2373,9 @@ static VOID UpdateProfileWnd(HWND hDlg) : ((GX_RATE + 1) * CPU_FREQ / 4); dwEndFreq = ((999 * 2 - 1) * dwFreq) / (2 * 1000); - // search for unit - for (i = 0; i < ARRAYSIZEOF(pcUnit) - 1; ++i) + // search for ENG unit + for (i = 0; i < ARRAYSIZEOF(pcUnit) - 1 && lVar <= dwEndFreq; ++i) { - if (lVar > dwEndFreq) break; // found ENG unit lVar *= 1000; // next ENG unit } @@ -2850,7 +2849,7 @@ static VOID OnEnterAddress(HWND hDlg, DWORD *dwValue) static INT_PTR CALLBACK EnterBreakpoint(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) { static BP_T *sBp; - + DWORD dwAddr; switch (message) @@ -3269,7 +3268,7 @@ static BOOL OnInfoIntr(HWND hDlg) // // view write only I/O registers // -static BOOL CALLBACK InfoWoRegister(HWND hDlg, UINT message, DWORD wParam, LONG lParam) +static INT_PTR CALLBACK InfoWoRegister(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) { TCHAR szBuffer[8]; diff --git a/Sources/Emu48/DISPLAY.C b/Sources/Emu48/DISPLAY.C index 9b4b600..764d8f0 100644 --- a/Sources/Emu48/DISPLAY.C +++ b/Sources/Emu48/DISPLAY.C @@ -48,7 +48,8 @@ UINT nBackgroundW = 0; UINT nBackgroundH = 0; UINT nLcdX = 0; UINT nLcdY = 0; -UINT nLcdZoom = 1; +UINT nLcdZoom = 1; // memory DC zoom +UINT nGdiZoom = 1; // GDI zoom HDC hLcdDC = NULL; HDC hMainDC = NULL; @@ -401,8 +402,8 @@ VOID UpdateMainDisplay(VOID) } EnterCriticalSection(&csGDILock); // solving NT GDI problems { - BitBlt(hWindowDC, nLcdX, nLcdY, 131*nLcdZoom, nLines*nLcdZoom, - hLcdDC, Chipset.boffset*nLcdZoom, 0, SRCCOPY); + StretchBlt(hWindowDC, nLcdX, nLcdY, 131*nLcdZoom*nGdiZoom, nLines*nLcdZoom*nGdiZoom, + hLcdDC, Chipset.boffset*nLcdZoom, 0, 131*nLcdZoom, nLines*nLcdZoom,SRCCOPY); GdiFlush(); } LeaveCriticalSection(&csGDILock); @@ -507,9 +508,9 @@ VOID UpdateMenuDisplay(VOID) } EnterCriticalSection(&csGDILock); // solving NT GDI problems { - BitBlt(hWindowDC, nLcdX, nLcdY+nLines*nLcdZoom, - 131*nLcdZoom, (64-nLines)*nLcdZoom, - hLcdDC, 0, nLines*nLcdZoom, SRCCOPY); + StretchBlt(hWindowDC, nLcdX, nLcdY+nLines*nLcdZoom*nGdiZoom, + 131*nLcdZoom*nGdiZoom, (64-nLines)*nLcdZoom*nGdiZoom, + hLcdDC, 0, nLines*nLcdZoom, 131*nLcdZoom, (64-nLines)*nLcdZoom, SRCCOPY); GdiFlush(); } LeaveCriticalSection(&csGDILock); @@ -554,7 +555,7 @@ VOID WriteToMainDisplay(LPBYTE a, DWORD d, UINT s) // calculate memory position in LCD bitmap p = (DWORD*) (pbyLcd + y0*LCD_ROW*nLcdZoom*nLcdZoom - + x0*sizeof(*p)*nLcdZoom); + + x0*sizeof(*p)*nLcdZoom); while (s--) // loop for nibbles to write { @@ -639,7 +640,9 @@ VOID WriteToMainDisplay(LPBYTE a, DWORD d, UINT s) EnterCriticalSection(&csGDILock); { - BitBlt(hWindowDC, nLcdX+x0, nLcdY+y0, x, y-y0, hLcdDC, x0+Chipset.boffset*nLcdZoom, y0, SRCCOPY); + StretchBlt(hWindowDC, nLcdX+x0*nGdiZoom, nLcdY+y0*nGdiZoom, + x*nGdiZoom, (y-y0)*nGdiZoom, + hLcdDC, x0+Chipset.boffset*nLcdZoom, y0, x, y-y0, SRCCOPY); GdiFlush(); } LeaveCriticalSection(&csGDILock); @@ -676,7 +679,7 @@ VOID WriteToMenuDisplay(LPBYTE a, DWORD d, UINT s) // calculate memory position in LCD bitmap p = (DWORD*) (pbyLcd + y0*LCD_ROW*nLcdZoom*nLcdZoom - + x0*sizeof(*p)*nLcdZoom); + + x0*sizeof(*p)*nLcdZoom); if (nLcdZoom == 4) { @@ -801,7 +804,9 @@ VOID WriteToMenuDisplay(LPBYTE a, DWORD d, UINT s) EnterCriticalSection(&csGDILock); // solving NT GDI problems { - BitBlt(hWindowDC, nLcdX+x0, nLcdY+y0, x-x0, y-y0+nLcdZoom, hLcdDC, x0, y0, SRCCOPY); + StretchBlt(hWindowDC, nLcdX+x0*nGdiZoom, nLcdY+y0*nGdiZoom, + (x-x0)*nGdiZoom, (y-y0+nLcdZoom)*nGdiZoom, + hLcdDC, x0, y0, x-x0, y-y0+nLcdZoom, SRCCOPY); GdiFlush(); } LeaveCriticalSection(&csGDILock); @@ -840,7 +845,7 @@ VOID ResizeWindow(VOID) AdjustWindowRect(&rectWindow, (DWORD) GetWindowLongPtr(hWnd,GWL_STYLE), - GetMenu(hWnd) != NULL); + GetMenu(hWnd) != NULL || IsRectEmpty(&rectWindow)); SetWindowPos(hWnd, bAlwaysOnTop ? HWND_TOPMOST : HWND_NOTOPMOST, 0, 0, rectWindow.right - rectWindow.left, rectWindow.bottom - rectWindow.top, diff --git a/Sources/Emu48/EMU48.C b/Sources/Emu48/EMU48.C index ba52fcc..0fe546f 100644 --- a/Sources/Emu48/EMU48.C +++ b/Sources/Emu48/EMU48.C @@ -13,7 +13,7 @@ #include "kml.h" #include "debugger.h" -#define VERSION "1.57" +#define VERSION "1.58" #ifdef _DEBUG LPCTSTR szNoTitle = _T("Emu48 ")_T(VERSION)_T(" Debug"); @@ -35,9 +35,9 @@ static const LPCTSTR szLicence = _T("MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\r\n") _T("See the GNU General Public License for more details.\r\n") _T("\r\n") - _T("You should have received a copy of the GNU General Public License\r\n") - _T("along with this program; if not, write to the Free Software Foundation,\r\n") - _T("Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA"); + _T("You should have received a copy of the GNU General Public License along\r\n") + _T("with this program; if not, write to the Free Software Foundation, Inc.,\r\n") + _T("51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA."); static BOOL bOwnCursor = FALSE; static BOOL bTitleBar = TRUE; @@ -318,35 +318,6 @@ static BOOL IsFileWriteable(LPCTSTR szFilename) return bWriteable; } -// set listfield for sound device combo box -static VOID SetSoundDeviceList(HWND hWnd,UINT uDeviceID) -{ - WAVEOUTCAPS woc; - UINT uSelectDevice,uDevID,uDevNo; - - SendMessage(hWnd,CB_RESETCONTENT,0,0); - - // preset selector - uSelectDevice = (UINT) SendMessage(hWnd,CB_ADDSTRING,0,(LPARAM) _T("Standard Audio")); - SendMessage(hWnd,CB_SETITEMDATA,uSelectDevice,WAVE_MAPPER); - - uDevNo = waveOutGetNumDevs(); - for (uDevID = 0; uDevID < uDevNo; ++uDevID) - { - if ( waveOutGetDevCaps(uDevID,&woc,sizeof(woc)) == MMSYSERR_NOERROR - && (woc.dwFormats & WAVE_FORMAT_4M08) != 0) - { - // copy product name to combo box - LONG i = (LONG) SendMessage(hWnd,CB_ADDSTRING,0,(LPARAM) woc.szPname); - SendMessage(hWnd,CB_SETITEMDATA,i,uDevID); - - if (uDevID == uDeviceID) uSelectDevice = i; - } - } - SendMessage(hWnd,CB_SETCURSEL,uSelectDevice,0L); - return; -} - // set listfield for serial combo boxes static VOID SetCommList(HWND hDlg,LPCTSTR szWireSetting,LPCTSTR szIrSetting) { @@ -423,7 +394,7 @@ static VOID SetCommList(HWND hDlg,LPCTSTR szWireSetting,LPCTSTR szIrSetting) return; } -static BOOL CALLBACK SettingsGeneralProc(HWND hDlg, UINT uMsg, DWORD wParam, LONG lParam) +static INT_PTR CALLBACK SettingsGeneralProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) { HWND hWndInsertAfter; @@ -495,7 +466,7 @@ static BOOL CALLBACK SettingsGeneralProc(HWND hDlg, UINT uMsg, DWORD wParam, LON UNREFERENCED_PARAMETER(wParam); } -static BOOL CALLBACK SettingsMemoryProc(HWND hDlg, UINT uMsg, DWORD wParam, LONG lParam) +static INT_PTR CALLBACK SettingsMemoryProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) { LPCTSTR szActPort2Filename = _T(""); @@ -685,7 +656,7 @@ static BOOL CALLBACK SettingsMemoryProc(HWND hDlg, UINT uMsg, DWORD wParam, LONG return FALSE; } -static BOOL CALLBACK SettingsPeripheralProc(HWND hDlg, UINT uMsg, DWORD wParam, LONG lParam) +static INT_PTR CALLBACK SettingsPeripheralProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) { TCHAR cPort[8]; LONG i; @@ -914,13 +885,15 @@ static LRESULT OnPaint(HWND hWindow) SetWindowOrgEx(hPaintDC, nBackgroundX, nBackgroundY, NULL); // redraw main display area - BitBlt(hPaintDC, nLcdX, nLcdY, - 131*nLcdZoom, nLines*nLcdZoom, - hLcdDC, Chipset.boffset*nLcdZoom, 0, SRCCOPY); + StretchBlt(hPaintDC, nLcdX, nLcdY, + 131*nLcdZoom*nGdiZoom, nLines*nLcdZoom*nGdiZoom, + hLcdDC, Chipset.boffset*nLcdZoom, 0, + 131*nLcdZoom, nLines*nLcdZoom, SRCCOPY); // redraw menu display area - BitBlt(hPaintDC, nLcdX, nLcdY+nLines*nLcdZoom, - 131*nLcdZoom, (64-nLines)*nLcdZoom, - hLcdDC, 0, nLines*nLcdZoom, SRCCOPY); + StretchBlt(hPaintDC, nLcdX, nLcdY+nLines*nLcdZoom*nGdiZoom, + 131*nLcdZoom*nGdiZoom, (64-nLines)*nLcdZoom*nGdiZoom, + hLcdDC, 0, nLines*nLcdZoom, + 131*nLcdZoom, (64-nLines)*nLcdZoom, SRCCOPY); GdiFlush(); } LeaveCriticalSection(&csGDILock); @@ -1324,7 +1297,7 @@ static LRESULT OnViewSettings(VOID) psp[0].pszTemplate = MAKEINTRESOURCE(IDD_SET_GENERAL); psp[0].hIcon = NULL; psp[0].pszTitle = NULL; - psp[0].pfnDlgProc = (DLGPROC) SettingsGeneralProc; + psp[0].pfnDlgProc = SettingsGeneralProc; psp[0].lParam = 0; psp[0].pfnCallback = NULL; @@ -1334,7 +1307,7 @@ static LRESULT OnViewSettings(VOID) psp[1].pszTemplate = MAKEINTRESOURCE(IDD_SET_MEMORY); psp[1].hIcon = NULL; psp[1].pszTitle = NULL; - psp[1].pfnDlgProc = (DLGPROC) SettingsMemoryProc; + psp[1].pfnDlgProc = SettingsMemoryProc; psp[1].lParam = 0; psp[1].pfnCallback = NULL; @@ -1344,7 +1317,7 @@ static LRESULT OnViewSettings(VOID) psp[2].pszTemplate = MAKEINTRESOURCE(IDD_SET_PERIPHERAL); psp[2].hIcon = NULL; psp[2].pszTitle = NULL; - psp[2].pfnDlgProc = (DLGPROC) SettingsPeripheralProc; + psp[2].pfnDlgProc = SettingsPeripheralProc; psp[2].lParam = 0; psp[2].pfnCallback = NULL; diff --git a/Sources/Emu48/EMU48.DSP b/Sources/Emu48/EMU48.DSP index 9448d6f..a68cc5a 100644 --- a/Sources/Emu48/EMU48.DSP +++ b/Sources/Emu48/EMU48.DSP @@ -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 @@ -35,13 +35,13 @@ RSC=rc.exe # PROP BASE Use_MFC 0 # PROP BASE Use_Debug_Libraries 0 -# PROP BASE Output_Dir ".\Release" -# PROP BASE Intermediate_Dir ".\Release" +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" # PROP BASE Target_Dir "" # PROP Use_MFC 0 # PROP Use_Debug_Libraries 0 -# PROP Output_Dir ".\Release" -# PROP Intermediate_Dir ".\Release" +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" # ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /YX /c @@ -61,13 +61,13 @@ LINK32=link.exe # PROP BASE Use_MFC 0 # PROP BASE Use_Debug_Libraries 1 -# PROP BASE Output_Dir ".\Debug" -# PROP BASE Intermediate_Dir ".\Debug" +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" # PROP BASE Target_Dir "" # PROP Use_MFC 0 # PROP Use_Debug_Libraries 1 -# PROP Output_Dir ".\Debug" -# PROP Intermediate_Dir ".\Debug" +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" # ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /YX /c @@ -87,14 +87,14 @@ LINK32=link.exe # PROP BASE Use_MFC 0 # PROP BASE Use_Debug_Libraries 0 -# PROP BASE Output_Dir "Emu48___" -# PROP BASE Intermediate_Dir "Emu48___" +# PROP BASE Output_Dir "ReleaseUnicode" +# PROP BASE Intermediate_Dir "ReleaseUnicode" # PROP BASE Ignore_Export_Lib 0 # PROP BASE Target_Dir "" # PROP Use_MFC 0 # PROP Use_Debug_Libraries 0 -# PROP Output_Dir ".\ReleaseUnicode" -# PROP Intermediate_Dir ".\ReleaseUnicode" +# PROP Output_Dir "ReleaseUnicode" +# PROP Intermediate_Dir "ReleaseUnicode" # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" # ADD BASE CPP /nologo /Gr /MT /W3 /GX /O2 /Ob2 /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "STRICT" /Yu"pch.h" /FD /c @@ -114,14 +114,14 @@ LINK32=link.exe # PROP BASE Use_MFC 0 # PROP BASE Use_Debug_Libraries 1 -# PROP BASE Output_Dir "Emu48__0" -# PROP BASE Intermediate_Dir "Emu48__0" +# PROP BASE Output_Dir "DebugUnicode" +# PROP BASE Intermediate_Dir "DebugUnicode" # PROP BASE Ignore_Export_Lib 0 # PROP BASE Target_Dir "" # PROP Use_MFC 0 # PROP Use_Debug_Libraries 1 -# PROP Output_Dir ".\DebugUnicode" -# PROP Intermediate_Dir ".\DebugUnicode" +# PROP Output_Dir "DebugUnicode" +# PROP Intermediate_Dir "DebugUnicode" # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" # ADD BASE CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "STRICT" /FR /Yu"pch.h" /FD /c @@ -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 @@ -256,6 +256,10 @@ SOURCE=.\settings.c # End Source File # Begin Source File +SOURCE=.\sndenum.c +# End Source File +# Begin Source File + SOURCE=.\sound.c # End Source File # Begin Source File @@ -320,6 +324,10 @@ SOURCE=.\pch.h # End Source File # Begin Source File +SOURCE=.\snddef.h +# End Source File +# Begin Source File + SOURCE=.\types.h # End Source File # End Group diff --git a/Sources/Emu48/EMU48.H b/Sources/Emu48/EMU48.H index ae0209d..4a270a7 100644 --- a/Sources/Emu48/EMU48.H +++ b/Sources/Emu48/EMU48.H @@ -160,6 +160,7 @@ extern UINT nBackgroundH; extern UINT nLcdX; extern UINT nLcdY; extern UINT nLcdZoom; +extern UINT nGdiZoom; extern HDC hLcdDC; extern HDC hMainDC; extern BYTE (*GetLineCounter)(VOID); @@ -361,8 +362,11 @@ extern VOID RPL_Replace(DWORD n); extern VOID RPL_Push(UINT l,DWORD n); // External.c -extern VOID External(CHIPSET* w); -extern VOID RCKBp(CHIPSET* w); +extern VOID External(CHIPSET* w); +extern VOID RCKBp(CHIPSET* w); + +// SndEnum.c +extern VOID SetSoundDeviceList(HWND hWnd,UINT uDeviceID); // Sound.c extern DWORD dwWaveVol; diff --git a/Sources/Emu48/EMU48.RC b/Sources/Emu48/EMU48.RC index ee022ba..54eaf48 100644 --- a/Sources/Emu48/EMU48.RC +++ b/Sources/Emu48/EMU48.RC @@ -106,7 +106,6 @@ BEGIN VERTGUIDE, 14 VERTGUIDE, 147 VERTGUIDE, 154 - VERTGUIDE, 161 VERTGUIDE, 237 TOPMARGIN, 7 BOTTOMMARGIN, 127 @@ -296,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 © 2015 Christoph Gießelink && Sébastien Carlier", + LTEXT "Copyright © 2016 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 | @@ -365,9 +364,9 @@ FONT 8, "MS Sans Serif" BEGIN LTEXT "Volume",IDC_STATIC,14,21,24,8 CONTROL "Slider1",IDC_SOUND_SLIDER,"msctls_trackbar32", - TBS_AUTOTICKS | WS_TABSTOP,44,16,118,18 + TBS_AUTOTICKS | WS_TABSTOP,44,16,193,18 LTEXT "Device",IDC_STATIC,13,42,24,8 - COMBOBOX IDC_SOUND_DEVICE,44,40,118,87,CBS_DROPDOWNLIST | + COMBOBOX IDC_SOUND_DEVICE,44,40,193,87,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP GROUPBOX "Sound",IDC_STATIC,7,7,237,54 LTEXT "IP Address:",IDC_STATIC,14,81,37,8 @@ -692,8 +691,8 @@ END // VS_VERSION_INFO VERSIONINFO - FILEVERSION 1,5,7,0 - PRODUCTVERSION 1,5,7,0 + FILEVERSION 1,5,8,0 + PRODUCTVERSION 1,5,8,0 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -710,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, 5, 7, 0\0" + VALUE "FileVersion", "1, 5, 8, 0\0" VALUE "InternalName", "Emu48\0" - VALUE "LegalCopyright", "Copyright © 2015\0" + VALUE "LegalCopyright", "Copyright © 2016\0" VALUE "OriginalFilename", "Emu48.exe\0" VALUE "ProductName", "Emu48\0" - VALUE "ProductVersion", "1, 5, 7, 0\0" + VALUE "ProductVersion", "1, 5, 8, 0\0" END END BLOCK "VarFileInfo" diff --git a/Sources/Emu48/KML.C b/Sources/Emu48/KML.C index d129278..e05d10a 100644 --- a/Sources/Emu48/KML.C +++ b/Sources/Emu48/KML.C @@ -1335,9 +1335,15 @@ static KmlLine* InitLcd(KmlBlock* pBlock) nLcdY = (UINT) pLine->nParam[1]; break; case TOK_ZOOM: - nLcdZoom = (UINT) pLine->nParam[0]; - if (!(nLcdZoom >= 1 && nLcdZoom <= 4)) - nLcdZoom = 1; + if ((nGdiZoom = (UINT) pLine->nParam[0]) == 0) + { + nGdiZoom = 1; // default zoom + } + + // search for memory DC zoom (1-4) + for (nLcdZoom = 4; (nGdiZoom % nLcdZoom) != 0; --nLcdZoom) { }; + _ASSERT(nLcdZoom > 0); // because (nGdiZoom % 1) == 0 + nGdiZoom /= nLcdZoom; // remainder is GDI zoom break; case TOK_COLOR: SetLcdColor((UINT) pLine->nParam[0],(UINT) pLine->nParam[1], @@ -1674,6 +1680,7 @@ VOID KillKML(VOID) nBackgroundW = 256; nBackgroundH = 0; nLcdZoom = 1; + nGdiZoom = 1; dwTColor = (DWORD) -1; dwTColorTol = 0; cCurrentRomType = 0; @@ -1740,20 +1747,21 @@ static DWORD GetIntegerParam(KmlBlock* pBlock, TokenId eBlock, TokenId eCommand, //# //################ -static INT iSqrt(INT nNumber) // integer y=sqrt(x) function +static UINT iSqrt(UINT nNumber) // integer y=sqrt(x) function { - INT m, b = 0, t = nNumber; + UINT b, t; - do + b = t = nNumber; + + if (nNumber > 0) { - m = (b + t + 1) / 2; // median number - if (m * m - nNumber > 0) // calculate x^2-y - t = m; // adjust upper border - else - b = m; // adjust lower border + do + { + b = t; + t = (t + nNumber / t) / 2; // Heron's method + } + while (t < b); } - while (t - b > 1); - return b; } diff --git a/Sources/Emu48/SNDDEF.H b/Sources/Emu48/SNDDEF.H new file mode 100644 index 0000000..500232d --- /dev/null +++ b/Sources/Emu48/SNDDEF.H @@ -0,0 +1,102 @@ +/* + * snddef.h + * + * This file is part of Emu48 + * + * Copyright (C) 2015 Christoph Gießelink + * + */ + +#include + +#if _MSC_VER >= 1600 // valid for VS2010 and later + +#include +#include + +#else // create the necessary definitions manually + +// +// IKsPropertySet +// + +#ifndef _IKsPropertySet_ +#define _IKsPropertySet_ + +#ifdef __cplusplus +struct IKsPropertySet; +#endif // __cplusplus + +typedef struct IKsPropertySet *LPKSPROPERTYSET; + +DEFINE_GUID(IID_IKsPropertySet, 0x31efac30, 0x515c, 0x11d0, 0xa9, 0xaa, 0x00, 0xaa, 0x00, 0x61, 0xbe, 0x93); + +#undef INTERFACE +#define INTERFACE IKsPropertySet + +DECLARE_INTERFACE_(IKsPropertySet, IUnknown) +{ + // IUnknown methods + STDMETHOD(QueryInterface) (THIS_ REFIID, LPVOID*) PURE; + STDMETHOD_(ULONG,AddRef) (THIS) PURE; + STDMETHOD_(ULONG,Release) (THIS) PURE; + + // IKsPropertySet methods + STDMETHOD(Get) (THIS_ REFGUID rguidPropSet, ULONG ulId, LPVOID pInstanceData, ULONG ulInstanceLength, + LPVOID pPropertyData, ULONG ulDataLength, PULONG pulBytesReturned) PURE; + STDMETHOD(Set) (THIS_ REFGUID rguidPropSet, ULONG ulId, LPVOID pInstanceData, ULONG ulInstanceLength, + LPVOID pPropertyData, ULONG ulDataLength) PURE; + STDMETHOD(QuerySupport) (THIS_ REFGUID rguidPropSet, ULONG ulId, PULONG pulTypeSupport) PURE; +}; + +#endif // _IKsPropertySet_ + +// DirectSound Configuration Component GUID {11AB3EC0-25EC-11d1-A4D8-00C04FC28ACA} +DEFINE_GUID(CLSID_DirectSoundPrivate, 0x11ab3ec0, 0x25ec, 0x11d1, 0xa4, 0xd8, 0x0, 0xc0, 0x4f, 0xc2, 0x8a, 0xca); + +// DirectSound Device Properties {84624F82-25EC-11d1-A4D8-00C04FC28ACA} +DEFINE_GUID(DSPROPSETID_DirectSoundDevice, 0x84624f82, 0x25ec, 0x11d1, 0xa4, 0xd8, 0x0, 0xc0, 0x4f, 0xc2, 0x8a, 0xca); + +typedef enum +{ + DSPROPERTY_DIRECTSOUNDDEVICE_WAVEDEVICEMAPPING_A = 1, + DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_1 = 2, + DSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE_1 = 3, + DSPROPERTY_DIRECTSOUNDDEVICE_WAVEDEVICEMAPPING_W = 4, + DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_A = 5, + DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_W = 6, + DSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE_A = 7, + DSPROPERTY_DIRECTSOUNDDEVICE_ENUMERATE_W = 8, +} DSPROPERTY_DIRECTSOUNDDEVICE; + +#ifdef UNICODE +#define DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_W +#else // UNICODE +#define DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_A +#endif // UNICODE + +typedef enum +{ + DIRECTSOUNDDEVICE_TYPE_EMULATED, + DIRECTSOUNDDEVICE_TYPE_VXD, + DIRECTSOUNDDEVICE_TYPE_WDM +} DIRECTSOUNDDEVICE_TYPE; + +typedef enum +{ + DIRECTSOUNDDEVICE_DATAFLOW_RENDER, + DIRECTSOUNDDEVICE_DATAFLOW_CAPTURE +} DIRECTSOUNDDEVICE_DATAFLOW; + +typedef struct _DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_DATA +{ + DIRECTSOUNDDEVICE_TYPE Type; // Device type + DIRECTSOUNDDEVICE_DATAFLOW DataFlow; // Device dataflow + GUID DeviceId; // DirectSound device id + LPTSTR Description; // Device description + LPTSTR Module; // Device driver module + LPTSTR Interface; // Device interface + ULONG WaveDeviceId; // Wave device id +} DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_DATA, *PDSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_DATA; + +#endif diff --git a/Sources/Emu48/SNDENUM.C b/Sources/Emu48/SNDENUM.C new file mode 100644 index 0000000..eb9adda --- /dev/null +++ b/Sources/Emu48/SNDENUM.C @@ -0,0 +1,256 @@ +/* + * SndEnum.c + * + * This file is part of Emu48 + * + * Copyright (C) 2015 Christoph Gießelink + * + */ +#include "pch.h" +#include "Emu48.h" +#include "snddef.h" + +typedef HRESULT (WINAPI *LPFNDLLGETCLASSOBJECT)(REFCLSID,REFIID,LPVOID *); +static LPFNDLLGETCLASSOBJECT pfnDllGetClassObject = NULL; + +// +// create a IKsPropertySet interface +// +static __inline HRESULT DirectSoundPrivateCreate(LPKSPROPERTYSET *ppKsPropertySet) +{ + LPCLASSFACTORY pClassFactory = NULL; + HRESULT hr; + + // create a class factory object + #if defined __cplusplus + hr = pfnDllGetClassObject(CLSID_DirectSoundPrivate,IID_IClassFactory,(LPVOID *) &pClassFactory); + #else + hr = pfnDllGetClassObject(&CLSID_DirectSoundPrivate,&IID_IClassFactory,(LPVOID *) &pClassFactory); + #endif + + // create the DirectSoundPrivate object and query for an IKsPropertySet interface + if (SUCCEEDED(hr)) + { + #if defined __cplusplus + hr = pClassFactory->CreateInstance(NULL,IID_IKsPropertySet,(LPVOID *) ppKsPropertySet); + #else + hr = pClassFactory->lpVtbl->CreateInstance(pClassFactory,NULL,&IID_IKsPropertySet,(LPVOID *) ppKsPropertySet); + #endif + } + + if (pClassFactory) // release the class factory object + { + #if defined __cplusplus + pClassFactory->Release(); + #else + pClassFactory->lpVtbl->Release(pClassFactory); + #endif + } + + if (FAILED(hr) && *ppKsPropertySet) // handle failure + { + #if defined __cplusplus + (*ppKsPropertySet)->Release(); + #else + (*ppKsPropertySet)->lpVtbl->Release(*ppKsPropertySet); + #endif + } + return hr; +} + +// +// get the device information about a DirectSound GUID. +// +static BOOL GetInfoFromDSoundGUID(CONST GUID *lpGUID, UINT *puWaveDeviceID) +{ + LPKSPROPERTYSET pKsPropertySet = NULL; + HRESULT hr; + BOOL bSuccess = FALSE; + + hr = DirectSoundPrivateCreate(&pKsPropertySet); + if (SUCCEEDED(hr)) + { + ULONG ulBytesReturned = 0; + + DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_DATA sDirectSoundDeviceDescription; + + ZeroMemory(&sDirectSoundDeviceDescription,sizeof(sDirectSoundDeviceDescription)); + sDirectSoundDeviceDescription.DeviceId = *lpGUID; + + // get the size of the direct sound device description + #if defined __cplusplus + hr = pKsPropertySet->Get( + DSPROPSETID_DirectSoundDevice, + DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION, + NULL, + 0, + &sDirectSoundDeviceDescription, + sizeof(sDirectSoundDeviceDescription), + &ulBytesReturned + ); + #else + hr = pKsPropertySet->lpVtbl->Get(pKsPropertySet, + &DSPROPSETID_DirectSoundDevice, + DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION, + NULL, + 0, + &sDirectSoundDeviceDescription, + sizeof(sDirectSoundDeviceDescription), + &ulBytesReturned + ); + #endif + + if (SUCCEEDED(hr) && ulBytesReturned) + { + PDSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_DATA psDirectSoundDeviceDescription = NULL; + + // fetch the direct sound device description + psDirectSoundDeviceDescription = (PDSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_DATA) malloc(ulBytesReturned); + if (psDirectSoundDeviceDescription != NULL) + { + // init structure with data from length request + *psDirectSoundDeviceDescription = sDirectSoundDeviceDescription; + + #if defined __cplusplus + hr = pKsPropertySet->Get( + DSPROPSETID_DirectSoundDevice, + DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION, + NULL, + 0, + psDirectSoundDeviceDescription, + ulBytesReturned, + &ulBytesReturned + ); + #else + hr = pKsPropertySet->lpVtbl->Get(pKsPropertySet, + &DSPROPSETID_DirectSoundDevice, + DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION, + NULL, + 0, + psDirectSoundDeviceDescription, + ulBytesReturned, + &ulBytesReturned + ); + #endif + + if ((bSuccess = SUCCEEDED(hr))) + { + // the requested device ID + *puWaveDeviceID = psDirectSoundDeviceDescription->WaveDeviceId; + } + free(psDirectSoundDeviceDescription); + } + } + + #if defined __cplusplus + pKsPropertySet->Release(); + #else + pKsPropertySet->lpVtbl->Release(pKsPropertySet); + #endif + } + return bSuccess; +} + +// +// callback function for DirectSoundEnumerate() +// +static BOOL CALLBACK DSEnumProc(LPGUID lpGUID,LPCTSTR lpszDesc,LPCTSTR lpszDrvName,LPVOID lpContext) +{ + HWND hWnd = (HWND) lpContext; // window handle of the combo box + + if (lpGUID != NULL) // NULL only for "Primary Sound Driver" + { + UINT uDevID; + + if (GetInfoFromDSoundGUID(lpGUID,&uDevID)) + { + WAVEOUTCAPS woc; + + // has device the necessary capabilities? + if ( waveOutGetDevCaps(uDevID,&woc,sizeof(woc)) == MMSYSERR_NOERROR + && (woc.dwFormats & WAVE_FORMAT_4M08) != 0) + { + // copy product name and wave device ID to combo box + LONG i = (LONG) SendMessage(hWnd,CB_ADDSTRING,0,(LPARAM) lpszDesc); + SendMessage(hWnd,CB_SETITEMDATA,i,uDevID); + } + } + } + return TRUE; + UNREFERENCED_PARAMETER(lpszDrvName); +} + +// set listfield for sound device combo box +VOID SetSoundDeviceList(HWND hWnd,UINT uDeviceID) +{ + typedef BOOL (CALLBACK *LPDSENUMCALLBACK)(LPGUID, LPCTSTR, LPCTSTR, LPVOID); + typedef HRESULT (WINAPI *LPFN_SDE)(LPDSENUMCALLBACK lpDSEnumCallback,LPVOID lpContext); + LPFN_SDE pfnDirectSoundEnumerate = NULL; + + UINT uSelectDevice,uDevID,uDevNo; + + HMODULE hDSound = LoadLibrary(_T("dsound.dll")); + + if (hDSound != NULL) // direct sound dll found + { + #if defined _UNICODE + pfnDirectSoundEnumerate = (LPFN_SDE) GetProcAddress(hDSound,"DirectSoundEnumerateW"); + #else + pfnDirectSoundEnumerate = (LPFN_SDE) GetProcAddress(hDSound,"DirectSoundEnumerateA"); + #endif + pfnDllGetClassObject = (LPFNDLLGETCLASSOBJECT) GetProcAddress(hDSound,"DllGetClassObject"); + } + + SendMessage(hWnd,CB_RESETCONTENT,0,0); + + // preset selector + uSelectDevice = (UINT) SendMessage(hWnd,CB_ADDSTRING,0,(LPARAM) _T("Standard Audio")); + SendMessage(hWnd,CB_SETITEMDATA,uSelectDevice,WAVE_MAPPER); + + // check for direct sound interface functions + if (pfnDirectSoundEnumerate != NULL && pfnDllGetClassObject != NULL) + { + // copy product name and wave device ID to combo box + if (SUCCEEDED(pfnDirectSoundEnumerate((LPDSENUMCALLBACK) DSEnumProc,hWnd))) + { + UINT i; + + uDevNo = (UINT) SendMessage(hWnd,CB_GETCOUNT,0,0); + for (i = 0; i < uDevNo; ++i) + { + // translate device ID to combo box position + uDevID = (UINT) SendMessage(hWnd,CB_GETITEMDATA,i,0); + + if (uDevID == uDeviceID) uSelectDevice = i; + } + } + } + else // direct sound not available, detect over wave capabilities + { + WAVEOUTCAPS woc; + + uDevNo = waveOutGetNumDevs(); + for (uDevID = 0; uDevID < uDevNo; ++uDevID) + { + if ( waveOutGetDevCaps(uDevID,&woc,sizeof(woc)) == MMSYSERR_NOERROR + && (woc.dwFormats & WAVE_FORMAT_4M08) != 0) + { + // copy product name and wave device ID to combo box + LONG i = (LONG) SendMessage(hWnd,CB_ADDSTRING,0,(LPARAM) woc.szPname); + SendMessage(hWnd,CB_SETITEMDATA,i,uDevID); + + if (uDevID == uDeviceID) uSelectDevice = i; + } + } + } + + // activate last selected combo box item + SendMessage(hWnd,CB_SETCURSEL,uSelectDevice,0L); + + if (hDSound != NULL) // direct sound dll loaded + { + pfnDllGetClassObject = NULL; + VERIFY(FreeLibrary(hDSound)); + } + return; +} diff --git a/Sources/Emu48/STACK.C b/Sources/Emu48/STACK.C index 2840687..b709cc1 100644 --- a/Sources/Emu48/STACK.C +++ b/Sources/Emu48/STACK.C @@ -7,7 +7,6 @@ * */ #include "pch.h" -#include "resource.h" #include "Emu48.h" #include "io.h" diff --git a/Sources/GCCPatch/EMU48GCC.RC b/Sources/GCCPatch/EMU48GCC.RC index 6e22004..f6be9ad 100644 --- a/Sources/GCCPatch/EMU48GCC.RC +++ b/Sources/GCCPatch/EMU48GCC.RC @@ -106,7 +106,6 @@ BEGIN VERTGUIDE, 14 VERTGUIDE, 147 VERTGUIDE, 154 - VERTGUIDE, 161 VERTGUIDE, 237 TOPMARGIN, 7 BOTTOMMARGIN, 127 @@ -296,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 © 2015 Christoph Gießelink && Sébastien Carlier", + LTEXT "Copyright © 2016 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 | @@ -365,9 +364,9 @@ FONT 8, "MS Sans Serif" BEGIN LTEXT "Volume",IDC_STATIC,14,21,24,8 CONTROL "Slider1",IDC_SOUND_SLIDER,"msctls_trackbar32", - TBS_AUTOTICKS | WS_TABSTOP,44,16,118,18 + TBS_AUTOTICKS | WS_TABSTOP,44,16,193,18 LTEXT "Device",IDC_STATIC,13,42,24,8 - COMBOBOX IDC_SOUND_DEVICE,44,40,118,87,CBS_DROPDOWNLIST | + COMBOBOX IDC_SOUND_DEVICE,44,40,193,87,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP GROUPBOX "Sound",IDC_STATIC,7,7,237,54 LTEXT "IP Address:",IDC_STATIC,14,81,37,8 @@ -720,8 +719,8 @@ END // VS_VERSION_INFO VERSIONINFO - FILEVERSION 1,5,7,0 - PRODUCTVERSION 1,5,7,0 + FILEVERSION 1,5,8,0 + PRODUCTVERSION 1,5,8,0 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -738,12 +737,12 @@ BEGIN BEGIN VALUE "CompanyName", "Christoph Gießelink & Sebastien Carlier\0" VALUE "FileDescription", "HP38/39/40/48/49 Emulator\0" - VALUE "FileVersion", "1, 5, 7, 0\0" + VALUE "FileVersion", "1, 5, 8, 0\0" VALUE "InternalName", "Emu48\0" - VALUE "LegalCopyright", "Copyright © 2015\0" + VALUE "LegalCopyright", "Copyright © 2016\0" VALUE "OriginalFilename", "Emu48.exe\0" VALUE "ProductName", "Emu48\0" - VALUE "ProductVersion", "1, 5, 7, 0\0" + VALUE "ProductVersion", "1, 5, 8, 0\0" END END BLOCK "VarFileInfo" diff --git a/Sources/GCCPatch/Makefile b/Sources/GCCPatch/Makefile index 64db038..0b636fe 100644 --- a/Sources/GCCPatch/Makefile +++ b/Sources/GCCPatch/Makefile @@ -25,10 +25,11 @@ 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 sound.o stack.o symbfile.o timer.o udp.o \ + serial.o settings.o sndenum.o sound.o stack.o symbfile.o timer.o \ + udp.o \ $(RSRCOBJ) -LIBS=-lwinmm -lcomctl32 -lws2_32 +LIBS=-lwinmm -lcomctl32 -lws2_32 -luuid all: $(TARGET) @@ -127,10 +128,13 @@ serial.o: serial.c pch.h emu48.h types.h io.h settings.o: settings.c pch.h emu48.h types.h i28f160.h $(CC) $(CFLAGS) $(DEFINES) -c -o settings.o settings.c +sndenum.o: sndenum.c pch.h emu48.h snddef.h + $(CC) $(CFLAGS) $(DEFINES) -c -o sndenum.o sndenum.c + sound.o: sound.c pch.h emu48.h types.h $(CC) $(CFLAGS) $(DEFINES) -c -o sound.o sound.c -stack.o: stack.c pch.h resource.h emu48.h types.h io.h +stack.o: stack.c pch.h emu48.h types.h io.h $(CC) $(CFLAGS) $(DEFINES) -c -o stack.o stack.c symbfile.o: symbfile.c pch.h emu48.h types.h diff --git a/Sources/GCCPatch/README.TXT b/Sources/GCCPatch/README.TXT index 5a21663..8663411 100644 --- a/Sources/GCCPatch/README.TXT +++ b/Sources/GCCPatch/README.TXT @@ -48,4 +48,4 @@ Many thanks to Pedro A. Arranda Guti compatible. -03/13/15 (c) by Christoph Gießelink +06/28/16 (c) by Christoph Gießelink diff --git a/uninst.exe b/uninst.exe index 3e41d59..e9c5832 100755 Binary files a/uninst.exe and b/uninst.exe differ