Version 1.12
Added Numpad Keys, Fixed ResourcePack code on Linux Updated Sound PGEX to be compilable, but not functional on linux
This commit is contained in:
parent
742e5d1c3a
commit
f8bda426d4
192
olcPGEX_Sound.h
192
olcPGEX_Sound.h
@ -69,6 +69,16 @@
|
||||
#undef min
|
||||
#undef max
|
||||
|
||||
typedef struct {
|
||||
unsigned short wFormatTag;
|
||||
unsigned short nChannels;
|
||||
unsigned long nSamplesPerSec;
|
||||
unsigned long nAvgBytesPerSec;
|
||||
unsigned short nBlockAlign;
|
||||
unsigned short wBitsPerSample;
|
||||
unsigned short cbSize;
|
||||
} OLC_WAVEFORMATEX;
|
||||
|
||||
namespace olc
|
||||
{
|
||||
// Container class for Advanced 2D Drawing functions
|
||||
@ -84,7 +94,7 @@ namespace olc
|
||||
olc::rcode LoadFromFile(std::string sWavFile, olc::ResourcePack *pack = nullptr);
|
||||
|
||||
public:
|
||||
WAVEFORMATEX wavHeader;
|
||||
OLC_WAVEFORMATEX wavHeader;
|
||||
float *fSample = nullptr;
|
||||
long nSamples = 0;
|
||||
int nChannels = 0;
|
||||
@ -115,10 +125,10 @@ namespace olc
|
||||
static void StopAll();
|
||||
static float GetMixerOutput(int nChannel, float fGlobalTime, float fTimeStep);
|
||||
|
||||
#ifdef WIN32
|
||||
|
||||
private:
|
||||
static void CALLBACK waveOutProc(HWAVEOUT hWaveOut, UINT uMsg, DWORD dwParam1, DWORD dwParam2);
|
||||
static void AudioThread();
|
||||
#ifdef WIN32 // Windows specific sound management
|
||||
static void CALLBACK waveOutProc(HWAVEOUT hWaveOut, UINT uMsg, DWORD dwParam1, DWORD dwParam2);
|
||||
static unsigned int m_nSampleRate;
|
||||
static unsigned int m_nChannels;
|
||||
static unsigned int m_nBlockCount;
|
||||
@ -126,16 +136,19 @@ namespace olc
|
||||
static unsigned int m_nBlockCurrent;
|
||||
static short* m_pBlockMemory;
|
||||
static WAVEHDR *m_pWaveHeaders;
|
||||
static HWAVEOUT m_hwDevice;
|
||||
static std::thread m_AudioThread;
|
||||
static std::atomic<bool> m_bAudioThreadActive;
|
||||
static HWAVEOUT m_hwDevice;
|
||||
static std::atomic<unsigned int> m_nBlockFree;
|
||||
static std::condition_variable m_cvBlockNotZero;
|
||||
static std::mutex m_muxBlockNotZero;
|
||||
#endif
|
||||
|
||||
static void AudioThread();
|
||||
static std::thread m_AudioThread;
|
||||
static std::atomic<bool> m_bAudioThreadActive;
|
||||
static std::atomic<float> m_fGlobalTime;
|
||||
static std::function<float(int, float, float)> funcUserSynth;
|
||||
static std::function<float(int, float, float)> funcUserFilter;
|
||||
#endif
|
||||
|
||||
|
||||
};
|
||||
}
|
||||
@ -143,14 +156,11 @@ namespace olc
|
||||
|
||||
#ifdef WIN32
|
||||
#pragma comment(lib, "winmm.lib")
|
||||
|
||||
namespace olc
|
||||
{
|
||||
SOUND::AudioSample::AudioSample()
|
||||
{
|
||||
|
||||
|
||||
|
||||
}
|
||||
{ }
|
||||
|
||||
SOUND::AudioSample::AudioSample(std::string sWavFile, olc::ResourcePack *pack)
|
||||
{
|
||||
@ -506,8 +516,162 @@ namespace olc
|
||||
std::function<float(int, float, float)> SOUND::funcUserSynth = nullptr;
|
||||
std::function<float(int, float, float)> SOUND::funcUserFilter = nullptr;
|
||||
}
|
||||
|
||||
#else // Non Windows
|
||||
namespace olc
|
||||
{
|
||||
SOUND::AudioSample::AudioSample()
|
||||
{}
|
||||
|
||||
SOUND::AudioSample::AudioSample(std::string sWavFile, olc::ResourcePack *pack)
|
||||
{
|
||||
LoadFromFile(sWavFile, pack);
|
||||
}
|
||||
|
||||
olc::rcode SOUND::AudioSample::LoadFromFile(std::string sWavFile, olc::ResourcePack *pack)
|
||||
{
|
||||
return olc::OK;
|
||||
}
|
||||
|
||||
bool SOUND::InitialiseAudio(unsigned int nSampleRate, unsigned int nChannels, unsigned int nBlocks, unsigned int nBlockSamples)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
// Stop and clean up audio system
|
||||
bool SOUND::DestroyAudio()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
// Audio thread. This loop responds to requests from the soundcard to fill 'blocks'
|
||||
// with audio data. If no requests are available it goes dormant until the sound
|
||||
// card is ready for more data. The block is fille by the "user" in some manner
|
||||
// and then issued to the soundcard.
|
||||
void SOUND::AudioThread()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
// This vector holds all loaded sound samples in memory
|
||||
std::vector<olc::SOUND::AudioSample> vecAudioSamples;
|
||||
|
||||
// This structure represents a sound that is currently playing. It only
|
||||
// holds the sound ID and where this instance of it is up to for its
|
||||
// current playback
|
||||
|
||||
void SOUND::SetUserSynthFunction(std::function<float(int, float, float)> func)
|
||||
{
|
||||
funcUserSynth = func;
|
||||
}
|
||||
|
||||
void SOUND::SetUserFilterFunction(std::function<float(int, float, float)> func)
|
||||
{
|
||||
funcUserFilter = func;
|
||||
}
|
||||
|
||||
// Load a 16-bit WAVE file @ 44100Hz ONLY into memory. A sample ID
|
||||
// number is returned if successful, otherwise -1
|
||||
unsigned int SOUND::LoadAudioSample(std::string sWavFile, olc::ResourcePack *pack)
|
||||
{
|
||||
olc::SOUND::AudioSample a(sWavFile, pack);
|
||||
if (a.bSampleValid)
|
||||
{
|
||||
vecAudioSamples.push_back(a);
|
||||
return vecAudioSamples.size();
|
||||
}
|
||||
else
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Add sample 'id' to the mixers sounds to play list
|
||||
void SOUND::PlaySample(int id, bool bLoop)
|
||||
{
|
||||
olc::SOUND::sCurrentlyPlayingSample a;
|
||||
a.nAudioSampleID = id;
|
||||
a.nSamplePosition = 0;
|
||||
a.bFinished = false;
|
||||
a.bFlagForStop = false;
|
||||
a.bLoop = bLoop;
|
||||
SOUND::listActiveSamples.push_back(a);
|
||||
}
|
||||
|
||||
void SOUND::StopSample(int id)
|
||||
{
|
||||
// Find first occurence of sample id
|
||||
auto s = std::find_if(listActiveSamples.begin(), listActiveSamples.end(), [&](const olc::SOUND::sCurrentlyPlayingSample &s) { return s.nAudioSampleID == id; });
|
||||
if (s != listActiveSamples.end())
|
||||
s->bFlagForStop = true;
|
||||
}
|
||||
|
||||
void SOUND::StopAll()
|
||||
{
|
||||
for (auto &s : listActiveSamples)
|
||||
{
|
||||
s.bFlagForStop = true;
|
||||
}
|
||||
}
|
||||
|
||||
float SOUND::GetMixerOutput(int nChannel, float fGlobalTime, float fTimeStep)
|
||||
{
|
||||
// Accumulate sample for this channel
|
||||
float fMixerSample = 0.0f;
|
||||
|
||||
for (auto &s : listActiveSamples)
|
||||
{
|
||||
if (m_bAudioThreadActive)
|
||||
{
|
||||
if (s.bFlagForStop)
|
||||
{
|
||||
s.bLoop = false;
|
||||
s.bFinished = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Calculate sample position
|
||||
s.nSamplePosition += (long)((float)vecAudioSamples[s.nAudioSampleID - 1].wavHeader.nSamplesPerSec * fTimeStep);
|
||||
|
||||
// If sample position is valid add to the mix
|
||||
if (s.nSamplePosition < vecAudioSamples[s.nAudioSampleID - 1].nSamples)
|
||||
fMixerSample += vecAudioSamples[s.nAudioSampleID - 1].fSample[(s.nSamplePosition * vecAudioSamples[s.nAudioSampleID - 1].nChannels) + nChannel];
|
||||
else
|
||||
{
|
||||
if (s.bLoop)
|
||||
{
|
||||
s.nSamplePosition = 0;
|
||||
}
|
||||
else
|
||||
s.bFinished = true; // Else sound has completed
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
return 0.0f;
|
||||
}
|
||||
|
||||
// If sounds have completed then remove them
|
||||
listActiveSamples.remove_if([](const sCurrentlyPlayingSample &s) {return s.bFinished; });
|
||||
|
||||
// The users application might be generating sound, so grab that if it exists
|
||||
if (funcUserSynth != nullptr)
|
||||
fMixerSample += funcUserSynth(nChannel, fGlobalTime, fTimeStep);
|
||||
|
||||
// Return the sample via an optional user override to filter the sound
|
||||
if (funcUserFilter != nullptr)
|
||||
return funcUserFilter(nChannel, fGlobalTime, fMixerSample);
|
||||
else
|
||||
return fMixerSample;
|
||||
}
|
||||
|
||||
std::thread SOUND::m_AudioThread;
|
||||
std::atomic<bool> SOUND::m_bAudioThreadActive{ false };
|
||||
std::atomic<float> SOUND::m_fGlobalTime{ 0.0f };
|
||||
std::list<SOUND::sCurrentlyPlayingSample> SOUND::listActiveSamples;
|
||||
std::function<float(int, float, float)> SOUND::funcUserSynth = nullptr;
|
||||
std::function<float(int, float, float)> SOUND::funcUserFilter = nullptr;
|
||||
}
|
||||
#endif
|
||||
|
||||
// Currently no Linux implementation so just go blank :(
|
||||
|
||||
#endif
|
@ -2,11 +2,9 @@
|
||||
olcPixelGameEngine.h
|
||||
|
||||
+-------------------------------------------------------------+
|
||||
| OneLoneCoder Pixel Game Engine v1.11 |
|
||||
| OneLoneCoder Pixel Game Engine v1.12 |
|
||||
| "Like the command prompt console one, but not..." - javidx9 |
|
||||
+-------------------------------------------------------------+
|
||||
|
||||
The Original & Best... :P
|
||||
|
||||
What is this?
|
||||
~~~~~~~~~~~~~
|
||||
@ -90,6 +88,7 @@
|
||||
Twitch: https://www.twitch.tv/javidx9
|
||||
GitHub: https://www.github.com/onelonecoder
|
||||
Homepage: https://www.onelonecoder.com
|
||||
Patreon: https://www.patreon.com/javidx9
|
||||
|
||||
Relevant Videos
|
||||
~~~~~~~~~~~~~~~
|
||||
@ -121,17 +120,20 @@
|
||||
~~~~~~
|
||||
I'd like to extend thanks to Eremiell, slavka, gurkanctn, Phantim,
|
||||
JackOJC, KrossX, Huhlig, Dragoneye, Appa, JustinRichardsMusic, SliceNDice
|
||||
& MagetzUb for advice, ideas and testing, and I'd like to extend
|
||||
my appreciation to the 14K YouTube followers and 1K Discord server
|
||||
Ralakus, Gorbit99, raoul & MagetzUb for advice, ideas and testing, and I'd like
|
||||
to extend my appreciation to the 23K YouTube followers and 1.5K Discord server
|
||||
members who give me the motivation to keep going with all this :D
|
||||
|
||||
Special thanks to those who bring gifts!
|
||||
GnarGnarHead.......Domina
|
||||
Gorbit99...........Bastion
|
||||
|
||||
Special thanks to my Patreons too - I wont name you on here, but I've
|
||||
certainly enjoyed my tea and flapjacks :D
|
||||
|
||||
Author
|
||||
~~~~~~
|
||||
David Barr, aka javidx9, ©OneLoneCoder 2018
|
||||
David Barr, aka javidx9, ©OneLoneCoder 2018, 2019
|
||||
*/
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
@ -279,7 +281,8 @@ namespace olc // All OneLoneCoder stuff will now exist in the "olc" namespace
|
||||
ResourcePack();
|
||||
~ResourcePack();
|
||||
struct sEntry : public std::streambuf {
|
||||
uint32_t nID, nFileOffset, nFileSize; uint8_t* data; void _config() { this->setg((char*)data, (char*)data, (char*)(data + nFileSize)); }};
|
||||
uint32_t nID, nFileOffset, nFileSize; uint8_t* data; void _config() { this->setg((char*)data, (char*)data, (char*)(data + nFileSize)); }
|
||||
};
|
||||
|
||||
public:
|
||||
olc::rcode AddToPack(std::string sFile);
|
||||
@ -346,7 +349,9 @@ namespace olc // All OneLoneCoder stuff will now exist in the "olc" namespace
|
||||
F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, F11, F12,
|
||||
UP, DOWN, LEFT, RIGHT,
|
||||
SPACE, TAB, SHIFT, CTRL, INS, DEL, HOME, END, PGUP, PGDN,
|
||||
BACK, ESCAPE, ENTER, PAUSE, SCROLL,
|
||||
BACK, ESCAPE, RETURN, ENTER, PAUSE, SCROLL,
|
||||
NP0, NP1, NP2, NP3, NP4, NP5, NP6, NP7, NP8, NP9,
|
||||
NP_MUL, NP_DIV, NP_ADD, NP_SUB, NP_DECIMAL,
|
||||
};
|
||||
|
||||
|
||||
@ -402,6 +407,7 @@ namespace olc // All OneLoneCoder stuff will now exist in the "olc" namespace
|
||||
// olc::Pixel::MASK = Transparent if alpha is < 255
|
||||
// olc::Pixel::ALPHA = Full transparency
|
||||
void SetPixelMode(Pixel::Mode m);
|
||||
Pixel::Mode GetPixelMode();
|
||||
// Use a custom blend function
|
||||
void SetPixelMode(std::function<olc::Pixel(const int x, const int y, const olc::Pixel& pSource, const olc::Pixel& pDest)> pixelMode);
|
||||
// Change the blend factor form between 0.0f to 1.0f;
|
||||
@ -647,7 +653,8 @@ namespace olc
|
||||
}
|
||||
else
|
||||
{
|
||||
std::istream is(&(pack->GetStreamBuffer(sImageFile)));
|
||||
auto streamBuffer = pack->GetStreamBuffer(sImageFile);
|
||||
std::istream is(&streamBuffer);
|
||||
ReadData(is);
|
||||
}
|
||||
|
||||
@ -852,10 +859,10 @@ namespace olc
|
||||
// Create entry
|
||||
sEntry e;
|
||||
e.data = nullptr;
|
||||
e.nFileSize = p;
|
||||
e.nFileSize = (uint32_t)p;
|
||||
|
||||
// Read file into memory
|
||||
e.data = new uint8_t[e.nFileSize];
|
||||
e.data = new uint8_t[(uint32_t)e.nFileSize];
|
||||
ifs.read((char*)e.data, e.nFileSize);
|
||||
ifs.close();
|
||||
|
||||
@ -886,7 +893,7 @@ namespace olc
|
||||
std::streampos offset = ofs.tellp();
|
||||
for (auto &e : mapFiles)
|
||||
{
|
||||
e.second.nFileOffset = offset;
|
||||
e.second.nFileOffset = (uint32_t)offset;
|
||||
ofs.write((char*)e.second.data, e.second.nFileSize);
|
||||
offset += e.second.nFileSize;
|
||||
}
|
||||
@ -936,12 +943,10 @@ namespace olc
|
||||
// 2) Read Data
|
||||
for (auto &e : mapFiles)
|
||||
{
|
||||
e.second.data = new uint8_t[e.second.nFileSize];
|
||||
e.second.data = new uint8_t[(uint32_t)e.second.nFileSize];
|
||||
ifs.seekg(e.second.nFileOffset);
|
||||
ifs.read((char*)e.second.data, e.second.nFileSize);
|
||||
//e.second.setg
|
||||
e.second._config();
|
||||
//e.second.pubsetbuf((char*)e.second.data, e.second.nFileSize);
|
||||
}
|
||||
|
||||
ifs.close();
|
||||
@ -1542,6 +1547,11 @@ namespace olc
|
||||
nPixelMode = m;
|
||||
}
|
||||
|
||||
Pixel::Mode PixelGameEngine::GetPixelMode()
|
||||
{
|
||||
return nPixelMode;
|
||||
}
|
||||
|
||||
void PixelGameEngine::SetPixelMode(std::function<olc::Pixel(const int x, const int y, const olc::Pixel&, const olc::Pixel&)> pixelMode)
|
||||
{
|
||||
funcPixelMode = pixelMode;
|
||||
@ -1884,6 +1894,7 @@ namespace olc
|
||||
mapKeys[VK_F9] = Key::F9; mapKeys[VK_F10] = Key::F10; mapKeys[VK_F11] = Key::F11; mapKeys[VK_F12] = Key::F12;
|
||||
|
||||
mapKeys[VK_DOWN] = Key::DOWN; mapKeys[VK_LEFT] = Key::LEFT; mapKeys[VK_RIGHT] = Key::RIGHT; mapKeys[VK_UP] = Key::UP;
|
||||
mapKeys[VK_RETURN] = Key::ENTER; //mapKeys[VK_RETURN] = Key::RETURN;
|
||||
|
||||
mapKeys[VK_BACK] = Key::BACK; mapKeys[VK_ESCAPE] = Key::ESCAPE; mapKeys[VK_RETURN] = Key::ENTER; mapKeys[VK_PAUSE] = Key::PAUSE;
|
||||
mapKeys[VK_SCROLL] = Key::SCROLL; mapKeys[VK_TAB] = Key::TAB; mapKeys[VK_DELETE] = Key::DEL; mapKeys[VK_HOME] = Key::HOME;
|
||||
@ -1894,6 +1905,10 @@ namespace olc
|
||||
mapKeys[0x30] = Key::K0; mapKeys[0x31] = Key::K1; mapKeys[0x32] = Key::K2; mapKeys[0x33] = Key::K3; mapKeys[0x34] = Key::K4;
|
||||
mapKeys[0x35] = Key::K5; mapKeys[0x36] = Key::K6; mapKeys[0x37] = Key::K7; mapKeys[0x38] = Key::K8; mapKeys[0x39] = Key::K9;
|
||||
|
||||
mapKeys[VK_NUMPAD0] = Key::NP0; mapKeys[VK_NUMPAD1] = Key::NP1; mapKeys[VK_NUMPAD2] = Key::NP2; mapKeys[VK_NUMPAD3] = Key::NP3; mapKeys[VK_NUMPAD4] = Key::NP4;
|
||||
mapKeys[VK_NUMPAD5] = Key::NP5; mapKeys[VK_NUMPAD6] = Key::NP6; mapKeys[VK_NUMPAD7] = Key::NP7; mapKeys[VK_NUMPAD8] = Key::NP8; mapKeys[VK_NUMPAD9] = Key::NP9;
|
||||
mapKeys[VK_MULTIPLY] = Key::NP_MUL; mapKeys[VK_ADD] = Key::NP_ADD; mapKeys[VK_DIVIDE] = Key::NP_DIV; mapKeys[VK_SUBTRACT] = Key::NP_SUB; mapKeys[VK_DECIMAL] = Key::NP_DECIMAL;
|
||||
|
||||
return olc_hWnd;
|
||||
}
|
||||
|
||||
@ -1995,6 +2010,7 @@ namespace olc
|
||||
mapKeys[XK_F9] = Key::F9; mapKeys[XK_F10] = Key::F10; mapKeys[XK_F11] = Key::F11; mapKeys[XK_F12] = Key::F12;
|
||||
|
||||
mapKeys[XK_Down] = Key::DOWN; mapKeys[XK_Left] = Key::LEFT; mapKeys[XK_Right] = Key::RIGHT; mapKeys[XK_Up] = Key::UP;
|
||||
mapKeys[XK_KP_Enter] = Key::ENTER; mapKeys[XK_Return] = Key::ENTER;
|
||||
|
||||
mapKeys[XK_BackSpace] = Key::BACK; mapKeys[XK_Escape] = Key::ESCAPE; mapKeys[XK_Linefeed] = Key::ENTER; mapKeys[XK_Pause] = Key::PAUSE;
|
||||
mapKeys[XK_Scroll_Lock] = Key::SCROLL; mapKeys[XK_Tab] = Key::TAB; mapKeys[XK_Delete] = Key::DEL; mapKeys[XK_Home] = Key::HOME;
|
||||
@ -2005,6 +2021,10 @@ namespace olc
|
||||
mapKeys[XK_0] = Key::K0; mapKeys[XK_1] = Key::K1; mapKeys[XK_2] = Key::K2; mapKeys[XK_3] = Key::K3; mapKeys[XK_4] = Key::K4;
|
||||
mapKeys[XK_5] = Key::K5; mapKeys[XK_6] = Key::K6; mapKeys[XK_7] = Key::K7; mapKeys[XK_8] = Key::K8; mapKeys[XK_9] = Key::K9;
|
||||
|
||||
mapKeys[XK_KP_0] = Key::NP0; mapKeys[XK_KP_1] = Key::NP1; mapKeys[XK_KP_2] = Key::NP2; mapKeys[XK_KP_3] = Key::NP3; mapKeys[XK_KP_4] = Key::NP4;
|
||||
mapKeys[XK_KP_5] = Key::NP5; mapKeys[XK_KP_6] = Key::NP6; mapKeys[XK_KP_7] = Key::NP7; mapKeys[XK_KP_8] = Key::NP8; mapKeys[XK_KP_9] = Key::NP9;
|
||||
mapKeys[XK_KP_Multiply] = Key::NP_MUL; mapKeys[XK_KP_Add] = Key::NP_ADD; mapKeys[XK_KP_Divide] = Key::NP_DIV; mapKeys[XK_KP_Subtract] = Key::NP_SUB; mapKeys[XK_KP_Decimal] = Key::NP_DECIMAL;
|
||||
|
||||
return olc_Display;
|
||||
}
|
||||
|
||||
@ -2044,4 +2064,4 @@ namespace olc
|
||||
//=============================================================
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif
|
Loading…
x
Reference in New Issue
Block a user