Version 1.12

Added Numpad Keys,
Fixed ResourcePack code on Linux
Updated Sound PGEX to be compilable, but not functional on linux
pull/113/head
Javidx9 6 years ago committed by GitHub
parent 742e5d1c3a
commit f8bda426d4
  1. 192
      olcPGEX_Sound.h
  2. 52
      olcPixelGameEngine.h

@ -69,6 +69,16 @@
#undef min #undef min
#undef max #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 namespace olc
{ {
// Container class for Advanced 2D Drawing functions // Container class for Advanced 2D Drawing functions
@ -84,7 +94,7 @@ namespace olc
olc::rcode LoadFromFile(std::string sWavFile, olc::ResourcePack *pack = nullptr); olc::rcode LoadFromFile(std::string sWavFile, olc::ResourcePack *pack = nullptr);
public: public:
WAVEFORMATEX wavHeader; OLC_WAVEFORMATEX wavHeader;
float *fSample = nullptr; float *fSample = nullptr;
long nSamples = 0; long nSamples = 0;
int nChannels = 0; int nChannels = 0;
@ -115,10 +125,10 @@ namespace olc
static void StopAll(); static void StopAll();
static float GetMixerOutput(int nChannel, float fGlobalTime, float fTimeStep); static float GetMixerOutput(int nChannel, float fGlobalTime, float fTimeStep);
#ifdef WIN32
private: private:
static void CALLBACK waveOutProc(HWAVEOUT hWaveOut, UINT uMsg, DWORD dwParam1, DWORD dwParam2); #ifdef WIN32 // Windows specific sound management
static void AudioThread(); static void CALLBACK waveOutProc(HWAVEOUT hWaveOut, UINT uMsg, DWORD dwParam1, DWORD dwParam2);
static unsigned int m_nSampleRate; static unsigned int m_nSampleRate;
static unsigned int m_nChannels; static unsigned int m_nChannels;
static unsigned int m_nBlockCount; static unsigned int m_nBlockCount;
@ -126,16 +136,19 @@ namespace olc
static unsigned int m_nBlockCurrent; static unsigned int m_nBlockCurrent;
static short* m_pBlockMemory; static short* m_pBlockMemory;
static WAVEHDR *m_pWaveHeaders; static WAVEHDR *m_pWaveHeaders;
static HWAVEOUT m_hwDevice; static HWAVEOUT m_hwDevice;
static std::thread m_AudioThread;
static std::atomic<bool> m_bAudioThreadActive;
static std::atomic<unsigned int> m_nBlockFree; static std::atomic<unsigned int> m_nBlockFree;
static std::condition_variable m_cvBlockNotZero; static std::condition_variable m_cvBlockNotZero;
static std::mutex m_muxBlockNotZero; 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::atomic<float> m_fGlobalTime;
static std::function<float(int, float, float)> funcUserSynth; static std::function<float(int, float, float)> funcUserSynth;
static std::function<float(int, float, float)> funcUserFilter; static std::function<float(int, float, float)> funcUserFilter;
#endif
}; };
} }
@ -143,14 +156,11 @@ namespace olc
#ifdef WIN32 #ifdef WIN32
#pragma comment(lib, "winmm.lib") #pragma comment(lib, "winmm.lib")
namespace olc namespace olc
{ {
SOUND::AudioSample::AudioSample() SOUND::AudioSample::AudioSample()
{ { }
}
SOUND::AudioSample::AudioSample(std::string sWavFile, olc::ResourcePack *pack) 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::funcUserSynth = nullptr;
std::function<float(int, float, float)> SOUND::funcUserFilter = 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 #endif
// Currently no Linux implementation so just go blank :(
#endif #endif

@ -2,11 +2,9 @@
olcPixelGameEngine.h olcPixelGameEngine.h
+-------------------------------------------------------------+ +-------------------------------------------------------------+
| OneLoneCoder Pixel Game Engine v1.11 | | OneLoneCoder Pixel Game Engine v1.12 |
| "Like the command prompt console one, but not..." - javidx9 | | "Like the command prompt console one, but not..." - javidx9 |
+-------------------------------------------------------------+ +-------------------------------------------------------------+
The Original & Best... :P
What is this? What is this?
~~~~~~~~~~~~~ ~~~~~~~~~~~~~
@ -90,6 +88,7 @@
Twitch: https://www.twitch.tv/javidx9 Twitch: https://www.twitch.tv/javidx9
GitHub: https://www.github.com/onelonecoder GitHub: https://www.github.com/onelonecoder
Homepage: https://www.onelonecoder.com Homepage: https://www.onelonecoder.com
Patreon: https://www.patreon.com/javidx9
Relevant Videos Relevant Videos
~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~
@ -121,17 +120,20 @@
~~~~~~ ~~~~~~
I'd like to extend thanks to Eremiell, slavka, gurkanctn, Phantim, I'd like to extend thanks to Eremiell, slavka, gurkanctn, Phantim,
JackOJC, KrossX, Huhlig, Dragoneye, Appa, JustinRichardsMusic, SliceNDice JackOJC, KrossX, Huhlig, Dragoneye, Appa, JustinRichardsMusic, SliceNDice
& MagetzUb for advice, ideas and testing, and I'd like to extend Ralakus, Gorbit99, raoul & MagetzUb for advice, ideas and testing, and I'd like
my appreciation to the 14K YouTube followers and 1K Discord server 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 members who give me the motivation to keep going with all this :D
Special thanks to those who bring gifts! Special thanks to those who bring gifts!
GnarGnarHead.......Domina GnarGnarHead.......Domina
Gorbit99...........Bastion 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 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();
~ResourcePack(); ~ResourcePack();
struct sEntry : public std::streambuf { 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: public:
olc::rcode AddToPack(std::string sFile); 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, F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, F11, F12,
UP, DOWN, LEFT, RIGHT, UP, DOWN, LEFT, RIGHT,
SPACE, TAB, SHIFT, CTRL, INS, DEL, HOME, END, PGUP, PGDN, 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::MASK = Transparent if alpha is < 255
// olc::Pixel::ALPHA = Full transparency // olc::Pixel::ALPHA = Full transparency
void SetPixelMode(Pixel::Mode m); void SetPixelMode(Pixel::Mode m);
Pixel::Mode GetPixelMode();
// Use a custom blend function // 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); 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; // Change the blend factor form between 0.0f to 1.0f;
@ -647,7 +653,8 @@ namespace olc
} }
else else
{ {
std::istream is(&(pack->GetStreamBuffer(sImageFile))); auto streamBuffer = pack->GetStreamBuffer(sImageFile);
std::istream is(&streamBuffer);
ReadData(is); ReadData(is);
} }
@ -852,10 +859,10 @@ namespace olc
// Create entry // Create entry
sEntry e; sEntry e;
e.data = nullptr; e.data = nullptr;
e.nFileSize = p; e.nFileSize = (uint32_t)p;
// Read file into memory // 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.read((char*)e.data, e.nFileSize);
ifs.close(); ifs.close();
@ -886,7 +893,7 @@ namespace olc
std::streampos offset = ofs.tellp(); std::streampos offset = ofs.tellp();
for (auto &e : mapFiles) for (auto &e : mapFiles)
{ {
e.second.nFileOffset = offset; e.second.nFileOffset = (uint32_t)offset;
ofs.write((char*)e.second.data, e.second.nFileSize); ofs.write((char*)e.second.data, e.second.nFileSize);
offset += e.second.nFileSize; offset += e.second.nFileSize;
} }
@ -936,12 +943,10 @@ namespace olc
// 2) Read Data // 2) Read Data
for (auto &e : mapFiles) 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.seekg(e.second.nFileOffset);
ifs.read((char*)e.second.data, e.second.nFileSize); ifs.read((char*)e.second.data, e.second.nFileSize);
//e.second.setg
e.second._config(); e.second._config();
//e.second.pubsetbuf((char*)e.second.data, e.second.nFileSize);
} }
ifs.close(); ifs.close();
@ -1542,6 +1547,11 @@ namespace olc
nPixelMode = m; 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) void PixelGameEngine::SetPixelMode(std::function<olc::Pixel(const int x, const int y, const olc::Pixel&, const olc::Pixel&)> pixelMode)
{ {
funcPixelMode = 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_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_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_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; 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[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[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; 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_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_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_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; 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_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_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; return olc_Display;
} }
@ -2044,4 +2064,4 @@ namespace olc
//============================================================= //=============================================================
} }
#endif #endif
Loading…
Cancel
Save