1 /* OpenCP Module Player 2 * copyright (c) '94-'10 Niklas Beisert <nbeisert@physik.tu-muenchen.de> 3 * 4 * ITPlay Instrument display code 5 * 6 * This program is free software; you can redistribute it and/or modify 7 * it under the terms of the GNU General Public License as published by 8 * the Free Software Foundation; either version 2 of the License, or 9 * (at your option) any later version. 10 * 11 * This program is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 * GNU General Public License for more details. 15 * 16 * You should have received a copy of the GNU General Public License 17 * along with this program; if not, write to the Free Software 18 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 19 * 20 * revision history: (please note changes here) 21 * -nb980510 Niklas Beisert <nbeisert@physik.tu-muenchen.de> 22 * -first release main(int,char **)23 * -kb980717 Tammo Hinrichs <opencp@gmx.net> 24 * -changed some minor things for better output 25 */ 26 27 #include "config.h" 28 #include <stdlib.h> 29 #include <string.h> 30 #include "types.h" 31 #include "dev/mcp.h" 32 #include "stuff/poutput.h" 33 #include "cpiface/cpiface.h" 34 #include "itplay.h" 35 36 static int instnum; 37 static int sampnum; 38 static uint8_t *plInstUsed = NULL; 39 static uint8_t *plSampUsed = NULL; 40 static uint8_t *plBigInstNum = NULL; 41 static uint16_t *plBigSampNum = NULL; 42 43 /* extern uint8_t plNoteStr[132][4]; cpiface.h */ 44 45 static const struct it_instrument *plInstr; 46 static const struct it_sampleinfo *plSamples; 47 static const struct it_sample *plModSamples; 48 49 static uint8_t plInstShowFreq; 50 51 static void itDisplayIns40(uint16_t *buf, int n, int plInstMode) 52 { 53 char col=plInstMode?0x07:"\x08\x08\x0B\x0A"[plInstUsed[n]]; 54 writestring(buf, 0, col, (!plInstMode&&plInstUsed[n])?"\xfe##: ":" ##: ", 5); 55 writenum(buf, 1, col, n+1, 16, 2, 0); 56 writestring(buf, 5, col, plInstr[n].name, 35); 57 } 58 59 static void itDisplayIns33(uint16_t *buf, int n, int plInstMode) 60 { 61 char col=plInstMode?0x07:"\x08\x08\x0B\x0A"[plInstUsed[n]]; 62 writestring(buf, 0, col, (!plInstMode&&plInstUsed[n])?"\xfe##: ":" ##: ", 5); 63 writenum(buf, 1, col, n+1, 16, 2, 0); 64 writestring(buf, 5, col, plInstr[n].name, 28); 65 } 66 67 static void itDisplayIns52(uint16_t *buf, int n, int plInstMode) 68 { 69 char col=plInstMode?0x07:"\x08\x08\x0B\x0A"[plInstUsed[n]]; 70 writestring(buf, 0, col, (!plInstMode&&plInstUsed[n])?" \xfe##: ":" ##: ", 9); 71 writenum(buf, 5, col, n+1, 16, 2, 0); 72 writestring(buf, 9, col, plInstr[n].name, 43); 73 } 74 75 static void itDisplayIns80(uint16_t *buf, int n, int plInstMode) 76 { 77 char col; 78 writestring(buf, 0, 0, "", 80); 79 80 if (plBigInstNum[n]!=0xFF) 81 { 82 const struct it_instrument *ins=&plInstr[plBigInstNum[n]]; 83 col=plInstMode?0x07:"\x08\x08\x0B\x0A"[plInstUsed[plBigInstNum[n]]]; 84 writestring(buf, 0, col, (!plInstMode&&plInstUsed[plBigInstNum[n]])?"\xfe##: ":" ##: ", 5); 85 writenum(buf, 1, col, plBigInstNum[n]+1, 16, 2, 0); 86 writestring(buf, 5, col, ins->name, 31); 87 } 88 89 if (plBigSampNum[n]!=0xFFFF) 90 { 91 const struct it_sample *sm=&plModSamples[plBigSampNum[n]]; 92 const struct it_sampleinfo *si=&plSamples[sm->handle]; 93 94 col=plInstMode?0x07:"\x08\x08\x0B\x0A"[plSampUsed[plBigSampNum[n]]]; 95 writestring(buf, 34, col, (!plInstMode&&plSampUsed[plBigSampNum[n]])?"\xfe###: ":" ###: ", 6); 96 writenum(buf, 35, col, plBigSampNum[n], 16, 3, 0); 97 if (si->type&mcpSampLoop) 98 { 99 _writenum(buf, 40, col, si->loopend, 10, 6); 100 _writenum(buf, 47, col, si->loopend-si->loopstart, 10, 6); 101 if (si->type&mcpSampBiDi) 102 writestring(buf, 53, col, "\x1D", 1); 103 } else { 104 _writenum(buf, 40, col, si->length, 10, 6); 105 writestring(buf, 52, col, "-", 1); 106 } 107 writestring(buf, 55, col, (si->type&mcpSamp16Bit)?"16":" 8", 2); 108 writestring(buf, 57, col, (si->type&mcpSampRedRate4)?"\xac":(si->type&mcpSampRedRate2)?"\xab":(si->type&mcpSampRedBits)?"!":" ", 2); 109 110 if (!plInstShowFreq) 111 { 112 writestring(buf, 60, col, plNoteStr[(sm->normnote+60*256)>>8], 3); 113 writenum(buf, 64, col, sm->normnote&0xFF, 16, 2, 0); 114 } else 115 if (plInstShowFreq==1) 116 writenum(buf, 60, col, mcpGetFreq8363(-sm->normnote), 10, 6, 1); 117 else 118 writenum(buf, 60, col, si->samprate, 10, 6, 1); 119 120 writenum(buf, 68, col, sm->vol, 16, 2, 0); 121 /* 122 if (ins->stdpan!=-1) 123 writenum(buf, 72, col, ins->stdpan, 16, 2, 0); 124 else 125 writestring(buf, 72, col, " -", 2); 126 if (ins->volenv!=0xFFFF) 127 writestring(buf, 76, col, "v", 1); 128 if (ins->panenv!=0xFFFF) 129 writestring(buf, 77, col, "p", 1); 130 if (ins->vibdepth&&sm.vibrate) 131 writestring(buf, 78, col, "~", 1); 132 if (ins->fadeout) 133 writestring(buf, 79, col, "\x19", 1); 134 */ 135 } 136 } 137 138 static void itDisplayIns132(uint16_t *buf, int n, int plInstMode) 139 { 140 char col; 141 writestring(buf, 0, 0, "", 132); 142 143 if (plBigInstNum[n]!=0xFF) 144 { 145 const struct it_instrument *ins=&plInstr[plBigInstNum[n]]; 146 col=plInstMode?0x07:"\x08\x08\x0B\x0A"[plInstUsed[plBigInstNum[n]]]; 147 writestring(buf, 0, col, (!plInstMode&&plInstUsed[plBigInstNum[n]])?"\xfe##: ":" ##: ", 5); 148 writenum(buf, 1, col, plBigInstNum[n]+1, 16, 2, 0); 149 writestring(buf, 5, col, ins->name, 35); 150 } 151 152 if (plBigSampNum[n]!=0xFFFF) 153 { 154 const struct it_sample *sm=&plModSamples[plBigSampNum[n]]; 155 const struct it_sampleinfo *si=&plSamples[sm->handle]; 156 157 col=plInstMode?0x07:"\x08\x08\x0B\x0A"[plSampUsed[plBigSampNum[n]]]; 158 writestring(buf, 34, col, (!plInstMode&&plSampUsed[plBigSampNum[n]])?"\xfe###: ":" ###: ", 6); 159 writenum(buf, 35, col, plBigSampNum[n], 16, 3, 0); 160 writestring(buf, 40, col, sm->name, 28); 161 if (si->type&mcpSampLoop) 162 { 163 _writenum(buf, 70, col, si->loopend, 10, 6); 164 _writenum(buf, 77, col, si->loopend-si->loopstart, 10, 6); 165 if (si->type&mcpSampBiDi) 166 writestring(buf, 83, col, "\x1D", 1); 167 } else { 168 _writenum(buf, 70, col, si->length, 10, 6); 169 writestring(buf, 82, col, "-", 1); 170 } 171 writestring(buf, 85, col, (si->type&mcpSamp16Bit)?"16":" 8", 2); 172 writestring(buf, 87, col, (si->type&mcpSampRedRate4)?"\xac":(si->type&mcpSampRedRate2)?"\xab":(si->type&mcpSampRedBits)?"!":" ", 2); 173 174 if (!plInstShowFreq) 175 { 176 writestring(buf, 90, col, plNoteStr[(sm->normnote+60*256)>>8], 3); 177 writenum(buf, 94, col, sm->normnote&0xFF, 16, 2, 0); 178 } else if (plInstShowFreq==1) 179 writenum(buf, 90, col, mcpGetFreq8363(-sm->normnote), 10, 6, 1); 180 else 181 writenum(buf, 90, col, si->samprate, 10, 6, 1); 182 183 writenum(buf, 98, col, sm->vol, 16, 2, 0); 184 /* 185 if (ins->stdpan!=-1) 186 writenum(buf, 102, col, ins->stdpan, 16, 2, 0); 187 else 188 writestring(buf, 102, col, " -", 2); 189 190 if (ins->volenv!=0xFFFF) 191 writestring(buf, 106, col, "v", 1); 192 if (ins->panenv!=0xFFFF) 193 writestring(buf, 107, col, "p", 1); 194 if (ins->vibdepth&&ins->vibrate) 195 writestring(buf, 108, col, "~", 1); 196 197 if (ins->fadeout) 198 writenum(buf, 110, col, ins->fadeout, 16, 4, 1); 199 else 200 writestring(buf, 113, col, "-", 1); 201 */ 202 } 203 } 204 205 static void itDisplayIns(uint16_t *buf, int len, int n, int plInstMode) 206 { 207 switch (len) 208 { 209 case 33: 210 itDisplayIns33(buf, n, plInstMode); 211 break; 212 case 40: 213 itDisplayIns40(buf, n, plInstMode); 214 break; 215 case 52: 216 itDisplayIns52(buf, n, plInstMode); 217 break; 218 case 80: 219 itDisplayIns80(buf, n, plInstMode); 220 break; 221 case 132: 222 itDisplayIns132(buf, n, plInstMode); 223 break; 224 } 225 } 226 227 static void (*Mark)(uint8_t *, uint8_t *); 228 229 static void itMark(void) 230 { 231 int i; 232 for (i=0; i<instnum; i++) 233 if (plInstUsed[i]) 234 plInstUsed[i]=1; 235 for (i=0; i<sampnum; i++) 236 if (plSampUsed[i]) 237 plSampUsed[i]=1; 238 Mark(plInstUsed, plSampUsed); 239 } 240 241 static void itpInstClear(void) 242 { 243 memset(plInstUsed, 0, instnum); 244 memset(plSampUsed, 0, sampnum); 245 } 246 247 static void Done(void) 248 { 249 if (plInstUsed) 250 { 251 free(plInstUsed); 252 plInstUsed=NULL; 253 } 254 if (plSampUsed) 255 { 256 free(plSampUsed); 257 plSampUsed=NULL; 258 } 259 if (plBigInstNum) 260 { 261 free(plBigInstNum); 262 plBigInstNum=NULL; 263 } 264 if (plBigSampNum) 265 { 266 free(plBigSampNum); 267 plBigSampNum=NULL; 268 } 269 } 270 271 void __attribute__ ((visibility ("internal"))) itpInstSetup(const struct it_instrument *ins, int nins, const struct it_sample *smp, int nsmp, const struct it_sampleinfo *smpi, /*int unused,*/ int type, void (*MarkyBoy)(uint8_t *, uint8_t *)) 272 { 273 int i,j; 274 int biginstlen=0; 275 struct insdisplaystruct plInsDisplay; 276 277 instnum=nins; 278 sampnum=nsmp; 279 280 plSampUsed=malloc(sizeof(uint8_t)*sampnum); 281 plInstUsed=malloc(sizeof(uint8_t)*instnum); 282 if (!plSampUsed||!plInstUsed) 283 return; 284 285 itpInstClear(); 286 287 Mark=MarkyBoy; 288 289 plInstr=ins; 290 plModSamples=smp; 291 plSamples=smpi; 292 293 for (i=0; i<instnum; i++) 294 { 295 const struct it_instrument *ins=&plInstr[i]; 296 int num=0; 297 298 for (j=0; j<IT_KEYTABS; j++) 299 if (ins->keytab[j][1]&&(ins->keytab[j][1]<=sampnum)) 300 if (plModSamples[ins->keytab[j][1]-1].handle<nsmp) 301 plSampUsed[ins->keytab[j][1]-1]=1; 302 for (j=0; j<sampnum; j++) 303 if (plSampUsed[j]) 304 num++; 305 biginstlen+=num?num:1; 306 } 307 plBigInstNum=malloc(sizeof(uint8_t)*biginstlen); 308 plBigSampNum=malloc(sizeof(uint16_t)*biginstlen); 309 if (!plBigInstNum||!plBigSampNum) 310 return; 311 memset(plBigInstNum, -1, biginstlen); 312 memset(plBigSampNum, -1, biginstlen*2); 313 314 biginstlen=0; 315 for (i=0; i<instnum; i++) 316 { 317 const struct it_instrument *ins=&plInstr[i]; 318 int num=0; 319 320 memset(plSampUsed, 0, sampnum); 321 322 for (j=0; j<IT_KEYTABS; j++) 323 if (ins->keytab[j][1]&&(ins->keytab[j][1]<=sampnum)) 324 if (plModSamples[ins->keytab[j][1]-1].handle<nsmp) 325 plSampUsed[ins->keytab[j][1]-1]=1; 326 327 plBigInstNum[biginstlen]=i; 328 for (j=0; j<sampnum; j++) 329 if (plSampUsed[j]) 330 plBigSampNum[biginstlen+num++]=j; 331 332 biginstlen+=num?num:1; 333 } 334 335 plInstShowFreq=type; 336 plInsDisplay.Clear=itpInstClear; 337 /* 338 plInsDisplay.n40=instnum; 339 plInsDisplay.n52=instnum; 340 plInsDisplay.n80=biginstlen; 341 */ 342 plInsDisplay.height=instnum; 343 plInsDisplay.bigheight=biginstlen; 344 plInsDisplay.title80=plInstShowFreq? 345 " ## instrument name / song message length replen bit samprate vol pan flgs": 346 " ## instrument name / song message length replen bit base ft vol pan flgs"; 347 plInsDisplay.title132=plInstShowFreq? 348 " ## instrument name / song message sample name length replen bit samprate vol pan fl fade ": 349 " ## instrument name / song message sample name length replen bit base ft vol pan fl fade "; 350 351 plInsDisplay.Mark=itMark; 352 plInsDisplay.Display=itDisplayIns; 353 plInsDisplay.Done=Done; 354 itpInstClear(); 355 plUseInstruments(&plInsDisplay); 356 } 357