/* * PSX-Tools Bundle Pack * Copyright (C) 1998 Heiko Eissfeldt * portions used& Chris Smith * Modified by Yazoo, then by * Nicolas "Pixel" Noble * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include #include #include #include #include #include static int do_decode_L2(unsigned char in[(L2_RAW+L2_Q+L2_P)], unsigned char out[L2_RAW]) { return 0; } #endif #define MAX_SUB_DEL 8 static unsigned char sub_delay_line[MAX_SUB_DEL][LSUB_RAW+LSUB_Q+LSUB_P]; static unsigned sub_del_index; /* R-W Subchannel en/decoder */ int do_encode_sub(unsigned char in[LSUB_RAW*PACKETS_PER_SUBCHANNELFRAME], unsigned char out[(LSUB_RAW+LSUB_Q+LSUB_P)*PACKETS_PER_SUBCHANNELFRAME], int delay1, int permute) { int i; if (in == out) return -1; for (i = 0; i < PACKETS_PER_SUBCHANNELFRAME; i++) { int j; unsigned char t; memcpy(out, in, (LSUB_RAW)); /* build Q parity */ encode_LSUB_Q(out); /* build P parity */ encode_LSUB_P(out); if (permute) { /* permute */ t = out[1]; out[1] = out[18]; out[18] = t; t = out[2]; out[2] = out[ 5]; out[ 5] = t; t = out[3]; out[3] = out[23]; out[23] = t; } if (delay1) { /* shift through delay_line */ for (j = 0; j < LSUB_RAW+LSUB_Q+LSUB_P; j++) { if ((j % MAX_SUB_DEL) != 0) { t = sub_delay_line[(sub_del_index) % MAX_SUB_DEL][j]; sub_delay_line[(sub_del_index + j) % MAX_SUB_DEL][j] = out[j]; out[j] = t; } } } sub_del_index++; out += LSUB_RAW+LSUB_Q+LSUB_P; in += LSUB_RAW; } return 0; } int do_decode_sub( unsigned char in[(LSUB_RAW+LSUB_Q+LSUB_P)*PACKETS_PER_SUBCHANNELFRAME], unsigned char out[LSUB_RAW*PACKETS_PER_SUBCHANNELFRAME], int delay1, int permute) { int i; if (in == out) return -1; for (i = 0; i < PACKETS_PER_SUBCHANNELFRAME; i++) { int j; unsigned char t; if (delay1) { /* shift through delay_line */ for (j = 0; j < LSUB_RAW+LSUB_Q+LSUB_P; j++) { if ((j % MAX_SUB_DEL) != MAX_SUB_DEL-1) { t = sub_delay_line[(sub_del_index) % MAX_SUB_DEL][j]; sub_delay_line[(sub_del_index + (MAX_SUB_DEL - j)) % MAX_SUB_DEL][j] = in[j]; in[j] = t; } } } if (permute) { /* permute */ t = in[1]; in[1] = in[18]; in[18] = t; t = in[2]; in[2] = in[ 5]; in[ 5] = t; t = in[3]; in[3] = in[23]; in[23] = t; } /* build P parity */ decode_LSUB_P(in); /* build Q parity */ decode_LSUB_Q(in); memcpy(out, in, LSUB_QRAW); memcpy(out+LSUB_QRAW, in+LSUB_QRAW+LSUB_Q, LSUB_RAW-LSUB_QRAW); sub_del_index++; in += LSUB_RAW+LSUB_Q+LSUB_P; out += LSUB_RAW; } return 0; } static int sectortype = MODE_0; int get_sector_type(void) { return sectortype; } int set_sector_type(int st) { switch(st) { case MODE_0: case MODE_1: case MODE_2: case MODE_2_FORM_1: case MODE_2_FORM_2: sectortype = st; default: return -1; } return 0; } /* ------------- --------------*/ #ifdef MAIN #define DO_L1 1 #define DO_L2 2 #define DO_SUB 4 static const unsigned sect_size[8][2] = { /* nothing */ {0,0}, /* Layer 1 decode/encode */ { (L1_RAW+L1_Q+L1_P)*FRAMES_PER_SECTOR, L1_RAW*FRAMES_PER_SECTOR}, /* Layer 2 decode/encode */ { 16+L2_RAW+12+L2_Q+L2_P, L2_RAW}, /* Layer 1 and 2 decode/encode */ { (L1_RAW+L1_Q+L1_P)*FRAMES_PER_SECTOR, L1_RAW*FRAMES_PER_SECTOR}, /* Subchannel decode/encode */ { (LSUB_RAW+LSUB_Q+LSUB_P)*PACKETS_PER_SUBCHANNELFRAME, LSUB_RAW*PACKETS_PER_SUBCHANNELFRAME}, /* Layer 1 and subchannel decode/encode */ { (L1_RAW+L1_Q+L1_P)*FRAMES_PER_SECTOR + (LSUB_RAW+LSUB_Q+LSUB_P)*PACKETS_PER_SUBCHANNELFRAME, LSUB_RAW*PACKETS_PER_SUBCHANNELFRAME + L1_RAW*FRAMES_PER_SECTOR}, /* Layer 2 and subchannel decode/encode */ { L2_RAW+L2_Q+L2_P+ (LSUB_RAW+LSUB_Q+LSUB_P)*PACKETS_PER_SUBCHANNELFRAME, LSUB_RAW*PACKETS_PER_SUBCHANNELFRAME + L2_RAW}, /* Layer 1, 2 and subchannel decode/encode */ { (L1_RAW+L1_Q+L1_P)*FRAMES_PER_SECTOR + (LSUB_RAW+LSUB_Q+LSUB_P)*PACKETS_PER_SUBCHANNELFRAME, LSUB_RAW*PACKETS_PER_SUBCHANNELFRAME + L1_RAW*FRAMES_PER_SECTOR}, }; int main(int argc, char **argv) { int encode = 1; int mask = DO_L2; FILE * infp; FILE * outfp; unsigned address = 0; unsigned char *l1_inbuf; unsigned char *l1_outbuf; unsigned char *l2_inbuf; unsigned char *l2_outbuf; unsigned char *sub_inbuf; unsigned char *sub_outbuf; unsigned char *last_outbuf; unsigned char inbuf[(LSUB_RAW+LSUB_Q+LSUB_P)*PACKETS_PER_SUBCHANNELFRAME + (L1_RAW+L1_Q+L1_P)*FRAMES_PER_SECTOR]; unsigned char outbuf[(LSUB_RAW+LSUB_Q+LSUB_P)*PACKETS_PER_SUBCHANNELFRAME + (L1_RAW+L1_Q+L1_P)*FRAMES_PER_SECTOR]; unsigned load_offset; l1_inbuf = l2_inbuf = sub_inbuf = inbuf; l1_outbuf = l2_outbuf = sub_outbuf = last_outbuf = outbuf; infp = fopen("sectors_in", "rb"); outfp = fopen("sectors_out", "wb"); sectortype= MODE_2_FORM_1; address = 0 + 75*2; switch (sectortype) { case MODE_1: case MODE_2: load_offset = 16; break; case MODE_2_FORM_1: case MODE_2_FORM_2: load_offset = 24; break; default: load_offset = 0; } while(1) { if (1 != fread(inbuf+load_offset, sect_size[mask][encode], 1, infp)) { perror(""); break; } if (encode == 1) { if (mask & DO_L2) { switch (sectortype) { case MODE_0: break; case MODE_1: break; case MODE_2: if (1 != fread(inbuf+load_offset+ sect_size[mask][encode], 2336 - sect_size[mask][encode], 1, infp)) { perror(""); break; } break; case MODE_2_FORM_1: break; case MODE_2_FORM_2: if (1 != fread(inbuf+load_offset+ sect_size[mask][encode], 2324 - sect_size[mask][encode], 1, infp)) { perror(""); break; } break; default: if (1 != fread(inbuf+load_offset+ sect_size[mask][encode], 2448 - sect_size[mask][encode], 1, infp)) { perror(""); break; } memset(inbuf,0,16); /*memset(inbuf+16+2048,0,12+272);*/ break; } do_encode_L2(l2_inbuf, MODE_1, address); if (0) scramble_L2(l2_inbuf); last_outbuf = l1_inbuf = l2_inbuf; l1_outbuf = l2_inbuf; sub_inbuf = l2_inbuf + L2_RAW; sub_outbuf = l2_outbuf + 12 + 4+ L2_RAW+4+ 8+ L2_Q+L2_P; } if (mask & DO_L1) { do_encode_L1(l1_inbuf, l1_outbuf,1,1,1,1); last_outbuf = l1_outbuf; sub_inbuf = l1_inbuf + L1_RAW*FRAMES_PER_SECTOR; sub_outbuf = l1_outbuf + (L1_RAW+L1_Q+L1_P)*FRAMES_PER_SECTOR; } if (mask & DO_SUB) { do_encode_sub(sub_inbuf, sub_outbuf, 0, 0); } } else { if (mask & DO_L1) { do_decode_L1(l1_inbuf, l1_outbuf,1,1,1,1); last_outbuf = l2_inbuf = l1_outbuf; l2_outbuf = l1_inbuf; sub_inbuf = l1_inbuf + (L1_RAW+L1_Q+L1_P)*FRAMES_PER_SECTOR; sub_outbuf = l1_outbuf + L1_RAW*FRAMES_PER_SECTOR; } if (mask & DO_L2) { do_decode_L2(l2_inbuf, l2_outbuf); last_outbuf = l2_outbuf; sub_inbuf = l2_inbuf + L2_RAW+L2_Q+L2_P; sub_outbuf = l2_outbuf + L2_RAW; } if (mask & DO_SUB) { do_decode_sub(sub_inbuf, sub_outbuf, 1, 1); } } if (1 != fwrite(last_outbuf, sect_size[mask][1 - encode], 1, outfp)) { perror(""); break; } address++; } #if 0 /* flush the data from the delay lines with zeroed sectors, if necessary */ #endif return 0; }