/*
Creates number list of unique program chains in pgclist.txt.
author: ballofsnow
date: 11 November 2007
license: none (public domain)
target: win32 (MINGW), recommend using the free IDE from bloodshed.net
version: beta 0.3
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fstream>
#include <iostream>
using namespace std;
void usage(char *argv0);
unsigned char checkifo[12]= { 0x44, 0x56, 0x44, 0x56, 0x49, 0x44, 0x45, 0x4F, 0x2D, 0x56, 0x54, 0x53 }; /* DVDVIDEO-VTS */
unsigned char buffer[1024*1024];
int main (int argc, char **argv) {
FILE *ifo;
char *ifoname=NULL;
int pgctable=0x1000;
int pgctotal;
unsigned long sectors[1024]; // obscene, I know.
unsigned long pgcstart;
unsigned long cellsector;
int goodpgcs;
int cellstart;
int flag;
int curpgc=0;
cout << "PGC count v0.1, ballofsnow" << endl;
if (argc==1) {
usage(argv[0]);
return -1;
}
fstream pgclist("pgclist.txt",ios::out);
for (int p=1;p<argc;p++) {
/* LOAD AND VALIDATE THE IFO */
ifoname=argv[p];
//cout << argv[p] << endl;
if ((ifo=fopen(ifoname,"rb"))==NULL) {
cout << "Failed to open IFO file " << ifoname << endl;
return -1;
}
fread(buffer,1,1024*1024,ifo);
if (memcmp(checkifo,buffer,12) != 0) {
cout << "This isn't an IFO file." << endl;
free(buffer);
fclose(ifo);
usage(argv[0]);
return -1;
}
/* FINISHED VALIDATING */
goodpgcs=1;
pgctotal=buffer[pgctable]*0x100+buffer[pgctable+1];
for (int i=1; i<=pgctotal; i++) {
/* Get PGC start byte */
pgcstart=buffer[pgctable+i*8+4]*0x1000000+buffer[pgctable+i*8+5]*0x10000+buffer[pgctable+i*8+6]*0x100+buffer[pgctable+i*8+7];
cellstart=buffer[pgctable+pgcstart+0xE8]*0x100+buffer[pgctable+pgcstart+0xE9]+8;
cellsector=buffer[pgctable+pgcstart+cellstart+0]*0x1000000+buffer[pgctable+pgcstart+cellstart+1]*0x10000+buffer[pgctable+pgcstart+cellstart+2]*0x100+buffer[pgctable+pgcstart+cellstart+3];
//cout << pgcstart << endl;
//cout << cellstart << endl;
//cout << cellsector << endl << endl;
curpgc++;
flag=0;
for (int a=0; a<goodpgcs-1; a++) {
if (cellsector==sectors[a]) {
flag=1;
break;
}
}
if (flag==0) {
sectors[goodpgcs-1]=cellsector;
goodpgcs++;
//cout << "curpgc: " << curpgc << endl;
pgclist << curpgc << "," << argv[p] << endl;
}
}
free(buffer); // ifo buffer
fclose(ifo);
}
pgclist.close();
cout << "pgclist.txt created successfully." << endl;
return 0;
}
void usage(char *argv0) {
cout << "Usage: " << argv0 << "<VTS IFO file> [VTS IFO file]" << endl;
cout << "Creates number list of unique program chains in pgclist.txt." << endl;
}