Mercurial > audlegacy
annotate Plugins/Input/adplug/core/imf.cpp @ 713:cf7b5a288564 trunk
[svn] rule for installing data
| author | nenolod |
|---|---|
| date | Sun, 26 Feb 2006 20:14:08 -0800 |
| parents | 2b06eb5e472d |
| children | f12d7e208b43 |
| rev | line source |
|---|---|
| 359 | 1 /* |
| 2 * Adplug - Replayer for many OPL2/OPL3 audio file formats. | |
|
637
2b06eb5e472d
[svn] Sync with upstream. Drop hardware OPL2/3 support, it throws warnings and is not used on most modern machines. Added var inits where GCC 4.0 thought it was a good idea.
chainsaw
parents:
428
diff
changeset
|
3 * Copyright (C) 1999 - 2006 Simon Peter <dn.tlp@gmx.net>, et al. |
| 359 | 4 * |
| 5 * This library is free software; you can redistribute it and/or | |
| 6 * modify it under the terms of the GNU Lesser General Public | |
| 7 * License as published by the Free Software Foundation; either | |
| 8 * version 2.1 of the License, or (at your option) any later version. | |
| 9 * | |
| 10 * This library is distributed in the hope that it will be useful, | |
| 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
| 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
| 13 * Lesser General Public License for more details. | |
| 14 * | |
| 15 * You should have received a copy of the GNU Lesser General Public | |
| 16 * License along with this library; if not, write to the Free Software | |
| 17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | |
| 18 * | |
| 19 * imf.cpp - IMF Player by Simon Peter <dn.tlp@gmx.net> | |
| 20 * | |
| 21 * FILE FORMAT: | |
| 22 * There seem to be 2 different flavors of IMF formats out there. One version | |
| 23 * contains just the raw IMF music data. In this case, the first word of the | |
| 24 * file is always 0 (because the music data starts this way). This is already | |
| 25 * the music data! So read in the entire file and play it. | |
| 26 * | |
| 27 * If this word is greater than 0, it specifies the size of the following | |
| 28 * song data in bytes. In this case, the file has a footer that contains | |
| 29 * arbitrary infos about it. Mostly, this is plain ASCII text with some words | |
| 30 * of the author. Read and play the specified amount of song data and display | |
| 31 * the remaining data as ASCII text. | |
| 32 * | |
| 33 * NOTES: | |
| 34 * This player handles the two above mentioned formats, as well as a third | |
| 35 * type, invented by Martin Fernandez <mfernan@cnba.uba.ar>, that's got a | |
| 36 * proper header to add title/game name information. After the header starts | |
| 37 * the normal IMF file in one of the two above mentioned formats. | |
|
637
2b06eb5e472d
[svn] Sync with upstream. Drop hardware OPL2/3 support, it throws warnings and is not used on most modern machines. Added var inits where GCC 4.0 thought it was a good idea.
chainsaw
parents:
428
diff
changeset
|
38 * |
|
2b06eb5e472d
[svn] Sync with upstream. Drop hardware OPL2/3 support, it throws warnings and is not used on most modern machines. Added var inits where GCC 4.0 thought it was a good idea.
chainsaw
parents:
428
diff
changeset
|
39 * This player also handles a special footer format by Adam Nielsen, |
|
2b06eb5e472d
[svn] Sync with upstream. Drop hardware OPL2/3 support, it throws warnings and is not used on most modern machines. Added var inits where GCC 4.0 thought it was a good idea.
chainsaw
parents:
428
diff
changeset
|
40 * which has defined fields of information about the song, the author |
|
2b06eb5e472d
[svn] Sync with upstream. Drop hardware OPL2/3 support, it throws warnings and is not used on most modern machines. Added var inits where GCC 4.0 thought it was a good idea.
chainsaw
parents:
428
diff
changeset
|
41 * and more. |
| 359 | 42 */ |
| 43 | |
| 44 #include <string.h> | |
| 45 | |
| 46 #include "imf.h" | |
| 47 #include "database.h" | |
| 48 | |
| 49 /*** public methods *************************************/ | |
| 50 | |
| 51 CPlayer *CimfPlayer::factory(Copl *newopl) | |
| 52 { | |
| 53 return new CimfPlayer(newopl); | |
| 54 } | |
| 55 | |
| 56 bool CimfPlayer::load(const std::string &filename, const CFileProvider &fp) | |
| 57 { | |
| 58 binistream *f = fp.open(filename); if(!f) return false; | |
| 59 unsigned long fsize, flsize, mfsize = 0; | |
| 60 unsigned int i; | |
| 61 | |
| 62 // file validation section | |
| 63 { | |
| 64 char header[5]; | |
| 65 int version; | |
| 66 | |
| 67 f->readString(header, 5); | |
| 68 version = f->readInt(1); | |
| 69 | |
| 70 if(strncmp(header, "ADLIB", 5) || version != 1) { | |
| 71 if(!fp.extension(filename, ".imf") && !fp.extension(filename, ".wlf")) { | |
| 72 // It's no IMF file at all | |
| 73 fp.close(f); | |
| 74 return false; | |
| 75 } else | |
| 76 f->seek(0); // It's a normal IMF file | |
| 77 } else { | |
| 78 // It's a IMF file with header | |
| 79 track_name = f->readString('\0'); | |
| 80 game_name = f->readString('\0'); | |
| 81 f->ignore(1); | |
| 82 mfsize = f->pos() + 2; | |
| 83 } | |
| 84 } | |
| 85 | |
| 86 // load section | |
| 87 if(mfsize) | |
| 88 fsize = f->readInt(4); | |
| 89 else | |
| 90 fsize = f->readInt(2); | |
| 91 flsize = fp.filesize(f); | |
| 92 if(!fsize) { // footerless file (raw music data) | |
| 93 if(mfsize) | |
| 94 f->seek(-4, binio::Add); | |
| 95 else | |
| 96 f->seek(-2, binio::Add); | |
|
428
15ca2ea93a30
[svn] Sync with upstream CVS. This implements RIX playback.
chainsaw
parents:
359
diff
changeset
|
97 size = (flsize - mfsize) / 4; |
| 359 | 98 } else // file has got a footer |
| 99 size = fsize / 4; | |
| 100 | |
| 101 data = new Sdata[size]; | |
| 102 for(i = 0; i < size; i++) { | |
| 103 data[i].reg = f->readInt(1); data[i].val = f->readInt(1); | |
| 104 data[i].time = f->readInt(2); | |
| 105 } | |
| 106 | |
| 107 // read footer, if any | |
|
428
15ca2ea93a30
[svn] Sync with upstream CVS. This implements RIX playback.
chainsaw
parents:
359
diff
changeset
|
108 if(fsize && (fsize < flsize - 2 - mfsize)) |
|
15ca2ea93a30
[svn] Sync with upstream CVS. This implements RIX playback.
chainsaw
parents:
359
diff
changeset
|
109 if(f->readInt(1) == 0x1a) { |
|
15ca2ea93a30
[svn] Sync with upstream CVS. This implements RIX playback.
chainsaw
parents:
359
diff
changeset
|
110 // Adam Nielsen's footer format |
|
15ca2ea93a30
[svn] Sync with upstream CVS. This implements RIX playback.
chainsaw
parents:
359
diff
changeset
|
111 track_name = f->readString(); |
|
15ca2ea93a30
[svn] Sync with upstream CVS. This implements RIX playback.
chainsaw
parents:
359
diff
changeset
|
112 author_name = f->readString(); |
|
15ca2ea93a30
[svn] Sync with upstream CVS. This implements RIX playback.
chainsaw
parents:
359
diff
changeset
|
113 remarks = f->readString(); |
|
15ca2ea93a30
[svn] Sync with upstream CVS. This implements RIX playback.
chainsaw
parents:
359
diff
changeset
|
114 } else { |
|
15ca2ea93a30
[svn] Sync with upstream CVS. This implements RIX playback.
chainsaw
parents:
359
diff
changeset
|
115 // Generic footer |
|
15ca2ea93a30
[svn] Sync with upstream CVS. This implements RIX playback.
chainsaw
parents:
359
diff
changeset
|
116 unsigned long footerlen = flsize - fsize - 2 - mfsize; |
| 359 | 117 |
|
428
15ca2ea93a30
[svn] Sync with upstream CVS. This implements RIX playback.
chainsaw
parents:
359
diff
changeset
|
118 footer = new char[footerlen + 1]; |
|
15ca2ea93a30
[svn] Sync with upstream CVS. This implements RIX playback.
chainsaw
parents:
359
diff
changeset
|
119 f->readString(footer, footerlen); |
|
15ca2ea93a30
[svn] Sync with upstream CVS. This implements RIX playback.
chainsaw
parents:
359
diff
changeset
|
120 footer[footerlen] = '\0'; // Make ASCIIZ string |
|
15ca2ea93a30
[svn] Sync with upstream CVS. This implements RIX playback.
chainsaw
parents:
359
diff
changeset
|
121 } |
| 359 | 122 |
|
637
2b06eb5e472d
[svn] Sync with upstream. Drop hardware OPL2/3 support, it throws warnings and is not used on most modern machines. Added var inits where GCC 4.0 thought it was a good idea.
chainsaw
parents:
428
diff
changeset
|
123 rate = getrate(filename, fp, f); |
| 359 | 124 fp.close(f); |
| 125 rewind(0); | |
| 126 return true; | |
| 127 } | |
| 128 | |
| 129 bool CimfPlayer::update() | |
| 130 { | |
| 131 do { | |
| 132 opl->write(data[pos].reg,data[pos].val); | |
| 133 del = data[pos].time; | |
| 134 pos++; | |
| 135 } while(!del && pos < size); | |
| 136 | |
| 137 if(pos >= size) { | |
| 138 pos = 0; | |
| 139 songend = true; | |
| 140 } | |
| 141 else timer = rate / (float)del; | |
| 142 | |
| 143 return !songend; | |
| 144 } | |
| 145 | |
| 146 void CimfPlayer::rewind(int subsong) | |
| 147 { | |
| 148 pos = 0; del = 0; timer = rate; songend = false; | |
| 149 opl->init(); opl->write(1,32); // go to OPL2 mode | |
| 150 } | |
| 151 | |
| 152 std::string CimfPlayer::gettitle() | |
| 153 { | |
| 154 std::string title; | |
| 155 | |
| 156 title = track_name; | |
| 157 | |
| 158 if(!track_name.empty() && !game_name.empty()) | |
| 159 title += " - "; | |
| 160 | |
| 161 title += game_name; | |
| 162 | |
| 163 return title; | |
| 164 } | |
| 165 | |
|
428
15ca2ea93a30
[svn] Sync with upstream CVS. This implements RIX playback.
chainsaw
parents:
359
diff
changeset
|
166 std::string CimfPlayer::getdesc() |
|
15ca2ea93a30
[svn] Sync with upstream CVS. This implements RIX playback.
chainsaw
parents:
359
diff
changeset
|
167 { |
|
15ca2ea93a30
[svn] Sync with upstream CVS. This implements RIX playback.
chainsaw
parents:
359
diff
changeset
|
168 std::string desc; |
|
15ca2ea93a30
[svn] Sync with upstream CVS. This implements RIX playback.
chainsaw
parents:
359
diff
changeset
|
169 |
|
15ca2ea93a30
[svn] Sync with upstream CVS. This implements RIX playback.
chainsaw
parents:
359
diff
changeset
|
170 if(footer) |
|
15ca2ea93a30
[svn] Sync with upstream CVS. This implements RIX playback.
chainsaw
parents:
359
diff
changeset
|
171 desc = std::string(footer); |
|
15ca2ea93a30
[svn] Sync with upstream CVS. This implements RIX playback.
chainsaw
parents:
359
diff
changeset
|
172 |
|
15ca2ea93a30
[svn] Sync with upstream CVS. This implements RIX playback.
chainsaw
parents:
359
diff
changeset
|
173 if(!remarks.empty() && footer) |
|
15ca2ea93a30
[svn] Sync with upstream CVS. This implements RIX playback.
chainsaw
parents:
359
diff
changeset
|
174 desc += "\n\n"; |
|
15ca2ea93a30
[svn] Sync with upstream CVS. This implements RIX playback.
chainsaw
parents:
359
diff
changeset
|
175 |
|
15ca2ea93a30
[svn] Sync with upstream CVS. This implements RIX playback.
chainsaw
parents:
359
diff
changeset
|
176 desc += remarks; |
|
15ca2ea93a30
[svn] Sync with upstream CVS. This implements RIX playback.
chainsaw
parents:
359
diff
changeset
|
177 |
|
15ca2ea93a30
[svn] Sync with upstream CVS. This implements RIX playback.
chainsaw
parents:
359
diff
changeset
|
178 return desc; |
|
15ca2ea93a30
[svn] Sync with upstream CVS. This implements RIX playback.
chainsaw
parents:
359
diff
changeset
|
179 } |
|
15ca2ea93a30
[svn] Sync with upstream CVS. This implements RIX playback.
chainsaw
parents:
359
diff
changeset
|
180 |
| 359 | 181 /*** private methods *************************************/ |
| 182 | |
|
637
2b06eb5e472d
[svn] Sync with upstream. Drop hardware OPL2/3 support, it throws warnings and is not used on most modern machines. Added var inits where GCC 4.0 thought it was a good idea.
chainsaw
parents:
428
diff
changeset
|
183 float CimfPlayer::getrate(const std::string &filename, const CFileProvider &fp, binistream *f) |
| 359 | 184 { |
|
637
2b06eb5e472d
[svn] Sync with upstream. Drop hardware OPL2/3 support, it throws warnings and is not used on most modern machines. Added var inits where GCC 4.0 thought it was a good idea.
chainsaw
parents:
428
diff
changeset
|
185 if(db) { // Database available |
|
2b06eb5e472d
[svn] Sync with upstream. Drop hardware OPL2/3 support, it throws warnings and is not used on most modern machines. Added var inits where GCC 4.0 thought it was a good idea.
chainsaw
parents:
428
diff
changeset
|
186 f->seek(0, binio::Set); |
|
2b06eb5e472d
[svn] Sync with upstream. Drop hardware OPL2/3 support, it throws warnings and is not used on most modern machines. Added var inits where GCC 4.0 thought it was a good idea.
chainsaw
parents:
428
diff
changeset
|
187 CClockRecord *record = (CClockRecord *)db->search(CAdPlugDatabase::CKey(*f)); |
|
2b06eb5e472d
[svn] Sync with upstream. Drop hardware OPL2/3 support, it throws warnings and is not used on most modern machines. Added var inits where GCC 4.0 thought it was a good idea.
chainsaw
parents:
428
diff
changeset
|
188 if (record && record->type == CAdPlugDatabase::CRecord::ClockSpeed) |
|
2b06eb5e472d
[svn] Sync with upstream. Drop hardware OPL2/3 support, it throws warnings and is not used on most modern machines. Added var inits where GCC 4.0 thought it was a good idea.
chainsaw
parents:
428
diff
changeset
|
189 return record->clock; |
|
2b06eb5e472d
[svn] Sync with upstream. Drop hardware OPL2/3 support, it throws warnings and is not used on most modern machines. Added var inits where GCC 4.0 thought it was a good idea.
chainsaw
parents:
428
diff
changeset
|
190 } |
| 359 | 191 |
|
637
2b06eb5e472d
[svn] Sync with upstream. Drop hardware OPL2/3 support, it throws warnings and is not used on most modern machines. Added var inits where GCC 4.0 thought it was a good idea.
chainsaw
parents:
428
diff
changeset
|
192 // Otherwise the database is either unavailable, or there's no entry for this file |
|
2b06eb5e472d
[svn] Sync with upstream. Drop hardware OPL2/3 support, it throws warnings and is not used on most modern machines. Added var inits where GCC 4.0 thought it was a good idea.
chainsaw
parents:
428
diff
changeset
|
193 if (fp.extension(filename, ".imf")) return 560.0f; |
|
2b06eb5e472d
[svn] Sync with upstream. Drop hardware OPL2/3 support, it throws warnings and is not used on most modern machines. Added var inits where GCC 4.0 thought it was a good idea.
chainsaw
parents:
428
diff
changeset
|
194 if (fp.extension(filename, ".wlf")) return 700.0f; |
|
2b06eb5e472d
[svn] Sync with upstream. Drop hardware OPL2/3 support, it throws warnings and is not used on most modern machines. Added var inits where GCC 4.0 thought it was a good idea.
chainsaw
parents:
428
diff
changeset
|
195 return 700.0f; // default speed for unknown files that aren't .IMF or .WLF |
| 359 | 196 } |
