From 33d11a733c3001dd08356cf6acba17f8194b456a Mon Sep 17 00:00:00 2001 From: nkorslund Date: Sun, 20 Jul 2008 21:31:01 +0000 Subject: [PATCH] More music changes, Makefile updates, minor changes git-svn-id: https://openmw.svn.sourceforge.net/svnroot/openmw/trunk@31 ea6a568a-9f4f-0410-981a-c910a81bb256 --- Makefile | 69 +++++++++++++++++++------------------------ README.txt | 17 +++++++++-- bored.d | 6 ++++ core/resource.d | 1 + dsss.conf | 2 +- esm/loaddial.d | 2 -- esm/loadinfo.d | 27 +++++++++++------ openmw.d | 30 ++++--------------- scene/soundlist.d | 7 +++++ sound/cpp_avcodec.cpp | 62 +++++++++++++++++++------------------- sound/music.d | 16 ++++++++-- 11 files changed, 129 insertions(+), 110 deletions(-) diff --git a/Makefile b/Makefile index 063974364..d9043d1a8 100644 --- a/Makefile +++ b/Makefile @@ -6,13 +6,15 @@ CXXFLAGS?= -Wall -g DMD=gdmd -version=Posix # Some extra flags for niftool and bsatool -NIFFLAGS= +NIFFLAGS=-debug=warnstd -debug=check -debug=statecheck -debug=strict -debug=verbose # Compiler settings for Ogre + OIS. Change as needed. -OGCC=$(CXX) $(CXXFLAGS) `pkg-config --cflags OGRE OIS` +CF_OIS=$(shell pkg-config --cflags OGRE OIS) +OGCC=$(CXX) $(CXXFLAGS) $(CF_OIS) # Compiler settings for ffmpeg. Change as needed. -AVGCC=$(CXX) $(CXXFLAGS) `pkg-config --cflags libavcodec libavformat` +CF_FFMPEG=$(shell pkg-config --cflags libavcodec libavformat) +AVGCC=$(CXX) $(CXXFLAGS) $(CF_FFMPEG) # Ogre C++ files, on the form ogre/cpp_X.cpp. Only the first file is # passed to the compiler, the rest are dependencies. @@ -22,25 +24,31 @@ ogre_cpp=ogre framelistener interface overlay bsaarchive # passed to the compiler, the rest are dependencies. avcodec_cpp=avcodec -## The rest of this file is automatic ## +## No modifications should be required below this line. ## ogre_cpp_files=$(ogre_cpp:%=ogre/cpp_%.cpp) avcodec_cpp_files=$(avcodec_cpp:%=sound/cpp_%.cpp) -d_files=$(wildcard */*.d) $(wildcard monster/util/*.d) -d_files_nif=$(wildcard nif/*.d) $(wildcard util/*.d) $(wildcard core/memory.d) $(wildcard monster/util/*.d) +# All object files needed by openmw and esmtool +src := $(wildcard */*.d) +src := $(src) $(wildcard monster/util/*.d) +obj := $(src:%.d=objs/%.o) # The NIF object files for niftool and bsatool are put in a separate # directory, since they are built with different flags. -d_objs=$(d_files:%.d=objs/%.o) -d_objs_nif=$(d_files_nif:%.d=nifobjs/%.o) +src_nif := $(wildcard nif/*.d) +src_nif := $(src_nif) $(wildcard util/*.d) +src_nif := $(src_nif) core/memory.d +src_nif := $(src_nif) $(wildcard monster/util/*.d) +obj_nif := $(src_nif:%.d=nifobjs/%.o) -.PHONY: cpp all clean makedirs +.PHONY: cpp all clean -# By default, make will only build the Ogre C++ sources. -cpp: cpp_ogre.o cpp_avcodec.o +# Build everything. Default when running 'make' directly. +all: openmw esmtool niftool bsatool bored -all: makedirs openmw esmtool niftool bsatool bored +# Only build C++ sources. Used when building from DSSS. +cpp: cpp_ogre.o cpp_avcodec.o cpp_ogre.o: $(ogre_cpp_files) $(OGCC) -c $< @@ -48,41 +56,24 @@ cpp_ogre.o: $(ogre_cpp_files) cpp_avcodec.o: $(avcodec_cpp_files) $(AVGCC) -c $< -objs/%.o: %.d makedirs +objs/%.o: %.d + dirname $@ | xargs mkdir -p $(DMD) -c $< -of$@ -nifobjs/%.o: %.d makedirs - $(DMD) -debug=warnstd -debug=check -debug=statecheck -debug=strict -debug=verbose -c $< -of$@ - -# This is a hack for gdmd (dmd-like frontend to gdc), since it does -# not automatically create directories as it should. -makedirs: - mkdir -p objs/bsa - mkdir -p objs/core - mkdir -p objs/esm - mkdir -p objs/input - mkdir -p objs/monster/util - mkdir -p objs/nif - mkdir -p objs/ogre - mkdir -p objs/scene - mkdir -p objs/sound - mkdir -p objs/util - mkdir -p nifobjs/nif - mkdir -p nifobjs/util - mkdir -p nifobjs/core - mkdir -p nifobjs/monster/util - mkdir -p nifobjs/bsa - -openmw: openmw.d cpp_ogre.o cpp_avcodec.o $(d_objs) +nifobjs/%.o: %.d + dirname $@ | xargs mkdir -p + $(DMD) $(NIFFLAGS) -c $< -of$@ + +openmw: openmw.d cpp_ogre.o cpp_avcodec.o $(obj) $(DMD) $^ -of$@ -L-lopenal -L-lOgreMain -L-lOIS -L-lavcodec -L-lavformat -esmtool: esmtool.d cpp_ogre.o cpp_avcodec.o $(d_objs) +esmtool: esmtool.d cpp_ogre.o cpp_avcodec.o $(obj) $(DMD) $^ -of$@ -L-lopenal -L-lOgreMain -L-lOIS -L-lavcodec -L-lavformat -niftool: niftool.d $(d_objs_nif) +niftool: niftool.d $(obj_nif) $(DMD) $^ -of$@ -bsatool: bsatool.d $(d_objs_nif) bsa/bsafile.d +bsatool: bsatool.d $(obj_nif) objs/bsa/bsafile.o $(DMD) $^ -of$@ bored: bored.d diff --git a/README.txt b/README.txt index 995282b5e..fbaaea97e 100644 --- a/README.txt +++ b/README.txt @@ -6,7 +6,7 @@ Email: korslund@gmail.com WWW: http://openmw.snaptoad.com License: See GPL3.txt Current version: 0.4 (still very pre-alpha) -Date: 2008 jul. 12 +Date: 2008 jul. 20 @@ -115,17 +115,26 @@ Thanks goes out to: - Chris Robinson for OpenAL and MP3 support +- Various others for testing, ideas and patches + + Changelog: ========== -0.4 (Work in progress) +0.4 (2008 jul. 20) - work in progress + - switched from Audiere to OpenAL (BIG thanks to Chris Robinson) - added complete Makefile (again) as a alternative build tool +- much more realistic lighting (thanks again to Chris Robinson) +- should work with Russian version +- various bug-fixes - cosmetic changes to placate gdc -Wall + 0.3 (2008 jul. 10) - latest release + - built and tested on Windows XP - partial support for FreeBSD (exceptions do not work) - temporarily dropped DSSS and Monster as necessary dependencies @@ -138,10 +147,14 @@ Changelog: Dmitry Marakasov.) - tested against OIS 1.0.0 (Ubuntu repository package) + 0.2 (2008 jun. 17) + - compiles with gdc - switched to DSSS for building D code - includes the program esmtool + 0.1 (2008 jun. 03) + - first release diff --git a/bored.d b/bored.d index fbf8573b8..e11346754 100644 --- a/bored.d +++ b/bored.d @@ -110,6 +110,12 @@ those plugins."); play=false; break; } + if(rnd() < 0.02) + { + writefln("You were eaten by a grue."); + play=false; + break; + } switch(rand(0,15)) { case 0: str = "Fjol the Outlaw"; goldinc = rand(0,70); lootinc = rand(10,120); break; diff --git a/core/resource.d b/core/resource.d index e859857d2..5132698a3 100644 --- a/core/resource.d +++ b/core/resource.d @@ -192,6 +192,7 @@ struct ResourceManager // Copy name and insert. We MUST copy here, since indices during // load are put in a temporary buffer, and thus overwritten. si.name = esmRegion.copyz(id); + assert(si.name == id); soundLookup[si.name] = si; return si; diff --git a/dsss.conf b/dsss.conf index bdf93a9e7..db6c03a9a 100644 --- a/dsss.conf +++ b/dsss.conf @@ -11,7 +11,7 @@ version(Windows) { prebuild = warn Not designed for Windows yet. } version(Posix) { - prebuild = make ; + prebuild = make cpp; } # Make sure we recompile the nif files without the debug output prebuild += dsss clean niftool diff --git a/esm/loaddial.d b/esm/loaddial.d index 3c7e7cddb..6e36f0b88 100644 --- a/esm/loaddial.d +++ b/esm/loaddial.d @@ -180,8 +180,6 @@ struct Dialogue }} } -// TODO/FIXME: HACK suddenly needed with version 0.167 :( -// Haven't re-tested it with non-ancient compiler typedef Dialogue.Type DialogueType; /+ diff --git a/esm/loadinfo.d b/esm/loadinfo.d index 58ef857b9..9a8bd74b6 100644 --- a/esm/loadinfo.d +++ b/esm/loadinfo.d @@ -187,17 +187,26 @@ struct DialInfo deleted = false; questStatus = Quest.None; - // Figure out how we check the owner's type - if(tp == Dialogue.Type.Journal) - { - if(subName == "QSTN") questStatus = Quest.Name; - else if(subName == "QSTF") questStatus = Quest.Finished; - else if(subName == "QSTR") questStatus = Quest.Restart; + if(subName == "QSTN") questStatus = Quest.Name; + else if(subName == "QSTF") questStatus = Quest.Finished; + else if(subName == "QSTR") questStatus = Quest.Restart; + else if(subName == "DELE") {getHInt(); deleted = true;} + else + fail("Don't know what to do with " ~ subName ~ " in INFO " ~ id); - if(questStatus != Quest.None) getHByte(); + if(questStatus != Quest.None) + { + getHByte(); + // The Quest markers should only appear in journal INFOs, but + // sometime the appear outside it. We could issue a warning, + // but lets just ignore it instead. + + /* + if(tp != Dialogue.Type.Journal) + writefln("WARNING: Found INFO quest marker in INFO %s type %s", + id, cast(int)tp); + */ } - else if(subName == "DELE") {getHInt(); deleted = true;} - else fail("Don't know what to do with " ~ subName ~ " here."); }} } diff --git a/openmw.d b/openmw.d index a14bb4523..2275a4268 100644 --- a/openmw.d +++ b/openmw.d @@ -201,26 +201,6 @@ void main(char[][] args) return null; } - /* - Sound *l = cast(Sound*) sounds.lookup("Fire 40"); - if(l) - { - writefln("id: %s", l.id); - writefln("volume: ", l.data.volume); - writefln("range: %s-%s", l.data.minRange, l.data.maxRange); - writefln("sound file name: ", l.sound.getName); - writefln("playing... press enter to quit"); - - SoundInstance inst = SoundList.getInstance(l, true); - inst.setPos(0,0,0); - inst.setPlayerPos(0, 0, 0); - inst.play(); - din.readLine(); - inst.kill; - render = false; - } - */ - if(render) { // Warm up OGRE @@ -287,11 +267,11 @@ void main(char[][] args) if(s) { writefln("Static light %s has sound %s", ls.m.id, s.id); - ls.loopSound = soundScene.insert(s, true); - if(ls.loopSound) - ls.loopSound.setPos(ls.base.pos.position[0], - ls.base.pos.position[1], - ls.base.pos.position[2]); + ls.loopSound = soundScene.insert(s, true); + if(ls.loopSound) + ls.loopSound.setPos(ls.base.pos.position[0], + ls.base.pos.position[1], + ls.base.pos.position[2]); } } // Misc items diff --git a/scene/soundlist.d b/scene/soundlist.d index ad45526ef..8917c6bab 100644 --- a/scene/soundlist.d +++ b/scene/soundlist.d @@ -44,6 +44,8 @@ struct SoundList { const distFactor = 40.0; // Just guessing, really. + assert(!s.sound.isEmpty()); + SoundInstance inst = s.sound.getInstance(); inst.setParams(s.data.volume/255.0, s.data.minRange*distFactor, @@ -54,6 +56,11 @@ struct SoundList SoundInstance *insert(Sound *snd, bool loop=false) { + // For some reason, we get called with empty sound instances here + // if some files are missing, but not for others. Check into it + // later. + if(snd.sound.isEmpty) return null; + // Reuse a dead instance if one exists foreach(ref s; list) { diff --git a/sound/cpp_avcodec.cpp b/sound/cpp_avcodec.cpp index 305fc9573..4973a4359 100644 --- a/sound/cpp_avcodec.cpp +++ b/sound/cpp_avcodec.cpp @@ -128,7 +128,7 @@ extern "C" int cpp_getAVAudioInfo(MyFile::MyStream *stream, return 0; } -static int getNextPacket(MyFile *file) +static void getNextPacket(MyFile *file, int streamidx) { AVPacket packet; while(av_read_frame(file->FmtCtx, &packet) >= 0) @@ -141,14 +141,16 @@ static int getNextPacket(MyFile *file) size_t idx = (*i)->Data.size(); (*i)->Data.resize(idx + packet.size); memcpy(&(*i)->Data[idx], packet.data, packet.size); - av_free_packet(&packet); - return 0; + if(streamidx == packet.stream_index) + { + av_free_packet(&packet); + return; + } + break; } } av_free_packet(&packet); } - - return 1; } extern "C" int cpp_getAVAudioData(MyFile::MyStream *stream, char *data, int length) @@ -158,14 +160,25 @@ extern "C" int cpp_getAVAudioData(MyFile::MyStream *stream, char *data, int leng int dec = 0; while(dec < length) { + if(stream->DecodedData.size() > 0) + { + size_t rem = length-dec; + if(rem > stream->DecodedData.size()) + rem = stream->DecodedData.size(); + + memcpy(data, &stream->DecodedData[0], rem); + data += rem; + dec += rem; + if(rem < stream->DecodedData.size()) + memmove(&stream->DecodedData[0], &stream->DecodedData[rem], + stream->DecodedData.size() - rem); + stream->DecodedData.resize(stream->DecodedData.size()-rem); + } if(stream->DecodedData.size() == 0) { - while(stream->Data.size() == 0) - { - if(getNextPacket(stream->parent) != 0) - break; - } - + // Must always get at least one more packet if possible, in case + // the previous one wasn't enough + getNextPacket(stream->parent, stream->StreamNum); int insize = stream->Data.size(); if(insize == 0) break; @@ -174,6 +187,7 @@ extern "C" int cpp_getAVAudioData(MyFile::MyStream *stream, char *data, int leng // codecs read in larger chunks and may accidently read // past the end of the allocated buffer stream->Data.resize(insize + FF_INPUT_BUFFER_PADDING_SIZE); + memset(&stream->Data[insize], 0, FF_INPUT_BUFFER_PADDING_SIZE); stream->DecodedData.resize(AVCODEC_MAX_AUDIO_FRAME_SIZE); int16_t *ptr = (int16_t*)&stream->DecodedData[0]; @@ -185,28 +199,16 @@ extern "C" int cpp_getAVAudioData(MyFile::MyStream *stream, char *data, int leng stream->Data.resize(insize); break; } - - int datarem = insize-len; - if(datarem) - memmove(&stream->Data[0], &stream->Data[len], datarem); - stream->Data.resize(datarem); + if(len > 0) + { + int datarem = insize-len; + if(datarem) + memmove(&stream->Data[0], &stream->Data[len], datarem); + stream->Data.resize(datarem); + } stream->DecodedData.resize(size); - if(stream->DecodedData.size() == 0) - break; } - - size_t rem = length-dec; - if(rem > stream->DecodedData.size()) - rem = stream->DecodedData.size(); - - memcpy(data, &stream->DecodedData[0], rem); - data += rem; - dec += rem; - if(rem < stream->DecodedData.size()) - memmove(&stream->DecodedData[0], &stream->DecodedData[rem], - stream->DecodedData.size() - rem); - stream->DecodedData.resize(stream->DecodedData.size()-rem); } return dec; } diff --git a/sound/music.d b/sound/music.d index 3a978c8cb..806a2286d 100644 --- a/sound/music.d +++ b/sound/music.d @@ -183,6 +183,8 @@ struct MusicManager // If something fails, clean everything up. scope(failure) { + // This block is only executed if an exception is thrown. + if(fileHandle) cpp_closeAVFile(fileHandle); fileHandle = null; @@ -199,6 +201,8 @@ struct MusicManager // Try the next track if playNext is called again index++; + + // The function exits here. } if(checkALError()) @@ -222,13 +226,21 @@ struct MusicManager { if(ch == 1) bufFormat = AL_FORMAT_MONO8; if(ch == 2) bufFormat = AL_FORMAT_STEREO8; - if(ch == 4) bufFormat = alGetEnumValue("AL_FORMAT_QUAD8"); + if(alIsExtensionPresent("AL_EXT_MCFORMATS")) + { + if(ch == 4) bufFormat = alGetEnumValue("AL_FORMAT_QUAD8"); + if(ch == 6) bufFormat = alGetEnumValue("AL_FORMAT_51CHN8"); + } } if(bits == 16) { if(ch == 1) bufFormat = AL_FORMAT_MONO16; if(ch == 2) bufFormat = AL_FORMAT_STEREO16; - if(ch == 4) bufFormat = alGetEnumValue("AL_FORMAT_QUAD16"); + if(alIsExtensionPresent("AL_EXT_MCFORMATS")) + { + if(ch == 4) bufFormat = alGetEnumValue("AL_FORMAT_QUAD16"); + if(ch == 6) bufFormat = alGetEnumValue("AL_FORMAT_51CHN16"); + } } if(bufFormat == 0)