253 lines
7.1 KiB
C++
253 lines
7.1 KiB
C++
/*************************************************************************/
|
|
/* cp_loader_it_info.cpp */
|
|
/*************************************************************************/
|
|
/* This file is part of: */
|
|
/* GODOT ENGINE */
|
|
/* https://godotengine.org */
|
|
/*************************************************************************/
|
|
/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
|
|
/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
|
|
/* */
|
|
/* Permission is hereby granted, free of charge, to any person obtaining */
|
|
/* a copy of this software and associated documentation files (the */
|
|
/* "Software"), to deal in the Software without restriction, including */
|
|
/* without limitation the rights to use, copy, modify, merge, publish, */
|
|
/* distribute, sublicense, and/or sell copies of the Software, and to */
|
|
/* permit persons to whom the Software is furnished to do so, subject to */
|
|
/* the following conditions: */
|
|
/* */
|
|
/* The above copyright notice and this permission notice shall be */
|
|
/* included in all copies or substantial portions of the Software. */
|
|
/* */
|
|
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
|
|
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
|
|
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
|
|
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
|
|
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
|
|
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
|
|
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
|
/*************************************************************************/
|
|
|
|
#include "cp_loader_it.h"
|
|
|
|
CPLoader::Error CPLoader_IT::load_header(bool p_dont_set) {
|
|
|
|
char aux_songname[26];
|
|
|
|
file->get_byte_array((uint8_t *)aux_songname, 26);
|
|
if (!p_dont_set)
|
|
song->set_name(aux_songname);
|
|
|
|
uint8_t aux_hlmin = file->get_byte();
|
|
uint8_t aux_hlmaj = file->get_byte();
|
|
|
|
if (aux_hlmin == 0) aux_hlmin = 4;
|
|
if (aux_hlmaj == 0) aux_hlmaj = 16;
|
|
|
|
if (!p_dont_set) {
|
|
song->set_row_highlight_minor(aux_hlmin);
|
|
song->set_row_highlight_major(aux_hlmaj);
|
|
}
|
|
|
|
header.ordnum = file->get_word();
|
|
header.insnum = file->get_word();
|
|
header.smpnum = file->get_word();
|
|
header.patnum = file->get_word();
|
|
|
|
header.cwt = file->get_word(); /* Created with tracker (y.xx = 0x0yxx) */
|
|
header.cmwt = file->get_word(); /* Compatible with tracker ver > than val. */
|
|
header.flags = file->get_word();
|
|
|
|
if (!p_dont_set) {
|
|
song->set_stereo(header.flags & 1);
|
|
song->set_linear_slides(header.flags & 8);
|
|
song->set_old_effects(header.flags & 16);
|
|
song->set_compatible_gxx(header.flags & 32);
|
|
song->set_instruments(header.flags & 4);
|
|
}
|
|
|
|
header.special = file->get_word();
|
|
if (!p_dont_set) {
|
|
|
|
song->set_global_volume(file->get_byte());
|
|
song->set_mixing_volume(file->get_byte());
|
|
song->set_speed(file->get_byte());
|
|
song->set_tempo(file->get_byte());
|
|
song->set_stereo_separation(file->get_byte());
|
|
|
|
} else {
|
|
|
|
file->get_byte(); // skip
|
|
file->get_byte(); // skip
|
|
file->get_byte(); // skip
|
|
file->get_byte(); // skip
|
|
file->get_byte(); // skip
|
|
}
|
|
file->get_byte(); // ZERO Byte
|
|
header.msglength = file->get_word();
|
|
header.msgoffset = file->get_dword();
|
|
char chibi[4];
|
|
file->get_byte_array((uint8_t *)chibi, 4);
|
|
header.is_chibi = (chibi[0] == 'C' && chibi[1] == 'H' && chibi[2] == 'B' && chibi[3] == 'I');
|
|
|
|
for (int i = 0; i < 64; i++) {
|
|
|
|
uint8_t panbyte = file->get_byte();
|
|
|
|
uint8_t pan_dst = (panbyte < 65) ? panbyte : 32;
|
|
bool surround_dst = (panbyte == 100);
|
|
bool mute_dst = (panbyte >= 128);
|
|
|
|
if (!p_dont_set) {
|
|
song->set_channel_pan(i, pan_dst);
|
|
song->set_channel_surround(i, surround_dst);
|
|
song->set_channel_mute(i, mute_dst);
|
|
}
|
|
}
|
|
for (int i = 0; i < 64; i++) {
|
|
unsigned char cv = file->get_byte();
|
|
if (!p_dont_set)
|
|
song->set_channel_volume(i, cv);
|
|
}
|
|
|
|
CP_ERR_COND_V(file->eof_reached(), FILE_CORRUPTED);
|
|
CP_ERR_COND_V(file->get_error(), FILE_CORRUPTED);
|
|
|
|
return FILE_OK;
|
|
}
|
|
|
|
CPLoader::Error CPLoader_IT::load_effects() {
|
|
|
|
if (!header.is_chibi)
|
|
return FILE_OK; //no effects, regular IT file
|
|
|
|
/* GOTO End of IT header */
|
|
file->seek(0xC0 + header.ordnum + header.insnum * 4 + header.smpnum * 4 + header.patnum * 4);
|
|
|
|
if (file->get_byte() > 0) //not made with this version, ignore extended info
|
|
return FILE_OK;
|
|
|
|
/* Chibitracker Extended info */
|
|
|
|
switch (file->get_byte()) {
|
|
|
|
case CPSong::REVERB_MODE_ROOM: {
|
|
|
|
song->set_reverb_mode(CPSong::REVERB_MODE_ROOM);
|
|
} break;
|
|
case CPSong::REVERB_MODE_STUDIO_SMALL: {
|
|
|
|
song->set_reverb_mode(CPSong::REVERB_MODE_STUDIO_SMALL);
|
|
|
|
} break;
|
|
case CPSong::REVERB_MODE_STUDIO_MEDIUM: {
|
|
|
|
song->set_reverb_mode(CPSong::REVERB_MODE_STUDIO_MEDIUM);
|
|
|
|
} break;
|
|
case CPSong::REVERB_MODE_STUDIO_LARGE: {
|
|
|
|
song->set_reverb_mode(CPSong::REVERB_MODE_STUDIO_LARGE);
|
|
|
|
} break;
|
|
case CPSong::REVERB_MODE_HALL: {
|
|
|
|
song->set_reverb_mode(CPSong::REVERB_MODE_HALL);
|
|
|
|
} break;
|
|
case CPSong::REVERB_MODE_SPACE_ECHO: {
|
|
|
|
song->set_reverb_mode(CPSong::REVERB_MODE_SPACE_ECHO);
|
|
|
|
} break;
|
|
|
|
case CPSong::REVERB_MODE_ECHO: {
|
|
|
|
song->set_reverb_mode(CPSong::REVERB_MODE_ECHO);
|
|
|
|
} break;
|
|
case CPSong::REVERB_MODE_DELAY: {
|
|
|
|
song->set_reverb_mode(CPSong::REVERB_MODE_DELAY);
|
|
|
|
} break;
|
|
case CPSong::REVERB_MODE_HALF_ECHO: {
|
|
|
|
song->set_reverb_mode(CPSong::REVERB_MODE_HALF_ECHO);
|
|
|
|
} break;
|
|
}
|
|
|
|
//chorus
|
|
song->set_chorus_speed_hz10(file->get_byte());
|
|
song->set_chorus_delay_ms(file->get_byte());
|
|
song->set_chorus_depth_ms10(file->get_byte());
|
|
song->set_chorus_separation_ms(file->get_byte());
|
|
|
|
for (int i = 0; i < CPPattern::WIDTH; i++) {
|
|
song->set_channel_reverb(i, file->get_byte());
|
|
}
|
|
for (int i = 0; i < CPPattern::WIDTH; i++) {
|
|
song->set_channel_chorus(i, file->get_byte());
|
|
}
|
|
|
|
return FILE_OK;
|
|
}
|
|
|
|
CPLoader::Error CPLoader_IT::load_message() {
|
|
|
|
if (!(header.special & 1)) {
|
|
|
|
return FILE_OK;
|
|
}
|
|
|
|
file->seek(header.msgoffset);
|
|
|
|
//(void*)tmpmsg=malloc(header.msglength+1);
|
|
|
|
char message[8000];
|
|
|
|
char *tmpmsg = message;
|
|
|
|
file->get_byte_array((uint8_t *)tmpmsg, header.msglength);
|
|
tmpmsg[header.msglength] = 0;
|
|
|
|
for (int i = 0; i < header.msglength; i++)
|
|
if (tmpmsg[i] == '\r') tmpmsg[i] = '\n';
|
|
|
|
song->set_message(tmpmsg);
|
|
|
|
return FILE_OK;
|
|
}
|
|
|
|
CPLoader::Error CPLoader_IT::load_orders() {
|
|
|
|
file->seek(0xC0);
|
|
|
|
for (int i = 0; i < header.ordnum; i++) {
|
|
|
|
uint8_t aux_order = file->get_byte();
|
|
CPOrder order = CP_ORDER_NONE;
|
|
|
|
if (i >= CPSong::MAX_ORDERS)
|
|
continue;
|
|
if (aux_order == 254) {
|
|
|
|
order = CP_ORDER_BREAK;
|
|
|
|
} else if (aux_order < 200) {
|
|
|
|
order = aux_order;
|
|
//nothing!
|
|
}
|
|
song->set_order(i, order);
|
|
}
|
|
|
|
if (file->eof_reached() || file->get_error()) {
|
|
|
|
return FILE_CORRUPTED;
|
|
}
|
|
|
|
return FILE_OK;
|
|
}
|