Project::OSiRiON - Git repositories
Project::OSiRiON
News . About . Screenshots . Downloads . Forum . Wiki . Tracker . Git
summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorStijn Buys <ingar@osirion.org>2008-05-18 09:21:20 +0000
committerStijn Buys <ingar@osirion.org>2008-05-18 09:21:20 +0000
commit4a2bad92171ff8a9a248599f47087cfe39e93653 (patch)
treeb8a4fe7f616b3e4f707d89a35fff5e8b5fdcfcc8 /src
parenta185c11f2397c0296a4b62cc266b4fa00a63c1e2 (diff)
OpenAL support
Diffstat (limited to 'src')
-rw-r--r--src/Makefile.am23
-rw-r--r--src/audio/Makefile.am6
-rw-r--r--src/audio/audio.cc80
-rw-r--r--src/audio/audio.h28
-rw-r--r--src/audio/buffers.cc112
-rw-r--r--src/audio/buffers.h47
-rw-r--r--src/audio/pcm.cc49
-rw-r--r--src/audio/pcm.h57
-rw-r--r--src/audio/wav.cc119
-rw-r--r--src/audio/wav.h22
-rw-r--r--src/client/client.cc39
-rw-r--r--src/client/client.h25
-rw-r--r--src/client/console.cc4
-rw-r--r--src/client/console.h2
-rw-r--r--src/client/view.cc6
-rw-r--r--src/core/application.cc11
-rw-r--r--src/core/application.h8
-rw-r--r--src/core/gameserver.cc25
-rw-r--r--src/core/netconnection.cc5
-rw-r--r--src/model/map.cc2
-rw-r--r--src/render/image.h18
21 files changed, 627 insertions, 61 deletions
diff --git a/src/Makefile.am b/src/Makefile.am
index 81bd629..6ad49f8 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -4,7 +4,8 @@ SUFFIXES = .rc
.rc.o:
windres $< -o $@
-SUBDIRS = auxiliary sys math filesystem model core server render client game
+SUBDIRS = sys math auxiliary filesystem core model server audio render client \
+ game
noinst_HEADERS = config.h
bin_PROGRAMS = osiriond osirion
@@ -24,17 +25,19 @@ osiriond_LDADD = $(top_builddir)/src/auxiliary/libauxiliary.la \
# client
osirion_SOURCES = osirion.cc
EXTRA_osirion_SOURCES = osirion-res.rc
-osirion_DEPENDENCIES = $(ICON_CLIENT) $(top_builddir)/src/client/libclient.la \
+osirion_DEPENDENCIES = $(ICON_CLIENT) \
+ $(top_builddir)/src/auxiliary/libauxiliary.la $(top_builddir)/src/client/libclient.la \
$(top_builddir)/src/core/libcore.la $(top_builddir)/src/filesystem/libfilesystem.la \
$(top_builddir)/src/game/libgame.la $(top_builddir)/src/math/libmath.la \
- $(top_builddir)/src/model/libmodel.la $(top_builddir)/src/render/librender.la \
- $(top_builddir)/src/sys/libsys.la $(top_builddir)/src/auxiliary/libauxiliary.la
+ $(top_builddir)/src/model/libmodel.la $(top_builddir)/src/audio/libaudio.la \
+ $(top_builddir)/src/render/librender.la $(top_builddir)/src/sys/libsys.la
osirion_CFLAGS = $(LIBSDL_CFLAGS) $(GL_CFLAGS) $(GLUT_CFLAGS)
-osirion_LDADD = $(top_builddir)/src/client/libclient.la \
- $(top_builddir)/src/core/libcore.la $(top_builddir)/src/game/libgame.la $(top_builddir)/src/math/libmath.la \
- $(top_builddir)/src/model/libmodel.la $(top_builddir)/src/render/librender.la \
- $(top_builddir)/src/filesystem/libfilesystem.la $(top_builddir)/src/sys/libsys.la \
- $(top_builddir)/src/auxiliary/libauxiliary.la
+osirion_LDADD = $(top_builddir)/src/game/libgame.la \
+ $(top_builddir)/src/client/libclient.la $(top_builddir)/src/audio/libaudio.la \
+ $(top_builddir)/src/render/librender.la $(top_builddir)/src/core/libcore.la \
+ $(top_builddir)/src/filesystem/libfilesystem.la $(top_builddir)/src/model/libmodel.la \
+ $(top_builddir)/src/math/libmath.la $(top_builddir)/src/auxiliary/libauxiliary.la \
+ $(top_builddir)/src/sys/libsys.la
$(top_builddir)/src/filesystem/libfilesystem.la $(top_builddir)/src/sys/libsys.la \
$(top_builddir)/src/auxiliary/libauxiliary.la $(GL_LIBS) $(HOST_LIBS) $(ICON_CLIENT)
-osirion_LDFLAGS = $(LIBSDL_LIBS)
+osirion_LDFLAGS = $(LIBSDL_LIBS) $(GL_LIBS) $(AL_LIBS)
diff --git a/src/audio/Makefile.am b/src/audio/Makefile.am
new file mode 100644
index 0000000..d1524cf
--- /dev/null
+++ b/src/audio/Makefile.am
@@ -0,0 +1,6 @@
+INCLUDES = -I$(top_srcdir)/src
+METASOURCES = AUTO
+noinst_LTLIBRARIES = libaudio.la
+libaudio_la_LDFLAGS = -avoid-version -no-undefined
+noinst_HEADERS = audio.h buffers.h pcm.h wav.h
+libaudio_la_SOURCES = audio.cc buffers.cc pcm.cc wav.cc
diff --git a/src/audio/audio.cc b/src/audio/audio.cc
new file mode 100644
index 0000000..063a079
--- /dev/null
+++ b/src/audio/audio.cc
@@ -0,0 +1,80 @@
+/*
+ audio/audio.cc
+ This file is part of the Osirion project and is distributed under
+ the terms of the GNU General Public License version 2
+*/
+
+#include "AL/al.h"
+#include "AL/alc.h"
+
+#include "audio/audio.h"
+#include "audio/buffers.h"
+#include "audio/pcm.h"
+#include "sys/sys.h"
+
+namespace audio
+{
+
+ALCdevice *audio_device = 0;
+ALCcontext *audio_context = 0;
+
+ALuint source = 0;
+
+void init()
+{
+ con_print << "^BInitializing audio...";
+
+ // open the default audio device
+ audio_device = alcOpenDevice(0);
+
+ if (!audio_device) {
+ con_warn << "Could not initialize audio!";
+ return;
+ }
+
+ // create the audio context
+ audio_context = alcCreateContext(audio_device ,0);
+ alcMakeContextCurrent(audio_context);
+
+ // clear errors
+ alGetError();
+
+ Buffers::init();
+
+ //con_debug << " device ^B" << alcGetString(audio_device, ALC_DEFAULT_DEVICE_SPECIFIER) << std::endl;
+ load("ui/chat");
+
+ // default sound source
+ alGenSources(1, &source);
+}
+
+void load (const char *name)
+{
+ Buffers::load(std::string(name));
+}
+
+void shutdown()
+{
+ con_print << "^BShutting down audio...";
+
+ if (audio_context) {
+ alcMakeContextCurrent(0);
+ alcDestroyContext(audio_context);
+ audio_context = 0;
+ }
+
+ if (audio_device) {
+ alcCloseDevice(audio_device);
+ audio_device = 0;
+ }
+
+ alDeleteSources(1, &source);
+}
+
+void play(const char *name)
+{
+ Buffers::bind(source, std::string(name));
+ alSourcePlay(source);
+}
+
+}
diff --git a/src/audio/audio.h b/src/audio/audio.h
new file mode 100644
index 0000000..92b8786
--- /dev/null
+++ b/src/audio/audio.h
@@ -0,0 +1,28 @@
+/*
+ audio/audio.h
+ This file is part of the Osirion project and is distributed under
+ the terms of the GNU General Public License version 2
+*/
+
+#ifndef __INCLUDED_AUDIO_AUDIO_H__
+#define __INCLUDED_AUDIO_AUDIO_H__
+
+/// functions to handle audio
+namespace audio
+{
+
+/// initialize the audio subsystem
+void init();
+
+/// shut down the audio subsystem
+void shutdown();
+
+/// load an audio sample
+void load(const char *name);
+
+/// play a previously loaded audio sample
+void play(const char *name);
+
+}
+
+#endif // __INCLUDED_AUDIO_AUDIO_H__
diff --git a/src/audio/buffers.cc b/src/audio/buffers.cc
new file mode 100644
index 0000000..9223380
--- /dev/null
+++ b/src/audio/buffers.cc
@@ -0,0 +1,112 @@
+/*
+ audio/buffers.h
+ This file is part of the Osirion project and is distributed under
+ the terms of the GNU General Public License version 2
+*/
+
+#include "audio/buffers.h"
+#include "audio/pcm.h"
+#include "audio/wav.h"
+#include "sys/sys.h"
+
+namespace audio {
+
+std::map<std::string, size_t> Buffers::registry;
+size_t Buffers::index;
+ALuint Buffers::buffers[MAXBUFFERS];
+
+void Buffers::init()
+{
+ int error;
+ clear();
+
+ alGenBuffers(MAXBUFFERS, buffers);
+
+ if ((error = alGetError()) != AL_NO_ERROR) {
+ con_warn << "Error " << error << " initializing OpenAL bufers!" << std::endl;
+ return;
+ }
+}
+
+void Buffers::shutdown()
+{
+ alDeleteBuffers(MAXBUFFERS, buffers);
+
+ clear();
+}
+
+void Buffers::clear()
+{
+ registry.clear();
+ memset(buffers,0, sizeof(buffers));
+ index = 0;
+}
+
+size_t Buffers::load(std::string name)
+{
+ // check if it is already loaded
+ iterator it = registry.find(name);
+ if (it != registry.end())
+ return (*it).second;
+
+ // load wav file
+ PCM *pcm = Wav::load(name);
+ if (!pcm) {
+ registry[name] = 0;
+ return 0;
+ }
+
+ if (index == MAXBUFFERS) {
+ con_error << "Buffer limit " << MAXBUFFERS << " exceeded!" << std::endl;
+ delete pcm;
+ registry[name] = 0;
+ return 0;
+ }
+
+ ALenum format = 0;
+ if (pcm->bitspersample() == 16) {
+ if (pcm->channels() == 1) {
+ format = AL_FORMAT_MONO16;
+ } else if (pcm->channels() == 2) {
+ format = AL_FORMAT_STEREO16;
+ };
+ } else if (pcm->bitspersample() == 8) {
+ if (pcm->channels() == 1) {
+ format = AL_FORMAT_MONO8;
+ } else if (pcm->channels() == 2) {
+ format = AL_FORMAT_STEREO8;
+ };
+ }
+
+ size_t id = index;
+ alBufferData(buffers[id], format, pcm->data(), pcm->size(), pcm->samplerate());
+ if (alGetError())
+ con_warn << "Error loading PCM data " << name << std::endl;
+
+ registry[name] = id;
+ index++;
+
+ return id;
+}
+
+size_t Buffers::find(std::string name)
+{
+ size_t id = 0;
+ iterator it = registry.find(name);
+ if (it != registry.end())
+ id = (*it).second;
+ return id;
+}
+
+void Buffers::bind(ALuint source, std::string name)
+{
+ int error;
+ size_t id = find(name);
+ alSourcei(source, AL_BUFFER, buffers[id]);
+ if ((error = alGetError()) != AL_NO_ERROR) {
+ con_warn << "Error " << std::hex << error << " binding " << name
+ << " source " << source << " buffer " << buffers[id] << std::endl;
+ }
+}
+
+}
diff --git a/src/audio/buffers.h b/src/audio/buffers.h
new file mode 100644
index 0000000..e61ba7b
--- /dev/null
+++ b/src/audio/buffers.h
@@ -0,0 +1,47 @@
+/*
+ audio/buffers.h
+ This file is part of the Osirion project and is distributed under
+ the terms of the GNU General Public License version 2
+*/
+
+#ifndef __INCLUDED_AUDIO_BUFFERS_H__
+#define __INCLUDED_AUDIO_BUFFERS_H__
+
+#include "AL/al.h"
+#include "AL/alc.h"
+
+#include <string>
+#include <map>
+
+namespace audio {
+
+const size_t MAXBUFFERS = 128;
+
+/// OpenAL buffers wrapper class
+
+class Buffers {
+public:
+ static void init();
+ static void shutdown();
+ static void clear();
+
+ /// find previously loaded PCM data
+ static size_t find(std::string name);
+
+ /// load audio data into a buffer ans return the buffer index
+ static size_t load(std::string name);
+
+ /// bind a buffer to a source
+ static void bind(ALuint source, std::string name);
+
+private:
+ typedef std::map<std::string, size_t>::iterator iterator;
+
+ static std::map<std::string, size_t> registry;
+ static size_t index;
+ static ALuint buffers[MAXBUFFERS];
+};
+
+}
+
+#endif // __INCLUDED_AUDIO_BUFFERS_H__
diff --git a/src/audio/pcm.cc b/src/audio/pcm.cc
new file mode 100644
index 0000000..b485199
--- /dev/null
+++ b/src/audio/pcm.cc
@@ -0,0 +1,49 @@
+/*
+ audio/pcm.cc
+ This file is part of the Osirion project and is distributed under
+ the terms of the GNU General Public License version 2
+*/
+
+#include <stdlib.h>
+#include <string.h>
+
+#include "audio/pcm.h"
+#include "audio/wav.h"
+
+namespace audio {
+
+PCM::PCM(unsigned int samplerate, unsigned int bitspersample, unsigned int channels, size_t size)
+{
+ pcm_bitspersample = bitspersample;
+ pcm_samplerate = samplerate;
+ pcm_size = size;
+ pcm_channels = channels;
+
+ pcm_data = (unsigned char *) malloc(pcm_size);
+ clear();
+}
+
+PCM::~PCM()
+{
+ free(pcm_data);
+}
+
+void PCM::clear()
+{
+ memset(pcm_data, 0, pcm_size);
+}
+
+void PCM::load(const char *name)
+{
+ PCM *pcm = Wav::load(name);
+ if (pcm) {
+ delete pcm;
+ }
+}
+
+void PCM::load(std::string const & name)
+{
+ load(name.c_str());
+}
+
+}
diff --git a/src/audio/pcm.h b/src/audio/pcm.h
new file mode 100644
index 0000000..740a23c
--- /dev/null
+++ b/src/audio/pcm.h
@@ -0,0 +1,57 @@
+/*
+ audio/pcm.h
+ This file is part of the Osirion project and is distributed under
+ the terms of the GNU General Public License version 2
+*/
+
+#ifndef __INCLUDED_AUDIO_PCM_H__
+#define __INCLUDED_AUDIO_PCM_H__
+
+#include <string>
+
+namespace audio {
+
+/// class to hold PCM audio data
+class PCM {
+
+public:
+ PCM(unsigned int samplerate, unsigned int samplesize, unsigned int channels, size_t size);
+ ~PCM();
+
+ void clear();
+
+ /// pointer to the raw pcm data
+ inline unsigned char *data() { return pcm_data; }
+
+ /// index into the raw pcm data
+ inline unsigned char *operator[](size_t index) { return &pcm_data[index]; }
+
+ /// size in bytes
+ inline size_t size() { return pcm_size; }
+
+ /// samplerate in samples per second
+ inline unsigned int samplerate() const { return pcm_samplerate; }
+
+ /// number of bits per sample
+ inline unsigned int bitspersample() const { return pcm_bitspersample; }
+
+ /// number of channels
+ inline unsigned int channels() const { return pcm_channels; }
+
+ /// load PCM audio data from file
+ static void load(std::string const & name);
+
+ static void load(const char *name);
+
+private:
+ unsigned char *pcm_data;
+
+ unsigned int pcm_channels;
+ unsigned int pcm_samplerate;
+ unsigned int pcm_bitspersample;
+ size_t pcm_size;
+};
+
+}
+
+#endif // __INCLUDED_AUDIO_PCM_H__
diff --git a/src/audio/wav.cc b/src/audio/wav.cc
new file mode 100644
index 0000000..5d118c6
--- /dev/null
+++ b/src/audio/wav.cc
@@ -0,0 +1,119 @@
+/*
+ audio/wav.h
+ This file is part of the Osirion project and is distributed under
+ the terms of the GNU General Public License version 2
+*/
+
+/*
+see
+
+http://ccrma.stanford.edu/CCRMA/Courses/422/projects/WaveFormat/
+*/
+
+#include "string.h"
+
+#include <iostream>
+#include <string>
+
+#include "audio/wav.h"
+#include "filesystem/filesystem.h"
+#include "sys/sys.h"
+
+namespace audio {
+
+PCM *Wav::load(std::string const & name)
+{
+ if (!name.size())
+ return 0;
+
+ std::string filename("sounds/");
+ filename.append(name);
+ filename.append(".wav");
+
+ filesystem::File *wav_file = filesystem::open(filename.c_str());
+ if (!wav_file) {
+ con_warn << "Could not open " << filename << std::endl;
+ return 0;
+ }
+
+ unsigned char header[44];
+ memset(header, 0, sizeof(header));
+ if (!wav_file->read(header, 44)) {
+ con_warn << "Error reading " << filename << std::endl;
+ filesystem::close(wav_file);
+ return 0;
+ }
+
+ // header RIFF
+ if (strncmp((char *)header, "RIFF", 4)) {
+ con_warn << "Error reading " << filename << ": invalid RIFF header!" << std::endl;
+ filesystem::close(wav_file);
+ return 0;
+ }
+
+ // format WAVE
+ if (strncmp((char *)header+8, "WAVE", 4) != 0) {
+ con_warn << "Error reading " << filename << ": invalid WAVE header!" << std::endl;
+ filesystem::close(wav_file);
+ return 0;
+ }
+
+ // file size
+ //size_t chunksize = header[4] + (header[5] << 8) + (header[6] << 16) + (header[7] << 24);
+
+ if (strncmp((char *)header+12, "fmt ", 4) != 0) {
+ con_warn << "Error reading " << filename << ": invalid format header!" << std::endl;
+ filesystem::close(wav_file);
+ return 0;
+ }
+
+ size_t subchunksize1 = header[16] + (header[17] << 8) + (header[18] << 16) + (header[19] << 24);
+ size_t audioformat = header[20] + (header[21] << 8);
+
+ if ((subchunksize1 != 16) || (audioformat != 1)) {
+ con_warn << "Error reading " << filename << ": unrecognized file format!" << std::endl;
+ filesystem::close(wav_file);
+ return 0;
+
+ }
+
+ unsigned int channels = header[22] + (header[23] << 8);
+ if ((channels < 1) || (channels >2)) {
+ con_warn << "Error reading " << filename << ": invalid number of channels!" << std::endl;
+ filesystem::close(wav_file);
+ return 0;
+ }
+
+ unsigned int samplerate = header[24] + ((size_t)header[25] << 8) + ((size_t)header[26] << 16) + ((size_t)header[27] << 24);
+ //size_t byterate = header[28] + (header[29] << 8) + (header[30] << 16) + (header[31] << 24);
+ //size_t blockalign = header[32] + (header[33] << 8);
+ size_t bitspersample = header[34] + (header[35] << 8);
+
+ if (strncmp((char *)header + 36, "data", 4) !=0) {
+ con_warn << "Error reading " << filename << ": invalid data header!" << std::endl;
+ filesystem::close(wav_file);
+ return 0;
+ }
+
+ size_t datasize = header[40] + (header[41] << 8) + (header[42] << 16) + (header[43] << 24);
+
+ PCM *pcm = new PCM(samplerate, bitspersample, channels, datasize);
+ const size_t readblocksize = channels * (bitspersample / 8);
+ size_t total_bytes = 0;
+
+ while ((wav_file->read((void *)(*pcm)[total_bytes], readblocksize)) && (total_bytes < datasize)) {
+ total_bytes += readblocksize;
+ }
+
+ if (total_bytes < datasize) {
+ con_warn << "Error reading " << filename << ": file truncated!" << std::endl;
+ }
+
+ con_print << " " << filename << " " << pcm->samplerate()<< "Hz " << pcm->bitspersample() << "bit " <<
+ pcm->channels() << " chan " << pcm->size() << " bytes" << std::endl;
+
+ filesystem::close(wav_file);
+ return pcm;
+}
+
+}
diff --git a/src/audio/wav.h b/src/audio/wav.h
new file mode 100644
index 0000000..a94b6fb
--- /dev/null
+++ b/src/audio/wav.h
@@ -0,0 +1,22 @@
+/*
+ audio/wav.h
+ This file is part of the Osirion project and is distributed under
+ the terms of the GNU General Public License version 2
+*/
+
+#ifndef __INCLUDED_AUDIO_WAV_H__
+#define __INCLUDED_AUDIO_WAV_H__
+
+#include "audio/pcm.h"
+
+namespace audio {
+
+/// class to read microsoft PCM wav files
+class Wav {
+public:
+ static PCM *load(std::string const & name);
+};
+
+}
+
+#endif // __INCLUDED_AUDIO_WAV_H__
diff --git a/src/client/client.cc b/src/client/client.cc
index 85dec27..ed31c65 100644
--- a/src/client/client.cc
+++ b/src/client/client.cc
@@ -10,6 +10,7 @@
#include <cmath>
#include <iomanip>
+#include "audio/audio.h"
#include "client/chat.h"
#include "client/client.h"
#include "client/video.h"
@@ -23,26 +24,6 @@ namespace client
{
core::Cvar *cl_framerate = 0;
-
-//--- private definition ------------------------------------------
-
-/// client application implementation
-class Client : public core::Application
-{
-public:
- /// initialize the client Client
- virtual void init(int count, char **arguments);
-
- /// run the client Client
- virtual void run();
-
- /// shutdown the client Client
- virtual void shutdown();
-
- /// quit the client Client
- virtual void quit(int status);
-};
-
Client app;
//--- engine functions --------------------------------------------
@@ -71,6 +52,11 @@ void client_main(int count, char **arguments)
app.shutdown();
}
+Client *client()
+{
+ return &app;
+}
+
//--- private -----------------------------------------------------
void Client::quit(int status)
@@ -112,6 +98,9 @@ void Client::init(int count, char **arguments)
// initialize input
input::init();
+
+ // initialize audio
+ audio::init();
// add engine functions
core::Func *func = 0;
@@ -147,8 +136,6 @@ void Client::run()
}
};
- //con_debug << "tick " << std::setw(8) << chrono << " " << std::setw(8) << current << " " << elapsed;
-
}
}
@@ -157,11 +144,12 @@ void Client::shutdown()
{
con_print << "^BShutting down client..." << std::endl;
- // remove engine functions
core::Func::remove("r_restart");
chat::shutdown();
+ audio::shutdown();
+
Console::shutdown();
input::shutdown();
@@ -173,5 +161,10 @@ void Client::shutdown()
quit(0);
}
+void Client::notify_sound(const char * name)
+{
+ audio::play(name);
+}
+
} // namespace client
diff --git a/src/client/client.h b/src/client/client.h
index b1a50df..57488ec 100644
--- a/src/client/client.h
+++ b/src/client/client.h
@@ -7,12 +7,37 @@
#ifndef __INCLUDED_CLIENT_H__
#define __INCLUDED_CLIENT_H__
+#include "core/application.h"
+
/// client part of the engine
namespace client {
+/// client application implementation
+class Client : public core::Application
+{
+public:
+ /// initialize the client
+ virtual void init(int count, char **arguments);
+
+ /// run the client
+ virtual void run();
+
+ /// shutdown the client
+ virtual void shutdown();
+
+ /// quit the client
+ virtual void quit(int status);
+
+ /// sound notifications from the core to the application
+ virtual void notify_sound(const char * name);
+};
+
+
/// the client main loop
void client_main(int count, char **arguments);
+Client *client();
+
}
#endif // __INCLUDED_CLIENT_H__
diff --git a/src/client/console.cc b/src/client/console.cc
index f692db4..ac977f2 100644
--- a/src/client/console.cc
+++ b/src/client/console.cc
@@ -245,9 +245,9 @@ void Console::draw_notify()
Text::setcolor('N');
size_t width = (size_t) ((video::width-8) / Text::fontwidth());
size_t n = notify_pos % MAXNOTIFYLINES;
- float h = 4 + 2*Text::fontheight();
+ float h = video::height/2;
for (size_t l = 0; l < MAXNOTIFYLINES; l++) {
- if (notify_text[n].size() > 2 && notify_time[n] + 4 > core::application()->time()) {
+ if (notify_text[n].size() > 2 && notify_time[n] + 5 > core::application()->time()) {
std::string linedata(notify_text[n]);
linedata += '\n';
diff --git a/src/client/console.h b/src/client/console.h
index 2f8d6a0..5bdbde6 100644
--- a/src/client/console.h
+++ b/src/client/console.h
@@ -11,7 +11,7 @@
namespace client {
-const size_t MAXNOTIFYLINES = 3;
+const size_t MAXNOTIFYLINES = 5;
const size_t MAXHISTOLINES = 512;
/// client console implementation
diff --git a/src/client/view.cc b/src/client/view.cc
index e2c8687..5c12710 100644
--- a/src/client/view.cc
+++ b/src/client/view.cc
@@ -138,8 +138,8 @@ void draw_status()
int minutes = (int) floorf(core::game()->clientframetime() / 60.0f);
int seconds = (int) floorf( core::game()->clientframetime() - (float) minutes* 60.0f);
- status << "^Ntime ^B" << std::setfill('0') << std::setw(2) << minutes << "^N:^B" << std::setfill('0') << std::setw(2) << seconds;
- Text::draw(4, 4, status);
+ status << "^Ntime ^B" << std::setfill('0') << std::setw(2) << minutes << ":" << std::setfill('0') << std::setw(2) << seconds;
+ Text::draw(video::width-Text::fontwidth()*11-4, 4+Text::fontheight(), status);
}
// print stats if desired
@@ -152,7 +152,7 @@ void draw_status()
}
stats << "^Ntx ^B"<< std::setw(5) << (core::Stats::network_bytes_sent >> 10) << "\n";
stats << "^Nrx ^B"<< std::setw(5) << (core::Stats::network_bytes_received >> 10) << "\n";
- Text::draw(video::width-Text::fontwidth()*12, video::height - Text::fontheight()*8, stats);
+ Text::draw(video::width-Text::fontwidth()*11-4, 4 + Text::fontheight()*3, stats);
}
// draw a basic HUD
diff --git a/src/core/application.cc b/src/core/application.cc
index 67bb952..db97af8 100644
--- a/src/core/application.cc
+++ b/src/core/application.cc
@@ -377,4 +377,15 @@ void Application::load_commandline(int count, char **arguments)
cmd() << '\n';
}
+void Application::notify_sound(const char *name)
+{
+ // the default implementation does nothing.
+ // Dedicated servers don't need sounds
+}
+
+void Application::notify_message(std::string const & message)
+{
+ con_print << message << std::endl;
+}
+
}
diff --git a/src/core/application.h b/src/core/application.h
index bec53d9..aad3ac9 100644
--- a/src/core/application.h
+++ b/src/core/application.h
@@ -56,6 +56,14 @@ public:
/// quit the application without proper shutdown
virtual void quit(int status);
+/*----- notifications --------------------------------------------- */
+
+ /// sound notifications from the core to the application
+ virtual void notify_sound(const char * name);
+
+ /// text notifications from the core to the application
+ virtual void notify_message(std::string const & message);
+
/*----- static --------------------------------------------------- */
/// a pointer to the current application instance
diff --git a/src/core/gameserver.cc b/src/core/gameserver.cc
index fb828e2..54d667b 100644
--- a/src/core/gameserver.cc
+++ b/src/core/gameserver.cc
@@ -8,6 +8,7 @@
#include "auxiliary/functions.h"
#include "sys/sys.h"
+#include "core/application.h"
#include "core/cvar.h"
#include "core/func.h"
#include "core/gameserver.h"
@@ -143,15 +144,19 @@ void GameServer::say(Player *player, std::string const &message)
if (!message.size())
return;
- // send to console
- con_print << "^B" << player->name() << "^F:^B " << message << std::endl;
+ std::string notification("^B");
+ notification.append(player->name());
+ notification.append("^F:^B ");
+ notification.append(message);
+
+ // send to application
+ application()->notify_message(notification);
+ application()->notify_sound("ui/chat.wav");
// broadcast to remote clients
if (server_network) {
- std::string netmessage("msg public ^B");
- netmessage.append(player->name());
- netmessage.append("^F:^B ");
- netmessage.append(message);
+ std::string netmessage("msg public ");
+ netmessage.append(notification);
netmessage += '\n';
server_network->broadcast(netmessage);
}
@@ -159,8 +164,8 @@ void GameServer::say(Player *player, std::string const &message)
void GameServer::broadcast(std::string const & message, Player *ignore_player)
{
- // send to console
- con_print << message << "\n";
+ // send to application
+ application()->notify_message(message);
// broadcast to remote clients
if (server_network) {
@@ -173,9 +178,9 @@ void GameServer::broadcast(std::string const & message, Player *ignore_player)
void GameServer::send(Player *player, std::string message)
{
- // send to console
+ // send to application
if (player->id() == localplayer()->id()) {
- con_print << message << "\n";
+ application()->notify_message(message);
}
// send to remote clients
diff --git a/src/core/netconnection.cc b/src/core/netconnection.cc
index 22614d2..8da8b1b 100644
--- a/src/core/netconnection.cc
+++ b/src/core/netconnection.cc
@@ -283,12 +283,13 @@ void NetConnection::parse_incoming_message(const std::string & message)
if (msgstream >> level) {
if (level =="info") {
if (message.size() > 9) {
- con_print << message.substr(9) << std::endl;
+ application()->notify_message(message.substr(9));
}
} else if (level == "public") {
// FIXME - separate sender nickname
if (message.size() > 11) {
- con_print << message.substr(11) << std::endl;
+ application()->notify_message(message.substr(11));
+ application()->notify_sound("ui/chat.wav");
}
}
diff --git a/src/model/map.cc b/src/model/map.cc
index 03ebe69..fea98e0 100644
--- a/src/model/map.cc
+++ b/src/model/map.cc
@@ -172,7 +172,7 @@ Model * Map::load(std::string const &name)
}
- con_print << " maps/" << model->name() << ".map " << mapfile.brushes << " brush " << model->tris()
+ con_print << " maps/" << model->name() << ".map " << mapfile.brushes << " brushes " << model->tris()
<< " tris (" << model->details() << " detail)" << std::endl;
return model;
diff --git a/src/render/image.h b/src/render/image.h
index 0c1069b..a129773 100644
--- a/src/render/image.h
+++ b/src/render/image.h
@@ -15,31 +15,31 @@ public:
Image(unsigned int width, unsigned int height, unsigned int channels);
~Image();
- // pointer to the image data
+ /// pointer to the raw image data
inline unsigned char *data() { return image_data; }
- // index into the image data
+ /// index into the raw image data
inline unsigned char *operator[](size_t index) { return &image_data[index]; }
- // width of the image in pixels
+ /// width of the image in pixels
inline unsigned int width() const { return image_width; }
- // height of the image in pixels
+ /// height of the image in pixels
inline unsigned int height() const { return image_height; }
- // size of the image data in bytes
+ /// size of the image data in bytes
inline size_t size() const { return ((size_t) image_width * (size_t) image_height * (size_t) image_channels); }
- // number of channels 3 (RGB) or 4 (RGBA)
+ /// number of channels 3 (RGB) or 4 (RGBA)
inline unsigned int channels() const { return image_channels; }
- // set image data to zero
+ /// set image data to zero
void clear();
- // swap the red and blue channel values of the image
+ /// swap the red and blue channel values of the image
void swap_channels();
- // flip upside-down
+ /// flip upside-down
void flip();
private: