You've already forked Microtransactions64
mirror of
https://github.com/Print-and-Panic/Microtransactions64.git
synced 2026-01-21 10:17:19 -08:00
added make_patch and flips (#628)
This commit is contained in:
4
Makefile
4
Makefile
@@ -502,6 +502,7 @@ VADPCM_ENC := $(TOOLS_DIR)/vadpcm_enc
|
||||
EXTRACT_DATA_FOR_MIO := $(TOOLS_DIR)/extract_data_for_mio
|
||||
SKYCONV := $(TOOLS_DIR)/skyconv
|
||||
FIXLIGHTS_PY := $(TOOLS_DIR)/fixlights.py
|
||||
FLIPS := $(TOOLS_DIR)/flips
|
||||
ifeq ($(GZIPVER),std)
|
||||
GZIP := gzip
|
||||
else
|
||||
@@ -587,6 +588,9 @@ unf: $(ROM) $(LOADER)
|
||||
|
||||
libultra: $(BUILD_DIR)/libultra.a
|
||||
|
||||
patch: $(ROM)
|
||||
$(FLIPS) --create --bps ./baserom.$(VERSION).z64 $(ROM) $(BUILD_DIR)/$(TARGET_STRING).bps
|
||||
|
||||
# Extra object file dependencies
|
||||
$(BUILD_DIR)/asm/boot.o: $(IPL3_RAW_FILES)
|
||||
$(BUILD_DIR)/src/game/crash_screen.o: $(CRASH_TEXTURE_C_FILES)
|
||||
|
||||
1
tools/.gitignore
vendored
1
tools/.gitignore
vendored
@@ -14,6 +14,7 @@
|
||||
/tabledesign
|
||||
/textconv
|
||||
/vadpcm_enc
|
||||
/flips
|
||||
!/ido5.3_compiler/lib/*.so
|
||||
!/ido5.3_compiler/usr/lib/*.so
|
||||
!/ido5.3_compiler/usr/lib/*.so.1
|
||||
|
||||
5393
tools/Flips/Flips.cpp
Executable file
5393
tools/Flips/Flips.cpp
Executable file
File diff suppressed because it is too large
Load Diff
11
tools/Flips/crc32.h
Executable file
11
tools/Flips/crc32.h
Executable file
@@ -0,0 +1,11 @@
|
||||
#pragma once
|
||||
//Module name: crc32
|
||||
//Author: Alcaro
|
||||
//Date: June 3, 2015
|
||||
//Licence: GPL v3.0 or higher
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
uint32_t crc32_update(const uint8_t* data, size_t len, uint32_t crc);
|
||||
static inline uint32_t crc32(const uint8_t* data, size_t len) { return crc32_update(data, len, 0); }
|
||||
63
tools/Flips/divsufsort.h
Executable file
63
tools/Flips/divsufsort.h
Executable file
@@ -0,0 +1,63 @@
|
||||
/*
|
||||
* divsufsort.h for libdivsufsort-lite
|
||||
* Copyright (c) 2003-2008 Yuta Mori All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person
|
||||
* obtaining a copy of this software and associated documentation
|
||||
* files (the "Software"), to deal in the Software without
|
||||
* restriction, including without limitation the rights to use,
|
||||
* copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following
|
||||
* conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
||||
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
* OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef _DIVSUFSORT_H
|
||||
#define _DIVSUFSORT_H 1
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
|
||||
|
||||
/*- Prototypes -*/
|
||||
|
||||
/**
|
||||
* Constructs the suffix array of a given string.
|
||||
* @param T[0..n-1] The input string.
|
||||
* @param SA[0..n-1] The output array of suffixes.
|
||||
* @param n The length of the given string.
|
||||
* @return 0 if no error occurred, -1 or -2 otherwise.
|
||||
*/
|
||||
int
|
||||
divsufsort(const unsigned char *T, int *SA, int n);
|
||||
|
||||
/**
|
||||
* Constructs the burrows-wheeler transformed string of a given string.
|
||||
* @param T[0..n-1] The input string.
|
||||
* @param U[0..n-1] The output string. (can be T)
|
||||
* @param A[0..n-1] The temporary array. (can be NULL)
|
||||
* @param n The length of the given string.
|
||||
* @return The primary index if no error occurred, -1 or -2 otherwise.
|
||||
*/
|
||||
int
|
||||
divbwt(const unsigned char *T, unsigned char *U, int *A, int n);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#endif /* _DIVSUFSORT_H */
|
||||
208
tools/Flips/divsufsort_private.h
Executable file
208
tools/Flips/divsufsort_private.h
Executable file
@@ -0,0 +1,208 @@
|
||||
#pragma once
|
||||
/*
|
||||
* divsufsort_private.h for libdivsufsort
|
||||
* Copyright (c) 2003-2008 Yuta Mori All Rights Reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person
|
||||
* obtaining a copy of this software and associated documentation
|
||||
* files (the "Software"), to deal in the Software without
|
||||
* restriction, including without limitation the rights to use,
|
||||
* copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following
|
||||
* conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
||||
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
* OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef _DIVSUFSORT_PRIVATE_H
|
||||
#define _DIVSUFSORT_PRIVATE_H 1
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#if HAVE_CONFIG_H
|
||||
# include "config.h"
|
||||
#endif
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
#if HAVE_STRING_H
|
||||
# include <string.h>
|
||||
#endif
|
||||
#if HAVE_STDLIB_H
|
||||
# include <stdlib.h>
|
||||
#endif
|
||||
#if HAVE_MEMORY_H
|
||||
# include <memory.h>
|
||||
#endif
|
||||
#if HAVE_STDDEF_H
|
||||
# include <stddef.h>
|
||||
#endif
|
||||
#if HAVE_STRINGS_H
|
||||
# include <strings.h>
|
||||
#endif
|
||||
#if HAVE_INTTYPES_H
|
||||
# include <inttypes.h>
|
||||
#else
|
||||
# if HAVE_STDINT_H
|
||||
# include <stdint.h>
|
||||
# endif
|
||||
#endif
|
||||
#if defined(BUILD_DIVSUFSORT64)
|
||||
# include "divsufsort64.h"
|
||||
# ifndef SAIDX_T
|
||||
# define SAIDX_T
|
||||
# define saidx_t saidx64_t
|
||||
# endif /* SAIDX_T */
|
||||
# ifndef PRIdSAIDX_T
|
||||
# define PRIdSAIDX_T PRIdSAIDX64_T
|
||||
# endif /* PRIdSAIDX_T */
|
||||
# define divsufsort divsufsort64
|
||||
# define divbwt divbwt64
|
||||
# define divsufsort_version divsufsort64_version
|
||||
# define bw_transform bw_transform64
|
||||
# define inverse_bw_transform inverse_bw_transform64
|
||||
# define sufcheck sufcheck64
|
||||
# define sa_search sa_search64
|
||||
# define sa_simplesearch sa_simplesearch64
|
||||
# define sssort sssort64
|
||||
# define trsort trsort64
|
||||
#else
|
||||
# include "divsufsort.h"
|
||||
#endif
|
||||
|
||||
|
||||
/*- Constants -*/
|
||||
#if !defined(UINT8_MAX)
|
||||
# define UINT8_MAX (255)
|
||||
#endif /* UINT8_MAX */
|
||||
#if defined(ALPHABET_SIZE) && (ALPHABET_SIZE < 1)
|
||||
# undef ALPHABET_SIZE
|
||||
#endif
|
||||
#if !defined(ALPHABET_SIZE)
|
||||
# define ALPHABET_SIZE (UINT8_MAX + 1)
|
||||
#endif
|
||||
/* for divsufsort.c */
|
||||
#define BUCKET_A_SIZE (ALPHABET_SIZE)
|
||||
#define BUCKET_B_SIZE (ALPHABET_SIZE * ALPHABET_SIZE)
|
||||
/* for sssort.c */
|
||||
#if defined(SS_INSERTIONSORT_THRESHOLD)
|
||||
# if SS_INSERTIONSORT_THRESHOLD < 1
|
||||
# undef SS_INSERTIONSORT_THRESHOLD
|
||||
# define SS_INSERTIONSORT_THRESHOLD (1)
|
||||
# endif
|
||||
#else
|
||||
# define SS_INSERTIONSORT_THRESHOLD (8)
|
||||
#endif
|
||||
#if defined(SS_BLOCKSIZE)
|
||||
# if SS_BLOCKSIZE < 0
|
||||
# undef SS_BLOCKSIZE
|
||||
# define SS_BLOCKSIZE (0)
|
||||
# elif 32768 <= SS_BLOCKSIZE
|
||||
# undef SS_BLOCKSIZE
|
||||
# define SS_BLOCKSIZE (32767)
|
||||
# endif
|
||||
#else
|
||||
# define SS_BLOCKSIZE (1024)
|
||||
#endif
|
||||
/* minstacksize = log(SS_BLOCKSIZE) / log(3) * 2 */
|
||||
#if SS_BLOCKSIZE == 0
|
||||
# if defined(BUILD_DIVSUFSORT64)
|
||||
# define SS_MISORT_STACKSIZE (96)
|
||||
# else
|
||||
# define SS_MISORT_STACKSIZE (64)
|
||||
# endif
|
||||
#elif SS_BLOCKSIZE <= 4096
|
||||
# define SS_MISORT_STACKSIZE (16)
|
||||
#else
|
||||
# define SS_MISORT_STACKSIZE (24)
|
||||
#endif
|
||||
#if defined(BUILD_DIVSUFSORT64)
|
||||
# define SS_SMERGE_STACKSIZE (64)
|
||||
#else
|
||||
# define SS_SMERGE_STACKSIZE (32)
|
||||
#endif
|
||||
/* for trsort.c */
|
||||
#define TR_INSERTIONSORT_THRESHOLD (8)
|
||||
#if defined(BUILD_DIVSUFSORT64)
|
||||
# define TR_STACKSIZE (96)
|
||||
#else
|
||||
# define TR_STACKSIZE (64)
|
||||
#endif
|
||||
|
||||
|
||||
/*- Macros -*/
|
||||
#ifndef SWAP
|
||||
# define SWAP(_a, _b) do { t = (_a); (_a) = (_b); (_b) = t; } while(0)
|
||||
#endif /* SWAP */
|
||||
#ifndef MIN
|
||||
# define MIN(_a, _b) (((_a) < (_b)) ? (_a) : (_b))
|
||||
#endif /* MIN */
|
||||
#ifndef MAX
|
||||
# define MAX(_a, _b) (((_a) > (_b)) ? (_a) : (_b))
|
||||
#endif /* MAX */
|
||||
#define STACK_PUSH(_a, _b, _c, _d)\
|
||||
do {\
|
||||
assert(ssize < STACK_SIZE);\
|
||||
stack[ssize].a = (_a), stack[ssize].b = (_b),\
|
||||
stack[ssize].c = (_c), stack[ssize++].d = (_d);\
|
||||
} while(0)
|
||||
#define STACK_PUSH5(_a, _b, _c, _d, _e)\
|
||||
do {\
|
||||
assert(ssize < STACK_SIZE);\
|
||||
stack[ssize].a = (_a), stack[ssize].b = (_b),\
|
||||
stack[ssize].c = (_c), stack[ssize].d = (_d), stack[ssize++].e = (_e);\
|
||||
} while(0)
|
||||
#define STACK_POP(_a, _b, _c, _d)\
|
||||
do {\
|
||||
assert(0 <= ssize);\
|
||||
if(ssize == 0) { return; }\
|
||||
(_a) = stack[--ssize].a, (_b) = stack[ssize].b,\
|
||||
(_c) = stack[ssize].c, (_d) = stack[ssize].d;\
|
||||
} while(0)
|
||||
#define STACK_POP5(_a, _b, _c, _d, _e)\
|
||||
do {\
|
||||
assert(0 <= ssize);\
|
||||
if(ssize == 0) { return; }\
|
||||
(_a) = stack[--ssize].a, (_b) = stack[ssize].b,\
|
||||
(_c) = stack[ssize].c, (_d) = stack[ssize].d, (_e) = stack[ssize].e;\
|
||||
} while(0)
|
||||
/* for divsufsort.c */
|
||||
#define BUCKET_A(_c0) bucket_A[(_c0)]
|
||||
#if ALPHABET_SIZE == 256
|
||||
#define BUCKET_B(_c0, _c1) (bucket_B[((_c1) << 8) | (_c0)])
|
||||
#define BUCKET_BSTAR(_c0, _c1) (bucket_B[((_c0) << 8) | (_c1)])
|
||||
#else
|
||||
#define BUCKET_B(_c0, _c1) (bucket_B[(_c1) * ALPHABET_SIZE + (_c0)])
|
||||
#define BUCKET_BSTAR(_c0, _c1) (bucket_B[(_c0) * ALPHABET_SIZE + (_c1)])
|
||||
#endif
|
||||
|
||||
|
||||
/*- Private Prototypes -*/
|
||||
/* sssort.c */
|
||||
void
|
||||
sssort(const sauchar_t *Td, const saidx_t *PA,
|
||||
saidx_t *first, saidx_t *last,
|
||||
saidx_t *buf, saidx_t bufsize,
|
||||
saidx_t depth, saidx_t n, saint_t lastsuffix);
|
||||
/* trsort.c */
|
||||
void
|
||||
trsort(saidx_t *ISA, saidx_t *SA, saidx_t n, saidx_t depth);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#endif /* _DIVSUFSORT_PRIVATE_H */
|
||||
24
tools/Flips/errors
Executable file
24
tools/Flips/errors
Executable file
@@ -0,0 +1,24 @@
|
||||
flips5.cpp:2771: warning: "error" redefined
|
||||
2771 | #define error(which) do { err = which; goto error; } while(0)
|
||||
|
|
||||
flips5.cpp:2021: note: this is the location of the previous definition
|
||||
2021 | #define error(why) do { ret.error=why; return ret; } while(0)
|
||||
|
|
||||
flips5.cpp:3454: warning: "error" redefined
|
||||
3454 | #define error(which) do { error=which; goto exit; } while(0)
|
||||
|
|
||||
flips5.cpp:2771: note: this is the location of the previous definition
|
||||
2771 | #define error(which) do { err = which; goto error; } while(0)
|
||||
|
|
||||
flips5.cpp:3455: warning: "assert_sum" redefined
|
||||
3455 | #define assert_sum(a,b) do { if (SIZE_MAX-(a)<(b)) error(ups_too_big); } while(0)
|
||||
|
|
||||
flips5.cpp:1675: note: this is the location of the previous definition
|
||||
1675 | #define assert_sum(a,b) do { if (SIZE_MAX-(a)<(b)) error(bps_too_big); } while(0)
|
||||
|
|
||||
flips5.cpp:3456: warning: "assert_shift" redefined
|
||||
3456 | #define assert_shift(a,b) do { if (SIZE_MAX>>(b)<(a)) error(ups_too_big); } while(0)
|
||||
|
|
||||
flips5.cpp:1676: note: this is the location of the previous definition
|
||||
1676 | #define assert_shift(a,b) do { if (SIZE_MAX>>(b)<(a)) error(bps_too_big); } while(0)
|
||||
|
|
||||
283
tools/Flips/flips.h
Executable file
283
tools/Flips/flips.h
Executable file
@@ -0,0 +1,283 @@
|
||||
#pragma once
|
||||
//Module name: Floating IPS, header for all frontends
|
||||
//Author: Alcaro
|
||||
//Date: See Git history
|
||||
//Licence: GPL v3.0 or higher
|
||||
|
||||
//Preprocessor switch documentation:
|
||||
//
|
||||
//FLIPS_WINDOWS
|
||||
//FLIPS_GTK
|
||||
//FLIPS_CLI
|
||||
// Picks which frontend to use for Flips. You can pick one manually, or let Flips choose
|
||||
// automatically depending on the platform (Windows -> FLIPS_WINDOWS, Linux -> FLIPS_GTK, anything
|
||||
// else -> FLIPS_CLI). FLIPS_WINDOWS and FLIPS_CLI can be compiled under both C99 and C++98;
|
||||
// FLIPS_GTK is only tested under C99.
|
||||
// Note that picking the platform native frontend will bring a few advantages even if you only
|
||||
// intend to use Flips from the command line; Windows gains access to filenames outside the 8bit
|
||||
// charset, and GTK+ will gain the ability to handle files on URIs and not the local file system.
|
||||
//
|
||||
//All of these must be defined globally, or Flips will behave erratically.
|
||||
|
||||
#if defined(FLIPS_WINDOWS) || defined(FLIPS_GTK) || defined(FLIPS_CLI)
|
||||
//already picked
|
||||
#elif defined(_WIN32)
|
||||
#define FLIPS_WINDOWS
|
||||
#elif defined(__linux__)
|
||||
#define FLIPS_GTK
|
||||
#else
|
||||
#define FLIPS_CLI
|
||||
#endif
|
||||
|
||||
//#ifdef __cplusplus
|
||||
//#define EXTERN_C extern "C"
|
||||
//#else
|
||||
//#define EXTERN_C
|
||||
//#endif
|
||||
|
||||
#define flipsversion "Floating IPS"
|
||||
|
||||
|
||||
#if defined(FLIPS_WINDOWS)
|
||||
#define UNICODE
|
||||
#define _WIN32_WINNT 0x0501
|
||||
#define _WIN32_IE 0x0600
|
||||
|
||||
#define NOMINMAX // this seems automatically on in C++ - crazy.
|
||||
#ifdef __MINGW32__
|
||||
#include <stdlib.h>
|
||||
#undef __USE_MINGW_ANSI_STDIO // must remove this, to avoid a libgcc_s_sjlj-1.dll dependency on 32bit
|
||||
#endif // comments say libstdc++ demands a POSIX printf, but I'm not using that, so I don't care
|
||||
#include <windows.h>
|
||||
#include <windowsx.h>
|
||||
#include <shlobj.h>
|
||||
#include <wchar.h>
|
||||
#include <stdio.h>
|
||||
#include <commctrl.h>
|
||||
#include <ctype.h>
|
||||
|
||||
#define wcsicmp _wcsicmp // wcsicmp deprecated? okay, have a define
|
||||
#define wcsdup _wcsdup
|
||||
#define wtoi _wtoi
|
||||
|
||||
|
||||
#else
|
||||
#include <string.h>
|
||||
#include <strings.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <ctype.h>
|
||||
|
||||
//Flips uses Windows type names internally, since it's easier to #define them to Linux types than
|
||||
//defining "const char *" to anything else. I could invent my own typedefs, but the only advantage
|
||||
//that would bring over Windows types would be not being Windows types, and I don't see that as a
|
||||
//valid argument.
|
||||
|
||||
#define LPCWSTR const char *
|
||||
#define LPWSTR char *
|
||||
#define WCHAR char
|
||||
|
||||
#define wcscpy strcpy
|
||||
#define wcscat strcat
|
||||
#define wcschr strchr
|
||||
#define wcslen strlen
|
||||
#define wcsdup strdup
|
||||
#define wcsrchr strrchr
|
||||
#define wcscmp strcmp
|
||||
#define wcsncmp strncmp
|
||||
#define wcsicmp strcasecmp
|
||||
//#define wcsnicmp strncasecmp
|
||||
#define wprintf printf
|
||||
#define wsprintf sprintf
|
||||
#define wscanf scanf
|
||||
#define swscanf sscanf
|
||||
#define wtoi atoi
|
||||
|
||||
#define iswalnum isalnum
|
||||
#define iswalpha isalpha
|
||||
#define iswascii isascii
|
||||
#define iswblank isblank
|
||||
#define iswcntrl iscntrl
|
||||
#define iswdigit isdigit
|
||||
#define iswgraph isgraph
|
||||
#define iswlower islower
|
||||
#define iswprint isprint
|
||||
#define iswpunct ispunct
|
||||
#define iswspace isspace
|
||||
#define iswupper isupper
|
||||
#define iswxdigit isxdigit
|
||||
|
||||
#define TEXT(text) text
|
||||
//EXTERN_C int strcasecmp(const char *s1, const char *s2);
|
||||
|
||||
//some platforms define strdup, some don't.
|
||||
#define strdup strdup_flips
|
||||
static inline char* strdup(const char * in)
|
||||
{
|
||||
size_t len=strlen(in);
|
||||
char * ret=(char*)malloc(len+1);
|
||||
memcpy(ret, in, len+1);
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
#include "libbps.h"
|
||||
#include "libips.h"
|
||||
#include "libups.h"
|
||||
|
||||
#ifndef __cplusplus
|
||||
#include <stdbool.h>//If this file does not exist, remove it and uncomment the following three lines.
|
||||
//#define bool int
|
||||
//#define true 1
|
||||
//#define false 0
|
||||
#endif
|
||||
|
||||
|
||||
//provided by Flips core
|
||||
#include "global.h"
|
||||
|
||||
enum patchtype {
|
||||
ty_null,
|
||||
ty_bps,
|
||||
ty_ips,
|
||||
|
||||
//non-recommended formats
|
||||
ty_bps_linear,
|
||||
ty_bps_moremem,
|
||||
ty_ups,
|
||||
|
||||
ty_shut_up_gcc
|
||||
};
|
||||
|
||||
enum errorlevel {
|
||||
el_ok,
|
||||
el_notice,
|
||||
el_unlikelythis,
|
||||
el_warning,
|
||||
el_notthis,
|
||||
el_broken,
|
||||
el_shut_up_gcc
|
||||
};
|
||||
|
||||
struct errorinfo {
|
||||
enum errorlevel level;
|
||||
const char * description;
|
||||
};
|
||||
|
||||
struct manifestinfo {
|
||||
bool use;
|
||||
bool required;
|
||||
LPCWSTR name;
|
||||
};
|
||||
|
||||
class file;
|
||||
class filewrite;
|
||||
|
||||
LPWSTR GetExtension(LPCWSTR fname);
|
||||
LPWSTR GetBaseName(LPCWSTR fname);
|
||||
bool shouldRemoveHeader(LPCWSTR romname, size_t romlen);
|
||||
|
||||
class config
|
||||
{
|
||||
LPWSTR filename;
|
||||
|
||||
size_t numentries;
|
||||
LPWSTR * names;
|
||||
LPWSTR * values;
|
||||
|
||||
//stupid c++, why is there no sane way to get the implementation out of the headers
|
||||
void sort();
|
||||
|
||||
public:
|
||||
|
||||
config()
|
||||
{
|
||||
numentries = 0;
|
||||
names = NULL;
|
||||
values = NULL;
|
||||
}
|
||||
|
||||
//This ends up writing a really ugly format on Windows: UTF-16, no BOM, LF endings.
|
||||
//This is because Microsoft are rude and refuse to support UTF-8 properly. I'm not rewarding that.
|
||||
//I'm catering to their shitty char type, that's way more than enough.
|
||||
|
||||
//If the input is invalid, the object will ignore the invalid parts and remain valid.
|
||||
//In particular, failure to initialize from a file will still update the file on destruction.
|
||||
//Only init once, or it may leak memory or otherwise misbehave.
|
||||
void init_file(LPCWSTR filename);
|
||||
void init_raw(LPWSTR contents); // Modifies the input string.
|
||||
|
||||
//The key may only contain alphanumerics, . and _.
|
||||
//The value may not have leading or trailing whitespace, or contain \r or \n.
|
||||
void set(LPCWSTR key, LPCWSTR value); // If NULL, the key is removed. This may alter or rearrange unrelated get{name,value}byid values.
|
||||
LPCWSTR get(LPCWSTR key, LPCWSTR def = NULL);
|
||||
|
||||
void setint(LPCWSTR key, int value) { WCHAR valstr[16]; wsprintf(valstr, TEXT("%i"), value); set(key, valstr); }
|
||||
int getint(LPCWSTR key, int def = 0) { LPCWSTR val = get(key); return val ? wtoi(val) : def; }
|
||||
|
||||
size_t getcount() { return numentries; }
|
||||
LPCWSTR getnamebyid(size_t i) { return names[i]; }
|
||||
LPCWSTR getvaluebyid(size_t i) { return values[i]; }
|
||||
|
||||
LPWSTR flatten(); // free() this when you're done.
|
||||
~config(); // If you used init_file, this saves automatically.
|
||||
};
|
||||
extern config cfg;
|
||||
|
||||
//TODO: rewrite these
|
||||
struct mem GetRomList();
|
||||
void SetRomList(struct mem data);
|
||||
LPCWSTR FindRomForPatch(file* patch, bool * possibleToFind);
|
||||
void AddToRomList(file* patch, LPCWSTR path);
|
||||
void AddConfigToRomList(LPCWSTR key, LPCWSTR value);
|
||||
void DeleteRomFromList(LPCWSTR path);
|
||||
|
||||
LPCWSTR GetEmuFor(LPCWSTR filename); // NULL if none
|
||||
void SetEmuFor(LPCWSTR filename, LPCWSTR emu);
|
||||
|
||||
struct errorinfo ApplyPatchMem2(file* patch, struct mem inrom, bool removeheader, bool verifyinput,
|
||||
LPCWSTR outromname, struct manifestinfo * manifestinfo);
|
||||
struct errorinfo ApplyPatchMem(file* patch, LPCWSTR inromname, bool verifyinput,
|
||||
LPCWSTR outromname, struct manifestinfo * manifestinfo, bool update_rom_list);
|
||||
struct errorinfo ApplyPatch(LPCWSTR patchname, LPCWSTR inromname, bool verifyinput,
|
||||
LPCWSTR outromname, struct manifestinfo * manifestinfo, bool update_rom_list);
|
||||
//struct errorinfo CreatePatchToMem(file* inrom, file* outrom, enum patchtype patchtype,
|
||||
//struct manifestinfo * manifestinfo, struct mem * patchmem);
|
||||
//struct errorinfo CreatePatch(file* inrom, file* outrom, enum patchtype patchtype,
|
||||
//struct manifestinfo * manifestinfo, LPCWSTR patchname);
|
||||
struct errorinfo CreatePatchToMem(LPCWSTR inromname, LPCWSTR outromname, enum patchtype patchtype,
|
||||
struct manifestinfo * manifestinfo, struct mem * patchmem);
|
||||
struct errorinfo CreatePatch(LPCWSTR inromname, LPCWSTR outromname, enum patchtype patchtype,
|
||||
struct manifestinfo * manifestinfo, LPCWSTR patchname);
|
||||
|
||||
extern char bpsdProgStr[24];
|
||||
extern int bpsdLastPromille;
|
||||
bool bpsdeltaGetProgress(size_t done, size_t total);
|
||||
|
||||
int flipsmain(int argc, WCHAR * argv[]);
|
||||
void usage();//does not return
|
||||
|
||||
|
||||
//provided by the OS port
|
||||
//several functions of file:: and filewrite:: also belong to the OS port
|
||||
|
||||
//TODO: delete
|
||||
struct mem ReadWholeFile(LPCWSTR filename);
|
||||
bool WriteWholeFile(LPCWSTR filename, struct mem data);
|
||||
bool WriteWholeFileWithHeader(LPCWSTR filename, struct mem header, struct mem data);
|
||||
void FreeFileMemory(struct mem mem);
|
||||
|
||||
void bpsdeltaBegin();
|
||||
bool bpsdeltaProgress(void* userdata, size_t done, size_t total);
|
||||
void bpsdeltaEnd();
|
||||
|
||||
int GUIShow(LPCWSTR filename);
|
||||
void GUILoadConfig();
|
||||
//LPCWSTR GUIGetFileFor(uint32_t crc32); // use FindRomForPatch instead
|
||||
#ifdef FLIPS_WINDOWS
|
||||
void GUIClaimConsole();
|
||||
#else
|
||||
#define GUIClaimConsole() // all other platforms have consoles already
|
||||
#endif
|
||||
|
||||
//the OS port is responsible for main()
|
||||
72
tools/Flips/global.h
Executable file
72
tools/Flips/global.h
Executable file
@@ -0,0 +1,72 @@
|
||||
//Module name: Floating IPS, global header
|
||||
//Author: Alcaro
|
||||
//Date: See Git history
|
||||
//Licence: GPL v3.0 or higher
|
||||
|
||||
#ifndef struct_mem
|
||||
#define struct_mem
|
||||
|
||||
//the standard library can be assumed to exist
|
||||
#include <stddef.h>//size_t, SIZE_MAX
|
||||
#include <stdint.h>//uint8_t
|
||||
|
||||
#ifndef SIZE_MAX
|
||||
#define SIZE_MAX ((size_t)-1)
|
||||
#endif
|
||||
|
||||
struct mem {
|
||||
uint8_t * ptr;
|
||||
size_t len;
|
||||
};
|
||||
|
||||
#if defined(FLIPS_WINDOWS)
|
||||
#define LPCWSTR const wchar_t *
|
||||
#else
|
||||
#define LPCWSTR const char *
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
//used by both Flips core/GUI and the BPS creator
|
||||
class file {
|
||||
public:
|
||||
static file* create(LPCWSTR filename);
|
||||
static file* create_libc(const char * filename);
|
||||
static bool exists(LPCWSTR filename);
|
||||
static bool exists_libc(const char * filename);
|
||||
|
||||
virtual size_t len() = 0;
|
||||
virtual bool read(uint8_t* target, size_t start, size_t len) = 0;
|
||||
|
||||
//these two add sizeof(WCHAR) 00s after the actual data, so you can cast it to LPCWSTR
|
||||
static struct mem read(LPCWSTR filename); // provided by Flips core
|
||||
struct mem read(); // provided by Flips core
|
||||
|
||||
virtual ~file() {}
|
||||
};
|
||||
|
||||
class filemap {
|
||||
public:
|
||||
static filemap* create(LPCWSTR filename);
|
||||
static filemap* create_fallback(LPCWSTR filename);
|
||||
|
||||
virtual size_t len() = 0;
|
||||
virtual const uint8_t * ptr() = 0;
|
||||
struct mem get() { struct mem m = { (uint8_t*)ptr(), len() }; return m; }
|
||||
|
||||
virtual ~filemap() {}
|
||||
};
|
||||
|
||||
class filewrite {
|
||||
public:
|
||||
static filewrite* create(LPCWSTR filename);
|
||||
static filewrite* create_libc(const char * filename);
|
||||
|
||||
virtual bool append(const uint8_t* data, size_t len) = 0;
|
||||
|
||||
static bool write(LPCWSTR filename, struct mem data); // provided by Flips core
|
||||
|
||||
virtual ~filewrite() {}
|
||||
};
|
||||
#endif
|
||||
|
||||
#endif
|
||||
107
tools/Flips/libbps.h
Executable file
107
tools/Flips/libbps.h
Executable file
@@ -0,0 +1,107 @@
|
||||
#pragma once
|
||||
|
||||
//Module name: libbps
|
||||
//Author: Alcaro
|
||||
//Date: November 30, 2015
|
||||
//Licence: GPL v3.0 or higher
|
||||
|
||||
#include "global.h"
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
#ifndef __cplusplus
|
||||
#include <stdbool.h>//bool; if this file does not exist (hi msvc), remove it and uncomment the following three lines.
|
||||
//#define bool int
|
||||
//#define true 1
|
||||
//#define false 0
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
enum bpserror {
|
||||
bps_ok,//Patch applied or created successfully.
|
||||
|
||||
bps_to_output,//You attempted to apply a patch to its output.
|
||||
bps_not_this, //This is not the intended input file for this patch.
|
||||
bps_broken, //This is not a BPS patch, or it's malformed somehow.
|
||||
bps_io, //The patch could not be read.
|
||||
|
||||
bps_identical, //The input files are identical.
|
||||
bps_too_big, //Somehow, you're asking for something a size_t can't represent.
|
||||
bps_out_of_mem,//Memory allocation failure.
|
||||
bps_canceled, //The callback returned false.
|
||||
|
||||
bps_shut_up_gcc//This one isn't used, it's just to kill a stray comma warning.
|
||||
};
|
||||
|
||||
//Applies the given BPS patch to the given ROM and puts it in 'out'. Metadata, if present and
|
||||
// requested ('metadata'!=NULL), is also returned. Send both to bps_free when you're done with them.
|
||||
//If accept_wrong_input is true, it may return bps_to_output or bps_not_this, while putting non-NULL in out/metadata.
|
||||
enum bpserror bps_apply(struct mem patch, struct mem in, struct mem * out, struct mem * metadata, bool accept_wrong_input);
|
||||
|
||||
//Creates a BPS patch that converts source to target and stores it to patch. It is safe to give
|
||||
// {NULL,0} as metadata.
|
||||
enum bpserror bps_create_linear(struct mem source, struct mem target, struct mem metadata, struct mem * patch);
|
||||
|
||||
#ifdef __cplusplus // TODO: make this functionality available from C and C-ABI-only languages
|
||||
//Very similar to bps_create_linear; the difference is that this one takes longer to run, but
|
||||
// generates smaller patches.
|
||||
//Because it can take much longer, a progress meter is supplied; total is guaranteed to be constant
|
||||
// between every call until this function returns, done is guaranteed to increase between each
|
||||
// call, and done/total is an approximate percentage counter. Anything else is undefined; for
|
||||
// example, progress may or may not be called for done=0, progress may or may not be called for
|
||||
// done=total, done may or may not increase by the same amount between each call, and the duration
|
||||
// between each call may or may not be constant.
|
||||
//To cancel the patch creation, return false from the callback.
|
||||
//It is safe to pass in NULL for the progress indicator if you're not interested. If the callback is
|
||||
// NULL, it can obviously not be canceled that way (though if it's a CLI program, you can always
|
||||
// Ctrl-C it).
|
||||
//The 'moremem' flag makes it use about twice as much memory (9*(source+target) instead of 5*), but is usually slightly faster.
|
||||
enum bpserror bps_create_delta(file* source, file* target, struct mem metadata, struct mem * patch,
|
||||
bool (*progress)(void* userdata, size_t done, size_t total), void* userdata,
|
||||
bool moremem);
|
||||
#endif
|
||||
|
||||
//Like the above, but takes struct mem rather than file*. Better use the above if possible, the
|
||||
// creator takes 5*(source+target) in addition to whatever the source/target arguments need.
|
||||
enum bpserror bps_create_delta_inmem(struct mem source, struct mem target, struct mem metadata, struct mem * patch,
|
||||
bool (*progress)(void* userdata, size_t done, size_t total), void* userdata,
|
||||
bool moremem);
|
||||
|
||||
//Frees the memory returned in the output parameters of the above. Do not call it twice on the same
|
||||
// input, nor on anything you got from anywhere else. bps_free is guaranteed to be equivalent to
|
||||
// calling stdlib.h's free() on mem.ptr.
|
||||
void bps_free(struct mem mem);
|
||||
|
||||
#ifdef __cplusplus
|
||||
struct bpsinfo {
|
||||
enum bpserror error; // If this is not bps_ok, all other values are undefined.
|
||||
|
||||
size_t size_in;
|
||||
size_t size_out;
|
||||
|
||||
uint32_t crc_in;
|
||||
uint32_t crc_out;
|
||||
uint32_t crc_patch;
|
||||
|
||||
size_t meta_start;
|
||||
size_t meta_size;
|
||||
|
||||
//Tells approximately how much of the input ROM is changed compared to the output ROM.
|
||||
//It's quite heuristic. The algorithm may change with or without notice.
|
||||
//As of writing, I believe this is accurate to 2 significant digits in base 10.
|
||||
//It's also more expensive to calculate than the other data, so it's optional.
|
||||
//If you don't want it, their values are undefined.
|
||||
//The denominator is always guaranteed nonzero, even if something else says it's undefined.
|
||||
//Note that this can return success for invalid patches.
|
||||
size_t change_num;
|
||||
size_t change_denom;
|
||||
};
|
||||
struct bpsinfo bps_get_info(file* patch, bool changefrac);
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
50
tools/Flips/libips.h
Executable file
50
tools/Flips/libips.h
Executable file
@@ -0,0 +1,50 @@
|
||||
#pragma once
|
||||
//Module name: libips
|
||||
//Author: Alcaro
|
||||
//Date: March 8, 2013
|
||||
//Licence: GPL v3.0 or higher
|
||||
|
||||
#include "global.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
enum ipserror {
|
||||
ips_ok,//Patch applied or created successfully.
|
||||
|
||||
ips_notthis,//The patch is most likely not intended for this ROM.
|
||||
ips_thisout,//You most likely applied the patch on the output ROM.
|
||||
ips_scrambled,//The patch is technically valid, but seems scrambled or malformed.
|
||||
ips_invalid,//The patch is invalid.
|
||||
|
||||
ips_16MB,//One or both files is bigger than 16MB. The IPS format doesn't support that. The created
|
||||
//patch contains only the differences to that point.
|
||||
ips_identical,//The input buffers are identical.
|
||||
|
||||
ips_shut_up_gcc//This one isn't used, it's just to kill a stray comma warning.
|
||||
};
|
||||
|
||||
//Applies the IPS patch in [patch, patchlen] to [in, inlen] and stores it to [out, outlen]. Send the
|
||||
// return value in out to ips_free when you're done with it.
|
||||
enum ipserror ips_apply(struct mem patch, struct mem in, struct mem * out);
|
||||
|
||||
//Creates an IPS patch that converts source to target and stores it to patch.
|
||||
enum ipserror ips_create(struct mem source, struct mem target, struct mem * patch);
|
||||
|
||||
//Frees the memory returned in the output parameters of the above. Do not call it twice on the same
|
||||
// input, nor on anything you got from anywhere else. ips_free is guaranteed to be equivalent to
|
||||
// calling stdlib.h's free() on mem.ptr.
|
||||
void ips_free(struct mem mem);
|
||||
|
||||
//ips_study allows you to detect most patching errors without applying it to a ROM, or even a ROM to
|
||||
// apply it to. ips_apply calls ips_study and ips_apply_study, so if you call ips_study yourself,
|
||||
// it's recommended to call ips_apply_study to not redo the calculation. ips_free is still
|
||||
// required.
|
||||
struct ipsstudy;
|
||||
enum ipserror ips_study(struct mem patch, struct ipsstudy * study);
|
||||
enum ipserror ips_apply_study(struct mem patch, struct ipsstudy * study, struct mem in, struct mem * out);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
44
tools/Flips/libups.h
Executable file
44
tools/Flips/libups.h
Executable file
@@ -0,0 +1,44 @@
|
||||
#pragma once
|
||||
//Module name: libups
|
||||
//Author: Alcaro
|
||||
//Date: April 4, 2013
|
||||
//Licence: GPL v3.0 or higher
|
||||
|
||||
#include "global.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
//Several of those are unused, but remain there so the remaining ones match bpserror.
|
||||
enum upserror {
|
||||
ups_ok,//Patch applied or created successfully.
|
||||
|
||||
ups_unused1, //bps_to_output
|
||||
ups_not_this,//This is not the intended input file for this patch.
|
||||
ups_broken, //This is not a UPS patch, or it's malformed somehow.
|
||||
ups_unused2, //bps_io
|
||||
|
||||
ups_identical,//The input files are identical.
|
||||
ups_too_big, //Somehow, you're asking for something a size_t can't represent.
|
||||
ups_unused3, //bps_out_of_mem
|
||||
ups_unused4, //bps_canceled
|
||||
|
||||
ups_shut_up_gcc//This one isn't used, it's just to kill a stray comma warning.
|
||||
};
|
||||
|
||||
//Applies the UPS patch in [patch, patchlen] to [in, inlen] and stores it to [out, outlen]. Send the
|
||||
// return value in out to ups_free when you're done with it.
|
||||
enum upserror ups_apply(struct mem patch, struct mem in, struct mem * out);
|
||||
|
||||
//Creates an UPS patch that converts source to target and stores it to patch. (Not implemented.)
|
||||
enum upserror ups_create(struct mem source, struct mem target, struct mem * patch);
|
||||
|
||||
//Frees the memory returned in the output parameters of the above. Do not call it twice on the same
|
||||
// input, nor on anything you got from anywhere else. ups_free is guaranteed to be equivalent to
|
||||
// calling stdlib.h's free() on mem.ptr.
|
||||
void ups_free(struct mem mem);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
@@ -7,7 +7,7 @@ CC := gcc
|
||||
CXX := g++
|
||||
CFLAGS := -I. -O2 -s
|
||||
LDFLAGS := -lm
|
||||
ALL_PROGRAMS := armips filesizer rncpack n64graphics n64graphics_ci mio0 slienc n64cksum textconv patch_elf_32bit aifc_decode aiff_extract_codebook vadpcm_enc tabledesign extract_data_for_mio skyconv
|
||||
ALL_PROGRAMS := armips filesizer rncpack n64graphics n64graphics_ci mio0 slienc n64cksum textconv patch_elf_32bit aifc_decode aiff_extract_codebook vadpcm_enc tabledesign extract_data_for_mio skyconv flips
|
||||
LIBAUDIOFILE := audiofile/libaudiofile.a
|
||||
|
||||
# Only build armips from tools if it is not found on the system
|
||||
@@ -66,6 +66,9 @@ ifeq ($(HOST_ENV),MinGW)
|
||||
armips_LDFLAGS += -municode
|
||||
endif
|
||||
|
||||
flips: CC := $(CXX)
|
||||
flips_SOURCES := Flips/Flips.cpp
|
||||
|
||||
all-except-recomp: $(LIBAUDIOFILE) $(BUILD_PROGRAMS)
|
||||
|
||||
all: all-except-recomp
|
||||
|
||||
Reference in New Issue
Block a user