Project categories

Project site header
Category
Games
Platform
PC
Language
C++
Type
Open source
Team members
10+
Date
2007
State
Completed

Description

Hero of Allacrost is a single player 2D role-playing game inspired by classic console RPGs. In Hero of Allacrost, the player will explore rich environments, solve challenging dungeon puzzles, and fight strategic battles in an active-time based system. The game is free open-source software and is available across several platforms including Windows, OS X, Linux, and FreeBSD. The team behind the project consists of people all across the globe who contributes to Allacrost in their spare time.

During the time I was involved in the development team, I mainly worked in the video and audio engine, but also in general code for debugging purposes. The specific tasks I was involved were the following.

Regarding the rendering engine:

  • Rewriting some functions.
  • Solving pixel accuracy rendering problems.
  • Adding support for advanced tile loading system.
  • Refactor the system, mainly renaiming items to make all follow the same nomenclature system.
  • Solving bugs.

Regarding the audio engine, I was in charge to redesign and rewrite the whole system. The following features were implemented:

  • Rewrite whole audio system interface.
  • Reimplementation in OpenAL (previous version was SDL based).
  • WAV and OGG support.
  • Support for positional audio (3D sound).
  • Streaming support, both from disk and memory.
  • Special sound effects (fades, crossfades...).
  • Custom play mode, allowing segment playing with sample precission and custom per-segment looping modes.

Images

Video

            

Code sample

The following code shows the classes for handling audio input sources.

weapon.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
////////////////////////////////////////////////////////////////////////////////
// Copyright (C) 2004-2010 by The Allacrost Project
// All Rights Reserved
//
// This code is licensed under the GNU GPL version 2. It is free software
// and you may modify it and/or redistribute it under the terms of this license.
// See http://www.gnu.org/copyleft/gpl.html for details.
////////////////////////////////////////////////////////////////////////////////
 
/** ****************************************************************************
*** \file audio_input.h
*** \author Mois�s Ferrer Serra, This email address is being protected from spambots. You need JavaScript enabled to view it.
*** \author Aaron Smith - This email address is being protected from spambots. You need JavaScript enabled to view it.
*** \brief Header file for classes that provide input for sounds
***
*** This code provides classes for loading sounds (WAV and OGG). It also
*** provides the functionality for basic streaming operations, both from memory
*** and from a file.
***
*** \note This code uses the Ogg/Vorbis libraries for loading Ogg files. WAV
*** files are loaded via custom loading code
*** ***************************************************************************/
 
#ifndef __AUDIO_INPUT_HEADER__
#define __AUDIO_INPUT_HEADER__
 
#ifdef __MACH__
#include <OpenAL/al.h>
#include <OpenAL/alc.h>
#else
#include "al.h"
#include "alc.h"
#endif
 
#include "defs.h"
#include "utils.h"
 
#include <vorbis/vorbisfile.h>
#include <fstream>
 
namespace hoa_audio {
 
namespace private_audio {
 
/** ****************************************************************************
*** \brief Abstract class for audio input objects
***
*** This class is responsible for managing the audio input, whether the input
*** source is from a file or data that is stored in memory. This class also
*** retains a series of variables that describe the input data Additionally,
*** data read and seek operations are implemented by derivatives of this class.
*** ***************************************************************************/
class AudioInput {
public:
AudioInput();
 
virtual ~AudioInput ()
{};
 
/** \brief Prepares and initializes the input stream for reading
*** \return True if the stream was successfully opened and is ready to read
*** This function is responsible for prepairing the stream from where the
*** data is going to be read. For instance, if it is a file, it will be
*** responsible of getting a file descriptor, open the file and seek the data.
*** This function also sets many of the class members which describe the
*** input data's properties.
**/
virtual bool Initialize() = 0;
 
/** \brief Seeks the stream to a specific sample
*** \param sample_position The sample position to place the read cursor
*** If the cursor exceeds the maximum sample position, the read cursor will
*** not change.
**/
virtual void Seek(uint32 sample_position) = 0;
 
/** \brief Reads data up to a specified number of samples
*** \param data_buffer The buffer to store the read audio data in
*** \param number_samples The number of samples to read
*** \param end A boolean reference which will be set to true if the last of the data was read
*** \return The number of samples which were read
*** Reads up to the specified number of samples, and stores it in a buffer. It can store from 0 to
*** the spcified number of samples. The buffer must hold enough information for the data.
**/
virtual uint32 Read(uint8* data_buffer, uint32 number_samples, bool& end) = 0;
 
//! \name Class member access functions
//@{
const std::string& GetFilename() const
{ return _filename; }
 
uint32 GetSamplesPerSecond() const
{ return _samples_per_second; }
 
uint16 GetBitsPerSample() const
{ return _bits_per_sample; }
 
uint16 GetNumberChannels() const
{ return _number_channels; }
 
uint32 GetTotalNumberSamples() const
{ return _total_number_samples; }
 
uint32 GetDataSize() const
{ return _data_size; }
 
float GetPlayTime() const
{ return _play_time; }
 
uint16 GetSampleSize() const
{ return _sample_size; }
//@}
 
protected:
//! \brief The name of the audio file operated on by the class
std::string _filename;
 
//! \brief The number of samples per second (typically 11025, 22050, 44100)
uint32 _samples_per_second;
 
//! \brief The number of bits per sample (typically 8 or 16)
uint16 _bits_per_sample;
 
//! \brief Channels of the sound (1 = mono, 2 = stereo)
uint16 _number_channels;
 
//! \brief The total number of samples of the audio piece
uint32 _total_number_samples;
 
//! \brief The size of the audio data in bytes
uint32 _data_size;
 
//! \brief The size of an individual sample in bytes (_bits_per_sample * _channels / 8)
uint16 _sample_size;
 
//! \brief The total play ime of the audio piece in seconds (_samples / _samples_per_second)
float _play_time;
}; // class AudioInput
 
 
/** ****************************************************************************
*** \brief Manages input extraced from .wav files
***
*** Wav files are usually used for sounds. This class implements its own custom
*** wav file parser/loader to interpret the data from the file into meaningful
*** audio data.
*** ***************************************************************************/
class WavFile : public AudioInput {
public:
WavFile(const std::string& file_name) :
AudioInput() { _filename = file_name; }
 
~WavFile()
{ if (_file_input) _file_input.close(); }
 
//! \brief Inherited functions from AudioInput class
//@{
//! \todo Enable this function to handle loading of more complex WAV files
bool Initialize();
 
void Seek(uint32 sample_position);
 
uint32 Read(uint8* data_buffer, uint32 number_samples, bool& end);
//@}
 
private:
//! \brief The input I/O stream for the file
std::ifstream _file_input;
 
//! \brief The offset to where the data begins in the file (past the header information)
std::streampos _data_init;
}; // class WavFile : public AudioInput
 
 
/** ****************************************************************************
*** \brief Manages input extracted from .ogg files
***
*** Ogg files are typically used for music. The functions in this class
*** make calls to the libvorbis library in order to read and seek through
*** the audio data.
*** ***************************************************************************/
class OggFile : public AudioInput {
public:
OggFile(const std::string& file_name) :
AudioInput(), _read_buffer_position(0), _read_buffer_size(0) { _filename = file_name; }
 
~OggFile()
{ ov_clear(&_vorbis_file); }
 
//! \brief Inherited functions from AudioInput class
//@{
bool Initialize();
 
void Seek(uint32 sample_position);
 
uint32 Read(uint8* data_buffer, uint32 number_samples, bool& end);
//@}
 
private:
//! \brief Contains information about the Vorbis Ogg file
OggVorbis_File _vorbis_file;
 
//! \brief Temporary buffer for reading data.
unsigned char _read_buffer[4096];
 
//! \brief Position of previous read data (for the emporal buffer).
uint16 _read_buffer_position;
 
//! \brief Size of available data on the buffer (for the emporal buffer).
uint16 _read_buffer_size;
 
/** \brief A wrapper function for file seek operations
*** \param ffile A pointer to the FILE struct which represents the input stream
*** \param off The number of bytes to offset from the stream's origin
*** \param whence The position to read, added to the off paramater to determine the actual seek position
*** \return The return value of the fseek function, or -1 if the file pointer was invalid
***
*** \note This function is required and used only by the Windows platform. It is static out
*** of necessity (it gets used as a function pointer) and uses the normally forbidden int type
*** since it is a wrapper to a C function which expects those types.
*/
static int _FileSeekWrapper(FILE* file, ogg_int64_t off, int whence);
}; // class OggFile : public AudioInput
 
 
/** ****************************************************************************
*** \brief Manages audio input data that is stored in memory
***
*** The class requires a pointer to a section of memory where the audio data is
*** stored, and then operates off of that data. This is useful for efficient
*** streaming operations so that I/O files containing the data do not need to
*** be continually accessed.
*** ***************************************************************************/
class AudioMemory : public AudioInput {
public:
/** \brief The class must be constructed using existing audio input data
*** \param input A pointer to the already initialized AudioInput for this class to use
*** This constructor will allocate enough memory to hold the entire audio data and
*** fill that memory with the audio data read from the input argument
**/
AudioMemory(AudioInput* input);
 
AudioMemory(const AudioMemory& audio_memory);
AudioMemory& operator=(const AudioMemory& other_audio_memory);
 
~AudioMemory();
 
//! \brief Inherited functions from AudioInput class
//@{
//! \note Audio memory does not need to be initialized, as that is done in the class constructor
bool Initialize()
{ return true; }
 
void Seek(uint32 sample_position);
 
uint32 Read(uint8* buffer, uint32 size, bool& end);
//@}
 
private:
//! \brief The memory location where all the audio is stored
uint8* _audio_data;
 
//! \brief Position in the data where the next read operation will be performed
uint32 _data_position;
}; // class AudioMemory : public AudioInput
 
} // namespace private_audio
 
} // namespace hoa_audio
 
#endif // __AUDIO_INPUT_HEADER__
 

Links

Hero of Allacrost
Game site. You can download the game from there.

NOTE! This site uses cookies and similar technologies.

This site uses cookies and similar technologies. If you not change browser settings, you agree to it. Learn more

I understand