mirror of
https://github.com/pret/pokeplatinum.git
synced 2024-11-23 22:09:40 +00:00
Real-match ov86 by defining .itcm section properties; add asmdiff
This commit is contained in:
parent
488f1a6d6e
commit
a33633c089
@ -1,7 +1,7 @@
|
||||
.include "macros/function.inc"
|
||||
.include "global.inc"
|
||||
|
||||
.section .itcm
|
||||
.section .itcm,4,1,4
|
||||
|
||||
arm_func_start sub_01FF8000
|
||||
sub_01FF8000: ; 0x01FF8000
|
||||
|
@ -3435,7 +3435,7 @@ ov86_0223CD00: ; 0x0223CD00
|
||||
ldr r2, [r3, r2]
|
||||
mov r0, #3
|
||||
add r1, #0x14
|
||||
.byte 0xBB, 0xF5, 0x4C, 0xEC
|
||||
bl sub_01FF85B8
|
||||
ldr r0, _0223CD30 ; =0x04000448
|
||||
mov r1, #1
|
||||
str r1, [r0, #0]
|
||||
@ -4063,7 +4063,7 @@ ov86_0223D220: ; 0x0223D220
|
||||
ldr r2, [r4, r2]
|
||||
mov r0, #3
|
||||
add r1, r4, r1
|
||||
.byte 0xBB, 0xF5, 0xBA, 0xE9
|
||||
bl sub_01FF85B8
|
||||
ldr r0, _0223D260 ; =0x04000448
|
||||
mov r1, #1
|
||||
str r1, [r0, #0]
|
||||
|
4
tools/asmdiff/.gitignore
vendored
Normal file
4
tools/asmdiff/.gitignore
vendored
Normal file
@ -0,0 +1,4 @@
|
||||
.bins/
|
||||
.files/
|
||||
ntrextractfile
|
||||
ntruncompbw
|
17
tools/asmdiff/Makefile
Normal file
17
tools/asmdiff/Makefile
Normal file
@ -0,0 +1,17 @@
|
||||
CC := gcc
|
||||
CFLAGS := -O2 -g -Wno-unused-result
|
||||
|
||||
ifneq ($(DEBUG),1)
|
||||
CFLAGS += -DNDEBUG
|
||||
endif
|
||||
|
||||
programs := ntrextractfile ntruncompbw
|
||||
|
||||
all: $(programs)
|
||||
@:
|
||||
|
||||
clean:
|
||||
$(RM) $(programs)
|
||||
|
||||
%: %.c
|
||||
$(CC) $(CFLAGS) -o $@ $<
|
8
tools/asmdiff/find_module_params.py
Normal file
8
tools/asmdiff/find_module_params.py
Normal file
@ -0,0 +1,8 @@
|
||||
import sys
|
||||
|
||||
with open(sys.argv[1], 'rb') as fp:
|
||||
data = fp.read()
|
||||
x = data.find(b'\x21\x06\xc0\xde')
|
||||
if x != -1:
|
||||
x -= 28
|
||||
print(x)
|
153
tools/asmdiff/ntrextractfile.c
Normal file
153
tools/asmdiff/ntrextractfile.c
Normal file
@ -0,0 +1,153 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#ifndef NDEBUG
|
||||
#ifdef _MSC_VER
|
||||
#define debug_printf(fmt, ...) fprintf(stderr, fmt, __VA_ARGS__)
|
||||
#else
|
||||
#define debug_printf(fmt, ...) fprintf(stderr, fmt, ##__VA_ARGS__)
|
||||
#endif //_MSC_VER
|
||||
#else
|
||||
#define debug_printf(fmt, ...) ((void)0)
|
||||
#endif //NDEBUG
|
||||
|
||||
#define FIND_FAIL (-1u)
|
||||
|
||||
struct NtrDirHeader {
|
||||
unsigned offset;
|
||||
unsigned short first_file;
|
||||
unsigned short count_or_parent;
|
||||
};
|
||||
|
||||
static char FILEBUF[BUFSIZ];
|
||||
|
||||
unsigned find_file(struct NtrDirHeader * fnt, const char * cfilename) {
|
||||
unsigned file_id = fnt->first_file;
|
||||
char * filename = strdup(cfilename);
|
||||
char * tokenizer = filename;
|
||||
int found = 0;
|
||||
char * tree = (char *)fnt + fnt->offset;
|
||||
char * token;
|
||||
|
||||
while ((token = strtok(tokenizer, "/")) != NULL) {
|
||||
tokenizer = NULL;
|
||||
debug_printf("TOKEN: %s\n", token);
|
||||
long toklen = strlen(token);
|
||||
while (*tree) {
|
||||
char flag = *tree++;
|
||||
#ifndef NDEBUG
|
||||
char *entname = malloc((flag & 0x7F) + 1);
|
||||
*stpncpy(entname, tree, flag & 0x7F) = 0;
|
||||
debug_printf("testing entry %s...", entname);
|
||||
free(entname);
|
||||
#endif //NDEBUG
|
||||
if ((toklen != (flag & 0x7F)) || strncmp(tree, token, toklen) != 0) {
|
||||
debug_printf("no; is %s\n", (flag & 0x80) ? "dir" : "file");
|
||||
// Next entry
|
||||
tree += (flag & 0x7F);
|
||||
if (flag & 0x80) {
|
||||
tree += 2; // skip dir id
|
||||
}
|
||||
else {
|
||||
file_id++;
|
||||
}
|
||||
}
|
||||
else {
|
||||
debug_printf("yes; is %s\n", (flag & 0x80) ? "dir" : "file");
|
||||
tree += (flag & 0x7F);
|
||||
if (flag & 0x80) {
|
||||
// navigate to next dir
|
||||
unsigned short dir_id = (unsigned char) tree[0] | ((unsigned char) tree[1] << 8);
|
||||
file_id = fnt[dir_id & 0xFFF].first_file;
|
||||
tree = (char *)fnt + fnt[dir_id & 0xFFF].offset;
|
||||
break;
|
||||
}
|
||||
else {
|
||||
found = 1;
|
||||
token = strtok(NULL, "/");
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
done:
|
||||
free(filename);
|
||||
if (!found || token != NULL) {
|
||||
file_id = FIND_FAIL;
|
||||
}
|
||||
return file_id;
|
||||
}
|
||||
|
||||
int main(int argc, char ** argv) {
|
||||
if (argc < 3) {
|
||||
fprintf(stderr, "missing required argument: %s\n", (argc == 1) ? "BASEROM" : "FILENAME");
|
||||
return 1;
|
||||
}
|
||||
FILE *baserom = fopen(argv[1], "rb");
|
||||
if (baserom == NULL) {
|
||||
fprintf(stderr, "unable to open ROM %s for reading\n", argv[1]);
|
||||
return 1;
|
||||
}
|
||||
debug_printf("opened baserom\n");
|
||||
|
||||
// fnt offset, fnt size, fat offset, fat size
|
||||
unsigned offsets[4];
|
||||
fseek(baserom, 64, SEEK_SET);
|
||||
if (fread(offsets, 4, 4, baserom) != 4) {
|
||||
fprintf(stderr, "failed to read from baserom\n");
|
||||
fclose(baserom);
|
||||
return 1;
|
||||
}
|
||||
debug_printf("read offsets\n");
|
||||
|
||||
// read fnt
|
||||
struct NtrDirHeader *fnt = malloc(offsets[1]);
|
||||
if (fnt == NULL) {
|
||||
fprintf(stderr, "unable to allocate FNT buffer\n");
|
||||
fclose(baserom);
|
||||
return 1;
|
||||
}
|
||||
fseek(baserom, offsets[0], SEEK_SET);
|
||||
if (fread(fnt, 1, offsets[1], baserom) != offsets[1]) {
|
||||
fprintf(stderr, "unable to read FNT\n");
|
||||
free(fnt);
|
||||
fclose(baserom);
|
||||
return 1;
|
||||
}
|
||||
debug_printf("read fnt\n");
|
||||
|
||||
unsigned file_id = find_file(fnt, argv[2]);
|
||||
free(fnt);
|
||||
if (file_id == FIND_FAIL) {
|
||||
fprintf(stderr, "file not found");
|
||||
fclose(baserom);
|
||||
return 1;
|
||||
}
|
||||
debug_printf("found file with id %u\n", file_id);
|
||||
|
||||
// Extract the file to stdout
|
||||
if (8 * file_id >= offsets[3]) {
|
||||
fprintf(stderr, "nitrofs lookup failed");
|
||||
fclose(baserom);
|
||||
return 1;
|
||||
}
|
||||
|
||||
FILE *out = fdopen(dup(fileno(stdout)), "wb");
|
||||
fseek(baserom, offsets[2] + 8 * file_id, SEEK_SET);
|
||||
fread(offsets, 4, 2, baserom);
|
||||
fseek(baserom, offsets[0], SEEK_SET);
|
||||
while (offsets[1] - offsets[0] > BUFSIZ) {
|
||||
fread(FILEBUF, 1, BUFSIZ, baserom);
|
||||
fwrite(FILEBUF, 1, BUFSIZ, out);
|
||||
offsets[0] += BUFSIZ;
|
||||
}
|
||||
fread(FILEBUF, 1, offsets[1] - offsets[0], baserom);
|
||||
fwrite(FILEBUF, 1, offsets[1] - offsets[0], out);
|
||||
fclose(out);
|
||||
|
||||
fclose(baserom);
|
||||
return 0;
|
||||
}
|
107
tools/asmdiff/ntruncompbw.c
Normal file
107
tools/asmdiff/ntruncompbw.c
Normal file
@ -0,0 +1,107 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
|
||||
static inline uint32_t READ32(const unsigned char * ptr)
|
||||
{
|
||||
return ptr[0] | (ptr[1] << 8) | (ptr[2] << 16) | (ptr[3] << 24);
|
||||
}
|
||||
|
||||
static uint32_t MIi_UncompressBackwards(unsigned char ** out_p, size_t compsize)
|
||||
{
|
||||
unsigned char * out = *out_p;
|
||||
|
||||
// Read the pointer to the end of the compressed image
|
||||
uint8_t * endptr = out + compsize - 8;
|
||||
uint32_t size = READ32(endptr);
|
||||
uint32_t offset = READ32(endptr + 4);
|
||||
out = realloc(out, compsize + offset);
|
||||
if (out == NULL)
|
||||
return -1u;
|
||||
endptr = out + compsize;
|
||||
uint8_t * dest_p = endptr + offset;
|
||||
uint8_t * end = endptr - ((uint8_t)(size >> 24));
|
||||
uint8_t * start = endptr - (size & ~0xFF000000);
|
||||
while (end > start) {
|
||||
uint8_t r5 = *--end;
|
||||
for (int i = 0; i < 8; i++) {
|
||||
if ((r5 & 0x80) == 0)
|
||||
*--dest_p = *--end;
|
||||
else {
|
||||
int ip = *--end;
|
||||
int r7 = *--end;
|
||||
|
||||
|
||||
r7 = ((r7 | (ip << 8)) & ~0xF000) + 2;
|
||||
ip += 0x20;
|
||||
while (ip >= 0) {
|
||||
dest_p[-1] = dest_p[r7];
|
||||
dest_p--;
|
||||
ip -= 0x10;
|
||||
}
|
||||
}
|
||||
if (end <= start)
|
||||
break;
|
||||
r5 <<= 1;
|
||||
}
|
||||
}
|
||||
*out_p = out;
|
||||
return compsize + offset;
|
||||
}
|
||||
|
||||
int main(int argc, char ** argv)
|
||||
{
|
||||
if (argc < 4) {
|
||||
fprintf(stderr, "usage: %s FILE VMA END\n\ninsufficient arguments\n", argv[0]);
|
||||
return 1;
|
||||
}
|
||||
char * infname = argv[1];
|
||||
uint32_t vma = strtoul(argv[2], NULL, 0);
|
||||
uint32_t end = strtoul(argv[3], NULL, 0);
|
||||
if (end == 0) {
|
||||
fprintf(stderr, "compressed size is 0, no action taken\n");
|
||||
return 0;
|
||||
}
|
||||
FILE * infile = fopen(infname, "r+b");
|
||||
if (infile == NULL) {
|
||||
fclose(infile);
|
||||
fprintf(stderr, "unable to open file %s for reading\n", infname);
|
||||
return 1;
|
||||
}
|
||||
fseek(infile, 0, SEEK_END);
|
||||
long infsize = ftell(infile);
|
||||
fseek(infile, 0, SEEK_SET);
|
||||
if (infsize != end - vma) {
|
||||
fclose(infile);
|
||||
fprintf(stderr, "compressed size does not match file size, I am cowardly doing nothing\n");
|
||||
return 0;
|
||||
}
|
||||
unsigned char * inbuf = malloc(infsize);
|
||||
if (inbuf == NULL) {
|
||||
fclose(infile);
|
||||
fprintf(stderr, "error: malloc(%d)\n", (int)infsize);
|
||||
return 1;
|
||||
}
|
||||
if (fread(inbuf, 1, infsize, infile) != infsize) {
|
||||
fclose(infile);
|
||||
free(inbuf);
|
||||
fprintf(stderr, "error reading from %s\n", infname);
|
||||
return 1;
|
||||
}
|
||||
uint32_t outsize = MIi_UncompressBackwards(&inbuf, end - vma);
|
||||
if (outsize == -1u) {
|
||||
fclose(infile);
|
||||
fprintf(stderr, "fatal error reallocating for decompression\n");
|
||||
return 1;
|
||||
}
|
||||
fseek(infile, 0, SEEK_SET);
|
||||
if (fwrite(inbuf, 1, outsize, infile) != outsize) {
|
||||
fclose(infile);
|
||||
free(inbuf);
|
||||
fprintf(stderr, "error writing back to %s\n", infname);
|
||||
return 1;
|
||||
}
|
||||
fclose(infile);
|
||||
free(inbuf);
|
||||
return 0;
|
||||
}
|
Loading…
Reference in New Issue
Block a user