Remove fixed-sized pools for most things except audio
This commit is contained in:
parent
6117ab9e4c
commit
45dbaa7468
24 changed files with 7079 additions and 55 deletions
2
Makefile
2
Makefile
|
@ -454,7 +454,7 @@ ifeq ($(TARGET_WEB),1)
|
||||||
PLATFORM_LDFLAGS := -lm -no-pie -s TOTAL_MEMORY=20MB -g4 --source-map-base http://localhost:8080/ -s "EXTRA_EXPORTED_RUNTIME_METHODS=['callMain']"
|
PLATFORM_LDFLAGS := -lm -no-pie -s TOTAL_MEMORY=20MB -g4 --source-map-base http://localhost:8080/ -s "EXTRA_EXPORTED_RUNTIME_METHODS=['callMain']"
|
||||||
endif
|
endif
|
||||||
|
|
||||||
PLATFORM_CFLAGS += -DNO_SEGMENTED_MEMORY
|
PLATFORM_CFLAGS += -DNO_SEGMENTED_MEMORY -DUSE_SYSTEM_MALLOC
|
||||||
|
|
||||||
# Compiler and linker flags for graphics backend
|
# Compiler and linker flags for graphics backend
|
||||||
ifeq ($(ENABLE_OPENGL),1)
|
ifeq ($(ENABLE_OPENGL),1)
|
||||||
|
|
|
@ -4424,7 +4424,8 @@ typedef union {
|
||||||
_g0->words.w0 = _SHIFTL(G_FILLRECT, 24, 8) | \
|
_g0->words.w0 = _SHIFTL(G_FILLRECT, 24, 8) | \
|
||||||
_SHIFTL((lrx), 2, 22); \
|
_SHIFTL((lrx), 2, 22); \
|
||||||
_g0->words.w1 = _SHIFTL((lry), 2, 22); \
|
_g0->words.w1 = _SHIFTL((lry), 2, 22); \
|
||||||
_g1->words.w0 = _SHIFTL((ulx), 2, 22); \
|
_g1->words.w0 = _SHIFTL(G_RDPHALF_1, 24, 8) | \
|
||||||
|
_SHIFTL((ulx), 2, 22); \
|
||||||
_g1->words.w1 = _SHIFTL((uly), 2, 22); \
|
_g1->words.w1 = _SHIFTL((uly), 2, 22); \
|
||||||
}
|
}
|
||||||
#define gsDPFillRectangle(ulx, uly, lrx, lry) \
|
#define gsDPFillRectangle(ulx, uly, lrx, lry) \
|
||||||
|
@ -4433,7 +4434,7 @@ typedef union {
|
||||||
_SHIFTL((lry), 2, 22), \
|
_SHIFTL((lry), 2, 22), \
|
||||||
}}, \
|
}}, \
|
||||||
{{ \
|
{{ \
|
||||||
_SHIFTL((ulx), 2, 22), \
|
(_SHIFTL(G_RDPHALF_1, 24, 8) | _SHIFTL((ulx), 2, 22)), \
|
||||||
_SHIFTL((uly), 2, 22), \
|
_SHIFTL((uly), 2, 22), \
|
||||||
}}
|
}}
|
||||||
#else
|
#else
|
||||||
|
@ -4670,24 +4671,26 @@ typedef union {
|
||||||
\
|
\
|
||||||
_g0->words.w0 = _SHIFTL(G_TEXRECT, 24, 8) | \
|
_g0->words.w0 = _SHIFTL(G_TEXRECT, 24, 8) | \
|
||||||
_SHIFTL((xh), 0, 24); \
|
_SHIFTL((xh), 0, 24); \
|
||||||
_g0->words.w1 = _SHIFTL((yh), 0, 24); \
|
_g0->words.w1 = (_SHIFTL(tile, 24, 3) | _SHIFTL((yh), 0, 24)); \
|
||||||
_g1->words.w0 = (_SHIFTL(tile, 24, 3) | _SHIFTL((xl), 0, 24)); \
|
_g1->words.w0 = (_SHIFTL(G_RDPHALF_1, 24, 8) | \
|
||||||
_g1->words.w1 = _SHIFTL((yl), 0, 24); \
|
_SHIFTL((xl), 0, 24)); \
|
||||||
_g2->words.w0 = (_SHIFTL(s, 16, 16) | _SHIFTL(t, 0, 16)); \
|
_g1->words.w1 = (_SHIFTL(s, 16, 16) | _SHIFTL(t, 0, 16)); \
|
||||||
|
_g2->words.w0 = _SHIFTL(G_RDPHALF_2, 24, 8) | \
|
||||||
|
_SHIFTL((yl), 0, 24); \
|
||||||
_g2->words.w1 = (_SHIFTL(dsdx, 16, 16) | _SHIFTL(dtdy, 0, 16)); \
|
_g2->words.w1 = (_SHIFTL(dsdx, 16, 16) | _SHIFTL(dtdy, 0, 16)); \
|
||||||
}
|
}
|
||||||
|
|
||||||
# define gsSPTextureRectangle(xl, yl, xh, yh, tile, s, t, dsdx, dtdy) \
|
# define gsSPTextureRectangle(xl, yl, xh, yh, tile, s, t, dsdx, dtdy) \
|
||||||
{{ \
|
{{ \
|
||||||
(_SHIFTL(G_TEXRECT, 24, 8) | _SHIFTL((xh), 0, 24)), \
|
(_SHIFTL(G_TEXRECT, 24, 8) | _SHIFTL((xh), 0, 24)), \
|
||||||
_SHIFTL((yh), 0, 24), \
|
(_SHIFTL((tile), 24, 3) | _SHIFTL((yh), 0, 24)), \
|
||||||
}}, \
|
|
||||||
{{ \
|
|
||||||
(_SHIFTL((tile), 24, 3) | _SHIFTL((xl), 0, 24)), \
|
|
||||||
_SHIFTL((yl), 0, 24), \
|
|
||||||
}}, \
|
}}, \
|
||||||
{{ \
|
{{ \
|
||||||
|
(_SHIFTL((G_RDPHALF_1), 24, 8) | _SHIFTL((xl), 0, 24)), \
|
||||||
_SHIFTL(s, 16, 16) | _SHIFTL(t, 0, 16), \
|
_SHIFTL(s, 16, 16) | _SHIFTL(t, 0, 16), \
|
||||||
|
}}, \
|
||||||
|
{{ \
|
||||||
|
(_SHIFTL((G_RDPHALF_2), 24, 8) | _SHIFTL((yl), 0, 24)), \
|
||||||
_SHIFTL(dsdx, 16, 16) | _SHIFTL(dtdy, 0, 16) \
|
_SHIFTL(dsdx, 16, 16) | _SHIFTL(dtdy, 0, 16) \
|
||||||
}}
|
}}
|
||||||
|
|
||||||
|
@ -4697,10 +4700,12 @@ typedef union {
|
||||||
\
|
\
|
||||||
_g0->words.w0 = _SHIFTL(G_TEXRECTFLIP, 24, 8) | \
|
_g0->words.w0 = _SHIFTL(G_TEXRECTFLIP, 24, 8) | \
|
||||||
_SHIFTL((xh), 0, 24); \
|
_SHIFTL((xh), 0, 24); \
|
||||||
_g0->words.w1 = _SHIFTL((yh), 0, 24); \
|
_g0->words.w1 = (_SHIFTL(tile, 24, 3) | _SHIFTL((yh), 0, 24)); \
|
||||||
_g1->words.w0 = (_SHIFTL(tile, 24, 3) | _SHIFTL((xl), 0, 24)); \
|
_g1->words.w0 = (_SHIFTL(G_RDPHALF_1, 24, 8) | \
|
||||||
_g1->words.w1 = _SHIFTL((yl), 0, 24); \
|
_SHIFTL((xl), 0, 24)); \
|
||||||
_g2->words.w0 = (_SHIFTL(s, 16, 16) | _SHIFTL(t, 0, 16)); \
|
_g1->words.w1 = (_SHIFTL(s, 16, 16) | _SHIFTL(t, 0, 16)); \
|
||||||
|
_g2->words.w0 = _SHIFTL(G_RDPHALF_2, 24, 8) | \
|
||||||
|
_SHIFTL((yl), 0, 24); \
|
||||||
_g2->words.w1 = (_SHIFTL(dsdx, 16, 16) | _SHIFTL(dtdy, 0, 16)); \
|
_g2->words.w1 = (_SHIFTL(dsdx, 16, 16) | _SHIFTL(dtdy, 0, 16)); \
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
|
|
|
@ -312,6 +312,10 @@ struct GraphNodeObject *init_graph_node_object(struct AllocOnlyPool *pool,
|
||||||
vec3f_copy(graphNode->pos, pos);
|
vec3f_copy(graphNode->pos, pos);
|
||||||
vec3f_copy(graphNode->scale, scale);
|
vec3f_copy(graphNode->scale, scale);
|
||||||
vec3s_copy(graphNode->angle, angle);
|
vec3s_copy(graphNode->angle, angle);
|
||||||
|
#ifdef USE_SYSTEM_MALLOC
|
||||||
|
// To avoid uninitialised memory usage in audio code
|
||||||
|
vec3f_copy(graphNode->cameraToObject, gVec3fZero);
|
||||||
|
#endif
|
||||||
graphNode->sharedChild = sharedChild;
|
graphNode->sharedChild = sharedChild;
|
||||||
graphNode->throwMatrix = NULL;
|
graphNode->throwMatrix = NULL;
|
||||||
graphNode->animInfo.animID = 0;
|
graphNode->animInfo.animID = 0;
|
||||||
|
|
|
@ -55,6 +55,10 @@ static s16 sScriptStatus;
|
||||||
static s32 sRegister;
|
static s32 sRegister;
|
||||||
static struct LevelCommand *sCurrentCmd;
|
static struct LevelCommand *sCurrentCmd;
|
||||||
|
|
||||||
|
#ifdef USE_SYSTEM_MALLOC
|
||||||
|
static struct MemoryPool *sMemPoolForGoddard;
|
||||||
|
#endif
|
||||||
|
|
||||||
static s32 eval_script_op(s8 op, s32 arg) {
|
static s32 eval_script_op(s8 op, s32 arg) {
|
||||||
s32 result = 0;
|
s32 result = 0;
|
||||||
|
|
||||||
|
@ -280,7 +284,23 @@ static void level_cmd_load_mio0(void) {
|
||||||
sCurrentCmd = CMD_NEXT;
|
sCurrentCmd = CMD_NEXT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef USE_SYSTEM_MALLOC
|
||||||
|
static void *alloc_for_goddard(u32 size) {
|
||||||
|
return mem_pool_alloc(sMemPoolForGoddard, size);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void free_for_goddard(void *ptr) {
|
||||||
|
mem_pool_free(sMemPoolForGoddard, ptr);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
static void level_cmd_load_mario_head(void) {
|
static void level_cmd_load_mario_head(void) {
|
||||||
|
#ifdef USE_SYSTEM_MALLOC
|
||||||
|
sMemPoolForGoddard = mem_pool_init(0, 0);
|
||||||
|
gdm_init(alloc_for_goddard, free_for_goddard);
|
||||||
|
gdm_setup();
|
||||||
|
gdm_maketestdl(CMD_GET(s16, 2));
|
||||||
|
#else
|
||||||
// TODO: Fix these hardcoded sizes
|
// TODO: Fix these hardcoded sizes
|
||||||
void *addr = main_pool_alloc(DOUBLE_SIZE_ON_64_BIT(0xE1000), MEMORY_POOL_LEFT);
|
void *addr = main_pool_alloc(DOUBLE_SIZE_ON_64_BIT(0xE1000), MEMORY_POOL_LEFT);
|
||||||
if (addr != NULL) {
|
if (addr != NULL) {
|
||||||
|
@ -291,6 +311,7 @@ static void level_cmd_load_mario_head(void) {
|
||||||
gdm_maketestdl(CMD_GET(s16, 2));
|
gdm_maketestdl(CMD_GET(s16, 2));
|
||||||
} else {
|
} else {
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
sCurrentCmd = CMD_NEXT;
|
sCurrentCmd = CMD_NEXT;
|
||||||
}
|
}
|
||||||
|
@ -320,8 +341,12 @@ static void level_cmd_clear_level(void) {
|
||||||
|
|
||||||
static void level_cmd_alloc_level_pool(void) {
|
static void level_cmd_alloc_level_pool(void) {
|
||||||
if (sLevelPool == NULL) {
|
if (sLevelPool == NULL) {
|
||||||
|
#ifdef USE_SYSTEM_MALLOC
|
||||||
|
sLevelPool = alloc_only_pool_init();
|
||||||
|
#else
|
||||||
sLevelPool = alloc_only_pool_init(main_pool_available() - sizeof(struct AllocOnlyPool),
|
sLevelPool = alloc_only_pool_init(main_pool_available() - sizeof(struct AllocOnlyPool),
|
||||||
MEMORY_POOL_LEFT);
|
MEMORY_POOL_LEFT);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
sCurrentCmd = CMD_NEXT;
|
sCurrentCmd = CMD_NEXT;
|
||||||
|
@ -330,7 +355,9 @@ static void level_cmd_alloc_level_pool(void) {
|
||||||
static void level_cmd_free_level_pool(void) {
|
static void level_cmd_free_level_pool(void) {
|
||||||
s32 i;
|
s32 i;
|
||||||
|
|
||||||
|
#ifndef USE_SYSTEM_MALLOC
|
||||||
alloc_only_pool_resize(sLevelPool, sLevelPool->usedSpace);
|
alloc_only_pool_resize(sLevelPool, sLevelPool->usedSpace);
|
||||||
|
#endif
|
||||||
sLevelPool = NULL;
|
sLevelPool = NULL;
|
||||||
|
|
||||||
for (i = 0; i < 8; i++) {
|
for (i = 0; i < 8; i++) {
|
||||||
|
|
|
@ -27,6 +27,13 @@ SpatialPartitionCell gDynamicSurfacePartition[NUM_CELLS][NUM_CELLS];
|
||||||
/**
|
/**
|
||||||
* Pools of data to contain either surface nodes or surfaces.
|
* Pools of data to contain either surface nodes or surfaces.
|
||||||
*/
|
*/
|
||||||
|
#ifdef USE_SYSTEM_MALLOC
|
||||||
|
static struct AllocOnlyPool *sStaticSurfaceNodePool;
|
||||||
|
static struct AllocOnlyPool *sStaticSurfacePool;
|
||||||
|
static struct AllocOnlyPool *sDynamicSurfaceNodePool;
|
||||||
|
static struct AllocOnlyPool *sDynamicSurfacePool;
|
||||||
|
static u8 sStaticSurfaceLoadComplete;
|
||||||
|
#else
|
||||||
struct SurfaceNode *sSurfaceNodePool;
|
struct SurfaceNode *sSurfaceNodePool;
|
||||||
struct Surface *sSurfacePool;
|
struct Surface *sSurfacePool;
|
||||||
|
|
||||||
|
@ -34,6 +41,8 @@ struct Surface *sSurfacePool;
|
||||||
* The size of the surface pool (2300).
|
* The size of the surface pool (2300).
|
||||||
*/
|
*/
|
||||||
s16 sSurfacePoolSize;
|
s16 sSurfacePoolSize;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
u8 unused8038EEA8[0x30];
|
u8 unused8038EEA8[0x30];
|
||||||
|
|
||||||
|
@ -41,16 +50,24 @@ u8 unused8038EEA8[0x30];
|
||||||
* Allocate the part of the surface node pool to contain a surface node.
|
* Allocate the part of the surface node pool to contain a surface node.
|
||||||
*/
|
*/
|
||||||
static struct SurfaceNode *alloc_surface_node(void) {
|
static struct SurfaceNode *alloc_surface_node(void) {
|
||||||
|
#ifdef USE_SYSTEM_MALLOC
|
||||||
|
struct AllocOnlyPool *pool = !sStaticSurfaceLoadComplete ?
|
||||||
|
sStaticSurfaceNodePool : sDynamicSurfaceNodePool;
|
||||||
|
struct SurfaceNode *node = alloc_only_pool_alloc(pool, sizeof(struct SurfaceNode));
|
||||||
|
#else
|
||||||
struct SurfaceNode *node = &sSurfaceNodePool[gSurfaceNodesAllocated];
|
struct SurfaceNode *node = &sSurfaceNodePool[gSurfaceNodesAllocated];
|
||||||
|
#endif
|
||||||
gSurfaceNodesAllocated++;
|
gSurfaceNodesAllocated++;
|
||||||
|
|
||||||
node->next = NULL;
|
node->next = NULL;
|
||||||
|
|
||||||
|
#ifndef USE_SYSTEM_MALLOC
|
||||||
//! A bounds check! If there's more surface nodes than 7000 allowed,
|
//! A bounds check! If there's more surface nodes than 7000 allowed,
|
||||||
// we, um...
|
// we, um...
|
||||||
// Perhaps originally just debug feedback?
|
// Perhaps originally just debug feedback?
|
||||||
if (gSurfaceNodesAllocated >= 7000) {
|
if (gSurfaceNodesAllocated >= 7000) {
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
|
@ -60,15 +77,22 @@ static struct SurfaceNode *alloc_surface_node(void) {
|
||||||
* initialize the surface.
|
* initialize the surface.
|
||||||
*/
|
*/
|
||||||
static struct Surface *alloc_surface(void) {
|
static struct Surface *alloc_surface(void) {
|
||||||
|
#ifdef USE_SYSTEM_MALLOC
|
||||||
|
struct AllocOnlyPool *pool = !sStaticSurfaceLoadComplete ?
|
||||||
|
sStaticSurfacePool : sDynamicSurfacePool;
|
||||||
|
struct Surface *surface = alloc_only_pool_alloc(pool, sizeof(struct Surface));
|
||||||
|
#else
|
||||||
struct Surface *surface = &sSurfacePool[gSurfacesAllocated];
|
struct Surface *surface = &sSurfacePool[gSurfacesAllocated];
|
||||||
|
#endif
|
||||||
gSurfacesAllocated++;
|
gSurfacesAllocated++;
|
||||||
|
|
||||||
|
#ifndef USE_SYSTEM_MALLOC
|
||||||
//! A bounds check! If there's more surfaces than the 2300 allowed,
|
//! A bounds check! If there's more surfaces than the 2300 allowed,
|
||||||
// we, um...
|
// we, um...
|
||||||
// Perhaps originally just debug feedback?
|
// Perhaps originally just debug feedback?
|
||||||
if (gSurfacesAllocated >= sSurfacePoolSize) {
|
if (gSurfacesAllocated >= sSurfacePoolSize) {
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
surface->type = 0;
|
surface->type = 0;
|
||||||
surface->force = 0;
|
surface->force = 0;
|
||||||
|
@ -524,9 +548,16 @@ static void load_environmental_regions(s16 **data) {
|
||||||
* Allocate some of the main pool for surfaces (2300 surf) and for surface nodes (7000 nodes).
|
* Allocate some of the main pool for surfaces (2300 surf) and for surface nodes (7000 nodes).
|
||||||
*/
|
*/
|
||||||
void alloc_surface_pools(void) {
|
void alloc_surface_pools(void) {
|
||||||
|
#ifdef USE_SYSTEM_MALLOC
|
||||||
|
sStaticSurfaceNodePool = alloc_only_pool_init();
|
||||||
|
sStaticSurfacePool = alloc_only_pool_init();
|
||||||
|
sDynamicSurfaceNodePool = alloc_only_pool_init();
|
||||||
|
sDynamicSurfacePool = alloc_only_pool_init();
|
||||||
|
#else
|
||||||
sSurfacePoolSize = 2300;
|
sSurfacePoolSize = 2300;
|
||||||
sSurfaceNodePool = main_pool_alloc(7000 * sizeof(struct SurfaceNode), MEMORY_POOL_LEFT);
|
sSurfaceNodePool = main_pool_alloc(7000 * sizeof(struct SurfaceNode), MEMORY_POOL_LEFT);
|
||||||
sSurfacePool = main_pool_alloc(sSurfacePoolSize * sizeof(struct Surface), MEMORY_POOL_LEFT);
|
sSurfacePool = main_pool_alloc(sSurfacePoolSize * sizeof(struct Surface), MEMORY_POOL_LEFT);
|
||||||
|
#endif
|
||||||
|
|
||||||
gCCMEnteredSlide = 0;
|
gCCMEnteredSlide = 0;
|
||||||
reset_red_coins_collected();
|
reset_red_coins_collected();
|
||||||
|
@ -597,6 +628,13 @@ void load_area_terrain(s16 index, s16 *data, s8 *surfaceRooms, s16 *macroObjects
|
||||||
unused8038BE90 = 0;
|
unused8038BE90 = 0;
|
||||||
gSurfaceNodesAllocated = 0;
|
gSurfaceNodesAllocated = 0;
|
||||||
gSurfacesAllocated = 0;
|
gSurfacesAllocated = 0;
|
||||||
|
#ifdef USE_SYSTEM_MALLOC
|
||||||
|
alloc_only_pool_clear(sStaticSurfaceNodePool);
|
||||||
|
alloc_only_pool_clear(sStaticSurfacePool);
|
||||||
|
alloc_only_pool_clear(sDynamicSurfaceNodePool);
|
||||||
|
alloc_only_pool_clear(sDynamicSurfacePool);
|
||||||
|
sStaticSurfaceLoadComplete = FALSE;
|
||||||
|
#endif
|
||||||
|
|
||||||
clear_static_surfaces();
|
clear_static_surfaces();
|
||||||
|
|
||||||
|
@ -639,6 +677,10 @@ void load_area_terrain(s16 index, s16 *data, s8 *surfaceRooms, s16 *macroObjects
|
||||||
|
|
||||||
gNumStaticSurfaceNodes = gSurfaceNodesAllocated;
|
gNumStaticSurfaceNodes = gSurfaceNodesAllocated;
|
||||||
gNumStaticSurfaces = gSurfacesAllocated;
|
gNumStaticSurfaces = gSurfacesAllocated;
|
||||||
|
|
||||||
|
#ifdef USE_SYSTEM_MALLOC
|
||||||
|
sStaticSurfaceLoadComplete = TRUE;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -646,6 +688,15 @@ void load_area_terrain(s16 index, s16 *data, s8 *surfaceRooms, s16 *macroObjects
|
||||||
*/
|
*/
|
||||||
void clear_dynamic_surfaces(void) {
|
void clear_dynamic_surfaces(void) {
|
||||||
if (!(gTimeStopState & TIME_STOP_ACTIVE)) {
|
if (!(gTimeStopState & TIME_STOP_ACTIVE)) {
|
||||||
|
#ifdef USE_SYSTEM_MALLOC
|
||||||
|
if (gSurfacesAllocated > gNumStaticSurfaces) {
|
||||||
|
alloc_only_pool_clear(sDynamicSurfacePool);
|
||||||
|
}
|
||||||
|
if (gSurfaceNodesAllocated > gNumStaticSurfaceNodes) {
|
||||||
|
alloc_only_pool_clear(sDynamicSurfaceNodePool);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
gSurfacesAllocated = gNumStaticSurfaces;
|
gSurfacesAllocated = gNumStaticSurfaces;
|
||||||
gSurfaceNodesAllocated = gNumStaticSurfaceNodes;
|
gSurfaceNodesAllocated = gNumStaticSurfaceNodes;
|
||||||
|
|
||||||
|
|
|
@ -159,6 +159,11 @@ void load_obj_warp_nodes(void) {
|
||||||
struct ObjectWarpNode *sp24;
|
struct ObjectWarpNode *sp24;
|
||||||
struct Object *sp20 = (struct Object *) gObjParentGraphNode.children;
|
struct Object *sp20 = (struct Object *) gObjParentGraphNode.children;
|
||||||
|
|
||||||
|
#ifdef USE_SYSTEM_MALLOC
|
||||||
|
if (sp20 == NULL) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
do {
|
do {
|
||||||
struct Object *sp1C = sp20;
|
struct Object *sp1C = sp20;
|
||||||
|
|
||||||
|
|
|
@ -12,7 +12,13 @@ void bhv_object_bubble_loop(void) {
|
||||||
f32 bubbleY = o->oPosY;
|
f32 bubbleY = o->oPosY;
|
||||||
|
|
||||||
if (bubbleY > waterY) {
|
if (bubbleY > waterY) {
|
||||||
if (gFreeObjectList.next) {
|
if (
|
||||||
|
#ifdef USE_SYSTEM_MALLOC
|
||||||
|
TRUE
|
||||||
|
#else
|
||||||
|
gFreeObjectList.next != NULL
|
||||||
|
#endif
|
||||||
|
) {
|
||||||
bubbleSplash = spawn_object_at_origin(o, 0, MODEL_SMALL_WATER_SPLASH, bhvBubbleSplash);
|
bubbleSplash = spawn_object_at_origin(o, 0, MODEL_SMALL_WATER_SPLASH, bhvBubbleSplash);
|
||||||
bubbleSplash->oPosX = o->oPosX;
|
bubbleSplash->oPosX = o->oPosX;
|
||||||
bubbleSplash->oPosY = bubbleY + 5.0f;
|
bubbleSplash->oPosY = bubbleY + 5.0f;
|
||||||
|
|
|
@ -63,8 +63,15 @@ void bhv_small_water_wave_loop(void) {
|
||||||
if (o->oPosY > sp1C) {
|
if (o->oPosY > sp1C) {
|
||||||
o->activeFlags = ACTIVE_FLAG_DEACTIVATED;
|
o->activeFlags = ACTIVE_FLAG_DEACTIVATED;
|
||||||
o->oPosY += 5.0f;
|
o->oPosY += 5.0f;
|
||||||
if (gFreeObjectList.next != NULL)
|
if (
|
||||||
|
#ifdef USE_SYSTEM_MALLOC
|
||||||
|
TRUE
|
||||||
|
#else
|
||||||
|
gFreeObjectList.next != NULL
|
||||||
|
#endif
|
||||||
|
) {
|
||||||
spawn_object(o, MODEL_SMALL_WATER_SPLASH, bhvObjectWaterSplash);
|
spawn_object(o, MODEL_SMALL_WATER_SPLASH, bhvObjectWaterSplash);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (o->oInteractStatus & INT_STATUS_INTERACTED)
|
if (o->oInteractStatus & INT_STATUS_INTERACTED)
|
||||||
obj_mark_for_deletion(o);
|
obj_mark_for_deletion(o);
|
||||||
|
|
|
@ -25,8 +25,14 @@
|
||||||
// know of a good way to split them
|
// know of a good way to split them
|
||||||
struct Controller gControllers[3];
|
struct Controller gControllers[3];
|
||||||
struct SPTask *gGfxSPTask;
|
struct SPTask *gGfxSPTask;
|
||||||
|
#ifdef USE_SYSTEM_MALLOC
|
||||||
|
struct AllocOnlyPool *gGfxAllocOnlyPool;
|
||||||
|
Gfx *gDisplayListHeadInChunk;
|
||||||
|
Gfx *gDisplayListEndInChunk;
|
||||||
|
#else
|
||||||
Gfx *gDisplayListHead;
|
Gfx *gDisplayListHead;
|
||||||
u8 *gGfxPoolEnd;
|
u8 *gGfxPoolEnd;
|
||||||
|
#endif
|
||||||
struct GfxPool *gGfxPool;
|
struct GfxPool *gGfxPool;
|
||||||
OSContStatus gControllerStatuses[4];
|
OSContStatus gControllerStatuses[4];
|
||||||
OSContPad gControllerPads[4];
|
OSContPad gControllerPads[4];
|
||||||
|
@ -221,7 +227,7 @@ void create_task_structure(void) {
|
||||||
gGfxSPTask->msgqueue = &D_80339CB8;
|
gGfxSPTask->msgqueue = &D_80339CB8;
|
||||||
gGfxSPTask->msg = (OSMesg) 2;
|
gGfxSPTask->msg = (OSMesg) 2;
|
||||||
gGfxSPTask->task.t.type = M_GFXTASK;
|
gGfxSPTask->task.t.type = M_GFXTASK;
|
||||||
#if TARGET_N64
|
#ifdef TARGET_N64
|
||||||
gGfxSPTask->task.t.ucode_boot = rspF3DBootStart;
|
gGfxSPTask->task.t.ucode_boot = rspF3DBootStart;
|
||||||
gGfxSPTask->task.t.ucode_boot_size = ((u8 *) rspF3DBootEnd - (u8 *) rspF3DBootStart);
|
gGfxSPTask->task.t.ucode_boot_size = ((u8 *) rspF3DBootEnd - (u8 *) rspF3DBootStart);
|
||||||
gGfxSPTask->task.t.flags = 0;
|
gGfxSPTask->task.t.flags = 0;
|
||||||
|
@ -291,6 +297,7 @@ void draw_reset_bars(void) {
|
||||||
osRecvMesg(&gGameVblankQueue, &D_80339BEC, OS_MESG_BLOCK);
|
osRecvMesg(&gGameVblankQueue, &D_80339BEC, OS_MESG_BLOCK);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef TARGET_N64
|
||||||
void rendering_init(void) {
|
void rendering_init(void) {
|
||||||
gGfxPool = &gGfxPools[0];
|
gGfxPool = &gGfxPools[0];
|
||||||
set_segment_base_addr(1, gGfxPool->buffer);
|
set_segment_base_addr(1, gGfxPool->buffer);
|
||||||
|
@ -305,13 +312,31 @@ void rendering_init(void) {
|
||||||
frameBufferIndex++;
|
frameBufferIndex++;
|
||||||
gGlobalTimer++;
|
gGlobalTimer++;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef USE_SYSTEM_MALLOC
|
||||||
|
Gfx **alloc_next_dl(void) {
|
||||||
|
u32 size = 1000;
|
||||||
|
Gfx *new_chunk = alloc_only_pool_alloc(gGfxAllocOnlyPool, size * sizeof(Gfx));
|
||||||
|
gSPBranchList(gDisplayListHeadInChunk++, new_chunk);
|
||||||
|
gDisplayListHeadInChunk = new_chunk;
|
||||||
|
gDisplayListEndInChunk = new_chunk + size;
|
||||||
|
return &gDisplayListHeadInChunk;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
void config_gfx_pool(void) {
|
void config_gfx_pool(void) {
|
||||||
gGfxPool = &gGfxPools[gGlobalTimer % GFX_NUM_POOLS];
|
gGfxPool = &gGfxPools[gGlobalTimer % GFX_NUM_POOLS];
|
||||||
set_segment_base_addr(1, gGfxPool->buffer);
|
set_segment_base_addr(1, gGfxPool->buffer);
|
||||||
gGfxSPTask = &gGfxPool->spTask;
|
gGfxSPTask = &gGfxPool->spTask;
|
||||||
|
#ifdef USE_SYSTEM_MALLOC
|
||||||
|
gDisplayListHeadInChunk = gGfxPool->buffer;
|
||||||
|
gDisplayListEndInChunk = gDisplayListHeadInChunk + 1;
|
||||||
|
alloc_only_pool_clear(gGfxAllocOnlyPool);
|
||||||
|
#else
|
||||||
gDisplayListHead = gGfxPool->buffer;
|
gDisplayListHead = gGfxPool->buffer;
|
||||||
gGfxPoolEnd = (u8 *) (gGfxPool->buffer + GFX_POOL_SIZE);
|
gGfxPoolEnd = (u8 *) (gGfxPool->buffer + GFX_POOL_SIZE);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Handles vsync. */
|
/** Handles vsync. */
|
||||||
|
@ -648,9 +673,11 @@ void game_loop_one_iteration(void) {
|
||||||
|
|
||||||
// when debug info is enabled, print the "BUF %d" information.
|
// when debug info is enabled, print the "BUF %d" information.
|
||||||
if (gShowDebugText) {
|
if (gShowDebugText) {
|
||||||
|
#ifndef USE_SYSTEM_MALLOC
|
||||||
// subtract the end of the gfx pool with the display list to obtain the
|
// subtract the end of the gfx pool with the display list to obtain the
|
||||||
// amount of free space remaining.
|
// amount of free space remaining.
|
||||||
print_text_fmt_int(180, 20, "BUF %d", gGfxPoolEnd - (u8 *) gDisplayListHead);
|
print_text_fmt_int(180, 20, "BUF %d", gGfxPoolEnd - (u8 *) gDisplayListHead);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
#ifdef TARGET_N64
|
#ifdef TARGET_N64
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,7 +9,11 @@
|
||||||
#include "types.h"
|
#include "types.h"
|
||||||
#include "memory.h"
|
#include "memory.h"
|
||||||
|
|
||||||
|
#ifdef USE_SYSTEM_MALLOC
|
||||||
|
#define GFX_POOL_SIZE 1
|
||||||
|
#else
|
||||||
#define GFX_POOL_SIZE 6400
|
#define GFX_POOL_SIZE 6400
|
||||||
|
#endif
|
||||||
|
|
||||||
struct GfxPool {
|
struct GfxPool {
|
||||||
Gfx buffer[GFX_POOL_SIZE];
|
Gfx buffer[GFX_POOL_SIZE];
|
||||||
|
@ -37,8 +41,14 @@ extern uintptr_t gPhysicalZBuffer;
|
||||||
extern void *D_80339CF0;
|
extern void *D_80339CF0;
|
||||||
extern void *D_80339CF4;
|
extern void *D_80339CF4;
|
||||||
extern struct SPTask *gGfxSPTask;
|
extern struct SPTask *gGfxSPTask;
|
||||||
|
#ifdef USE_SYSTEM_MALLOC
|
||||||
|
extern struct AllocOnlyPool *gGfxAllocOnlyPool;
|
||||||
|
extern Gfx *gDisplayListHeadInChunk;
|
||||||
|
extern Gfx *gDisplayListEndInChunk;
|
||||||
|
#else
|
||||||
extern Gfx *gDisplayListHead;
|
extern Gfx *gDisplayListHead;
|
||||||
extern u8 *gGfxPoolEnd;
|
extern u8 *gGfxPoolEnd;
|
||||||
|
#endif
|
||||||
extern struct GfxPool *gGfxPool;
|
extern struct GfxPool *gGfxPool;
|
||||||
extern u8 gControllerBits;
|
extern u8 gControllerBits;
|
||||||
extern s8 gEepromProbe;
|
extern s8 gEepromProbe;
|
||||||
|
@ -73,4 +83,9 @@ void rendering_init(void);
|
||||||
void config_gfx_pool(void);
|
void config_gfx_pool(void);
|
||||||
void display_and_vsync(void);
|
void display_and_vsync(void);
|
||||||
|
|
||||||
|
#ifdef USE_SYSTEM_MALLOC
|
||||||
|
Gfx **alloc_next_dl(void);
|
||||||
|
#define gDisplayListHead (*(gDisplayListEndInChunk - gDisplayListHeadInChunk >= 2 ? &gDisplayListHeadInChunk : alloc_next_dl()))
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif // GAME_INIT_H
|
#endif // GAME_INIT_H
|
||||||
|
|
|
@ -2,6 +2,9 @@
|
||||||
#ifndef TARGET_N64
|
#ifndef TARGET_N64
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef USE_SYSTEM_MALLOC
|
||||||
|
#include <stdlib.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "sm64.h"
|
#include "sm64.h"
|
||||||
|
|
||||||
|
@ -14,6 +17,7 @@
|
||||||
#include "memory.h"
|
#include "memory.h"
|
||||||
#include "segment_symbols.h"
|
#include "segment_symbols.h"
|
||||||
#include "segments.h"
|
#include "segments.h"
|
||||||
|
#include "platform_info.h"
|
||||||
|
|
||||||
// round up to the next multiple
|
// round up to the next multiple
|
||||||
#define ALIGN4(val) (((val) + 0x3) & ~0x3)
|
#define ALIGN4(val) (((val) + 0x3) & ~0x3)
|
||||||
|
@ -21,26 +25,60 @@
|
||||||
#define ALIGN16(val) (((val) + 0xF) & ~0xF)
|
#define ALIGN16(val) (((val) + 0xF) & ~0xF)
|
||||||
|
|
||||||
struct MainPoolState {
|
struct MainPoolState {
|
||||||
|
#ifndef USE_SYSTEM_MALLOC
|
||||||
u32 freeSpace;
|
u32 freeSpace;
|
||||||
struct MainPoolBlock *listHeadL;
|
struct MainPoolBlock *listHeadL;
|
||||||
struct MainPoolBlock *listHeadR;
|
struct MainPoolBlock *listHeadR;
|
||||||
|
#endif
|
||||||
struct MainPoolState *prev;
|
struct MainPoolState *prev;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct MainPoolBlock {
|
struct MainPoolBlock {
|
||||||
struct MainPoolBlock *prev;
|
struct MainPoolBlock *prev;
|
||||||
struct MainPoolBlock *next;
|
struct MainPoolBlock *next;
|
||||||
|
#ifdef USE_SYSTEM_MALLOC
|
||||||
|
void (*releaseHandler)(void *addr);
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#ifdef USE_SYSTEM_MALLOC
|
||||||
|
struct AllocOnlyPoolBlock {
|
||||||
|
struct AllocOnlyPoolBlock *prev;
|
||||||
|
#if !IS_64_BIT
|
||||||
|
void *pad; // require 8 bytes alignment
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
struct AllocOnlyPool {
|
||||||
|
struct AllocOnlyPoolBlock *lastBlock;
|
||||||
|
u32 lastBlockSize;
|
||||||
|
u32 lastBlockNextPos;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct FreeListNode {
|
||||||
|
struct FreeListNode *next;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct AllocatedNode {
|
||||||
|
s32 bin;
|
||||||
|
s32 pad;
|
||||||
|
};
|
||||||
|
#else
|
||||||
struct MemoryBlock {
|
struct MemoryBlock {
|
||||||
struct MemoryBlock *next;
|
struct MemoryBlock *next;
|
||||||
u32 size;
|
u32 size;
|
||||||
};
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
struct MemoryPool {
|
struct MemoryPool {
|
||||||
|
#ifdef USE_SYSTEM_MALLOC
|
||||||
|
struct AllocOnlyPool *allocOnlyPool;
|
||||||
|
struct FreeListNode *bins[27];
|
||||||
|
#else
|
||||||
u32 totalSpace;
|
u32 totalSpace;
|
||||||
struct MemoryBlock *firstBlock;
|
struct MemoryBlock *firstBlock;
|
||||||
struct MemoryBlock freeList;
|
struct MemoryBlock freeList;
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
extern uintptr_t sSegmentTable[32];
|
extern uintptr_t sSegmentTable[32];
|
||||||
|
@ -110,6 +148,18 @@ void move_segment_table_to_dmem(void) {
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef USE_SYSTEM_MALLOC
|
||||||
|
static void main_pool_free_all(void) {
|
||||||
|
while (sPoolListHeadL != NULL) {
|
||||||
|
main_pool_free(sPoolListHeadL + 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void main_pool_init(void) {
|
||||||
|
atexit(main_pool_free_all);
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initialize the main memory pool. This pool is conceptually a pair of stacks
|
* Initialize the main memory pool. This pool is conceptually a pair of stacks
|
||||||
* that grow inward from the left and right. It therefore only supports
|
* that grow inward from the left and right. It therefore only supports
|
||||||
|
@ -127,7 +177,61 @@ void main_pool_init(void *start, void *end) {
|
||||||
sPoolListHeadR->prev = NULL;
|
sPoolListHeadR->prev = NULL;
|
||||||
sPoolListHeadR->next = NULL;
|
sPoolListHeadR->next = NULL;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef USE_SYSTEM_MALLOC
|
||||||
|
void *main_pool_alloc(u32 size, void (*releaseHandler)(void *addr)) {
|
||||||
|
struct MainPoolBlock *newListHead = (struct MainPoolBlock *) malloc(sizeof(struct MainPoolBlock) + size);
|
||||||
|
if (newListHead == NULL) {
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
if (sPoolListHeadL != NULL) {
|
||||||
|
sPoolListHeadL->next = newListHead;
|
||||||
|
}
|
||||||
|
newListHead->prev = sPoolListHeadL;
|
||||||
|
newListHead->next = NULL;
|
||||||
|
newListHead->releaseHandler = releaseHandler;
|
||||||
|
sPoolListHeadL = newListHead;
|
||||||
|
return newListHead + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
u32 main_pool_free(void *addr) {
|
||||||
|
struct MainPoolBlock *block = ((struct MainPoolBlock *) addr) - 1;
|
||||||
|
void *toFree;
|
||||||
|
do {
|
||||||
|
if (sPoolListHeadL == NULL) {
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
if (sPoolListHeadL->releaseHandler != NULL) {
|
||||||
|
sPoolListHeadL->releaseHandler(sPoolListHeadL + 1);
|
||||||
|
}
|
||||||
|
toFree = sPoolListHeadL;
|
||||||
|
sPoolListHeadL = sPoolListHeadL->prev;
|
||||||
|
if (sPoolListHeadL != NULL) {
|
||||||
|
sPoolListHeadL->next = NULL;
|
||||||
|
}
|
||||||
|
free(toFree);
|
||||||
|
} while (toFree != block);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
u32 main_pool_push_state(void) {
|
||||||
|
struct MainPoolState *prevState = gMainPoolState;
|
||||||
|
gMainPoolState = main_pool_alloc(sizeof(*gMainPoolState), NULL);
|
||||||
|
gMainPoolState->prev = prevState;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Restore pool state from a previous call to main_pool_push_state. Return the
|
||||||
|
* amount of free space left in the pool.
|
||||||
|
*/
|
||||||
|
u32 main_pool_pop_state(void) {
|
||||||
|
struct MainPoolState *prevState = gMainPoolState->prev;
|
||||||
|
main_pool_free(gMainPoolState);
|
||||||
|
gMainPoolState = prevState;
|
||||||
|
}
|
||||||
|
#else
|
||||||
/**
|
/**
|
||||||
* Allocate a block of memory from the pool of given size, and from the
|
* Allocate a block of memory from the pool of given size, and from the
|
||||||
* specified side of the pool (MEMORY_POOL_LEFT or MEMORY_POOL_RIGHT).
|
* specified side of the pool (MEMORY_POOL_LEFT or MEMORY_POOL_RIGHT).
|
||||||
|
@ -241,6 +345,7 @@ u32 main_pool_pop_state(void) {
|
||||||
gMainPoolState = gMainPoolState->prev;
|
gMainPoolState = gMainPoolState->prev;
|
||||||
return sPoolFreeSpace;
|
return sPoolFreeSpace;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Perform a DMA read from ROM. The transfer is split into 4KB blocks, and this
|
* Perform a DMA read from ROM. The transfer is split into 4KB blocks, and this
|
||||||
|
@ -270,11 +375,15 @@ static void dma_read(u8 *dest, u8 *srcStart, u8 *srcEnd) {
|
||||||
* Perform a DMA read from ROM, allocating space in the memory pool to write to.
|
* Perform a DMA read from ROM, allocating space in the memory pool to write to.
|
||||||
* Return the destination address.
|
* Return the destination address.
|
||||||
*/
|
*/
|
||||||
static void *dynamic_dma_read(u8 *srcStart, u8 *srcEnd, u32 side) {
|
static void *dynamic_dma_read(u8 *srcStart, u8 *srcEnd, UNUSED u32 side) {
|
||||||
void *dest;
|
void *dest;
|
||||||
u32 size = ALIGN16(srcEnd - srcStart);
|
u32 size = ALIGN16(srcEnd - srcStart);
|
||||||
|
|
||||||
|
#ifdef USE_SYSTEM_MALLOC
|
||||||
|
dest = main_pool_alloc(size, NULL);
|
||||||
|
#else
|
||||||
dest = main_pool_alloc(size, side);
|
dest = main_pool_alloc(size, side);
|
||||||
|
#endif
|
||||||
if (dest != NULL) {
|
if (dest != NULL) {
|
||||||
dma_read(dest, srcStart, srcEnd);
|
dma_read(dest, srcStart, srcEnd);
|
||||||
}
|
}
|
||||||
|
@ -377,6 +486,118 @@ void load_engine_code_segment(void) {
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef USE_SYSTEM_MALLOC
|
||||||
|
static void alloc_only_pool_release_handler(void *addr) {
|
||||||
|
struct AllocOnlyPool *pool = (struct AllocOnlyPool *) addr;
|
||||||
|
struct AllocOnlyPoolBlock *block = pool->lastBlock;
|
||||||
|
while (block != NULL) {
|
||||||
|
struct AllocOnlyPoolBlock *prev = block->prev;
|
||||||
|
free(block);
|
||||||
|
block = prev;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct AllocOnlyPool *alloc_only_pool_init(void) {
|
||||||
|
struct AllocOnlyPool *pool;
|
||||||
|
void *addr = main_pool_alloc(sizeof(struct AllocOnlyPool), alloc_only_pool_release_handler);
|
||||||
|
|
||||||
|
pool = (struct AllocOnlyPool *) addr;
|
||||||
|
pool->lastBlock = NULL;
|
||||||
|
pool->lastBlockSize = 0;
|
||||||
|
pool->lastBlockNextPos = 0;
|
||||||
|
|
||||||
|
return pool;
|
||||||
|
}
|
||||||
|
|
||||||
|
void alloc_only_pool_clear(struct AllocOnlyPool *pool) {
|
||||||
|
alloc_only_pool_release_handler(pool);
|
||||||
|
pool->lastBlock = NULL;
|
||||||
|
pool->lastBlockSize = 0;
|
||||||
|
pool->lastBlockNextPos = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void *alloc_only_pool_alloc(struct AllocOnlyPool *pool, s32 size) {
|
||||||
|
u8 *addr;
|
||||||
|
u32 s = size;
|
||||||
|
if (pool->lastBlockSize - pool->lastBlockNextPos < s) {
|
||||||
|
struct AllocOnlyPoolBlock *block;
|
||||||
|
u32 nextSize = pool->lastBlockSize * 2;
|
||||||
|
if (nextSize < 100) {
|
||||||
|
nextSize = 100;
|
||||||
|
}
|
||||||
|
if (nextSize < s) {
|
||||||
|
nextSize = s;
|
||||||
|
}
|
||||||
|
block = (struct AllocOnlyPoolBlock *) malloc(sizeof(struct AllocOnlyPoolBlock) + nextSize);
|
||||||
|
if (block == NULL) {
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
block->prev = pool->lastBlock;
|
||||||
|
pool->lastBlock = block;
|
||||||
|
pool->lastBlockSize = nextSize;
|
||||||
|
pool->lastBlockNextPos = 0;
|
||||||
|
}
|
||||||
|
addr = (u8 *) (pool->lastBlock + 1) + pool->lastBlockNextPos;
|
||||||
|
pool->lastBlockNextPos += s;
|
||||||
|
return addr;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct MemoryPool *mem_pool_init(UNUSED u32 size, UNUSED u32 side) {
|
||||||
|
struct MemoryPool *pool;
|
||||||
|
void *addr = main_pool_alloc(sizeof(struct MemoryPool), NULL);
|
||||||
|
u32 i;
|
||||||
|
|
||||||
|
pool = (struct MemoryPool *) addr;
|
||||||
|
pool->allocOnlyPool = alloc_only_pool_init();
|
||||||
|
for (i = 0; i < ARRAY_COUNT(pool->bins); i++) {
|
||||||
|
pool->bins[i] = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return pool;
|
||||||
|
}
|
||||||
|
|
||||||
|
void *mem_pool_alloc(struct MemoryPool *pool, u32 size) {
|
||||||
|
struct FreeListNode *node;
|
||||||
|
struct AllocatedNode *an;
|
||||||
|
s32 bin = -1;
|
||||||
|
u32 itemSize;
|
||||||
|
u32 i;
|
||||||
|
|
||||||
|
for (i = 3; i < 30; i++) {
|
||||||
|
if (size <= (1U << i)) {
|
||||||
|
bin = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (bin == -1) {
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
itemSize = 1 << bin;
|
||||||
|
node = pool->bins[bin - 3];
|
||||||
|
if (node == NULL) {
|
||||||
|
node = alloc_only_pool_alloc(pool->allocOnlyPool, sizeof(struct AllocatedNode) + itemSize);
|
||||||
|
node->next = NULL;
|
||||||
|
pool->bins[bin - 3] = node;
|
||||||
|
}
|
||||||
|
an = (struct AllocatedNode *) node;
|
||||||
|
pool->bins[bin - 3] = node->next;
|
||||||
|
an->bin = bin;
|
||||||
|
return an + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void mem_pool_free(struct MemoryPool *pool, void *addr) {
|
||||||
|
struct AllocatedNode *an = ((struct AllocatedNode *) addr) - 1;
|
||||||
|
struct FreeListNode *node = (struct FreeListNode *) an;
|
||||||
|
s32 bin = an->bin;
|
||||||
|
node->next = pool->bins[bin - 3];
|
||||||
|
pool->bins[bin - 3] = node;
|
||||||
|
}
|
||||||
|
|
||||||
|
void *alloc_display_list(u32 size) {
|
||||||
|
size = ALIGN8(size);
|
||||||
|
return alloc_only_pool_alloc(gGfxAllocOnlyPool, size);
|
||||||
|
}
|
||||||
|
#else
|
||||||
/**
|
/**
|
||||||
* Allocate an allocation-only pool from the main pool. This pool doesn't
|
* Allocate an allocation-only pool from the main pool. This pool doesn't
|
||||||
* support freeing allocated memory.
|
* support freeing allocated memory.
|
||||||
|
@ -537,6 +758,7 @@ void *alloc_display_list(u32 size) {
|
||||||
}
|
}
|
||||||
return ptr;
|
return ptr;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
static struct MarioAnimDmaRelatedThing *func_802789F0(u8 *srcAddr) {
|
static struct MarioAnimDmaRelatedThing *func_802789F0(u8 *srcAddr) {
|
||||||
struct MarioAnimDmaRelatedThing *sp1C = dynamic_dma_read(srcAddr, srcAddr + sizeof(u32),
|
struct MarioAnimDmaRelatedThing *sp1C = dynamic_dma_read(srcAddr, srcAddr + sizeof(u32),
|
||||||
|
|
|
@ -8,7 +8,9 @@
|
||||||
#define MEMORY_POOL_LEFT 0
|
#define MEMORY_POOL_LEFT 0
|
||||||
#define MEMORY_POOL_RIGHT 1
|
#define MEMORY_POOL_RIGHT 1
|
||||||
|
|
||||||
|
#ifdef USE_SYSTEM_MALLOC
|
||||||
|
struct AllocOnlyPool;
|
||||||
|
#else
|
||||||
struct AllocOnlyPool
|
struct AllocOnlyPool
|
||||||
{
|
{
|
||||||
s32 totalSpace;
|
s32 totalSpace;
|
||||||
|
@ -16,6 +18,7 @@ struct AllocOnlyPool
|
||||||
u8 *startPtr;
|
u8 *startPtr;
|
||||||
u8 *freePtr;
|
u8 *freePtr;
|
||||||
};
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
struct MemoryPool;
|
struct MemoryPool;
|
||||||
|
|
||||||
|
@ -32,8 +35,13 @@ void *segmented_to_virtual(const void *addr);
|
||||||
void *virtual_to_segmented(u32 segment, const void *addr);
|
void *virtual_to_segmented(u32 segment, const void *addr);
|
||||||
void move_segment_table_to_dmem(void);
|
void move_segment_table_to_dmem(void);
|
||||||
|
|
||||||
|
#ifdef USE_SYSTEM_MALLOC
|
||||||
|
void main_pool_init(void);
|
||||||
|
void *main_pool_alloc(u32 size, void (*releaseHandler)(void *addr));
|
||||||
|
#else
|
||||||
void main_pool_init(void *start, void *end);
|
void main_pool_init(void *start, void *end);
|
||||||
void *main_pool_alloc(u32 size, u32 side);
|
void *main_pool_alloc(u32 size, u32 side);
|
||||||
|
#endif
|
||||||
u32 main_pool_free(void *addr);
|
u32 main_pool_free(void *addr);
|
||||||
void *main_pool_realloc(void *addr, u32 size);
|
void *main_pool_realloc(void *addr, u32 size);
|
||||||
u32 main_pool_available(void);
|
u32 main_pool_available(void);
|
||||||
|
@ -54,9 +62,15 @@ void load_engine_code_segment(void);
|
||||||
#define load_engine_code_segment(...)
|
#define load_engine_code_segment(...)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef USE_SYSTEM_MALLOC
|
||||||
|
struct AllocOnlyPool *alloc_only_pool_init(void);
|
||||||
|
void alloc_only_pool_clear(struct AllocOnlyPool *pool);
|
||||||
|
void *alloc_only_pool_alloc(struct AllocOnlyPool *pool, s32 size);
|
||||||
|
#else
|
||||||
struct AllocOnlyPool *alloc_only_pool_init(u32 size, u32 side);
|
struct AllocOnlyPool *alloc_only_pool_init(u32 size, u32 side);
|
||||||
void *alloc_only_pool_alloc(struct AllocOnlyPool *pool, s32 size);
|
void *alloc_only_pool_alloc(struct AllocOnlyPool *pool, s32 size);
|
||||||
struct AllocOnlyPool *alloc_only_pool_resize(struct AllocOnlyPool *pool, u32 size);
|
struct AllocOnlyPool *alloc_only_pool_resize(struct AllocOnlyPool *pool, u32 size);
|
||||||
|
#endif
|
||||||
|
|
||||||
struct MemoryPool *mem_pool_init(u32 size, u32 side);
|
struct MemoryPool *mem_pool_init(u32 size, u32 side);
|
||||||
void *mem_pool_alloc(struct MemoryPool *pool, u32 size);
|
void *mem_pool_alloc(struct MemoryPool *pool, u32 size);
|
||||||
|
|
|
@ -551,7 +551,13 @@ struct Object *try_to_spawn_object(s16 offsetY, f32 scale, struct Object *parent
|
||||||
const BehaviorScript *behavior) {
|
const BehaviorScript *behavior) {
|
||||||
struct Object *obj;
|
struct Object *obj;
|
||||||
|
|
||||||
if (gFreeObjectList.next != NULL) {
|
if (
|
||||||
|
#ifdef USE_SYSTEM_MALLOC
|
||||||
|
TRUE
|
||||||
|
#else
|
||||||
|
gFreeObjectList.next != NULL
|
||||||
|
#endif
|
||||||
|
) {
|
||||||
obj = spawn_object(parent, model, behavior);
|
obj = spawn_object(parent, model, behavior);
|
||||||
obj->oPosY += offsetY;
|
obj->oPosY += offsetY;
|
||||||
obj_scale(obj, scale);
|
obj_scale(obj, scale);
|
||||||
|
|
|
@ -63,10 +63,12 @@ s16 gDebugInfoOverwrite[16][8];
|
||||||
*/
|
*/
|
||||||
u32 gTimeStopState;
|
u32 gTimeStopState;
|
||||||
|
|
||||||
|
#ifndef USE_SYSTEM_MALLOC
|
||||||
/**
|
/**
|
||||||
* The pool that objects are allocated from.
|
* The pool that objects are allocated from.
|
||||||
*/
|
*/
|
||||||
struct Object gObjectPool[OBJECT_POOL_CAPACITY];
|
struct Object gObjectPool[OBJECT_POOL_CAPACITY];
|
||||||
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A special object whose purpose is to act as a parent for macro objects.
|
* A special object whose purpose is to act as a parent for macro objects.
|
||||||
|
@ -540,16 +542,20 @@ void clear_objects(void) {
|
||||||
|
|
||||||
debug_unknown_level_select_check();
|
debug_unknown_level_select_check();
|
||||||
|
|
||||||
|
#ifndef USE_SYSTEM_MALLOC
|
||||||
init_free_object_list();
|
init_free_object_list();
|
||||||
|
#endif
|
||||||
clear_object_lists(gObjectListArray);
|
clear_object_lists(gObjectListArray);
|
||||||
|
|
||||||
stub_behavior_script_2();
|
stub_behavior_script_2();
|
||||||
stub_obj_list_processor_1();
|
stub_obj_list_processor_1();
|
||||||
|
|
||||||
|
#ifndef USE_SYSTEM_MALLOC
|
||||||
for (i = 0; i < OBJECT_POOL_CAPACITY; i++) {
|
for (i = 0; i < OBJECT_POOL_CAPACITY; i++) {
|
||||||
gObjectPool[i].activeFlags = ACTIVE_FLAG_DEACTIVATED;
|
gObjectPool[i].activeFlags = ACTIVE_FLAG_DEACTIVATED;
|
||||||
geo_reset_object_node(&gObjectPool[i].header.gfx);
|
geo_reset_object_node(&gObjectPool[i].header.gfx);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
gObjectMemoryPool = mem_pool_init(0x800, MEMORY_POOL_LEFT);
|
gObjectMemoryPool = mem_pool_init(0x800, MEMORY_POOL_LEFT);
|
||||||
gObjectLists = gObjectListArray;
|
gObjectLists = gObjectListArray;
|
||||||
|
|
|
@ -1051,8 +1051,12 @@ void geo_process_root(struct GraphNodeRoot *node, Vp *b, Vp *c, s32 clearColor)
|
||||||
Mtx *initialMatrix;
|
Mtx *initialMatrix;
|
||||||
Vp *viewport = alloc_display_list(sizeof(*viewport));
|
Vp *viewport = alloc_display_list(sizeof(*viewport));
|
||||||
|
|
||||||
|
#ifdef USE_SYSTEM_MALLOC
|
||||||
|
gDisplayListHeap = alloc_only_pool_init();
|
||||||
|
#else
|
||||||
gDisplayListHeap = alloc_only_pool_init(main_pool_available() - sizeof(struct AllocOnlyPool),
|
gDisplayListHeap = alloc_only_pool_init(main_pool_available() - sizeof(struct AllocOnlyPool),
|
||||||
MEMORY_POOL_LEFT);
|
MEMORY_POOL_LEFT);
|
||||||
|
#endif
|
||||||
initialMatrix = alloc_display_list(sizeof(*initialMatrix));
|
initialMatrix = alloc_display_list(sizeof(*initialMatrix));
|
||||||
gMatStackIndex = 0;
|
gMatStackIndex = 0;
|
||||||
gCurAnimType = 0;
|
gCurAnimType = 0;
|
||||||
|
@ -1081,8 +1085,10 @@ void geo_process_root(struct GraphNodeRoot *node, Vp *b, Vp *c, s32 clearColor)
|
||||||
}
|
}
|
||||||
gCurGraphNodeRoot = NULL;
|
gCurGraphNodeRoot = NULL;
|
||||||
if (gShowDebugText) {
|
if (gShowDebugText) {
|
||||||
|
#ifndef USE_SYSTEM_MALLOC
|
||||||
print_text_fmt_int(180, 36, "MEM %d",
|
print_text_fmt_int(180, 36, "MEM %d",
|
||||||
gDisplayListHeap->totalSpace - gDisplayListHeap->usedSpace);
|
gDisplayListHeap->totalSpace - gDisplayListHeap->usedSpace);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
main_pool_free(gDisplayListHeap);
|
main_pool_free(gDisplayListHeap);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,3 +1,6 @@
|
||||||
|
#ifdef USE_SYSTEM_MALLOC
|
||||||
|
#include <stdlib.h>
|
||||||
|
#endif
|
||||||
#include <PR/ultratypes.h>
|
#include <PR/ultratypes.h>
|
||||||
|
|
||||||
#include "audio/external.h"
|
#include "audio/external.h"
|
||||||
|
@ -89,10 +92,26 @@ struct Object *try_allocate_object(struct ObjectNode *destList, struct ObjectNod
|
||||||
destList->prev->next = nextObj;
|
destList->prev->next = nextObj;
|
||||||
destList->prev = nextObj;
|
destList->prev = nextObj;
|
||||||
} else {
|
} else {
|
||||||
|
#ifdef USE_SYSTEM_MALLOC
|
||||||
|
nextObj = (struct ObjectNode *) malloc(sizeof(struct Object));
|
||||||
|
if (nextObj == NULL) {
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
// Insert at end of destination list
|
||||||
|
nextObj->prev = destList->prev;
|
||||||
|
nextObj->next = destList;
|
||||||
|
destList->prev->next = nextObj;
|
||||||
|
destList->prev = nextObj;
|
||||||
|
#else
|
||||||
return NULL;
|
return NULL;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef USE_SYSTEM_MALLOC
|
||||||
|
init_graph_node_object(NULL, &nextObj->gfx, 0, gVec3fZero, gVec3sZero, gVec3fOne);
|
||||||
|
#else
|
||||||
geo_remove_child(&nextObj->gfx.node);
|
geo_remove_child(&nextObj->gfx.node);
|
||||||
|
#endif
|
||||||
geo_add_child(&gObjParentGraphNode, &nextObj->gfx.node);
|
geo_add_child(&gObjParentGraphNode, &nextObj->gfx.node);
|
||||||
|
|
||||||
return (struct Object *) nextObj;
|
return (struct Object *) nextObj;
|
||||||
|
@ -112,6 +131,7 @@ void unused_deallocate(struct LinkedList *freeList, struct LinkedList *node) {
|
||||||
node->next = freeList->next;
|
node->next = freeList->next;
|
||||||
freeList->next = node;
|
freeList->next = node;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Remove the given object from the object list that it's currently in, and
|
* Remove the given object from the object list that it's currently in, and
|
||||||
* insert it at the beginning of the free list (singly linked).
|
* insert it at the beginning of the free list (singly linked).
|
||||||
|
@ -126,6 +146,7 @@ static void deallocate_object(struct ObjectNode *freeList, struct ObjectNode *ob
|
||||||
freeList->next = obj;
|
freeList->next = obj;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef USE_SYSTEM_MALLOC
|
||||||
/**
|
/**
|
||||||
* Add every object in the pool to the free object list.
|
* Add every object in the pool to the free object list.
|
||||||
*/
|
*/
|
||||||
|
@ -146,6 +167,7 @@ void init_free_object_list(void) {
|
||||||
// End the list
|
// End the list
|
||||||
obj->header.next = NULL;
|
obj->header.next = NULL;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Clear each object list, without adding the objects back to the free list.
|
* Clear each object list, without adding the objects back to the free list.
|
||||||
|
@ -154,6 +176,17 @@ void clear_object_lists(struct ObjectNode *objLists) {
|
||||||
s32 i;
|
s32 i;
|
||||||
|
|
||||||
for (i = 0; i < NUM_OBJ_LISTS; i++) {
|
for (i = 0; i < NUM_OBJ_LISTS; i++) {
|
||||||
|
#ifdef USE_SYSTEM_MALLOC
|
||||||
|
struct ObjectNode *list = objLists + i;
|
||||||
|
struct ObjectNode *node = list->next;
|
||||||
|
|
||||||
|
while (node != NULL && node != list) {
|
||||||
|
struct Object *obj = (struct Object *) node;
|
||||||
|
node = node->next;
|
||||||
|
|
||||||
|
unload_object(obj);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
objLists[i].next = &objLists[i];
|
objLists[i].next = &objLists[i];
|
||||||
objLists[i].prev = &objLists[i];
|
objLists[i].prev = &objLists[i];
|
||||||
}
|
}
|
||||||
|
@ -192,7 +225,9 @@ void unload_object(struct Object *obj) {
|
||||||
obj->header.gfx.throwMatrix = NULL;
|
obj->header.gfx.throwMatrix = NULL;
|
||||||
func_803206F8(obj->header.gfx.cameraToObject);
|
func_803206F8(obj->header.gfx.cameraToObject);
|
||||||
geo_remove_child(&obj->header.gfx.node);
|
geo_remove_child(&obj->header.gfx.node);
|
||||||
|
#ifndef USE_SYSTEM_MALLOC
|
||||||
geo_add_child(&gObjParentGraphNode, &obj->header.gfx.node);
|
geo_add_child(&gObjParentGraphNode, &obj->header.gfx.node);
|
||||||
|
#endif
|
||||||
|
|
||||||
obj->header.gfx.node.flags &= ~GRAPH_RENDER_BILLBOARD;
|
obj->header.gfx.node.flags &= ~GRAPH_RENDER_BILLBOARD;
|
||||||
obj->header.gfx.node.flags &= ~GRAPH_RENDER_ACTIVE;
|
obj->header.gfx.node.flags &= ~GRAPH_RENDER_ACTIVE;
|
||||||
|
@ -209,6 +244,7 @@ struct Object *allocate_object(struct ObjectNode *objList) {
|
||||||
s32 i;
|
s32 i;
|
||||||
struct Object *obj = try_allocate_object(objList, &gFreeObjectList);
|
struct Object *obj = try_allocate_object(objList, &gFreeObjectList);
|
||||||
|
|
||||||
|
#ifndef USE_SYSTEM_MALLOC
|
||||||
// The object list is full if the newly created pointer is NULL.
|
// The object list is full if the newly created pointer is NULL.
|
||||||
// If this happens, we first attempt to unload unimportant objects
|
// If this happens, we first attempt to unload unimportant objects
|
||||||
// in order to finish allocating the object.
|
// in order to finish allocating the object.
|
||||||
|
@ -233,6 +269,7 @@ struct Object *allocate_object(struct ObjectNode *objList) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
// Initialize object fields
|
// Initialize object fields
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
#ifndef USE_SYSTEM_MALLOC
|
||||||
#include <PR/ultratypes.h>
|
#include <PR/ultratypes.h>
|
||||||
|
|
||||||
#include "debug_utils.h"
|
#include "debug_utils.h"
|
||||||
|
@ -312,6 +313,10 @@ void mem_stats(void) {
|
||||||
list = sEmptyBlockListHead;
|
list = sEmptyBlockListHead;
|
||||||
print_list_stats(list, FALSE, PERM_G_MEM_BLOCK | TEMP_G_MEM_BLOCK);
|
print_list_stats(list, FALSE, PERM_G_MEM_BLOCK | TEMP_G_MEM_BLOCK);
|
||||||
}
|
}
|
||||||
|
#else
|
||||||
|
void mem_stats(void) {
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
::::::
|
::::::
|
||||||
|
|
|
@ -114,8 +114,10 @@ static struct ObjGadget *sTimerGadgets[GD_NUM_TIMERS]; // @ 801BAEA8
|
||||||
static u32 D_801BAF28; // RAM addr offset?
|
static u32 D_801BAF28; // RAM addr offset?
|
||||||
static s16 D_801BAF30[13][8]; // [[s16; 8]; 13]? vert indices?
|
static s16 D_801BAF30[13][8]; // [[s16; 8]; 13]? vert indices?
|
||||||
static u32 unref_801bb000[3];
|
static u32 unref_801bb000[3];
|
||||||
|
#ifndef USE_SYSTEM_MALLOC
|
||||||
static u8 *sMemBlockPoolBase; // @ 801BB00C
|
static u8 *sMemBlockPoolBase; // @ 801BB00C
|
||||||
static u32 sAllocMemory; // @ 801BB010; malloc-ed bytes
|
static u32 sAllocMemory; // @ 801BB010; malloc-ed bytes
|
||||||
|
#endif
|
||||||
static u32 unref_801bb014;
|
static u32 unref_801bb014;
|
||||||
static s32 D_801BB018;
|
static s32 D_801BB018;
|
||||||
static s32 D_801BB01C;
|
static s32 D_801BB01C;
|
||||||
|
@ -182,6 +184,11 @@ static OSIoMesg D_801BE980;
|
||||||
static struct ObjView *D_801BE994; // store if View flag 0x40 set
|
static struct ObjView *D_801BE994; // store if View flag 0x40 set
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef USE_SYSTEM_MALLOC
|
||||||
|
static void *(*sAllocFn)(u32 size);
|
||||||
|
static void (*sFreeFn)(void *ptr);
|
||||||
|
#endif
|
||||||
|
|
||||||
// data
|
// data
|
||||||
static u32 unref_801a8670 = 0;
|
static u32 unref_801a8670 = 0;
|
||||||
static s32 D_801A8674 = 0;
|
static s32 D_801A8674 = 0;
|
||||||
|
@ -193,8 +200,10 @@ static f32 sDynamicsTime = 0.0f; // @ 801A8688
|
||||||
static f32 sDLGenTime = 0.0f; // @ 801A868C
|
static f32 sDLGenTime = 0.0f; // @ 801A868C
|
||||||
static f32 sRCPTime = 0.0f; // @ 801A8690
|
static f32 sRCPTime = 0.0f; // @ 801A8690
|
||||||
static f32 sTimeScaleFactor = 1.0f; // @ D_801A8694
|
static f32 sTimeScaleFactor = 1.0f; // @ D_801A8694
|
||||||
|
#ifndef USE_SYSTEM_MALLOC
|
||||||
static u32 sMemBlockPoolSize = 1; // @ 801A8698
|
static u32 sMemBlockPoolSize = 1; // @ 801A8698
|
||||||
static s32 sMemBlockPoolUsed = 0; // @ 801A869C
|
static s32 sMemBlockPoolUsed = 0; // @ 801A869C
|
||||||
|
#endif
|
||||||
static s32 D_801A86A0 = 0;
|
static s32 D_801A86A0 = 0;
|
||||||
static struct GdTimer *D_801A86A4 = NULL; // timer for dlgen, dynamics, or rcp
|
static struct GdTimer *D_801A86A4 = NULL; // timer for dlgen, dynamics, or rcp
|
||||||
static struct GdTimer *D_801A86A8 = NULL; // timer for dlgen, dynamics, or rcp
|
static struct GdTimer *D_801A86A8 = NULL; // timer for dlgen, dynamics, or rcp
|
||||||
|
@ -763,7 +772,11 @@ void reset_cur_dl_indices(void);
|
||||||
// TODO: make a gddl_num_t?
|
// TODO: make a gddl_num_t?
|
||||||
|
|
||||||
u32 get_alloc_mem_amt(void) {
|
u32 get_alloc_mem_amt(void) {
|
||||||
|
#ifdef USE_SYSTEM_MALLOC
|
||||||
|
return 0;
|
||||||
|
#else
|
||||||
return sAllocMemory;
|
return sAllocMemory;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
s32 gd_get_ostime(void) {
|
s32 gd_get_ostime(void) {
|
||||||
|
@ -959,9 +972,14 @@ void gd_exit(UNUSED s32 code) {
|
||||||
|
|
||||||
/* 24A1D4 -> 24A220; orig name: func_8019BA04 */
|
/* 24A1D4 -> 24A220; orig name: func_8019BA04 */
|
||||||
void gd_free(void *ptr) {
|
void gd_free(void *ptr) {
|
||||||
|
#ifdef USE_SYSTEM_MALLOC
|
||||||
|
sFreeFn(ptr);
|
||||||
|
#else
|
||||||
sAllocMemory -= gd_free_mem(ptr);
|
sAllocMemory -= gd_free_mem(ptr);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef USE_SYSTEM_MALLOC
|
||||||
/* 24A220 -> 24A318 */
|
/* 24A220 -> 24A318 */
|
||||||
void *gd_allocblock(u32 size) {
|
void *gd_allocblock(u32 size) {
|
||||||
void *block; // 1c
|
void *block; // 1c
|
||||||
|
@ -980,9 +998,13 @@ void *gd_allocblock(u32 size) {
|
||||||
sMemBlockPoolUsed += size;
|
sMemBlockPoolUsed += size;
|
||||||
return block;
|
return block;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/* 24A318 -> 24A3E8 */
|
/* 24A318 -> 24A3E8 */
|
||||||
void *gd_malloc(u32 size, u8 perm) {
|
void *gd_malloc(u32 size, UNUSED u8 perm) {
|
||||||
|
#ifdef USE_SYSTEM_MALLOC
|
||||||
|
return sAllocFn(size);
|
||||||
|
#else
|
||||||
void *ptr; // 1c
|
void *ptr; // 1c
|
||||||
size = ALIGN(size, 8);
|
size = ALIGN(size, 8);
|
||||||
ptr = gd_request_mem(size, perm);
|
ptr = gd_request_mem(size, perm);
|
||||||
|
@ -998,6 +1020,7 @@ void *gd_malloc(u32 size, u8 perm) {
|
||||||
sAllocMemory += size;
|
sAllocMemory += size;
|
||||||
|
|
||||||
return ptr;
|
return ptr;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 24A3E8 -> 24A420; orig name: func_8019BC18 */
|
/* 24A3E8 -> 24A420; orig name: func_8019BC18 */
|
||||||
|
@ -1122,12 +1145,23 @@ void Unknown8019C288(s32 stickX, s32 stickY) {
|
||||||
ctrl->stickYf = (f32)(stickY / 2);
|
ctrl->stickYf = (f32)(stickY / 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef USE_SYSTEM_MALLOC
|
||||||
/* 24AAA8 -> 24AAE0; orig name: func_8019C2D8 */
|
/* 24AAA8 -> 24AAE0; orig name: func_8019C2D8 */
|
||||||
void gd_add_to_heap(void *addr, u32 size) {
|
void gd_add_to_heap(void *addr, u32 size) {
|
||||||
// TODO: is this `1` for permanence special?
|
// TODO: is this `1` for permanence special?
|
||||||
gd_add_mem_to_heap(size, addr, 1);
|
gd_add_mem_to_heap(size, addr, 1);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef USE_SYSTEM_MALLOC
|
||||||
|
void gdm_init(void *(*allocFn)(u32 size), void (*freeFn)(void *addr)) {
|
||||||
|
add_to_stacktrace("gdm_init");
|
||||||
|
sAllocFn = allocFn;
|
||||||
|
sFreeFn = freeFn;
|
||||||
|
gd_reset_sfx();
|
||||||
|
imout();
|
||||||
|
}
|
||||||
|
#else
|
||||||
/* 24AAE0 -> 24AB7C */
|
/* 24AAE0 -> 24AB7C */
|
||||||
void gdm_init(void *blockpool, u32 size) {
|
void gdm_init(void *blockpool, u32 size) {
|
||||||
UNUSED u32 pad;
|
UNUSED u32 pad;
|
||||||
|
@ -1145,6 +1179,7 @@ void gdm_init(void *blockpool, u32 size) {
|
||||||
gd_reset_sfx();
|
gd_reset_sfx();
|
||||||
imout();
|
imout();
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/* 24AB7C -> 24AC18 */
|
/* 24AB7C -> 24AC18 */
|
||||||
void gdm_setup(void) {
|
void gdm_setup(void) {
|
||||||
|
@ -3118,9 +3153,11 @@ void gd_init(void) {
|
||||||
s8 *data; // 2c
|
s8 *data; // 2c
|
||||||
|
|
||||||
add_to_stacktrace("gd_init");
|
add_to_stacktrace("gd_init");
|
||||||
|
#ifndef USE_SYSTEM_MALLOC
|
||||||
i = (u32)(sMemBlockPoolSize - DOUBLE_SIZE_ON_64_BIT(0x3E800));
|
i = (u32)(sMemBlockPoolSize - DOUBLE_SIZE_ON_64_BIT(0x3E800));
|
||||||
data = gd_allocblock(i);
|
data = gd_allocblock(i);
|
||||||
gd_add_mem_to_heap(i, data, 0x10);
|
gd_add_mem_to_heap(i, data, 0x10);
|
||||||
|
#endif
|
||||||
D_801BB184 = (u16) 0xff;
|
D_801BB184 = (u16) 0xff;
|
||||||
D_801A867C = 0;
|
D_801A867C = 0;
|
||||||
D_801A8680 = 0;
|
D_801A8680 = 0;
|
||||||
|
|
|
@ -42,8 +42,12 @@ void *gd_malloc(u32 size, u8 perm);
|
||||||
void *gd_malloc_perm(u32 size);
|
void *gd_malloc_perm(u32 size);
|
||||||
void *gd_malloc_temp(u32 size);
|
void *gd_malloc_temp(u32 size);
|
||||||
void func_8019BD0C(s32 dlNum, s32 gfxIdx);
|
void func_8019BD0C(s32 dlNum, s32 gfxIdx);
|
||||||
|
#ifdef USE_SYSTEM_MALLOC
|
||||||
|
void gdm_init(void *(*allocFn)(u32 size), void (*freeFn)(void *ptr));
|
||||||
|
#else
|
||||||
void gd_add_to_heap(void *addr, u32 size);
|
void gd_add_to_heap(void *addr, u32 size);
|
||||||
void gdm_init(void *blockpool, u32 size);
|
void gdm_init(void *blockpool, u32 size);
|
||||||
|
#endif
|
||||||
void gdm_setup(void);
|
void gdm_setup(void);
|
||||||
void gdm_maketestdl(s32 id);
|
void gdm_maketestdl(s32 id);
|
||||||
void gd_vblank(void);
|
void gd_vblank(void);
|
||||||
|
|
6289
src/pc/dlmalloc.c
Normal file
6289
src/pc/dlmalloc.c
Normal file
File diff suppressed because it is too large
Load diff
192
src/pc/gfx/gfx_dummy.c
Normal file
192
src/pc/gfx/gfx_dummy.c
Normal file
|
@ -0,0 +1,192 @@
|
||||||
|
#ifdef ENABLE_GFX_DUMMY
|
||||||
|
#include <time.h>
|
||||||
|
#include <errno.h>
|
||||||
|
|
||||||
|
#include "gfx_window_manager_api.h"
|
||||||
|
#include "gfx_rendering_api.h"
|
||||||
|
|
||||||
|
static void gfx_dummy_wm_init(const char *game_name, bool start_in_fullscreen) {
|
||||||
|
}
|
||||||
|
|
||||||
|
static void gfx_dummy_wm_set_keyboard_callbacks(bool (*on_key_down)(int scancode), bool (*on_key_up)(int scancode), void (*on_all_keys_up)(void)) {
|
||||||
|
}
|
||||||
|
|
||||||
|
static void gfx_dummy_wm_set_fullscreen_changed_callback(void (*on_fullscreen_changed)(bool is_now_fullscreen)) {
|
||||||
|
}
|
||||||
|
|
||||||
|
static void gfx_dummy_wm_set_fullscreen(bool enable) {
|
||||||
|
}
|
||||||
|
|
||||||
|
static void gfx_dummy_wm_main_loop(void (*run_one_game_iter)(void)) {
|
||||||
|
while (1) {
|
||||||
|
run_one_game_iter();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void gfx_dummy_wm_get_dimensions(uint32_t *width, uint32_t *height) {
|
||||||
|
*width = 320;
|
||||||
|
*height = 240;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void gfx_dummy_wm_handle_events(void) {
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool gfx_dummy_wm_start_frame(void) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void gfx_dummy_wm_swap_buffers_begin(void) {
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct timespec gfx_dummy_wm_timediff(struct timespec t1, struct timespec t2) {
|
||||||
|
t1.tv_sec -= t2.tv_sec;
|
||||||
|
t1.tv_nsec -= t2.tv_nsec;
|
||||||
|
if (t1.tv_nsec < 0) {
|
||||||
|
t1.tv_nsec += 1000000000;
|
||||||
|
t1.tv_sec -= 1;
|
||||||
|
}
|
||||||
|
return t1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct timespec gfx_dummy_wm_timeadd(struct timespec t1, struct timespec t2) {
|
||||||
|
t1.tv_sec += t2.tv_sec;
|
||||||
|
t1.tv_nsec += t2.tv_nsec;
|
||||||
|
if (t1.tv_nsec > 1000000000) {
|
||||||
|
t1.tv_nsec -= 1000000000;
|
||||||
|
t1.tv_sec += 1;
|
||||||
|
}
|
||||||
|
return t1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void gfx_dummy_wm_swap_buffers_end(void) {
|
||||||
|
static struct timespec prev;
|
||||||
|
struct timespec t;
|
||||||
|
clock_gettime(CLOCK_MONOTONIC, &t);
|
||||||
|
struct timespec diff = gfx_dummy_wm_timediff(t, prev);
|
||||||
|
if (diff.tv_sec == 0 && diff.tv_nsec < 1000000000 / 30) {
|
||||||
|
struct timespec add = {0, 1000000000 / 30};
|
||||||
|
struct timespec next = gfx_dummy_wm_timeadd(prev, add);
|
||||||
|
while (clock_nanosleep(CLOCK_MONOTONIC, TIMER_ABSTIME, &next, NULL) == EINTR) {
|
||||||
|
}
|
||||||
|
prev = next;
|
||||||
|
} else {
|
||||||
|
prev = t;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static double gfx_dummy_wm_get_time(void) {
|
||||||
|
return 0.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool gfx_dummy_renderer_z_is_from_0_to_1(void) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void gfx_dummy_renderer_unload_shader(struct ShaderProgram *old_prg) {
|
||||||
|
}
|
||||||
|
|
||||||
|
static void gfx_dummy_renderer_load_shader(struct ShaderProgram *new_prg) {
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct ShaderProgram *gfx_dummy_renderer_create_and_load_new_shader(uint32_t shader_id) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct ShaderProgram *gfx_dummy_renderer_lookup_shader(uint32_t shader_id) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void gfx_dummy_renderer_shader_get_info(struct ShaderProgram *prg, uint8_t *num_inputs, bool used_textures[2]) {
|
||||||
|
*num_inputs = 0;
|
||||||
|
used_textures[0] = false;
|
||||||
|
used_textures[1] = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint32_t gfx_dummy_renderer_new_texture(void) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void gfx_dummy_renderer_select_texture(int tile, uint32_t texture_id) {
|
||||||
|
}
|
||||||
|
|
||||||
|
static void gfx_dummy_renderer_upload_texture(const uint8_t *rgba32_buf, int width, int height) {
|
||||||
|
}
|
||||||
|
|
||||||
|
static void gfx_dummy_renderer_set_sampler_parameters(int tile, bool linear_filter, uint32_t cms, uint32_t cmt) {
|
||||||
|
}
|
||||||
|
|
||||||
|
static void gfx_dummy_renderer_set_depth_test(bool depth_test) {
|
||||||
|
}
|
||||||
|
|
||||||
|
static void gfx_dummy_renderer_set_depth_mask(bool z_upd) {
|
||||||
|
}
|
||||||
|
|
||||||
|
static void gfx_dummy_renderer_set_zmode_decal(bool zmode_decal) {
|
||||||
|
}
|
||||||
|
|
||||||
|
static void gfx_dummy_renderer_set_viewport(int x, int y, int width, int height) {
|
||||||
|
}
|
||||||
|
|
||||||
|
static void gfx_dummy_renderer_set_scissor(int x, int y, int width, int height) {
|
||||||
|
}
|
||||||
|
|
||||||
|
static void gfx_dummy_renderer_set_use_alpha(bool use_alpha) {
|
||||||
|
}
|
||||||
|
|
||||||
|
static void gfx_dummy_renderer_draw_triangles(float buf_vbo[], size_t buf_vbo_len, size_t buf_vbo_num_tris) {
|
||||||
|
}
|
||||||
|
|
||||||
|
static void gfx_dummy_renderer_init(void) {
|
||||||
|
}
|
||||||
|
|
||||||
|
static void gfx_dummy_renderer_on_resize(void) {
|
||||||
|
}
|
||||||
|
|
||||||
|
static void gfx_dummy_renderer_start_frame(void) {
|
||||||
|
}
|
||||||
|
|
||||||
|
static void gfx_dummy_renderer_end_frame(void) {
|
||||||
|
}
|
||||||
|
|
||||||
|
static void gfx_dummy_renderer_finish_render(void) {
|
||||||
|
}
|
||||||
|
|
||||||
|
struct GfxWindowManagerAPI gfx_dummy_wm_api = {
|
||||||
|
gfx_dummy_wm_init,
|
||||||
|
gfx_dummy_wm_set_keyboard_callbacks,
|
||||||
|
gfx_dummy_wm_set_fullscreen_changed_callback,
|
||||||
|
gfx_dummy_wm_set_fullscreen,
|
||||||
|
gfx_dummy_wm_main_loop,
|
||||||
|
gfx_dummy_wm_get_dimensions,
|
||||||
|
gfx_dummy_wm_handle_events,
|
||||||
|
gfx_dummy_wm_start_frame,
|
||||||
|
gfx_dummy_wm_swap_buffers_begin,
|
||||||
|
gfx_dummy_wm_swap_buffers_end,
|
||||||
|
gfx_dummy_wm_get_time
|
||||||
|
};
|
||||||
|
|
||||||
|
struct GfxRenderingAPI gfx_dummy_renderer_api = {
|
||||||
|
gfx_dummy_renderer_z_is_from_0_to_1,
|
||||||
|
gfx_dummy_renderer_unload_shader,
|
||||||
|
gfx_dummy_renderer_load_shader,
|
||||||
|
gfx_dummy_renderer_create_and_load_new_shader,
|
||||||
|
gfx_dummy_renderer_lookup_shader,
|
||||||
|
gfx_dummy_renderer_shader_get_info,
|
||||||
|
gfx_dummy_renderer_new_texture,
|
||||||
|
gfx_dummy_renderer_select_texture,
|
||||||
|
gfx_dummy_renderer_upload_texture,
|
||||||
|
gfx_dummy_renderer_set_sampler_parameters,
|
||||||
|
gfx_dummy_renderer_set_depth_test,
|
||||||
|
gfx_dummy_renderer_set_depth_mask,
|
||||||
|
gfx_dummy_renderer_set_zmode_decal,
|
||||||
|
gfx_dummy_renderer_set_viewport,
|
||||||
|
gfx_dummy_renderer_set_scissor,
|
||||||
|
gfx_dummy_renderer_set_use_alpha,
|
||||||
|
gfx_dummy_renderer_draw_triangles,
|
||||||
|
gfx_dummy_renderer_init,
|
||||||
|
gfx_dummy_renderer_on_resize,
|
||||||
|
gfx_dummy_renderer_start_frame,
|
||||||
|
gfx_dummy_renderer_end_frame,
|
||||||
|
gfx_dummy_renderer_finish_render
|
||||||
|
};
|
||||||
|
#endif
|
14
src/pc/gfx/gfx_dummy.h
Normal file
14
src/pc/gfx/gfx_dummy.h
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
#ifdef ENABLE_GFX_DUMMY
|
||||||
|
|
||||||
|
#ifndef GFX_DUMMY_H
|
||||||
|
#define GFX_DUMMY_H
|
||||||
|
|
||||||
|
#include "gfx_rendering_api.h"
|
||||||
|
#include "gfx_window_manager_api.h"
|
||||||
|
|
||||||
|
extern struct GfxRenderingAPI gfx_dummy_renderer_api;
|
||||||
|
extern struct GfxWindowManagerAPI gfx_dummy_wm_api;
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
|
@ -100,6 +100,11 @@ static struct RSP {
|
||||||
} texture_scaling_factor;
|
} texture_scaling_factor;
|
||||||
|
|
||||||
struct LoadedVertex loaded_vertices[MAX_VERTICES + 4];
|
struct LoadedVertex loaded_vertices[MAX_VERTICES + 4];
|
||||||
|
|
||||||
|
uint8_t saved_opcode;
|
||||||
|
uint8_t saved_tile;
|
||||||
|
uint16_t saved_uls, saved_ult;
|
||||||
|
int32_t saved_lrx, saved_lry, saved_ulx, saved_uly;
|
||||||
} rsp;
|
} rsp;
|
||||||
|
|
||||||
static struct RDP {
|
static struct RDP {
|
||||||
|
@ -1459,6 +1464,56 @@ static void gfx_run_dl(Gfx* cmd) {
|
||||||
gfx_sp_set_other_mode(C0(8, 8) + 32, C0(0, 8), (uint64_t) cmd->words.w1 << 32);
|
gfx_sp_set_other_mode(C0(8, 8) + 32, C0(0, 8), (uint64_t) cmd->words.w1 << 32);
|
||||||
#endif
|
#endif
|
||||||
break;
|
break;
|
||||||
|
#ifdef F3D_OLD
|
||||||
|
case (uint8_t)G_RDPHALF_2:
|
||||||
|
#else
|
||||||
|
case (uint8_t)G_RDPHALF_1:
|
||||||
|
#endif
|
||||||
|
switch (rsp.saved_opcode) {
|
||||||
|
case G_TEXRECT:
|
||||||
|
case G_TEXRECTFLIP:
|
||||||
|
#ifdef F3DEX_GBI_2E
|
||||||
|
rsp.saved_ulx = (int32_t)(C0(0, 24) << 8) >> 8;
|
||||||
|
#endif
|
||||||
|
rsp.saved_uls = (uint16_t)C1(16, 16);
|
||||||
|
rsp.saved_ult = (uint16_t)C1(0, 16);
|
||||||
|
break;
|
||||||
|
#ifdef F3DEX_GBI_2E
|
||||||
|
case G_FILLRECT:
|
||||||
|
{
|
||||||
|
int32_t ulx = (int32_t)(C0(0, 24) << 8) >> 8;
|
||||||
|
int32_t uly = (int32_t)(C1(0, 24) << 8) >> 8;
|
||||||
|
gfx_dp_fill_rectangle(ulx, uly, rsp.saved_lrx, rsp.saved_lry);
|
||||||
|
rsp.saved_opcode = G_NOOP;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
#ifdef F3D_OLD
|
||||||
|
case (uint8_t)G_RDPHALF_CONT:
|
||||||
|
#else
|
||||||
|
case (uint8_t)G_RDPHALF_2:
|
||||||
|
#endif
|
||||||
|
switch (rsp.saved_opcode) {
|
||||||
|
case G_TEXRECT:
|
||||||
|
case G_TEXRECTFLIP:
|
||||||
|
{
|
||||||
|
uint8_t tile = rsp.saved_tile;
|
||||||
|
int32_t ulx = rsp.saved_ulx, lrx = rsp.saved_lrx, lry = rsp.saved_lry;
|
||||||
|
uint16_t uls = rsp.saved_uls, ult = rsp.saved_ult;
|
||||||
|
#ifdef F3DEX_GBI_2E
|
||||||
|
int32_t uly = (int32_t)(C0(0, 24) << 8) >> 8;
|
||||||
|
#else
|
||||||
|
int32_t uly = rsp.saved_uly;
|
||||||
|
#endif
|
||||||
|
uint16_t dsdx = (uint16_t)C1(16, 16);
|
||||||
|
uint16_t dtdy = (uint16_t)C1(0, 16);
|
||||||
|
gfx_dp_texture_rectangle(ulx, uly, lrx, lry, tile, uls, ult, dsdx, dtdy, rsp.saved_opcode == G_TEXRECTFLIP);
|
||||||
|
rsp.saved_opcode = G_NOOP;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// RDP Commands:
|
// RDP Commands:
|
||||||
case G_SETTIMG:
|
case G_SETTIMG:
|
||||||
|
@ -1503,45 +1558,26 @@ static void gfx_run_dl(Gfx* cmd) {
|
||||||
case G_TEXRECT:
|
case G_TEXRECT:
|
||||||
case G_TEXRECTFLIP:
|
case G_TEXRECTFLIP:
|
||||||
{
|
{
|
||||||
int32_t lrx, lry, tile, ulx, uly;
|
rsp.saved_opcode = opcode;
|
||||||
uint32_t uls, ult, dsdx, dtdy;
|
|
||||||
#ifdef F3DEX_GBI_2E
|
#ifdef F3DEX_GBI_2E
|
||||||
lrx = (int32_t)(C0(0, 24) << 8) >> 8;
|
rsp.saved_lrx = (int32_t)(C0(0, 24) << 8) >> 8;
|
||||||
lry = (int32_t)(C1(0, 24) << 8) >> 8;
|
rsp.saved_lry = (int32_t)(C1(0, 24) << 8) >> 8;
|
||||||
++cmd;
|
rsp.saved_tile = (int32_t)C1(24, 3);
|
||||||
ulx = (int32_t)(C0(0, 24) << 8) >> 8;
|
|
||||||
uly = (int32_t)(C1(0, 24) << 8) >> 8;
|
|
||||||
++cmd;
|
|
||||||
uls = C0(16, 16);
|
|
||||||
ult = C0(0, 16);
|
|
||||||
dsdx = C1(16, 16);
|
|
||||||
dtdy = C1(0, 16);
|
|
||||||
#else
|
#else
|
||||||
lrx = C0(12, 12);
|
rsp.saved_lrx = C0(12, 12);
|
||||||
lry = C0(0, 12);
|
rsp.saved_lry = C0(0, 12);
|
||||||
tile = C1(24, 3);
|
rsp.saved_tile = C1(24, 3);
|
||||||
ulx = C1(12, 12);
|
rsp.saved_ulx = C1(12, 12);
|
||||||
uly = C1(0, 12);
|
rsp.saved_uly = C1(0, 12);
|
||||||
++cmd;
|
|
||||||
uls = C1(16, 16);
|
|
||||||
ult = C1(0, 16);
|
|
||||||
++cmd;
|
|
||||||
dsdx = C1(16, 16);
|
|
||||||
dtdy = C1(0, 16);
|
|
||||||
#endif
|
#endif
|
||||||
gfx_dp_texture_rectangle(ulx, uly, lrx, lry, tile, uls, ult, dsdx, dtdy, opcode == G_TEXRECTFLIP);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case G_FILLRECT:
|
case G_FILLRECT:
|
||||||
#ifdef F3DEX_GBI_2E
|
#ifdef F3DEX_GBI_2E
|
||||||
{
|
{
|
||||||
int32_t lrx, lry, ulx, uly;
|
rsp.saved_opcode = G_FILLRECT;
|
||||||
lrx = (int32_t)(C0(0, 24) << 8) >> 8;
|
rsp.saved_lrx = (int32_t)(C0(0, 24) << 8) >> 8;
|
||||||
lry = (int32_t)(C1(0, 24) << 8) >> 8;
|
rsp.saved_lry = (int32_t)(C1(0, 24) << 8) >> 8;
|
||||||
++cmd;
|
|
||||||
ulx = (int32_t)(C0(0, 24) << 8) >> 8;
|
|
||||||
uly = (int32_t)(C1(0, 24) << 8) >> 8;
|
|
||||||
gfx_dp_fill_rectangle(ulx, uly, lrx, lry);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
|
|
|
@ -17,6 +17,7 @@
|
||||||
#include "gfx/gfx_dxgi.h"
|
#include "gfx/gfx_dxgi.h"
|
||||||
#include "gfx/gfx_glx.h"
|
#include "gfx/gfx_glx.h"
|
||||||
#include "gfx/gfx_sdl.h"
|
#include "gfx/gfx_sdl.h"
|
||||||
|
#include "gfx/gfx_dummy.h"
|
||||||
|
|
||||||
#include "audio/audio_api.h"
|
#include "audio/audio_api.h"
|
||||||
#include "audio/audio_wasapi.h"
|
#include "audio/audio_wasapi.h"
|
||||||
|
@ -140,8 +141,13 @@ static void on_fullscreen_changed(bool is_now_fullscreen) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void main_func(void) {
|
void main_func(void) {
|
||||||
|
#ifdef USE_SYSTEM_MALLOC
|
||||||
|
main_pool_init();
|
||||||
|
gGfxAllocOnlyPool = alloc_only_pool_init();
|
||||||
|
#else
|
||||||
static u64 pool[0x165000/8 / 4 * sizeof(void *)];
|
static u64 pool[0x165000/8 / 4 * sizeof(void *)];
|
||||||
main_pool_init(pool, pool + sizeof(pool) / sizeof(pool[0]));
|
main_pool_init(pool, pool + sizeof(pool) / sizeof(pool[0]));
|
||||||
|
#endif
|
||||||
gEffectsMemoryPool = mem_pool_init(0x4000, MEMORY_POOL_LEFT);
|
gEffectsMemoryPool = mem_pool_init(0x4000, MEMORY_POOL_LEFT);
|
||||||
|
|
||||||
configfile_load(CONFIG_FILE);
|
configfile_load(CONFIG_FILE);
|
||||||
|
@ -165,6 +171,9 @@ void main_func(void) {
|
||||||
#else
|
#else
|
||||||
wm_api = &gfx_sdl;
|
wm_api = &gfx_sdl;
|
||||||
#endif
|
#endif
|
||||||
|
#elif defined(ENABLE_GFX_DUMMY)
|
||||||
|
rendering_api = &gfx_dummy_renderer_api;
|
||||||
|
wm_api = &gfx_dummy_wm_api;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
gfx_init(wm_api, rendering_api, "Super Mario 64 PC-Port", configFullscreen);
|
gfx_init(wm_api, rendering_api, "Super Mario 64 PC-Port", configFullscreen);
|
||||||
|
|
Loading…
Add table
Reference in a new issue