2016-09-11: Updated to version 1.58

Signed-off-by: Gwenhael Le Moine <gwenhael.le.moine@gmail.com>
This commit is contained in:
Gwenhael Le Moine 2024-03-19 23:35:30 +01:00
parent 8c29c1313b
commit ed59d66683
No known key found for this signature in database
GPG key ID: FDFE3669426707A7
19 changed files with 615 additions and 172 deletions

View file

@ -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.
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) 19yy <name of author>
Copyright (C) <year> <name of author>
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.

BIN
Emu48.exe

Binary file not shown.

View file

@ -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

View file

@ -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

View file

@ -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);

View file

@ -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];

View file

@ -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,

View file

@ -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;

View file

@ -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

View file

@ -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;

View file

@ -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"

View file

@ -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;
}

102
Sources/Emu48/SNDDEF.H Normal file
View file

@ -0,0 +1,102 @@
/*
* snddef.h
*
* This file is part of Emu48
*
* Copyright (C) 2015 Christoph Gießelink
*
*/
#include <initguid.h>
#if _MSC_VER >= 1600 // valid for VS2010 and later
#include <DSound.h>
#include <Dsconf.h>
#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

256
Sources/Emu48/SNDENUM.C Normal file
View file

@ -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;
}

View file

@ -7,7 +7,6 @@
*
*/
#include "pch.h"
#include "resource.h"
#include "Emu48.h"
#include "io.h"

View file

@ -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"

View file

@ -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

View file

@ -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

Binary file not shown.