
//////////////////////////////////////////////////////////////////////////////
// bin2oDC.cpp          
// 
// By JMD. Adaptation of the bin2o by Rafael Vuijk (aka Dark Fader) 
// found on the net (sorry, I loose the url).
//                                                      //
//////////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////////
// Includes                                                                 //
//////////////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "iostream.h"
#include "string.h"


//////////////////////////////////////////////////////////////////////////////
// Defines                                                                  //
//////////////////////////////////////////////////////////////////////////////
#define VER		"v1.00"
#define PATCH(block, offset, value1, value2)	\
	((*(int *)(block + offset)) = value1 + value2)

#define EF_INTERWORK	0x04
#define EM_ARM			40


unsigned char header1[] =
{
	0x7F,0x45,0x4C,0x46,0x01,0x01,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,	// magic
	0x01,0x00,				// type
	0x2A,0x00,				// machine 
	0x01,0x00,0x00,0x00,	// version
	0x00,0x00,0x00,0x00,	// entry
	0x00,0x00,0x00,0x00,	// phoff
	0xA8,0x00,0x00,0x00,	// shoff
	0x00,0x00,0x00,0x00,	// flags (default thumb-interworking)
	0x34,0x00,				// ehsize
	0x00,0x00,				// phentsize
	0x00,0x00,				// phnum
	0x28,0x00,				// shentsize
	0x05,0x00,				// shnum
	0x02,0x00,				// shstrndx

};


unsigned char trailer1[] =	
{
		0x00,0x2e,0x73,0x79,0x6d,0x74,0x61,0x62,0x00,0x2e,0x73,0x74,
		0x72,0x74,0x61,0x62,0x00,0x2e,0x73,0x68,0x73,0x74,0x72,0x74,0x61,0x62,0x00,0x2e,
		0x72,0x6f,0x64,0x61,0x74,0x61,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
		0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
		0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
		0x1B,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
		0x34,0x00,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
		0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x11,0x00,0x00,0x00,0x03,0x00,0x00,0x00,
		0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x34,0x04,0x00,0x00,0x23,0x00,0x00,0x00,
		0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
		0x01,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
		0x20,0x05,0x00,0x00,0xA0,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x05,0x00,0x00,0x00,
		0x04,0x00,0x00,0x00,0x10,0x00,0x00,0x00,0x09,0x00,0x00,0x00,0x03,0x00,0x00,0x00,
		0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0x00,0x00,0x00,0x62,0x00,0x00,0x00,
		0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
		0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
		0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x00,0x01,0x00,
		0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x00,0x02,0x00,
		0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x00,0x03,0x00,
		0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x00,0x04,0x00,
		0x01,0x00,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x00,0xF1,0xFF,
		0x1A,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x11,0x00,0x01,0x00,
		0x23,0x00,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x00,0x01,0x00,
		0x3B,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x00,0x01,0x00,
		0x55,0x00,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x11,0x00,0x01,0x00,
		0x00,'_' ,'b' ,'i' ,'n' ,'a' ,'r' ,'y' ,'_' ,'r' ,'o' ,'m' ,'d' ,'i' ,'s' ,'k' ,
		'_' ,'i' ,'m' ,'g' ,'_' ,'s' ,'i' ,'z' ,'e' ,0x00,'_' ,'r' ,'o' ,'m' ,'d' ,'i' ,
		's' ,'k' ,0x00,'_' ,'b' ,'i' ,'n' ,'a' ,'r' ,'y' ,'_' ,'r' ,'o' ,'m' ,'d' ,'i' ,
		's' ,'k' ,'_' ,'i' ,'m' ,'g' ,'_' ,'e' ,'n' ,'d' ,0x00,'_' ,'b' ,'i' ,'n' ,'a' ,
		'r' ,'y' ,'_' ,'r' ,'o' ,'m' ,'d' ,'i' ,'s' ,'k' ,'_' ,'i' ,'m' ,'g' ,'_' ,'s' ,
		't' ,'a' ,'r' ,'t' ,0x00,'_' ,'r' ,'o' ,'m' ,'d' ,'i' ,'s' ,'k' ,'_' ,'e' ,'n' ,
		'd' 

};

unsigned char *header = header1;
unsigned char *trailer = trailer1;


//////////////////////////////////////////////////////////////////////////////
// strc                                                                     //
//////////////////////////////////////////////////////////////////////////////
// replaces non-identifnvx characters with underscores
void strc(char *s)
{
	while (*s)
	{
		if (!(((*s >= 'a') && (*s <= 'z')) || ((*s >= 'A') && (*s <= 'Z')) || ((*s >= '0') && (*s <= '9')))) *s = '_';
		s++;
	}
}

//////////////////////////////////////////////////////////////////////////////
// main                                                                     //
//////////////////////////////////////////////////////////////////////////////
int main(int argc, char *argv[])
{
	// syntax
	if (argc < 2)
	{
		printf("bin2oDC for GCC by JMD. Based on bin2o by Rafael Vuijk (aka Dark Fader)\n");
		printf("Syntax:\n");
		printf("  bin2oDC <input.bin> <output.o>\n");
		printf("\n");
		return -1;
	}

	char *arg_input = argv[1];	// input
	char *arg_output = argv[2];	// output
	 
	// check file/prefix args
	if (!arg_input) { fprintf(stderr, "Error: Need input filename!\n"); return -1; }
	if (!arg_output) { fprintf(stderr, "Error: Need output filename!\n"); return -1; }

	// open files
	FILE *fi = fopen(arg_input, "rb");
	if (!fi) { printf("Error opening input file!\n"); return -1; }
	FILE *fo = fopen(arg_output, "wb");
	if (!fo) { printf("Error opening output file!\n"); return -1; }

	// size
	fseek(fi, 0, SEEK_END);
	int size = (ftell(fi)+3) &~ 3;		// align
	fseek(fi, 0, SEEK_SET);

	// generate id from filename?
	char identifier[256] = "";
	char own_prefix[256] = "";
	if (!identifier[0])
	{
		char s[256]; strcpy(s, arg_input);
		char *p = strrchr(s, '\\');
		if (!p) p = strrchr(s, '/');	// remove directory
		if (p) p++; else p = s;

		strc(p);	// convert non-identifier characters
		strlwr(p);	// convert to lowercase?

		strcpy(identifier, own_prefix);	// can be empty ofcourse
		strcat(identifier, p);
	}
	int idsize = strlen(identifier);

	// patch simple 
		PATCH(header, 0x20, size, 0xA8 - 80); 
		PATCH(trailer, 0x140, size, 0x40 - 64);  
		PATCH(trailer, 0x160, size, 0x40 - 64);  
		PATCH(trailer, 0x180, size, 0x40 - 64); 
		PATCH(trailer, 0x60, size, 0x40 - 64); 
		PATCH(trailer, 0x84, size, 0x40 - 12 ); 
		
		PATCH(trailer, 0xAc, size + 0x100, 0x20  );  
		PATCH(trailer, 0xD4, size + 0x100, 0xC0  );  

		// write data
		fwrite(header, sizeof(header1), 1, fo);
		unsigned char *buf = new unsigned char[size];
		if (size >= 3) { buf[size-1] = 0; buf[size-2] = 0; buf[size-3] = 0; }
		fread(buf, size, 1, fi);
		fwrite(buf, size, 1, fo);
		delete buf;
		fwrite( trailer, sizeof(trailer1), 1, fo);
 
		fputc(0, fo);

		// close files
		fclose(fi);
		fclose(fo);


	return 0;
}
