]> 4ch.mooo.com Git - 16.git/blob - 16/adplug/adplug/test/playertest.cpp
wwww~
[16.git] / 16 / adplug / adplug / test / playertest.cpp
1 /*
2  * Adplug - Replayer for many OPL2/OPL3 audio file formats.
3  * Copyright (C) 1999 - 2008 Simon Peter, <dn.tlp@gmx.net>, et al.
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  * playertest.cpp - Test AdPlug replayers, by Simon Peter <dn.tlp@gmx.net>
20  */
21
22 #include <stdlib.h>
23 #include <stdio.h>
24 #include <cstring>
25 #include <string>
26
27 #include "../src/adplug.h"
28 #include "../src/opl.h"
29
30 #ifdef MSDOS
31 #       define DIR_DELIM        "\\"
32 #else
33 #       define DIR_DELIM        "/"
34 #endif
35
36 /***** Local variables *****/
37
38 // List of all filenames to test
39 static const char *filelist[] = {
40   "SONG1.sng",          // Adlib Tracker
41   "2001.MKJ",           // MK-Jamz
42   "ADAGIO.DFM",         // Digital-FM
43   "adlibsp.s3m",        // Scream Tracker 3
44   "ALLOYRUN.RAD",       // Reality AdLib Tracker
45   "ARAB.BAM",           // Bob's AdLib Music
46   "BEGIN.KSM",          // Ken Silverman
47   "BOOTUP.M",           // Ultima 6
48   "CHILD1.XSM",         // eXtra Simple Music
49   "DTM-TRK1.DTM",       // DeFy Adlib Tracker
50   "fdance03.dmo",       // TwinTrack
51   "ice_thnk.sci",       // Sierra
52   "inc.raw",            // RAW
53   "loudness.lds",       // Loudness
54   "MARIO.A2M",          // AdLib Tracker 2
55   "mi2.laa",            // LucasArts
56   "michaeld.cmf",       // Creative Music Format
57   "PLAYMUS1.SNG",       // SNGPlay
58   "rat.xad",            // xad: rat
59   "REVELAT.SNG",        // Faust Music Creator
60   "SAILOR.CFF",         // Boomtracker
61   "samurai.dro",        // DOSBox v0.1 (one-byte hardware type)
62   "doofus.dro",         // DOSBox v0.1 (four-byte hardware type)
63   "SCALES.SA2",         // Surprise! Adlib Tracker 2
64   "SMKEREM.HSC",        // HSC-Tracker
65   "TOCCATA.MAD",        // Mlat Adlib Tracker
66   "TUBES.SAT",          // Surprise! Adlib Tracker
67   "TU_BLESS.AMD",       // AMUSIC
68   "VIB_VOL3.D00",       // EdLib Packed
69   "WONDERIN.WLF",       // Apogee
70   "bmf1_2.xad",         // xad: BMF
71   "flash.xad",          // xad: flash
72   "HIP_D.ROL",          // Visual Composer
73   "hybrid.xad",         // xad: hybrid
74   "hyp.xad",            // xad: hyp
75   "psi1.xad",           // xad: PSI
76   "SATNIGHT.HSP",       // HSC Packed
77   "blaster2.msc",       // AdLib MSCplay
78   "RI051.RIX",          // Softstar RIX OPL Music
79   "DUNE19.ADL",         // Westwood ADL
80   "DEMO4.JBM",          // JBM Adlib Music
81   "dro_v2.dro",         // DOSBox DRO v2.0
82   NULL
83 };
84
85 // String holding the relative path to the source directory
86 static const char *srcdir;
87
88 /***** Testopl *****/
89
90 class Testopl: public Copl
91 {
92 public:
93   Testopl(const std::string filename)
94   {
95     f = fopen(filename.c_str(), "w");
96     if(!f) std::cerr << "Error opening for writing: " << filename << std::endl;
97
98     currType = TYPE_OPL3;
99   }
100
101   virtual ~Testopl()
102   {
103     if(f) fclose(f);
104   }
105
106   void update(CPlayer *p)
107   {
108     if(!f) return;
109     fprintf(f, "r%.2f\n", p->getrefresh());
110   }
111
112   // template methods
113   void write(int reg, int val)
114   {
115     if(reg > 255 || val > 255 || reg < 0 || val < 0)
116       std::cerr << "Warning: The player is writing data out of range! (reg = "
117                 << std::hex << reg << ", val = " << val << ")\n";
118     if(!f) return;
119     fprintf(f, "%x <- %x\n", reg, val);
120   }
121
122   void setchip(int n)
123   {
124     Copl::setchip(n);
125
126     if(!f) return;
127     fprintf(f, "setchip(%d)\n", n);
128   }
129
130   void init()
131   {
132     if(!f) return;
133     fprintf(f, "init\n");
134   }
135
136 private:
137   FILE  *f;
138 };
139
140 /***** Local functions *****/
141
142 static bool diff(const std::string fn1, const std::string fn2)
143   /*
144    * Compares files 'fn1' and 'fn2' line by line and returns true if they are
145    * equal or false otherwise. A line is at most 79 characters in length or the
146    * comparison will fail.
147    */
148 {
149   FILE  *f1, *f2;
150   bool  retval = true;
151
152   // open both files
153   if(!(f1 = fopen(fn1.c_str(), "r"))) return false;
154   if(!(f2 = fopen(fn2.c_str(), "r"))) { fclose(f1); return false; }
155
156   // compare both files line by line
157   char  *s1 = (char *)malloc(80), *s2 = (char *)malloc(80);
158   while(!(feof(f1) || feof(f2))) {
159     fgets(s1, 80, f1);
160     fgets(s2, 80, f2);
161     if(strncmp(s1, s2, 79)) {
162       retval = false;
163       break;
164     }
165   }
166   free(s1), free(s2);
167   if(feof(f1) != feof(f2))
168     retval = false;
169
170   // close both files
171   fclose(f1), fclose(f2);
172   return retval;
173 }
174
175 static bool testplayer(const std::string filename)
176   /*
177    * Tests playback of file 'filename' by comparing its RAW output with a
178    * prerecorded original and returns true if they match, false otherwise.
179    */
180 {
181   std::string   fn = std::string(srcdir) + DIR_DELIM + filename;
182 #ifdef __WATCOMC__
183   std::string   testfn = tmpnam(NULL);
184 #else
185   std::string   testfn = filename + ".test";
186 #endif
187   std::string   reffn = fn.substr(0, fn.find_last_of(".")) + ".ref";
188   Testopl       *opl = new Testopl(testfn);
189   CPlayer       *p = CAdPlug::factory(fn, opl);
190
191   if(!p) {
192     std::cout << "Error loading: " << fn << std::endl;
193     delete opl; return false;
194   }
195
196   // Output file information
197   std::cout << "Testing format: " << p->gettype() << " - ";
198
199   // Write whole file to disk
200   while(p->update())
201     opl->update(p);
202
203   delete p;
204   delete opl;
205
206   if(diff(reffn, testfn)) {
207     std::cout << "OK\n";
208     remove(std::string(testfn).c_str());
209     return true;
210   } else {
211     std::cout << "FAIL\n";
212     return false;
213   }
214 }
215
216 /***** Main program *****/
217
218 int main(int argc, char *argv[])
219 {
220   int   i;
221   bool  retval = true;
222
223   // Set path to source directory
224   srcdir = getenv("srcdir");
225   if(!srcdir) srcdir = ".";
226
227   // Try all files one by one
228   if(argc > 1) {
229     for(i = 1; i < argc; i++)
230       if(!testplayer(argv[i]))
231         retval = false;
232   } else
233     for(i = 0; filelist[i] != NULL; i++)
234       if(!testplayer(filelist[i]))
235         retval = false;
236
237   return retval ? EXIT_SUCCESS : EXIT_FAILURE;
238 }