summaryrefslogtreecommitdiff
path: root/plugins/adplug/adplug/rol.h
blob: a7f936b76dcfcc93057546ee3cb2c5a98087b8ab (plain)
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
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
/*
 * Adplug - Replayer for many OPL2/OPL3 audio file formats.
 * Copyright (C) 1999 - 2008 Simon Peter, <dn.tlp@gmx.net>, et al.
 * 
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 * 
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 * 
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 *
 * rol.h - ROL Player by OPLx <oplx@yahoo.com>
 *
 * Visit:  http://tenacity.hispeed.com/aomit/oplx/
 */
#ifndef H_ROLPLAYER
#define H_ROLPLAYER

#include "player.h"

class CrolPlayer: public CPlayer
{
public:
  static CPlayer *factory(Copl *newopl);

    CrolPlayer(Copl *newopl);

    ~CrolPlayer();

    bool  load      (const char *filename, const CFileProvider &fp);
    bool  update    ();
    void  rewind    (int subsong);	// rewinds to specified subsong
    float getrefresh();			// returns needed timer refresh rate

    const char * gettype() { return "Adlib Visual Composer"; }

private:
    typedef unsigned short    uint16;
    typedef signed   short    int16;
#ifdef __x86_64__
    typedef signed   int      int32;
#else
    typedef signed long int   int32;
#endif
    typedef float             real32;

    typedef struct
    {
        uint16 version_major;
        uint16 version_minor;
        char   unused0[40];
        uint16 ticks_per_beat;
        uint16 beats_per_measure;
        uint16 edit_scale_y;
        uint16 edit_scale_x;
        char   unused1;
        char   mode;
        char   unused2[90];
        char   filler0[38];
        char   filler1[15];
        real32 basic_tempo;
    } SRolHeader;

    typedef struct
    {
        int16  time;
        real32 multiplier;
    } STempoEvent;

    typedef struct
    {
        int16 number;
        int16 duration;
    } SNoteEvent;

    typedef struct
    {
        int16 time;
        char  name[9];
        int16 ins_index;
    } SInstrumentEvent;

    typedef struct
    {
        int16  time;
        real32 multiplier;
    } SVolumeEvent;

    typedef struct
    {
        int16  time;
        real32 variation;
    } SPitchEvent;

    enum {
        MAX_NOTE_EVENTS = 2000,
    };

#define bit_pos( pos ) (1<<pos)

    class CVoiceData
    {
    public:
        enum EEventStatus
        {
            kES_NoteEnd   = bit_pos( 0 ),
            kES_PitchEnd  = bit_pos( 1 ),
            kES_InstrEnd  = bit_pos( 2 ),
            kES_VolumeEnd = bit_pos( 3 ),

            kES_None     = 0
        };

        explicit CVoiceData()
            :   mForceNote           ( true )
               ,mEventStatus         ( kES_None )
               ,current_note         ( 0 )
               ,current_note_duration( 0 )
               ,mNoteDuration        ( 0 )
               ,next_instrument_event( 0 )
               ,next_volume_event    ( 0 )
               ,next_pitch_event     ( 0 )
                ,n_note_events (0)
                ,n_instrument_events(0)
                ,n_volume_events(0)
                ,n_pitch_events(0)
        {
            memset (note_events, 0, sizeof (note_events));
            instrument_events = 0;
            volume_events = 0;
            pitch_events = 0;
        }

        ~CVoiceData () {
            delete[] instrument_events;
            delete[] volume_events;
            delete[] pitch_events;
        }

        void Reset()
        {
            mForceNote            = true;
            mEventStatus          = kES_None;
            current_note          = 0;
            current_note_duration = 0;
            mNoteDuration         = 0;
            next_instrument_event = 0;
            next_volume_event     = 0;
            next_pitch_event      = 0;
        }

        SNoteEvent       note_events[MAX_NOTE_EVENTS];
        int n_note_events;
        SInstrumentEvent *instrument_events;
        int n_instrument_events;
        SVolumeEvent     *volume_events;
        int n_volume_events;
        SPitchEvent      *pitch_events;
        int n_pitch_events;

        bool              mForceNote : 1;
        int               mEventStatus;
        unsigned int      current_note;
        int               current_note_duration;
        int               mNoteDuration;
        unsigned int      next_instrument_event;
        unsigned int      next_volume_event;
        unsigned int      next_pitch_event;
    };

    typedef struct
    {
        uint16 index;
        char   record_used;
        char   name[9];
    } SInstrumentName;

    typedef struct
    {
        char   version_major;
        char   version_minor;
        char   signature[6];
        uint16 number_of_list_entries_used;
        uint16 total_number_of_list_entries;
        int32  abs_offset_of_name_list;
        int32  abs_offset_of_data;

        SInstrumentName *ins_name_list;
        int n_ins_names;
    } SBnkHeader;

    typedef struct
    {
        unsigned char key_scale_level;
        unsigned char freq_multiplier;
        unsigned char feed_back;
        unsigned char attack_rate;
        unsigned char sustain_level;
        unsigned char sustaining_sound;
        unsigned char decay_rate;
        unsigned char release_rate;
        unsigned char output_level;
        unsigned char amplitude_vibrato;
        unsigned char frequency_vibrato;
        unsigned char envelope_scaling;
        unsigned char fm_type;
    } SFMOperator;

    typedef struct
    {
        unsigned char ammulti;
        unsigned char ksltl;
        unsigned char ardr;  
        unsigned char slrr;
        unsigned char fbc;
        unsigned char waveform;
    } SOPL2Op;

    typedef struct
    {
        char        mode;
        char        voice_number;
        SOPL2Op     modulator;
        SOPL2Op     carrier;
    } SRolInstrument;

    typedef struct
    {
        const char *    name;
        SRolInstrument instrument;
    } SUsedList;

    void load_tempo_events     ( binistream *f );
    bool load_voice_data       ( binistream *f, const char *bnk_filename, const CFileProvider &fp );
    void load_note_events      ( binistream *f, CVoiceData &voice );
    void load_instrument_events( binistream *f, CVoiceData &voice,
                                 binistream *bnk_file, SBnkHeader const &bnk_header );
    void load_volume_events    ( binistream *f, CVoiceData &voice );
    void load_pitch_events     ( binistream *f, CVoiceData &voice );

    bool load_bnk_info         ( binistream *f, SBnkHeader &header );
    int  load_rol_instrument   ( binistream *f, SBnkHeader const &header, const char *name );
    void read_rol_instrument   ( binistream *f, SRolInstrument &ins );
    void read_fm_operator      ( binistream *f, SOPL2Op &opl2_op );
    int  get_ins_index( const char * const &name ) const;

    void UpdateVoice( int const voice, CVoiceData &voiceData );
    void SetNote( int const voice, int const note );
    void SetNoteMelodic(  int const voice, int const note  );
    void SetNotePercussive( int const voice, int const note );
    void SetFreq   ( int const voice, int const note, bool const keyOn=false );
    void SetPitch  ( int const voice, real32 const variation );
    void SetVolume ( int const voice, int const volume );
    void SetRefresh( float const multiplier );
    void send_ins_data_to_chip( int const voice, int const ins_index );
    void send_operator( int const voice, SOPL2Op const &modulator, SOPL2Op const &carrier );

    SRolHeader *rol_header;
    STempoEvent    *mTempoEvents;
    int n_tempo_events;
    CVoiceData                  *voice_data;
    int n_voice_data;
    SUsedList      *ins_list;
    int n_used_ins;

    unsigned int                mNextTempoEvent;
    int                         mCurrTick;
    int                         mTimeOfLastNote;
    float                       mRefresh;
    unsigned char               bdRegister;
    unsigned char               bxRegister[9];
    unsigned char               volumeCache[11];
    uint16			freqCache[11];
    real32                      pitchCache[11];

    static int    const kSizeofDataRecord;
    static int    const kMaxTickBeat;
    static int    const kSilenceNote;
    static int    const kNumMelodicVoices;
    static int    const kNumPercussiveVoices;
    static int    const kBassDrumChannel;
    static int    const kSnareDrumChannel;
    static int    const kTomtomChannel;
    static int    const kTomtomFreq;
    static int    const kSnareDrumFreq;
    static float  const kDefaultUpdateTme;
    static float  const kPitchFactor;
    static uint16 const kNoteTable[12];
};

#endif