220 lines
5 KiB
C++
220 lines
5 KiB
C++
//
|
|
// cfile.cpp
|
|
//
|
|
#include "cfile.h"
|
|
|
|
#ifdef __STDC_LIB_EXT1__
|
|
#define __STDC_WANT_LIB_EXT1__ 1
|
|
#endif
|
|
|
|
#include <stdio.h>
|
|
|
|
//------------------------------------------------------------------------------
|
|
// Static Helpers
|
|
|
|
static bool contains(char x, const char* pSeparators)
|
|
{
|
|
while (*pSeparators)
|
|
{
|
|
if (x == *pSeparators)
|
|
{
|
|
return true;
|
|
}
|
|
pSeparators++;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
static std::vector<std::string> split(const std::string& s, const char* separators)
|
|
{
|
|
std::vector<std::string> output;
|
|
std::string::size_type prev_pos = 0, pos = 0;
|
|
|
|
for (int index = 0; index < s.length(); ++index)
|
|
{
|
|
pos = index;
|
|
|
|
// if the index is a separator
|
|
if (contains(s[index], separators))
|
|
{
|
|
// if we've skipped a token, collect it
|
|
if (prev_pos != index)
|
|
{
|
|
output.push_back(s.substr(prev_pos, index-prev_pos));
|
|
|
|
// skip white space here
|
|
while (index < s.length())
|
|
{
|
|
if (contains(s[index], separators))
|
|
{
|
|
++index;
|
|
}
|
|
else
|
|
{
|
|
prev_pos = index;
|
|
pos = index;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
prev_pos++;
|
|
}
|
|
}
|
|
}
|
|
|
|
output.push_back(s.substr(prev_pos, pos-prev_pos+1)); // Last word
|
|
|
|
return output;
|
|
}
|
|
|
|
#if 0
|
|
// make this string lowercase
|
|
static void tolower(std::string& s)
|
|
{
|
|
for (int index = 0; index < s.length(); ++index)
|
|
{
|
|
s[index] = tolower( s[index] );
|
|
}
|
|
}
|
|
#endif
|
|
|
|
static std::string next_token(std::vector<std::string>& tokens, MemoryStream& memStream)
|
|
{
|
|
std::string result = "";
|
|
|
|
if (tokens.size() >= 1)
|
|
{
|
|
result = tokens[0];
|
|
tokens.erase(tokens.cbegin());
|
|
}
|
|
else
|
|
{
|
|
while (memStream.NumBytesAvailable())
|
|
{
|
|
std::string lineData = memStream.ReadLine();
|
|
tokens = split(lineData, "[](), \t");
|
|
|
|
if (tokens.size() >= 1)
|
|
{
|
|
return next_token(tokens, memStream);
|
|
}
|
|
}
|
|
|
|
}
|
|
return result;
|
|
}
|
|
|
|
//------------------------------------------------------------------------------
|
|
CFile::CFile( std::string filepath )
|
|
: m_filepath( filepath )
|
|
{
|
|
FILE* pFile = nullptr;
|
|
#ifdef __STDC_LIB_EXT1__
|
|
int err = fopen_s(&pFile, filepath.c_str(), "rb");
|
|
#else
|
|
int err = 0;
|
|
pFile = fopen(filepath.c_str(), "rb");
|
|
#endif
|
|
|
|
if ((0==err) && (nullptr!=pFile))
|
|
{
|
|
fseek(pFile, 0, SEEK_END);
|
|
size_t length = ftell(pFile);
|
|
fseek(pFile, 0, SEEK_SET);
|
|
|
|
//printf("\n// CFile %s - %lld bytes\n", filepath.c_str(), length);
|
|
//printf("// Reading %s\n", filepath.c_str());
|
|
//printf("//\n");
|
|
//printf("// This file generated by overlayhelper.exe\n");
|
|
//printf("//\n");
|
|
//printf("//\n");
|
|
|
|
u8* pData = new u8[ length ];
|
|
|
|
fread(pData, sizeof(u8), length / sizeof(u8), pFile);
|
|
|
|
// Now we have a buffer, with the whole C File
|
|
// Looking to parse 2 types of things
|
|
// CODE_BLOCK macros
|
|
// DATA_BLOCK macros
|
|
// INCBIN macros
|
|
{
|
|
MemoryStream memStream(pData, length);
|
|
|
|
while (memStream.NumBytesAvailable())
|
|
{
|
|
std::string lineData = memStream.ReadLine();
|
|
|
|
// symbols are case sensitive
|
|
|
|
// we care about the first 32 bit value in hex, and the last value on the line, the symbol
|
|
std::vector<std::string> tokens = split(lineData, "[](), \t");
|
|
|
|
if (tokens.size() >= 2)
|
|
{
|
|
std::string token = next_token(tokens, memStream);
|
|
|
|
if (token == "INCBIN")
|
|
{
|
|
// section
|
|
token = next_token(tokens, memStream);
|
|
token = next_token(tokens, memStream);
|
|
|
|
printf("incbin_%s_start_high = incbin_%s_start>>16;\n", token.c_str(),token.c_str());
|
|
printf("incbin_%s_start_BLOCK = incbin_%s_start/0x2000;\n", token.c_str(),token.c_str());
|
|
printf("incbin_%s_length = incbin_%s_end-incbin_%s_start;\n", token.c_str(),token.c_str(),token.c_str());
|
|
printf("incbin_%s_length_high = incbin_%s_length>>16;\n", token.c_str(),token.c_str());
|
|
|
|
}
|
|
else if ( (token == "CODE_BLOCK") ||
|
|
(token == "DATA_BLOCK") )
|
|
{
|
|
// We aren't as good as the C Preprocessor, but we will allow this
|
|
// to span 1 line, because RickJr has weird syntax
|
|
|
|
// First get the block number
|
|
token = next_token(tokens, memStream);
|
|
u32 block_num = strtoul(token.c_str(), nullptr, 0);
|
|
|
|
// Next we need the function name
|
|
do
|
|
{
|
|
token = next_token(tokens, memStream);
|
|
|
|
} while (token=="static" || token =="volatile");
|
|
|
|
// now token has return type
|
|
|
|
token = next_token(tokens, memStream);
|
|
|
|
// now token finally has our function or data name
|
|
printf("%s_BLOCK = %lu;\n", token.c_str(), block_num); // just need the block number for mapper
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
delete[] pData;
|
|
|
|
fclose(pFile);
|
|
|
|
//printf("\n// Read Completed\n");
|
|
}
|
|
else
|
|
{
|
|
printf("// CFile could not open %s\n", filepath.c_str());
|
|
printf("//\n");
|
|
}
|
|
}
|
|
|
|
//------------------------------------------------------------------------------
|
|
|
|
CFile::~CFile()
|
|
{
|
|
}
|
|
|
|
//------------------------------------------------------------------------------
|
|
|