diff --git a/Game/src/Game.cpp b/Game/src/Game.cpp index d966259..b789e31 100644 --- a/Game/src/Game.cpp +++ b/Game/src/Game.cpp @@ -2,17 +2,21 @@ #include "MainState.h" int main(int argc, char* argv[]) { - nf::Config conf = { 1280, 720, false, "Example Game"}; - nf::Application app(conf); - //app.setWindowIcon(...); - // app.setWindowCursor(...); + + //New scope to test Application destructor + { + nf::Config conf = { 1280, 720, false, "Example Game" }; + nf::Application app(conf); + //app.setWindowIcon(...); + // app.setWindowCursor(...); - //Has to be on the heap for some reason - MainState* test = new MainState; - app.addState(test, "Main State"); - app.setDefaultState("Main State"); + //Has to be on the heap for some reason + MainState* test = new MainState; + app.addState(test, "Main State"); + app.setDefaultState("Main State"); - app.run(); + app.run(); + } return 0; } \ No newline at end of file diff --git a/Game/src/MainState.cpp b/Game/src/MainState.cpp index 534bc2e..77b4b9e 100644 --- a/Game/src/MainState.cpp +++ b/Game/src/MainState.cpp @@ -21,6 +21,9 @@ void MainState::onEnter() { sound.create(ap["sound.wav"]); sound.setEntity(test); + sound2.create(ap["test.ogg"]); + sound2.setVolume(3.0); + sound2.setEntity(test); for (int x = 0; x < 10; x++) { for (int y = 0; y < 10; y++) { @@ -60,18 +63,23 @@ void MainState::update(double deltaTime) { offset -= 2.0 * deltaTime; test.setRotation(0.0, 0.0, -offset * 20.0); - light.setPosition(nf::Vec3(std::sin(circle) * 10.0, 5.0, std::cos(circle) * 10.0)); + test.setPosition(nf::Vec3(std::sin(circle) * 10.0, 5.0, std::cos(circle) * 10.0)); circle += 2.0 * deltaTime; text.setText("FPS: " + std::to_string(app->getFPS())); if (button.isClicked()) app->changeState("Main State"); - if (button2.isClicked() || app->isKeyPressed(NFI_SPACE)) - sound.play(true); - if (app->isKeyPressed(NFI_O)) + if (button2.isClicked() || app->isKeyPressed(NFI_SPACE)) + sound.play(); + if (app->isKeyPressed(NFI_M)) + sound2.play(); + + if (app->isKeyPressed(NFI_O)) { sound.stop(); + sound2.stop(); + } if (app->isKeyPressed(NFI_ESCAPE)) app->quit(); diff --git a/Game/src/include/MainState.h b/Game/src/include/MainState.h index 31c3962..bf7c197 100644 --- a/Game/src/include/MainState.h +++ b/Game/src/include/MainState.h @@ -23,6 +23,7 @@ private: nf::Cubemap cm; nf::Sound sound; + nf::Sound sound2; double circle; diff --git a/NFPackCreator/AssetBuild/example/sounds/test.ogg b/NFPackCreator/AssetBuild/example/sounds/test.ogg new file mode 100644 index 0000000..8185a05 Binary files /dev/null and b/NFPackCreator/AssetBuild/example/sounds/test.ogg differ diff --git a/NFPackCreator/src/main.cpp b/NFPackCreator/src/main.cpp index cd0beee..595ac35 100644 --- a/NFPackCreator/src/main.cpp +++ b/NFPackCreator/src/main.cpp @@ -112,7 +112,7 @@ int main(int argc, char* argv[]) { CreateCompressor(COMPRESS_ALGORITHM_XPRESS_HUFF, NULL, &cHandle); std::set extensions; - extensions.insert({ "shader", "obj", "png", "jpg", "ttf", "wav" }); + extensions.insert({ "shader", "obj", "png", "jpg", "ttf", "wav", "ogg" }); unsigned int dirCount = 0; const std::filesystem::path workingDir = std::filesystem::current_path(); diff --git a/NothinFancy/NothinFancy.vcxproj b/NothinFancy/NothinFancy.vcxproj index 233df84..be42db6 100644 --- a/NothinFancy/NothinFancy.vcxproj +++ b/NothinFancy/NothinFancy.vcxproj @@ -67,10 +67,10 @@ true - glew32s.lib;opengl32.lib;freetype.lib;xaudio2.lib;Cabinet.lib;%(AdditionalDependencies) + glew32s.lib;opengl32.lib;freetype.lib;xaudio2.lib;Cabinet.lib;libogg.lib;libvorbis.lib;libvorbisfile.lib;%(AdditionalDependencies) - $(ProjectDir)dep\lib\;%(AdditionalLibraryDirectories) + $(ProjectDir)dep\lib\Shared;$(ProjectDir)dep\lib\$(Configuration);%(AdditionalLibraryDirectories) /ignore:4006 %(AdditionalOptions) @@ -96,10 +96,10 @@ true - glew32s.lib;opengl32.lib;freetype.lib;xaudio2.lib;Cabinet.lib;%(AdditionalDependencies) + glew32s.lib;opengl32.lib;freetype.lib;xaudio2.lib;Cabinet.lib;libogg.lib;libvorbis.lib;libvorbisfile.lib;%(AdditionalDependencies) - $(ProjectDir)dep\lib\;%(AdditionalLibraryDirectories) + $(ProjectDir)dep\lib\Shared;$(ProjectDir)dep\lib\$(Configuration);%(AdditionalLibraryDirectories) /ignore:4006 %(AdditionalOptions) diff --git a/NothinFancy/dep/include/ogg/ogg.h b/NothinFancy/dep/include/ogg/ogg.h new file mode 100644 index 0000000..c4325aa --- /dev/null +++ b/NothinFancy/dep/include/ogg/ogg.h @@ -0,0 +1,209 @@ +/******************************************************************** + * * + * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. * + * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * + * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * + * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * + * * + * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2007 * + * by the Xiph.Org Foundation http://www.xiph.org/ * + * * + ******************************************************************** + + function: toplevel libogg include + + ********************************************************************/ +#ifndef _OGG_H +#define _OGG_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include + +typedef struct { + void *iov_base; + size_t iov_len; +} ogg_iovec_t; + +typedef struct { + long endbyte; + int endbit; + + unsigned char *buffer; + unsigned char *ptr; + long storage; +} oggpack_buffer; + +/* ogg_page is used to encapsulate the data in one Ogg bitstream page *****/ + +typedef struct { + unsigned char *header; + long header_len; + unsigned char *body; + long body_len; +} ogg_page; + +/* ogg_stream_state contains the current encode/decode state of a logical + Ogg bitstream **********************************************************/ + +typedef struct { + unsigned char *body_data; /* bytes from packet bodies */ + long body_storage; /* storage elements allocated */ + long body_fill; /* elements stored; fill mark */ + long body_returned; /* elements of fill returned */ + + + int *lacing_vals; /* The values that will go to the segment table */ + ogg_int64_t *granule_vals; /* granulepos values for headers. Not compact + this way, but it is simple coupled to the + lacing fifo */ + long lacing_storage; + long lacing_fill; + long lacing_packet; + long lacing_returned; + + unsigned char header[282]; /* working space for header encode */ + int header_fill; + + int e_o_s; /* set when we have buffered the last packet in the + logical bitstream */ + int b_o_s; /* set after we've written the initial page + of a logical bitstream */ + long serialno; + long pageno; + ogg_int64_t packetno; /* sequence number for decode; the framing + knows where there's a hole in the data, + but we need coupling so that the codec + (which is in a separate abstraction + layer) also knows about the gap */ + ogg_int64_t granulepos; + +} ogg_stream_state; + +/* ogg_packet is used to encapsulate the data and metadata belonging + to a single raw Ogg/Vorbis packet *************************************/ + +typedef struct { + unsigned char *packet; + long bytes; + long b_o_s; + long e_o_s; + + ogg_int64_t granulepos; + + ogg_int64_t packetno; /* sequence number for decode; the framing + knows where there's a hole in the data, + but we need coupling so that the codec + (which is in a separate abstraction + layer) also knows about the gap */ +} ogg_packet; + +typedef struct { + unsigned char *data; + int storage; + int fill; + int returned; + + int unsynced; + int headerbytes; + int bodybytes; +} ogg_sync_state; + +/* Ogg BITSTREAM PRIMITIVES: bitstream ************************/ + +extern void oggpack_writeinit(oggpack_buffer *b); +extern int oggpack_writecheck(oggpack_buffer *b); +extern void oggpack_writetrunc(oggpack_buffer *b,long bits); +extern void oggpack_writealign(oggpack_buffer *b); +extern void oggpack_writecopy(oggpack_buffer *b,void *source,long bits); +extern void oggpack_reset(oggpack_buffer *b); +extern void oggpack_writeclear(oggpack_buffer *b); +extern void oggpack_readinit(oggpack_buffer *b,unsigned char *buf,int bytes); +extern void oggpack_write(oggpack_buffer *b,unsigned long value,int bits); +extern long oggpack_look(oggpack_buffer *b,int bits); +extern long oggpack_look1(oggpack_buffer *b); +extern void oggpack_adv(oggpack_buffer *b,int bits); +extern void oggpack_adv1(oggpack_buffer *b); +extern long oggpack_read(oggpack_buffer *b,int bits); +extern long oggpack_read1(oggpack_buffer *b); +extern long oggpack_bytes(oggpack_buffer *b); +extern long oggpack_bits(oggpack_buffer *b); +extern unsigned char *oggpack_get_buffer(oggpack_buffer *b); + +extern void oggpackB_writeinit(oggpack_buffer *b); +extern int oggpackB_writecheck(oggpack_buffer *b); +extern void oggpackB_writetrunc(oggpack_buffer *b,long bits); +extern void oggpackB_writealign(oggpack_buffer *b); +extern void oggpackB_writecopy(oggpack_buffer *b,void *source,long bits); +extern void oggpackB_reset(oggpack_buffer *b); +extern void oggpackB_writeclear(oggpack_buffer *b); +extern void oggpackB_readinit(oggpack_buffer *b,unsigned char *buf,int bytes); +extern void oggpackB_write(oggpack_buffer *b,unsigned long value,int bits); +extern long oggpackB_look(oggpack_buffer *b,int bits); +extern long oggpackB_look1(oggpack_buffer *b); +extern void oggpackB_adv(oggpack_buffer *b,int bits); +extern void oggpackB_adv1(oggpack_buffer *b); +extern long oggpackB_read(oggpack_buffer *b,int bits); +extern long oggpackB_read1(oggpack_buffer *b); +extern long oggpackB_bytes(oggpack_buffer *b); +extern long oggpackB_bits(oggpack_buffer *b); +extern unsigned char *oggpackB_get_buffer(oggpack_buffer *b); + +/* Ogg BITSTREAM PRIMITIVES: encoding **************************/ + +extern int ogg_stream_packetin(ogg_stream_state *os, ogg_packet *op); +extern int ogg_stream_iovecin(ogg_stream_state *os, ogg_iovec_t *iov, + int count, long e_o_s, ogg_int64_t granulepos); +extern int ogg_stream_pageout(ogg_stream_state *os, ogg_page *og); +extern int ogg_stream_pageout_fill(ogg_stream_state *os, ogg_page *og, int nfill); +extern int ogg_stream_flush(ogg_stream_state *os, ogg_page *og); +extern int ogg_stream_flush_fill(ogg_stream_state *os, ogg_page *og, int nfill); + +/* Ogg BITSTREAM PRIMITIVES: decoding **************************/ + +extern int ogg_sync_init(ogg_sync_state *oy); +extern int ogg_sync_clear(ogg_sync_state *oy); +extern int ogg_sync_reset(ogg_sync_state *oy); +extern int ogg_sync_destroy(ogg_sync_state *oy); +extern int ogg_sync_check(ogg_sync_state *oy); + +extern char *ogg_sync_buffer(ogg_sync_state *oy, long size); +extern int ogg_sync_wrote(ogg_sync_state *oy, long bytes); +extern long ogg_sync_pageseek(ogg_sync_state *oy,ogg_page *og); +extern int ogg_sync_pageout(ogg_sync_state *oy, ogg_page *og); +extern int ogg_stream_pagein(ogg_stream_state *os, ogg_page *og); +extern int ogg_stream_packetout(ogg_stream_state *os,ogg_packet *op); +extern int ogg_stream_packetpeek(ogg_stream_state *os,ogg_packet *op); + +/* Ogg BITSTREAM PRIMITIVES: general ***************************/ + +extern int ogg_stream_init(ogg_stream_state *os,int serialno); +extern int ogg_stream_clear(ogg_stream_state *os); +extern int ogg_stream_reset(ogg_stream_state *os); +extern int ogg_stream_reset_serialno(ogg_stream_state *os,int serialno); +extern int ogg_stream_destroy(ogg_stream_state *os); +extern int ogg_stream_check(ogg_stream_state *os); +extern int ogg_stream_eos(ogg_stream_state *os); + +extern void ogg_page_checksum_set(ogg_page *og); + +extern int ogg_page_version(const ogg_page *og); +extern int ogg_page_continued(const ogg_page *og); +extern int ogg_page_bos(const ogg_page *og); +extern int ogg_page_eos(const ogg_page *og); +extern ogg_int64_t ogg_page_granulepos(const ogg_page *og); +extern int ogg_page_serialno(const ogg_page *og); +extern long ogg_page_pageno(const ogg_page *og); +extern int ogg_page_packets(const ogg_page *og); + +extern void ogg_packet_clear(ogg_packet *op); + + +#ifdef __cplusplus +} +#endif + +#endif /* _OGG_H */ diff --git a/NothinFancy/dep/include/ogg/os_types.h b/NothinFancy/dep/include/ogg/os_types.h new file mode 100644 index 0000000..e655a1d --- /dev/null +++ b/NothinFancy/dep/include/ogg/os_types.h @@ -0,0 +1,158 @@ +/******************************************************************** + * * + * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. * + * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * + * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * + * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * + * * + * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2002 * + * by the Xiph.Org Foundation http://www.xiph.org/ * + * * + ******************************************************************** + + function: Define a consistent set of types on each platform. + + ********************************************************************/ +#ifndef _OS_TYPES_H +#define _OS_TYPES_H + +/* make it easy on the folks that want to compile the libs with a + different malloc than stdlib */ +#define _ogg_malloc malloc +#define _ogg_calloc calloc +#define _ogg_realloc realloc +#define _ogg_free free + +#if defined(_WIN32) + +# if defined(__CYGWIN__) +# include + typedef int16_t ogg_int16_t; + typedef uint16_t ogg_uint16_t; + typedef int32_t ogg_int32_t; + typedef uint32_t ogg_uint32_t; + typedef int64_t ogg_int64_t; + typedef uint64_t ogg_uint64_t; +# elif defined(__MINGW32__) +# include + typedef short ogg_int16_t; + typedef unsigned short ogg_uint16_t; + typedef int ogg_int32_t; + typedef unsigned int ogg_uint32_t; + typedef long long ogg_int64_t; + typedef unsigned long long ogg_uint64_t; +# elif defined(__MWERKS__) + typedef long long ogg_int64_t; + typedef unsigned long long ogg_uint64_t; + typedef int ogg_int32_t; + typedef unsigned int ogg_uint32_t; + typedef short ogg_int16_t; + typedef unsigned short ogg_uint16_t; +# else +# if defined(_MSC_VER) && (_MSC_VER >= 1800) /* MSVC 2013 and newer */ +# include + typedef int16_t ogg_int16_t; + typedef uint16_t ogg_uint16_t; + typedef int32_t ogg_int32_t; + typedef uint32_t ogg_uint32_t; + typedef int64_t ogg_int64_t; + typedef uint64_t ogg_uint64_t; +# else + /* MSVC/Borland */ + typedef __int64 ogg_int64_t; + typedef __int32 ogg_int32_t; + typedef unsigned __int32 ogg_uint32_t; + typedef unsigned __int64 ogg_uint64_t; + typedef __int16 ogg_int16_t; + typedef unsigned __int16 ogg_uint16_t; +# endif +# endif + +#elif (defined(__APPLE__) && defined(__MACH__)) /* MacOS X Framework build */ + +# include + typedef int16_t ogg_int16_t; + typedef u_int16_t ogg_uint16_t; + typedef int32_t ogg_int32_t; + typedef u_int32_t ogg_uint32_t; + typedef int64_t ogg_int64_t; + typedef u_int64_t ogg_uint64_t; + +#elif defined(__HAIKU__) + + /* Haiku */ +# include + typedef short ogg_int16_t; + typedef unsigned short ogg_uint16_t; + typedef int ogg_int32_t; + typedef unsigned int ogg_uint32_t; + typedef long long ogg_int64_t; + typedef unsigned long long ogg_uint64_t; + +#elif defined(__BEOS__) + + /* Be */ +# include + typedef int16_t ogg_int16_t; + typedef uint16_t ogg_uint16_t; + typedef int32_t ogg_int32_t; + typedef uint32_t ogg_uint32_t; + typedef int64_t ogg_int64_t; + typedef uint64_t ogg_uint64_t; + +#elif defined (__EMX__) + + /* OS/2 GCC */ + typedef short ogg_int16_t; + typedef unsigned short ogg_uint16_t; + typedef int ogg_int32_t; + typedef unsigned int ogg_uint32_t; + typedef long long ogg_int64_t; + typedef unsigned long long ogg_uint64_t; + + +#elif defined (DJGPP) + + /* DJGPP */ + typedef short ogg_int16_t; + typedef int ogg_int32_t; + typedef unsigned int ogg_uint32_t; + typedef long long ogg_int64_t; + typedef unsigned long long ogg_uint64_t; + +#elif defined(R5900) + + /* PS2 EE */ + typedef long ogg_int64_t; + typedef unsigned long ogg_uint64_t; + typedef int ogg_int32_t; + typedef unsigned ogg_uint32_t; + typedef short ogg_int16_t; + +#elif defined(__SYMBIAN32__) + + /* Symbian GCC */ + typedef signed short ogg_int16_t; + typedef unsigned short ogg_uint16_t; + typedef signed int ogg_int32_t; + typedef unsigned int ogg_uint32_t; + typedef long long int ogg_int64_t; + typedef unsigned long long int ogg_uint64_t; + +#elif defined(__TMS320C6X__) + + /* TI C64x compiler */ + typedef signed short ogg_int16_t; + typedef unsigned short ogg_uint16_t; + typedef signed int ogg_int32_t; + typedef unsigned int ogg_uint32_t; + typedef long long int ogg_int64_t; + typedef unsigned long long int ogg_uint64_t; + +#else + +# include + +#endif + +#endif /* _OS_TYPES_H */ diff --git a/NothinFancy/dep/include/vorbis/codec.h b/NothinFancy/dep/include/vorbis/codec.h new file mode 100644 index 0000000..f8a912b --- /dev/null +++ b/NothinFancy/dep/include/vorbis/codec.h @@ -0,0 +1,242 @@ +/******************************************************************** + * * + * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. * + * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * + * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * + * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * + * * + * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2001 * + * by the Xiph.Org Foundation https://xiph.org/ * + + ******************************************************************** + + function: libvorbis codec headers + + ********************************************************************/ + +#ifndef _vorbis_codec_h_ +#define _vorbis_codec_h_ + +#ifdef __cplusplus +extern "C" +{ +#endif /* __cplusplus */ + +#include + +typedef struct vorbis_info{ + int version; + int channels; + long rate; + + /* The below bitrate declarations are *hints*. + Combinations of the three values carry the following implications: + + all three set to the same value: + implies a fixed rate bitstream + only nominal set: + implies a VBR stream that averages the nominal bitrate. No hard + upper/lower limit + upper and or lower set: + implies a VBR bitstream that obeys the bitrate limits. nominal + may also be set to give a nominal rate. + none set: + the coder does not care to speculate. + */ + + long bitrate_upper; + long bitrate_nominal; + long bitrate_lower; + long bitrate_window; + + void *codec_setup; +} vorbis_info; + +/* vorbis_dsp_state buffers the current vorbis audio + analysis/synthesis state. The DSP state belongs to a specific + logical bitstream ****************************************************/ +typedef struct vorbis_dsp_state{ + int analysisp; + vorbis_info *vi; + + float **pcm; + float **pcmret; + int pcm_storage; + int pcm_current; + int pcm_returned; + + int preextrapolate; + int eofflag; + + long lW; + long W; + long nW; + long centerW; + + ogg_int64_t granulepos; + ogg_int64_t sequence; + + ogg_int64_t glue_bits; + ogg_int64_t time_bits; + ogg_int64_t floor_bits; + ogg_int64_t res_bits; + + void *backend_state; +} vorbis_dsp_state; + +typedef struct vorbis_block{ + /* necessary stream state for linking to the framing abstraction */ + float **pcm; /* this is a pointer into local storage */ + oggpack_buffer opb; + + long lW; + long W; + long nW; + int pcmend; + int mode; + + int eofflag; + ogg_int64_t granulepos; + ogg_int64_t sequence; + vorbis_dsp_state *vd; /* For read-only access of configuration */ + + /* local storage to avoid remallocing; it's up to the mapping to + structure it */ + void *localstore; + long localtop; + long localalloc; + long totaluse; + struct alloc_chain *reap; + + /* bitmetrics for the frame */ + long glue_bits; + long time_bits; + long floor_bits; + long res_bits; + + void *internal; + +} vorbis_block; + +/* vorbis_block is a single block of data to be processed as part of +the analysis/synthesis stream; it belongs to a specific logical +bitstream, but is independent from other vorbis_blocks belonging to +that logical bitstream. *************************************************/ + +struct alloc_chain{ + void *ptr; + struct alloc_chain *next; +}; + +/* vorbis_info contains all the setup information specific to the + specific compression/decompression mode in progress (eg, + psychoacoustic settings, channel setup, options, codebook + etc). vorbis_info and substructures are in backends.h. +*********************************************************************/ + +/* the comments are not part of vorbis_info so that vorbis_info can be + static storage */ +typedef struct vorbis_comment{ + /* unlimited user comment fields. libvorbis writes 'libvorbis' + whatever vendor is set to in encode */ + char **user_comments; + int *comment_lengths; + int comments; + char *vendor; + +} vorbis_comment; + + +/* libvorbis encodes in two abstraction layers; first we perform DSP + and produce a packet (see docs/analysis.txt). The packet is then + coded into a framed OggSquish bitstream by the second layer (see + docs/framing.txt). Decode is the reverse process; we sync/frame + the bitstream and extract individual packets, then decode the + packet back into PCM audio. + + The extra framing/packetizing is used in streaming formats, such as + files. Over the net (such as with UDP), the framing and + packetization aren't necessary as they're provided by the transport + and the streaming layer is not used */ + +/* Vorbis PRIMITIVES: general ***************************************/ + +extern void vorbis_info_init(vorbis_info *vi); +extern void vorbis_info_clear(vorbis_info *vi); +extern int vorbis_info_blocksize(vorbis_info *vi,int zo); +extern void vorbis_comment_init(vorbis_comment *vc); +extern void vorbis_comment_add(vorbis_comment *vc, const char *comment); +extern void vorbis_comment_add_tag(vorbis_comment *vc, + const char *tag, const char *contents); +extern char *vorbis_comment_query(vorbis_comment *vc, const char *tag, int count); +extern int vorbis_comment_query_count(vorbis_comment *vc, const char *tag); +extern void vorbis_comment_clear(vorbis_comment *vc); + +extern int vorbis_block_init(vorbis_dsp_state *v, vorbis_block *vb); +extern int vorbis_block_clear(vorbis_block *vb); +extern void vorbis_dsp_clear(vorbis_dsp_state *v); +extern double vorbis_granule_time(vorbis_dsp_state *v, + ogg_int64_t granulepos); + +extern const char *vorbis_version_string(void); + +/* Vorbis PRIMITIVES: analysis/DSP layer ****************************/ + +extern int vorbis_analysis_init(vorbis_dsp_state *v,vorbis_info *vi); +extern int vorbis_commentheader_out(vorbis_comment *vc, ogg_packet *op); +extern int vorbis_analysis_headerout(vorbis_dsp_state *v, + vorbis_comment *vc, + ogg_packet *op, + ogg_packet *op_comm, + ogg_packet *op_code); +extern float **vorbis_analysis_buffer(vorbis_dsp_state *v,int vals); +extern int vorbis_analysis_wrote(vorbis_dsp_state *v,int vals); +extern int vorbis_analysis_blockout(vorbis_dsp_state *v,vorbis_block *vb); +extern int vorbis_analysis(vorbis_block *vb,ogg_packet *op); + +extern int vorbis_bitrate_addblock(vorbis_block *vb); +extern int vorbis_bitrate_flushpacket(vorbis_dsp_state *vd, + ogg_packet *op); + +/* Vorbis PRIMITIVES: synthesis layer *******************************/ +extern int vorbis_synthesis_idheader(ogg_packet *op); +extern int vorbis_synthesis_headerin(vorbis_info *vi,vorbis_comment *vc, + ogg_packet *op); + +extern int vorbis_synthesis_init(vorbis_dsp_state *v,vorbis_info *vi); +extern int vorbis_synthesis_restart(vorbis_dsp_state *v); +extern int vorbis_synthesis(vorbis_block *vb,ogg_packet *op); +extern int vorbis_synthesis_trackonly(vorbis_block *vb,ogg_packet *op); +extern int vorbis_synthesis_blockin(vorbis_dsp_state *v,vorbis_block *vb); +extern int vorbis_synthesis_pcmout(vorbis_dsp_state *v,float ***pcm); +extern int vorbis_synthesis_lapout(vorbis_dsp_state *v,float ***pcm); +extern int vorbis_synthesis_read(vorbis_dsp_state *v,int samples); +extern long vorbis_packet_blocksize(vorbis_info *vi,ogg_packet *op); + +extern int vorbis_synthesis_halfrate(vorbis_info *v,int flag); +extern int vorbis_synthesis_halfrate_p(vorbis_info *v); + +/* Vorbis ERRORS and return codes ***********************************/ + +#define OV_FALSE -1 +#define OV_EOF -2 +#define OV_HOLE -3 + +#define OV_EREAD -128 +#define OV_EFAULT -129 +#define OV_EIMPL -130 +#define OV_EINVAL -131 +#define OV_ENOTVORBIS -132 +#define OV_EBADHEADER -133 +#define OV_EVERSION -134 +#define OV_ENOTAUDIO -135 +#define OV_EBADPACKET -136 +#define OV_EBADLINK -137 +#define OV_ENOSEEK -138 + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif + diff --git a/NothinFancy/dep/include/vorbis/vorbisfile.h b/NothinFancy/dep/include/vorbis/vorbisfile.h new file mode 100644 index 0000000..3d65393 --- /dev/null +++ b/NothinFancy/dep/include/vorbis/vorbisfile.h @@ -0,0 +1,205 @@ +/******************************************************************** + * * + * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. * + * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * + * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * + * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * + * * + * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2007 * + * by the Xiph.Org Foundation https://xiph.org/ * + * * + ******************************************************************** + + function: stdio-based convenience library for opening/seeking/decoding + + ********************************************************************/ + +#ifndef _OV_FILE_H_ +#define _OV_FILE_H_ + +#ifdef __cplusplus +extern "C" +{ +#endif /* __cplusplus */ + +#include +#include "codec.h" + +/* The function prototypes for the callbacks are basically the same as for + * the stdio functions fread, fseek, fclose, ftell. + * The one difference is that the FILE * arguments have been replaced with + * a void * - this is to be used as a pointer to whatever internal data these + * functions might need. In the stdio case, it's just a FILE * cast to a void * + * + * If you use other functions, check the docs for these functions and return + * the right values. For seek_func(), you *MUST* return -1 if the stream is + * unseekable + */ +typedef struct { + size_t (*read_func) (void *ptr, size_t size, size_t nmemb, void *datasource); + int (*seek_func) (void *datasource, ogg_int64_t offset, int whence); + int (*close_func) (void *datasource); + long (*tell_func) (void *datasource); +} ov_callbacks; + +#ifndef OV_EXCLUDE_STATIC_CALLBACKS + +/* a few sets of convenient callbacks, especially for use under + * Windows where ov_open_callbacks() should always be used instead of + * ov_open() to avoid problems with incompatible crt.o version linking + * issues. */ + +static int _ov_header_fseek_wrap(FILE *f,ogg_int64_t off,int whence){ + if(f==NULL)return(-1); + +#ifdef __MINGW32__ + return fseeko64(f,off,whence); +#elif defined (_WIN32) + return _fseeki64(f,off,whence); +#else + return fseek(f,off,whence); +#endif +} + +/* These structs below (OV_CALLBACKS_DEFAULT etc) are defined here as + * static data. That means that every file which includes this header + * will get its own copy of these structs whether it uses them or + * not unless it #defines OV_EXCLUDE_STATIC_CALLBACKS. + * These static symbols are essential on platforms such as Windows on + * which several different versions of stdio support may be linked to + * by different DLLs, and we need to be certain we know which one + * we're using (the same one as the main application). + */ + +static ov_callbacks OV_CALLBACKS_DEFAULT = { + (size_t (*)(void *, size_t, size_t, void *)) fread, + (int (*)(void *, ogg_int64_t, int)) _ov_header_fseek_wrap, + (int (*)(void *)) fclose, + (long (*)(void *)) ftell +}; + +static ov_callbacks OV_CALLBACKS_NOCLOSE = { + (size_t (*)(void *, size_t, size_t, void *)) fread, + (int (*)(void *, ogg_int64_t, int)) _ov_header_fseek_wrap, + (int (*)(void *)) NULL, + (long (*)(void *)) ftell +}; + +static ov_callbacks OV_CALLBACKS_STREAMONLY = { + (size_t (*)(void *, size_t, size_t, void *)) fread, + (int (*)(void *, ogg_int64_t, int)) NULL, + (int (*)(void *)) fclose, + (long (*)(void *)) NULL +}; + +static ov_callbacks OV_CALLBACKS_STREAMONLY_NOCLOSE = { + (size_t (*)(void *, size_t, size_t, void *)) fread, + (int (*)(void *, ogg_int64_t, int)) NULL, + (int (*)(void *)) NULL, + (long (*)(void *)) NULL +}; + +#endif + +#define NOTOPEN 0 +#define PARTOPEN 1 +#define OPENED 2 +#define STREAMSET 3 +#define INITSET 4 + +typedef struct OggVorbis_File { + void *datasource; /* Pointer to a FILE *, etc. */ + int seekable; + ogg_int64_t offset; + ogg_int64_t end; + ogg_sync_state oy; + + /* If the FILE handle isn't seekable (eg, a pipe), only the current + stream appears */ + int links; + ogg_int64_t *offsets; + ogg_int64_t *dataoffsets; + long *serialnos; + ogg_int64_t *pcmlengths; /* overloaded to maintain binary + compatibility; x2 size, stores both + beginning and end values */ + vorbis_info *vi; + vorbis_comment *vc; + + /* Decoding working state local storage */ + ogg_int64_t pcm_offset; + int ready_state; + long current_serialno; + int current_link; + + double bittrack; + double samptrack; + + ogg_stream_state os; /* take physical pages, weld into a logical + stream of packets */ + vorbis_dsp_state vd; /* central working state for the packet->PCM decoder */ + vorbis_block vb; /* local working space for packet->PCM decode */ + + ov_callbacks callbacks; + +} OggVorbis_File; + + +extern int ov_clear(OggVorbis_File *vf); +extern int ov_fopen(const char *path,OggVorbis_File *vf); +extern int ov_open(FILE *f,OggVorbis_File *vf,const char *initial,long ibytes); +extern int ov_open_callbacks(void *datasource, OggVorbis_File *vf, + const char *initial, long ibytes, ov_callbacks callbacks); + +extern int ov_test(FILE *f,OggVorbis_File *vf,const char *initial,long ibytes); +extern int ov_test_callbacks(void *datasource, OggVorbis_File *vf, + const char *initial, long ibytes, ov_callbacks callbacks); +extern int ov_test_open(OggVorbis_File *vf); + +extern long ov_bitrate(OggVorbis_File *vf,int i); +extern long ov_bitrate_instant(OggVorbis_File *vf); +extern long ov_streams(OggVorbis_File *vf); +extern long ov_seekable(OggVorbis_File *vf); +extern long ov_serialnumber(OggVorbis_File *vf,int i); + +extern ogg_int64_t ov_raw_total(OggVorbis_File *vf,int i); +extern ogg_int64_t ov_pcm_total(OggVorbis_File *vf,int i); +extern double ov_time_total(OggVorbis_File *vf,int i); + +extern int ov_raw_seek(OggVorbis_File *vf,ogg_int64_t pos); +extern int ov_pcm_seek(OggVorbis_File *vf,ogg_int64_t pos); +extern int ov_pcm_seek_page(OggVorbis_File *vf,ogg_int64_t pos); +extern int ov_time_seek(OggVorbis_File *vf,double pos); +extern int ov_time_seek_page(OggVorbis_File *vf,double pos); + +extern int ov_raw_seek_lap(OggVorbis_File *vf,ogg_int64_t pos); +extern int ov_pcm_seek_lap(OggVorbis_File *vf,ogg_int64_t pos); +extern int ov_pcm_seek_page_lap(OggVorbis_File *vf,ogg_int64_t pos); +extern int ov_time_seek_lap(OggVorbis_File *vf,double pos); +extern int ov_time_seek_page_lap(OggVorbis_File *vf,double pos); + +extern ogg_int64_t ov_raw_tell(OggVorbis_File *vf); +extern ogg_int64_t ov_pcm_tell(OggVorbis_File *vf); +extern double ov_time_tell(OggVorbis_File *vf); + +extern vorbis_info *ov_info(OggVorbis_File *vf,int link); +extern vorbis_comment *ov_comment(OggVorbis_File *vf,int link); + +extern long ov_read_float(OggVorbis_File *vf,float ***pcm_channels,int samples, + int *bitstream); +extern long ov_read_filter(OggVorbis_File *vf,char *buffer,int length, + int bigendianp,int word,int sgned,int *bitstream, + void (*filter)(float **pcm,long channels,long samples,void *filter_param),void *filter_param); +extern long ov_read(OggVorbis_File *vf,char *buffer,int length, + int bigendianp,int word,int sgned,int *bitstream); +extern int ov_crosslap(OggVorbis_File *vf1,OggVorbis_File *vf2); + +extern int ov_halfrate(OggVorbis_File *vf,int flag); +extern int ov_halfrate_p(OggVorbis_File *vf); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif + diff --git a/NothinFancy/dep/lib/Debug/libogg.lib b/NothinFancy/dep/lib/Debug/libogg.lib new file mode 100644 index 0000000..9e7e7fd Binary files /dev/null and b/NothinFancy/dep/lib/Debug/libogg.lib differ diff --git a/NothinFancy/dep/lib/Debug/libvorbis.lib b/NothinFancy/dep/lib/Debug/libvorbis.lib new file mode 100644 index 0000000..7dc1485 Binary files /dev/null and b/NothinFancy/dep/lib/Debug/libvorbis.lib differ diff --git a/NothinFancy/dep/lib/Debug/libvorbisfile.lib b/NothinFancy/dep/lib/Debug/libvorbisfile.lib new file mode 100644 index 0000000..f58bed9 Binary files /dev/null and b/NothinFancy/dep/lib/Debug/libvorbisfile.lib differ diff --git a/NothinFancy/dep/lib/Release/libogg.lib b/NothinFancy/dep/lib/Release/libogg.lib new file mode 100644 index 0000000..f52b2e5 Binary files /dev/null and b/NothinFancy/dep/lib/Release/libogg.lib differ diff --git a/NothinFancy/dep/lib/Release/libvorbis.lib b/NothinFancy/dep/lib/Release/libvorbis.lib new file mode 100644 index 0000000..939f61d Binary files /dev/null and b/NothinFancy/dep/lib/Release/libvorbis.lib differ diff --git a/NothinFancy/dep/lib/Release/libvorbisfile.lib b/NothinFancy/dep/lib/Release/libvorbisfile.lib new file mode 100644 index 0000000..60b445c Binary files /dev/null and b/NothinFancy/dep/lib/Release/libvorbisfile.lib differ diff --git a/NothinFancy/dep/lib/freetype.lib b/NothinFancy/dep/lib/Shared/freetype.lib similarity index 100% rename from NothinFancy/dep/lib/freetype.lib rename to NothinFancy/dep/lib/Shared/freetype.lib diff --git a/NothinFancy/dep/lib/glew32s.lib b/NothinFancy/dep/lib/Shared/glew32s.lib similarity index 100% rename from NothinFancy/dep/lib/glew32s.lib rename to NothinFancy/dep/lib/Shared/glew32s.lib diff --git a/NothinFancy/src/Application.cpp b/NothinFancy/src/Application.cpp index 14beb93..97619dc 100644 --- a/NothinFancy/src/Application.cpp +++ b/NothinFancy/src/Application.cpp @@ -20,7 +20,7 @@ namespace nf { Log("Creating NF application"); Log("Width: " + std::to_string(m_currentConfig.width) + ", Height: " + std::to_string(m_currentConfig.height) + ", Fullscreen: " + std::to_string(m_currentConfig.fullscreen) + ", Title: " + m_currentConfig.title); - if (getApp() != nullptr) + if (getApp(true) != nullptr) Error("Cannot create two NF Application objects!"); setApp(this); m_hInst = GetModuleHandle(NULL); @@ -29,7 +29,7 @@ namespace nf { int x = 0; int y = 0; calculateNewWindowPos(x, y); - m_window = CreateWindowEx(NULL, m_wclassName, toWide(m_currentConfig.title), WS_OVERLAPPED | WS_SYSMENU | WS_MINIMIZEBOX, x, y, windowSize.right, windowSize.bottom, NULL, NULL, m_hInst, NULL); + m_window = CreateWindowEx(NULL, m_wclassName, toWide(m_currentConfig.title).data(), WS_OVERLAPPED | WS_SYSMENU | WS_MINIMIZEBOX, x, y, windowSize.right, windowSize.bottom, NULL, NULL, m_hInst, NULL); m_defaultWindowStyle = GetWindowLong(m_window, GWL_STYLE); SetProp(m_window, L"App", this); if (m_currentConfig.fullscreen) toggleFullscreen(); @@ -126,7 +126,7 @@ namespace nf { } //TODO: Throughly test this void Application::changeConfig(const Config& in) { - SetWindowText(m_window, toWide(in.title)); + SetWindowText(m_window, toWide(in.title).data()); bool temp = m_currentConfig.fullscreen; m_currentConfig = in; if (in.fullscreen != temp) @@ -186,7 +186,9 @@ namespace nf { return Vec2(m_mouseX, m_mouseY); } - Application* Application::getApp() { + Application* Application::getApp(bool first) { + if (!currentApp && !first) + Error("No Application has been created yet!"); return currentApp; } @@ -284,8 +286,8 @@ namespace nf { #ifdef _DEBUG SetThreadDescription(GetCurrentThread(), L"Main Engine Thread"); #endif - m_sIntro = new IntroGamestate; - m_currentState = m_sIntro; + Gamestate* sIntro = new IntroGamestate; + m_currentState = sIntro; m_audio = new AudioEngine(this); m_renderer = new Renderer(this); m_currentState->setup(this); @@ -320,6 +322,7 @@ namespace nf { m_audio->stopAllSounds(); m_currentState->onExit(); m_currentState->cleanup(); + delete sIntro; delete m_audio; delete m_renderer; } diff --git a/NothinFancy/src/Assets.cpp b/NothinFancy/src/Assets.cpp index f7982d3..722e03d 100644 --- a/NothinFancy/src/Assets.cpp +++ b/NothinFancy/src/Assets.cpp @@ -186,7 +186,7 @@ namespace nf { m_assets[assetName] = font; continue; } - if (extension == "wav") { + if (extension == "ogg" || extension == "wav") { ASound* sound = new ASound; sound->data = new char[assetSize]; std::memcpy(sound->data, &assetContents[0], assetSize); diff --git a/NothinFancy/src/AudioEngine.cpp b/NothinFancy/src/AudioEngine.cpp index e4c9cbc..cdf500f 100644 --- a/NothinFancy/src/AudioEngine.cpp +++ b/NothinFancy/src/AudioEngine.cpp @@ -81,8 +81,12 @@ namespace nf { float az[20] = { 0 }; emitter.pChannelAzimuths = az; XAUDIO2_FILTER_PARAMETERS filter = { LowPassFilter, 1.0, 1.0 }; - XAUDIO2_VOICE_STATE state; Vec3 temp; + XAUDIO2_VOICE_STATE state; + XAUDIO2_VOICE_DETAILS details; + m_masterVoice->GetVoiceDetails(&details); + unsigned int outChannels = details.InputChannels; + x3dSettings.DstChannelCount = outChannels; while (m_threadRunning) { if (m_isActive && Application::getApp()->getCurrentState()->isRunning()) { @@ -94,7 +98,7 @@ namespace nf { //Stop all sounds if requested if (m_clear) - clearSounds(); + stopAllSounds(); //Update sounds for (SoundData& curr : m_sounds) { @@ -134,13 +138,12 @@ namespace nf { int ch = curr.format->Format.nChannels; emitter.ChannelCount = ch; x3dSettings.SrcChannelCount = ch; - x3dSettings.DstChannelCount = ch; emitter.Position = X3DAUDIO_VECTOR((float)temp.x, (float)temp.y, (float)-temp.z); X3DAudioCalculate(x3d, &listener, &emitter, X3DAUDIO_CALCULATE_MATRIX | X3DAUDIO_CALCULATE_DOPPLER | X3DAUDIO_CALCULATE_LPF_DIRECT | X3DAUDIO_CALCULATE_REVERB, &x3dSettings); float temp2 = matrix[1]; matrix[1] = matrix[2]; matrix[2] = temp2; - curr.voice->SetOutputMatrix(m_masterVoice, ch, ch, matrix); + curr.voice->SetOutputMatrix(m_masterVoice, ch, outChannels, matrix); curr.voice->SetFrequencyRatio(x3dSettings.DopplerFactor); filter.Frequency = 2.0f * std::sinf(X3DAUDIO_PI / 6.0f * x3dSettings.LPFDirectCoefficient); curr.voice->SetFilterParameters(&filter); @@ -149,7 +152,7 @@ namespace nf { //Delete all finished sounds from the list for (size_t i = 0; i < m_sounds.size(); i++) { - if (m_sounds[i].finished) { + if (m_sounds[i].finished && m_sounds[i].voice) { m_sounds[i].voice->Stop(); m_sounds[i].voice->FlushSourceBuffers(); m_sounds[i].voice->DestroyVoice(); @@ -161,7 +164,7 @@ namespace nf { } //Cleanup - clearSounds(); + stopAllSounds(); m_masterVoice->DestroyVoice(); } @@ -178,10 +181,6 @@ namespace nf { } void AudioEngine::stopAllSounds() { - m_clear = true; - } - - void AudioEngine::clearSounds() { m_clear = false; for (SoundData& curr : m_sounds) { if (curr.start) continue; diff --git a/NothinFancy/src/IntroGamestate.cpp b/NothinFancy/src/IntroGamestate.cpp index 6c62d35..e46165d 100644 --- a/NothinFancy/src/IntroGamestate.cpp +++ b/NothinFancy/src/IntroGamestate.cpp @@ -16,8 +16,8 @@ namespace nf { void IntroGamestate::update(double deltaTime) { static unsigned int frame = 0; frame++; - if (frame < 10) return; - if (frame == 10) + if (frame < 5) return; + if (frame == 5) m_start = std::chrono::steady_clock::now(); std::chrono::steady_clock::time_point now = std::chrono::steady_clock::now(); diff --git a/NothinFancy/src/NFObject/Sound.cpp b/NothinFancy/src/NFObject/Sound.cpp index 2e5f6e8..c9f9037 100644 --- a/NothinFancy/src/NFObject/Sound.cpp +++ b/NothinFancy/src/NFObject/Sound.cpp @@ -1,10 +1,85 @@ #include "Sound.h" +#include "vorbis/vorbisfile.h" + #include "Application.h" #include "Assets.h" #include "Entity.h" namespace nf { +#pragma region Ogg File Loading + struct oggFileMem { + char* data; + int size; + size_t pointer; + }; + + size_t v_read(void* out, size_t sizeofByte, size_t toRead, void* in) { + oggFileMem* file = (oggFileMem*)in; + if (file == nullptr) return -1; + + size_t actual, left = file->size - file->pointer; + if ((toRead * sizeofByte) < left) + actual = toRead * sizeofByte; + else + actual = left; + + if (actual) { + std::memcpy(out, (char*)file->data + file->pointer, actual); + file->pointer += actual; + } + + return actual; + } + + int v_seek(void* in, ogg_int64_t offset, int origin) { + oggFileMem* file = (oggFileMem*)in; + if (file == nullptr) return -1; + + switch (origin) { + case SEEK_SET: { + ogg_int64_t actual; + if (file->size >= offset) + actual = offset; + else + actual = file->size; + + file->pointer = actual; + break; + } + case SEEK_CUR: { + int left = file->size - (int)file->pointer; + + ogg_int64_t actual; + if (offset < left) + actual = offset; + else + actual = left; + + file->pointer += actual; + break; + } + case SEEK_END: { + file->pointer = file->size + 1; + break; + } + } + + return 0; + } + + int v_close(void* in) { + return 0; + } + + long v_tell(void* in) { + oggFileMem* file = (oggFileMem*)in; + if (file == nullptr) return -1; + + return (long)file->pointer; + } +#pragma endregion + Sound::Sound() : m_constructed(false), m_volume(1.0f), @@ -26,27 +101,85 @@ namespace nf { if ((sound = dynamic_cast(soundAsset)) == nullptr) Error("Non-sound asset passed to Sound::create!"); std::string data(sound->data, sound->size); - if (data.find("RIFF") == std::string::npos) + + size_t dataSize; + if (data.find("OggS") == 0) + dataSize = loadOGG(data); + else if (data.find("RIFF") == 0) + dataSize = loadWAV(data); + else Error("Sound asset not of correct format!"); - unsigned int fileSize = *(unsigned int*)&data[4]; - size_t fmtPos; - if ((fmtPos = data.find("fmt")) == std::string::npos) - Error("Sound asset not of correct format!"); - std::memcpy(&m_format, &data[fmtPos + 8], 16); - size_t dataPos; - if ((dataPos = data.find("data")) == std::string::npos) - Error("Sound asset not of correct m_format!"); - unsigned int dataSize = *(unsigned int*)&data[dataPos + 4]; - m_buffer = new unsigned char[dataSize]; - std::memcpy(m_buffer, &data[dataPos + 8], dataSize); - m_xBuffer.pAudioData = m_buffer; - m_xBuffer.AudioBytes = dataSize; + + m_xBuffer.pAudioData = (unsigned char*)m_buffer; + m_xBuffer.AudioBytes = (unsigned int)dataSize; m_xBuffer.Flags = XAUDIO2_END_OF_STREAM; if (!Application::getApp()->getCurrentState()->isRunning()) Application::getApp()->getCurrentState()->m_nfObjects.push_back(this); } + size_t Sound::loadOGG(std::string& data) { + m_format.Format.cbSize = sizeof(m_format.Format); + size_t pos = data.find("vorbis") + 10; + m_format.Format.nChannels = data[pos]; + m_format.Format.wBitsPerSample = 16; + pos++; + m_format.Format.nSamplesPerSec = *(unsigned int*)&data[pos]; + m_format.Format.nAvgBytesPerSec = m_format.Format.nSamplesPerSec * m_format.Format.nChannels * 2; + m_format.Format.nBlockAlign = m_format.Format.nChannels * 2; + m_format.Format.wFormatTag = 1; + + OggVorbis_File file; + oggFileMem memFile; + memFile.pointer = 0; + memFile.size = (int)data.size(); + memFile.data = &data[0]; + + ov_callbacks callbacks; + callbacks.read_func = v_read; + callbacks.seek_func = v_seek; + callbacks.close_func = v_close; + callbacks.tell_func = v_tell; + + int open = ov_open_callbacks(&memFile, &file, nullptr, 0, callbacks); + char* buff = new char[65536 * 1000]; + + int stream = 0; + int read = 1; + size_t size = 0; + + while (read) { + read = ov_read(&file, buff + size, 4096, 0, 2, 1, &stream); + size += read; + } + + ov_clear(&file); + + m_buffer = new char[size]; + for (unsigned int i = 0; i < size; i++) + m_buffer[i] = buff[i]; + + delete[] buff; + + return size; + } + + size_t Sound::loadWAV(std::string& data) { + unsigned int fileSize = *(unsigned int*)&data[4]; + size_t fmtPos; + if ((fmtPos = data.find("fmt")) == std::string::npos) + Error("WAV not of correct format!"); + std::memcpy(&m_format, &data[fmtPos + 8], 16); + size_t dataPos; + if ((dataPos = data.find("data")) == std::string::npos) + Error("WAV not of correct m_format!"); + unsigned int dataSize = *(unsigned int*)&data[dataPos + 4]; + m_buffer = new char[dataSize]; + std::memcpy(m_buffer, &data[dataPos + 8], dataSize); + + return dataSize; + } + void Sound::setVolume(double volume) { m_volume = (float)volume; } diff --git a/NothinFancy/src/Renderer/Renderer.cpp b/NothinFancy/src/Renderer/Renderer.cpp index d3a4ee2..7667a74 100644 --- a/NothinFancy/src/Renderer/Renderer.cpp +++ b/NothinFancy/src/Renderer/Renderer.cpp @@ -95,6 +95,7 @@ namespace nf { pixels[i * 4 + 2] = tex[i * 4 + 0]; pixels[i * 4 + 3] = tex[i * 4 + 3]; } + stbi_image_free(tex); HICON windowIcon = CreateIcon(GetModuleHandle(NULL), width, height, 1, 32, NULL, &pixels[0]); SendMessage(m_app->getWindow(), WM_SETICON, ICON_BIG, (LPARAM)windowIcon); SendMessage(m_app->getWindow(), WM_SETICON, ICON_SMALL, (LPARAM)windowIcon); diff --git a/NothinFancy/src/Renderer/Shader.cpp b/NothinFancy/src/Renderer/Shader.cpp index 8512c59..1b95b80 100644 --- a/NothinFancy/src/Renderer/Shader.cpp +++ b/NothinFancy/src/Renderer/Shader.cpp @@ -114,5 +114,6 @@ namespace nf { Shader::~Shader() { glDeleteProgram(m_id); + m_uniformLocations.clear(); } } \ No newline at end of file diff --git a/NothinFancy/src/Utility.cpp b/NothinFancy/src/Utility.cpp index 95b3df5..6c07137 100644 --- a/NothinFancy/src/Utility.cpp +++ b/NothinFancy/src/Utility.cpp @@ -56,18 +56,24 @@ namespace nf { } #endif - const wchar_t* toWide(const char* in) { + const std::wstring toWide(const char* in) { unsigned int length = (unsigned int)std::strlen(in) + 1; wchar_t* out = new wchar_t[length]; MultiByteToWideChar(CP_ACP, NULL, in, -1, out, length); - return out; + std::wstring str(out, length); + + delete[] out; + return str; } - const wchar_t* toWide(const std::string& in) { + const std::wstring toWide(const std::string& in) { const char* cstr = in.c_str(); unsigned int length = (unsigned int)std::strlen(cstr) + 1; wchar_t* out = new wchar_t[length]; MultiByteToWideChar(CP_ACP, NULL, cstr, -1, out, length); - return out; + std::wstring str(out, length); + + delete[] out; + return str; } void writeFile(const std::string& filename, const std::string& in, bool encrypted) { diff --git a/NothinFancy/src/include/Application.h b/NothinFancy/src/include/Application.h index 3fa5200..4c33463 100644 --- a/NothinFancy/src/include/Application.h +++ b/NothinFancy/src/include/Application.h @@ -38,7 +38,7 @@ namespace nf { void trackMouse(bool track); void getMouseDiff(int& x, int& y); Vec2 getMousePos(); - static Application* getApp(); + static Application* getApp(bool first = false); void quit(); ~Application(); @@ -76,7 +76,6 @@ namespace nf { //Inactive states to potentially be active during the Application's lifetime //Mapped to const char* to be referenced later in the frontend std::unordered_map m_states; - Gamestate* m_sIntro; std::string m_defaultState; bool m_defaultStateAdded; Gamestate* m_currentState; diff --git a/NothinFancy/src/include/AudioEngine.h b/NothinFancy/src/include/AudioEngine.h index a273dec..575de6c 100644 --- a/NothinFancy/src/include/AudioEngine.h +++ b/NothinFancy/src/include/AudioEngine.h @@ -36,8 +36,6 @@ namespace nf { void stopAllSounds(); ~AudioEngine(); private: - void clearSounds(); - Application* m_app; IXAudio2* m_engine; IXAudio2MasteringVoice* m_masterVoice; diff --git a/NothinFancy/src/include/Sound.h b/NothinFancy/src/include/Sound.h index 77dd030..b0e59ca 100644 --- a/NothinFancy/src/include/Sound.h +++ b/NothinFancy/src/include/Sound.h @@ -21,13 +21,16 @@ namespace nf { void destroy() override; ~Sound(); private: + size_t loadOGG(std::string& data); + size_t loadWAV(std::string& data); + bool m_constructed; float m_volume; bool m_usePos; bool m_useEntity; WAVEFORMATEXTENSIBLE m_format; XAUDIO2_BUFFER m_xBuffer; - unsigned char* m_buffer; + char* m_buffer; Entity* m_targetEntity; Vec3 m_soundPos; }; diff --git a/NothinFancy/src/include/Utility.h b/NothinFancy/src/include/Utility.h index 5e09b36..e554dfb 100644 --- a/NothinFancy/src/include/Utility.h +++ b/NothinFancy/src/include/Utility.h @@ -36,7 +36,7 @@ __debugbreak();} #define DEBUGINIT #define Log(x) //Shows error dialog with specified message then exits -#define Error(x) {MessageBox(FindWindow(L"NFClass", NULL), toWide(x), L"NF Engine Error", MB_OK | MB_ICONERROR);\ +#define Error(x) {MessageBox(FindWindow(L"NFClass", NULL), toWide(x).data(), L"NF Engine Error", MB_OK | MB_ICONERROR);\ std::exit(-1);} #endif struct Vec2 { @@ -86,8 +86,8 @@ std::exit(-1);} double x, y, z; }; - const wchar_t* toWide(const char* in); - const wchar_t* toWide(const std::string& in); + const std::wstring toWide(const char* in); + const std::wstring toWide(const std::string& in); void writeFile(const std::string& filename, const std::string& in, bool encrypted = false); std::string readFile(const std::string& filename, bool compressed = false); } \ No newline at end of file