Ticket #8491: mikmod.diff

File mikmod.diff, 11.7 KB (added by eriktorbjorn, 18 years ago)

Patch against a December 2 CVS snapshot

  • base/main.cpp

    diff -urN --exclude=CVS scummvm/base/main.cpp scummvm+mikmod/base/main.cpp
    old new  
    113113        "MP3 "
    114114#endif
    115115
     116#ifdef USE_MIKMOD
     117        "MikMod "
     118#endif
     119
    116120#ifdef USE_ALSA
    117121        "ALSA "
    118122#endif
  • configure

    diff -urN --exclude=CVS scummvm/configure scummvm+mikmod/configure
    old new  
    3939_tremor=auto
    4040_flac=auto
    4141_mad=auto
     42_mikmod=auto
    4243_alsa=auto
    4344_zlib=auto
    4445_mpeg2=auto
     
    322323  --with-flac-prefix=DIR   Prefix where libFLAC is installed (optional)
    323324  --disable-flac           disable FLAC support [autodetect]
    324325
     326  --with-mikmod-prefix=DIR Prefix where libmikmod is installed (optional)
     327  --disable-mikmod         disable MikMod support [autodetect]
     328
    325329  --with-zlib-prefix=DIR   Prefix where zlib is installed (optional)
    326330  --disable-zlib           disable zlib (compression) support [autodetect]
    327331
     
    375379      --disable-flac)           _flac=no        ;;
    376380      --enable-mad)             _mad=yes        ;;
    377381      --disable-mad)            _mad=no         ;;
     382      --enable-mikmod)          _mikmod=yes     ;;
     383      --disable-mikmod)         _mikmod=no      ;;
    378384      --enable-zlib)            _zlib=yes       ;;
    379385      --disable-zlib)           _zlib=no        ;;
    380386      --enable-nasm)            _nasm=yes       ;;
     
    424430        MAD_CFLAGS="-I$_prefix/include"
    425431        MAD_LIBS="-L$_prefix/lib"
    426432        ;;
     433      --with-mikmod-prefix=*)
     434        _prefix=`echo $ac_option | cut -d '=' -f 2`
     435        MIKMOD_CFLAGS="-I$_prefix/include"
     436        MIKMOD_LIBS="-L$_prefix/lib"
     437        ;;
    427438      --with-zlib-prefix=*)
    428439        _prefix=`echo $ac_option | cut -d '=' -f 2`
    429440        ZLIB_CFLAGS="-I$_prefix/include"
     
    10541065echo "$_mad"
    10551066
    10561067#
     1068# Check for MikMod (MOD decoder library)
     1069#
     1070
     1071echocheck "MikMod"
     1072if test "$_mikmod" = auto ; then
     1073        _mikmod=no
     1074        cat > $TMPC << EOF
     1075#include <mikmod.h>
     1076int main(void) {return 0; }
     1077EOF
     1078        cc_check $LDFLAGS $CXXFLAGS $MIKMOD_CFLAGS $MIKMOD_LIBS -lmikmod && _mikmod=yes
     1079fi
     1080if test "$_mikmod" = yes ; then
     1081        _def_mikmod='#define USE_MIKMOD'
     1082        LIBS="$LIBS $MIKMOD_LIBS -lmikmod"
     1083        INCLUDES="$INCLUDES $MIKMOD_CFLAGS"
     1084else
     1085        _def_mikmod='#undef USE_MIKMOD'
     1086fi
     1087echo "$_mikmod"
     1088
     1089#
    10571090# Check for ALSA
    10581091#
    10591092echocheck "ALSA >= 0.9"
     
    13041337$_def_vorbis
    13051338$_def_tremor
    13061339$_def_flac
     1340$_def_mikmod
    13071341$_def_mad
    13081342$_def_alsa
    13091343$_def_zlib
  • sound/audiocd.cpp

    diff -urN --exclude=CVS scummvm/sound/audiocd.cpp scummvm+mikmod/sound/audiocd.cpp
    old new  
    2525#include "sound/mp3.h"
    2626#include "sound/vorbis.h"
    2727#include "sound/flac.h"
     28#include "sound/mod.h"
    2829#include "base/engine.h"
    2930#include "common/file.h"
    3031#include "common/util.h"
     
    5354#ifdef USE_MAD
    5455        { "Mpeg Layer 3",       getMP3Track },
    5556#endif
     57#ifdef USE_MIKMOD
     58        { "MOD",                        getMODTrack },
     59#endif
    5660
    5761        { NULL, NULL } // Terminator
    5862};
  • sound/mixer.cpp

    diff -urN --exclude=CVS scummvm/sound/mixer.cpp scummvm+mikmod/sound/mixer.cpp
    old new  
    3232#include "sound/flac.h"
    3333#include "sound/mp3.h"
    3434#include "sound/vorbis.h"
     35#include "sound/mod.h"
    3536
    3637
    3738namespace Audio {
     
    125126                error("OSystem returned invalid sample rate");
    126127
    127128        debug(1, "Output sample rate: %d Hz", _outputRate);
     129
     130#ifdef USE_MIKMOD
     131        initMOD(this);
     132#endif
    128133}
    129134
    130135Mixer::~Mixer() {
     
    133138
    134139        delete _premixChannel;
    135140        _premixChannel = 0;
     141
     142#ifdef USE_MIKMOD
     143        exitMOD();
     144#endif
    136145}
    137146
    138147bool Mixer::isPaused() {
  • sound/mod.cpp

    diff -urN --exclude=CVS scummvm/sound/mod.cpp scummvm+mikmod/sound/mod.cpp
    old new  
     1/* ScummVM - Scumm Interpreter
     2 * Copyright (C) 2003-2005 The ScummVM project
     3 *
     4 * This program is free software; you can redistribute it and/or
     5 * modify it under the terms of the GNU General Public License
     6 * as published by the Free Software Foundation; either version 2
     7 * of the License, or (at your option) any later version.
     8
     9 * This program is distributed in the hope that it will be useful,
     10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
     11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     12 * GNU General Public License for more details.
     13
     14 * You should have received a copy of the GNU General Public License
     15 * along with this program; if not, write to the Free Software
     16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
     17 *
     18 * $Header:$
     19 *
     20 */
     21
     22#include "sound/mod.h"
     23
     24#ifdef USE_MIKMOD
     25
     26#include "common/file.h"
     27#include "common/util.h"
     28
     29#include "sound/audiostream.h"
     30#include "sound/audiocd.h"
     31
     32#include <mikmod.h>
     33
     34
     35using Common::File;
     36
     37
     38void initMOD(Audio::Mixer *mixer) {
     39        // We only use the MikMod library for decoding. Therefore, we only need
     40        // the "No Sound" driver.
     41        MikMod_RegisterDriver(&drv_nos);
     42        MikMod_RegisterAllLoaders();
     43
     44        md_mixfreq = mixer->getOutputRate();
     45
     46        CHAR mmArgs[] = "";
     47
     48        MikMod_Init(mmArgs);
     49}
     50
     51void exitMOD() {
     52        MikMod_Exit();
     53}
     54
     55
     56#pragma mark -
     57#pragma mark --- MOD Audio CD emulation ---
     58#pragma mark -
     59
     60class MODTrackInfo : public DigitalTrackInfo {
     61private:
     62        File *_file;
     63        MODULE *_module;
     64        bool _error_flag;
     65
     66public:
     67        MODTrackInfo(File *file);
     68        ~MODTrackInfo();
     69        bool openTrack();
     70        bool error() { return _error_flag; }
     71        void play(Audio::Mixer *mixer, Audio::SoundHandle *handle, int startFrame, int duration);
     72};
     73
     74
     75// These are wrapper functions to allow using a File object to provide data to
     76// the MOD reader
     77
     78struct MFILEREADER {
     79        MREADER core;
     80        MODULE *module;
     81        File *file;
     82};
     83
     84static int mm_eof_wrapper(struct MREADER *reader) {
     85        return ((MFILEREADER *)reader)->file->eof();
     86}
     87
     88static BOOL mm_read_wrapper(struct MREADER *reader, void *dest, size_t length) {
     89        return ((MFILEREADER *)reader)->file->read(dest, length);
     90}
     91
     92static int mm_get_wrapper(struct MREADER *reader) {
     93        File *file = ((MFILEREADER *)reader)->file;
     94
     95        if (file->eof())
     96                return EOF;
     97
     98        return file->readByte();
     99}
     100
     101static BOOL mm_seek_wrapper(struct MREADER *reader, long offset, int whence) {
     102        ((MFILEREADER *)reader)->file->seek(offset, whence);
     103        return 0;
     104}
     105
     106static long mm_tell_wrapper(struct MREADER *reader) {
     107        return ((MFILEREADER *)reader)->file->pos();
     108}
     109
     110static MODULE *loadModuleFromFile(File *file) {
     111        assert(file);
     112
     113        MFILEREADER *reader = (MFILEREADER *)malloc(sizeof(MFILEREADER));
     114
     115        assert(reader);
     116
     117        reader->core.Eof = &mm_eof_wrapper;
     118        reader->core.Read = &mm_read_wrapper;
     119        reader->core.Get = &mm_get_wrapper;
     120        reader->core.Seek = &mm_seek_wrapper;
     121        reader->core.Tell = &mm_tell_wrapper;
     122
     123        reader->file = file;
     124
     125        MODULE *module = Player_LoadGeneric((MREADER *)reader, 64, 0);
     126
     127        if (!module) {
     128                free(reader);
     129                return NULL;
     130        }
     131
     132        file->incRef();
     133
     134        Player_Start(module);
     135        Player_SetPosition(0);
     136
     137        return module;
     138}
     139
     140MODTrackInfo::MODTrackInfo(File *file) {
     141        _file = file;
     142
     143        if (openTrack()) {
     144                warning("Invalid file format");
     145                _error_flag = true;
     146                _file = 0;
     147        } else {
     148                _error_flag = false;
     149                _file->incRef();
     150        }
     151}
     152
     153MODTrackInfo::~MODTrackInfo() {
     154        if (!_error_flag) {
     155                Player_Free(_module);
     156        }
     157}
     158
     159bool MODTrackInfo::openTrack() {
     160        assert(_file);
     161
     162        _module = loadModuleFromFile(_file);
     163
     164        if (!_module) {
     165                return 1;
     166        }
     167
     168        return 0;
     169}
     170
     171void MODTrackInfo::play(Audio::Mixer *mixer, Audio::SoundHandle *handle, int startFrame, int duration) {
     172        // TODO: We don't handle position or duration at all
     173
     174        bool err = openTrack();
     175        assert(!err);
     176
     177        AudioStream *input = makeMODStream(_file);
     178        mixer->playInputStream(Audio::Mixer::kMusicSoundType, handle, input);
     179}
     180
     181DigitalTrackInfo *getMODTrack(int track) {
     182        char track_name[32];
     183        File *file = new File();
     184
     185        // TODO: MikMod can handle a lot more MOD file types than this
     186        sprintf(track_name, "track%d.mod", track);
     187        file->open(track_name);
     188
     189        if (file->isOpen()) {
     190                MODTrackInfo *trackInfo = new MODTrackInfo(file);
     191                file->decRef();
     192                if (!trackInfo->error())
     193                        return trackInfo;
     194                delete trackInfo;
     195        }
     196        delete file;
     197        return NULL;
     198}
     199
     200#pragma mark -
     201#pragma mark --- MOD stream ---
     202#pragma mark -
     203
     204
     205class MODInputStream : public AudioStream {
     206private:
     207        int16 _buffer[4096];
     208        const int16 *_bufferEnd;
     209        const int16 *_pos;
     210        MODULE *_module;
     211
     212        void refill();
     213        inline bool eosIntern() const;
     214
     215public:
     216        MODInputStream(File *file);
     217        ~MODInputStream();
     218
     219        int readBuffer(int16 *buffer, const int numSamples);
     220
     221        bool endOfData() const          { return eosIntern(); }
     222        bool isStereo() const           { return true; }
     223
     224        int getRate() const             { return md_mixfreq; }
     225};
     226
     227MODInputStream::MODInputStream(File *file) {
     228        _module = loadModuleFromFile(file);
     229
     230        // Read in initial data
     231        refill();
     232}
     233
     234MODInputStream::~MODInputStream() {
     235        if (_module) {
     236                Player_Free(_module);
     237        }
     238}
     239
     240inline bool MODInputStream::eosIntern() const {
     241        return _pos >= _bufferEnd;
     242}
     243
     244int MODInputStream::readBuffer(int16 *buffer, const int numSamples) {
     245        int samples = 0;
     246        while (samples < numSamples && !eosIntern()) {
     247                const int len = MIN(numSamples - samples, (int)(_bufferEnd - _pos));
     248                memcpy(buffer, _pos, len * 2);
     249                buffer += len;
     250                _pos += len;
     251                samples += len;
     252                if (_pos >= _bufferEnd) {
     253                        refill();
     254                }
     255        }
     256        return samples;
     257}
     258
     259void MODInputStream::refill() {
     260        // Read the samples
     261        uint len_left = sizeof(_buffer);
     262        char *read_pos = (char *)_buffer;
     263
     264        Player_Start(_module);
     265
     266        int len = VC_WriteBytes((SBYTE *)_buffer, len_left);
     267
     268        len_left -= len;
     269        read_pos += len;
     270
     271        _pos = _buffer;
     272        _bufferEnd = (int16 *)read_pos;
     273}
     274
     275AudioStream *makeMODStream(File *file) {
     276        return new MODInputStream(file);
     277}
     278
     279#endif
  • sound/mod.h

    diff -urN --exclude=CVS scummvm/sound/mod.h scummvm+mikmod/sound/mod.h
    old new  
     1/* ScummVM - Scumm Interpreter
     2 * Copyright (C) 2003-2005 The ScummVM project
     3 *
     4 * This program is free software; you can redistribute it and/or
     5 * modify it under the terms of the GNU General Public License
     6 * as published by the Free Software Foundation; either version 2
     7 * of the License, or (at your option) any later version.
     8
     9 * This program is distributed in the hope that it will be useful,
     10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
     11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     12 * GNU General Public License for more details.
     13
     14 * You should have received a copy of the GNU General Public License
     15 * along with this program; if not, write to the Free Software
     16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
     17 *
     18 * $Header:$
     19 *
     20 */
     21
     22#ifndef SOUND_MOD_H
     23#define SOUND_MOD_H
     24
     25#include "common/stdafx.h"
     26#include "common/scummsys.h"
     27
     28#ifdef USE_MIKMOD
     29
     30class AudioStream;
     31class DigitalTrackInfo;
     32namespace Common {
     33        class File;
     34}
     35namespace Audio {
     36        class Mixer;
     37}
     38
     39DigitalTrackInfo *getMODTrack(int track);
     40
     41void initMOD(Audio::Mixer *mixer);
     42void exitMOD();
     43
     44AudioStream *makeMODStream(Common::File *file);
     45
     46#endif
     47
     48#endif
  • sound/module.mk

    diff -urN --exclude=CVS scummvm/sound/module.mk scummvm+mikmod/sound/module.mk
    old new  
    1111        sound/midiparser_smf.o \
    1212        sound/midiparser_xmidi.o \
    1313        sound/mixer.o \
     14        sound/mod.o \
    1415        sound/mp3.o \
    1516        sound/mpu401.o \
    1617        sound/rate.o \