Tcll
Smash Lord
@L-a-t-e-r-a-l-u-s:
I'd add ya, but I don't use MSN...
I use chatango though
I'd add ya, but I don't use MSN...
I use chatango though
Welcome to Smashboards, the world's largest Super Smash Brothers community! Over 250,000 Smash Bros. fans from around the world have come to discuss these great games in over 19 million posts!
You are currently viewing our boards as a visitor. Click here to sign up right now and start on your path in the Smash community!
I dont even know what a chatango is x_x. Anyway, due to my *****y art teacher and her ridiculous amounts of homework (I'm never taking an AP art course again... it's not that its out of my ability, it's that shes a ***** and I hate her.), drawing up concept art for each of the characters might take a while. Bare with me.@L-a-t-e-r-a-l-u-s:
I'd add ya, but I don't use MSN...
I use chatango though
The 'G' looks like a 'C', and the '!' looks like a lower case 'L'.I don't get the camel - GAME thing.
Can I have the download link to Rage quit pause screen?look what i found with the pause screen. oh the possibilities
so far i can only change the left side of the screen and those little rectangles on the top right. The dolphin doesn't dump the other stuff
Thanks!^ this is really cool. i have no idea how you did that background
Nube's clear pause was **** but it froze event matches. these don't. I haven't thoroughly tested them but i think they are good. the offsets are really weird in this file, curious.
this is the rage quit one and i also included the fixed clear pause
http://www.megaupload.com/?d=3OAIOW3X
<3 <3
Almost done people! The background just needs that little extra something...
BTW, that weird white line segment to the left is a Koopa I've yet to de-texture.
/*
hps_insert.exe
--creates HPS files from a supplied HPS file and two channels of audio
--will fit the new HPS to the supplied HPS structure and size
--you need to have dspadpcm.exe in the same directory as hps_insert.exe
--you need to have soundfile.dll and dsptool.dll in the directory, too
Parameters
>>hps_insert (hps_name r_wav l_wav)
hps_name is the name of the HPS file you're going to supply as a model.
r_wav is the name of the mono WAV file that is the right channel that you want.
l_wav is the name of the mono WAV file that is the left channel that you want.
Example of use
C:\Documents and Settings\Admin>hps_insert hyaku.hps battleR.wav battleL.wav
--this will create an HPS file called "temp.hps", which will have the exact
same structure as the hyaku.hps file, while having the audio from battleL.wav
and battleR.wav
Program written by GodFed of smashboards.com, with HPS structure info from
hcs of halley's comet software. Permission is given to copy, distribute,
etc as long as you don't make any money from it.
10/11/2010
*/
#include <stdio.h>
#include <string.h>
#include <process.h>
#include <inttypes.h>
int get32bit(unsigned char * p);
int main(int argc, char *argv[])
{
FILE *hps, *dsp1, *dsp2, *tmp, *infile; //FILE stuff..
long start_offset, current_offset, next_offset; //offset variables for fseek() and fgetc() in FILE *hps
long l_count, r_count; //keep track of where I am when copying left DSP and right DSP to HPS
int block_length, channel_length, chanlen_check, chans, block_nibbles; //variables for HPS audio blocks
int sam0, sam1, sam2; //sample rate checker variables
int x, test, counter; //loops, I think
float time, total_time; //time for each block, total time for all of the blocks to that point
char ch; //for copying files character by character
unsigned char readbuf[128]; //for get32bit()
char hpsname[80], wavLname[80], wavRname[80], txtname[80]; //arguments for various functions in string form - they're just necessary
char coef_L[32], coef_R[32]; //coefficient data for L and R DSPs
char arg1[80], arg2[80], arg3[80]; //argument strings in case all parameters are not met
bool loop_flag = false; //does the HPS loop? initially set to false
printf("hps_insert v1.2 by GodFed\nwith help from hcs\n");
printf("-updated 10/11/10\n");
if(argc == 1){
printf("\nPlease provide the HPS name.\n");
gets(arg1);
argc++;
argv[1] = arg1;
}
if(argc == 2){
printf("\nPlease provide the WAV left channel name.\n");
gets(arg2);
argc++;
argv[2] = arg2;
}
if(argc == 3){
printf("\nPlease provide the WAV right channel name.\n");
gets(arg3);
argc++;
argv[3] = arg3;
}
if(argc == 4){
printf("\nAll necessary parameters are in place.\n***\n");
}
strcpy(hpsname, argv[1]);
strcpy(wavLname, argv[2]);
strcpy(wavRname, argv[3]);
spawnl(P_WAIT, "dspadpcm.exe", "dspadpcm.exe", "-e", wavLname, NULL);
spawnl(P_WAIT, "dspadpcm.exe", "dspadpcm.exe", "-e", wavRname, NULL);
//this creates info files...delete them?
//clear the original WAV names.
//Basically, it looks for the ".wav" at the end of the name
//and cuts it out so that the name can be used for the DSP name a few
//lines below.
test = strlen(wavLname)-4;
if(wavLname[test] == '.') wavLname[test] = 0;
if(wavLname[test+1] == 0) printf("Looking for L WAV channel file.\n");
test = strlen(wavRname)-4;
if(wavRname[test] == '.') wavRname[test] = 0;
if(wavRname[test+1] == 0) printf("Looking for R WAV channel file.\n");
//make string with WAV L and R names to pass to be DSPs
strcat(wavLname, ".dsp"); //adding the previous wav names that we cut up
strcat(wavRname, ".dsp");
//open the files for work
if((hps = fopen(hpsname , "rb")) == NULL){
printf("Error: Cannot open HPS file.\n");
return 1;
}
if((dsp1 = fopen(wavLname , "rb")) == NULL){
printf("Error: Cannot open DSP left channel file.\n");
return 1;
}
if((dsp2 = fopen(wavRname , "rb")) == NULL){
printf("Error: Cannot open DSP right channel file.\n");
return 1;
}
if((tmp = fopen("temp.hps" , "wb")) == NULL){
printf("Error: Cannot create temp file .\n");
return 1;
}
printf("Reading HPS and new DSPs...\n");
//read header of the header into readbuf - only 0x20 bytes
fseek(hps, 0, 0);
for(x=0; x<0x20; x++){
readbuf[x] = getc(hps);
}
sam0 = get32bit(readbuf+0x8);
printf("HPS Sample rate: %i\n", get32bit(readbuf+0x8));
printf("HPS Channels: %i\n", get32bit(readbuf+0x0c));
//DSP L
fseek(dsp1, 0, 0);
for(x=0; x<0x1c; x++){
readbuf[x] = getc(dsp1);
}
for(x=0x0; x<0x20; x++){
coef_L[x] = getc(dsp1);
//printf("%08x\n", coef_L[x]);
}
sam1 = get32bit(readbuf+0x8);
printf("L DSP Sample rate: %i\n", sam1);
//DSP R
fseek(dsp2, 0, 0);
for(x=0; x<0x1c; x++){
readbuf[x] = getc(dsp2);
}
for(x=0x0; x<0x20; x++){
coef_R[x] = getc(dsp2);
}
sam2 = get32bit(readbuf+0x8);
printf("R DSP Sample rate: %i\n\n", sam2);
if(sam1 != sam2){
printf("Sample rates for left and right DSP channels don't match\n");
return 1;
}
if((sam0 != sam1)|| (sam0 != sam2)){
printf("Sample rate for HPS doesn't match that for the DSP channels.\n");
return 1;
}
//copy header and coefficient data to TMP.
//total of 0x80 bytes copied.
//" HALPST"
fseek(hps, 0, 0);
for(x=0;x<0x20;x++){
ch = getc(hps);
putc(ch, tmp);
}
//L coefficients
fseek(hps, 0x20, 0);
for(x=0;x<0x20;x++){
putc(coef_L[x], tmp);
//printf("%08x\n", coef_L[x]);
}
//inter-coefficient data
fseek(hps, 0x40, 0);
for(x=0;x<0x18;x++){
ch = getc(hps);
putc(ch, tmp);
}
//R coefficients
for(x=0;x<0x20;x++){
putc(coef_R[x], tmp);
}
//last 8 bytes
fseek(hps, 0x78, 0);
for(x=0;x<8;x++){
ch = getc(hps);
putc(ch, tmp);
}
//set variables for the upcoming loop
chans = 2;
start_offset = 0x80;
l_count = 0x60;
r_count = 0x60;
counter = 0;
total_time = 0;
//Start while loop for block data.
//This loops through the blocks and copies them
//one by one to the temp.hps file.
while(1){
fseek(hps, start_offset, 0); //offset for the block header
for(x=0; x<0x20; x++){
readbuf[x] = getc(hps);
ch = readbuf[x];
putc(ch, tmp);
}
block_length = get32bit(readbuf);
channel_length = (block_length/2);
time = (channel_length*1.792)/32776;
printf("offset:%08x length:%08x secs:%5.3f total secs:%5.3f\n", start_offset, channel_length, time, total_time);
total_time += time;
block_nibbles = get32bit(readbuf+0x4)+1;
next_offset = get32bit(readbuf+0x8);
//chanlen_check = (next_offset - (start_offset+0x10))/2;
//printf("check:%08x\n", chanlen_check);
/*if (chanlen_check != channel_length){
printf("Channel checks don't match, check program math.\n");
return 1;
}*/
if(next_offset<start_offset){
printf("Loop in %s from offset %08x back to %08x\n", argv[1], start_offset, next_offset);
loop_flag = true;
}
else start_offset = next_offset;
fseek(dsp1, l_count, 0);
for(x=0;x<channel_length;x++) {
ch = getc(dsp1);
putc(ch, tmp);
l_count++;
}
//printf("%08x\n", l_count);
fseek(dsp2, r_count, 0);
for(x=0;x<channel_length;x++) {
ch = getc(dsp2);
putc(ch, tmp);
r_count++;
}
//printf("%08x\n", r_count);
counter++;
if(loop_flag){
printf("%i audio blocks, %5.3f seconds\n", counter, total_time);
break;
}
}
printf("closing files...\n");
//Clean up
fseek(hps, 0,0);
fclose(hps);
fclose(dsp1);
fclose(dsp2);
fclose(tmp);
/*
GENERAL STEPS TO THE PROGRAM
1. create HPSname, WAVLname, WAVRname
2. a. run "dspadpcm -e WAVLname" , then run "dspadpcm -e WAVRname"
b. delete info files that it creates, or disable them somehow??? yes or no??
3. fopen() HPS, DSP1, DSP2, TMP
4. make sure that
a. channels == 2
b. DSP1 sample rate == DSP2 sample rate
5.get
a. DSP1 and DSP2 coefs into HPS file.
b. DSP1 and DSP2 sample rates into HPS file.
6.start data copy
a. start_offset = 0x80;
b. while(!feof(HPS))
a. fseek(HPS, start_offset, 0);
b. read header into readbuf
1. int block_length = get32bit(readbuf);
2. int channel_length = (block_length/2)+8;
a. int chanlen_check = (next_offset - current_offset)/2;
b. if(chanlen_check != channel_length) throw error, and double check math
3. int next_offset = get32bit(readbuf+0x8);
4. if(next_offset<start_offset) throw loop flag;
5. else start_offset = next_offset;
b. for(x=0;x<channel_length;x++)
1. keep a l_count and a r_count for advancing the fseek on the DSPs
2. copy data from channel 1 (L) DSP to TMP to start of data, after header
2. repeat for second channel (R) DSP
c. if loop flag thrown -> last block....break out of while loop;
d. else loop back to while
7. clean up
a. fclose HPS, DSP1, DSP2, TMP
b. keep TMP file
*/
return 0; //end of program
}
int get32bit(unsigned char* p)
{
//this is from hcs (Halley's Comet Software)
//I got this idea from their in_cube winamp plugin
//it transforms char[] values into their hex data equivalent
//for 32 bits, or four bytes, of hex data
return (p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3];
}
/*
tpl_insert.exe - makes TPLs and inserts them in the right places given a DAT to edit
This program can read image and palette data
from TPL files (which it can also generate),
and insert them in the proper places in their
corresponding DAT files.
It can read offset data from "offsets.txt",
hopefully provided in the same directory.
Parameters
>>tpl_insert(DAT ## [-v] [-t])
where DAT is the dat to edit, and ## is the
texture number in the directory.
-v is the optional verbose flag, default to false - if true, will spit out extra info to the console
-t is the optional TexConv flag, default to false - if true, will run TexConv to make the TPL file
Example of Use
C:\Documents and Settings\Admin>tpl_insert PlCaNr.dat 10 -t
--this will look for PlCaNr.dat, check the TCS file named
"10.tcs", and then run TexConv.exe. Then, it will look
for "offsets.txt" to find the correct offset for texture
number 10, and then insert the TPL in a new PlCaNr.dat
at that offest.
Program written by GodFed of smashboards.com, with many thanks
to S. of Stack Smash. Permission is granted to copy, modify,
distribute, etc. as long as no personal profit is made. That's all.
Last updated 12/14/10
*/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <process.h>
void changeToHex(char *offset, long& location);
int replaceMagenta(FILE *tmpt, FILE *tpl, char *tplname, long offset);
int get16bit(unsigned char * p);
int get32bit(unsigned char * p);
int parse_args(char* filename, char* filenum);
int main(int argc, char *argv[])
{
FILE *dat, *tpl, *tmp, *off, *tcs, *tmpt; //for file I/O
unsigned char readbuf[0x400]; //for bitwise functions get16bit() and get32bit()
char ch; //for copying and appending to file
char str[80]; //I use scanf(str) as a makeshift 'pause' function
char filename[80], tplname[80], tcsname[80]; //for names of files to open
char filenum[3], cmp[3], offset[9], splat[2]; //for various input operations
int counter, x; //for iterations
long tplhead, paldata, magenta; //recipients of get32bit() and get16bit() returns
long donde, w, y; //for fseek
bool verboseflag, texflag; //parameter flags for verbose mode and TexConv.exe call
bool argd; //now being used for checking if offset points to _9 or _8 textures
verboseflag = false;
texflag = false;
argd = true;
if(argc >= 4){ //check for flags
for(x=0; x<argc; x++){
if(argv[x][0] == '-'){
if(argv[x][1] == 'v') verboseflag = true;
if(argv[x][1] == 't') texflag = true;
}
}
}
printf("tpl_insert v0.93 (updated 9/12/09)\n\n");
if(verboseflag){
printf("*******************************\n");
printf("**Melee: TPL Texture Inserter**\n");
printf("*******************************\n\n");
printf("This program will replace TPL \nfiles in the DAT based on their number.\n***\n");
}
if(argc <= 1){
printf("\nPlease provide the DAT file to be edited (including extension)\n");
gets(filename);
argc++;
argv[1] = filename;
}
if(argc == 2){
printf("\nPlease provide the ## of the TPL.\n");
gets(filenum);
argc++;
argv[2] = filenum;
argd = true;
}
if(argc >= 3){
printf("All necessary parameters are in place.\n***\n");
argd = true;
}
for(x=0;x<80;x++){
tplname[x] =0;
tcsname[x]=0;
}
strcpy(tplname, argv[2]);
strcpy(tcsname, tplname);
strcat(tplname, ".tpl");
strcat(tcsname, ".tcs");
//find which offset to go to.
if((off = fopen("offsets.txt", "rb")) == NULL){
printf("Error: Cannot open offsets.txt for read.\n");
return 1;
}
donde = 0;
w = 0;
while(1){
fseek(off, w, 0); //fseek to location W of offset txt file
fgets(cmp, 3, off); //read the next two chars, plus one null byte
//printf("cmp: %s\n", cmp); //debug info
if((cmp[0] == argv[2][0]) && (cmp[1] == argv[2][1])){
//printf("successss");
w+=4;
fseek(off, w, 0); //fseek 4 bytes farther
fgets(splat, 2, off); //fgets the next byte, plus one null byte
if(splat[0] == '*'){ //check if the byte is an asterisk, denoting more complex formats
argd = false;
}
w+=1;
fseek(off, w, 0); //fseek one byte farther
fgets(offset, 9, off); //fgets offset data in char bytes, 8 chars plus one null byte
//printf("Data Offset: %s\n", offset);
changeToHex(offset, donde);
break;
}
w+=15; //this should instead search for the 0D 0A for the newline characters
if(w > 1000*15){
printf("Error: The number requested is not in the offsets.txt file.\n");
return 1;
}
}
//printf("decimal offset: %i\n", donde);
fclose(off);
//make TPL
if(texflag) spawnl(P_WAIT, "TexConv.exe", "TexConv.exe", tcsname, tplname, NULL);
//delete whatever's in tmp, create it if it doesn't exist
if((tmp = fopen("tmp.dat" , "wb")) == NULL){
printf("Error: Cannot reset temp file usage.\n");
return 1;
}
if(verboseflag) printf("Created tmp.dat for temporary data storage.\n");
fclose(tmp);
//if statements for opening the files
if((dat = fopen(argv[1], "rb")) == NULL){
printf("Error: Cannot open DAT file for read.\n");
return 1;
}
if((tpl = fopen(tplname, "rb")) == NULL){
printf("Error: Cannot open TPL file for read.\n");
return 1;
}
if((tmp = fopen("tmp.dat", "ab")) == NULL){
printf("Error: Cannot open temp file for append.\n");
return 1;
}
if(verboseflag) printf("Data Offset: %s\n", offset);
//Actual reading and writing to files goes here.
//if _8 or _9 format
if(!argd) {
if(verboseflag) printf("Type: _8 or _9\n");
/*
future - - - check for magenta palette data, replace it
to check for magenta
0. place this code after tplhead and paldata are given values
1. read just the palette data from the paldata offset until you hit the tplhead offset
2. for loop to get16bit() at every offset between readbuf[0] abd readbuf[(tplhead-paldata)-2]
3. during that loop, check if the get16bit returns fc1f
if yes..
a. create a tmpt.tpl file
b. make sure that the offset of the magenta value is recorded
c. copy up to that offset to tmpt.tpl
d. append 00 00
e. copy/append from two after the offset until eof
f. copy tmpt.tpl to the original
NEXT
check next offset point? check if data is less than 32 lines...maybe for another time
*/
counter = 0; //the counter keeps track of how long the TPL data is
fseek(tpl, 0x0, 0); //start at beginning of file
for(x=0; x<0x400; x++){ //copy first 1024 bits from TPL to readbuf
readbuf[x] = getc(tpl);
}
tplhead = get32bit(readbuf + 0xc); //get tpl header location, which is 0x40 before the actual data
paldata = get32bit(readbuf + 0x1c); //get palette data location
fseek(tpl, paldata, 0);
for(x=0; x<tplhead-2; x++){
readbuf[x] = getc(tpl);
}
for(x=0; x<(tplhead-paldata)-2; x++){
magenta = get16bit(readbuf + x);
if (magenta == 0xfc1f){
y = x+0x20;
if(verboseflag) printf("Magenta found at offset: %i\n", y);
magenta = replaceMagenta(tmpt, tpl, tplname, y);
if(magenta == 1) return 1;
break;
}
}
fseek(dat, 0, 0);
for(x=0; x<donde; x++){ //copy DAT info to TMP (append)
ch = getc(dat);
putc(ch, tmp);
}
fseek(tpl, tplhead + 0x40, 0); //fseek to TPL image data
while(!feof(tpl)){ //copy TPL image data to TMP (append)
ch = getc(tpl);
if(!feof(tpl)) putc(ch, tmp);
counter++; //keep track of length of data
}
fseek(tpl, paldata, 0);
for(x=paldata; x<tplhead; x++){ //copy TPL palette data to TMP (append)
ch = getc(tpl); //this loop iterates from paldata to tplhead
if(!feof(tpl)) putc(ch, tmp);
counter++; //keeping track of length of both datas added together
}
donde = counter + donde - 1; //update the end-of-data location in DAT
fseek(dat, donde, 0);
while(!feof(dat)){ //copy rest of DAT to TMP (append)
ch = getc(dat);
if(!feof(dat)) putc(ch, tmp);
}
//if _14 CMPR format
}else if(argd){
if(verboseflag) printf("Type: _14 CMPR\n");
/* no comment */
counter = 0;
fseek(dat, 0, 0);
for(x=0; x<donde; x++){
ch = getc(dat);
putc(ch, tmp);
}
fseek(tpl, 0x40, 0); //offset start for tpl data
while(!feof(tpl)){
ch = getc(tpl);
if(!feof(tpl)) putc(ch, tmp);
counter ++;
}
donde = counter + donde - 1;
fseek(dat, donde, 0);
while(!feof(dat)){
ch = getc(dat);
if(!feof(dat)) putc(ch, tmp);
}
}
fclose(dat);
fclose(tpl);
fclose(tmp);
//Copy TMP contents to DAT and delete TMP
if((dat = fopen(argv[1], "wb")) == NULL){
printf("Error: Cannot open DAT file for rewrite.\n");
return 1;
}
if((tmp = fopen("tmp.dat", "rb")) == NULL){
printf("Error: Cannot open temp file for reread.\n");
return 1;
}
fseek(tmp, 0, 0);
while(!feof(tmp)){
ch = getc(tmp);
if(!feof(tmp)) putc(ch, dat);
}
fclose(dat);
fclose(tmp);
if(remove("tmp.dat")==-1) {
printf("Error: Cannot delete tmp.dat");
return 1;
}
if(verboseflag) printf("Copied tmp.dat to %s and deleted tmp.dat successfully.\n", argv[1]);
//scanf(str);
// system("PAUSE"); wtf. this made the program like 465 kb. I hate iostream.
return 0;
}
void changeToHex(char *offset, long& location)
{
//This function multiplies the nth digit from the right by 16^(n-1)
//and then adds all these values together until n <= 0,
//effectively converting hex to decimal, but really just
//converting from char[] to long
int p, q, r;
long base;
location = 0;
for(p=7; p>0; p--){
base = 16;
for(q=(p-1); q>0; q--){
base *= 16;
// printf("base: %i\n", base); debug info
}
switch(*offset){
case '0':r=0; break;
case '1':r=1; break;
case '2':r=2; break;
case '3':r=3; break;
case '4':r=4; break;
case '5':r=5; break;
case '6':r=6; break;
case '7':r=7; break;
case '8':r=8; break;
case '9':r=9; break;
case 'a':
case 'A':r=10; break;
case 'b':
case 'B':r=11; break;
case 'c':
case 'C':r=12; break;
case 'd':
case 'D':r=13; break;
case 'e':
case 'E':r=14; break;
case 'f':
case 'F':r=15; break;
}
//printf("offset: %i\n", r);
*offset ++;
location = location + (base*r);
//printf("location: %i\n\n", location);
}
}
int replaceMagenta(FILE *tmpt, FILE *tpl, char *tplname, long offset)
{
int z;
char ch;
/*if yes..
*/
if((tmpt = fopen("tmpt.tpl", "ab")) == NULL){
printf("Error: Cannot create tmpt.tpl for append.\n");
return 1;
}
fseek(tpl, 0, 0); //seek to 0 for offset with MAGENTA
for(z=0; z<offset; z++){ //copy up to that point, add it to tmpt
ch = getc(tpl);
putc(ch, tmpt);
}
fseek(tpl, 0x4, 0); //seek to offset 0x4, whose two bytes are always 00 00
for(z=0;z<2;z++){ //copy them to where the MAGENTA used to be
ch = getc(tpl);
putc(ch, tmpt);
}
fseek(tpl, offset+2, 0); //seek 2 past the original offset, aka, right after the MAGENTA change
while(!feof(tpl)){ //copy/append from there to eof
ch = getc(tpl);
if(!feof(tpl)) putc(ch, tmpt);
}
fclose(tmpt);
fclose(tpl); //close the tpl that was open for read
if((tpl = fopen(tplname, "wb")) == NULL){//open it again for write, which clears it
printf("Error: Cannot open %s to replace MAGENTA value.\n", tplname);
return 1;
}
if((tmpt = fopen("tmpt.tpl", "rb")) == NULL){
printf("Error: Cannot open tmpt.tpl for reread and copy.\n");
return 1;
}
fseek(tmpt, 0, 0); //copying tmpt.tpl over original TPL
while(!feof(tmpt)){
ch = getc(tmpt);
if(!feof(tmpt)) putc(ch, tpl);
}
fclose(tpl);
fclose(tmpt);
if(remove("tmpt.tpl")==-1) {
printf("Error: Cannot delete tmpt.tpl");
return 1;
}
//since TPL was open before the funtion call, reopen it the way it was before
if((tpl = fopen(tplname, "rb")) == NULL){
printf("Error: Cannot open %s for read.\n", tplname);
return 1;
}
}
int get16bit(unsigned char* p)
{
//this is from hcs (Halley's Comet Software)
//I got this idea from their in_cube winamp plugin
//it transforms char[] values into their hex data equivalent
//for 16 bits, or two bytes, of hex data
return (p[0] << 8) | p[1];
}
int get32bit(unsigned char* p)
{
//this is from hcs (Halley's Comet Software)
//I got this idea from their in_cube winamp plugin
//it transforms char[] values into their hex data equivalent
//for 32 bits, or four bytes, of hex data
return (p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3];
}
int parse_args(char* filename, char* filenum)
{
/*
This will switch() the args with the filename and ##, and
use stored values to return the offset
*/
}
NEW THREAD :DBack. My whole "colour change" thing should be ready tonight. Should I start a new thread for it? I think I might need to. Someone start nagging me to get going before I get lazy XD
Back. My whole "colour change" thing should be ready tonight. Should I start a new thread for it? I think I might need to. Someone start nagging me to get going before I get lazy XD
that makes 2 of us :DGodFed you are a God
Looking forward to the relocation table source
Mm, here's the problem with searching for strings: the .TPL file does not copy the string in the .DAT file word-for-word. There are SLIGHT changes that throw it off... You have to guess 'n check it; that's how I found my placements. (You'll know you screwed up when the final product doesn't look very pretty after hexing. )I don't understand steps 6 and 7 in the texture hacking. I loaded the Pl***.dat file and did a search for the string in Steelia's placement file and it didn't return any results. I figured I just misunderstood what it meant, so I tried loading the .tpl file and searching for that same string. Did I miss something? Also, in the Pl***.dat files, how do I know which files refer to which texture?
I get the feeling I'm WAY off. Any advice? I've never modded or hacked anything so I'm sorry for being noobsauce.
Edit: The hex editor I'm using is called XVI32. Not sure if that matters or not.
Edit2: Can I just download premodded textures and replace a file one-for-one and have it run fine? If so, how do I know which file(s) to replace?
^what he saidThats amazing. Simply Amazing.
loldon't say the b-word on christmas! ='[
Great stage, btw! <3
Download(Special attack boost plz) link?
In lieu of posting commented code, I think I'll just explain what the relocation tables are. My code is getting a bit more complex now that I understand DAT files more, and I couldn't quite finish it as soon as I wanted to. So here is an explanation of relocation tables and how to use them.Each value in the relocation table is an offset that points to some place in the DAT file. When we go to that place (plus 0x20), we find another offset that points somewhere else in the DAT file. When we go to that place (plus 0x20), we find the data.
sick .Hey, what's up.
Here are those source code files I promised way back. I decided not to do filesharing, it's just simpler to post the whole code here. If there's an issue with this, tell me and I'll fix it.
First is hps_insert.cpp, then tpl_insert.cpp
I wrote and compiled them in Dev-C++. It's kinda sloppy c++, but hey. It works.
I have a hitbox analyzer program that I just wrote, but it's a bit messy right now. I'll refine it and post it soon. Maybe it'll be a Christmas present for you fine people. What it does so far is look in a character file and analyze every single action that the character makes (like nair, upB, jab, dtilt, spot-dodge, taunt, etc). It checks for hitboxes, grab-boxes, whatever, then at the individual values (damage, angle, knockback, sound fx, etc). It spits it all into a txt file. So yeah.
Code:/* hps_insert.exe --creates HPS files from a supplied HPS file and two channels of audio --will fit the new HPS to the supplied HPS structure and size --you need to have dspadpcm.exe in the same directory as hps_insert.exe --you need to have soundfile.dll and dsptool.dll in the directory, too Parameters >>hps_insert (hps_name r_wav l_wav) hps_name is the name of the HPS file you're going to supply as a model. r_wav is the name of the mono WAV file that is the right channel that you want. l_wav is the name of the mono WAV file that is the left channel that you want. Example of use C:\Documents and Settings\Admin>hps_insert hyaku.hps battleR.wav battleL.wav --this will create an HPS file called "temp.hps", which will have the exact same structure as the hyaku.hps file, while having the audio from battleL.wav and battleR.wav Program written by GodFed of smashboards.com, with HPS structure info from hcs of halley's comet software. Permission is given to copy, distribute, etc as long as you don't make any money from it. 10/11/2010 */ #include <stdio.h> #include <string.h> #include <process.h> #include <inttypes.h> int get32bit(unsigned char * p); int main(int argc, char *argv[]) { FILE *hps, *dsp1, *dsp2, *tmp, *infile; //FILE stuff.. long start_offset, current_offset, next_offset; //offset variables for fseek() and fgetc() in FILE *hps long l_count, r_count; //keep track of where I am when copying left DSP and right DSP to HPS int block_length, channel_length, chanlen_check, chans, block_nibbles; //variables for HPS audio blocks int sam0, sam1, sam2; //sample rate checker variables int x, test, counter; //loops, I think float time, total_time; //time for each block, total time for all of the blocks to that point char ch; //for copying files character by character unsigned char readbuf[128]; //for get32bit() char hpsname[80], wavLname[80], wavRname[80], txtname[80]; //arguments for various functions in string form - they're just necessary char coef_L[32], coef_R[32]; //coefficient data for L and R DSPs char arg1[80], arg2[80], arg3[80]; //argument strings in case all parameters are not met bool loop_flag = false; //does the HPS loop? initially set to false printf("hps_insert v1.2 by GodFed\nwith help from hcs\n"); printf("-updated 10/11/10\n"); if(argc == 1){ printf("\nPlease provide the HPS name.\n"); gets(arg1); argc++; argv[1] = arg1; } if(argc == 2){ printf("\nPlease provide the WAV left channel name.\n"); gets(arg2); argc++; argv[2] = arg2; } if(argc == 3){ printf("\nPlease provide the WAV right channel name.\n"); gets(arg3); argc++; argv[3] = arg3; } if(argc == 4){ printf("\nAll necessary parameters are in place.\n***\n"); } strcpy(hpsname, argv[1]); strcpy(wavLname, argv[2]); strcpy(wavRname, argv[3]); spawnl(P_WAIT, "dspadpcm.exe", "dspadpcm.exe", "-e", wavLname, NULL); spawnl(P_WAIT, "dspadpcm.exe", "dspadpcm.exe", "-e", wavRname, NULL); //this creates info files...delete them? //clear the original WAV names. //Basically, it looks for the ".wav" at the end of the name //and cuts it out so that the name can be used for the DSP name a few //lines below. test = strlen(wavLname)-4; if(wavLname[test] == '.') wavLname[test] = 0; if(wavLname[test+1] == 0) printf("Looking for L WAV channel file.\n"); test = strlen(wavRname)-4; if(wavRname[test] == '.') wavRname[test] = 0; if(wavRname[test+1] == 0) printf("Looking for R WAV channel file.\n"); //make string with WAV L and R names to pass to be DSPs strcat(wavLname, ".dsp"); //adding the previous wav names that we cut up strcat(wavRname, ".dsp"); //open the files for work if((hps = fopen(hpsname , "rb")) == NULL){ printf("Error: Cannot open HPS file.\n"); return 1; } if((dsp1 = fopen(wavLname , "rb")) == NULL){ printf("Error: Cannot open DSP left channel file.\n"); return 1; } if((dsp2 = fopen(wavRname , "rb")) == NULL){ printf("Error: Cannot open DSP right channel file.\n"); return 1; } if((tmp = fopen("temp.hps" , "wb")) == NULL){ printf("Error: Cannot create temp file .\n"); return 1; } printf("Reading HPS and new DSPs...\n"); //read header of the header into readbuf - only 0x20 bytes fseek(hps, 0, 0); for(x=0; x<0x20; x++){ readbuf[x] = getc(hps); } sam0 = get32bit(readbuf+0x8); printf("HPS Sample rate: %i\n", get32bit(readbuf+0x8)); printf("HPS Channels: %i\n", get32bit(readbuf+0x0c)); //DSP L fseek(dsp1, 0, 0); for(x=0; x<0x1c; x++){ readbuf[x] = getc(dsp1); } for(x=0x0; x<0x20; x++){ coef_L[x] = getc(dsp1); //printf("%08x\n", coef_L[x]); } sam1 = get32bit(readbuf+0x8); printf("L DSP Sample rate: %i\n", sam1); //DSP R fseek(dsp2, 0, 0); for(x=0; x<0x1c; x++){ readbuf[x] = getc(dsp2); } for(x=0x0; x<0x20; x++){ coef_R[x] = getc(dsp2); } sam2 = get32bit(readbuf+0x8); printf("R DSP Sample rate: %i\n\n", sam2); if(sam1 != sam2){ printf("Sample rates for left and right DSP channels don't match\n"); return 1; } if((sam0 != sam1)|| (sam0 != sam2)){ printf("Sample rate for HPS doesn't match that for the DSP channels.\n"); return 1; } //copy header and coefficient data to TMP. //total of 0x80 bytes copied. //" HALPST" fseek(hps, 0, 0); for(x=0;x<0x20;x++){ ch = getc(hps); putc(ch, tmp); } //L coefficients fseek(hps, 0x20, 0); for(x=0;x<0x20;x++){ putc(coef_L[x], tmp); //printf("%08x\n", coef_L[x]); } //inter-coefficient data fseek(hps, 0x40, 0); for(x=0;x<0x18;x++){ ch = getc(hps); putc(ch, tmp); } //R coefficients for(x=0;x<0x20;x++){ putc(coef_R[x], tmp); } //last 8 bytes fseek(hps, 0x78, 0); for(x=0;x<8;x++){ ch = getc(hps); putc(ch, tmp); } //set variables for the upcoming loop chans = 2; start_offset = 0x80; l_count = 0x60; r_count = 0x60; counter = 0; total_time = 0; //Start while loop for block data. //This loops through the blocks and copies them //one by one to the temp.hps file. while(1){ fseek(hps, start_offset, 0); //offset for the block header for(x=0; x<0x20; x++){ readbuf[x] = getc(hps); ch = readbuf[x]; putc(ch, tmp); } block_length = get32bit(readbuf); channel_length = (block_length/2); time = (channel_length*1.792)/32776; printf("offset:%08x length:%08x secs:%5.3f total secs:%5.3f\n", start_offset, channel_length, time, total_time); total_time += time; block_nibbles = get32bit(readbuf+0x4)+1; next_offset = get32bit(readbuf+0x8); //chanlen_check = (next_offset - (start_offset+0x10))/2; //printf("check:%08x\n", chanlen_check); /*if (chanlen_check != channel_length){ printf("Channel checks don't match, check program math.\n"); return 1; }*/ if(next_offset<start_offset){ printf("Loop in %s from offset %08x back to %08x\n", argv[1], start_offset, next_offset); loop_flag = true; } else start_offset = next_offset; fseek(dsp1, l_count, 0); for(x=0;x<channel_length;x++) { ch = getc(dsp1); putc(ch, tmp); l_count++; } //printf("%08x\n", l_count); fseek(dsp2, r_count, 0); for(x=0;x<channel_length;x++) { ch = getc(dsp2); putc(ch, tmp); r_count++; } //printf("%08x\n", r_count); counter++; if(loop_flag){ printf("%i audio blocks, %5.3f seconds\n", counter, total_time); break; } } printf("closing files...\n"); //Clean up fseek(hps, 0,0); fclose(hps); fclose(dsp1); fclose(dsp2); fclose(tmp); /* GENERAL STEPS TO THE PROGRAM 1. create HPSname, WAVLname, WAVRname 2. a. run "dspadpcm -e WAVLname" , then run "dspadpcm -e WAVRname" b. delete info files that it creates, or disable them somehow??? yes or no?? 3. fopen() HPS, DSP1, DSP2, TMP 4. make sure that a. channels == 2 b. DSP1 sample rate == DSP2 sample rate 5.get a. DSP1 and DSP2 coefs into HPS file. b. DSP1 and DSP2 sample rates into HPS file. 6.start data copy a. start_offset = 0x80; b. while(!feof(HPS)) a. fseek(HPS, start_offset, 0); b. read header into readbuf 1. int block_length = get32bit(readbuf); 2. int channel_length = (block_length/2)+8; a. int chanlen_check = (next_offset - current_offset)/2; b. if(chanlen_check != channel_length) throw error, and double check math 3. int next_offset = get32bit(readbuf+0x8); 4. if(next_offset<start_offset) throw loop flag; 5. else start_offset = next_offset; b. for(x=0;x<channel_length;x++) 1. keep a l_count and a r_count for advancing the fseek on the DSPs 2. copy data from channel 1 (L) DSP to TMP to start of data, after header 2. repeat for second channel (R) DSP c. if loop flag thrown -> last block....break out of while loop; d. else loop back to while 7. clean up a. fclose HPS, DSP1, DSP2, TMP b. keep TMP file */ return 0; //end of program } int get32bit(unsigned char* p) { //this is from hcs (Halley's Comet Software) //I got this idea from their in_cube winamp plugin //it transforms char[] values into their hex data equivalent //for 32 bits, or four bytes, of hex data return (p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3]; }
Oh and by the way, I went to GSG2 in Concord this weekend and met some awesome people. I only stayed for one day, but it was fun. There was a station set up with hacked Melee, and all the cool people played on it :DCode:/* tpl_insert.exe - makes TPLs and inserts them in the right places given a DAT to edit This program can read image and palette data from TPL files (which it can also generate), and insert them in the proper places in their corresponding DAT files. It can read offset data from "offsets.txt", hopefully provided in the same directory. Parameters >>tpl_insert(DAT ## [-v] [-t]) where DAT is the dat to edit, and ## is the texture number in the directory. -v is the optional verbose flag, default to false - if true, will spit out extra info to the console -t is the optional TexConv flag, default to false - if true, will run TexConv to make the TPL file Example of Use C:\Documents and Settings\Admin>tpl_insert PlCaNr.dat 10 -t --this will look for PlCaNr.dat, check the TCS file named "10.tcs", and then run TexConv.exe. Then, it will look for "offsets.txt" to find the correct offset for texture number 10, and then insert the TPL in a new PlCaNr.dat at that offest. Program written by GodFed of smashboards.com, with many thanks to S. of Stack Smash. Permission is granted to copy, modify, distribute, etc. as long as no personal profit is made. That's all. Last updated 12/14/10 */ #include <stdlib.h> #include <stdio.h> #include <string.h> #include <process.h> void changeToHex(char *offset, long& location); int replaceMagenta(FILE *tmpt, FILE *tpl, char *tplname, long offset); int get16bit(unsigned char * p); int get32bit(unsigned char * p); int parse_args(char* filename, char* filenum); int main(int argc, char *argv[]) { FILE *dat, *tpl, *tmp, *off, *tcs, *tmpt; //for file I/O unsigned char readbuf[0x400]; //for bitwise functions get16bit() and get32bit() char ch; //for copying and appending to file char str[80]; //I use scanf(str) as a makeshift 'pause' function char filename[80], tplname[80], tcsname[80]; //for names of files to open char filenum[3], cmp[3], offset[9], splat[2]; //for various input operations int counter, x; //for iterations long tplhead, paldata, magenta; //recipients of get32bit() and get16bit() returns long donde, w, y; //for fseek bool verboseflag, texflag; //parameter flags for verbose mode and TexConv.exe call bool argd; //now being used for checking if offset points to _9 or _8 textures verboseflag = false; texflag = false; argd = true; if(argc >= 4){ //check for flags for(x=0; x<argc; x++){ if(argv[x][0] == '-'){ if(argv[x][1] == 'v') verboseflag = true; if(argv[x][1] == 't') texflag = true; } } } printf("tpl_insert v0.93 (updated 9/12/09)\n\n"); if(verboseflag){ printf("*******************************\n"); printf("**Melee: TPL Texture Inserter**\n"); printf("*******************************\n\n"); printf("This program will replace TPL \nfiles in the DAT based on their number.\n***\n"); } if(argc <= 1){ printf("\nPlease provide the DAT file to be edited (including extension)\n"); gets(filename); argc++; argv[1] = filename; } if(argc == 2){ printf("\nPlease provide the ## of the TPL.\n"); gets(filenum); argc++; argv[2] = filenum; argd = true; } if(argc >= 3){ printf("All necessary parameters are in place.\n***\n"); argd = true; } for(x=0;x<80;x++){ tplname[x] =0; tcsname[x]=0; } strcpy(tplname, argv[2]); strcpy(tcsname, tplname); strcat(tplname, ".tpl"); strcat(tcsname, ".tcs"); //find which offset to go to. if((off = fopen("offsets.txt", "rb")) == NULL){ printf("Error: Cannot open offsets.txt for read.\n"); return 1; } donde = 0; w = 0; while(1){ fseek(off, w, 0); //fseek to location W of offset txt file fgets(cmp, 3, off); //read the next two chars, plus one null byte //printf("cmp: %s\n", cmp); //debug info if((cmp[0] == argv[2][0]) && (cmp[1] == argv[2][1])){ //printf("successss"); w+=4; fseek(off, w, 0); //fseek 4 bytes farther fgets(splat, 2, off); //fgets the next byte, plus one null byte if(splat[0] == '*'){ //check if the byte is an asterisk, denoting more complex formats argd = false; } w+=1; fseek(off, w, 0); //fseek one byte farther fgets(offset, 9, off); //fgets offset data in char bytes, 8 chars plus one null byte //printf("Data Offset: %s\n", offset); changeToHex(offset, donde); break; } w+=15; //this should instead search for the 0D 0A for the newline characters if(w > 1000*15){ printf("Error: The number requested is not in the offsets.txt file.\n"); return 1; } } //printf("decimal offset: %i\n", donde); fclose(off); //make TPL if(texflag) spawnl(P_WAIT, "TexConv.exe", "TexConv.exe", tcsname, tplname, NULL); //delete whatever's in tmp, create it if it doesn't exist if((tmp = fopen("tmp.dat" , "wb")) == NULL){ printf("Error: Cannot reset temp file usage.\n"); return 1; } if(verboseflag) printf("Created tmp.dat for temporary data storage.\n"); fclose(tmp); //if statements for opening the files if((dat = fopen(argv[1], "rb")) == NULL){ printf("Error: Cannot open DAT file for read.\n"); return 1; } if((tpl = fopen(tplname, "rb")) == NULL){ printf("Error: Cannot open TPL file for read.\n"); return 1; } if((tmp = fopen("tmp.dat", "ab")) == NULL){ printf("Error: Cannot open temp file for append.\n"); return 1; } if(verboseflag) printf("Data Offset: %s\n", offset); //Actual reading and writing to files goes here. //if _8 or _9 format if(!argd) { if(verboseflag) printf("Type: _8 or _9\n"); /* future - - - check for magenta palette data, replace it to check for magenta 0. place this code after tplhead and paldata are given values 1. read just the palette data from the paldata offset until you hit the tplhead offset 2. for loop to get16bit() at every offset between readbuf[0] abd readbuf[(tplhead-paldata)-2] 3. during that loop, check if the get16bit returns fc1f if yes.. a. create a tmpt.tpl file b. make sure that the offset of the magenta value is recorded c. copy up to that offset to tmpt.tpl d. append 00 00 e. copy/append from two after the offset until eof f. copy tmpt.tpl to the original NEXT check next offset point? check if data is less than 32 lines...maybe for another time */ counter = 0; //the counter keeps track of how long the TPL data is fseek(tpl, 0x0, 0); //start at beginning of file for(x=0; x<0x400; x++){ //copy first 1024 bits from TPL to readbuf readbuf[x] = getc(tpl); } tplhead = get32bit(readbuf + 0xc); //get tpl header location, which is 0x40 before the actual data paldata = get32bit(readbuf + 0x1c); //get palette data location fseek(tpl, paldata, 0); for(x=0; x<tplhead-2; x++){ readbuf[x] = getc(tpl); } for(x=0; x<(tplhead-paldata)-2; x++){ magenta = get16bit(readbuf + x); if (magenta == 0xfc1f){ y = x+0x20; if(verboseflag) printf("Magenta found at offset: %i\n", y); magenta = replaceMagenta(tmpt, tpl, tplname, y); if(magenta == 1) return 1; break; } } fseek(dat, 0, 0); for(x=0; x<donde; x++){ //copy DAT info to TMP (append) ch = getc(dat); putc(ch, tmp); } fseek(tpl, tplhead + 0x40, 0); //fseek to TPL image data while(!feof(tpl)){ //copy TPL image data to TMP (append) ch = getc(tpl); if(!feof(tpl)) putc(ch, tmp); counter++; //keep track of length of data } fseek(tpl, paldata, 0); for(x=paldata; x<tplhead; x++){ //copy TPL palette data to TMP (append) ch = getc(tpl); //this loop iterates from paldata to tplhead if(!feof(tpl)) putc(ch, tmp); counter++; //keeping track of length of both datas added together } donde = counter + donde - 1; //update the end-of-data location in DAT fseek(dat, donde, 0); while(!feof(dat)){ //copy rest of DAT to TMP (append) ch = getc(dat); if(!feof(dat)) putc(ch, tmp); } //if _14 CMPR format }else if(argd){ if(verboseflag) printf("Type: _14 CMPR\n"); /* no comment */ counter = 0; fseek(dat, 0, 0); for(x=0; x<donde; x++){ ch = getc(dat); putc(ch, tmp); } fseek(tpl, 0x40, 0); //offset start for tpl data while(!feof(tpl)){ ch = getc(tpl); if(!feof(tpl)) putc(ch, tmp); counter ++; } donde = counter + donde - 1; fseek(dat, donde, 0); while(!feof(dat)){ ch = getc(dat); if(!feof(dat)) putc(ch, tmp); } } fclose(dat); fclose(tpl); fclose(tmp); //Copy TMP contents to DAT and delete TMP if((dat = fopen(argv[1], "wb")) == NULL){ printf("Error: Cannot open DAT file for rewrite.\n"); return 1; } if((tmp = fopen("tmp.dat", "rb")) == NULL){ printf("Error: Cannot open temp file for reread.\n"); return 1; } fseek(tmp, 0, 0); while(!feof(tmp)){ ch = getc(tmp); if(!feof(tmp)) putc(ch, dat); } fclose(dat); fclose(tmp); if(remove("tmp.dat")==-1) { printf("Error: Cannot delete tmp.dat"); return 1; } if(verboseflag) printf("Copied tmp.dat to %s and deleted tmp.dat successfully.\n", argv[1]); //scanf(str); // system("PAUSE"); wtf. this made the program like 465 kb. I hate iostream. return 0; } void changeToHex(char *offset, long& location) { //This function multiplies the nth digit from the right by 16^(n-1) //and then adds all these values together until n <= 0, //effectively converting hex to decimal, but really just //converting from char[] to long int p, q, r; long base; location = 0; for(p=7; p>0; p--){ base = 16; for(q=(p-1); q>0; q--){ base *= 16; // printf("base: %i\n", base); debug info } switch(*offset){ case '0':r=0; break; case '1':r=1; break; case '2':r=2; break; case '3':r=3; break; case '4':r=4; break; case '5':r=5; break; case '6':r=6; break; case '7':r=7; break; case '8':r=8; break; case '9':r=9; break; case 'a': case 'A':r=10; break; case 'b': case 'B':r=11; break; case 'c': case 'C':r=12; break; case 'd': case 'D':r=13; break; case 'e': case 'E':r=14; break; case 'f': case 'F':r=15; break; } //printf("offset: %i\n", r); *offset ++; location = location + (base*r); //printf("location: %i\n\n", location); } } int replaceMagenta(FILE *tmpt, FILE *tpl, char *tplname, long offset) { int z; char ch; /*if yes.. */ if((tmpt = fopen("tmpt.tpl", "ab")) == NULL){ printf("Error: Cannot create tmpt.tpl for append.\n"); return 1; } fseek(tpl, 0, 0); //seek to 0 for offset with MAGENTA for(z=0; z<offset; z++){ //copy up to that point, add it to tmpt ch = getc(tpl); putc(ch, tmpt); } fseek(tpl, 0x4, 0); //seek to offset 0x4, whose two bytes are always 00 00 for(z=0;z<2;z++){ //copy them to where the MAGENTA used to be ch = getc(tpl); putc(ch, tmpt); } fseek(tpl, offset+2, 0); //seek 2 past the original offset, aka, right after the MAGENTA change while(!feof(tpl)){ //copy/append from there to eof ch = getc(tpl); if(!feof(tpl)) putc(ch, tmpt); } fclose(tmpt); fclose(tpl); //close the tpl that was open for read if((tpl = fopen(tplname, "wb")) == NULL){//open it again for write, which clears it printf("Error: Cannot open %s to replace MAGENTA value.\n", tplname); return 1; } if((tmpt = fopen("tmpt.tpl", "rb")) == NULL){ printf("Error: Cannot open tmpt.tpl for reread and copy.\n"); return 1; } fseek(tmpt, 0, 0); //copying tmpt.tpl over original TPL while(!feof(tmpt)){ ch = getc(tmpt); if(!feof(tmpt)) putc(ch, tpl); } fclose(tpl); fclose(tmpt); if(remove("tmpt.tpl")==-1) { printf("Error: Cannot delete tmpt.tpl"); return 1; } //since TPL was open before the funtion call, reopen it the way it was before if((tpl = fopen(tplname, "rb")) == NULL){ printf("Error: Cannot open %s for read.\n", tplname); return 1; } } int get16bit(unsigned char* p) { //this is from hcs (Halley's Comet Software) //I got this idea from their in_cube winamp plugin //it transforms char[] values into their hex data equivalent //for 16 bits, or two bytes, of hex data return (p[0] << 8) | p[1]; } int get32bit(unsigned char* p) { //this is from hcs (Halley's Comet Software) //I got this idea from their in_cube winamp plugin //it transforms char[] values into their hex data equivalent //for 32 bits, or four bytes, of hex data return (p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3]; } int parse_args(char* filename, char* filenum) { /* This will switch() the args with the filename and ##, and use stored values to return the offset */ }