Skip to content

Commit

Permalink
Basic minimap functionality
Browse files Browse the repository at this point in the history
  • Loading branch information
mkst committed Sep 2, 2020
1 parent 63209b7 commit 91a56d8
Show file tree
Hide file tree
Showing 63 changed files with 769 additions and 24 deletions.
55 changes: 46 additions & 9 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -366,6 +366,21 @@ SEG_FILES := $(SEGMENT_ELF_FILES) $(ACTOR_ELF_FILES) $(LEVEL_ELF_FILES)
INCLUDE_CFLAGS := -I include -I $(BUILD_DIR) -I $(BUILD_DIR)/include -I src -I .
ENDIAN_BITWIDTH := $(BUILD_DIR)/endian-and-bitwidth

# minimap
ifeq ($(TARGET_N3DS),1)
MINIMAP := src/minimap

MINIMAP_C := $(wildcard $(MINIMAP)/*.c)
MINIMAP_O := $(foreach file,$(MINIMAP_C),$(BUILD_DIR)/$(file:.c=.o))

MINIMAP_TEXTURES := $(MINIMAP)/textures
MINIMAP_PNG := $(wildcard $(MINIMAP_TEXTURES)/*.png)
MINIMAP_T3S := $(foreach file,$(MINIMAP_PNG),$(BUILD_DIR)/$(file:.png=.t3s))
MINIMAP_T3X := $(foreach file,$(MINIMAP_T3S),$(file:.t3s=.t3x))
MINIMAP_T3X_O := $(foreach file,$(MINIMAP_T3X),$(file:.t3x=.t3x.o))
MINIMAP_T3X_HEADERS := $(foreach file,$(MINIMAP_PNG),$(BUILD_DIR)/$(file:.png=_t3x.h))
endif

ifeq ($(TARGET_N64),1)
IRIX_ROOT := tools/ido5.3_compiler

Expand Down Expand Up @@ -401,11 +416,8 @@ ifeq ($(COMPILER),gcc)
CC := $(CROSS)gcc
endif

ifeq ($(TARGET_N64),1)
TARGET_CFLAGS := -nostdinc -I include/libc -DTARGET_N64 -D_LANGUAGE_C
CC_CFLAGS := -fno-builtin
endif

TARGET_CFLAGS := -nostdinc -I include/libc -DTARGET_N64 -D_LANGUAGE_C
CC_CFLAGS := -fno-builtin
INCLUDE_CFLAGS := -I include -I $(BUILD_DIR) -I $(BUILD_DIR)/include -I src -I .

# Check code syntax with host compiler
Expand Down Expand Up @@ -480,8 +492,8 @@ 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']"
endif
ifeq ($(TARGET_N3DS),1)
CTRULIB := $(DEVKITPRO)/libctru
LIBDIRS := $(CTRULIB)
CTRULIB := $(DEVKITPRO)/libctru
LIBDIRS := $(CTRULIB)
export LIBPATHS := $(foreach dir,$(LIBDIRS),-L$(dir)/lib)
PLATFORM_CFLAGS := -mtp=soft -DTARGET_N3DS -DARM11 -DosGetTime=n64_osGetTime -D_3DS -march=armv6k -mtune=mpcore -mfloat-abi=hard -mword-relocations -fomit-frame-pointer -ffast-math $(foreach dir,$(LIBDIRS),-I$(dir)/include)
PLATFORM_LDFLAGS := $(LIBPATHS) -lcitro3d -lctru -lm -specs=3dsx.specs -g -marm -mthumb-interwork -march=armv6k -mtune=mpcore -mfloat-abi=hard -mtp=soft
Expand Down Expand Up @@ -641,6 +653,11 @@ $(BUILD_DIR)/text/%/define_text.inc.c: text/define_text.inc.c text/%/courses.h t
RSP_DIRS := $(BUILD_DIR)/rsp
ALL_DIRS := $(BUILD_DIR) $(addprefix $(BUILD_DIR)/,$(SRC_DIRS) $(ASM_DIRS) $(GODDARD_SRC_DIRS) $(ULTRA_SRC_DIRS) $(ULTRA_ASM_DIRS) $(ULTRA_BIN_DIRS) $(BIN_DIRS) $(TEXTURE_DIRS) $(TEXT_DIRS) $(SOUND_SAMPLE_DIRS) $(addprefix levels/,$(LEVEL_DIRS)) include) $(MIO0_DIR) $(addprefix $(MIO0_DIR)/,$(VERSION)) $(SOUND_BIN_DIR) $(SOUND_BIN_DIR)/sequences/$(VERSION) $(RSP_DIRS)

ifeq ($(TARGET_N3DS),1)
# create build dir for .t3x etc
ALL_DIRS += $(BUILD_DIR)/$(MINIMAP_TEXTURES)
endif

# Make sure build directory exists before compiling anything
DUMMY != mkdir -p $(ALL_DIRS)

Expand Down Expand Up @@ -871,10 +888,30 @@ SMDH_DESCRIPTION ?= Super Mario 64 3DS Port
SMDH_AUTHOR ?= mkst
SMDH_ICON := icon.smdh

$(EXE): $(O_FILES) $(MIO0_FILES:.mio0=.o) $(SOUND_OBJ_FILES) $(ULTRA_O_FILES) $(GODDARD_O_FILES) $(BUILD_DIR)/src/pc/gfx/shader.shbin.o $(SMDH_ICON)
$(LD) -L $(BUILD_DIR) -o $@.elf $(O_FILES) $(BUILD_DIR)/src/pc/gfx/shader.shbin.o $(SOUND_OBJ_FILES) $(ULTRA_O_FILES) $(GODDARD_O_FILES) $(LDFLAGS)
$(EXE): $(O_FILES) $(MIO0_FILES:.mio0=.o) $(SOUND_OBJ_FILES) $(ULTRA_O_FILES) $(GODDARD_O_FILES) $(BUILD_DIR)/src/pc/gfx/shader.shbin.o $(MINIMAP_O) $(SMDH_ICON)
$(LD) -L $(BUILD_DIR) -o $@.elf $(O_FILES) $(BUILD_DIR)/src/pc/gfx/shader.shbin.o $(MINIMAP_O) $(MINIMAP_T3X_O) $(SOUND_OBJ_FILES) $(ULTRA_O_FILES) $(GODDARD_O_FILES) $(LDFLAGS)
3dsxtool $@.elf $@ --smdh=$(BUILD_DIR)/$(SMDH_ICON)

# stolen from /opt/devkitpro/devkitARM/base_tools
define bin2o
bin2s -a 4 -H $(BUILD_DIR)/$(MINIMAP_TEXTURES)/`(echo $(<F) | tr . _)`.h $(BUILD_DIR)/$< | $(AS) -o $(BUILD_DIR)/$(MINIMAP_TEXTURES)/$(<F).o
endef

# TODO: simplify dependency chain
$(BUILD_DIR)/src/pc/gfx/gfx_citro3d.o: $(MINIMAP_O)
$(BUILD_DIR)/src/pc/gfx/gfx_3ds.o: $(MINIMAP_O)
$(BUILD_DIR)/src/pc/gfx/gfx_3ds_minimap.o: $(MINIMAP_O)
$(MINIMAP_O): $(MINIMAP_T3X_HEADERS)

%.t3x.o $(BUILD_DIR)/%_t3x.h: %.t3x
$(bin2o)

%.t3x: %.t3s
tex3ds -i $(BUILD_DIR)/$< -o $(BUILD_DIR)/$@

%.t3s: %.png
@printf -- "-f rgba -z auto\n../../../../../$(<)\n" > $(BUILD_DIR)/$@

%.smdh: %.png
smdhtool --create "$(SMDH_TITLE)" "$(SMDH_DESCRIPTION)" "$(SMDH_AUTHOR)" $< $(BUILD_DIR)/$@

Expand Down
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ A prior copy of the game is required to extract the assets.
- Experimental Stereo 3D support; add build flag `ENABLE_N3DS_3D_MODE=1` to try it out
- Support injection of [SMDH](https://www.3dbrew.org/wiki/SMDH) file into the .3dsx
- Change the `icon.png` in the base of this repository before building.
- Experimental Mini-Map; bottom screen displays an overview of the current level

## Building

Expand Down
180 changes: 180 additions & 0 deletions src/minimap/minimap.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,180 @@
#include "game/level_update.h"
#include "game/area.h"
#include "game/save_file.h"
#include "level_table.h"

#include "minimap_levels.h"
#include "minimap.h"

// SM64 map area is 16384x16384 (-8192 to +8192 in x and y)
static const float MAP_OFFSET = 8192.0f;
// vertical height of 3DS bottom screen is 240px
static const float MAP_SIZE = 240.0f;
// translate 0->16384 into 0->240
static const float MAP_SCALE = MAP_SIZE / (2 * MAP_OFFSET);

static u8 level_index = 0; // map gCurrLevelNum into level_info[X][]
static u8 area_index = 0; // map gCurrAreaIndex into level_info[][X]

static s16 current_level = -1;
static s16 current_area = -1;

bool minimap_has_level_or_area_changed()
{
return (current_level != gCurrLevelNum || current_area != gCurrAreaIndex);
}

bool minimap_load_level_and_area()
{
// gCurrAreaIndex is 1-indexed
area_index = gCurrAreaIndex > 0 ? gCurrAreaIndex - 1 : 0;

switch (gCurrLevelNum)
{
case LEVEL_BBH:
level_index = 1;
break;
case LEVEL_CCM:
level_index = 2;
break;
case LEVEL_CASTLE:
level_index = 3;
break;
case LEVEL_HMC:
level_index = 4;
break;
case LEVEL_SSL:
level_index = 5;
break;
case LEVEL_BOB:
level_index = 6;
break;
case LEVEL_SL:
level_index = 7;
break;
case LEVEL_WDW:
level_index = 8;
break;
case LEVEL_JRB:
level_index = 9;
break;
case LEVEL_THI:
level_index = 10;
break;
case LEVEL_TTC:
level_index = 11;
break;
case LEVEL_RR:
level_index = 12;
break;
case LEVEL_CASTLE_GROUNDS:
level_index = 13;
// special case for drained moat
if (save_file_get_flags() & SAVE_FLAG_MOAT_DRAINED)
area_index = 1;
break;
case LEVEL_BITDW:
level_index = 14;
break;
case LEVEL_VCUTM:
level_index = 15;
break;
case LEVEL_BITFS:
level_index = 16;
break;
case LEVEL_SA:
level_index = 17;
break;
case LEVEL_BITS:
level_index = 18;
break;
case LEVEL_LLL:
level_index = 19;
break;
case LEVEL_DDD:
level_index = 20;
break;
case LEVEL_WF:
level_index = 21;
break;
case LEVEL_CASTLE_COURTYARD:
level_index = 22;
break;
case LEVEL_PSS:
level_index = 23;
break;
case LEVEL_COTMC:
level_index = 24;
break;
case LEVEL_TOTWC:
level_index = 25;
break;
case LEVEL_BOWSER_1:
level_index = 26;
break;
case LEVEL_WMOTR:
level_index = 27;
break;
case LEVEL_BOWSER_2:
level_index = 28;
break;
case LEVEL_BOWSER_3:
level_index = 29;
break;
case LEVEL_TTM:
level_index = 30;
break;
case LEVEL_UNKNOWN_1:
case LEVEL_UNKNOWN_2:
case LEVEL_UNKNOWN_3:
case LEVEL_ENDING:
case LEVEL_UNKNOWN_32:
case LEVEL_UNKNOWN_35:
case LEVEL_UNKNOWN_37:
case LEVEL_UNKNOWN_38:
default:
level_index = 0; // blank
}

current_level = gCurrLevelNum;
current_area = gCurrAreaIndex;

// return whether or not this is a real level
return level_index > 0;
}

void minimap_get_current_texture(uint8_t **texture, size_t *texture_size, uint32_t *color)
{
#pragma GCC diagnostic ignored "-Wdiscarded-qualifiers"
*texture = level_info[level_index][area_index].texture;
#pragma GCC diagnostic pop
*texture_size = level_info[level_index][area_index].size;
*color = level_info[level_index][area_index].color;
}

bool minimap_get_mario_position(float *mario_x, float *mario_y, float *mario_direction)
{
if (gMarioState == NULL)
{
return false;
}

// get mario's current position
float cur_mario_x = gMarioState->pos[0]; // x
float cur_mario_y = gMarioState->pos[2]; // y

float cur_mario_direction = gMarioState->faceAngle[1];

// scale for the mini map and clamp
float mario_x_scaled_and_offset = MIN(MAP_SIZE, MAX(0.0f, (cur_mario_x + MAP_OFFSET) * MAP_SCALE));
float mario_y_scaled_and_offset = MIN(MAP_SIZE, MAX(0.0f, (cur_mario_y + MAP_OFFSET) * MAP_SCALE));

// range of rotation is +- 32768
float mario_direction_scaled = cur_mario_direction / 65536.0f;

*mario_x = mario_x_scaled_and_offset;
*mario_y = mario_y_scaled_and_offset;
*mario_direction = mario_direction_scaled;

return true;
}
11 changes: 11 additions & 0 deletions src/minimap/minimap.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
#ifndef GFX_MINIMAP_H
#define GFX_MINIMAP_H

#include <stdbool.h>

bool minimap_has_level_or_area_changed();
bool minimap_load_level_and_area();
void minimap_get_current_texture(uint8_t **texture, size_t *texture_size, uint32_t *color);
bool minimap_get_mario_position(float *mario_x, float *mario_y, float *mario_direction);

#endif
Loading

0 comments on commit 91a56d8

Please sign in to comment.