use libagbsyscall for all builds (#249)

This commit is contained in:
Oliver Bell authored and GitHub committed 2026-03-25 10:52:35 +00:00
1 parent 9da592bb8e
commit 763812acc3
13 files changed
+383 -1454

No files matched your search

+9 -10
View File
@@ -116,7 +116,7 @@ SDL_MINGW_LIB := $(SDL_MINGW_PKG)/lib
SDL_MINGW_FLAGS := -I$(SDL_MINGW_INCLUDE) -D_THREAD_SAFE
SDL_MINGW_LIBS := -L$(SDL_MINGW_LIB) -lSDL2main -lSDL2.dll
LIBABGSYSCALL_LIBS := -L$(ROOT_DIR)/libagbsyscall -lagbsyscall
LIBABGSYSCALL_LIBS := -L$(ROOT_DIR)/libagbsyscall/build/$(PLATFORM) -lagbsyscall
### FILES ###
@@ -355,13 +355,13 @@ endif
ifeq ($(PLATFORM),gba)
LIBS := $(ROOT_DIR)/tools/agbcc/lib/libgcc.a $(ROOT_DIR)/tools/agbcc/lib/libc.a $(LIBABGSYSCALL_LIBS)
else ifeq ($(PLATFORM),sdl)
LIBS := $(shell sdl2-config --cflags --libs)
LIBS := $(shell sdl2-config --cflags --libs) $(LIBABGSYSCALL_LIBS) -lm
else ifeq ($(PLATFORM),sdl_psp)
LIBS := -L$(PSPDEV)/psp/lib -L$(PSPSDK)/lib -lSDL2 -lm -lGL -lpspvram -lpspaudio -lpspvfpu -lpspdisplay -lpspgu -lpspge -lpsphprm -lpspctrl -lpsppower -lpspdebug -lpspnet -lpspnet_apctl -Wl,-zmax-page-size=128
LIBS := -L$(PSPDEV)/psp/lib $(LIBABGSYSCALL_LIBS) -L$(PSPSDK)/lib -lSDL2 -lm -lGL -lpspvram -lpspaudio -lpspvfpu -lpspdisplay -lpspgu -lpspge -lpsphprm -lpspctrl -lpsppower -lpspdebug -lpspnet -lpspnet_apctl -Wl,-zmax-page-size=128
else ifeq ($(PLATFORM),ps2)
LIBS := -T$(PS2SDK)/ee/startup/linkfile -L$(PS2SDK)/common/lib -L$(PS2SDK)/ee/lib -L$(PS2DEV)/gsKit/lib -L$(PS2SDK)/ports/lib -lgskit -ldmakit -lps2_drivers -lmc -lpatches -Wl,-zmax-page-size=128
LIBS := -T$(PS2SDK)/ee/startup/linkfile $(LIBABGSYSCALL_LIBS) -L$(PS2SDK)/common/lib -L$(PS2SDK)/ee/lib -L$(PS2DEV)/gsKit/lib -L$(PS2SDK)/ports/lib -lgskit -ldmakit -lps2_drivers -lmc -lpatches -Wl,-zmax-page-size=128
else ifeq ($(PLATFORM),sdl_win32)
LIBS := -mwin32 -lkernel32 -lwinmm -lmingw32 -lxinput $(SDL_MINGW_LIBS)
LIBS := -mwin32 -lkernel32 -lwinmm -lmingw32 -lxinput $(LIBABGSYSCALL_LIBS) $(SDL_MINGW_LIBS)
else ifeq ($(PLATFORM), win32)
LIBS := -mwin32 -lkernel32 -lwinmm -lgdi32 -lxinput -lopengl32 $(LIBABGSYSCALL_LIBS)
endif
@@ -533,12 +533,11 @@ ifeq ($(PLATFORM),gba)
$(ROM): $(ELF) libagbsyscall
$(OBJCOPY) -O binary --pad-to 0x8400000 $< $@
$(FIX) $@ -p -t"$(TITLE)" -c$(GAME_CODE) -m$(MAKER_CODE) -r$(GAME_REVISION) --silent
else ifeq ($(PLATFORM),win32)
$(ROM): $(ELF) libagbsyscall
$(OBJCOPY) -O pei-x86-64 $< $@
else
$(ROM): $(ELF)
ifeq ($(PLATFORM),sdl)
$(ROM): $(ELF) libagbsyscall
ifeq ($(PLATFORM),win32)
$(OBJCOPY) -O pei-x86-64 $< $@
else ifeq ($(PLATFORM),sdl)
cp $< $@
else ifeq ($(PLATFORM),sdl_psp)
@echo Creating $(ROM) from $(ELF)
-18
View File
@@ -3,24 +3,6 @@
#include "gba/types.h"
/* NOTE:
* "Unsafe" versions included for compatibility.
* This is just here so if someone accidentally calls
* LZUnCompWram, LZUnCompVram, RLUnCompWram orRLUnCompVram, it doesn't fail.
*
* Please do NOT call them directly if you know the size of the compressed data!
* Use Platform_LZDecompress and Platform_RLDecompress instead, and also
* make sure to call Platform_LZFree, Platform_RLFree once the data is not needed
* anymore.
*/
#define ENABLE_RL_LZ_LOGGING 1
extern unsigned char *Platform_LZDecompress(unsigned char *src, int srcSize);
extern unsigned char *Platform_RLDecompress(unsigned char *src, int srcSize);
extern void Platform_LZFree(unsigned char *dest);
extern void Platform_RLFree(unsigned char *dest);
extern void Platform_LZDecompressUnsafe(unsigned char *src, unsigned char *dest);
extern void Platform_RLDecompressUnsafe(unsigned char *src, unsigned char *dest);
extern void Platform_QueueAudio(const s16 *data, u32 numBytes);
extern void Platform_ProcessBackgroundsCopyQueue(void);
// TODO: Re-enable once #include-ing global.h/core.h/sprite.h does not result in compilation errors.
+19 -5
View File
@@ -2,7 +2,13 @@
PLATFORM ?= gba
CPU_ARCH ?= arm
SHELL := /bin/bash -o pipefail
SHELL := /bin/bash -o pipefail
OBJ_DIR := build/$(PLATFORM)
# a special command which ensures that stdout and stderr
# get printed instead of output into the makefile
infoshell = $(foreach line, $(shell $1 | sed "s/ /__SPACE__/g"), $(info $(subst __SPACE__, ,$(line))))
$(call infoshell, mkdir -p $(OBJ_DIR))
ifeq ($(PLATFORM),gba)
TOOLCHAIN := $(DEVKITARM)
@@ -34,6 +40,13 @@ else ifeq ($(CPU_ARCH),i386)
TOOLCHAIN := /usr/x86_64-w64-mingw32/
PREFIX := x86_64-w64-mingw32-
endif
else ifeq ($(PLATFORM),sdl_psp)
PSPDEV ?= $(HOME)/pspdev
PSPSDK := $(PSPDEV)/psp/sdk
export PATH := $(PSPDEV)/bin:$(PATH)
PREFIX := psp-
else ifeq ($(PLATFORM),ps2)
PREFIX := mips64r5900el-ps2-elf-
else ifneq ($(PLATFORM),sdl)
$(error Unknown CPU architecture $(CPU_ARCH))
endif # (PLATFORM == gba)
@@ -83,10 +96,12 @@ ifneq ($(PLATFORM),gba)
CPPFLAGS += -D CPU_ARCH_X86=0
endif
ifeq ($(PLATFORM), sdl)
ifeq ($(shell uname -s),Darwin)
# -E: Pre-process only (needed for MacOS?)
CPP := $(CC1) -E
endif
endif
endif # PLATFORM != gba
@@ -148,10 +163,9 @@ else
SRCS := libagbsyscall.c
endif
ASMS := $(foreach syscall, $(SYSCALLS), $(syscall).s) # $(syscall).s should only exist after compiling non-GBA
OBJS := $(foreach syscall, $(SYSCALLS), $(syscall).o)
OBJS := $(foreach syscall, $(SYSCALLS), $(OBJ_DIR)/$(syscall).o)
LIB := libagbsyscall.a
LIB := $(OBJ_DIR)/libagbsyscall.a
.PHONY: all clean
@@ -159,7 +173,7 @@ all: $(LIB)
@:
clean:
rm -f $(LIB) $(OBJS) $(ASMS)
rm -rf build
$(LIB): $(OBJS)
$(AR) $(ARFLAGS) $@ $^
File renamed without changes.
+80
View File
@@ -0,0 +1,80 @@
// Copyright (c) 2015 YamaArashi
#include <stdlib.h>
#include <stdbool.h>
#include <stdio.h>
#ifdef _MSC_VER
#define FATAL_ERROR(format, ...) \
do { \
fprintf(stderr, format, __VA_ARGS__); \
exit(1); \
} while (0)
#define UNUSED
#else
#define FATAL_ERROR(format, ...) \
do { \
fprintf(stderr, format, ##__VA_ARGS__); \
exit(1); \
} while (0)
#define UNUSED __attribute__((__unused__))
#endif // _MSC_VER
void LZDecompressUnsafe(unsigned char *src, unsigned char *dest, int *uncompressedSize)
{
int destSize = (src[3] << 16) | (src[2] << 8) | src[1];
if (dest == NULL)
goto fail;
int srcPos = 4;
int destPos = 0;
for (;;) {
unsigned char flags = src[srcPos++];
for (int i = 0; i < 8; i++) {
if (flags & 0x80) {
int blockSize = (src[srcPos] >> 4) + 3;
int blockDistance = (((src[srcPos] & 0xF) << 8) | src[srcPos + 1]) + 1;
srcPos += 2;
int blockPos = destPos - blockDistance;
// Some Ruby/Sapphire tilesets overflow.
if (destPos + blockSize > destSize) {
blockSize = destSize - destPos;
fprintf(stderr, "Destination buffer overflow.\n");
}
if (blockPos < 0)
goto fail;
for (int j = 0; j < blockSize; j++)
dest[destPos++] = dest[blockPos + j];
} else {
if (destPos >= destSize)
goto fail;
dest[destPos++] = src[srcPos++];
}
if (destPos == destSize) {
*uncompressedSize = destSize;
return;
}
flags <<= 1;
}
}
fail:
FATAL_ERROR("Fatal error while decompressing LZ file.\n");
}
+70
View File
@@ -0,0 +1,70 @@
// Copyright (c) 2016 YamaArashi
#include <stdlib.h>
#include <stdbool.h>
#include <stdio.h>
#ifdef _MSC_VER
#define FATAL_ERROR(format, ...) \
do { \
fprintf(stderr, format, __VA_ARGS__); \
exit(1); \
} while (0)
#define UNUSED
#else
#define FATAL_ERROR(format, ...) \
do { \
fprintf(stderr, format, ##__VA_ARGS__); \
exit(1); \
} while (0)
#define UNUSED __attribute__((__unused__))
#endif // _MSC_VER
void RLDecompressUnsafe(unsigned char *src, unsigned char *dest, int *uncompressedSize)
{
int destSize = (src[3] << 16) | (src[2] << 8) | src[1];
if (dest == NULL)
goto fail;
int srcPos = 4;
int destPos = 0;
for (;;) {
unsigned char flags = src[srcPos++];
bool compressed = ((flags & 0x80) != 0);
if (compressed) {
int length = (flags & 0x7F) + 3;
unsigned char data = src[srcPos++];
if (destPos + length > destSize)
goto fail;
for (int i = 0; i < length; i++)
dest[destPos++] = data;
} else {
int length = (flags & 0x7F) + 1;
if (destPos + length > destSize)
goto fail;
for (int i = 0; i < length; i++)
dest[destPos++] = src[srcPos++];
}
if (destPos == destSize) {
*uncompressedSize = destSize;
return;
}
}
fail:
FATAL_ERROR("Fatal error while decompressing RL file.\n");
}
+204 -18
View File
@@ -4,8 +4,7 @@
#if CPU_ARCH_X86
#include <immintrin.h>
#endif
#include "global.h"
#include "gba/syscall.h"
#include "gba/gba.h"
#if (!(defined PLATFORM_GBA) || (PLATFORM_GBA == 0))
@@ -52,8 +51,18 @@ void CpuSet(const void *inSrc, void *inDest, u32 control)
#endif
#if L_CpuFastSet
static uint32_t CPUReadMemory(const void *src)
{
uint32_t val;
memcpy(&val, src, sizeof(val));
return val;
}
static void CPUWriteMemory(void *dest, uint32_t val) { memcpy(dest, &val, sizeof(val)); }
void CpuFastSet(const void *inSrc, void *inDest, u32 control)
{
#if CPU_ARCH_X86
const u32 *src = inSrc;
const u32 *dest = inDest;
assert(((uintptr_t)src & 0x3) == 0); // should be aligned by 4
@@ -63,8 +72,6 @@ void CpuFastSet(const void *inSrc, void *inDest, u32 control)
word_count = ((word_count + 7) & ~0x7);
const u32 *target = &dest[word_count];
#if CPU_ARCH_X86
if (control & CPU_FAST_SET_SRC_FIXED) {
__m128i v = _mm_set_epi32(*src, *src, *src, *src);
@@ -86,7 +93,38 @@ void CpuFastSet(const void *inSrc, void *inDest, u32 control)
src += 4;
}
#else
assert(FALSE); // Arch not implemented
int count = control & 0x1FFFFF;
const u8 *source = inSrc;
u8 *dest = inDest;
// source = (u8 *)((uint32_t )source & ~3);
// dest = (u8 *)((uint32_t )dest & ~3);
// fill?
if ((control >> 24) & 1) {
uint32_t value = CPUReadMemory(source);
while (count > 0) {
// BIOS always transfers 32 bytes at a time
for (int i = 0; i < 8; i++) {
CPUWriteMemory(dest, value);
dest += 4;
}
count -= 8;
}
} else {
// copy
while (count > 0) {
// BIOS always transfers 32 bytes at a time
for (int i = 0; i < 8; i++) {
uint32_t value = CPUReadMemory(source);
CPUWriteMemory(dest, value);
source += 4;
dest += 4;
}
count -= 8;
}
}
#endif
}
#endif
@@ -205,12 +243,55 @@ void SoftResetExram(u32 resetFlags)
u16 Sqrt(u32 num) { return (u16)sqrt((double)num); }
#endif
#if L_ArcTan
u16 ArcTan(s16 x) { return (u16)atanf((float)x); }
#if L_ArcTan || L_ArcTan2
// Source modified from mGBA
// https://github.com/mgba-emu/mgba/blob/93fed7144836d20c9087ae88bc67dfdde834db9d/src/gba/bios.c#L291
u16 ArcTan(s16 i)
{
s32 a = -((i * i) >> 14);
s32 b = ((0xA9 * a) >> 14) + 0x390;
b = ((b * a) >> 14) + 0x91C;
b = ((b * a) >> 14) + 0xFB6;
b = ((b * a) >> 14) + 0x16AA;
b = ((b * a) >> 14) + 0x2081;
b = ((b * a) >> 14) + 0x3651;
b = ((b * a) >> 14) + 0xA2F9;
return (i * b) >> 16;
}
#endif
#if L_ArcTan2
u16 ArcTan2(s16 x, s16 y) { return (u16)atan2f((float)x, (float)y); }
// Source modified from mGBA
// https://github.com/mgba-emu/mgba/blob/93fed7144836d20c9087ae88bc67dfdde834db9d/src/gba/bios.c#L319
u16 ArcTan2(s16 x, s16 y)
{
if (!y) {
if (x >= 0)
return 0;
return 0x8000;
}
if (!x) {
if (y >= 0)
return 0x4000;
return 0xC000;
}
if (y >= 0) {
if (x >= 0) {
if (x >= y)
return ArcTan((y << 14) / x);
} else if (-x >= y)
return ArcTan((y << 14) / x) + 0x8000;
return 0x4000 - ArcTan((x << 14) / y);
} else {
if (x <= 0) {
if (-x > -y)
return ArcTan((y << 14) / x) + 0x8000;
} else if (x >= -y)
return ArcTan((y << 14) / x) + 0x10000;
return 0xC000 - ArcTan((x << 14) / y);
}
}
#endif
#if L_HuffUnComp
@@ -218,35 +299,140 @@ void HuffUnComp(void) { }
#endif
#if L_LZ77UnCompWram
#include "platform/platform.h"
#include "ext/gbagfx/lz.c"
void LZ77UnCompWram(const void *src, void *dest) { Platform_LZDecompressUnsafe(src, dest); }
void LZ77UnCompWram(const void *src, void *dest)
{
int size = 0;
LZDecompressUnsafe(src, dest, &size);
}
#endif
#if L_LZ77UnCompVram
#include "platform/platform.h"
#include "ext/gbagfx/lz.c"
void LZ77UnCompVram(const void *src, void *dest) { Platform_LZDecompressUnsafe(src, dest); }
void LZ77UnCompVram(const void *src, void *dest)
{
int size = 0;
LZDecompressUnsafe(src, dest, &size);
}
#endif
#if L_RLUnCompWram
#include "platform/platform.h"
#include "ext/gbagfx/rl.c"
void RLUnCompWram(const void *src, void *dest) { Platform_RLDecompressUnsafe(src, dest); }
void RLUnCompWram(const void *src, void *dest)
{
int size = 0;
RLDecompressUnsafe(src, dest, &size);
}
#endif
#if L_RLUnCompVram
#include "platform/platform.h"
#include "ext/gbagfx/rl.c"
void RLUnCompVram(const void *src, void *dest) { Platform_RLDecompressUnsafe(src, dest); }
void RLUnCompVram(const void *src, void *dest)
{
int size = 0;
RLDecompressUnsafe(src, dest, &size);
}
#endif
#if L_ObjAffineSet || L_BgAffineSet
const s16 sineTable[256]
= { (s16)0x0000, (s16)0x0192, (s16)0x0323, (s16)0x04B5, (s16)0x0645, (s16)0x07D5, (s16)0x0964, (s16)0x0AF1, (s16)0x0C7C, (s16)0x0E05,
(s16)0x0F8C, (s16)0x1111, (s16)0x1294, (s16)0x1413, (s16)0x158F, (s16)0x1708, (s16)0x187D, (s16)0x19EF, (s16)0x1B5D, (s16)0x1CC6,
(s16)0x1E2B, (s16)0x1F8B, (s16)0x20E7, (s16)0x223D, (s16)0x238E, (s16)0x24DA, (s16)0x261F, (s16)0x275F, (s16)0x2899, (s16)0x29CD,
(s16)0x2AFA, (s16)0x2C21, (s16)0x2D41, (s16)0x2E5A, (s16)0x2F6B, (s16)0x3076, (s16)0x3179, (s16)0x3274, (s16)0x3367, (s16)0x3453,
(s16)0x3536, (s16)0x3612, (s16)0x36E5, (s16)0x37AF, (s16)0x3871, (s16)0x392A, (s16)0x39DA, (s16)0x3A82, (s16)0x3B20, (s16)0x3BB6,
(s16)0x3C42, (s16)0x3CC5, (s16)0x3D3E, (s16)0x3DAE, (s16)0x3E14, (s16)0x3E71, (s16)0x3EC5, (s16)0x3F0E, (s16)0x3F4E, (s16)0x3F84,
(s16)0x3FB1, (s16)0x3FD3, (s16)0x3FEC, (s16)0x3FFB, (s16)0x4000, (s16)0x3FFB, (s16)0x3FEC, (s16)0x3FD3, (s16)0x3FB1, (s16)0x3F84,
(s16)0x3F4E, (s16)0x3F0E, (s16)0x3EC5, (s16)0x3E71, (s16)0x3E14, (s16)0x3DAE, (s16)0x3D3E, (s16)0x3CC5, (s16)0x3C42, (s16)0x3BB6,
(s16)0x3B20, (s16)0x3A82, (s16)0x39DA, (s16)0x392A, (s16)0x3871, (s16)0x37AF, (s16)0x36E5, (s16)0x3612, (s16)0x3536, (s16)0x3453,
(s16)0x3367, (s16)0x3274, (s16)0x3179, (s16)0x3076, (s16)0x2F6B, (s16)0x2E5A, (s16)0x2D41, (s16)0x2C21, (s16)0x2AFA, (s16)0x29CD,
(s16)0x2899, (s16)0x275F, (s16)0x261F, (s16)0x24DA, (s16)0x238E, (s16)0x223D, (s16)0x20E7, (s16)0x1F8B, (s16)0x1E2B, (s16)0x1CC6,
(s16)0x1B5D, (s16)0x19EF, (s16)0x187D, (s16)0x1708, (s16)0x158F, (s16)0x1413, (s16)0x1294, (s16)0x1111, (s16)0x0F8C, (s16)0x0E05,
(s16)0x0C7C, (s16)0x0AF1, (s16)0x0964, (s16)0x07D5, (s16)0x0645, (s16)0x04B5, (s16)0x0323, (s16)0x0192, (s16)0x0000, (s16)0xFE6E,
(s16)0xFCDD, (s16)0xFB4B, (s16)0xF9BB, (s16)0xF82B, (s16)0xF69C, (s16)0xF50F, (s16)0xF384, (s16)0xF1FB, (s16)0xF074, (s16)0xEEEF,
(s16)0xED6C, (s16)0xEBED, (s16)0xEA71, (s16)0xE8F8, (s16)0xE783, (s16)0xE611, (s16)0xE4A3, (s16)0xE33A, (s16)0xE1D5, (s16)0xE075,
(s16)0xDF19, (s16)0xDDC3, (s16)0xDC72, (s16)0xDB26, (s16)0xD9E1, (s16)0xD8A1, (s16)0xD767, (s16)0xD633, (s16)0xD506, (s16)0xD3DF,
(s16)0xD2BF, (s16)0xD1A6, (s16)0xD095, (s16)0xCF8A, (s16)0xCE87, (s16)0xCD8C, (s16)0xCC99, (s16)0xCBAD, (s16)0xCACA, (s16)0xC9EE,
(s16)0xC91B, (s16)0xC851, (s16)0xC78F, (s16)0xC6D6, (s16)0xC626, (s16)0xC57E, (s16)0xC4E0, (s16)0xC44A, (s16)0xC3BE, (s16)0xC33B,
(s16)0xC2C2, (s16)0xC252, (s16)0xC1EC, (s16)0xC18F, (s16)0xC13B, (s16)0xC0F2, (s16)0xC0B2, (s16)0xC07C, (s16)0xC04F, (s16)0xC02D,
(s16)0xC014, (s16)0xC005, (s16)0xC000, (s16)0xC005, (s16)0xC014, (s16)0xC02D, (s16)0xC04F, (s16)0xC07C, (s16)0xC0B2, (s16)0xC0F2,
(s16)0xC13B, (s16)0xC18F, (s16)0xC1EC, (s16)0xC252, (s16)0xC2C2, (s16)0xC33B, (s16)0xC3BE, (s16)0xC44A, (s16)0xC4E0, (s16)0xC57E,
(s16)0xC626, (s16)0xC6D6, (s16)0xC78F, (s16)0xC851, (s16)0xC91B, (s16)0xC9EE, (s16)0xCACA, (s16)0xCBAD, (s16)0xCC99, (s16)0xCD8C,
(s16)0xCE87, (s16)0xCF8A, (s16)0xD095, (s16)0xD1A6, (s16)0xD2BF, (s16)0xD3DF, (s16)0xD506, (s16)0xD633, (s16)0xD767, (s16)0xD8A1,
(s16)0xD9E1, (s16)0xDB26, (s16)0xDC72, (s16)0xDDC3, (s16)0xDF19, (s16)0xE075, (s16)0xE1D5, (s16)0xE33A, (s16)0xE4A3, (s16)0xE611,
(s16)0xE783, (s16)0xE8F8, (s16)0xEA71, (s16)0xEBED, (s16)0xED6C, (s16)0xEEEF, (s16)0xF074, (s16)0xF1FB, (s16)0xF384, (s16)0xF50F,
(s16)0xF69C, (s16)0xF82B, (s16)0xF9BB, (s16)0xFB4B, (s16)0xFCDD, (s16)0xFE6E };
#endif
#if L_BgAffineSet
void BgAffineSet(struct BgAffineSrcData *src, struct BgAffineDstData *dest, s32 count) { }
// Source modified from vba
// https://github.com/visualboyadvance-m/visualboyadvance-m/blob/0ceab88df51ca8b0ceb3bd30d9c296553cfa583e/src/core/gba/internal/gbaBios.cpp#L196
void BgAffineSet(struct BgAffineSrcData *src, struct BgAffineDstData *dest, s32 count)
{
for (s32 i = 0; i < count; i++) {
s32 cx = src[i].texX;
s32 cy = src[i].texY;
s16 dispx = src[i].scrX;
s16 dispy = src[i].scrY;
s16 rx = src[i].sx;
s16 ry = src[i].sy;
u16 theta = src[i].alpha >> 8;
s32 a = sineTable[(theta + 0x40) & 255];
s32 b = sineTable[theta];
s16 dx = (rx * a) >> 14;
s16 dmx = (rx * b) >> 14;
s16 dy = (ry * b) >> 14;
s16 dmy = (ry * a) >> 14;
dest[i].pa = dx;
dest[i].pb = -dmx;
dest[i].pc = dy;
dest[i].pd = dmy;
s32 startx = cx - dx * dispx + dmx * dispy;
s32 starty = cy - dy * dispx - dmy * dispy;
dest[i].dx = startx;
dest[i].dy = starty;
}
}
#endif
#if L_ObjAffineSet
void ObjAffineSet(struct ObjAffineSrcData *src, void *dest, s32 count, s32 offset) { }
// Source modified from vba
// https://github.com/visualboyadvance-m/visualboyadvance-m/blob/0ceab88df51ca8b0ceb3bd30d9c296553cfa583e/src/core/gba/internal/gbaBios.cpp#L796
static void CPUWriteHalfWord(void *dest, uint16_t val) { memcpy(dest, &val, sizeof(val)); }
void ObjAffineSet(struct ObjAffineSrcData *src, void *dest, s32 count, s32 offset)
{
for (s32 i = 0; i < count; i++) {
s16 rx = src[i].xScale;
s16 ry = src[i].yScale;
u16 theta = src[i].rotation >> 8;
s32 a = (s32)sineTable[(theta + 64) & 255];
s32 b = (s32)sineTable[theta];
s16 dx = ((s32)rx * a) >> 14;
s16 dmx = ((s32)rx * b) >> 14;
s16 dy = ((s32)ry * b) >> 14;
s16 dmy = ((s32)ry * a) >> 14;
CPUWriteHalfWord(dest, dx);
dest += offset;
CPUWriteHalfWord(dest, -dmx);
dest += offset;
CPUWriteHalfWord(dest, dy);
dest += offset;
CPUWriteHalfWord(dest, dmy);
dest += offset;
}
}
#endif
/* Stubs */
+1 -1
View File
@@ -280,7 +280,7 @@ include songs.mk
$(ELF): $(OBJS) $(LDSCRIPT) libagbsyscall
@echo "$(LD) -T $(LD_SCRIPT) -Map $(MAP) <objects> <lib>"
@$(LD) -T $(LDSCRIPT) -Map $(MAP) $(OBJS) ../../../tools/agbcc/lib/libgcc.a ../../../tools/agbcc/lib/libc.a -L../../../libagbsyscall -lagbsyscall -o $@
@$(LD) -T $(LDSCRIPT) -Map $(MAP) $(OBJS) ../../../tools/agbcc/lib/libgcc.a ../../../tools/agbcc/lib/libc.a -L../../../libagbsyscall/build/gba -lagbsyscall -o $@
%.gba: %.elf
$(OBJCOPY) -O binary $< $@
-206
View File
@@ -1,206 +0,0 @@
// Copyright (c) 2015 YamaArashi
#include <stdlib.h>
#include <stdbool.h>
#include "platform/ext/gbagfx/global.h"
#include "platform/ext/gbagfx/lz.h"
unsigned char *LZDecompress(unsigned char *src, int srcSize, int *uncompressedSize)
{
if (srcSize < 4)
goto fail;
int destSize = (src[3] << 16) | (src[2] << 8) | src[1];
unsigned char *dest = malloc(destSize);
if (dest == NULL)
goto fail;
int srcPos = 4;
int destPos = 0;
for (;;) {
if (srcPos >= srcSize)
goto fail;
unsigned char flags = src[srcPos++];
for (int i = 0; i < 8; i++) {
if (flags & 0x80) {
if (srcPos + 1 >= srcSize)
goto fail;
int blockSize = (src[srcPos] >> 4) + 3;
int blockDistance = (((src[srcPos] & 0xF) << 8) | src[srcPos + 1]) + 1;
srcPos += 2;
int blockPos = destPos - blockDistance;
// Some Ruby/Sapphire tilesets overflow.
if (destPos + blockSize > destSize) {
blockSize = destSize - destPos;
fprintf(stderr, "Destination buffer overflow.\n");
}
if (blockPos < 0)
goto fail;
for (int j = 0; j < blockSize; j++)
dest[destPos++] = dest[blockPos + j];
} else {
if (srcPos >= srcSize || destPos >= destSize)
goto fail;
dest[destPos++] = src[srcPos++];
}
if (destPos == destSize) {
*uncompressedSize = destSize;
return dest;
}
flags <<= 1;
}
}
fail:
FATAL_ERROR("Fatal error while decompressing LZ file.\n");
}
void LZDecompressUnsafe(unsigned char *src, unsigned char *dest, int *uncompressedSize)
{
int destSize = (src[3] << 16) | (src[2] << 8) | src[1];
if (dest == NULL)
goto fail;
int srcPos = 4;
int destPos = 0;
for (;;) {
unsigned char flags = src[srcPos++];
for (int i = 0; i < 8; i++) {
if (flags & 0x80) {
int blockSize = (src[srcPos] >> 4) + 3;
int blockDistance = (((src[srcPos] & 0xF) << 8) | src[srcPos + 1]) + 1;
srcPos += 2;
int blockPos = destPos - blockDistance;
// Some Ruby/Sapphire tilesets overflow.
if (destPos + blockSize > destSize) {
blockSize = destSize - destPos;
fprintf(stderr, "Destination buffer overflow.\n");
}
if (blockPos < 0)
goto fail;
for (int j = 0; j < blockSize; j++)
dest[destPos++] = dest[blockPos + j];
} else {
if (destPos >= destSize)
goto fail;
dest[destPos++] = src[srcPos++];
}
if (destPos == destSize) {
*uncompressedSize = destSize;
return;
}
flags <<= 1;
}
}
fail:
FATAL_ERROR("Fatal error while decompressing LZ file.\n");
}
unsigned char *LZCompress(unsigned char *src, int srcSize, int *compressedSize, const int minDistance)
{
if (srcSize <= 0)
goto fail;
int worstCaseDestSize = 4 + srcSize + ((srcSize + 7) / 8);
// Round up to the next multiple of four.
worstCaseDestSize = (worstCaseDestSize + 3) & ~3;
unsigned char *dest = malloc(worstCaseDestSize);
if (dest == NULL)
goto fail;
// header
dest[0] = 0x10; // LZ compression type
dest[1] = (unsigned char)srcSize;
dest[2] = (unsigned char)(srcSize >> 8);
dest[3] = (unsigned char)(srcSize >> 16);
int srcPos = 0;
int destPos = 4;
for (;;) {
unsigned char *flags = &dest[destPos++];
*flags = 0;
for (int i = 0; i < 8; i++) {
int bestBlockDistance = 0;
int bestBlockSize = 0;
int blockDistance = minDistance;
while (blockDistance <= srcPos && blockDistance <= 0x1000) {
int blockStart = srcPos - blockDistance;
int blockSize = 0;
while (blockSize < 18
&& srcPos + blockSize < srcSize
&& src[blockStart + blockSize] == src[srcPos + blockSize])
blockSize++;
if (blockSize > bestBlockSize) {
bestBlockDistance = blockDistance;
bestBlockSize = blockSize;
if (blockSize == 18)
break;
}
blockDistance++;
}
if (bestBlockSize >= 3) {
*flags |= (0x80 >> i);
srcPos += bestBlockSize;
bestBlockSize -= 3;
bestBlockDistance--;
dest[destPos++] = (bestBlockSize << 4) | ((unsigned int)bestBlockDistance >> 8);
dest[destPos++] = (unsigned char)bestBlockDistance;
} else {
dest[destPos++] = src[srcPos++];
}
if (srcPos == srcSize) {
// Pad to multiple of 4 bytes.
int remainder = destPos % 4;
if (remainder != 0) {
for (int i = 0; i < 4 - remainder; i++)
dest[destPos++] = 0;
}
*compressedSize = destPos;
return dest;
}
}
}
fail:
FATAL_ERROR("Fatal error while compressing LZ file.\n");
}
-197
View File
@@ -1,197 +0,0 @@
// Copyright (c) 2016 YamaArashi
#include <stdlib.h>
#include <stdbool.h>
#include "platform/ext/gbagfx/global.h"
#include "platform/ext/gbagfx/rl.h"
unsigned char *RLDecompress(unsigned char *src, int srcSize, int *uncompressedSize)
{
if (srcSize < 4)
goto fail;
int destSize = (src[3] << 16) | (src[2] << 8) | src[1];
unsigned char *dest = malloc(destSize);
if (dest == NULL)
goto fail;
int srcPos = 4;
int destPos = 0;
for (;;)
{
if (srcPos >= srcSize)
goto fail;
unsigned char flags = src[srcPos++];
bool compressed = ((flags & 0x80) != 0);
if (compressed)
{
int length = (flags & 0x7F) + 3;
unsigned char data = src[srcPos++];
if (destPos + length > destSize)
goto fail;
for (int i = 0; i < length; i++)
dest[destPos++] = data;
}
else
{
int length = (flags & 0x7F) + 1;
if (destPos + length > destSize)
goto fail;
for (int i = 0; i < length; i++)
dest[destPos++] = src[srcPos++];
}
if (destPos == destSize)
{
*uncompressedSize = destSize;
return dest;
}
}
fail:
FATAL_ERROR("Fatal error while decompressing RL file.\n");
}
void RLDecompressUnsafe(unsigned char *src, unsigned char *dest, int *uncompressedSize)
{
int destSize = (src[3] << 16) | (src[2] << 8) | src[1];
if (dest == NULL)
goto fail;
int srcPos = 4;
int destPos = 0;
for (;;)
{
unsigned char flags = src[srcPos++];
bool compressed = ((flags & 0x80) != 0);
if (compressed)
{
int length = (flags & 0x7F) + 3;
unsigned char data = src[srcPos++];
if (destPos + length > destSize)
goto fail;
for (int i = 0; i < length; i++)
dest[destPos++] = data;
}
else
{
int length = (flags & 0x7F) + 1;
if (destPos + length > destSize)
goto fail;
for (int i = 0; i < length; i++)
dest[destPos++] = src[srcPos++];
}
if (destPos == destSize)
{
*uncompressedSize = destSize;
return;
}
}
fail:
FATAL_ERROR("Fatal error while decompressing RL file.\n");
}
unsigned char *RLCompress(unsigned char *src, int srcSize, int *compressedSize)
{
if (srcSize <= 0)
goto fail;
int worstCaseDestSize = 4 + srcSize * 2;
// Round up to the next multiple of four.
worstCaseDestSize = (worstCaseDestSize + 3) & ~3;
unsigned char *dest = malloc(worstCaseDestSize);
if (dest == NULL)
goto fail;
// header
dest[0] = 0x30; // RL compression type
dest[1] = (unsigned char)srcSize;
dest[2] = (unsigned char)(srcSize >> 8);
dest[3] = (unsigned char)(srcSize >> 16);
int srcPos = 0;
int destPos = 4;
for (;;)
{
bool compress = false;
int uncompressedStart = srcPos;
int uncompressedLength = 0;
while (srcPos < srcSize && uncompressedLength < (0x7F + 1))
{
compress = (srcPos + 2 < srcSize && src[srcPos] == src[srcPos + 1] && src[srcPos] == src[srcPos + 2]);
if (compress)
break;
srcPos++;
uncompressedLength++;
}
if (uncompressedLength > 0)
{
dest[destPos++] = uncompressedLength - 1;
for (int i = 0; i < uncompressedLength; i++)
dest[destPos++] = src[uncompressedStart + i];
}
if (compress)
{
unsigned char data = src[srcPos];
int compressedLength = 0;
while (compressedLength < (0x7F + 3)
&& srcPos + compressedLength < srcSize
&& src[srcPos + compressedLength] == data)
{
compressedLength++;
}
dest[destPos++] = 0x80 | (compressedLength - 3);
dest[destPos++] = data;
srcPos += compressedLength;
}
if (srcPos == srcSize)
{
// Pad to multiple of 4 bytes.
int remainder = destPos % 4;
if (remainder != 0)
{
for (int i = 0; i < 4 - remainder; i++)
dest[destPos++] = 0;
}
*compressedSize = destPos;
return dest;
}
}
fail:
FATAL_ERROR("Fatal error while compressing RL file.\n");
}
-504
View File
@@ -20,10 +20,6 @@
#include "global.h"
#include "core.h"
#include "multi_sio.h"
#include "gba/defines.h"
#include "gba/io_reg.h"
#include "gba/types.h"
#include "lib/agb_flash/flash_internal.h"
#include "platform/shared/dma.h"
#include "platform/shared/input.h"
@@ -665,405 +661,6 @@ u16 Platform_GetKeyInput(void)
return keys;
}
// BIOS function implementations are based on the VBA-M source code.
// safe unaligned access for MIPS
static uint32_t CPUReadMemory(const void *src)
{
uint32_t val;
memcpy(&val, src, sizeof(val));
return val;
}
static void CPUWriteMemory(void *dest, uint32_t val) { memcpy(dest, &val, sizeof(val)); }
static uint16_t CPUReadHalfWord(const void *src)
{
uint16_t val;
memcpy(&val, src, sizeof(val));
return val;
}
static void CPUWriteHalfWord(void *dest, uint16_t val) { memcpy(dest, &val, sizeof(val)); }
static uint8_t CPUReadByte(const void *src) { return *(uint8_t *)src; }
static void CPUWriteByte(void *dest, uint8_t val) { *(uint8_t *)dest = val; }
void CpuSet(const void *src, void *dst, u32 cnt)
{
if (dst == NULL) {
puts("Attempted to CpuSet to NULL\n");
return;
}
int count = cnt & 0x1FFFFF;
const u8 *source = src;
u8 *dest = dst;
// 32-bit ?
if ((cnt >> 26) & 1) {
// assert(((uintptr_t)src & ~3) == (uintptr_t)src);
// assert(((uintptr_t)dst & ~3) == (uintptr_t)dst);
// needed for 32-bit mode!
// source = (u8 *)((uint32_t )source & ~3);
// dest = (u8 *)((uint32_t )dest & ~3);
// fill ?
if ((cnt >> 24) & 1) {
uint32_t value = CPUReadMemory(source);
while (count) {
CPUWriteMemory(dest, value);
dest += 4;
count--;
}
} else {
// copy
while (count) {
CPUWriteMemory(dest, CPUReadMemory(source));
source += 4;
dest += 4;
count--;
}
}
} else {
// No align on 16-bit fill?
// assert(((uintptr_t)src & ~1) == (uintptr_t)src);
// assert(((uintptr_t)dst & ~1) == (uintptr_t)dst);
// 16-bit fill?
if ((cnt >> 24) & 1) {
uint16_t value = CPUReadHalfWord(source);
while (count) {
CPUWriteHalfWord(dest, value);
dest += 2;
count--;
}
} else {
// copy
while (count) {
CPUWriteHalfWord(dest, CPUReadHalfWord(source));
source += 2;
dest += 2;
count--;
}
}
}
}
void CpuFastSet(const void *src, void *dst, u32 cnt)
{
if (dst == NULL) {
puts("Attempted to CpuFastSet to NULL\n");
return;
}
int count = cnt & 0x1FFFFF;
const u8 *source = src;
u8 *dest = dst;
// source = (u8 *)((uint32_t )source & ~3);
// dest = (u8 *)((uint32_t )dest & ~3);
// fill?
if ((cnt >> 24) & 1) {
uint32_t value = CPUReadMemory(source);
while (count > 0) {
// BIOS always transfers 32 bytes at a time
for (int i = 0; i < 8; i++) {
CPUWriteMemory(dest, value);
dest += 4;
}
count -= 8;
}
} else {
// copy
while (count > 0) {
// BIOS always transfers 32 bytes at a time
for (int i = 0; i < 8; i++) {
uint32_t value = CPUReadMemory(source);
CPUWriteMemory(dest, value);
source += 4;
dest += 4;
}
count -= 8;
}
}
}
void LZ77UnCompVram(const void *src_, void *dest_)
{
const u8 *src = (const u8 *)src_;
u8 *dest = dest_;
int destSize = (src[3] << 16) | (src[2] << 8) | src[1];
int srcPos = 4;
int destPos = 0;
for (;;) {
unsigned char flags = src[srcPos++];
for (int i = 0; i < 8; i++) {
if (flags & 0x80) {
int blockSize = (src[srcPos] >> 4) + 3;
int blockDistance = (((src[srcPos] & 0xF) << 8) | src[srcPos + 1]) + 1;
srcPos += 2;
int blockPos = destPos - blockDistance;
// Some Ruby/Sapphire tilesets overflow.
if (destPos + blockSize > destSize) {
blockSize = destSize - destPos;
// fprintf(stderr, "Destination buffer overflow.\n");
puts("Destination buffer overflow.\n");
}
if (blockPos < 0)
goto fail;
for (int j = 0; j < blockSize; j++)
dest[destPos++] = dest[blockPos + j];
} else {
if (destPos >= destSize)
goto fail;
dest[destPos++] = src[srcPos++];
}
if (destPos == destSize) {
return;
}
flags <<= 1;
}
}
fail:
puts("Fatal error while decompressing LZ file.\n");
}
void LZ77UnCompWram(const void *src, void *dst)
{
const uint8_t *source = src;
uint8_t *dest = dst;
uint32_t header = CPUReadMemory(source);
source += 4;
int len = header >> 8;
while (len > 0) {
uint8_t d = CPUReadByte(source++);
if (d) {
for (int i = 0; i < 8; i++) {
if (d & 0x80) {
uint16_t data = CPUReadByte(source++) << 8;
data |= CPUReadByte(source++);
int length = (data >> 12) + 3;
int offset = (data & 0x0FFF);
uint8_t *windowOffset = dest - offset - 1;
for (int i2 = 0; i2 < length; i2++) {
CPUWriteByte(dest++, CPUReadByte(windowOffset++));
len--;
if (len == 0)
return;
}
} else {
CPUWriteByte(dest++, CPUReadByte(source++));
len--;
if (len == 0)
return;
}
d <<= 1;
}
} else {
for (int i = 0; i < 8; i++) {
CPUWriteByte(dest++, CPUReadByte(source++));
len--;
if (len == 0)
return;
}
}
}
}
void RLUnCompWram(const void *src, void *dest)
{
int remaining = CPUReadMemory(src) >> 8;
int blockHeader;
int block;
src += 4;
while (remaining > 0) {
blockHeader = CPUReadByte(src);
src++;
if (blockHeader & 0x80) // Compressed?
{
blockHeader &= 0x7F;
blockHeader += 3;
block = CPUReadByte(src);
src++;
while (blockHeader-- && remaining) {
remaining--;
CPUWriteByte(dest, block);
dest++;
}
} else // Uncompressed
{
blockHeader++;
while (blockHeader-- && remaining) {
remaining--;
u8 byte = CPUReadByte(src);
src++;
CPUWriteByte(dest, byte);
dest++;
}
}
}
}
void RLUnCompVram(const void *src, void *dest)
{
int remaining = CPUReadMemory(src) >> 8;
int padding = (4 - remaining) & 0x3;
int blockHeader;
int block;
int halfWord = 0;
src += 4;
while (remaining > 0) {
blockHeader = CPUReadByte(src);
src++;
if (blockHeader & 0x80) // Compressed?
{
blockHeader &= 0x7F;
blockHeader += 3;
block = CPUReadByte(src);
src++;
while (blockHeader-- && remaining) {
remaining--;
if ((uintptr_t)dest & 1) {
halfWord |= block << 8;
CPUWriteHalfWord((void *)((uintptr_t)dest ^ 1), halfWord);
} else
halfWord = block;
dest++;
}
} else // Uncompressed
{
blockHeader++;
while (blockHeader-- && remaining) {
remaining--;
u8 byte = CPUReadByte(src);
src++;
if ((uintptr_t)dest & 1) {
halfWord |= byte << 8;
CPUWriteHalfWord((void *)((uintptr_t)dest ^ 1), halfWord);
} else
halfWord = byte;
dest++;
}
}
}
if ((uintptr_t)dest & 1) {
padding--;
dest++;
}
for (; padding > 0; padding -= 2, dest += 2)
CPUWriteHalfWord(dest, 0);
}
const s16 sineTable[256]
= { (s16)0x0000, (s16)0x0192, (s16)0x0323, (s16)0x04B5, (s16)0x0645, (s16)0x07D5, (s16)0x0964, (s16)0x0AF1, (s16)0x0C7C, (s16)0x0E05,
(s16)0x0F8C, (s16)0x1111, (s16)0x1294, (s16)0x1413, (s16)0x158F, (s16)0x1708, (s16)0x187D, (s16)0x19EF, (s16)0x1B5D, (s16)0x1CC6,
(s16)0x1E2B, (s16)0x1F8B, (s16)0x20E7, (s16)0x223D, (s16)0x238E, (s16)0x24DA, (s16)0x261F, (s16)0x275F, (s16)0x2899, (s16)0x29CD,
(s16)0x2AFA, (s16)0x2C21, (s16)0x2D41, (s16)0x2E5A, (s16)0x2F6B, (s16)0x3076, (s16)0x3179, (s16)0x3274, (s16)0x3367, (s16)0x3453,
(s16)0x3536, (s16)0x3612, (s16)0x36E5, (s16)0x37AF, (s16)0x3871, (s16)0x392A, (s16)0x39DA, (s16)0x3A82, (s16)0x3B20, (s16)0x3BB6,
(s16)0x3C42, (s16)0x3CC5, (s16)0x3D3E, (s16)0x3DAE, (s16)0x3E14, (s16)0x3E71, (s16)0x3EC5, (s16)0x3F0E, (s16)0x3F4E, (s16)0x3F84,
(s16)0x3FB1, (s16)0x3FD3, (s16)0x3FEC, (s16)0x3FFB, (s16)0x4000, (s16)0x3FFB, (s16)0x3FEC, (s16)0x3FD3, (s16)0x3FB1, (s16)0x3F84,
(s16)0x3F4E, (s16)0x3F0E, (s16)0x3EC5, (s16)0x3E71, (s16)0x3E14, (s16)0x3DAE, (s16)0x3D3E, (s16)0x3CC5, (s16)0x3C42, (s16)0x3BB6,
(s16)0x3B20, (s16)0x3A82, (s16)0x39DA, (s16)0x392A, (s16)0x3871, (s16)0x37AF, (s16)0x36E5, (s16)0x3612, (s16)0x3536, (s16)0x3453,
(s16)0x3367, (s16)0x3274, (s16)0x3179, (s16)0x3076, (s16)0x2F6B, (s16)0x2E5A, (s16)0x2D41, (s16)0x2C21, (s16)0x2AFA, (s16)0x29CD,
(s16)0x2899, (s16)0x275F, (s16)0x261F, (s16)0x24DA, (s16)0x238E, (s16)0x223D, (s16)0x20E7, (s16)0x1F8B, (s16)0x1E2B, (s16)0x1CC6,
(s16)0x1B5D, (s16)0x19EF, (s16)0x187D, (s16)0x1708, (s16)0x158F, (s16)0x1413, (s16)0x1294, (s16)0x1111, (s16)0x0F8C, (s16)0x0E05,
(s16)0x0C7C, (s16)0x0AF1, (s16)0x0964, (s16)0x07D5, (s16)0x0645, (s16)0x04B5, (s16)0x0323, (s16)0x0192, (s16)0x0000, (s16)0xFE6E,
(s16)0xFCDD, (s16)0xFB4B, (s16)0xF9BB, (s16)0xF82B, (s16)0xF69C, (s16)0xF50F, (s16)0xF384, (s16)0xF1FB, (s16)0xF074, (s16)0xEEEF,
(s16)0xED6C, (s16)0xEBED, (s16)0xEA71, (s16)0xE8F8, (s16)0xE783, (s16)0xE611, (s16)0xE4A3, (s16)0xE33A, (s16)0xE1D5, (s16)0xE075,
(s16)0xDF19, (s16)0xDDC3, (s16)0xDC72, (s16)0xDB26, (s16)0xD9E1, (s16)0xD8A1, (s16)0xD767, (s16)0xD633, (s16)0xD506, (s16)0xD3DF,
(s16)0xD2BF, (s16)0xD1A6, (s16)0xD095, (s16)0xCF8A, (s16)0xCE87, (s16)0xCD8C, (s16)0xCC99, (s16)0xCBAD, (s16)0xCACA, (s16)0xC9EE,
(s16)0xC91B, (s16)0xC851, (s16)0xC78F, (s16)0xC6D6, (s16)0xC626, (s16)0xC57E, (s16)0xC4E0, (s16)0xC44A, (s16)0xC3BE, (s16)0xC33B,
(s16)0xC2C2, (s16)0xC252, (s16)0xC1EC, (s16)0xC18F, (s16)0xC13B, (s16)0xC0F2, (s16)0xC0B2, (s16)0xC07C, (s16)0xC04F, (s16)0xC02D,
(s16)0xC014, (s16)0xC005, (s16)0xC000, (s16)0xC005, (s16)0xC014, (s16)0xC02D, (s16)0xC04F, (s16)0xC07C, (s16)0xC0B2, (s16)0xC0F2,
(s16)0xC13B, (s16)0xC18F, (s16)0xC1EC, (s16)0xC252, (s16)0xC2C2, (s16)0xC33B, (s16)0xC3BE, (s16)0xC44A, (s16)0xC4E0, (s16)0xC57E,
(s16)0xC626, (s16)0xC6D6, (s16)0xC78F, (s16)0xC851, (s16)0xC91B, (s16)0xC9EE, (s16)0xCACA, (s16)0xCBAD, (s16)0xCC99, (s16)0xCD8C,
(s16)0xCE87, (s16)0xCF8A, (s16)0xD095, (s16)0xD1A6, (s16)0xD2BF, (s16)0xD3DF, (s16)0xD506, (s16)0xD633, (s16)0xD767, (s16)0xD8A1,
(s16)0xD9E1, (s16)0xDB26, (s16)0xDC72, (s16)0xDDC3, (s16)0xDF19, (s16)0xE075, (s16)0xE1D5, (s16)0xE33A, (s16)0xE4A3, (s16)0xE611,
(s16)0xE783, (s16)0xE8F8, (s16)0xEA71, (s16)0xEBED, (s16)0xED6C, (s16)0xEEEF, (s16)0xF074, (s16)0xF1FB, (s16)0xF384, (s16)0xF50F,
(s16)0xF69C, (s16)0xF82B, (s16)0xF9BB, (s16)0xFB4B, (s16)0xFCDD, (s16)0xFE6E };
void BgAffineSet(struct BgAffineSrcData *src, struct BgAffineDstData *dest, s32 count)
{
for (s32 i = 0; i < count; i++) {
s32 cx = src[i].texX;
s32 cy = src[i].texY;
s16 dispx = src[i].scrX;
s16 dispy = src[i].scrY;
s16 rx = src[i].sx;
s16 ry = src[i].sy;
u16 theta = src[i].alpha >> 8;
s32 a = sineTable[(theta + 0x40) & 255];
s32 b = sineTable[theta];
s16 dx = (rx * a) >> 14;
s16 dmx = (rx * b) >> 14;
s16 dy = (ry * b) >> 14;
s16 dmy = (ry * a) >> 14;
dest[i].pa = dx;
dest[i].pb = -dmx;
dest[i].pc = dy;
dest[i].pd = dmy;
s32 startx = cx - dx * dispx + dmx * dispy;
s32 starty = cy - dy * dispx - dmy * dispy;
dest[i].dx = startx;
dest[i].dy = starty;
}
}
void ObjAffineSet(struct ObjAffineSrcData *src, void *dest, s32 count, s32 offset)
{
for (s32 i = 0; i < count; i++) {
s16 rx = src[i].xScale;
s16 ry = src[i].yScale;
u16 theta = src[i].rotation >> 8;
s32 a = (s32)sineTable[(theta + 64) & 255];
s32 b = (s32)sineTable[theta];
s16 dx = ((s32)rx * a) >> 14;
s16 dmx = ((s32)rx * b) >> 14;
s16 dy = ((s32)ry * b) >> 14;
s16 dmy = ((s32)ry * a) >> 14;
CPUWriteHalfWord(dest, dx);
dest += offset;
CPUWriteHalfWord(dest, -dmx);
dest += offset;
CPUWriteHalfWord(dest, dy);
dest += offset;
CPUWriteHalfWord(dest, dmy);
dest += offset;
}
}
void SoftReset(u32 resetFlags) { }
void SoftResetExram(u32 resetFlags) { }
#if ENABLE_VRAM_VIEW
void VramDraw(SDL_Texture *texture)
{
@@ -1079,104 +676,3 @@ void VDraw(SDL_Texture *texture)
SDL_UpdateTexture(texture, NULL, gameImage, DISPLAY_WIDTH * sizeof(Uint16));
REG_VCOUNT = DISPLAY_HEIGHT + 1; // prep for being in VBlank period
}
u8 BinToBcd(u8 bin)
{
int placeCounter = 1;
u8 out = 0;
do {
out |= (bin % 10) * placeCounter;
placeCounter *= 16;
} while ((bin /= 10) > 0);
return out;
}
// Following functions taken from mGBA's source
u16 ArcTan(s16 i)
{
s32 a = -((i * i) >> 14);
s32 b = ((0xA9 * a) >> 14) + 0x390;
b = ((b * a) >> 14) + 0x91C;
b = ((b * a) >> 14) + 0xFB6;
b = ((b * a) >> 14) + 0x16AA;
b = ((b * a) >> 14) + 0x2081;
b = ((b * a) >> 14) + 0x3651;
b = ((b * a) >> 14) + 0xA2F9;
return (i * b) >> 16;
}
u16 ArcTan2(s16 x, s16 y)
{
if (!y) {
if (x >= 0)
return 0;
return 0x8000;
}
if (!x) {
if (y >= 0)
return 0x4000;
return 0xC000;
}
if (y >= 0) {
if (x >= 0) {
if (x >= y)
return ArcTan((y << 14) / x);
} else if (-x >= y)
return ArcTan((y << 14) / x) + 0x8000;
return 0x4000 - ArcTan((x << 14) / y);
} else {
if (x <= 0) {
if (-x > -y)
return ArcTan((y << 14) / x) + 0x8000;
} else if (x >= -y)
return ArcTan((y << 14) / x) + 0x10000;
return 0xC000 - ArcTan((x << 14) / y);
}
}
u16 Sqrt(u32 num)
{
if (!num)
return 0;
u32 lower;
u32 upper = num;
u32 bound = 1;
while (bound < upper) {
upper >>= 1;
bound <<= 1;
}
while (1) {
upper = num;
u32 accum = 0;
lower = bound;
while (1) {
u32 oldLower = lower;
if (lower <= upper >> 1)
lower <<= 1;
if (oldLower >= upper >> 1)
break;
}
while (1) {
accum <<= 1;
if (upper >= lower) {
++accum;
upper -= lower;
}
if (lower == bound)
break;
lower >>= 1;
}
u32 oldBound = bound;
bound += accum;
bound >>= 1;
if (bound >= oldBound) {
bound = oldBound;
break;
}
}
return bound;
}
int MultiBoot(struct MultiBootParam *mp) { return 0; }
-436
View File
@@ -18,10 +18,6 @@
// Game
#include "global.h"
#include "core.h"
#include "multi_sio.h"
#include "gba/defines.h"
#include "gba/io_reg.h"
#include "gba/types.h"
#include "lib/agb_flash/flash_internal.h"
// Emulation
@@ -476,435 +472,3 @@ static void CloseSaveFile()
fclose(sSaveFile);
}
}
// BIOS function implementations are based on the VBA-M source code.
// TODO: Link these functions from Libagbsyscall
// safe unaligned access for MIPS
static uint32_t CPUReadMemory(const void *src)
{
uint32_t val;
memcpy(&val, src, sizeof(val));
return val;
}
static void CPUWriteMemory(void *dest, uint32_t val) { memcpy(dest, &val, sizeof(val)); }
static uint16_t CPUReadHalfWord(const void *src)
{
uint16_t val;
memcpy(&val, src, sizeof(val));
return val;
}
static void CPUWriteHalfWord(void *dest, uint16_t val) { memcpy(dest, &val, sizeof(val)); }
static uint8_t CPUReadByte(const void *src) { return *(uint8_t *)src; }
static void CPUWriteByte(void *dest, uint8_t val) { *(uint8_t *)dest = val; }
void CpuSet(const void *src, void *dst, u32 cnt)
{
if (dst == NULL) {
puts("Attempted to CpuSet to NULL\n");
return;
}
int count = cnt & 0x1FFFFF;
const u8 *source = src;
u8 *dest = dst;
// 32-bit ?
if ((cnt >> 26) & 1) {
// assert(((uintptr_t)src & ~3) == (uintptr_t)src);
// assert(((uintptr_t)dst & ~3) == (uintptr_t)dst);
// needed for 32-bit mode!
// source = (u8 *)((uint32_t )source & ~3);
// dest = (u8 *)((uint32_t )dest & ~3);
// fill ?
if ((cnt >> 24) & 1) {
uint32_t value = CPUReadMemory(source);
while (count) {
CPUWriteMemory(dest, value);
dest += 4;
count--;
}
} else {
// copy
while (count) {
CPUWriteMemory(dest, CPUReadMemory(source));
source += 4;
dest += 4;
count--;
}
}
} else {
// No align on 16-bit fill?
// assert(((uintptr_t)src & ~1) == (uintptr_t)src);
// assert(((uintptr_t)dst & ~1) == (uintptr_t)dst);
// 16-bit fill?
if ((cnt >> 24) & 1) {
uint16_t value = CPUReadHalfWord(source);
while (count) {
CPUWriteHalfWord(dest, value);
dest += 2;
count--;
}
} else {
// copy
while (count) {
CPUWriteHalfWord(dest, CPUReadHalfWord(source));
source += 2;
dest += 2;
count--;
}
}
}
}
void CpuFastSet(const void *src, void *dst, u32 cnt)
{
if (dst == NULL) {
puts("Attempted to CpuFastSet to NULL\n");
return;
}
int count = cnt & 0x1FFFFF;
const u8 *source = src;
u8 *dest = dst;
// source = (u8 *)((uint32_t )source & ~3);
// dest = (u8 *)((uint32_t )dest & ~3);
// fill?
if ((cnt >> 24) & 1) {
uint32_t value = CPUReadMemory(source);
while (count > 0) {
// BIOS always transfers 32 bytes at a time
for (int i = 0; i < 8; i++) {
CPUWriteMemory(dest, value);
dest += 4;
}
count -= 8;
}
} else {
// copy
while (count > 0) {
// BIOS always transfers 32 bytes at a time
for (int i = 0; i < 8; i++) {
uint32_t value = CPUReadMemory(source);
CPUWriteMemory(dest, value);
source += 4;
dest += 4;
}
count -= 8;
}
}
}
void LZ77UnCompVram(const void *src_, void *dest_)
{
const u8 *src = (const u8 *)src_;
u8 *dest = dest_;
int destSize = (src[3] << 16) | (src[2] << 8) | src[1];
int srcPos = 4;
int destPos = 0;
for (;;) {
unsigned char flags = src[srcPos++];
for (int i = 0; i < 8; i++) {
if (flags & 0x80) {
int blockSize = (src[srcPos] >> 4) + 3;
int blockDistance = (((src[srcPos] & 0xF) << 8) | src[srcPos + 1]) + 1;
srcPos += 2;
int blockPos = destPos - blockDistance;
// Some Ruby/Sapphire tilesets overflow.
if (destPos + blockSize > destSize) {
blockSize = destSize - destPos;
// fprintf(stderr, "Destination buffer overflow.\n");
puts("Destination buffer overflow.\n");
}
if (blockPos < 0)
goto fail;
for (int j = 0; j < blockSize; j++)
dest[destPos++] = dest[blockPos + j];
} else {
if (destPos >= destSize)
goto fail;
dest[destPos++] = src[srcPos++];
}
if (destPos == destSize) {
return;
}
flags <<= 1;
}
}
fail:
puts("Fatal error while decompressing LZ file.\n");
}
void LZ77UnCompWram(const void *src, void *dst)
{
const uint8_t *source = src;
uint8_t *dest = dst;
uint32_t header = CPUReadMemory(source);
source += 4;
int len = header >> 8;
while (len > 0) {
uint8_t d = CPUReadByte(source++);
if (d) {
for (int i = 0; i < 8; i++) {
if (d & 0x80) {
uint16_t data = CPUReadByte(source++) << 8;
data |= CPUReadByte(source++);
int length = (data >> 12) + 3;
int offset = (data & 0x0FFF);
uint8_t *windowOffset = dest - offset - 1;
for (int i2 = 0; i2 < length; i2++) {
CPUWriteByte(dest++, CPUReadByte(windowOffset++));
len--;
if (len == 0)
return;
}
} else {
CPUWriteByte(dest++, CPUReadByte(source++));
len--;
if (len == 0)
return;
}
d <<= 1;
}
} else {
for (int i = 0; i < 8; i++) {
CPUWriteByte(dest++, CPUReadByte(source++));
len--;
if (len == 0)
return;
}
}
}
}
void RLUnCompWram(const void *src, void *dest)
{
int remaining = CPUReadMemory(src) >> 8;
int blockHeader;
int block;
src += 4;
while (remaining > 0) {
blockHeader = CPUReadByte(src);
src++;
if (blockHeader & 0x80) // Compressed?
{
blockHeader &= 0x7F;
blockHeader += 3;
block = CPUReadByte(src);
src++;
while (blockHeader-- && remaining) {
remaining--;
CPUWriteByte(dest, block);
dest++;
}
} else // Uncompressed
{
blockHeader++;
while (blockHeader-- && remaining) {
remaining--;
u8 byte = CPUReadByte(src);
src++;
CPUWriteByte(dest, byte);
dest++;
}
}
}
}
void RLUnCompVram(const void *src, void *dest)
{
int remaining = CPUReadMemory(src) >> 8;
int padding = (4 - remaining) & 0x3;
int blockHeader;
int block;
int halfWord = 0;
src += 4;
while (remaining > 0) {
blockHeader = CPUReadByte(src);
src++;
if (blockHeader & 0x80) // Compressed?
{
blockHeader &= 0x7F;
blockHeader += 3;
block = CPUReadByte(src);
src++;
while (blockHeader-- && remaining) {
remaining--;
if ((uintptr_t)dest & 1) {
halfWord |= block << 8;
CPUWriteHalfWord((void *)((uintptr_t)dest ^ 1), halfWord);
} else
halfWord = block;
dest++;
}
} else // Uncompressed
{
blockHeader++;
while (blockHeader-- && remaining) {
remaining--;
u8 byte = CPUReadByte(src);
src++;
if ((uintptr_t)dest & 1) {
halfWord |= byte << 8;
CPUWriteHalfWord((void *)((uintptr_t)dest ^ 1), halfWord);
} else
halfWord = byte;
dest++;
}
}
}
if ((uintptr_t)dest & 1) {
padding--;
dest++;
}
for (; padding > 0; padding -= 2, dest += 2)
CPUWriteHalfWord(dest, 0);
}
const s16 sineTable[256]
= { (s16)0x0000, (s16)0x0192, (s16)0x0323, (s16)0x04B5, (s16)0x0645, (s16)0x07D5, (s16)0x0964, (s16)0x0AF1, (s16)0x0C7C, (s16)0x0E05,
(s16)0x0F8C, (s16)0x1111, (s16)0x1294, (s16)0x1413, (s16)0x158F, (s16)0x1708, (s16)0x187D, (s16)0x19EF, (s16)0x1B5D, (s16)0x1CC6,
(s16)0x1E2B, (s16)0x1F8B, (s16)0x20E7, (s16)0x223D, (s16)0x238E, (s16)0x24DA, (s16)0x261F, (s16)0x275F, (s16)0x2899, (s16)0x29CD,
(s16)0x2AFA, (s16)0x2C21, (s16)0x2D41, (s16)0x2E5A, (s16)0x2F6B, (s16)0x3076, (s16)0x3179, (s16)0x3274, (s16)0x3367, (s16)0x3453,
(s16)0x3536, (s16)0x3612, (s16)0x36E5, (s16)0x37AF, (s16)0x3871, (s16)0x392A, (s16)0x39DA, (s16)0x3A82, (s16)0x3B20, (s16)0x3BB6,
(s16)0x3C42, (s16)0x3CC5, (s16)0x3D3E, (s16)0x3DAE, (s16)0x3E14, (s16)0x3E71, (s16)0x3EC5, (s16)0x3F0E, (s16)0x3F4E, (s16)0x3F84,
(s16)0x3FB1, (s16)0x3FD3, (s16)0x3FEC, (s16)0x3FFB, (s16)0x4000, (s16)0x3FFB, (s16)0x3FEC, (s16)0x3FD3, (s16)0x3FB1, (s16)0x3F84,
(s16)0x3F4E, (s16)0x3F0E, (s16)0x3EC5, (s16)0x3E71, (s16)0x3E14, (s16)0x3DAE, (s16)0x3D3E, (s16)0x3CC5, (s16)0x3C42, (s16)0x3BB6,
(s16)0x3B20, (s16)0x3A82, (s16)0x39DA, (s16)0x392A, (s16)0x3871, (s16)0x37AF, (s16)0x36E5, (s16)0x3612, (s16)0x3536, (s16)0x3453,
(s16)0x3367, (s16)0x3274, (s16)0x3179, (s16)0x3076, (s16)0x2F6B, (s16)0x2E5A, (s16)0x2D41, (s16)0x2C21, (s16)0x2AFA, (s16)0x29CD,
(s16)0x2899, (s16)0x275F, (s16)0x261F, (s16)0x24DA, (s16)0x238E, (s16)0x223D, (s16)0x20E7, (s16)0x1F8B, (s16)0x1E2B, (s16)0x1CC6,
(s16)0x1B5D, (s16)0x19EF, (s16)0x187D, (s16)0x1708, (s16)0x158F, (s16)0x1413, (s16)0x1294, (s16)0x1111, (s16)0x0F8C, (s16)0x0E05,
(s16)0x0C7C, (s16)0x0AF1, (s16)0x0964, (s16)0x07D5, (s16)0x0645, (s16)0x04B5, (s16)0x0323, (s16)0x0192, (s16)0x0000, (s16)0xFE6E,
(s16)0xFCDD, (s16)0xFB4B, (s16)0xF9BB, (s16)0xF82B, (s16)0xF69C, (s16)0xF50F, (s16)0xF384, (s16)0xF1FB, (s16)0xF074, (s16)0xEEEF,
(s16)0xED6C, (s16)0xEBED, (s16)0xEA71, (s16)0xE8F8, (s16)0xE783, (s16)0xE611, (s16)0xE4A3, (s16)0xE33A, (s16)0xE1D5, (s16)0xE075,
(s16)0xDF19, (s16)0xDDC3, (s16)0xDC72, (s16)0xDB26, (s16)0xD9E1, (s16)0xD8A1, (s16)0xD767, (s16)0xD633, (s16)0xD506, (s16)0xD3DF,
(s16)0xD2BF, (s16)0xD1A6, (s16)0xD095, (s16)0xCF8A, (s16)0xCE87, (s16)0xCD8C, (s16)0xCC99, (s16)0xCBAD, (s16)0xCACA, (s16)0xC9EE,
(s16)0xC91B, (s16)0xC851, (s16)0xC78F, (s16)0xC6D6, (s16)0xC626, (s16)0xC57E, (s16)0xC4E0, (s16)0xC44A, (s16)0xC3BE, (s16)0xC33B,
(s16)0xC2C2, (s16)0xC252, (s16)0xC1EC, (s16)0xC18F, (s16)0xC13B, (s16)0xC0F2, (s16)0xC0B2, (s16)0xC07C, (s16)0xC04F, (s16)0xC02D,
(s16)0xC014, (s16)0xC005, (s16)0xC000, (s16)0xC005, (s16)0xC014, (s16)0xC02D, (s16)0xC04F, (s16)0xC07C, (s16)0xC0B2, (s16)0xC0F2,
(s16)0xC13B, (s16)0xC18F, (s16)0xC1EC, (s16)0xC252, (s16)0xC2C2, (s16)0xC33B, (s16)0xC3BE, (s16)0xC44A, (s16)0xC4E0, (s16)0xC57E,
(s16)0xC626, (s16)0xC6D6, (s16)0xC78F, (s16)0xC851, (s16)0xC91B, (s16)0xC9EE, (s16)0xCACA, (s16)0xCBAD, (s16)0xCC99, (s16)0xCD8C,
(s16)0xCE87, (s16)0xCF8A, (s16)0xD095, (s16)0xD1A6, (s16)0xD2BF, (s16)0xD3DF, (s16)0xD506, (s16)0xD633, (s16)0xD767, (s16)0xD8A1,
(s16)0xD9E1, (s16)0xDB26, (s16)0xDC72, (s16)0xDDC3, (s16)0xDF19, (s16)0xE075, (s16)0xE1D5, (s16)0xE33A, (s16)0xE4A3, (s16)0xE611,
(s16)0xE783, (s16)0xE8F8, (s16)0xEA71, (s16)0xEBED, (s16)0xED6C, (s16)0xEEEF, (s16)0xF074, (s16)0xF1FB, (s16)0xF384, (s16)0xF50F,
(s16)0xF69C, (s16)0xF82B, (s16)0xF9BB, (s16)0xFB4B, (s16)0xFCDD, (s16)0xFE6E };
void SoftReset(u32 resetFlags) { }
void SoftResetExram(u32 resetFlags) { }
// Following functions taken from mGBA's source
u16 ArcTan(s16 i)
{
s32 a = -((i * i) >> 14);
s32 b = ((0xA9 * a) >> 14) + 0x390;
b = ((b * a) >> 14) + 0x91C;
b = ((b * a) >> 14) + 0xFB6;
b = ((b * a) >> 14) + 0x16AA;
b = ((b * a) >> 14) + 0x2081;
b = ((b * a) >> 14) + 0x3651;
b = ((b * a) >> 14) + 0xA2F9;
return (i * b) >> 16;
}
u16 ArcTan2(s16 x, s16 y)
{
if (!y) {
if (x >= 0)
return 0;
return 0x8000;
}
if (!x) {
if (y >= 0)
return 0x4000;
return 0xC000;
}
if (y >= 0) {
if (x >= 0) {
if (x >= y)
return ArcTan((y << 14) / x);
} else if (-x >= y)
return ArcTan((y << 14) / x) + 0x8000;
return 0x4000 - ArcTan((x << 14) / y);
} else {
if (x <= 0) {
if (-x > -y)
return ArcTan((y << 14) / x) + 0x8000;
} else if (x >= -y)
return ArcTan((y << 14) / x) + 0x10000;
return 0xC000 - ArcTan((x << 14) / y);
}
}
u16 Sqrt(u32 num)
{
if (!num)
return 0;
u32 lower;
u32 upper = num;
u32 bound = 1;
while (bound < upper) {
upper >>= 1;
bound <<= 1;
}
while (1) {
upper = num;
u32 accum = 0;
lower = bound;
while (1) {
u32 oldLower = lower;
if (lower <= upper >> 1)
lower <<= 1;
if (oldLower >= upper >> 1)
break;
}
while (1) {
accum <<= 1;
if (upper >= lower) {
++accum;
upper -= lower;
}
if (lower == bound)
break;
lower >>= 1;
}
u32 oldBound = bound;
bound += accum;
bound >>= 1;
if (bound >= oldBound) {
bound = oldBound;
break;
}
}
return bound;
}
int MultiBoot(struct MultiBootParam *mp) { return 0; }
-59
View File
@@ -1,59 +0,0 @@
#if ENABLE_RL_LZ_LOGGING
#include <stdio.h>
#endif
#include "platform/platform.h"
#include "platform/ext/gbagfx/global.h"
#include "platform/ext/gbagfx/lz.h"
#include "platform/ext/gbagfx/rl.h"
unsigned char *Platform_LZDecompress(unsigned char *src, int srcSize)
{
int uncompressedSize = 0;
unsigned char *dest = LZDecompress(src, srcSize, &uncompressedSize);
#if ENABLE_RL_LZ_LOGGING
printf("LZDecompress(%p, %p) stored 0x%X bytes.\n", src, dest, uncompressedSize);
#endif
return dest;
}
unsigned char *Platform_RLDecompress(unsigned char *src, int srcSize)
{
int uncompressedSize = 0;
unsigned char *dest = RLDecompress(src, srcSize, &uncompressedSize);
#if ENABLE_RL_LZ_LOGGING
printf("RLDecompress(%p, %p) stored 0x%X bytes.\n", src, dest, uncompressedSize);
#endif
return dest;
}
void Platform_LZFree(unsigned char *dest) { free(dest); }
void Platform_RLFree(unsigned char *dest) { free(dest); }
/* NOTE:
* "Unsafe" versions included for compatibility.
* This is just here so it doesn't fail if someone accidentally calls
* LZUnCompWram, LZUnCompVram, RLUnCompWram or RLUnCompVram.
*
* Please do NOT call them directly if you know the size of the compressed data!
* (Use Platform_LZDecompress and Platform_RLDecompress instead!)
*/
void Platform_LZDecompressUnsafe(unsigned char *src, unsigned char *dest)
{
int uncompressedSize = 0;
LZDecompressUnsafe(src, dest, &uncompressedSize);
#if ENABLE_RL_LZ_LOGGING
printf("LZDecompress(%p, %p) stored 0x%X bytes.\n", src, dest, uncompressedSize);
#endif
}
void Platform_RLDecompressUnsafe(unsigned char *src, unsigned char *dest)
{
int uncompressedSize = 0;
RLDecompressUnsafe(src, dest, &uncompressedSize);
#if ENABLE_RL_LZ_LOGGING
printf("RLDecompress(%p, %p) stored 0x%X bytes.\n", src, dest, uncompressedSize);
#endif
}