Add support for a (munte) mockingboard.

Signed-off-by: Andrea Odetti <mariofutire@gmail.com>
This commit is contained in:
Andrea Odetti 2020-06-30 15:43:06 +01:00
parent fd9b2184bf
commit 259428a946
21 changed files with 630 additions and 60 deletions

View file

@ -1,6 +1,9 @@
include(FindPkgConfig)
add_library(appleii SHARED
AY8910.cpp
Mockingboard.cpp
Pravets.cpp
Tape.cpp
YamlHelper.cpp
@ -25,6 +28,7 @@ add_library(appleii SHARED
CardManager.cpp
Disk2CardManager.cpp
SaveState.cpp # uses g_CardMgr in m_ConfigNew (reverse order)
Riff.cpp
linux/windows/memory.cpp
linux/windows/handles.cpp
@ -37,6 +41,7 @@ add_library(appleii SHARED
linux/windows/misc.cpp
linux/windows/winbase.cpp
linux/windows/winuser.cpp
linux/windows/dsound.cpp
linux/data.cpp
linux/benchmark.cpp
@ -47,7 +52,7 @@ add_library(appleii SHARED
linux/duplicates/Debug.cpp
linux/duplicates/Video.cpp
linux/duplicates/Mockingboard.cpp
linux/duplicates/SoundCore.cpp
linux/duplicates/Joystick.cpp
linux/duplicates/Frame.cpp
linux/duplicates/SerialComms.cpp

View file

@ -1,3 +1,5 @@
#include "StdAfx.h"
#include "qapple.h"
#include <QApplication>
#include <QTimer>

View file

@ -96,25 +96,6 @@ namespace
REGSAVE(slotText.c_str(), (DWORD)newCardType);
}
const std::vector<eApple2Type> computerTypes = {A2TYPE_APPLE2, A2TYPE_APPLE2PLUS, A2TYPE_APPLE2JPLUS, A2TYPE_APPLE2E,
A2TYPE_APPLE2EENHANCED, A2TYPE_PRAVETS82, A2TYPE_PRAVETS8M, A2TYPE_PRAVETS8A,
A2TYPE_TK30002E};
int getApple2ComputerType()
{
const eApple2Type type = GetApple2Type();
const auto it = std::find(computerTypes.begin(), computerTypes.end(), type);
if (it != computerTypes.end())
{
return std::distance(computerTypes.begin(), it);
}
else
{
// default to A2E
return 2;
}
}
}
GlobalOptions::GlobalOptions()
@ -222,11 +203,11 @@ void getAppleWinPreferences(PreferenceData & data)
}
data.enhancedSpeed = pDisk2Card->GetEnhanceDisk();
data.mouseInSlot4 = g_CardMgr.QuerySlot(SLOT4) == CT_MouseInterface;
data.cpmInSlot5 = g_CardMgr.QuerySlot(SLOT5) == CT_Z80;
data.cardInSlot4 = g_CardMgr.QuerySlot(SLOT4);
data.cardInSlot5 = g_CardMgr.QuerySlot(SLOT5);
data.hdInSlot7 = HD_CardIsEnabled();
data.apple2Type = getApple2ComputerType();
data.apple2Type = GetApple2Type();
const std::string & saveState = Snapshot_GetFilename();
if (!saveState.empty())
@ -247,22 +228,19 @@ void setAppleWinPreferences(const PreferenceData & currentData, const Preference
if (currentData.apple2Type != newData.apple2Type)
{
const eApple2Type type = computerTypes[newData.apple2Type];
SetApple2Type(type);
REGSAVE(TEXT(REGVALUE_APPLE2_TYPE), type);
const eCpuType cpu = ProbeMainCpuDefault(type);
SetApple2Type(newData.apple2Type);
REGSAVE(TEXT(REGVALUE_APPLE2_TYPE), newData.apple2Type);
const eCpuType cpu = ProbeMainCpuDefault(newData.apple2Type);
SetMainCpu(cpu);
REGSAVE(TEXT(REGVALUE_CPU_TYPE), cpu);
}
if (currentData.mouseInSlot4 != newData.mouseInSlot4)
if (currentData.cardInSlot4 != newData.cardInSlot4)
{
const SS_CARDTYPE card = newData.mouseInSlot4 ? CT_MouseInterface : CT_Empty;
SetSlot(SLOT4, card);
SetSlot(SLOT4, newData.cardInSlot4);
}
if (currentData.cpmInSlot5 != newData.cpmInSlot5)
if (currentData.cardInSlot5 != newData.cardInSlot5)
{
const SS_CARDTYPE card = newData.cpmInSlot5 ? CT_Z80 : CT_Empty;
SetSlot(SLOT5, card);
SetSlot(SLOT5, newData.cardInSlot5);
}
if (currentData.hdInSlot7 != newData.hdInSlot7)
{

View file

@ -1,6 +1,9 @@
#ifndef CONFIGURATION_H
#define CONFIGURATION_H
#include "StdAfx.h"
#include "Card.h"
#include "Common.h"
#include "preferences.h"
class GlobalOptions
@ -29,9 +32,9 @@ struct PreferenceData
{
GlobalOptions options;
int apple2Type;
bool mouseInSlot4;
bool cpmInSlot5;
eApple2Type apple2Type;
SS_CARDTYPE cardInSlot4;
SS_CARDTYPE cardInSlot5;
bool hdInSlot7;
bool hz50;

View file

@ -118,6 +118,26 @@ namespace
item->addChildren(items);
}
const std::vector<eApple2Type> computerTypes = {A2TYPE_APPLE2, A2TYPE_APPLE2PLUS, A2TYPE_APPLE2JPLUS, A2TYPE_APPLE2E,
A2TYPE_APPLE2EENHANCED, A2TYPE_PRAVETS82, A2TYPE_PRAVETS8M, A2TYPE_PRAVETS8A,
A2TYPE_TK30002E};
const std::vector<SS_CARDTYPE> cardsInSlot4 = {CT_Empty, CT_MouseInterface, CT_MockingboardC, CT_Phasor};
const std::vector<SS_CARDTYPE> cardsInSlot5 = {CT_Empty, CT_Z80, CT_MockingboardC, CT_SAM};
template<class T>
int getIndexInList(const std::vector<T> & values, const T value, const int defaultValue)
{
const auto it = std::find(values.begin(), values.end(), value);
if (it != values.end())
{
return std::distance(values.begin(), it);
}
else
{
return defaultValue;
}
}
}
Preferences::Preferences(QWidget *parent) :
@ -193,9 +213,16 @@ void Preferences::setData(const PreferenceData & data)
initialiseDisks(myHDs, data.hds);
ui->enhanced_speed->setChecked(data.enhancedSpeed);
ui->apple2Type->setCurrentIndex(data.apple2Type);
ui->mouse_4->setChecked(data.mouseInSlot4);
ui->cpm_5->setChecked(data.cpmInSlot5);
const int apple2Index = getIndexInList(computerTypes, data.apple2Type, 2);
ui->apple2Type->setCurrentIndex(apple2Index);
const int slot4Index = getIndexInList(cardsInSlot4, data.cardInSlot4, 0);
ui->slot4_combo->setCurrentIndex(slot4Index);
const int slot5Index = getIndexInList(cardsInSlot4, data.cardInSlot5, 0);
ui->slot5_combo->setCurrentIndex(slot5Index);
ui->hd_7->setChecked(data.hdInSlot7);
// synchronise
@ -234,9 +261,9 @@ PreferenceData Preferences::getData() const
fillData(myHDs, data.hds);
data.enhancedSpeed = ui->enhanced_speed->isChecked();
data.apple2Type = ui->apple2Type->currentIndex();
data.mouseInSlot4 = ui->mouse_4->isChecked();
data.cpmInSlot5 = ui->cpm_5->isChecked();
data.apple2Type = computerTypes[ui->apple2Type->currentIndex()];
data.cardInSlot4 = cardsInSlot4[ui->slot4_combo->currentIndex()];
data.cardInSlot5 = cardsInSlot5[ui->slot5_combo->currentIndex()];
data.hdInSlot7 = ui->hd_7->isChecked();
data.saveState = ui->save_state->text();
@ -339,3 +366,39 @@ void Preferences::on_colorButton_clicked()
myMonochromeColor = dialog.currentColor();
}
}
void Preferences::on_slot4_combo_activated(int index)
{
const SS_CARDTYPE slot4Card = cardsInSlot4[index];
if (slot4Card == CT_MockingboardC)
{
const int slot5Index = getIndexInList(cardsInSlot5, CT_MockingboardC, 0);
ui->slot5_combo->setCurrentIndex(slot5Index);
}
else
{
const SS_CARDTYPE slot5Card = cardsInSlot5[ui->slot5_combo->currentIndex()];
if (slot5Card == CT_MockingboardC)
{
ui->slot5_combo->setCurrentIndex(0);
}
}
}
void Preferences::on_slot5_combo_activated(int index)
{
const SS_CARDTYPE slot5Card = cardsInSlot5[index];
if (slot5Card == CT_MockingboardC)
{
const int slot4Index = getIndexInList(cardsInSlot4, CT_MockingboardC, 0);
ui->slot4_combo->setCurrentIndex(slot4Index);
}
else
{
const SS_CARDTYPE slot4Card = cardsInSlot4[ui->slot4_combo->currentIndex()];
if (slot4Card == CT_MockingboardC)
{
ui->slot4_combo->setCurrentIndex(0);
}
}
}

View file

@ -42,6 +42,10 @@ private slots:
void on_colorButton_clicked();
void on_slot4_combo_activated(int index);
void on_slot5_combo_activated(int index);
private:
std::vector<QComboBox *> myDisks;
std::vector<QComboBox *> myHDs;

View file

@ -47,13 +47,6 @@
</property>
</widget>
</item>
<item row="4" column="1">
<widget class="QCheckBox" name="mouse_4">
<property name="text">
<string>Mouse</string>
</property>
</widget>
</item>
<item row="5" column="0">
<widget class="QLabel" name="label_9">
<property name="text">
@ -61,13 +54,6 @@
</property>
</widget>
</item>
<item row="5" column="1">
<widget class="QCheckBox" name="cpm_5">
<property name="text">
<string>CP/M</string>
</property>
</widget>
</item>
<item row="6" column="0">
<widget class="QLabel" name="label_10">
<property name="text">
@ -132,6 +118,54 @@
</property>
</widget>
</item>
<item row="4" column="1">
<widget class="QComboBox" name="slot4_combo">
<item>
<property name="text">
<string>Empty</string>
</property>
</item>
<item>
<property name="text">
<string>Mouse</string>
</property>
</item>
<item>
<property name="text">
<string>Mockingboard</string>
</property>
</item>
<item>
<property name="text">
<string>Phasor</string>
</property>
</item>
</widget>
</item>
<item row="5" column="1">
<widget class="QComboBox" name="slot5_combo">
<item>
<property name="text">
<string>Empty</string>
</property>
</item>
<item>
<property name="text">
<string>CP/M</string>
</property>
</item>
<item>
<property name="text">
<string>Mockingboard</string>
</property>
</item>
<item>
<property name="text">
<string>SAM/DAC</string>
</property>
</item>
</widget>
</item>
</layout>
</widget>
</item>

View file

@ -12,11 +12,14 @@
#include "Frame.h"
#include "Memory.h"
#include "LanguageCard.h"
#include "Mockingboard.h"
#include "MouseInterface.h"
#include "ParallelPrinter.h"
#include "Video.h"
#include "SoundCore.h"
#include "NTSC.h"
#include "SaveState.h"
#include "Riff.h"
#include "linux/data.h"
#include "linux/benchmark.h"
@ -44,6 +47,10 @@ namespace
void initialiseEmulator()
{
#ifdef RIFF_MB
RiffInitWriteFile("/tmp/Mockingboard.wav", 44100, 2);
#endif
g_fh = fopen("/tmp/applewin.txt", "w");
setbuf(g_fh, nullptr);
@ -94,6 +101,8 @@ namespace
break;
}
DSInit();
MB_Initialize();
MemInitialize();
VideoInitialize();
@ -111,6 +120,8 @@ namespace
pMouseCard->Reset();
}
MemDestroy();
MB_Destroy();
DSUninit();
}
void uninitialiseEmulator()
@ -121,8 +132,8 @@ namespace
g_CardMgr.GetDisk2CardMgr().Destroy();
ImageDestroy();
fclose(g_fh);
g_fh = nullptr;
LogDone();
RiffFinishWriteFile();
}
qint64 emulatorTimeInMS()
@ -315,6 +326,8 @@ void QApple::on_timer()
const DWORD uActualCyclesExecuted = CpuExecute(uCyclesToExecute, bVideoUpdate);
g_dwCyclesThisFrame += uActualCyclesExecuted;
g_CardMgr.GetDisk2CardMgr().UpdateDriveState(uActualCyclesExecuted);
MB_PeriodicUpdate(uActualCyclesExecuted);
// in case we run more than 1 frame
g_dwCyclesThisFrame = g_dwCyclesThisFrame % dwClksPerFrame;
++count;

View file

@ -61,6 +61,9 @@ static IPropertySheet * sg = NULL;
IPropertySheet& sg_PropertySheet = *sg;
static double g_fMHz = 1.0; // Affected by Config dialog's speed slider bar
bool g_bDisableDirectSound = false;
bool g_bDisableDirectSoundMockingboard = false;
void LogFileTimeUntilFirstKeyReadReset(void)
{
if (!g_fh)
@ -371,3 +374,8 @@ void LoadConfiguration(void)
g_bConfirmReboot = dwTmp;
#endif
}
double Get6502BaseClock(void)
{
return (GetVideoRefreshRate() == VR_50HZ) ? CLK_6502_PAL : CLK_6502_NTSC;
}

View file

@ -0,0 +1,148 @@
#include "StdAfx.h"
#include "Common.h"
#include "SoundCore.h"
#include "Log.h"
bool g_bDSAvailable = false;
static int g_nErrorInc = 20; // Old: 1
bool DSZeroVoiceWritableBuffer(PVOICE Voice, const char* pszDevName, DWORD dwBufferSize)
{
return true;
}
void DSReleaseSoundBuffer(VOICE* pVoice)
{
delete pVoice->lpDSBvoice;
pVoice->lpDSBvoice = nullptr;
}
int SoundCore_GetErrorInc()
{
return g_nErrorInc;
}
LONG NewVolume(DWORD dwVolume, DWORD dwVolumeMax)
{
float fVol = (float) dwVolume / (float) dwVolumeMax; // 0.0=Max, 1.0=Min
return (LONG) ((float) DSBVOLUME_MIN * fVol);
}
HRESULT DSGetSoundBuffer(VOICE* pVoice, DWORD dwFlags, DWORD dwBufferSize, DWORD nSampleRate, int nChannels)
{
IDirectSoundBuffer * dsVoice = new IDirectSoundBuffer;
dsVoice->flags = dwFlags;
dsVoice->bufferSize = dwBufferSize;
dsVoice->sampleRate = nSampleRate;
dsVoice->channels = nChannels;
dsVoice->soundBuffer.resize(dwBufferSize);
pVoice->lpDSBvoice = dsVoice;
return S_OK;
}
bool DSInit()
{
g_bDSAvailable = true;
return true;
}
//-----------------------------------------------------------------------------
void DSUninit()
{
g_bDSAvailable = false;
}
bool DSZeroVoiceBuffer(PVOICE Voice, const char* pszDevName, DWORD dwBufferSize)
{
#ifdef NO_DIRECT_X
return false;
#else
DWORD dwDSLockedBufferSize = 0; // Size of the locked DirectSound buffer
SHORT* pDSLockedBuffer;
_ASSERT(Voice->lpDSBvoice);
HRESULT hr = Voice->lpDSBvoice->Stop();
if(FAILED(hr))
{
if(g_fh) fprintf(g_fh, "%s: DSStop failed (%08X)\n",pszDevName,hr);
return false;
}
hr = DSGetLock(Voice->lpDSBvoice, 0, 0, &pDSLockedBuffer, &dwDSLockedBufferSize, NULL, 0);
if(FAILED(hr))
{
if(g_fh) fprintf(g_fh, "%s: DSGetLock failed (%08X)\n",pszDevName,hr);
return false;
}
_ASSERT(dwDSLockedBufferSize == dwBufferSize);
memset(pDSLockedBuffer, 0x00, dwDSLockedBufferSize);
hr = Voice->lpDSBvoice->Unlock((void*)pDSLockedBuffer, dwDSLockedBufferSize, NULL, 0);
if(FAILED(hr))
{
if(g_fh) fprintf(g_fh, "%s: DSUnlock failed (%08X)\n",pszDevName,hr);
return false;
}
hr = Voice->lpDSBvoice->Play(0,0,DSBPLAY_LOOPING);
if(FAILED(hr))
{
if(g_fh) fprintf(g_fh, "%s: DSPlay failed (%08X)\n",pszDevName,hr);
return false;
}
return true;
#endif // NO_DIRECT_X
}
bool DSGetLock(LPDIRECTSOUNDBUFFER pVoice, DWORD dwOffset, DWORD dwBytes,
SHORT** ppDSLockedBuffer0, DWORD* pdwDSLockedBufferSize0,
SHORT** ppDSLockedBuffer1, DWORD* pdwDSLockedBufferSize1)
{
DWORD nStatus;
HRESULT hr = pVoice->GetStatus(&nStatus);
if(hr != DS_OK)
return false;
if(nStatus & DSBSTATUS_BUFFERLOST)
{
do
{
hr = pVoice->Restore();
if(hr == DSERR_BUFFERLOST)
Sleep(10);
}
while(hr != DS_OK);
}
// Get write only pointer(s) to sound buffer
if(dwBytes == 0)
{
if(FAILED(hr = pVoice->Lock(0, 0,
(void**)ppDSLockedBuffer0, pdwDSLockedBufferSize0,
(void**)ppDSLockedBuffer1, pdwDSLockedBufferSize1,
DSBLOCK_ENTIREBUFFER)))
return false;
}
else
{
if(FAILED(hr = pVoice->Lock(dwOffset, dwBytes,
(void**)ppDSLockedBuffer0, pdwDSLockedBufferSize0,
(void**)ppDSLockedBuffer1, pdwDSLockedBufferSize1,
0)))
return false;
}
return true;
}

View file

@ -0,0 +1,12 @@
#include "StdAfx.h"
#include "YamlHelper.h"
#include "Common.h"
void SpkrLoadSnapshot(YamlLoadHelper&)
{
}
void SpkrSaveSnapshot(YamlSaveHelper&)
{
}

View file

@ -14,3 +14,5 @@
#include "linux/windows/gdi.h"
#include "linux/windows/winbase.h"
#include "linux/windows/winuser.h"
#include "linux/windows/dsound.h"
#include "linux/windows/winerror.h"

View file

@ -0,0 +1,112 @@
#include "linux/windows/dsound.h"
#include "linux/windows/winerror.h"
HRESULT IDirectSoundNotify::SetNotificationPositions(DWORD cPositionNotifies, LPCDSBPOSITIONNOTIFY lpcPositionNotifies)
{
return DS_OK;
}
IDirectSoundBuffer::IDirectSoundBuffer(): soundNotify(new IDirectSoundNotify)
{
}
HRESULT IDirectSoundBuffer::QueryInterface(int riid, void **ppvObject)
{
if (riid == IID_IDirectSoundNotify)
{
*ppvObject = soundNotify.get();
return S_OK;
}
return E_NOINTERFACE;
}
HRESULT IDirectSoundBuffer::Unlock( LPVOID lpvAudioPtr1, DWORD dwAudioBytes1, LPVOID lpvAudioPtr2, DWORD dwAudioBytes2 )
{
const size_t totalWrittenBytes = dwAudioBytes1 + dwAudioBytes2;
writePosition = (writePosition + totalWrittenBytes) % this->soundBuffer.size();
return DS_OK;
}
HRESULT IDirectSoundBuffer::Stop()
{
const DWORD mask = DSBSTATUS_PLAYING | DSBSTATUS_LOOPING;
this->status &= ~mask;
return DS_OK;
}
HRESULT IDirectSoundBuffer::SetCurrentPosition( DWORD dwNewPosition )
{
return DS_OK;
}
HRESULT IDirectSoundBuffer::Play( DWORD dwReserved1, DWORD dwReserved2, DWORD dwFlags )
{
this->status |= DSBSTATUS_PLAYING;
if (dwFlags & DSBPLAY_LOOPING)
{
this->status |= DSBSTATUS_LOOPING;
}
return S_OK;
}
HRESULT IDirectSoundBuffer::SetVolume( LONG lVolume )
{
this->volume = lVolume;
return DS_OK;
}
HRESULT IDirectSoundBuffer::GetStatus( LPDWORD lpdwStatus )
{
*lpdwStatus = this->status;
return DS_OK;
}
HRESULT IDirectSoundBuffer::Restore()
{
return DS_OK;
}
HRESULT IDirectSoundBuffer::Lock( DWORD dwWriteCursor, DWORD dwWriteBytes, LPVOID * lplpvAudioPtr1, DWORD * lpdwAudioBytes1, LPVOID * lplpvAudioPtr2, DWORD * lpdwAudioBytes2, DWORD dwFlags )
{
if (dwFlags & DSBLOCK_ENTIREBUFFER)
{
*lplpvAudioPtr1 = this->soundBuffer.data();
*lpdwAudioBytes1 = this->soundBuffer.size();
if (lplpvAudioPtr2 && lpdwAudioBytes2)
{
*lplpvAudioPtr2 = nullptr;
*lpdwAudioBytes2 = 0;
}
}
else
{
const DWORD availableInFirstPart = this->soundBuffer.size() - dwWriteCursor;
*lplpvAudioPtr1 = this->soundBuffer.data() + dwWriteCursor;
*lpdwAudioBytes1 = std::min(availableInFirstPart, dwWriteBytes);
if (lplpvAudioPtr2 && lpdwAudioBytes2)
{
if (*lpdwAudioBytes1 < dwWriteBytes)
{
*lplpvAudioPtr2 = this->soundBuffer.data();
*lpdwAudioBytes2 = std::min(dwWriteCursor, dwWriteBytes - *lpdwAudioBytes1);
}
else
{
*lplpvAudioPtr2 = nullptr;
*lpdwAudioBytes2 = 0;
}
}
}
return DS_OK;
}
HRESULT IDirectSoundBuffer::GetCurrentPosition( LPDWORD lpdwCurrentPlayCursor, LPDWORD lpdwCurrentWriteCursor )
{
*lpdwCurrentPlayCursor = this->writePosition;
*lpdwCurrentWriteCursor = this->writePosition;
return DS_OK;
}

View file

@ -0,0 +1,79 @@
#pragma once
#include "linux/windows/winbase.h"
#include "linux/windows/winerror.h"
#include <vector>
#include <memory>
#define IID_IDirectSoundNotify 1234
#define DS_OK 0
#define DSBPN_OFFSETSTOP -1
#define DSBCAPS_CTRLVOLUME 0x00000080
#define DSBCAPS_CTRLPOSITIONNOTIFY 0x00000100
#define DSBCAPS_LOCSOFTWARE 0x00000008
#define DSBVOLUME_MIN -10000
#define DSBVOLUME_MAX 0
#define DSBPLAY_LOOPING 0x00000001
#define DSBSTATUS_PLAYING 0x00000001
#define DSBSTATUS_BUFFERLOST 0x00000002
#define DSBSTATUS_LOOPING 0x00000004
#define DSERR_BUFFERLOST MAKE_DSHRESULT(150)
#define DSBLOCK_ENTIREBUFFER 0x00000002
#define _FACDS 0x878
#define MAKE_DSHRESULT(code) MAKE_HRESULT(1,_FACDS,code)
typedef struct _DSBPOSITIONNOTIFY
{
DWORD dwOffset;
HANDLE hEventNotify;
} DSBPOSITIONNOTIFY,*LPDSBPOSITIONNOTIFY;
typedef const DSBPOSITIONNOTIFY *LPCDSBPOSITIONNOTIFY;
struct IDirectSoundNotify
{
HRESULT SetNotificationPositions(DWORD cPositionNotifies, LPCDSBPOSITIONNOTIFY lpcPositionNotifies);
};
typedef struct IDirectSoundNotify *LPDIRECTSOUNDNOTIFY,**LPLPDIRECTSOUNDNOTIFY;
struct IDirectSoundBuffer
{
std::unique_ptr<IDirectSoundNotify> soundNotify;
std::vector<SHORT> soundBuffer;
size_t playPosition = 0;
size_t writePosition = 0;
LONG volume = DSBVOLUME_MIN;
DWORD flags = 0;
DWORD bufferSize = 0;
DWORD sampleRate = 0;
WORD status = 0;
int channels = 0;
IDirectSoundBuffer();
HRESULT QueryInterface(int riid, void **ppvObject);
HRESULT SetCurrentPosition( DWORD dwNewPosition );
HRESULT GetCurrentPosition( LPDWORD lpdwCurrentPlayCursor, LPDWORD lpdwCurrentWriteCursor );
HRESULT Lock( DWORD dwWriteCursor, DWORD dwWriteBytes, LPVOID * lplpvAudioPtr1, DWORD * lpdwAudioBytes1, LPVOID * lplpvAudioPtr2, DWORD * lpdwAudioBytes2, DWORD dwFlags );
HRESULT Unlock( LPVOID lpvAudioPtr1, DWORD dwAudioBytes1, LPVOID lpvAudioPtr2, DWORD dwAudioBytes2 );
HRESULT Stop();
HRESULT Play( DWORD dwReserved1, DWORD dwReserved2, DWORD dwFlags );
HRESULT SetVolume( LONG lVolume );
HRESULT GetStatus( LPDWORD lpdwStatus );
HRESULT Restore();
};
typedef struct IDirectSoundBuffer *LPDIRECTSOUNDBUFFER,**LPLPDIRECTSOUNDBUFFER;

View file

@ -85,7 +85,7 @@ HANDLE CreateFile(LPCTSTR lpFileName,
HANDLE hTemplateFile)
{
FILE * f = nullptr;
if (dwCreationDisposition == CREATE_NEW)
if (dwCreationDisposition == CREATE_NEW || dwCreationDisposition == CREATE_ALWAYS)
{
if (dwDesiredAccess & GENERIC_READ)
f = fopen(lpFileName, "w+");

View file

@ -32,6 +32,7 @@ typedef struct tagOFN {
#define OFN_FILEMUSTEXIST 0x00001000
#define OPEN_EXISTING 3
#define CREATE_NEW 1
#define CREATE_ALWAYS 2
#define GENERIC_READ 0x80000000
#define GENERIC_WRITE 0x40000000

View file

@ -22,6 +22,7 @@ void strcpy_s(char * dest, size_t size, const char * source);
#define _tcscpy strcpy
#define _snprintf snprintf
#define wsprintf sprintf
#define sscanf_s sscanf
inline bool IsCharLower(char ch) {
return isascii(ch) && islower(ch);

View file

@ -2,6 +2,8 @@
#include <errno.h>
#include <iostream>
#include <chrono>
#include <thread>
DWORD WINAPI GetLastError(void)
{
@ -26,10 +28,54 @@ void LeaveCriticalSection(CRITICAL_SECTION * criticalSection)
void OutputDebugString(const char * str)
{
std::cerr << str << std::endl;
std::cerr << str;
}
void ExitProcess(int status)
{
exit(status);
}
DWORD WINAPI WaitForMultipleObjects(DWORD,const HANDLE*,BOOL,DWORD)
{
return WAIT_FAILED;
}
BOOL WINAPI GetExitCodeThread(HANDLE,LPDWORD code)
{
*code = 0;
return TRUE;
}
BOOL WINAPI SetEvent(HANDLE)
{
return TRUE;
}
VOID WINAPI Sleep(DWORD ms)
{
std::this_thread::sleep_for (std::chrono::milliseconds(ms));
}
BOOL WINAPI SetThreadPriority(HANDLE,INT)
{
return TRUE;
}
HANDLE WINAPI CreateEvent(LPSECURITY_ATTRIBUTES,BOOL,BOOL,LPCSTR)
{
return INVALID_HANDLE_VALUE;
}
HANDLE WINAPI CreateThread(LPSECURITY_ATTRIBUTES,SIZE_T,LPTHREAD_START_ROUTINE,LPVOID,DWORD,LPDWORD)
{
return INVALID_HANDLE_VALUE;
}
BOOL WINAPI QueryPerformanceCounter(LARGE_INTEGER*counter)
{
const auto now = std::chrono::steady_clock::now();
const auto ms = std::chrono::duration_cast<std::chrono::milliseconds>(now.time_since_epoch());
counter->QuadPart = ms.count();
return TRUE;
}

View file

@ -3,9 +3,46 @@
#include "linux/windows/wincompat.h"
#include "linux/windows/handles.h"
#include <cstddef>
DWORD WINAPI GetLastError(void);
void DeleteCriticalSection(CRITICAL_SECTION * criticalSection);
void InitializeCriticalSection(CRITICAL_SECTION * criticalSection);
void EnterCriticalSection(CRITICAL_SECTION * criticalSection);
void LeaveCriticalSection(CRITICAL_SECTION * criticalSection);
void OutputDebugString(const char * str);
#define INFINITE 0xFFFFFFFF
#define WAIT_OBJECT_0 0
#define WAIT_FAILED 0xffffffff
#define STATUS_PENDING 0x00000103
#define STILL_ACTIVE STATUS_PENDING
#define THREAD_BASE_PRIORITY_LOWRT 15
#define THREAD_PRIORITY_TIME_CRITICAL THREAD_BASE_PRIORITY_LOWRT
typedef DWORD (CALLBACK *LPTHREAD_START_ROUTINE)(LPVOID);
typedef size_t SIZE_T;
BOOL WINAPI SetThreadPriority(HANDLE,INT);
DWORD WINAPI WaitForMultipleObjects(DWORD,const HANDLE*,BOOL,DWORD);
BOOL WINAPI GetExitCodeThread(HANDLE,LPDWORD);
BOOL WINAPI SetEvent(HANDLE);
VOID WINAPI Sleep(DWORD);
HANDLE WINAPI CreateEvent(LPSECURITY_ATTRIBUTES,BOOL,BOOL,LPCSTR);
HANDLE WINAPI CreateThread(LPSECURITY_ATTRIBUTES,SIZE_T,LPTHREAD_START_ROUTINE,LPVOID,DWORD,LPDWORD);
typedef union _LARGE_INTEGER {
struct {
DWORD LowPart;
LONG HighPart;
} DUMMYSTRUCTNAME;
struct {
DWORD LowPart;
LONG HighPart;
} u;
LONGLONG QuadPart;
} LARGE_INTEGER;
BOOL WINAPI QueryPerformanceCounter(LARGE_INTEGER*);

View file

@ -37,6 +37,8 @@ typedef signed short INT16; // why there was char instead of short? --bb ??????
typedef unsigned short UINT16; // why there was char instead of short? --bb ??????????????????? 0_0
#define __int64 long long
typedef long long LONGLONG;
typedef unsigned int UINT32;
typedef unsigned char UINT8;
typedef int INT32;

View file

@ -0,0 +1,20 @@
#pragma once
#include "linux/windows/wincompat.h"
#define FAILED(stat) ((HRESULT)(stat)<0)
#define E_NOINTERFACE HRESULT(0x80004002)
#define S_OK HRESULT(0)
#define SEVERITY_SUCCESS 0
#define SEVERITY_ERROR 1
#define MAKE_HRESULT(sev,fac,code) \
((HRESULT) (((unsigned int)(sev)<<31) | ((unsigned int)(fac)<<16) | ((unsigned int)(code))) )
#define MAKE_SCODE(sev,fac,code) \
((SCODE) (((unsigned int)(sev)<<31) | ((unsigned int)(fac)<<16) | ((unsigned int)(code))) )
#define SUCCEEDED(stat) ((HRESULT)(stat)>=0)
#define FAILED(stat) ((HRESULT)(stat)<0)
#define IS_ERROR(stat) (((unsigned int)(stat)>>31) == SEVERITY_ERROR)
#define HRESULT_CODE(hr) ((hr) & 0xFFFF)
#define SCODE_CODE(sc) ((sc) & 0xFFFF)